aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--bitcoin-qt.pro33
-rw-r--r--contrib/debian/changelog38
-rw-r--r--doc/README2
-rw-r--r--doc/README_windows.txt2
-rw-r--r--doc/assets-attribution.txt4
-rw-r--r--doc/build-osx.txt2
-rw-r--r--doc/build-unix.txt7
-rw-r--r--doc/release-process.txt1
-rw-r--r--share/setup.nsi6
-rw-r--r--src/addrman.cpp29
-rw-r--r--src/addrman.h7
-rw-r--r--src/allocators.h2
-rw-r--r--src/base58.h4
-rw-r--r--src/bignum.h2
-rw-r--r--src/bitcoinrpc.cpp736
-rw-r--r--src/bitcoinrpc.h17
-rw-r--r--src/checkpoints.cpp2
-rw-r--r--src/checkpoints.h2
-rw-r--r--src/compat.h2
-rw-r--r--src/db.cpp150
-rw-r--r--src/db.h22
-rw-r--r--src/init.cpp462
-rw-r--r--src/init.h9
-rw-r--r--src/irc.cpp20
-rw-r--r--src/irc.h3
-rw-r--r--src/key.cpp3
-rw-r--r--src/key.h2
-rw-r--r--src/keystore.cpp17
-rw-r--r--src/keystore.h23
-rw-r--r--src/main.cpp220
-rw-r--r--src/main.h57
-rw-r--r--src/makefile.linux-mingw7
-rw-r--r--src/makefile.mingw5
-rw-r--r--src/makefile.osx7
-rw-r--r--src/makefile.unix11
-rw-r--r--src/mruset.h2
-rw-r--r--src/net.cpp573
-rw-r--r--src/net.h51
-rw-r--r--src/netbase.cpp441
-rw-r--r--src/netbase.h29
-rw-r--r--src/noui.cpp35
-rw-r--r--src/protocol.cpp2
-rw-r--r--src/protocol.h2
-rw-r--r--src/qt/addressbookpage.cpp57
-rw-r--r--src/qt/addressbookpage.h5
-rw-r--r--src/qt/addresstablemodel.cpp85
-rw-r--r--src/qt/addresstablemodel.h9
-rw-r--r--src/qt/askpassphrasedialog.cpp3
-rw-r--r--src/qt/bitcoin.cpp149
-rw-r--r--src/qt/bitcoin.qrc11
-rw-r--r--src/qt/bitcoinaddressvalidator.cpp28
-rw-r--r--src/qt/bitcoingui.cpp94
-rw-r--r--src/qt/bitcoingui.h13
-rw-r--r--src/qt/bitcoinstrings.cpp39
-rw-r--r--src/qt/clientmodel.cpp111
-rw-r--r--src/qt/clientmodel.h19
-rw-r--r--src/qt/csvmodelwriter.cpp5
-rw-r--r--src/qt/editaddressdialog.cpp2
-rw-r--r--src/qt/forms/aboutdialog.ui12
-rw-r--r--src/qt/forms/addressbookpage.ui12
-rw-r--r--src/qt/forms/askpassphrasedialog.ui30
-rw-r--r--src/qt/forms/messagepage.ui21
-rw-r--r--src/qt/forms/overviewpage.ui238
-rw-r--r--src/qt/forms/qrcodedialog.ui6
-rw-r--r--src/qt/forms/rpcconsole.ui401
-rw-r--r--src/qt/forms/sendcoinsdialog.ui4
-rw-r--r--src/qt/forms/transactiondescdialog.ui4
-rw-r--r--src/qt/forms/verifymessagedialog.ui125
-rw-r--r--src/qt/guiconstants.h5
-rw-r--r--src/qt/guiutil.cpp199
-rw-r--r--src/qt/guiutil.h26
-rw-r--r--src/qt/locale/bitcoin_bg.ts2247
-rw-r--r--src/qt/locale/bitcoin_el_GR.ts2269
-rw-r--r--src/qt/locale/bitcoin_en.ts1283
-rw-r--r--src/qt/locale/bitcoin_fr.ts2267
-rw-r--r--src/qt/locale/bitcoin_pt_PT.ts2265
-rw-r--r--src/qt/messagepage.cpp30
-rw-r--r--src/qt/messagepage.h4
-rw-r--r--src/qt/optionsdialog.cpp302
-rw-r--r--src/qt/optionsdialog.h10
-rw-r--r--src/qt/optionsmodel.cpp16
-rw-r--r--src/qt/optionsmodel.h7
-rw-r--r--src/qt/overviewpage.cpp39
-rw-r--r--src/qt/overviewpage.h4
-rw-r--r--src/qt/qrcodedialog.cpp3
-rw-r--r--src/qt/qtipcserver.cpp5
-rw-r--r--src/qt/qvaluecombobox.cpp6
-rw-r--r--src/qt/qvaluecombobox.h9
-rw-r--r--src/qt/res/icons/debugwindow.pngbin0 -> 5402 bytes
-rw-r--r--src/qt/res/icons/qrcode.pngbin0 -> 237 bytes
-rw-r--r--src/qt/res/images/qrcode.pngbin5993 -> 0 bytes
-rw-r--r--src/qt/rpcconsole.cpp328
-rw-r--r--src/qt/rpcconsole.h64
-rw-r--r--src/qt/sendcoinsdialog.cpp10
-rw-r--r--src/qt/sendcoinsentry.cpp4
-rw-r--r--src/qt/transactionrecord.cpp181
-rw-r--r--src/qt/transactiontablemodel.cpp146
-rw-r--r--src/qt/transactiontablemodel.h6
-rw-r--r--src/qt/transactionview.cpp14
-rw-r--r--src/qt/transactionview.h1
-rw-r--r--src/qt/verifymessagedialog.cpp104
-rw-r--r--src/qt/verifymessagedialog.h37
-rw-r--r--src/qt/walletmodel.cpp87
-rw-r--r--src/qt/walletmodel.h11
-rw-r--r--src/rpcdump.cpp6
-rw-r--r--src/script.cpp8
-rw-r--r--src/script.h2
-rw-r--r--src/serialize.h2
-rw-r--r--src/sync.cpp120
-rw-r--r--src/sync.h209
-rw-r--r--src/test/DoS_tests.cpp8
-rw-r--r--src/test/base58_tests.cpp4
-rw-r--r--src/test/base64_tests.cpp2
-rw-r--r--src/test/test_bitcoin.cpp4
-rw-r--r--src/test/util_tests.cpp2
-rw-r--r--src/ui_interface.h134
-rw-r--r--src/uint256.h2
-rw-r--r--src/util.cpp479
-rw-r--r--src/util.h139
-rw-r--r--src/version.cpp2
-rw-r--r--src/version.h11
-rw-r--r--src/wallet.cpp42
-rw-r--r--src/wallet.h23
-rw-r--r--src/walletdb.cpp5
-rw-r--r--src/walletdb.h2
126 files changed, 15140 insertions, 2590 deletions
diff --git a/.gitignore b/.gitignore
index dafbc2b6bc..fe93caafbf 100644
--- a/.gitignore
+++ b/.gitignore
@@ -20,3 +20,4 @@ qrc_*.cpp
*.pro.user
#mac specific
.DS_Store
+build
diff --git a/bitcoin-qt.pro b/bitcoin-qt.pro
index f586c53372..a47d661678 100644
--- a/bitcoin-qt.pro
+++ b/bitcoin-qt.pro
@@ -1,8 +1,8 @@
TEMPLATE = app
TARGET =
-VERSION = 0.6.1
+VERSION = 0.6.99
INCLUDEPATH += src src/json src/qt
-DEFINES += QT_GUI BOOST_THREAD_USE_LIB
+DEFINES += QT_GUI BOOST_THREAD_USE_LIB BOOST_SPIRIT_THREADSAFE USE_IPV6
CONFIG += no_include_pwd
# for boost 1.37, add -mt to the boost libraries
@@ -83,14 +83,14 @@ contains(BITCOIN_NEED_QT_PLUGINS, 1) {
# regenerate src/build.h
!windows || contains(USE_BUILD_INFO, 1) {
genbuild.depends = FORCE
- genbuild.commands = cd $$PWD; share/genbuild.sh $$OUT_PWD/build/build.h
- genbuild.target = genbuildhook
- PRE_TARGETDEPS += genbuildhook
+ genbuild.commands = cd $$PWD; /bin/sh share/genbuild.sh $$OUT_PWD/build/build.h
+ genbuild.target = $$OUT_PWD/build/build.h
+ PRE_TARGETDEPS += $$OUT_PWD/build/build.h
QMAKE_EXTRA_TARGETS += genbuild
DEFINES += HAVE_BUILD_INFO
}
-QMAKE_CXXFLAGS_WARN_ON = -fdiagnostics-show-option -Wall -Wextra -Wformat -Wformat-security -Wno-invalid-offsetof -Wno-sign-compare -Wno-unused-parameter
+QMAKE_CXXFLAGS_WARN_ON = -fdiagnostics-show-option -Wall -Wextra -Wformat -Wformat-security -Wno-unused-parameter
# Input
DEPENDPATH += src src/json src/qt
@@ -109,6 +109,7 @@ HEADERS += src/qt/bitcoingui.h \
src/bignum.h \
src/checkpoints.h \
src/compat.h \
+ src/sync.h \
src/util.h \
src/uint256.h \
src/serialize.h \
@@ -158,7 +159,9 @@ HEADERS += src/qt/bitcoingui.h \
src/qt/notificator.h \
src/qt/qtipcserver.h \
src/allocators.h \
- src/ui_interface.h
+ src/ui_interface.h \
+ src/qt/rpcconsole.h \
+ src/qt/verifymessagedialog.h
SOURCES += src/qt/bitcoin.cpp src/qt/bitcoingui.cpp \
src/qt/transactiontablemodel.cpp \
@@ -171,6 +174,7 @@ SOURCES += src/qt/bitcoin.cpp src/qt/bitcoingui.cpp \
src/qt/editaddressdialog.cpp \
src/qt/bitcoinaddressvalidator.cpp \
src/version.cpp \
+ src/sync.cpp \
src/util.cpp \
src/netbase.cpp \
src/key.cpp \
@@ -212,7 +216,9 @@ SOURCES += src/qt/bitcoin.cpp src/qt/bitcoingui.cpp \
src/qt/askpassphrasedialog.cpp \
src/protocol.cpp \
src/qt/notificator.cpp \
- src/qt/qtipcserver.cpp
+ src/qt/qtipcserver.cpp \
+ src/qt/rpcconsole.cpp \
+ src/qt/verifymessagedialog.cpp
RESOURCES += \
src/qt/bitcoin.qrc
@@ -226,7 +232,9 @@ FORMS += \
src/qt/forms/transactiondescdialog.ui \
src/qt/forms/overviewpage.ui \
src/qt/forms/sendcoinsentry.ui \
- src/qt/forms/askpassphrasedialog.ui
+ src/qt/forms/askpassphrasedialog.ui \
+ src/qt/forms/rpcconsole.ui \
+ src/qt/forms/verifymessagedialog.ui
contains(USE_QRCODE, 1) {
HEADERS += src/qt/qrcodedialog.h
@@ -254,15 +262,14 @@ isEmpty(QMAKE_LRELEASE) {
win32:QMAKE_LRELEASE = $$[QT_INSTALL_BINS]\\lrelease.exe
else:QMAKE_LRELEASE = $$[QT_INSTALL_BINS]/lrelease
}
-isEmpty(TS_DIR):TS_DIR = src/qt/locale
+isEmpty(QM_DIR):QM_DIR = $$PWD/src/qt/locale
# automatically build translations, so they can be included in resource file
TSQM.name = lrelease ${QMAKE_FILE_IN}
TSQM.input = TRANSLATIONS
-TSQM.output = $$TS_DIR/${QMAKE_FILE_BASE}.qm
-TSQM.commands = $$QMAKE_LRELEASE ${QMAKE_FILE_IN}
+TSQM.output = $$QM_DIR/${QMAKE_FILE_BASE}.qm
+TSQM.commands = $$QMAKE_LRELEASE ${QMAKE_FILE_IN} -qm ${QMAKE_FILE_OUT}
TSQM.CONFIG = no_link
QMAKE_EXTRA_COMPILERS += TSQM
-PRE_TARGETDEPS += compiler_TSQM_make_all
# "Other files" to show in Qt Creator
OTHER_FILES += \
diff --git a/contrib/debian/changelog b/contrib/debian/changelog
index db5e2682c6..cdd4a47e91 100644
--- a/contrib/debian/changelog
+++ b/contrib/debian/changelog
@@ -1,13 +1,43 @@
-bitcoin (0.5.1-natty1) natty; urgency=low
+bitcoin (0.6.1-natty0) natty; urgency=low
+
+ * New upstream release.
+
+ -- Matt Corallo <matt@bluematt.me> Sun, 6 May 2012 20:09:00 -0500
+
+bitcoin (0.6.0-natty0) natty; urgency=low
+
+ * New upstream release.
+ * Add GNOME/KDE support for bitcoin-qt's bitcoin: URI support.
+ Thanks to luke-jr for the KDE .protocol file.
+
+ -- Matt Corallo <matt@bluematt.me> Sat, 31 Mar 2012 15:35:00 -0500
+
+bitcoin (0.5.3-natty1) natty; urgency=low
+
+ * Mark for upload to PPA.
+
+ -- Matt Corallo <matt@bluematt.me> Wed, 14 Mar 2012 23:06:00 -0400
+
+bitcoin (0.5.3-natty0) natty; urgency=low
+
+ * New upstream release.
+
+ -- Luke Dashjr <luke+bitcoin+deb@dashjr.org> Tue, 10 Jan 2012 15:57:00 -0500
+
+bitcoin (0.5.2-natty1) natty; urgency=low
* Remove mentions on anonymity in package descriptions and manpage.
These should never have been there, bitcoin isnt anonymous without
a ton of work that virtually no users will ever be willing and
capable of doing
- * Add GNOME/KDE support for bitcoin-qt's bitcoin: URI support.
- Thanks to luke-jr for the KDE .protocol file.
- -- Matt Corallo <matt@bluematt.me> Fri, 23 Dec 2011 20:25:00 -0500
+ -- Matt Corallo <matt@bluematt.me> Sat, 7 Jan 2012 13:37:00 -0500
+
+bitcoin (0.5.2-natty0) natty; urgency=low
+
+ * New upstream release.
+
+ -- Luke Dashjr <luke+bitcoin+deb@dashjr.org> Fri, 16 Dec 2011 17:57:00 -0500
bitcoin (0.5.1-natty0) natty; urgency=low
diff --git a/doc/README b/doc/README
index a196a461e5..4eda8bcd76 100644
--- a/doc/README
+++ b/doc/README
@@ -1,4 +1,4 @@
-Bitcoin 0.6.1 BETA
+Bitcoin 0.6.99 BETA
Copyright (c) 2009-2012 Bitcoin Developers
Distributed under the MIT/X11 software license, see the accompanying
diff --git a/doc/README_windows.txt b/doc/README_windows.txt
index ec0225fd92..eec252931d 100644
--- a/doc/README_windows.txt
+++ b/doc/README_windows.txt
@@ -1,4 +1,4 @@
-Bitcoin 0.6.1 BETA
+Bitcoin 0.6.99 BETA
Copyright (c) 2009-2012 Bitcoin Developers
Distributed under the MIT/X11 software license, see the accompanying
diff --git a/doc/assets-attribution.txt b/doc/assets-attribution.txt
index 0b0e377065..75062f7fef 100644
--- a/doc/assets-attribution.txt
+++ b/doc/assets-attribution.txt
@@ -54,3 +54,7 @@ Designer: Crobbo (forum)
Site: https://bitcointalk.org/index.php?topic=32273.0
License: Public domain
+Icon: src/qt/res/icons/debugwindow.png
+Designer: Vignoni David
+Site: http://www.oxygen-icons.org/
+License: Oxygen icon theme is dual licensed. You may copy it under the Creative Common Attribution-ShareAlike 3.0 License or the GNU Library General Public License.
diff --git a/doc/build-osx.txt b/doc/build-osx.txt
index 2ae77067fc..256614f7ab 100644
--- a/doc/build-osx.txt
+++ b/doc/build-osx.txt
@@ -44,7 +44,7 @@ sudo port install qrencode
4. Now you should be able to build bitcoind:
cd bitcoin/src
-make -f makefile.osx
+make -f makefile.osx USE_IPV6=1
Run:
./bitcoind --help # for a list of command-line options.
diff --git a/doc/build-unix.txt b/doc/build-unix.txt
index c5b4205084..c32563814d 100644
--- a/doc/build-unix.txt
+++ b/doc/build-unix.txt
@@ -40,9 +40,12 @@ turned off by default. Set USE_UPNP to a different value to control this:
libqrencode may be used for QRCode image generation. It can be downloaded
from http://fukuchi.org/works/qrencode/index.html.en, or installed via
your package manager. Set USE_QRCODE to control this:
- USE_QRCODE=0 (the default) No QRCode support - libarcode not required
+ USE_QRCODE=0 (the default) No QRCode support - libqrcode not required
USE_QRCODE=1 QRCode support enabled
+IPv6 support may be enabled by setting
+ USE_IPV6=1 Enable IPv6 support
+
Licenses of statically linked libraries:
Berkeley DB New BSD license with additional requirement that linked
software must be free open source
@@ -80,7 +83,7 @@ emerge -av1 --noreplace boost glib openssl sys-libs/db:4.8
Take the following steps to build (no UPnP support):
cd ${BITCOIN_DIR}/src
- make -f makefile.unix USE_UPNP= BDB_INCLUDE_PATH='/usr/include/db4.8'
+ make -f makefile.unix USE_UPNP= USE_IPV6=1 BDB_INCLUDE_PATH='/usr/include/db4.8'
strip bitcoind
diff --git a/doc/release-process.txt b/doc/release-process.txt
index 00fafa4818..efa2063459 100644
--- a/doc/release-process.txt
+++ b/doc/release-process.txt
@@ -93,6 +93,7 @@
* create SHA256SUMS for builds, and PGP-sign it
* update bitcoin.org version
+ make sure all OS download links go to the right versions
* update forum version
diff --git a/share/setup.nsi b/share/setup.nsi
index 10bf36b4cf..fbbad3769e 100644
--- a/share/setup.nsi
+++ b/share/setup.nsi
@@ -5,7 +5,7 @@ SetCompressor /SOLID lzma
# General Symbol Definitions
!define REGKEY "SOFTWARE\$(^Name)"
-!define VERSION 0.6.1
+!define VERSION 0.6.99
!define COMPANY "Bitcoin project"
!define URL http://www.bitcoin.org/
@@ -45,13 +45,13 @@ Var StartMenuGroup
!insertmacro MUI_LANGUAGE English
# Installer attributes
-OutFile bitcoin-0.6.1-win32-setup.exe
+OutFile bitcoin-0.6.99-win32-setup.exe
InstallDir $PROGRAMFILES\Bitcoin
CRCCheck on
XPStyle on
BrandingText " "
ShowInstDetails show
-VIProductVersion 0.6.1.3
+VIProductVersion 0.6.99.0
VIAddVersionKey ProductName Bitcoin
VIAddVersionKey ProductVersion "${VERSION}"
VIAddVersionKey CompanyName "${COMPANY}"
diff --git a/src/addrman.cpp b/src/addrman.cpp
index 345261e229..acd0d46790 100644
--- a/src/addrman.cpp
+++ b/src/addrman.cpp
@@ -1,6 +1,6 @@
// Copyright (c) 2012 Pieter Wuille
// Distributed under the MIT/X11 software license, see the accompanying
-// file license.txt or http://www.opensource.org/licenses/mit-license.php.
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "addrman.h"
@@ -102,14 +102,19 @@ CAddrInfo* CAddrMan::Create(const CAddress &addr, const CNetAddr &addrSource, in
return &mapInfo[nId];
}
-void CAddrMan::SwapRandom(int nRndPos1, int nRndPos2)
+void CAddrMan::SwapRandom(unsigned int nRndPos1, unsigned int nRndPos2)
{
if (nRndPos1 == nRndPos2)
return;
+ assert(nRndPos1 < vRandom.size() && nRndPos2 < vRandom.size());
+
int nId1 = vRandom[nRndPos1];
int nId2 = vRandom[nRndPos2];
+ assert(mapInfo.count(nId1) == 1);
+ assert(mapInfo.count(nId2) == 1);
+
mapInfo[nId1].nRandomPos = nRndPos2;
mapInfo[nId2].nRandomPos = nRndPos1;
@@ -124,26 +129,32 @@ int CAddrMan::SelectTried(int nKBucket)
// random shuffle the first few elements (using the entire list)
// find the least recently tried among them
int64 nOldest = -1;
+ int nOldestPos = -1;
for (unsigned int i = 0; i < ADDRMAN_TRIED_ENTRIES_INSPECT_ON_EVICT && i < vTried.size(); i++)
{
int nPos = GetRandInt(vTried.size() - i) + i;
int nTemp = vTried[nPos];
vTried[nPos] = vTried[i];
vTried[i] = nTemp;
- if (nOldest == -1 || mapInfo[nTemp].nLastSuccess < mapInfo[nOldest].nLastSuccess)
+ assert(nOldest == -1 || mapInfo.count(nTemp) == 1);
+ if (nOldest == -1 || mapInfo[nTemp].nLastSuccess < mapInfo[nOldest].nLastSuccess) {
nOldest = nTemp;
+ nOldestPos = nPos;
+ }
}
- return nOldest;
+ return nOldestPos;
}
int CAddrMan::ShrinkNew(int nUBucket)
{
+ assert(nUBucket >= 0 && (unsigned int)nUBucket < vvNew.size());
std::set<int> &vNew = vvNew[nUBucket];
// first look for deletable items
for (std::set<int>::iterator it = vNew.begin(); it != vNew.end(); it++)
{
+ assert(mapInfo.count(*it));
CAddrInfo &info = mapInfo[*it];
if (info.IsTerrible())
{
@@ -168,11 +179,13 @@ int CAddrMan::ShrinkNew(int nUBucket)
{
if (nI == n[0] || nI == n[1] || nI == n[2] || nI == n[3])
{
+ assert(nOldest == -1 || mapInfo.count(*it) == 1);
if (nOldest == -1 || mapInfo[*it].nTime < mapInfo[nOldest].nTime)
nOldest = *it;
}
nI++;
}
+ assert(mapInfo.count(nOldest) == 1);
CAddrInfo &info = mapInfo[nOldest];
if (--info.nRefCount == 0)
{
@@ -189,6 +202,8 @@ int CAddrMan::ShrinkNew(int nUBucket)
void CAddrMan::MakeTried(CAddrInfo& info, int nId, int nOrigin)
{
+ assert(vvNew[nOrigin].count(nId) == 1);
+
// remove the entry from all new buckets
for (std::vector<std::set<int> >::iterator it = vvNew.begin(); it != vvNew.end(); it++)
{
@@ -197,6 +212,8 @@ void CAddrMan::MakeTried(CAddrInfo& info, int nId, int nOrigin)
}
nNew--;
+ assert(info.nRefCount == 0);
+
// what tried bucket to move the entry to
int nKBucket = info.GetTriedBucket(nKey);
std::vector<int> &vTried = vvTried[nKBucket];
@@ -214,6 +231,7 @@ void CAddrMan::MakeTried(CAddrInfo& info, int nId, int nOrigin)
int nPos = SelectTried(nKBucket);
// find which new bucket it belongs to
+ assert(mapInfo.count(vTried[nPos]) == 1);
int nUBucket = mapInfo[vTried[nPos]].GetNewBucket(nKey);
std::set<int> &vNew = vvNew[nUBucket];
@@ -385,6 +403,7 @@ CAddress CAddrMan::Select_(int nUnkBias)
std::vector<int> &vTried = vvTried[nKBucket];
if (vTried.size() == 0) continue;
int nPos = GetRandInt(vTried.size());
+ assert(mapInfo.count(vTried[nPos]) == 1);
CAddrInfo &info = mapInfo[vTried[nPos]];
if (GetRandInt(1<<30) < fChanceFactor*info.GetChance()*(1<<30))
return info;
@@ -402,6 +421,7 @@ CAddress CAddrMan::Select_(int nUnkBias)
std::set<int>::iterator it = vNew.begin();
while (nPos--)
it++;
+ assert(mapInfo.count(*it) == 1);
CAddrInfo &info = mapInfo[*it];
if (GetRandInt(1<<30) < fChanceFactor*info.GetChance()*(1<<30))
return info;
@@ -481,6 +501,7 @@ void CAddrMan::GetAddr_(std::vector<CAddress> &vAddr)
{
int nRndPos = GetRandInt(vRandom.size() - n) + n;
SwapRandom(n, nRndPos);
+ assert(mapInfo.count(vRandom[n]) == 1);
vAddr.push_back(mapInfo[vRandom[n]]);
}
}
diff --git a/src/addrman.h b/src/addrman.h
index 7652df66ae..b996839e3c 100644
--- a/src/addrman.h
+++ b/src/addrman.h
@@ -1,12 +1,13 @@
// Copyright (c) 2012 Pieter Wuille
// Distributed under the MIT/X11 software license, see the accompanying
-// file license.txt or http://www.opensource.org/licenses/mit-license.php.
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifndef _BITCOIN_ADDRMAN
#define _BITCOIN_ADDRMAN 1
#include "netbase.h"
#include "protocol.h"
#include "util.h"
+#include "sync.h"
#include <map>
@@ -62,7 +63,7 @@ public:
nRandomPos = -1;
}
- CAddrInfo(const CAddress &addrIn, const CNetAddr &addrSource) : CAddress(addrIn)
+ CAddrInfo(const CAddress &addrIn, const CNetAddr &addrSource) : CAddress(addrIn), source(addrSource)
{
Init();
}
@@ -204,7 +205,7 @@ protected:
CAddrInfo* Create(const CAddress &addr, const CNetAddr &addrSource, int *pnId = NULL);
// Swap two elements in vRandom.
- void SwapRandom(int nRandomPos1, int nRandomPos2);
+ void SwapRandom(unsigned int nRandomPos1, unsigned int nRandomPos2);
// Return position in given bucket to replace.
int SelectTried(int nKBucket);
diff --git a/src/allocators.h b/src/allocators.h
index fa9534bc52..4b3356e874 100644
--- a/src/allocators.h
+++ b/src/allocators.h
@@ -1,7 +1,7 @@
// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2012 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
-// file license.txt or http://www.opensource.org/licenses/mit-license.php.
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifndef BITCOIN_ALLOCATORS_H
#define BITCOIN_ALLOCATORS_H
diff --git a/src/base58.h b/src/base58.h
index 90ce34b05b..a4ff35c4a8 100644
--- a/src/base58.h
+++ b/src/base58.h
@@ -1,7 +1,7 @@
// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2012 The Bitcoin Developers
// Distributed under the MIT/X11 software license, see the accompanying
-// file license.txt or http://www.opensource.org/licenses/mit-license.php.
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
//
@@ -252,7 +252,7 @@ public:
bool operator> (const CBase58Data& b58) const { return CompareTo(b58) > 0; }
};
-/** base58-encoded bitcoin addresses.
+/** base58-encoded Bitcoin addresses.
* Public-key-hash-addresses have version 0 (or 111 testnet).
* The data vector contains RIPEMD160(SHA256(pubkey)), where pubkey is the serialized public key.
* Script-hash-addresses have version 5 (or 196 testnet).
diff --git a/src/bignum.h b/src/bignum.h
index f0971e8850..307017b0ab 100644
--- a/src/bignum.h
+++ b/src/bignum.h
@@ -1,7 +1,7 @@
// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2012 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
-// file license.txt or http://www.opensource.org/licenses/mit-license.php.
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifndef BITCOIN_BIGNUM_H
#define BITCOIN_BIGNUM_H
diff --git a/src/bitcoinrpc.cpp b/src/bitcoinrpc.cpp
index 15bcf1da3d..24fa97588c 100644
--- a/src/bitcoinrpc.cpp
+++ b/src/bitcoinrpc.cpp
@@ -1,7 +1,7 @@
// Copyright (c) 2010 Satoshi Nakamoto
// Copyright (c) 2009-2012 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
-// file license.txt or http://www.opensource.org/licenses/mit-license.php.
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "main.h"
#include "wallet.h"
@@ -44,6 +44,10 @@ static CCriticalSection cs_nWalletUnlockTime;
extern Value dumpprivkey(const Array& params, bool fHelp);
extern Value importprivkey(const Array& params, bool fHelp);
+const Object emptyobj;
+
+void ThreadRPCServer3(void* parg);
+
Object JSONRPCError(int code, const string& message)
{
Object error;
@@ -111,6 +115,48 @@ HexBits(unsigned int nBits)
return HexStr(BEGIN(uBits.cBits), END(uBits.cBits));
}
+static std::string
+HelpRequiringPassphrase()
+{
+ return pwalletMain->IsCrypted()
+ ? "\nrequires wallet passphrase to be set with walletpassphrase first"
+ : "";
+}
+
+static inline void
+EnsureWalletIsUnlocked()
+{
+ if (pwalletMain->IsLocked())
+ throw JSONRPCError(-13, "Error: Please enter the wallet passphrase with walletpassphrase first.");
+}
+
+enum DecomposeMode {
+ DM_NONE = 0,
+ DM_HASH,
+ DM_HEX,
+ DM_ASM,
+ DM_OBJ,
+};
+
+enum DecomposeMode
+FindDecompose(const Object& decompositions, const char* pcType, const char* pcDefault)
+{
+ Value val = find_value(decompositions, pcType);
+ std::string strDecompose = (val.type() == null_type) ? pcDefault : val.get_str();
+
+ if (strDecompose == "no")
+ return DM_NONE;
+ if (strDecompose == "hash")
+ return DM_HASH;
+ if (strDecompose == "hex")
+ return DM_HEX;
+ if (strDecompose == "asm")
+ return DM_ASM;
+ if (strDecompose == "obj")
+ return DM_OBJ;
+ throw JSONRPCError(-18, "Invalid decomposition");
+}
+
void WalletTxToJSON(const CWalletTx& wtx, Object& entry)
{
int confirms = wtx.GetDepthInMainChain();
@@ -126,6 +172,141 @@ void WalletTxToJSON(const CWalletTx& wtx, Object& entry)
entry.push_back(Pair(item.first, item.second));
}
+void
+ScriptSigToJSON(const CTxIn& txin, Object& out)
+{
+ out.push_back(Pair("asm", txin.scriptSig.ToString()));
+ out.push_back(Pair("hex", HexStr(txin.scriptSig.begin(), txin.scriptSig.end())));
+
+ CTransaction txprev;
+ uint256 hashTxprevBlock;
+ if (!GetTransaction(txin.prevout.hash, txprev, hashTxprevBlock))
+ return;
+
+ txnouttype type;
+ vector<CBitcoinAddress> addresses;
+ int nRequired;
+
+ if (!ExtractAddresses(txprev.vout[txin.prevout.n].scriptPubKey, type,
+ addresses, nRequired))
+ {
+ out.push_back(Pair("type", GetTxnOutputType(TX_NONSTANDARD)));
+ return;
+ }
+
+ out.push_back(Pair("type", GetTxnOutputType(type)));
+ if (type == TX_MULTISIG)
+ {
+ // TODO: Need to handle this specially since not all input addresses are required...
+ return;
+ }
+
+ Array a;
+ BOOST_FOREACH(const CBitcoinAddress& addr, addresses)
+ a.push_back(addr.ToString());
+ out.push_back(Pair("addresses", a));
+}
+
+void
+ScriptPubKeyToJSON(const CScript& scriptPubKey, Object& out)
+{
+ txnouttype type;
+ vector<CBitcoinAddress> addresses;
+ int nRequired;
+
+ out.push_back(Pair("asm", scriptPubKey.ToString()));
+ out.push_back(Pair("hex", HexStr(scriptPubKey.begin(), scriptPubKey.end())));
+
+ if (!ExtractAddresses(scriptPubKey, type, addresses, nRequired))
+ {
+ out.push_back(Pair("type", GetTxnOutputType(TX_NONSTANDARD)));
+ return;
+ }
+
+ out.push_back(Pair("reqSigs", nRequired));
+ out.push_back(Pair("type", GetTxnOutputType(type)));
+
+ Array a;
+ BOOST_FOREACH(const CBitcoinAddress& addr, addresses)
+ a.push_back(addr.ToString());
+ out.push_back(Pair("addresses", a));
+}
+
+void TxToJSON(const CTransaction &tx, Object& entry, const Object& decompositions)
+{
+ entry.push_back(Pair("version", tx.nVersion));
+ entry.push_back(Pair("locktime", (boost::int64_t)tx.nLockTime));
+ entry.push_back(Pair("size", (boost::int64_t)::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION)));
+
+ enum DecomposeMode decomposeScript = FindDecompose(decompositions, "script", "asm");
+
+ Array vin;
+ BOOST_FOREACH(const CTxIn& txin, tx.vin)
+ {
+ Object in;
+ if (tx.IsCoinBase())
+ in.push_back(Pair("coinbase", HexStr(txin.scriptSig.begin(), txin.scriptSig.end())));
+ else
+ {
+ Object prevout;
+ prevout.push_back(Pair("hash", txin.prevout.hash.GetHex()));
+ prevout.push_back(Pair("n", (boost::int64_t)txin.prevout.n));
+ in.push_back(Pair("prevout", prevout));
+ switch (decomposeScript) {
+ case DM_NONE:
+ break;
+ case DM_HEX:
+ in.push_back(Pair("scriptSig", HexStr(txin.scriptSig.begin(), txin.scriptSig.end())));
+ break;
+ case DM_ASM:
+ in.push_back(Pair("scriptSig", txin.scriptSig.ToString()));
+ break;
+ case DM_OBJ:
+ {
+ Object o;
+ ScriptSigToJSON(txin, o);
+ in.push_back(Pair("scriptSig", o));
+ break;
+ }
+ default:
+ throw JSONRPCError(-18, "Invalid script decomposition");
+ }
+ }
+ in.push_back(Pair("sequence", (boost::int64_t)txin.nSequence));
+ vin.push_back(in);
+ }
+ entry.push_back(Pair("vin", vin));
+ Array vout;
+ BOOST_FOREACH(const CTxOut& txout, tx.vout)
+ {
+ Object out;
+ out.push_back(Pair("value", ValueFromAmount(txout.nValue)));
+ switch (decomposeScript) {
+ case DM_NONE:
+ break;
+ case DM_HEX:
+ out.push_back(Pair("scriptPubKey", HexStr(txout.scriptPubKey.begin(), txout.scriptPubKey.end())));
+ break;
+ case DM_ASM:
+ out.push_back(Pair("scriptPubKey", txout.scriptPubKey.ToString()));
+ break;
+ case DM_OBJ:
+ {
+ Object o;
+ ScriptPubKeyToJSON(txout.scriptPubKey, o);
+ out.push_back(Pair("scriptPubKey", o));
+ break;
+ }
+ default:
+ throw JSONRPCError(-18, "Invalid script decomposition");
+ }
+ vout.push_back(out);
+ }
+ entry.push_back(Pair("vout", vout));
+}
+
+void AnyTxToJSON(const uint256 hash, const CTransaction* ptx, Object& entry, const Object& decompositions);
+
string AccountFromValue(const Value& value)
{
string strAccount = value.get_str();
@@ -134,10 +315,13 @@ string AccountFromValue(const Value& value)
return strAccount;
}
-Object blockToJSON(const CBlock& block, const CBlockIndex* blockindex)
+Object blockToJSON(const CBlock& block, const CBlockIndex* blockindex, const Object& decompositions)
{
Object result;
result.push_back(Pair("hash", block.GetHash().GetHex()));
+ CMerkleTx txGen(block.vtx[0]);
+ txGen.SetMerkleBranch(&block);
+ result.push_back(Pair("confirmations", (int)txGen.GetDepthInMainChain()));
result.push_back(Pair("size", (int)::GetSerializeSize(block, SER_NETWORK, PROTOCOL_VERSION)));
result.push_back(Pair("height", blockindex->nHeight));
result.push_back(Pair("version", block.nVersion));
@@ -146,10 +330,38 @@ Object blockToJSON(const CBlock& block, const CBlockIndex* blockindex)
result.push_back(Pair("nonce", (boost::uint64_t)block.nNonce));
result.push_back(Pair("bits", HexBits(block.nBits)));
result.push_back(Pair("difficulty", GetDifficulty(blockindex)));
- Array txhashes;
- BOOST_FOREACH (const CTransaction&tx, block.vtx)
- txhashes.push_back(tx.GetHash().GetHex());
- result.push_back(Pair("tx", txhashes));
+
+ enum DecomposeMode decomposeTxn = FindDecompose(decompositions, "tx", "hash");
+ if (decomposeTxn)
+ {
+ Array txs;
+ switch (decomposeTxn) {
+ case DM_OBJ:
+ BOOST_FOREACH (const CTransaction&tx, block.vtx)
+ {
+ Object entry;
+ AnyTxToJSON(tx.GetHash(), &tx, entry, decompositions);
+ txs.push_back(entry);
+ }
+ break;
+ case DM_HEX:
+ BOOST_FOREACH (const CTransaction&tx, block.vtx)
+ {
+ CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION);
+ ssTx << tx;
+
+ txs.push_back(HexStr(ssTx.begin(), ssTx.end()));
+ }
+ break;
+ case DM_HASH:
+ BOOST_FOREACH (const CTransaction&tx, block.vtx)
+ txs.push_back(tx.GetHash().GetHex());
+ break;
+ default:
+ throw JSONRPCError(-18, "Invalid transaction decomposition");
+ }
+ result.push_back(Pair("tx", txs));
+ }
if (blockindex->pprev)
result.push_back(Pair("previousblockhash", blockindex->pprev->GetBlockHash().GetHex()));
@@ -160,6 +372,7 @@ Object blockToJSON(const CBlock& block, const CBlockIndex* blockindex)
+
///
/// Note: This interface may still be subject to change.
///
@@ -173,10 +386,7 @@ string CRPCTable::help(string strCommand) const
const CRPCCommand *pcmd = mi->second;
string strMethod = mi->first;
// We already filter duplicates, but these deprecated screw up the sort order
- if (strMethod == "getamountreceived" ||
- strMethod == "getallreceived" ||
- strMethod == "getblocknumber" || // deprecated
- (strMethod.find("label") != string::npos))
+ if (strMethod.find("label") != string::npos)
continue;
if (strCommand != "" && strMethod != strCommand)
continue;
@@ -223,10 +433,10 @@ Value stop(const Array& params, bool fHelp)
if (fHelp || params.size() != 0)
throw runtime_error(
"stop\n"
- "Stop bitcoin server.");
+ "Stop Bitcoin server.");
// Shutdown will take long enough that the response should get back
- QueueShutdown();
- return "bitcoin server stopping";
+ uiInterface.QueueShutdown();
+ return "Bitcoin server stopping";
}
@@ -241,18 +451,6 @@ Value getblockcount(const Array& params, bool fHelp)
}
-// deprecated
-Value getblocknumber(const Array& params, bool fHelp)
-{
- if (fHelp || params.size() != 0)
- throw runtime_error(
- "getblocknumber\n"
- "Deprecated. Use getblockcount.");
-
- return nBestHeight;
-}
-
-
Value getconnectioncount(const Array& params, bool fHelp)
{
if (fHelp || params.size() != 0)
@@ -379,7 +577,7 @@ Value getnewaddress(const Array& params, bool fHelp)
if (fHelp || params.size() > 1)
throw runtime_error(
"getnewaddress [account]\n"
- "Returns a new bitcoin address for receiving payments. "
+ "Returns a new Bitcoin address for receiving payments. "
"If [account] is specified (recommended), it is added to the address book "
"so payments received with the address will be credited to [account].");
@@ -446,7 +644,7 @@ Value getaccountaddress(const Array& params, bool fHelp)
if (fHelp || params.size() != 1)
throw runtime_error(
"getaccountaddress <account>\n"
- "Returns the current bitcoin address for receiving payments to this account.");
+ "Returns the current Bitcoin address for receiving payments to this account.");
// Parse the account first so we don't generate a key if there's an error
string strAccount = AccountFromValue(params[0]);
@@ -469,7 +667,7 @@ Value setaccount(const Array& params, bool fHelp)
CBitcoinAddress address(params[0].get_str());
if (!address.IsValid())
- throw JSONRPCError(-5, "Invalid bitcoin address");
+ throw JSONRPCError(-5, "Invalid Bitcoin address");
string strAccount;
@@ -499,7 +697,7 @@ Value getaccount(const Array& params, bool fHelp)
CBitcoinAddress address(params[0].get_str());
if (!address.IsValid())
- throw JSONRPCError(-5, "Invalid bitcoin address");
+ throw JSONRPCError(-5, "Invalid Bitcoin address");
string strAccount;
map<CBitcoinAddress, string>::iterator mi = pwalletMain->mapAddressBook.find(address);
@@ -548,19 +746,15 @@ Value settxfee(const Array& params, bool fHelp)
Value sendtoaddress(const Array& params, bool fHelp)
{
- if (pwalletMain->IsCrypted() && (fHelp || params.size() < 2 || params.size() > 4))
- throw runtime_error(
- "sendtoaddress <bitcoinaddress> <amount> [comment] [comment-to]\n"
- "<amount> is a real and is rounded to the nearest 0.00000001\n"
- "requires wallet passphrase to be set with walletpassphrase first");
- if (!pwalletMain->IsCrypted() && (fHelp || params.size() < 2 || params.size() > 4))
+ if (fHelp || params.size() < 2 || params.size() > 4)
throw runtime_error(
"sendtoaddress <bitcoinaddress> <amount> [comment] [comment-to]\n"
- "<amount> is a real and is rounded to the nearest 0.00000001");
+ "<amount> is a real and is rounded to the nearest 0.00000001"
+ + HelpRequiringPassphrase());
CBitcoinAddress address(params[0].get_str());
if (!address.IsValid())
- throw JSONRPCError(-5, "Invalid bitcoin address");
+ throw JSONRPCError(-5, "Invalid Bitcoin address");
// Amount
int64 nAmount = AmountFromValue(params[1]);
@@ -589,8 +783,7 @@ Value signmessage(const Array& params, bool fHelp)
"signmessage <bitcoinaddress> <message>\n"
"Sign a message with the private key of an address");
- if (pwalletMain->IsLocked())
- throw JSONRPCError(-13, "Error: Please enter the wallet passphrase with walletpassphrase first.");
+ EnsureWalletIsUnlocked();
string strAddress = params[0].get_str();
string strMessage = params[1].get_str();
@@ -658,7 +851,7 @@ Value getreceivedbyaddress(const Array& params, bool fHelp)
CBitcoinAddress address = CBitcoinAddress(params[0].get_str());
CScript scriptPubKey;
if (!address.IsValid())
- throw JSONRPCError(-5, "Invalid bitcoin address");
+ throw JSONRPCError(-5, "Invalid Bitcoin address");
scriptPubKey.SetBitcoinAddress(address);
if (!IsMine(*pwalletMain,scriptPubKey))
return (double)0.0;
@@ -839,7 +1032,8 @@ Value movecmd(const Array& params, bool fHelp)
strComment = params[4].get_str();
CWalletDB walletdb(pwalletMain->strWalletFile);
- walletdb.TxnBegin();
+ if (!walletdb.TxnBegin())
+ throw JSONRPCError(-20, "database error");
int64 nNow = GetAdjustedTime();
@@ -861,7 +1055,8 @@ Value movecmd(const Array& params, bool fHelp)
credit.strComment = strComment;
walletdb.WriteAccountingEntry(credit);
- walletdb.TxnCommit();
+ if (!walletdb.TxnCommit())
+ throw JSONRPCError(-20, "database error");
return true;
}
@@ -869,20 +1064,16 @@ Value movecmd(const Array& params, bool fHelp)
Value sendfrom(const Array& params, bool fHelp)
{
- if (pwalletMain->IsCrypted() && (fHelp || params.size() < 3 || params.size() > 6))
+ if (fHelp || params.size() < 3 || params.size() > 6)
throw runtime_error(
"sendfrom <fromaccount> <tobitcoinaddress> <amount> [minconf=1] [comment] [comment-to]\n"
- "<amount> is a real and is rounded to the nearest 0.00000001\n"
- "requires wallet passphrase to be set with walletpassphrase first");
- if (!pwalletMain->IsCrypted() && (fHelp || params.size() < 3 || params.size() > 6))
- throw runtime_error(
- "sendfrom <fromaccount> <tobitcoinaddress> <amount> [minconf=1] [comment] [comment-to]\n"
- "<amount> is a real and is rounded to the nearest 0.00000001");
+ "<amount> is a real and is rounded to the nearest 0.00000001"
+ + HelpRequiringPassphrase());
string strAccount = AccountFromValue(params[0]);
CBitcoinAddress address(params[1].get_str());
if (!address.IsValid())
- throw JSONRPCError(-5, "Invalid bitcoin address");
+ throw JSONRPCError(-5, "Invalid Bitcoin address");
int64 nAmount = AmountFromValue(params[2]);
int nMinDepth = 1;
if (params.size() > 3)
@@ -895,8 +1086,7 @@ Value sendfrom(const Array& params, bool fHelp)
if (params.size() > 5 && params[5].type() != null_type && !params[5].get_str().empty())
wtx.mapValue["to"] = params[5].get_str();
- if (pwalletMain->IsLocked())
- throw JSONRPCError(-13, "Error: Please enter the wallet passphrase with walletpassphrase first.");
+ EnsureWalletIsUnlocked();
// Check funds
int64 nBalance = GetAccountBalance(strAccount, nMinDepth);
@@ -914,15 +1104,11 @@ Value sendfrom(const Array& params, bool fHelp)
Value sendmany(const Array& params, bool fHelp)
{
- if (pwalletMain->IsCrypted() && (fHelp || params.size() < 2 || params.size() > 4))
+ if (fHelp || params.size() < 2 || params.size() > 4)
throw runtime_error(
"sendmany <fromaccount> {address:amount,...} [minconf=1] [comment]\n"
- "amounts are double-precision floating point numbers\n"
- "requires wallet passphrase to be set with walletpassphrase first");
- if (!pwalletMain->IsCrypted() && (fHelp || params.size() < 2 || params.size() > 4))
- throw runtime_error(
- "sendmany <fromaccount> {address:amount,...} [minconf=1] [comment]\n"
- "amounts are double-precision floating point numbers");
+ "amounts are double-precision floating point numbers"
+ + HelpRequiringPassphrase());
string strAccount = AccountFromValue(params[0]);
Object sendTo = params[1].get_obj();
@@ -943,7 +1129,7 @@ Value sendmany(const Array& params, bool fHelp)
{
CBitcoinAddress address(s.name_);
if (!address.IsValid())
- throw JSONRPCError(-5, string("Invalid bitcoin address:")+s.name_);
+ throw JSONRPCError(-5, string("Invalid Bitcoin address:")+s.name_);
if (setAddress.count(address))
throw JSONRPCError(-8, string("Invalid parameter, duplicated address: ")+s.name_);
@@ -957,8 +1143,7 @@ Value sendmany(const Array& params, bool fHelp)
vecSend.push_back(make_pair(scriptPubKey, nAmount));
}
- if (pwalletMain->IsLocked())
- throw JSONRPCError(-13, "Error: Please enter the wallet passphrase with walletpassphrase first.");
+ EnsureWalletIsUnlocked();
// Check funds
int64 nBalance = GetAccountBalance(strAccount, nMinDepth);
@@ -987,7 +1172,7 @@ Value addmultisigaddress(const Array& params, bool fHelp)
{
string msg = "addmultisigaddress <nrequired> <'[\"key\",\"key\"]'> [account]\n"
"Add a nrequired-to-sign multisignature address to the wallet\"\n"
- "each key is a bitcoin address or hex-encoded public key\n"
+ "each key is a Bitcoin address or hex-encoded public key\n"
"If [account] is specified, assign address to [account].";
throw runtime_error(msg);
}
@@ -999,17 +1184,19 @@ Value addmultisigaddress(const Array& params, bool fHelp)
strAccount = AccountFromValue(params[2]);
// Gather public keys
- if ((nRequired < 1) || ((int)keys.size() < nRequired))
+ if (nRequired < 1)
+ throw runtime_error("a multisignature address must require at least one key to redeem");
+ if ((int)keys.size() < nRequired)
throw runtime_error(
- strprintf("wrong number of keys"
- "(got %d, need at least %d)", keys.size(), nRequired));
+ strprintf("not enough keys supplied "
+ "(got %d keys, but need at least %d to redeem)", keys.size(), nRequired));
std::vector<CKey> pubkeys;
pubkeys.resize(keys.size());
for (unsigned int i = 0; i < keys.size(); i++)
{
const std::string& ks = keys[i].get_str();
- // Case 1: bitcoin address and we have full public key:
+ // Case 1: Bitcoin address and we have full public key:
CBitcoinAddress address(ks);
if (address.IsValid())
{
@@ -1327,7 +1514,7 @@ Value listtransactions(const Array& params, bool fHelp)
if (pacentry != 0)
AcentryToJSON(*pacentry, strAccount, ret);
- if (ret.size() >= (nCount+nFrom)) break;
+ if ((int)ret.size() >= (nCount+nFrom)) break;
}
// ret is newest to oldest
@@ -1462,11 +1649,69 @@ Value listsinceblock(const Array& params, bool fHelp)
return ret;
}
+void
+AnyTxToJSON(const uint256 hash, const CTransaction* ptx, Object& entry, const Object& decompositions)
+{
+ if (pwalletMain->mapWallet.count(hash))
+ {
+ const CWalletTx& wtx = pwalletMain->mapWallet[hash];
+
+ TxToJSON(wtx, entry, decompositions);
+
+ int64 nCredit = wtx.GetCredit();
+ int64 nDebit = wtx.GetDebit();
+ int64 nNet = nCredit - nDebit;
+ int64 nFee = (wtx.IsFromMe() ? wtx.GetValueOut() - nDebit : 0);
+
+ entry.push_back(Pair("amount", ValueFromAmount(nNet - nFee)));
+ if (wtx.IsFromMe())
+ entry.push_back(Pair("fee", ValueFromAmount(nFee)));
+
+ WalletTxToJSON(wtx, entry);
+
+ Array details;
+ ListTransactions(pwalletMain->mapWallet[hash], "*", 0, false, details);
+ entry.push_back(Pair("details", details));
+ }
+ else
+ {
+ CTransaction tx;
+ uint256 hashBlock = 0;
+ if ((!ptx) && GetTransaction(hash, tx, hashBlock))
+ ptx = &tx;
+ if (ptx)
+ {
+ entry.push_back(Pair("txid", hash.GetHex()));
+ TxToJSON(*ptx, entry, decompositions);
+ if (hashBlock == 0)
+ entry.push_back(Pair("confirmations", 0));
+ else
+ {
+ entry.push_back(Pair("blockhash", hashBlock.GetHex()));
+ map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hashBlock);
+ if (mi != mapBlockIndex.end() && (*mi).second)
+ {
+ CBlockIndex* pindex = (*mi).second;
+ if (pindex->IsInMainChain())
+ {
+ entry.push_back(Pair("confirmations", 1 + nBestHeight - pindex->nHeight));
+ entry.push_back(Pair("time", (boost::int64_t)pindex->nTime));
+ }
+ else
+ entry.push_back(Pair("confirmations", 0));
+ }
+ }
+ }
+ else
+ throw JSONRPCError(-5, "No information available about transaction");
+ }
+}
+
Value gettransaction(const Array& params, bool fHelp)
{
- if (fHelp || params.size() != 1)
+ if (fHelp || params.size() < 1 || params.size() > 2)
throw runtime_error(
- "gettransaction <txid>\n"
+ "gettransaction <txid> [decompositions]\n"
"Get detailed information about <txid>");
uint256 hash;
@@ -1474,24 +1719,8 @@ Value gettransaction(const Array& params, bool fHelp)
Object entry;
- if (!pwalletMain->mapWallet.count(hash))
- throw JSONRPCError(-5, "Invalid or non-wallet transaction id");
- const CWalletTx& wtx = pwalletMain->mapWallet[hash];
-
- int64 nCredit = wtx.GetCredit();
- int64 nDebit = wtx.GetDebit();
- int64 nNet = nCredit - nDebit;
- int64 nFee = (wtx.IsFromMe() ? wtx.GetValueOut() - nDebit : 0);
-
- entry.push_back(Pair("amount", ValueFromAmount(nNet - nFee)));
- if (wtx.IsFromMe())
- entry.push_back(Pair("fee", ValueFromAmount(nFee)));
-
- WalletTxToJSON(pwalletMain->mapWallet[hash], entry);
-
- Array details;
- ListTransactions(pwalletMain->mapWallet[hash], "*", 0, false, details);
- entry.push_back(Pair("details", details));
+ AnyTxToJSON(hash, NULL, entry,
+ (params.size() > 1) ? params[1].get_obj() : emptyobj);
return entry;
}
@@ -1513,17 +1742,13 @@ Value backupwallet(const Array& params, bool fHelp)
Value keypoolrefill(const Array& params, bool fHelp)
{
- if (pwalletMain->IsCrypted() && (fHelp || params.size() > 0))
- throw runtime_error(
- "keypoolrefill\n"
- "Fills the keypool, requires wallet passphrase to be set.");
- if (!pwalletMain->IsCrypted() && (fHelp || params.size() > 0))
+ if (fHelp || params.size() > 0)
throw runtime_error(
"keypoolrefill\n"
- "Fills the keypool.");
+ "Fills the keypool."
+ + HelpRequiringPassphrase());
- if (pwalletMain->IsLocked())
- throw JSONRPCError(-13, "Error: Please enter the wallet passphrase with walletpassphrase first.");
+ EnsureWalletIsUnlocked();
pwalletMain->TopUpKeyPool();
@@ -1703,8 +1928,8 @@ Value encryptwallet(const Array& params, bool fHelp)
// BDB seems to have a bad habit of writing old data into
// slack space in .dat files; that is bad if the old data is
// unencrypted private keys. So:
- QueueShutdown();
- return "wallet encrypted; bitcoin server stopping, restart to run with encrypted wallet";
+ uiInterface.QueueShutdown();
+ return "wallet encrypted; Bitcoin server stopping, restart to run with encrypted wallet";
}
@@ -1781,7 +2006,7 @@ Value getwork(const Array& params, bool fHelp)
throw JSONRPCError(-10, "Bitcoin is downloading blocks...");
typedef map<uint256, pair<CBlock*, CScript> > mapNewBlock_t;
- static mapNewBlock_t mapNewBlock;
+ static mapNewBlock_t mapNewBlock; // FIXME: thread safety
static vector<CBlock*> vNewBlock;
static CReserveKey reservekey(pwalletMain);
@@ -1973,9 +2198,9 @@ Value getblockhash(const Array& params, bool fHelp)
Value getblock(const Array& params, bool fHelp)
{
- if (fHelp || params.size() != 1)
+ if (fHelp || params.size() < 1 || params.size() > 2)
throw runtime_error(
- "getblock <hash>\n"
+ "getblock <hash> [decompositions]\n"
"Returns details of a block with given block-hash.");
std::string strHash = params[0].get_str();
@@ -1988,7 +2213,8 @@ Value getblock(const Array& params, bool fHelp)
CBlockIndex* pblockindex = mapBlockIndex[hash];
block.ReadFromDisk(pblockindex, true);
- return blockToJSON(block, pblockindex);
+ return blockToJSON(block, pblockindex,
+ (params.size() > 1) ? params[1].get_obj() : emptyobj);
}
@@ -2012,7 +2238,6 @@ static const CRPCCommand vRPCCommands[] =
{ "help", &help, true },
{ "stop", &stop, true },
{ "getblockcount", &getblockcount, true },
- { "getblocknumber", &getblocknumber, true },
{ "getconnectioncount", &getconnectioncount, true },
{ "getdifficulty", &getdifficulty, true },
{ "getgenerate", &getgenerate, true },
@@ -2114,7 +2339,7 @@ string rfc1123Time()
return string(buffer);
}
-static string HTTPReply(int nStatus, const string& strMsg)
+static string HTTPReply(int nStatus, const string& strMsg, bool keepalive)
{
if (nStatus == 401)
return strprintf("HTTP/1.0 401 Authorization Required\r\n"
@@ -2143,7 +2368,7 @@ static string HTTPReply(int nStatus, const string& strMsg)
return strprintf(
"HTTP/1.1 %d %s\r\n"
"Date: %s\r\n"
- "Connection: close\r\n"
+ "Connection: %s\r\n"
"Content-Length: %d\r\n"
"Content-Type: application/json\r\n"
"Server: bitcoin-json-rpc/%s\r\n"
@@ -2152,12 +2377,13 @@ static string HTTPReply(int nStatus, const string& strMsg)
nStatus,
cStatus,
rfc1123Time().c_str(),
+ keepalive ? "keep-alive" : "close",
strMsg.size(),
FormatFullVersion().c_str(),
strMsg.c_str());
}
-int ReadHTTPStatus(std::basic_istream<char>& stream)
+int ReadHTTPStatus(std::basic_istream<char>& stream, int &proto)
{
string str;
getline(stream, str);
@@ -2165,6 +2391,10 @@ int ReadHTTPStatus(std::basic_istream<char>& stream)
boost::split(vWords, str, boost::is_any_of(" "));
if (vWords.size() < 2)
return 500;
+ proto = 0;
+ const char *ver = strstr(str.c_str(), "HTTP/1.");
+ if (ver != NULL)
+ proto = atoi(ver+7);
return atoi(vWords[1].c_str());
}
@@ -2199,7 +2429,8 @@ int ReadHTTP(std::basic_istream<char>& stream, map<string, string>& mapHeadersRe
strMessageRet = "";
// Read status
- int nStatus = ReadHTTPStatus(stream);
+ int nProto = 0;
+ int nStatus = ReadHTTPStatus(stream, nProto);
// Read header
int nLen = ReadHTTPHeader(stream, mapHeadersRet);
@@ -2214,6 +2445,16 @@ int ReadHTTP(std::basic_istream<char>& stream, map<string, string>& mapHeadersRe
strMessageRet = string(vch.begin(), vch.end());
}
+ string sConHdr = mapHeadersRet["connection"];
+
+ if ((sConHdr != "close") && (sConHdr != "keep-alive"))
+ {
+ if (nProto >= 1)
+ mapHeadersRet["connection"] = "keep-alive";
+ else
+ mapHeadersRet["connection"] = "close";
+ }
+
return nStatus;
}
@@ -2266,7 +2507,7 @@ void ErrorReply(std::ostream& stream, const Object& objError, const Value& id)
if (code == -32600) nStatus = 400;
else if (code == -32601) nStatus = 404;
string strReply = JSONRPCReply(Value::null, objError, id);
- stream << HTTPReply(nStatus, strReply) << std::flush;
+ stream << HTTPReply(nStatus, strReply, false) << std::flush;
}
bool ClientAllowed(const string& strAddress)
@@ -2332,23 +2573,37 @@ private:
SSLStream& stream;
};
+class AcceptedConnection
+{
+ public:
+ SSLStream sslStream;
+ SSLIOStreamDevice d;
+ iostreams::stream<SSLIOStreamDevice> stream;
+
+ ip::tcp::endpoint peer;
+
+ AcceptedConnection(asio::io_service &io_service, ssl::context &context,
+ bool fUseSSL) : sslStream(io_service, context), d(sslStream, fUseSSL),
+ stream(d) { ; }
+};
+
void ThreadRPCServer(void* parg)
{
IMPLEMENT_RANDOMIZE_STACK(ThreadRPCServer(parg));
try
{
- vnThreadsRunning[THREAD_RPCSERVER]++;
+ vnThreadsRunning[THREAD_RPCLISTENER]++;
ThreadRPCServer2(parg);
- vnThreadsRunning[THREAD_RPCSERVER]--;
+ vnThreadsRunning[THREAD_RPCLISTENER]--;
}
catch (std::exception& e) {
- vnThreadsRunning[THREAD_RPCSERVER]--;
+ vnThreadsRunning[THREAD_RPCLISTENER]--;
PrintException(&e, "ThreadRPCServer()");
} catch (...) {
- vnThreadsRunning[THREAD_RPCSERVER]--;
+ vnThreadsRunning[THREAD_RPCLISTENER]--;
PrintException(NULL, "ThreadRPCServer()");
}
- printf("ThreadRPCServer exiting\n");
+ printf("ThreadRPCServer exited\n");
}
void ThreadRPCServer2(void* parg)
@@ -2365,7 +2620,7 @@ void ThreadRPCServer2(void* parg)
strWhatAmI = strprintf(_("To use the %s option"), "\"-server\"");
else if (mapArgs.count("-daemon"))
strWhatAmI = strprintf(_("To use the %s option"), "\"-daemon\"");
- ThreadSafeMessageBox(strprintf(
+ uiInterface.ThreadSafeMessageBox(strprintf(
_("%s, you must set a rpcpassword in the configuration file:\n %s\n"
"It is recommended you use the following random password:\n"
"rpcuser=bitcoinrpc\n"
@@ -2375,8 +2630,8 @@ void ThreadRPCServer2(void* parg)
strWhatAmI.c_str(),
GetConfigFile().string().c_str(),
EncodeBase58(&rand_pwd[0],&rand_pwd[0]+32).c_str()),
- _("Error"), wxOK | wxMODAL);
- QueueShutdown();
+ _("Error"), CClientUIInterface::OK | CClientUIInterface::MODAL);
+ uiInterface.QueueShutdown();
return;
}
@@ -2395,9 +2650,9 @@ void ThreadRPCServer2(void* parg)
}
catch(boost::system::system_error &e)
{
- ThreadSafeMessageBox(strprintf(_("An error occured while setting up the RPC port %i for listening: %s"), endpoint.port(), e.what()),
- _("Error"), wxOK | wxMODAL);
- QueueShutdown();
+ uiInterface.ThreadSafeMessageBox(strprintf(_("An error occured while setting up the RPC port %i for listening: %s"), endpoint.port(), e.what()),
+ _("Error"), CClientUIInterface::OK | CClientUIInterface::MODAL);
+ uiInterface.QueueShutdown();
return;
}
@@ -2423,55 +2678,78 @@ void ThreadRPCServer2(void* parg)
loop
{
// Accept connection
- SSLStream sslStream(io_service, context);
- SSLIOStreamDevice d(sslStream, fUseSSL);
- iostreams::stream<SSLIOStreamDevice> stream(d);
-
- ip::tcp::endpoint peer;
- vnThreadsRunning[THREAD_RPCSERVER]--;
- acceptor.accept(sslStream.lowest_layer(), peer);
- vnThreadsRunning[4]++;
+ AcceptedConnection *conn =
+ new AcceptedConnection(io_service, context, fUseSSL);
+
+ vnThreadsRunning[THREAD_RPCLISTENER]--;
+ acceptor.accept(conn->sslStream.lowest_layer(), conn->peer);
+ vnThreadsRunning[THREAD_RPCLISTENER]++;
+
if (fShutdown)
+ {
+ delete conn;
return;
+ }
- // Restrict callers by IP
- if (!ClientAllowed(peer.address().to_string()))
+ // Restrict callers by IP. It is important to
+ // do this before starting client thread, to filter out
+ // certain DoS and misbehaving clients.
+ if (!ClientAllowed(conn->peer.address().to_string()))
{
// Only send a 403 if we're not using SSL to prevent a DoS during the SSL handshake.
if (!fUseSSL)
- stream << HTTPReply(403, "") << std::flush;
- continue;
+ conn->stream << HTTPReply(403, "", false) << std::flush;
+ delete conn;
+ }
+
+ // start HTTP client thread
+ else if (!CreateThread(ThreadRPCServer3, conn)) {
+ printf("Failed to create RPC server client thread\n");
+ delete conn;
}
+ }
+}
+
+void ThreadRPCServer3(void* parg)
+{
+ IMPLEMENT_RANDOMIZE_STACK(ThreadRPCServer3(parg));
+ vnThreadsRunning[THREAD_RPCHANDLER]++;
+ AcceptedConnection *conn = (AcceptedConnection *) parg;
+ bool fRun = true;
+ loop {
+ if (fShutdown || !fRun)
+ {
+ conn->stream.close();
+ delete conn;
+ --vnThreadsRunning[THREAD_RPCHANDLER];
+ return;
+ }
map<string, string> mapHeaders;
string strRequest;
- boost::thread api_caller(ReadHTTP, boost::ref(stream), boost::ref(mapHeaders), boost::ref(strRequest));
- if (!api_caller.timed_join(boost::posix_time::seconds(GetArg("-rpctimeout", 30))))
- { // Timed out:
- acceptor.cancel();
- printf("ThreadRPCServer ReadHTTP timeout\n");
- continue;
- }
+ ReadHTTP(conn->stream, mapHeaders, strRequest);
// Check authorization
if (mapHeaders.count("authorization") == 0)
{
- stream << HTTPReply(401, "") << std::flush;
- continue;
+ conn->stream << HTTPReply(401, "", false) << std::flush;
+ break;
}
if (!HTTPAuthorized(mapHeaders))
{
- printf("ThreadRPCServer incorrect password attempt from %s\n",peer.address().to_string().c_str());
+ printf("ThreadRPCServer incorrect password attempt from %s\n", conn->peer.address().to_string().c_str());
/* Deter brute-forcing short passwords.
If this results in a DOS the user really
shouldn't have their RPC port exposed.*/
if (mapArgs["-rpcpassword"].size() < 20)
Sleep(250);
- stream << HTTPReply(401, "") << std::flush;
- continue;
+ conn->stream << HTTPReply(401, "", false) << std::flush;
+ break;
}
+ if (mapHeaders["connection"] == "close")
+ fRun = false;
Value id = Value::null;
try
@@ -2505,47 +2783,56 @@ void ThreadRPCServer2(void* parg)
else
throw JSONRPCError(-32600, "Params must be an array");
- // Find method
- const CRPCCommand *pcmd = tableRPC[strMethod];
- if (!pcmd)
- throw JSONRPCError(-32601, "Method not found");
-
- // Observe safe mode
- string strWarning = GetWarnings("rpc");
- if (strWarning != "" && !GetBoolArg("-disablesafemode") &&
- !pcmd->okSafeMode)
- throw JSONRPCError(-2, string("Safe mode: ") + strWarning);
-
- try
- {
- // Execute
- Value result;
- {
- LOCK2(cs_main, pwalletMain->cs_wallet);
- result = pcmd->actor(params, false);
- }
+ Value result = tableRPC.execute(strMethod, params);
- // Send reply
- string strReply = JSONRPCReply(result, Value::null, id);
- stream << HTTPReply(200, strReply) << std::flush;
- }
- catch (std::exception& e)
- {
- ErrorReply(stream, JSONRPCError(-1, e.what()), id);
- }
+ // Send reply
+ string strReply = JSONRPCReply(result, Value::null, id);
+ conn->stream << HTTPReply(200, strReply, fRun) << std::flush;
}
catch (Object& objError)
{
- ErrorReply(stream, objError, id);
+ ErrorReply(conn->stream, objError, id);
+ break;
}
catch (std::exception& e)
{
- ErrorReply(stream, JSONRPCError(-32700, e.what()), id);
+ ErrorReply(conn->stream, JSONRPCError(-32700, e.what()), id);
+ break;
}
}
+
+ delete conn;
+ vnThreadsRunning[THREAD_RPCHANDLER]--;
}
+json_spirit::Value CRPCTable::execute(const std::string &strMethod, const json_spirit::Array &params) const
+{
+ // Find method
+ const CRPCCommand *pcmd = tableRPC[strMethod];
+ if (!pcmd)
+ throw JSONRPCError(-32601, "Method not found");
+ // Observe safe mode
+ string strWarning = GetWarnings("rpc");
+ if (strWarning != "" && !GetBoolArg("-disablesafemode") &&
+ !pcmd->okSafeMode)
+ throw JSONRPCError(-2, string("Safe mode: ") + strWarning);
+
+ try
+ {
+ // Execute
+ Value result;
+ {
+ LOCK2(cs_main, pwalletMain->cs_wallet);
+ result = pcmd->actor(params, false);
+ }
+ return result;
+ }
+ catch (std::exception& e)
+ {
+ throw JSONRPCError(-1, e.what());
+ }
+}
Object CallRPC(const string& strMethod, const Array& params)
@@ -2619,6 +2906,62 @@ void ConvertTo(Value& value)
}
}
+// Convert strings to command-specific RPC representation
+Array RPCConvertValues(const std::string &strMethod, const std::vector<std::string> &strParams)
+{
+ Array params;
+ BOOST_FOREACH(const std::string &param, strParams)
+ params.push_back(param);
+
+ int n = params.size();
+
+ //
+ // Special case non-string parameter types
+ //
+ if (strMethod == "setgenerate" && n > 0) ConvertTo<bool>(params[0]);
+ if (strMethod == "setgenerate" && n > 1) ConvertTo<boost::int64_t>(params[1]);
+ if (strMethod == "sendtoaddress" && n > 1) ConvertTo<double>(params[1]);
+ if (strMethod == "settxfee" && n > 0) ConvertTo<double>(params[0]);
+ if (strMethod == "getreceivedbyaddress" && n > 1) ConvertTo<boost::int64_t>(params[1]);
+ if (strMethod == "getreceivedbyaccount" && n > 1) ConvertTo<boost::int64_t>(params[1]);
+ if (strMethod == "listreceivedbyaddress" && n > 0) ConvertTo<boost::int64_t>(params[0]);
+ if (strMethod == "listreceivedbyaddress" && n > 1) ConvertTo<bool>(params[1]);
+ if (strMethod == "listreceivedbyaccount" && n > 0) ConvertTo<boost::int64_t>(params[0]);
+ if (strMethod == "listreceivedbyaccount" && n > 1) ConvertTo<bool>(params[1]);
+ if (strMethod == "getbalance" && n > 1) ConvertTo<boost::int64_t>(params[1]);
+ if (strMethod == "getblock" && n > 1) ConvertTo<Object>(params[1]);
+ if (strMethod == "getblockhash" && n > 0) ConvertTo<boost::int64_t>(params[0]);
+ if (strMethod == "gettransaction" && n > 1) ConvertTo<Object>(params[1]);
+ if (strMethod == "move" && n > 2) ConvertTo<double>(params[2]);
+ if (strMethod == "move" && n > 3) ConvertTo<boost::int64_t>(params[3]);
+ if (strMethod == "sendfrom" && n > 2) ConvertTo<double>(params[2]);
+ if (strMethod == "sendfrom" && n > 3) ConvertTo<boost::int64_t>(params[3]);
+ if (strMethod == "listtransactions" && n > 1) ConvertTo<boost::int64_t>(params[1]);
+ if (strMethod == "listtransactions" && n > 2) ConvertTo<boost::int64_t>(params[2]);
+ if (strMethod == "listaccounts" && n > 0) ConvertTo<boost::int64_t>(params[0]);
+ if (strMethod == "walletpassphrase" && n > 1) ConvertTo<boost::int64_t>(params[1]);
+ if (strMethod == "listsinceblock" && n > 1) ConvertTo<boost::int64_t>(params[1]);
+ if (strMethod == "sendmany" && n > 1)
+ {
+ string s = params[1].get_str();
+ Value v;
+ if (!read_string(s, v) || v.type() != obj_type)
+ throw runtime_error("type mismatch");
+ params[1] = v.get_obj();
+ }
+ if (strMethod == "sendmany" && n > 2) ConvertTo<boost::int64_t>(params[2]);
+ if (strMethod == "addmultisigaddress" && n > 0) ConvertTo<boost::int64_t>(params[0]);
+ if (strMethod == "addmultisigaddress" && n > 1)
+ {
+ string s = params[1].get_str();
+ Value v;
+ if (!read_string(s, v) || v.type() != array_type)
+ throw runtime_error("type mismatch "+s);
+ params[1] = v.get_array();
+ }
+ return params;
+}
+
int CommandLineRPC(int argc, char *argv[])
{
string strPrint;
@@ -2638,53 +2981,8 @@ int CommandLineRPC(int argc, char *argv[])
string strMethod = argv[1];
// Parameters default to strings
- Array params;
- for (int i = 2; i < argc; i++)
- params.push_back(argv[i]);
- int n = params.size();
-
- //
- // Special case non-string parameter types
- //
- if (strMethod == "setgenerate" && n > 0) ConvertTo<bool>(params[0]);
- if (strMethod == "setgenerate" && n > 1) ConvertTo<boost::int64_t>(params[1]);
- if (strMethod == "sendtoaddress" && n > 1) ConvertTo<double>(params[1]);
- if (strMethod == "settxfee" && n > 0) ConvertTo<double>(params[0]);
- if (strMethod == "getreceivedbyaddress" && n > 1) ConvertTo<boost::int64_t>(params[1]);
- if (strMethod == "getreceivedbyaccount" && n > 1) ConvertTo<boost::int64_t>(params[1]);
- if (strMethod == "listreceivedbyaddress" && n > 0) ConvertTo<boost::int64_t>(params[0]);
- if (strMethod == "listreceivedbyaddress" && n > 1) ConvertTo<bool>(params[1]);
- if (strMethod == "listreceivedbyaccount" && n > 0) ConvertTo<boost::int64_t>(params[0]);
- if (strMethod == "listreceivedbyaccount" && n > 1) ConvertTo<bool>(params[1]);
- if (strMethod == "getbalance" && n > 1) ConvertTo<boost::int64_t>(params[1]);
- if (strMethod == "getblockhash" && n > 0) ConvertTo<boost::int64_t>(params[0]);
- if (strMethod == "move" && n > 2) ConvertTo<double>(params[2]);
- if (strMethod == "move" && n > 3) ConvertTo<boost::int64_t>(params[3]);
- if (strMethod == "sendfrom" && n > 2) ConvertTo<double>(params[2]);
- if (strMethod == "sendfrom" && n > 3) ConvertTo<boost::int64_t>(params[3]);
- if (strMethod == "listtransactions" && n > 1) ConvertTo<boost::int64_t>(params[1]);
- if (strMethod == "listtransactions" && n > 2) ConvertTo<boost::int64_t>(params[2]);
- if (strMethod == "listaccounts" && n > 0) ConvertTo<boost::int64_t>(params[0]);
- if (strMethod == "walletpassphrase" && n > 1) ConvertTo<boost::int64_t>(params[1]);
- if (strMethod == "listsinceblock" && n > 1) ConvertTo<boost::int64_t>(params[1]);
- if (strMethod == "sendmany" && n > 1)
- {
- string s = params[1].get_str();
- Value v;
- if (!read_string(s, v) || v.type() != obj_type)
- throw runtime_error("type mismatch");
- params[1] = v.get_obj();
- }
- if (strMethod == "sendmany" && n > 2) ConvertTo<boost::int64_t>(params[2]);
- if (strMethod == "addmultisigaddress" && n > 0) ConvertTo<boost::int64_t>(params[0]);
- if (strMethod == "addmultisigaddress" && n > 1)
- {
- string s = params[1].get_str();
- Value v;
- if (!read_string(s, v) || v.type() != array_type)
- throw runtime_error("type mismatch "+s);
- params[1] = v.get_array();
- }
+ std::vector<std::string> strParams(&argv[2], &argv[argc]);
+ Array params = RPCConvertValues(strMethod, strParams);
// Execute
Object reply = CallRPC(strMethod, params);
diff --git a/src/bitcoinrpc.h b/src/bitcoinrpc.h
index 6b7293ed19..8b2d905179 100644
--- a/src/bitcoinrpc.h
+++ b/src/bitcoinrpc.h
@@ -1,7 +1,7 @@
// Copyright (c) 2010 Satoshi Nakamoto
// Copyright (c) 2009-2012 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
-// file license.txt or http://www.opensource.org/licenses/mit-license.php.
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifndef _BITCOINRPC_H_
#define _BITCOINRPC_H_ 1
@@ -16,6 +16,9 @@
void ThreadRPCServer(void* parg);
int CommandLineRPC(int argc, char *argv[]);
+/** Convert parameter values for RPC call from strings to command-specific JSON objects. */
+json_spirit::Array RPCConvertValues(const std::string &strMethod, const std::vector<std::string> &strParams);
+
typedef json_spirit::Value(*rpcfn_type)(const json_spirit::Array& params, bool fHelp);
class CRPCCommand
@@ -26,6 +29,9 @@ public:
bool okSafeMode;
};
+/**
+ * Bitcoin RPC command dispatcher.
+ */
class CRPCTable
{
private:
@@ -34,6 +40,15 @@ public:
CRPCTable();
const CRPCCommand* operator[](std::string name) const;
std::string help(std::string name) const;
+
+ /**
+ * Execute a method.
+ * @param method Method to execute
+ * @param params Array of arguments (JSON objects)
+ * @returns Result of the call.
+ * @throws an exception (json_spirit::Value) when an error happens.
+ */
+ json_spirit::Value execute(const std::string &method, const json_spirit::Array &params) const;
};
extern const CRPCTable tableRPC;
diff --git a/src/checkpoints.cpp b/src/checkpoints.cpp
index cf56fa0695..6679bc93d4 100644
--- a/src/checkpoints.cpp
+++ b/src/checkpoints.cpp
@@ -1,6 +1,6 @@
// Copyright (c) 2009-2012 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
-// file license.txt or http://www.opensource.org/licenses/mit-license.php.
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include <boost/assign/list_of.hpp> // for 'map_list_of()'
#include <boost/foreach.hpp>
diff --git a/src/checkpoints.h b/src/checkpoints.h
index 5d3228f3fc..70e936564c 100644
--- a/src/checkpoints.h
+++ b/src/checkpoints.h
@@ -1,6 +1,6 @@
// Copyright (c) 2009-2012 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
-// file license.txt or http://www.opensource.org/licenses/mit-license.php.
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifndef BITCOIN_CHECKPOINT_H
#define BITCOIN_CHECKPOINT_H
diff --git a/src/compat.h b/src/compat.h
index 804a8141b5..79ebb9323a 100644
--- a/src/compat.h
+++ b/src/compat.h
@@ -1,7 +1,7 @@
// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2012 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
-// file license.txt or http://www.opensource.org/licenses/mit-license.php.
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifndef _BITCOIN_COMPAT_H
#define _BITCOIN_COMPAT_H 1
diff --git a/src/db.cpp b/src/db.cpp
index 12647e568a..a0b9dc20f7 100644
--- a/src/db.cpp
+++ b/src/db.cpp
@@ -1,7 +1,7 @@
// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2012 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
-// file license.txt or http://www.opensource.org/licenses/mit-license.php.
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "db.h"
#include "util.h"
@@ -76,6 +76,10 @@ CDB::CDB(const char *pszFile, const char* pszMode) : pdb(NULL)
if (fCreate)
nFlags |= DB_CREATE;
+ unsigned int nEnvFlags = 0;
+ if (GetBoolArg("-privdb", true))
+ nEnvFlags |= DB_PRIVATE;
+
{
LOCK(cs_db);
if (!fDbEnvInit)
@@ -96,6 +100,7 @@ CDB::CDB(const char *pszFile, const char* pszMode) : pdb(NULL)
dbenv.set_lk_max_locks(10000);
dbenv.set_lk_max_objects(10000);
dbenv.set_errfile(fopen(pathErrorFile.string().c_str(), "a")); /// debug
+ dbenv.set_flags(DB_TXN_WRITE_NOSYNC, 1);
dbenv.set_flags(DB_AUTO_COMMIT, 1);
dbenv.log_set_config(DB_LOG_AUTO_REMOVE, 1);
ret = dbenv.open(pathDataDir.string().c_str(),
@@ -105,7 +110,8 @@ CDB::CDB(const char *pszFile, const char* pszMode) : pdb(NULL)
DB_INIT_MPOOL |
DB_INIT_TXN |
DB_THREAD |
- DB_RECOVER,
+ DB_RECOVER |
+ nEnvFlags,
S_IRUSR | S_IWUSR);
if (ret > 0)
throw runtime_error(strprintf("CDB() : error %d opening database environment", ret));
@@ -164,8 +170,6 @@ void CDB::Close()
unsigned int nMinutes = 0;
if (fReadOnly)
nMinutes = 1;
- if (strFile == "addr.dat")
- nMinutes = 2;
if (strFile == "blkindex.dat")
nMinutes = 2;
if (strFile == "blkindex.dat" && IsInitialBlockDownload())
@@ -291,6 +295,7 @@ bool CDB::Rewrite(const string& strFile, const char* pszSkip)
void DBFlush(bool fShutdown)
{
+ int64 nStart = GetTimeMillis();
// Flush log data to the actual data file
// on all files that are not in use
printf("DBFlush(%s)%s\n", fShutdown ? "true" : "false", fDbEnvInit ? "" : " db not started");
@@ -310,7 +315,7 @@ void DBFlush(bool fShutdown)
CloseDb(strFile);
printf("%s checkpoint\n", strFile.c_str());
dbenv.txn_checkpoint(0, 0, 0);
- if ((strFile != "blkindex.dat" && strFile != "addr.dat") || fDetachDB) {
+ if (strFile != "blkindex.dat" || fDetachDB) {
printf("%s detach\n", strFile.c_str());
dbenv.lsn_reset(strFile.c_str(), 0);
}
@@ -320,6 +325,7 @@ void DBFlush(bool fShutdown)
else
mi++;
}
+ printf("DBFlush(%s)%s ended %15"PRI64d"ms\n", fShutdown ? "true" : "false", fDbEnvInit ? "" : " db not started", GetTimeMillis() - nStart);
if (fShutdown)
{
char** listp;
@@ -463,11 +469,6 @@ bool CTxDB::WriteBlockIndex(const CDiskBlockIndex& blockindex)
return Write(make_pair(string("blockindex"), blockindex.GetBlockHash()), blockindex);
}
-bool CTxDB::EraseBlockIndex(uint256 hash)
-{
- return Erase(make_pair(string("blockindex"), hash));
-}
-
bool CTxDB::ReadHashBestChain(uint256& hashBestChain)
{
return Read(string("hashBestChain"), hashBestChain);
@@ -613,7 +614,7 @@ bool CTxDB::LoadBlockIndex()
map<pair<unsigned int, unsigned int>, CBlockIndex*> mapBlockPos;
for (CBlockIndex* pindex = pindexBest; pindex && pindex->pprev; pindex = pindex->pprev)
{
- if (pindex->nHeight < nBestHeight-nCheckDepth)
+ if (fRequestShutdown || pindex->nHeight < nBestHeight-nCheckDepth)
break;
CBlock block;
if (!block.ReadFromDisk(pindex))
@@ -715,7 +716,7 @@ bool CTxDB::LoadBlockIndex()
}
}
}
- if (pindexFork)
+ if (pindexFork && !fRequestShutdown)
{
// Reorg back to the fork
printf("LoadBlockIndex() : *** moving best chain pointer back to block %d\n", pindexFork->nHeight);
@@ -737,65 +738,96 @@ bool CTxDB::LoadBlockIndex()
// CAddrDB
//
-bool CAddrDB::WriteAddrman(const CAddrMan& addrman)
+
+CAddrDB::CAddrDB()
{
- return Write(string("addrman"), addrman);
+ pathAddr = GetDataDir() / "peers.dat";
}
-bool CAddrDB::LoadAddresses()
+bool CAddrDB::Write(const CAddrMan& addr)
{
- if (Read(string("addrman"), addrman))
- {
- printf("Loaded %i addresses\n", addrman.size());
- return true;
+ // Generate random temporary filename
+ unsigned short randv = 0;
+ RAND_bytes((unsigned char *)&randv, sizeof(randv));
+ std::string tmpfn = strprintf("peers.dat.%04x", randv);
+
+ // serialize addresses, checksum data up to that point, then append csum
+ CDataStream ssPeers(SER_DISK, CLIENT_VERSION);
+ ssPeers << FLATDATA(pchMessageStart);
+ ssPeers << addr;
+ uint256 hash = Hash(ssPeers.begin(), ssPeers.end());
+ ssPeers << hash;
+
+ // open temp output file, and associate with CAutoFile
+ boost::filesystem::path pathTmp = GetDataDir() / tmpfn;
+ FILE *file = fopen(pathTmp.string().c_str(), "wb");
+ CAutoFile fileout = CAutoFile(file, SER_DISK, CLIENT_VERSION);
+ if (!fileout)
+ return error("CAddrman::Write() : open failed");
+
+ // Write and commit header, data
+ try {
+ fileout << ssPeers;
}
-
- // Read pre-0.6 addr records
+ catch (std::exception &e) {
+ return error("CAddrman::Write() : I/O error");
+ }
+ FileCommit(fileout);
+ fileout.fclose();
- vector<CAddress> vAddr;
- vector<vector<unsigned char> > vDelete;
+ // replace existing peers.dat, if any, with new peers.dat.XXXX
+ if (!RenameOver(pathTmp, pathAddr))
+ return error("CAddrman::Write() : Rename-into-place failed");
- // Get cursor
- Dbc* pcursor = GetCursor();
- if (!pcursor)
- return false;
-
- loop
- {
- // Read next record
- CDataStream ssKey(SER_DISK, CLIENT_VERSION);
- CDataStream ssValue(SER_DISK, CLIENT_VERSION);
- int ret = ReadAtCursor(pcursor, ssKey, ssValue);
- if (ret == DB_NOTFOUND)
- break;
- else if (ret != 0)
- return false;
+ return true;
+}
- // Unserialize
- string strType;
- ssKey >> strType;
- if (strType == "addr")
- {
- CAddress addr;
- ssValue >> addr;
- vAddr.push_back(addr);
- }
+bool CAddrDB::Read(CAddrMan& addr)
+{
+ // open input file, and associate with CAutoFile
+ FILE *file = fopen(pathAddr.string().c_str(), "rb");
+ CAutoFile filein = CAutoFile(file, SER_DISK, CLIENT_VERSION);
+ if (!filein)
+ return error("CAddrman::Read() : open failed");
+
+ // use file size to size memory buffer
+ int fileSize = GetFilesize(filein);
+ int dataSize = fileSize - sizeof(uint256);
+ vector<unsigned char> vchData;
+ vchData.resize(dataSize);
+ uint256 hashIn;
+
+ // read data and checksum from file
+ try {
+ filein.read((char *)&vchData[0], dataSize);
+ filein >> hashIn;
}
- pcursor->close();
+ catch (std::exception &e) {
+ return error("CAddrman::Read() 2 : I/O error or stream data corrupted");
+ }
+ filein.fclose();
- addrman.Add(vAddr, CNetAddr("0.0.0.0"));
- printf("Loaded %i addresses\n", addrman.size());
+ CDataStream ssPeers(vchData, SER_DISK, CLIENT_VERSION);
- // Note: old records left; we ran into hangs-on-startup
- // bugs for some users who (we think) were running after
- // an unclean shutdown.
+ // verify stored checksum matches input data
+ uint256 hashTmp = Hash(ssPeers.begin(), ssPeers.end());
+ if (hashIn != hashTmp)
+ return error("CAddrman::Read() : checksum mismatch; data corrupted");
- return true;
-}
+ // de-serialize address data
+ unsigned char pchMsgTmp[4];
+ try {
+ ssPeers >> FLATDATA(pchMsgTmp);
+ ssPeers >> addr;
+ }
+ catch (std::exception &e) {
+ return error("CAddrman::Read() : I/O error or stream data corrupted");
+ }
-bool LoadAddresses()
-{
- return CAddrDB("cr+").LoadAddresses();
-}
+ // finally, verify the network matches ours
+ if (memcmp(pchMsgTmp, pchMessageStart, sizeof(pchMsgTmp)))
+ return error("CAddrman::Read() : invalid network magic number");
+ return true;
+}
diff --git a/src/db.h b/src/db.h
index 3ce8f1758f..b8fc4db512 100644
--- a/src/db.h
+++ b/src/db.h
@@ -1,7 +1,7 @@
// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2012 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
-// file license.txt or http://www.opensource.org/licenses/mit-license.php.
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifndef BITCOIN_DB_H
#define BITCOIN_DB_H
@@ -216,7 +216,7 @@ public:
if (!pdb)
return false;
DbTxn* ptxn = NULL;
- int ret = dbenv.txn_begin(GetTxn(), &ptxn, DB_TXN_NOSYNC);
+ int ret = dbenv.txn_begin(GetTxn(), &ptxn, DB_TXN_WRITE_NOSYNC);
if (!ptxn || ret != 0)
return false;
vTxn.push_back(ptxn);
@@ -285,7 +285,6 @@ public:
bool ReadDiskTx(COutPoint outpoint, CTransaction& tx, CTxIndex& txindex);
bool ReadDiskTx(COutPoint outpoint, CTransaction& tx);
bool WriteBlockIndex(const CDiskBlockIndex& blockindex);
- bool EraseBlockIndex(uint256 hash);
bool ReadHashBestChain(uint256& hashBestChain);
bool WriteHashBestChain(uint256 hashBestChain);
bool ReadBestInvalidWork(CBigNum& bnBestInvalidWork);
@@ -296,20 +295,15 @@ public:
-/** Access to the (IP) address database (addr.dat) */
-class CAddrDB : public CDB
+/** Access to the (IP) address database (peers.dat) */
+class CAddrDB
{
-public:
- CAddrDB(const char* pszMode="r+") : CDB("addr.dat", pszMode) { }
private:
- CAddrDB(const CAddrDB&);
- void operator=(const CAddrDB&);
+ boost::filesystem::path pathAddr;
public:
- bool WriteAddrman(const CAddrMan& addr);
- bool LoadAddresses();
+ CAddrDB();
+ bool Write(const CAddrMan& addr);
+ bool Read(CAddrMan& addr);
};
-bool LoadAddresses();
-
-
#endif // BITCOIN_DB_H
diff --git a/src/init.cpp b/src/init.cpp
index 3fe6d1b091..325f8e0c50 100644
--- a/src/init.cpp
+++ b/src/init.cpp
@@ -1,7 +1,7 @@
// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2012 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
-// file license.txt or http://www.opensource.org/licenses/mit-license.php.
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "db.h"
#include "walletdb.h"
#include "bitcoinrpc.h"
@@ -13,6 +13,7 @@
#include <boost/filesystem/fstream.hpp>
#include <boost/filesystem/convenience.hpp>
#include <boost/interprocess/sync/file_lock.hpp>
+#include <boost/algorithm/string/predicate.hpp>
#ifndef WIN32
#include <signal.h>
@@ -22,6 +23,7 @@ using namespace std;
using namespace boost;
CWallet* pwalletMain;
+CClientUIInterface uiInterface;
//////////////////////////////////////////////////////////////////////////////
//
@@ -62,7 +64,7 @@ void Shutdown(void* parg)
delete pwalletMain;
CreateThread(ExitTimeout, NULL);
Sleep(50);
- printf("Bitcoin exiting\n\n");
+ printf("Bitcoin exited\n\n");
fExit = true;
exit(0);
}
@@ -80,6 +82,10 @@ void HandleSIGTERM(int)
fRequestShutdown = true;
}
+void HandleSIGHUP(int)
+{
+ fReopenDebugLog = true;
+}
@@ -90,24 +96,51 @@ void HandleSIGTERM(int)
// Start
//
#if !defined(QT_GUI)
-int main(int argc, char* argv[])
-{
- bool fRet = false;
- fRet = AppInit(argc, argv);
-
- if (fRet && fDaemon)
- return 0;
-
- return 1;
-}
-#endif
-
bool AppInit(int argc, char* argv[])
{
bool fRet = false;
try
{
- fRet = AppInit2(argc, argv);
+ //
+ // Parameters
+ //
+ // If Qt is used, parameters/bitcoin.conf are parsed in qt/bitcoin.cpp's main()
+ ParseParameters(argc, argv);
+ if (!boost::filesystem::is_directory(GetDataDir(false)))
+ {
+ fprintf(stderr, "Error: Specified directory does not exist\n");
+ Shutdown(NULL);
+ }
+ ReadConfigFile(mapArgs, mapMultiArgs);
+
+ if (mapArgs.count("-?") || mapArgs.count("--help"))
+ {
+ // First part of help message is specific to bitcoind / RPC client
+ std::string strUsage = _("Bitcoin version") + " " + FormatFullVersion() + "\n\n" +
+ _("Usage:") + "\n" +
+ " bitcoind [options] " + "\n" +
+ " bitcoind [options] <command> [params] " + _("Send command to -server or bitcoind") + "\n" +
+ " bitcoind [options] help " + _("List commands") + "\n" +
+ " bitcoind [options] help <command> " + _("Get help for a command") + "\n";
+
+ strUsage += "\n" + HelpMessage();
+
+ fprintf(stderr, "%s", strUsage.c_str());
+ return false;
+ }
+
+ // Command-line RPC
+ for (int i = 1; i < argc; i++)
+ if (!IsSwitchChar(argv[i][0]) && !boost::algorithm::istarts_with(argv[i], "bitcoin:"))
+ fCommandLine = true;
+
+ if (fCommandLine)
+ {
+ int ret = CommandLineRPC(argc, argv);
+ exit(ret);
+ }
+
+ fRet = AppInit2();
}
catch (std::exception& e) {
PrintException(&e, "AppInit()");
@@ -119,7 +152,128 @@ bool AppInit(int argc, char* argv[])
return fRet;
}
-bool AppInit2(int argc, char* argv[])
+extern void noui_connect();
+int main(int argc, char* argv[])
+{
+ bool fRet = false;
+
+ // Connect bitcoind signal handlers
+ noui_connect();
+
+ fRet = AppInit(argc, argv);
+
+ if (fRet && fDaemon)
+ return 0;
+
+ return 1;
+}
+#endif
+
+bool static InitError(const std::string &str)
+{
+ uiInterface.ThreadSafeMessageBox(str, _("Bitcoin"), CClientUIInterface::OK | CClientUIInterface::MODAL);
+ return false;
+}
+
+bool static InitWarning(const std::string &str)
+{
+ uiInterface.ThreadSafeMessageBox(str, _("Bitcoin"), CClientUIInterface::OK | CClientUIInterface::ICON_EXCLAMATION | CClientUIInterface::MODAL);
+ return true;
+}
+
+
+bool static Bind(const CService &addr) {
+ if (IsLimited(addr))
+ return false;
+ std::string strError;
+ if (!BindListenPort(addr, strError))
+ return InitError(strError);
+ return true;
+}
+
+// Core-specific options shared between UI and daemon
+std::string HelpMessage()
+{
+ string strUsage = _("Options:") + "\n" +
+ " -conf=<file> " + _("Specify configuration file (default: bitcoin.conf)") + "\n" +
+ " -pid=<file> " + _("Specify pid file (default: bitcoind.pid)") + "\n" +
+ " -gen " + _("Generate coins") + "\n" +
+ " -gen=0 " + _("Don't generate coins") + "\n" +
+ " -datadir=<dir> " + _("Specify data directory") + "\n" +
+ " -dbcache=<n> " + _("Set database cache size in megabytes (default: 25)") + "\n" +
+ " -dblogsize=<n> " + _("Set database disk log size in megabytes (default: 100)") + "\n" +
+ " -timeout=<n> " + _("Specify connection timeout (in milliseconds)") + "\n" +
+ " -proxy=<ip:port> " + _("Connect through socks proxy") + "\n" +
+ " -socks=<n> " + _("Select the version of socks proxy to use (4 or 5, 5 is default)") + "\n" +
+ " -noproxy=<net> " + _("Do not use proxy for connections to network <net> (IPv4 or IPv6)") + "\n" +
+ " -dns " + _("Allow DNS lookups for -addnode, -seednode and -connect") + "\n" +
+ " -proxydns " + _("Pass DNS requests to (SOCKS5) proxy") + "\n" +
+ " -port=<port> " + _("Listen for connections on <port> (default: 8333 or testnet: 18333)") + "\n" +
+ " -maxconnections=<n> " + _("Maintain at most <n> connections to peers (default: 125)") + "\n" +
+ " -addnode=<ip> " + _("Add a node to connect to and attempt to keep the connection open") + "\n" +
+ " -connect=<ip> " + _("Connect only to the specified node") + "\n" +
+ " -seednode=<ip> " + _("Connect to a node to retrieve peer addresses, and disconnect") + "\n" +
+ " -externalip=<ip> " + _("Specify your own public address") + "\n" +
+ " -onlynet=<net> " + _("Only connect to nodes in network <net> (IPv4 or IPv6)") + "\n" +
+ " -discover " + _("Try to discover public IP address (default: 1)") + "\n" +
+ " -irc " + _("Find peers using internet relay chat (default: 0)") + "\n" +
+ " -listen " + _("Accept connections from outside (default: 1)") + "\n" +
+ " -bind=<addr> " + _("Bind to given address. Use [host]:port notation for IPv6") + "\n" +
+ " -dnsseed " + _("Find peers using DNS lookup (default: 1)") + "\n" +
+ " -banscore=<n> " + _("Threshold for disconnecting misbehaving peers (default: 100)") + "\n" +
+ " -bantime=<n> " + _("Number of seconds to keep misbehaving peers from reconnecting (default: 86400)") + "\n" +
+ " -maxreceivebuffer=<n> " + _("Maximum per-connection receive buffer, <n>*1000 bytes (default: 10000)") + "\n" +
+ " -maxsendbuffer=<n> " + _("Maximum per-connection send buffer, <n>*1000 bytes (default: 10000)") + "\n" +
+#ifdef USE_UPNP
+#if USE_UPNP
+ " -upnp " + _("Use Universal Plug and Play to map the listening port (default: 1)") + "\n" +
+#else
+ " -upnp " + _("Use Universal Plug and Play to map the listening port (default: 0)") + "\n" +
+#endif
+#endif
+ " -detachdb " + _("Detach block and address databases. Increases shutdown time (default: 0)") + "\n" +
+ " -paytxfee=<amt> " + _("Fee per KB to add to transactions you send") + "\n" +
+#ifdef QT_GUI
+ " -server " + _("Accept command line and JSON-RPC commands") + "\n" +
+#endif
+#if !defined(WIN32) && !defined(QT_GUI)
+ " -daemon " + _("Run in the background as a daemon and accept commands") + "\n" +
+#endif
+ " -testnet " + _("Use the test network") + "\n" +
+ " -debug " + _("Output extra debugging information") + "\n" +
+ " -logtimestamps " + _("Prepend debug output with timestamp") + "\n" +
+ " -printtoconsole " + _("Send trace/debug info to console instead of debug.log file") + "\n" +
+#ifdef WIN32
+ " -printtodebugger " + _("Send trace/debug info to debugger") + "\n" +
+#endif
+ " -rpcuser=<user> " + _("Username for JSON-RPC connections") + "\n" +
+ " -rpcpassword=<pw> " + _("Password for JSON-RPC connections") + "\n" +
+ " -rpcport=<port> " + _("Listen for JSON-RPC connections on <port> (default: 8332)") + "\n" +
+ " -rpcallowip=<ip> " + _("Allow JSON-RPC connections from specified IP address") + "\n" +
+ " -rpcconnect=<ip> " + _("Send commands to node running on <ip> (default: 127.0.0.1)") + "\n" +
+ " -blocknotify=<cmd> " + _("Execute command when the best block changes (%s in cmd is replaced by block hash)") + "\n" +
+ " -upgradewallet " + _("Upgrade wallet to latest format") + "\n" +
+ " -keypool=<n> " + _("Set key pool size to <n> (default: 100)") + "\n" +
+ " -rescan " + _("Rescan the block chain for missing wallet transactions") + "\n" +
+ " -checkblocks=<n> " + _("How many blocks to check at startup (default: 2500, 0 = all)") + "\n" +
+ " -checklevel=<n> " + _("How thorough the block verification is (0-6, default: 1)") + "\n" +
+ " -loadblock=<file> " + _("Imports blocks from external blk000?.dat file") + "\n" +
+ " -? " + _("This help message") + "\n";
+
+ strUsage += string() +
+ _("\nSSL options: (see the Bitcoin Wiki for SSL setup instructions)") + "\n" +
+ " -rpcssl " + _("Use OpenSSL (https) for JSON-RPC connections") + "\n" +
+ " -rpcsslcertificatechainfile=<file.cert> " + _("Server certificate file (default: server.cert)") + "\n" +
+ " -rpcsslprivatekeyfile=<file.pem> " + _("Server private key (default: server.pem)") + "\n" +
+ " -rpcsslciphers=<ciphers> " + _("Acceptable ciphers (default: TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!AH:!3DES:@STRENGTH)") + "\n";
+
+ return strUsage;
+}
+
+/** Initialize bitcoin.
+ * @pre Parameters should be parsed and config file should be read.
+ */
+bool AppInit2()
{
#ifdef _MSC_VER
// Turn off microsoft heap dump noise
@@ -141,113 +295,14 @@ bool AppInit2(int argc, char* argv[])
sa.sa_flags = 0;
sigaction(SIGTERM, &sa, NULL);
sigaction(SIGINT, &sa, NULL);
- sigaction(SIGHUP, &sa, NULL);
-#endif
-
- //
- // Parameters
- //
- // If Qt is used, parameters/bitcoin.conf are parsed in qt/bitcoin.cpp's main()
-#if !defined(QT_GUI)
- ParseParameters(argc, argv);
- if (!boost::filesystem::is_directory(GetDataDir(false)))
- {
- fprintf(stderr, "Error: Specified directory does not exist\n");
- Shutdown(NULL);
- }
- ReadConfigFile(mapArgs, mapMultiArgs);
-#endif
- if (mapArgs.count("-?") || mapArgs.count("--help"))
- {
- string strUsage = string() +
- _("Bitcoin version") + " " + FormatFullVersion() + "\n\n" +
- _("Usage:") + "\t\t\t\t\t\t\t\t\t\t\n" +
- " bitcoind [options] \t " + "\n" +
- " bitcoind [options] <command> [params]\t " + _("Send command to -server or bitcoind") + "\n" +
- " bitcoind [options] help \t\t " + _("List commands") + "\n" +
- " bitcoind [options] help <command> \t\t " + _("Get help for a command") + "\n" +
- _("Options:") + "\n" +
- " -conf=<file> \t\t " + _("Specify configuration file (default: bitcoin.conf)") + "\n" +
- " -pid=<file> \t\t " + _("Specify pid file (default: bitcoind.pid)") + "\n" +
- " -gen \t\t " + _("Generate coins") + "\n" +
- " -gen=0 \t\t " + _("Don't generate coins") + "\n" +
- " -min \t\t " + _("Start minimized") + "\n" +
- " -splash \t\t " + _("Show splash screen on startup (default: 1)") + "\n" +
- " -datadir=<dir> \t\t " + _("Specify data directory") + "\n" +
- " -dbcache=<n> \t\t " + _("Set database cache size in megabytes (default: 25)") + "\n" +
- " -dblogsize=<n> \t\t " + _("Set database disk log size in megabytes (default: 100)") + "\n" +
- " -timeout=<n> \t " + _("Specify connection timeout (in milliseconds)") + "\n" +
- " -proxy=<ip:port> \t " + _("Connect through socks4 proxy") + "\n" +
- " -dns \t " + _("Allow DNS lookups for addnode and connect") + "\n" +
- " -port=<port> \t\t " + _("Listen for connections on <port> (default: 8333 or testnet: 18333)") + "\n" +
- " -maxconnections=<n>\t " + _("Maintain at most <n> connections to peers (default: 125)") + "\n" +
- " -addnode=<ip> \t " + _("Add a node to connect to and attempt to keep the connection open") + "\n" +
- " -connect=<ip> \t\t " + _("Connect only to the specified node") + "\n" +
- " -irc \t " + _("Find peers using internet relay chat (default: 0)") + "\n" +
- " -listen \t " + _("Accept connections from outside (default: 1)") + "\n" +
-#ifdef QT_GUI
- " -lang=<lang> \t\t " + _("Set language, for example \"de_DE\" (default: system locale)") + "\n" +
-#endif
- " -dnsseed \t " + _("Find peers using DNS lookup (default: 1)") + "\n" +
- " -banscore=<n> \t " + _("Threshold for disconnecting misbehaving peers (default: 100)") + "\n" +
- " -bantime=<n> \t " + _("Number of seconds to keep misbehaving peers from reconnecting (default: 86400)") + "\n" +
- " -maxreceivebuffer=<n>\t " + _("Maximum per-connection receive buffer, <n>*1000 bytes (default: 10000)") + "\n" +
- " -maxsendbuffer=<n>\t " + _("Maximum per-connection send buffer, <n>*1000 bytes (default: 10000)") + "\n" +
-#ifdef USE_UPNP
-#if USE_UPNP
- " -upnp \t " + _("Use Universal Plug and Play to map the listening port (default: 1)") + "\n" +
-#else
- " -upnp \t " + _("Use Universal Plug and Play to map the listening port (default: 0)") + "\n" +
-#endif
- " -detachdb \t " + _("Detach block and address databases. Increases shutdown time (default: 0)") + "\n" +
-#endif
- " -paytxfee=<amt> \t " + _("Fee per KB to add to transactions you send") + "\n" +
-#ifdef QT_GUI
- " -server \t\t " + _("Accept command line and JSON-RPC commands") + "\n" +
-#endif
-#if !defined(WIN32) && !defined(QT_GUI)
- " -daemon \t\t " + _("Run in the background as a daemon and accept commands") + "\n" +
+ // Reopen debug.log on SIGHUP
+ struct sigaction sa_hup;
+ sa_hup.sa_handler = HandleSIGHUP;
+ sigemptyset(&sa_hup.sa_mask);
+ sa_hup.sa_flags = 0;
+ sigaction(SIGHUP, &sa_hup, NULL);
#endif
- " -testnet \t\t " + _("Use the test network") + "\n" +
- " -debug \t\t " + _("Output extra debugging information") + "\n" +
- " -logtimestamps \t " + _("Prepend debug output with timestamp") + "\n" +
- " -printtoconsole \t " + _("Send trace/debug info to console instead of debug.log file") + "\n" +
-#ifdef WIN32
- " -printtodebugger \t " + _("Send trace/debug info to debugger") + "\n" +
-#endif
- " -rpcuser=<user> \t " + _("Username for JSON-RPC connections") + "\n" +
- " -rpcpassword=<pw>\t " + _("Password for JSON-RPC connections") + "\n" +
- " -rpcport=<port> \t\t " + _("Listen for JSON-RPC connections on <port> (default: 8332)") + "\n" +
- " -rpcallowip=<ip> \t\t " + _("Allow JSON-RPC connections from specified IP address") + "\n" +
- " -rpcconnect=<ip> \t " + _("Send commands to node running on <ip> (default: 127.0.0.1)") + "\n" +
- " -blocknotify=<cmd> " + _("Execute command when the best block changes (%s in cmd is replaced by block hash)") + "\n" +
- " -upgradewallet \t " + _("Upgrade wallet to latest format") + "\n" +
- " -keypool=<n> \t " + _("Set key pool size to <n> (default: 100)") + "\n" +
- " -rescan \t " + _("Rescan the block chain for missing wallet transactions") + "\n" +
- " -checkblocks=<n> \t\t " + _("How many blocks to check at startup (default: 2500, 0 = all)") + "\n" +
- " -checklevel=<n> \t\t " + _("How thorough the block verification is (0-6, default: 1)") + "\n";
-
- strUsage += string() +
- _("\nSSL options: (see the Bitcoin Wiki for SSL setup instructions)") + "\n" +
- " -rpcssl \t " + _("Use OpenSSL (https) for JSON-RPC connections") + "\n" +
- " -rpcsslcertificatechainfile=<file.cert>\t " + _("Server certificate file (default: server.cert)") + "\n" +
- " -rpcsslprivatekeyfile=<file.pem> \t " + _("Server private key (default: server.pem)") + "\n" +
- " -rpcsslciphers=<ciphers> \t " + _("Acceptable ciphers (default: TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!AH:!3DES:@STRENGTH)") + "\n";
-
- strUsage += string() +
- " -? \t\t " + _("This help message") + "\n";
-
- // Remove tabs
- strUsage.erase(std::remove(strUsage.begin(), strUsage.end(), '\t'), strUsage.end());
-#if defined(QT_GUI) && defined(WIN32)
- // On windows, show a message box, as there is no stderr
- ThreadSafeMessageBox(strUsage, _("Usage"), wxOK | wxMODAL);
-#else
- fprintf(stderr, "%s", strUsage.c_str());
-#endif
- return false;
- }
fTestNet = GetBoolArg("-testnet");
if (fTestNet)
@@ -277,18 +332,6 @@ bool AppInit2(int argc, char* argv[])
fPrintToDebugger = GetBoolArg("-printtodebugger");
fLogTimestamps = GetBoolArg("-logtimestamps");
-#ifndef QT_GUI
- for (int i = 1; i < argc; i++)
- if (!IsSwitchChar(argv[i][0]) && !(strlen(argv[i]) > 7 && strncasecmp(argv[i], "bitcoin:", 8) == 0))
- fCommandLine = true;
-
- if (fCommandLine)
- {
- int ret = CommandLineRPC(argc, argv);
- exit(ret);
- }
-#endif
-
#if !defined(WIN32) && !defined(QT_GUI)
if (fDaemon)
{
@@ -325,33 +368,36 @@ bool AppInit2(int argc, char* argv[])
return false;
}
- // Make sure only a single bitcoin process is using the data directory.
+ // Make sure only a single Bitcoin process is using the data directory.
boost::filesystem::path pathLockFile = GetDataDir() / ".lock";
FILE* file = fopen(pathLockFile.string().c_str(), "a"); // empty lock file; created if it doesn't exist.
if (file) fclose(file);
static boost::interprocess::file_lock lock(pathLockFile.string().c_str());
if (!lock.try_lock())
- {
- ThreadSafeMessageBox(strprintf(_("Cannot obtain a lock on data directory %s. Bitcoin is probably already running."), GetDataDir().string().c_str()), _("Bitcoin"), wxOK|wxMODAL);
- return false;
- }
+ return InitError(strprintf(_("Cannot obtain a lock on data directory %s. Bitcoin is probably already running."), GetDataDir().string().c_str()));
std::ostringstream strErrors;
//
// Load data files
//
if (fDaemon)
- fprintf(stdout, "bitcoin server starting\n");
+ fprintf(stdout, "Bitcoin server starting\n");
int64 nStart;
- InitMessage(_("Loading addresses..."));
+ uiInterface.InitMessage(_("Loading addresses..."));
printf("Loading addresses...\n");
nStart = GetTimeMillis();
- if (!LoadAddresses())
- strErrors << _("Error loading addr.dat") << "\n";
- printf(" addresses %15"PRI64d"ms\n", GetTimeMillis() - nStart);
- InitMessage(_("Loading block index..."));
+ {
+ CAddrDB adb;
+ if (!adb.Read(addrman))
+ printf("Invalid or missing peers.dat; recreating\n");
+ }
+
+ printf("Loaded %i addresses from peers.dat %"PRI64d"ms\n",
+ addrman.size(), GetTimeMillis() - nStart);
+
+ uiInterface.InitMessage(_("Loading block index..."));
printf("Loading block index...\n");
nStart = GetTimeMillis();
if (!LoadBlockIndex())
@@ -367,7 +413,17 @@ bool AppInit2(int argc, char* argv[])
}
printf(" block index %15"PRI64d"ms\n", GetTimeMillis() - nStart);
- InitMessage(_("Loading wallet..."));
+ if (mapArgs.count("-loadblock"))
+ {
+ BOOST_FOREACH(string strFile, mapMultiArgs["-loadblock"])
+ {
+ FILE *file = fopen(strFile.c_str(), "rb");
+ if (file)
+ LoadExternalBlockFile(file);
+ }
+ }
+
+ uiInterface.InitMessage(_("Loading wallet..."));
printf("Loading wallet...\n");
nStart = GetTimeMillis();
bool fFirstRun;
@@ -383,8 +439,7 @@ bool AppInit2(int argc, char* argv[])
{
strErrors << _("Wallet needed to be rewritten: restart Bitcoin to complete") << "\n";
printf("%s", strErrors.str().c_str());
- ThreadSafeMessageBox(strErrors.str(), _("Bitcoin"), wxOK | wxICON_ERROR | wxMODAL);
- return false;
+ return InitError(strErrors.str());
}
else
strErrors << _("Error loading wallet.dat") << "\n";
@@ -436,14 +491,14 @@ bool AppInit2(int argc, char* argv[])
}
if (pindexBest != pindexRescan)
{
- InitMessage(_("Rescanning..."));
+ uiInterface.InitMessage(_("Rescanning..."));
printf("Rescanning last %i blocks (from block %i)...\n", pindexBest->nHeight - pindexRescan->nHeight, pindexRescan->nHeight);
nStart = GetTimeMillis();
pwalletMain->ScanForWalletTransactions(pindexRescan, true);
printf(" rescan %15"PRI64d"ms\n", GetTimeMillis() - nStart);
}
- InitMessage(_("Done loading"));
+ uiInterface.InitMessage(_("Done loading"));
printf("Done loading\n");
//// debug print
@@ -454,15 +509,12 @@ bool AppInit2(int argc, char* argv[])
printf("mapAddressBook.size() = %d\n", pwalletMain->mapAddressBook.size());
if (!strErrors.str().empty())
- {
- ThreadSafeMessageBox(strErrors.str(), _("Bitcoin"), wxOK | wxICON_ERROR | wxMODAL);
- return false;
- }
+ return InitError(strErrors.str());
// Add wallet transactions that aren't already in a block to mapTransactions
pwalletMain->ReacceptWalletTransactions();
- // Note: Bitcoin-QT stores several settings in the wallet, so we want
+ // Note: Bitcoin-Qt stores several settings in the wallet, so we want
// to load the wallet BEFORE parsing command-line arguments, so
// the command-line/bitcoin.conf settings override GUI setting.
@@ -510,12 +562,26 @@ bool AppInit2(int argc, char* argv[])
fUseProxy = true;
addrProxy = CService(mapArgs["-proxy"], 9050);
if (!addrProxy.IsValid())
- {
- ThreadSafeMessageBox(_("Invalid -proxy address"), _("Bitcoin"), wxOK | wxMODAL);
- return false;
+ return InitError(strprintf(_("Invalid -proxy address: '%s'"), mapArgs["-proxy"].c_str()));
+ }
+
+ if (mapArgs.count("-noproxy"))
+ {
+ BOOST_FOREACH(std::string snet, mapMultiArgs["-noproxy"]) {
+ enum Network net = ParseNetwork(snet);
+ if (net == NET_UNROUTABLE)
+ return InitError(strprintf(_("Unknown network specified in -noproxy: '%s'"), snet.c_str()));
+ SetNoProxy(net);
}
}
+ if (mapArgs.count("-connect"))
+ SoftSetBoolArg("-dnsseed", false);
+
+ // even in Tor mode, if -bind is specified, you really want -listen
+ if (mapArgs.count("-bind"))
+ SoftSetBoolArg("-listen", true);
+
bool fTor = (fUseProxy && addrProxy.GetPort() == 9050);
if (fTor)
{
@@ -523,13 +589,37 @@ bool AppInit2(int argc, char* argv[])
// Note: the GetBoolArg() calls for all of these must happen later.
SoftSetBoolArg("-listen", false);
SoftSetBoolArg("-irc", false);
- SoftSetBoolArg("-dnsseed", false);
+ SoftSetBoolArg("-proxydns", true);
SoftSetBoolArg("-upnp", false);
- SoftSetBoolArg("-dns", false);
+ SoftSetBoolArg("-discover", false);
+ }
+
+ if (mapArgs.count("-onlynet")) {
+ std::set<enum Network> nets;
+ BOOST_FOREACH(std::string snet, mapMultiArgs["-onlynet"]) {
+ enum Network net = ParseNetwork(snet);
+ if (net == NET_UNROUTABLE)
+ return InitError(strprintf(_("Unknown network specified in -onlynet: '%s'"), snet.c_str()));
+ nets.insert(net);
+ }
+ for (int n = 0; n < NET_MAX; n++) {
+ enum Network net = (enum Network)n;
+ if (!nets.count(net))
+ SetLimited(net);
+ }
}
- fAllowDNS = GetBoolArg("-dns");
+ fNameLookup = GetBoolArg("-dns");
+ fProxyNameLookup = GetBoolArg("-proxydns");
+ if (fProxyNameLookup)
+ fNameLookup = true;
fNoListen = !GetBoolArg("-listen", true);
+ nSocksVersion = GetArg("-socks", 5);
+ if (nSocksVersion != 4 && nSocksVersion != 5)
+ return InitError(strprintf(_("Unknown -socks proxy version requested: %i"), nSocksVersion));
+
+ BOOST_FOREACH(string strDest, mapMultiArgs["-seednode"])
+ AddOneShot(strDest);
// Continue to put "/P2SH/" in the coinbase to monitor
// BIP16 support.
@@ -537,36 +627,47 @@ bool AppInit2(int argc, char* argv[])
const char* pszP2SH = "/P2SH/";
COINBASE_FLAGS << std::vector<unsigned char>(pszP2SH, pszP2SH+strlen(pszP2SH));
+ bool fBound = false;
if (!fNoListen)
{
std::string strError;
- if (!BindListenPort(strError))
- {
- ThreadSafeMessageBox(strError, _("Bitcoin"), wxOK | wxMODAL);
- return false;
+ if (mapArgs.count("-bind")) {
+ BOOST_FOREACH(std::string strBind, mapMultiArgs["-bind"]) {
+ CService addrBind;
+ if (!Lookup(strBind.c_str(), addrBind, GetListenPort(), false))
+ return InitError(strprintf(_("Cannot resolve -bind address: '%s'"), strBind.c_str()));
+ fBound |= Bind(addrBind);
+ }
+ } else {
+ struct in_addr inaddr_any;
+ inaddr_any.s_addr = INADDR_ANY;
+ if (!IsLimited(NET_IPV4))
+ fBound |= Bind(CService(inaddr_any, GetListenPort()));
+#ifdef USE_IPV6
+ if (!IsLimited(NET_IPV6))
+ fBound |= Bind(CService(in6addr_any, GetListenPort()));
+#endif
}
+ if (!fBound)
+ return InitError(_("Not listening on any port"));
}
- if (mapArgs.count("-addnode"))
+ if (mapArgs.count("-externalip"))
{
- BOOST_FOREACH(string strAddr, mapMultiArgs["-addnode"])
- {
- CAddress addr(CService(strAddr, GetDefaultPort(), fAllowDNS));
- addr.nTime = 0; // so it won't relay unless successfully connected
- if (addr.IsValid())
- addrman.Add(addr, CNetAddr("127.0.0.1"));
+ BOOST_FOREACH(string strAddr, mapMultiArgs["-externalip"]) {
+ CService addrLocal(strAddr, GetListenPort(), fNameLookup);
+ if (!addrLocal.IsValid())
+ return InitError(strprintf(_("Cannot resolve -externalip address: '%s'"), strAddr.c_str()));
+ AddLocal(CService(strAddr, GetListenPort(), fNameLookup), LOCAL_MANUAL);
}
}
if (mapArgs.count("-paytxfee"))
{
if (!ParseMoney(mapArgs["-paytxfee"], nTransactionFee))
- {
- ThreadSafeMessageBox(_("Invalid amount for -paytxfee=<amount>"), _("Bitcoin"), wxOK | wxMODAL);
- return false;
- }
+ return InitError(strprintf(_("Invalid amount for -paytxfee=<amount>: '%s'"), mapArgs["-paytxfee"].c_str()));
if (nTransactionFee > 0.25 * COIN)
- ThreadSafeMessageBox(_("Warning: -paytxfee is set very high. This is the transaction fee you will pay if you send a transaction."), _("Bitcoin"), wxOK | wxICON_EXCLAMATION | wxMODAL);
+ InitWarning(_("Warning: -paytxfee is set very high. This is the transaction fee you will pay if you send a transaction."));
}
//
@@ -578,17 +679,14 @@ bool AppInit2(int argc, char* argv[])
RandAddSeedPerfmon();
if (!CreateThread(StartNode, NULL))
- ThreadSafeMessageBox(_("Error: CreateThread(StartNode) failed"), _("Bitcoin"), wxOK | wxMODAL);
+ InitError(_("Error: could not start node"));
if (fServer)
CreateThread(ThreadRPCServer, NULL);
-#ifdef QT_GUI
- if (GetStartOnSystemStartup())
- SetStartOnSystemStartup(true); // Remove startup links
-#endif
-
#if !defined(QT_GUI)
+ // Loop until process is exit()ed from shutdown() function,
+ // called from ThreadRPCServer thread when a "stop" command is received.
while (1)
Sleep(5000);
#endif
diff --git a/src/init.h b/src/init.h
index e3971c85e3..6159ededa5 100644
--- a/src/init.h
+++ b/src/init.h
@@ -1,7 +1,7 @@
// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2012 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
-// file license.txt or http://www.opensource.org/licenses/mit-license.php.
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifndef BITCOIN_INIT_H
#define BITCOIN_INIT_H
@@ -10,10 +10,7 @@
extern CWallet* pwalletMain;
void Shutdown(void* parg);
-bool AppInit(int argc, char* argv[]);
-bool AppInit2(int argc, char* argv[]);
-
-bool GetStartOnSystemStartup();
-bool SetStartOnSystemStartup(bool fAutoStart);
+bool AppInit2();
+std::string HelpMessage();
#endif
diff --git a/src/irc.cpp b/src/irc.cpp
index 237497055d..1049188411 100644
--- a/src/irc.cpp
+++ b/src/irc.cpp
@@ -1,7 +1,7 @@
// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2012 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
-// file license.txt or http://www.opensource.org/licenses/mit-license.php.
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "irc.h"
#include "net.h"
@@ -12,7 +12,6 @@ using namespace std;
using namespace boost;
int nGotIRCAddresses = 0;
-bool fGotExternalIP = false;
void ThreadIRCSeed2(void* parg);
@@ -201,7 +200,7 @@ void ThreadIRCSeed(void* parg)
} catch (...) {
PrintExceptionContinue(NULL, "ThreadIRCSeed()");
}
- printf("ThreadIRCSeed exiting\n");
+ printf("ThreadIRCSeed exited\n");
}
void ThreadIRCSeed2(void* parg)
@@ -216,7 +215,6 @@ void ThreadIRCSeed2(void* parg)
printf("ThreadIRCSeed started\n");
int nErrorWait = 10;
int nRetryWait = 10;
- bool fNameInUse = false;
while (!fShutdown)
{
@@ -248,10 +246,12 @@ void ThreadIRCSeed2(void* parg)
return;
}
+ CNetAddr addrIPv4("1.2.3.4"); // arbitrary IPv4 address to make GetLocal prefer IPv4 addresses
+ CService addrLocal;
string strMyName;
- if (addrLocalHost.IsRoutable() && !fUseProxy && !fNameInUse)
- strMyName = EncodeAddress(addrLocalHost);
- else
+ if (GetLocal(addrLocal, &addrIPv4))
+ strMyName = EncodeAddress(GetLocalAddress(&addrConnect));
+ if (strMyName == "")
strMyName = strprintf("x%u", GetRand(1000000000));
Send(hSocket, strprintf("NICK %s\r", strMyName.c_str()).c_str());
@@ -265,7 +265,6 @@ void ThreadIRCSeed2(void* parg)
if (nRet == 2)
{
printf("IRC name already in use\n");
- fNameInUse = true;
Wait(10);
continue;
}
@@ -285,9 +284,8 @@ void ThreadIRCSeed2(void* parg)
if (!fUseProxy && addrFromIRC.IsRoutable())
{
// IRC lets you to re-nick
- fGotExternalIP = true;
- addrLocalHost.SetIP(addrFromIRC);
- strMyName = EncodeAddress(addrLocalHost);
+ AddLocal(addrFromIRC, LOCAL_IRC);
+ strMyName = EncodeAddress(GetLocalAddress(&addrConnect));
Send(hSocket, strprintf("NICK %s\r", strMyName.c_str()).c_str());
}
}
diff --git a/src/irc.h b/src/irc.h
index 08d62b83d2..119aeb3fda 100644
--- a/src/irc.h
+++ b/src/irc.h
@@ -1,13 +1,12 @@
// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2012 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
-// file license.txt or http://www.opensource.org/licenses/mit-license.php.
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifndef BITCOIN_IRC_H
#define BITCOIN_IRC_H
void ThreadIRCSeed(void* parg);
extern int nGotIRCAddresses;
-extern bool fGotExternalIP;
#endif
diff --git a/src/key.cpp b/src/key.cpp
index ac7ac4db77..4172d6be5e 100644
--- a/src/key.cpp
+++ b/src/key.cpp
@@ -1,6 +1,6 @@
// Copyright (c) 2009-2012 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
-// file license.txt or http://www.opensource.org/licenses/mit-license.php.
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include <map>
@@ -9,6 +9,7 @@
#include <openssl/obj_mac.h>
#include "key.h"
+#include "sync.h"
#include "util.h"
// Generate a private key from just the secret parameter
diff --git a/src/key.h b/src/key.h
index f7255fcaf5..bd58c84375 100644
--- a/src/key.h
+++ b/src/key.h
@@ -1,7 +1,7 @@
// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2012 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
-// file license.txt or http://www.opensource.org/licenses/mit-license.php.
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifndef BITCOIN_KEY_H
#define BITCOIN_KEY_H
diff --git a/src/keystore.cpp b/src/keystore.cpp
index 313518711b..c56e820e0f 100644
--- a/src/keystore.cpp
+++ b/src/keystore.cpp
@@ -1,7 +1,7 @@
// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2012 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
-// file license.txt or http://www.opensource.org/licenses/mit-license.php.
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "keystore.h"
#include "script.h"
@@ -73,6 +73,20 @@ bool CCryptoKeyStore::SetCrypted()
return true;
}
+bool CCryptoKeyStore::Lock()
+{
+ if (!SetCrypted())
+ return false;
+
+ {
+ LOCK(cs_KeyStore);
+ vMasterKey.clear();
+ }
+
+ NotifyStatusChanged(this);
+ return true;
+}
+
bool CCryptoKeyStore::Unlock(const CKeyingMaterial& vMasterKeyIn)
{
{
@@ -99,6 +113,7 @@ bool CCryptoKeyStore::Unlock(const CKeyingMaterial& vMasterKeyIn)
}
vMasterKey = vMasterKeyIn;
}
+ NotifyStatusChanged(this);
return true;
}
diff --git a/src/keystore.h b/src/keystore.h
index 76820e204b..479d6c5a2e 100644
--- a/src/keystore.h
+++ b/src/keystore.h
@@ -1,13 +1,14 @@
// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2012 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
-// file license.txt or http://www.opensource.org/licenses/mit-license.php.
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifndef BITCOIN_KEYSTORE_H
#define BITCOIN_KEYSTORE_H
#include "crypter.h"
-#include "util.h"
+#include "sync.h"
#include "base58.h"
+#include <boost/signals2/signal.hpp>
class CScript;
@@ -143,18 +144,7 @@ public:
return result;
}
- bool Lock()
- {
- if (!SetCrypted())
- return false;
-
- {
- LOCK(cs_KeyStore);
- vMasterKey.clear();
- }
-
- return true;
- }
+ bool Lock();
virtual bool AddCryptedKey(const std::vector<unsigned char> &vchPubKey, const std::vector<unsigned char> &vchCryptedSecret);
bool AddKey(const CKey& key);
@@ -185,6 +175,11 @@ public:
mi++;
}
}
+
+ /* Wallet status (encrypted, locked) changed.
+ * Note: Called without locks held.
+ */
+ boost::signals2::signal<void (CCryptoKeyStore* wallet)> NotifyStatusChanged;
};
#endif
diff --git a/src/main.cpp b/src/main.cpp
index 263f1e6fee..8900115efe 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -1,7 +1,8 @@
// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2012 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
-// file license.txt or http://www.opensource.org/licenses/mit-license.php.
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
#include "checkpoints.h"
#include "db.h"
#include "net.h"
@@ -540,7 +541,7 @@ bool CTxMemPool::accept(CTxDB& txdb, CTransaction &tx, bool fCheckInputs,
return error("CTxMemPool::accept() : FetchInputs found invalid tx %s", hash.ToString().substr(0,10).c_str());
if (pfMissingInputs)
*pfMissingInputs = true;
- return error("CTxMemPool::accept() : FetchInputs failed %s", hash.ToString().substr(0,10).c_str());
+ return false;
}
// Check for non-standard pay-to-script-hash in inputs
@@ -607,7 +608,9 @@ bool CTxMemPool::accept(CTxDB& txdb, CTransaction &tx, bool fCheckInputs,
if (ptxOld)
EraseFromWallets(ptxOld->GetHash());
- printf("CTxMemPool::accept() : accepted %s\n", hash.ToString().substr(0,10).c_str());
+ printf("CTxMemPool::accept() : accepted %s (poolsz %u)\n",
+ hash.ToString().substr(0,10).c_str(),
+ mapTx.size());
return true;
}
@@ -618,7 +621,6 @@ bool CTransaction::AcceptToMemoryPool(CTxDB& txdb, bool fCheckInputs, bool* pfMi
bool CTxMemPool::addUnchecked(CTransaction &tx)
{
- printf("addUnchecked(): size %lu\n", mapTx.size());
// Add to memory pool without checking anything. Don't call this directly,
// call CTxMemPool::accept to properly check the transaction first.
{
@@ -731,7 +733,7 @@ bool CWalletTx::AcceptWalletTransaction(CTxDB& txdb, bool fCheckInputs)
return false;
}
-bool CWalletTx::AcceptWalletTransaction()
+bool CWalletTx::AcceptWalletTransaction()
{
CTxDB txdb("r");
return AcceptWalletTransaction(txdb);
@@ -753,7 +755,31 @@ int CTxIndex::GetDepthInMainChain() const
return 1 + nBestHeight - pindex->nHeight;
}
-
+// Return transaction in tx, and if it was found inside a block, its hash is placed in hashBlock
+bool GetTransaction(const uint256 &hash, CTransaction &tx, uint256 &hashBlock)
+{
+ {
+ LOCK(cs_main);
+ {
+ LOCK(mempool.cs);
+ if (mempool.exists(hash))
+ {
+ tx = mempool.lookup(hash);
+ return true;
+ }
+ }
+ CTxDB txdb("r");
+ CTxIndex txindex;
+ if (tx.ReadFromDisk(txdb, COutPoint(hash, 0), txindex))
+ {
+ CBlock block;
+ if (block.ReadFromDisk(txindex.pos.nFile, txindex.pos.nBlockPos, false))
+ hashBlock = block.GetHash();
+ return true;
+ }
+ }
+ return false;
+}
@@ -934,7 +960,7 @@ void static InvalidChainFound(CBlockIndex* pindexNew)
{
bnBestInvalidWork = pindexNew->bnChainWork;
CTxDB().WriteBestInvalidWork(bnBestInvalidWork);
- MainFrameRepaint();
+ uiInterface.NotifyBlocksChanged();
}
printf("InvalidChainFound: invalid block=%s height=%d work=%s\n", pindexNew->GetBlockHash().ToString().substr(0,20).c_str(), pindexNew->nHeight, pindexNew->bnChainWork.ToString().c_str());
printf("InvalidChainFound: current best=%s height=%d work=%s\n", hashBestChain.ToString().substr(0,20).c_str(), nBestHeight, bnBestChainWork.ToString().c_str());
@@ -1513,7 +1539,9 @@ bool CBlock::SetBestChain(CTxDB& txdb, CBlockIndex* pindexNew)
{
uint256 hash = GetHash();
- txdb.TxnBegin();
+ if (!txdb.TxnBegin())
+ return error("SetBestChain() : TxnBegin failed");
+
if (pindexGenesisBlock == NULL && hash == hashGenesisBlock)
{
txdb.WriteHashBestChain(hash);
@@ -1562,7 +1590,10 @@ bool CBlock::SetBestChain(CTxDB& txdb, CBlockIndex* pindexNew)
printf("SetBestChain() : ReadFromDisk failed\n");
break;
}
- txdb.TxnBegin();
+ if (!txdb.TxnBegin()) {
+ printf("SetBestChain() : TxnBegin 2 failed\n");
+ break;
+ }
// errors now are not fatal, we still did a reorganisation to a new chain in a valid way
if (!block.SetBestChainInner(txdb, pindex))
break;
@@ -1620,7 +1651,8 @@ bool CBlock::AddToBlockIndex(unsigned int nFile, unsigned int nBlockPos)
pindexNew->bnChainWork = (pindexNew->pprev ? pindexNew->pprev->bnChainWork : 0) + pindexNew->GetBlockWork();
CTxDB txdb;
- txdb.TxnBegin();
+ if (!txdb.TxnBegin())
+ return false;
txdb.WriteBlockIndex(CDiskBlockIndex(pindexNew));
if (!txdb.TxnCommit())
return false;
@@ -1640,7 +1672,7 @@ bool CBlock::AddToBlockIndex(unsigned int nFile, unsigned int nBlockPos)
hashPrevBestCoinBase = vtx[0].GetHash();
}
- MainFrameRepaint();
+ uiInterface.NotifyBlocksChanged();
return true;
}
@@ -1844,15 +1876,15 @@ bool CheckDiskSpace(uint64 nAdditionalBytes)
{
uint64 nFreeBytesAvailable = filesystem::space(GetDataDir()).available;
- // Check for 15MB because database could create another 10MB log file at any time
- if (nFreeBytesAvailable < (uint64)15000000 + nAdditionalBytes)
+ // Check for nMinDiskSpace bytes (currently 50MB)
+ if (nFreeBytesAvailable < nMinDiskSpace + nAdditionalBytes)
{
fShutdown = true;
- string strMessage = _("Warning: Disk space is low ");
+ string strMessage = _("Warning: Disk space is low");
strMiscWarning = strMessage;
printf("*** %s\n", strMessage.c_str());
- ThreadSafeMessageBox(strMessage, "Bitcoin", wxOK | wxICON_EXCLAMATION | wxMODAL);
- QueueShutdown();
+ uiInterface.ThreadSafeMessageBox(strMessage, "Bitcoin", CClientUIInterface::OK | CClientUIInterface::ICON_EXCLAMATION | CClientUIInterface::MODAL);
+ uiInterface.QueueShutdown();
return false;
}
return true;
@@ -1860,7 +1892,7 @@ bool CheckDiskSpace(uint64 nAdditionalBytes)
FILE* OpenBlockFile(unsigned int nFile, unsigned int nBlockPos, const char* pszMode)
{
- if (nFile == -1)
+ if ((nFile < 1) || (nFile == (unsigned int) -1))
return NULL;
FILE* file = fopen((GetDataDir() / strprintf("blk%04d.dat", nFile)).string().c_str(), pszMode);
if (!file)
@@ -2052,6 +2084,62 @@ void PrintBlockTree()
}
}
+bool LoadExternalBlockFile(FILE* fileIn)
+{
+ int nLoaded = 0;
+ {
+ LOCK(cs_main);
+ try {
+ CAutoFile blkdat(fileIn, SER_DISK, CLIENT_VERSION);
+ unsigned int nPos = 0;
+ while (nPos != (unsigned int)-1 && blkdat.good() && !fRequestShutdown)
+ {
+ unsigned char pchData[65536];
+ do {
+ fseek(blkdat, nPos, SEEK_SET);
+ int nRead = fread(pchData, 1, sizeof(pchData), blkdat);
+ if (nRead <= 8)
+ {
+ nPos = (unsigned int)-1;
+ break;
+ }
+ void* nFind = memchr(pchData, pchMessageStart[0], nRead+1-sizeof(pchMessageStart));
+ if (nFind)
+ {
+ if (memcmp(nFind, pchMessageStart, sizeof(pchMessageStart))==0)
+ {
+ nPos += ((unsigned char*)nFind - pchData) + sizeof(pchMessageStart);
+ break;
+ }
+ nPos += ((unsigned char*)nFind - pchData) + 1;
+ }
+ else
+ nPos += sizeof(pchData) - sizeof(pchMessageStart) + 1;
+ } while(!fRequestShutdown);
+ if (nPos == (unsigned int)-1)
+ break;
+ fseek(blkdat, nPos, SEEK_SET);
+ unsigned int nSize;
+ blkdat >> nSize;
+ if (nSize > 0 && nSize <= MAX_BLOCK_SIZE)
+ {
+ CBlock block;
+ blkdat >> block;
+ if (ProcessBlock(NULL,&block))
+ {
+ nLoaded++;
+ nPos += 4 + nSize;
+ }
+ }
+ }
+ }
+ catch (std::exception &e)
+ {
+ }
+ }
+ printf("Loaded %i blocks from external file\n", nLoaded);
+ return nLoaded > 0;
+}
@@ -2113,6 +2201,18 @@ string GetWarnings(string strFor)
return "error";
}
+CAlert CAlert::getAlertByHash(const uint256 &hash)
+{
+ CAlert retval;
+ {
+ LOCK(cs_mapAlerts);
+ map<uint256, CAlert>::iterator mi = mapAlerts.find(hash);
+ if(mi != mapAlerts.end())
+ retval = mi->second;
+ }
+ return retval;
+}
+
bool CAlert::ProcessAlert()
{
if (!CheckSignature())
@@ -2129,11 +2229,13 @@ bool CAlert::ProcessAlert()
if (Cancels(alert))
{
printf("cancelling alert %d\n", alert.nID);
+ uiInterface.NotifyAlertChanged((*mi).first, CT_DELETED);
mapAlerts.erase(mi++);
}
else if (!alert.IsInEffect())
{
printf("expiring alert %d\n", alert.nID);
+ uiInterface.NotifyAlertChanged((*mi).first, CT_DELETED);
mapAlerts.erase(mi++);
}
else
@@ -2153,10 +2255,12 @@ bool CAlert::ProcessAlert()
// Add to mapAlerts
mapAlerts.insert(make_pair(GetHash(), *this));
+ // Notify UI if it applies to me
+ if(AppliesToMe())
+ uiInterface.NotifyAlertChanged(GetHash(), CT_NEW);
}
printf("accepted alert %d, AppliesToMe()=%d\n", nID, AppliesToMe());
- MainFrameRepaint();
return true;
}
@@ -2210,10 +2314,8 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
{
static map<CService, vector<unsigned char> > mapReuseKey;
RandAddSeedPerfmon();
- if (fDebug) {
- printf("%s ", DateTimeStrFormat("%x %H:%M:%S", GetTime()).c_str());
+ if (fDebug)
printf("received: %s (%d bytes)\n", strCommand.c_str(), vRecv.size());
- }
if (mapArgs.count("-dropmessagestest") && GetRand(atoi(mapArgs["-dropmessagestest"])) == 0)
{
printf("dropmessagestest DROPPING RECV MESSAGE\n");
@@ -2256,6 +2358,12 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
if (!vRecv.empty())
vRecv >> pfrom->nStartingHeight;
+ if (pfrom->fInbound && addrMe.IsRoutable())
+ {
+ pfrom->addrLocal = addrMe;
+ SeenLocal(addrMe);
+ }
+
// Disconnect if we connected to ourself
if (nNonce == nLocalHostNonce && nNonce > 1)
{
@@ -2279,16 +2387,15 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
if (!pfrom->fInbound)
{
// Advertise our address
- if (!fNoListen && !fUseProxy && addrLocalHost.IsRoutable() &&
- !IsInitialBlockDownload())
+ if (!fNoListen && !fUseProxy && !IsInitialBlockDownload())
{
- CAddress addr(addrLocalHost);
- addr.nTime = GetAdjustedTime();
- pfrom->PushAddress(addr);
+ CAddress addr = GetLocalAddress(&pfrom->addr);
+ if (addr.IsRoutable())
+ pfrom->PushAddress(addr);
}
// Get recent addresses
- if (pfrom->nVersion >= CADDR_TIME_VERSION || addrman.size() < 1000)
+ if (pfrom->fOneShot || pfrom->nVersion >= CADDR_TIME_VERSION || addrman.size() < 1000)
{
pfrom->PushMessage("getaddr");
pfrom->fGetAddr = true;
@@ -2304,7 +2411,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
// Ask the first connected node for block updates
static int nAskedForBlocks = 0;
- if (!pfrom->fClient &&
+ if (!pfrom->fClient && !pfrom->fOneShot &&
(pfrom->nVersion < NOBLKS_VERSION_START ||
pfrom->nVersion >= NOBLKS_VERSION_END) &&
(nAskedForBlocks < 1 || vNodes.size() <= 1))
@@ -2357,18 +2464,17 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
}
// Store the new addresses
+ vector<CAddress> vAddrOk;
int64 nNow = GetAdjustedTime();
int64 nSince = nNow - 10 * 60;
BOOST_FOREACH(CAddress& addr, vAddr)
{
if (fShutdown)
return true;
- // ignore IPv6 for now, since it isn't implemented anyway
- if (!addr.IsIPv4())
- continue;
if (addr.nTime <= 100000000 || addr.nTime > nNow + 10 * 60)
addr.nTime = nNow - 5 * 24 * 60 * 60;
pfrom->AddAddressKnown(addr);
+ bool fReachable = IsReachable(addr);
if (addr.nTime > nSince && !pfrom->fGetAddr && vAddr.size() <= 10 && addr.IsRoutable())
{
// Relay to a limited number of other nodes
@@ -2393,15 +2499,20 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
hashKey = Hash(BEGIN(hashKey), END(hashKey));
mapMix.insert(make_pair(hashKey, pnode));
}
- int nRelayNodes = 2;
+ int nRelayNodes = fReachable ? 2 : 1; // limited relaying of addresses outside our network(s)
for (multimap<uint256, CNode*>::iterator mi = mapMix.begin(); mi != mapMix.end() && nRelayNodes-- > 0; ++mi)
((*mi).second)->PushAddress(addr);
}
}
+ // Do not store addresses outside our network
+ if (fReachable)
+ vAddrOk.push_back(addr);
}
- addrman.Add(vAddr, pfrom->addr, 2 * 60 * 60);
+ addrman.Add(vAddrOk, pfrom->addr, 2 * 60 * 60);
if (vAddr.size() < 1000)
pfrom->fGetAddr = false;
+ if (pfrom->fOneShot)
+ pfrom->fDisconnect = true;
}
@@ -2415,6 +2526,14 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
return error("message inv size() = %d", vInv.size());
}
+ // find last block in inv vector
+ unsigned int nLastBlock = (unsigned int)(-1);
+ for (unsigned int nInv = 0; nInv < vInv.size(); nInv++) {
+ if (vInv[vInv.size() - 1 - nInv].type == MSG_BLOCK) {
+ nLastBlock = vInv.size() - 1 - nInv;
+ break;
+ }
+ }
CTxDB txdb("r");
for (unsigned int nInv = 0; nInv < vInv.size(); nInv++)
{
@@ -2428,13 +2547,19 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
if (fDebug)
printf(" got inventory: %s %s\n", inv.ToString().c_str(), fAlreadyHave ? "have" : "new");
- // Always request the last block in an inv bundle (even if we already have it), as it is the
- // trigger for the other side to send further invs. If we are stuck on a (very long) side chain,
- // this is necessary to connect earlier received orphan blocks to the chain again.
- if (!fAlreadyHave || (inv.type == MSG_BLOCK && nInv==vInv.size()-1))
+ if (!fAlreadyHave)
pfrom->AskFor(inv);
- if (inv.type == MSG_BLOCK && mapOrphanBlocks.count(inv.hash))
+ else if (inv.type == MSG_BLOCK && mapOrphanBlocks.count(inv.hash)) {
pfrom->PushGetBlocks(pindexBest, GetOrphanRoot(mapOrphanBlocks[inv.hash]));
+ } else if (nInv == nLastBlock) {
+ // In case we are on a very long side-chain, it is possible that we already have
+ // the last block in an inv bundle sent in response to getblocks. Try to detect
+ // this situation and push another getblocks to continue.
+ std::vector<CInv> vGetData(1,inv);
+ pfrom->PushGetBlocks(mapBlockIndex[inv.hash], uint256(0));
+ if (fDebug)
+ printf("force request: %s\n", inv.ToString().c_str());
+ }
// Track requests for our stuff
Inventory(inv.hash);
@@ -2630,6 +2755,9 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
}
else if (fMissingInputs)
{
+ printf("storing orphan tx %s (mapsz %d)\n",
+ inv.hash.ToString().substr(0,10).c_str(),
+ mapOrphanTransactions.size() + 1);
AddOrphanTx(vMsg);
// DoS prevention: do not allow mapOrphanTransactions to grow unbounded
@@ -2895,7 +3023,7 @@ bool SendMessages(CNode* pto, bool fSendTrickle)
if (pto->nVersion == 0)
return true;
- // Keep-alive ping. We send a nonce of zero because we don't use it anywhere
+ // Keep-alive ping. We send a nonce of zero because we don't use it anywhere
// right now.
if (pto->nLastSend && GetTime() - pto->nLastSend > 30 * 60 && pto->vSend.empty()) {
if (pto->nVersion > BIP0031_VERSION)
@@ -2920,11 +3048,11 @@ bool SendMessages(CNode* pto, bool fSendTrickle)
pnode->setAddrKnown.clear();
// Rebroadcast our address
- if (!fNoListen && !fUseProxy && addrLocalHost.IsRoutable())
+ if (!fNoListen && !fUseProxy)
{
- CAddress addr(addrLocalHost);
- addr.nTime = GetAdjustedTime();
- pnode->PushAddress(addr);
+ CAddress addr = GetLocalAddress(&pnode->addr);
+ if (addr.IsRoutable())
+ pnode->PushAddress(addr);
}
}
}
@@ -3095,7 +3223,7 @@ void SHA256Transform(void* pstate, void* pinput, const void* pinit)
ctx.h[i] = ((uint32_t*)pinit)[i];
SHA256_Update(&ctx, data, sizeof(data));
- for (int i = 0; i < 8; i++)
+ for (int i = 0; i < 8; i++)
((uint32_t*)pstate)[i] = ctx.h[i];
}
@@ -3221,7 +3349,7 @@ CBlock* CreateNewBlock(CReserveKey& reservekey)
dPriority += (double)nValueIn * nConf;
if (fDebug && GetBoolArg("-printpriority"))
- printf("priority nValueIn=%-12I64d nConf=%-5d dPriority=%-20.1f\n", nValueIn, nConf, dPriority);
+ printf("priority nValueIn=%-12"PRI64d" nConf=%-5d dPriority=%-20.1f\n", nValueIn, nConf, dPriority);
}
// Priority is sum(valuein * age) / txsize
@@ -3404,7 +3532,6 @@ bool CheckWork(CBlock* pblock, CWallet& wallet, CReserveKey& reservekey)
printf("BitcoinMiner:\n");
printf("proof-of-work found \n hash: %s \ntarget: %s\n", hash.GetHex().c_str(), hashTarget.GetHex().c_str());
pblock->print();
- printf("%s ", DateTimeStrFormat("%x %H:%M", GetTime()).c_str());
printf("generated %s\n", FormatMoney(pblock->vtx[0].vout[0].nValue).c_str());
// Found a solution
@@ -3545,7 +3672,6 @@ void static BitcoinMiner(CWallet *pwallet)
if (GetTime() - nLogTime > 30 * 60)
{
nLogTime = GetTime();
- printf("%s ", DateTimeStrFormat("%x %H:%M", GetTime()).c_str());
printf("hashmeter %3d CPUs %6.0f khash/s\n", vnThreadsRunning[THREAD_MINER], dHashesPerSec/1000.0);
}
}
diff --git a/src/main.h b/src/main.h
index 262e77e806..ac5ba254ce 100644
--- a/src/main.h
+++ b/src/main.h
@@ -1,18 +1,15 @@
// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2012 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
-// file license.txt or http://www.opensource.org/licenses/mit-license.php.
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifndef BITCOIN_MAIN_H
#define BITCOIN_MAIN_H
#include "bignum.h"
+#include "sync.h"
#include "net.h"
#include "script.h"
-#ifdef WIN32
-#include <io.h> /* for _commit */
-#endif
-
#include <list>
class CWallet;
@@ -36,7 +33,7 @@ static const int64 MAX_MONEY = 21000000 * COIN;
inline bool MoneyRange(int64 nValue) { return (nValue >= 0 && nValue <= MAX_MONEY); }
static const int COINBASE_MATURITY = 100;
// Threshold for nLockTime: below this value it is interpreted as block number, otherwise as UNIX timestamp.
-static const int LOCKTIME_THRESHOLD = 500000000; // Tue Nov 5 00:53:20 1985 UTC
+static const unsigned int LOCKTIME_THRESHOLD = 500000000; // Tue Nov 5 00:53:20 1985 UTC
#ifdef USE_UPNP
static const int fHaveUPnP = true;
#else
@@ -69,12 +66,13 @@ extern int64 nHPSTimerStart;
extern int64 nTimeBestReceived;
extern CCriticalSection cs_setpwalletRegistered;
extern std::set<CWallet*> setpwalletRegistered;
+extern unsigned char pchMessageStart[4];
// Settings
extern int64 nTransactionFee;
-
-
+// Minimum disk space required - used in CheckDiskSpace()
+static const uint64 nMinDiskSpace = 52428800;
class CReserveKey;
@@ -91,6 +89,7 @@ bool LoadBlockIndex(bool fAllowNew=true);
void PrintBlockTree();
bool ProcessMessages(CNode* pfrom);
bool SendMessages(CNode* pto, bool fSendTrickle);
+bool LoadExternalBlockFile(FILE* fileIn);
void GenerateBitcoins(bool fGenerate, CWallet* pwallet);
CBlock* CreateNewBlock(CReserveKey& reservekey);
void IncrementExtraNonce(CBlock* pblock, CBlockIndex* pindexPrev, unsigned int& nExtraNonce);
@@ -101,7 +100,7 @@ unsigned int ComputeMinWork(unsigned int nBase, int64 nTime);
int GetNumBlocksOfPeers();
bool IsInitialBlockDownload();
std::string GetWarnings(std::string strFor);
-
+bool GetTransaction(const uint256 &hash, CTransaction &tx, uint256 &hashBlock);
@@ -136,8 +135,8 @@ public:
}
IMPLEMENT_SERIALIZE( READWRITE(FLATDATA(*this)); )
- void SetNull() { nFile = -1; nBlockPos = 0; nTxPos = 0; }
- bool IsNull() const { return (nFile == -1); }
+ void SetNull() { nFile = (unsigned int) -1; nBlockPos = 0; nTxPos = 0; }
+ bool IsNull() const { return (nFile == (unsigned int) -1); }
friend bool operator==(const CDiskTxPos& a, const CDiskTxPos& b)
{
@@ -176,8 +175,8 @@ public:
CInPoint() { SetNull(); }
CInPoint(CTransaction* ptxIn, unsigned int nIn) { ptx = ptxIn; n = nIn; }
- void SetNull() { ptx = NULL; n = -1; }
- bool IsNull() const { return (ptx == NULL && n == -1); }
+ void SetNull() { ptx = NULL; n = (unsigned int) -1; }
+ bool IsNull() const { return (ptx == NULL && n == (unsigned int) -1); }
};
@@ -192,8 +191,8 @@ public:
COutPoint() { SetNull(); }
COutPoint(uint256 hashIn, unsigned int nIn) { hash = hashIn; n = nIn; }
IMPLEMENT_SERIALIZE( READWRITE(FLATDATA(*this)); )
- void SetNull() { hash = 0; n = -1; }
- bool IsNull() const { return (hash == 0 && n == -1); }
+ void SetNull() { hash = 0; n = (unsigned int) -1; }
+ bool IsNull() const { return (hash == 0 && n == (unsigned int) -1); }
friend bool operator<(const COutPoint& a, const COutPoint& b)
{
@@ -953,13 +952,7 @@ public:
// Flush stdio buffers and commit to disk before returning
fflush(fileout);
if (!IsInitialBlockDownload() || (nBestHeight+1) % 500 == 0)
- {
-#ifdef WIN32
- _commit(_fileno(fileout));
-#else
- fsync(fileno(fileout));
-#endif
- }
+ FileCommit(fileout);
return true;
}
@@ -1127,21 +1120,6 @@ public:
return CheckProofOfWork(GetBlockHash(), nBits);
}
- bool EraseBlockFromDisk()
- {
- // Open history file
- CAutoFile fileout = CAutoFile(OpenBlockFile(nFile, nBlockPos, "rb+"), SER_DISK, CLIENT_VERSION);
- if (!fileout)
- return false;
-
- // Overwrite with empty null block
- CBlock block;
- block.SetNull();
- fileout << block;
-
- return true;
- }
-
enum { nMedianTimeSpan=11 };
int64 GetMedianTimePast() const
@@ -1596,6 +1574,11 @@ public:
}
bool ProcessAlert();
+
+ /*
+ * Get copy of (active) alert object by hash. Returns a null alert if it is not found.
+ */
+ static CAlert getAlertByHash(const uint256 &hash);
};
class CTxMemPool
diff --git a/src/makefile.linux-mingw b/src/makefile.linux-mingw
index 81934187e2..51f49bb3cf 100644
--- a/src/makefile.linux-mingw
+++ b/src/makefile.linux-mingw
@@ -27,9 +27,9 @@ LIBS= \
-l ssl \
-l crypto
-DEFS=-D_MT -DWIN32 -D_WINDOWS -DBOOST_THREAD_USE_LIB
+DEFS=-D_MT -DWIN32 -D_WINDOWS -DBOOST_THREAD_USE_LIB -DBOOST_SPIRIT_THREADSAFE -DUSE_IPV6
DEBUGFLAGS=-g
-CFLAGS=-O2 -w -Wno-invalid-offsetof -Wformat $(DEBUGFLAGS) $(DEFS) $(INCLUDEPATHS)
+CFLAGS=-O2 -w -Wall -Wextra -Wformat -Wformat-security -Wno-unused-parameter $(DEBUGFLAGS) $(DEFS) $(INCLUDEPATHS)
TESTDEFS = -DTEST_DATA_DIR=$(abspath test/data)
@@ -61,6 +61,7 @@ OBJS= \
obj/bitcoinrpc.o \
obj/rpcdump.o \
obj/script.o \
+ obj/sync.o \
obj/util.o \
obj/wallet.o \
obj/walletdb.o \
@@ -69,7 +70,7 @@ OBJS= \
all: bitcoind.exe
obj/build.h: FORCE
- ../share/genbuild.sh obj/build.h
+ /bin/sh ../share/genbuild.sh obj/build.h
version.cpp: obj/build.h
DEFS += -DHAVE_BUILD_INFO
diff --git a/src/makefile.mingw b/src/makefile.mingw
index 917eb12fcf..577c77b7d4 100644
--- a/src/makefile.mingw
+++ b/src/makefile.mingw
@@ -23,9 +23,9 @@ LIBS= \
-l ssl \
-l crypto
-DEFS=-DWIN32 -D_WINDOWS -DBOOST_THREAD_USE_LIB
+DEFS=-DWIN32 -D_WINDOWS -DBOOST_THREAD_USE_LIB -DBOOST_SPIRIT_THREADSAFE -DUSE_IPV6
DEBUGFLAGS=-g
-CFLAGS=-mthreads -O2 -w -Wno-invalid-offsetof -Wformat $(DEBUGFLAGS) $(DEFS) $(INCLUDEPATHS)
+CFLAGS=-mthreads -O2 -w -Wall -Wextra -Wformat -Wformat-security -Wno-unused-parameter $(DEBUGFLAGS) $(DEFS) $(INCLUDEPATHS)
TESTDEFS = -DTEST_DATA_DIR=$(abspath test/data)
@@ -58,6 +58,7 @@ OBJS= \
obj/bitcoinrpc.o \
obj/rpcdump.o \
obj/script.o \
+ obj/sync.o \
obj/util.o \
obj/wallet.o \
obj/walletdb.o \
diff --git a/src/makefile.osx b/src/makefile.osx
index be95aab446..9728733122 100644
--- a/src/makefile.osx
+++ b/src/makefile.osx
@@ -53,7 +53,7 @@ LIBS += \
TESTDEFS += -DBOOST_TEST_DYN_LINK
endif
-DEFS=-DMAC_OSX -DMSG_NOSIGNAL=0
+DEFS=-DMAC_OSX -DMSG_NOSIGNAL=0 -DBOOST_SPIRIT_THREADSAFE -DUSE_IPV6
ifdef RELEASE
# Compile for maximum compatibility and smallest size.
@@ -65,7 +65,7 @@ CFLAGS = -g
endif
# ppc doesn't work because we don't support big-endian
-CFLAGS += -Wextra -Wno-sign-compare -Wno-invalid-offsetof -Wformat-security \
+CFLAGS += -Wall -Wextra -Wformat -Wformat-security -Wno-unused-parameter \
$(DEBUGFLAGS) $(DEFS) $(INCLUDEPATHS)
OBJS= \
@@ -85,6 +85,7 @@ OBJS= \
obj/bitcoinrpc.o \
obj/rpcdump.o \
obj/script.o \
+ obj/sync.o \
obj/util.o \
obj/wallet.o \
obj/walletdb.o \
@@ -106,7 +107,7 @@ all: bitcoind
-include obj-test/*.P
obj/build.h: FORCE
- ../share/genbuild.sh obj/build.h
+ /bin/sh ../share/genbuild.sh obj/build.h
version.cpp: obj/build.h
DEFS += -DHAVE_BUILD_INFO
diff --git a/src/makefile.unix b/src/makefile.unix
index 90be398976..9052891b4f 100644
--- a/src/makefile.unix
+++ b/src/makefile.unix
@@ -4,7 +4,7 @@
USE_UPNP:=0
-DEFS=
+DEFS=-DUSE_IPV6 -DBOOST_SPIRIT_THREADSAFE
DEFS += $(addprefix -I,$(CURDIR) $(CURDIR)/obj $(BOOST_INCLUDE_PATH) $(BDB_INCLUDE_PATH) $(OPENSSL_INCLUDE_PATH))
LIBS = $(addprefix -L,$(BOOST_LIB_PATH) $(BDB_LIB_PATH) $(OPENSSL_LIB_PATH))
@@ -82,8 +82,10 @@ LIBS+= \
DEBUGFLAGS=-g
-CXXFLAGS=-O2
-xCXXFLAGS=-pthread -Wall -Wextra -Wno-sign-compare -Wno-invalid-offsetof -Wno-unused-parameter -Wformat -Wformat-security \
+
+# CXXFLAGS can be specified on the make command line, so we use xCXXFLAGS that only
+# adds some defaults in front. Unfortunately, CXXFLAGS=... $(CXXFLAGS) does not work.
+xCXXFLAGS=-O2 -pthread -Wall -Wextra -Wformat -Wformat-security -Wno-unused-parameter \
$(DEBUGFLAGS) $(DEFS) $(HARDENING) $(CXXFLAGS)
OBJS= \
@@ -103,6 +105,7 @@ OBJS= \
obj/bitcoinrpc.o \
obj/rpcdump.o \
obj/script.o \
+ obj/sync.o \
obj/util.o \
obj/wallet.o \
obj/walletdb.o \
@@ -116,7 +119,7 @@ all: bitcoind
-include obj-test/*.P
obj/build.h: FORCE
- ../share/genbuild.sh obj/build.h
+ /bin/sh ../share/genbuild.sh obj/build.h
version.cpp: obj/build.h
DEFS += -DHAVE_BUILD_INFO
diff --git a/src/mruset.h b/src/mruset.h
index b21f18563c..ad2e160d3a 100644
--- a/src/mruset.h
+++ b/src/mruset.h
@@ -1,6 +1,6 @@
// Copyright (c) 2012 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
-// file license.txt or http://www.opensource.org/licenses/mit-license.php.
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifndef BITCOIN_MRUSET_H
#define BITCOIN_MRUSET_H
diff --git a/src/net.cpp b/src/net.cpp
index 92b4a3173f..4c795554a9 100644
--- a/src/net.cpp
+++ b/src/net.cpp
@@ -1,7 +1,7 @@
// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2012 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
-// file license.txt or http://www.opensource.org/licenses/mit-license.php.
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "irc.h"
#include "db.h"
@@ -35,22 +35,28 @@ void ThreadOpenAddedConnections2(void* parg);
void ThreadMapPort2(void* parg);
#endif
void ThreadDNSAddressSeed2(void* parg);
-bool OpenNetworkConnection(const CAddress& addrConnect);
+bool OpenNetworkConnection(const CAddress& addrConnect, CSemaphoreGrant *grantOutbound = NULL, const char *strDest = NULL, bool fOneShot = false);
+struct LocalServiceInfo {
+ int nScore;
+ int nPort;
+};
//
// Global state variables
//
bool fClient = false;
-bool fAllowDNS = false;
static bool fUseUPnP = false;
uint64 nLocalServices = (fClient ? 0 : NODE_NETWORK);
-CAddress addrLocalHost(CService("0.0.0.0", 0), nLocalServices);
+static CCriticalSection cs_mapLocalHost;
+static map<CNetAddr, LocalServiceInfo> mapLocalHost;
+static bool vfReachable[NET_MAX] = {};
+static bool vfLimited[NET_MAX] = {};
static CNode* pnodeLocalHost = NULL;
uint64 nLocalHostNonce = 0;
array<int, THREAD_MAX> vnThreadsRunning;
-static SOCKET hListenSocket = INVALID_SOCKET;
+static std::vector<SOCKET> vhListenSocket;
CAddrMan addrman;
vector<CNode*> vNodes;
@@ -60,14 +66,19 @@ deque<pair<int64, CInv> > vRelayExpiration;
CCriticalSection cs_mapRelay;
map<CInv, int64> mapAlreadyAskedFor;
+static deque<string> vOneShots;
+CCriticalSection cs_vOneShots;
set<CNetAddr> setservAddNodeAddresses;
CCriticalSection cs_setservAddNodeAddresses;
-static CWaitableCriticalSection csOutbound;
-static int nOutbound = 0;
-static CConditionVariable condOutbound;
+static CSemaphore *semOutbound = NULL;
+void AddOneShot(string strDest)
+{
+ LOCK(cs_vOneShots);
+ vOneShots.push_back(strDest);
+}
unsigned short GetListenPort()
{
@@ -85,7 +96,44 @@ void CNode::PushGetBlocks(CBlockIndex* pindexBegin, uint256 hashEnd)
PushMessage("getblocks", CBlockLocator(pindexBegin), hashEnd);
}
+// find 'best' local address for a particular peer
+bool GetLocal(CService& addr, const CNetAddr *paddrPeer)
+{
+ if (fUseProxy || mapArgs.count("-connect") || fNoListen)
+ return false;
+
+ int nBestScore = -1;
+ int nBestReachability = -1;
+ {
+ LOCK(cs_mapLocalHost);
+ for (map<CNetAddr, LocalServiceInfo>::iterator it = mapLocalHost.begin(); it != mapLocalHost.end(); it++)
+ {
+ int nScore = (*it).second.nScore;
+ int nReachability = (*it).first.GetReachabilityFrom(paddrPeer);
+ if (nReachability > nBestReachability || (nReachability == nBestReachability && nScore > nBestScore))
+ {
+ addr = CService((*it).first, (*it).second.nPort);
+ nBestReachability = nReachability;
+ nBestScore = nScore;
+ }
+ }
+ }
+ return nBestScore >= 0;
+}
+// get best local address for a particular peer as a CAddress
+CAddress GetLocalAddress(const CNetAddr *paddrPeer)
+{
+ CAddress ret(CService("0.0.0.0",0),0);
+ CService addr;
+ if (GetLocal(addr, paddrPeer))
+ {
+ ret = CAddress(addr);
+ ret.nServices = nLocalServices;
+ ret.nTime = GetAdjustedTime();
+ }
+ return ret;
+}
bool RecvLine(SOCKET hSocket, string& strLine)
{
@@ -138,7 +186,111 @@ bool RecvLine(SOCKET hSocket, string& strLine)
}
}
+// used when scores of local addresses may have changed
+// pushes better local address to peers
+void static AdvertizeLocal()
+{
+ LOCK(cs_vNodes);
+ BOOST_FOREACH(CNode* pnode, vNodes)
+ {
+ if (pnode->fSuccessfullyConnected)
+ {
+ CAddress addrLocal = GetLocalAddress(&pnode->addr);
+ if (addrLocal.IsRoutable() && (CService)addrLocal != (CService)pnode->addrLocal)
+ {
+ pnode->PushAddress(addrLocal);
+ pnode->addrLocal = addrLocal;
+ }
+ }
+ }
+}
+
+// learn a new local address
+bool AddLocal(const CService& addr, int nScore)
+{
+ if (!addr.IsRoutable())
+ return false;
+
+ if (!GetBoolArg("-discover", true) && nScore < LOCAL_MANUAL)
+ return false;
+
+ if (IsLimited(addr))
+ return false;
+
+ printf("AddLocal(%s,%i)\n", addr.ToString().c_str(), nScore);
+
+ {
+ LOCK(cs_mapLocalHost);
+ bool fAlready = mapLocalHost.count(addr) > 0;
+ LocalServiceInfo &info = mapLocalHost[addr];
+ if (!fAlready || nScore >= info.nScore) {
+ info.nScore = nScore;
+ info.nPort = addr.GetPort() + (fAlready ? 1 : 0);
+ }
+ enum Network net = addr.GetNetwork();
+ vfReachable[net] = true;
+ if (net == NET_IPV6) vfReachable[NET_IPV4] = true;
+ }
+
+ AdvertizeLocal();
+
+ return true;
+}
+
+bool AddLocal(const CNetAddr &addr, int nScore)
+{
+ return AddLocal(CService(addr, GetListenPort()), nScore);
+}
+
+/** Make a particular network entirely off-limits (no automatic connects to it) */
+void SetLimited(enum Network net, bool fLimited)
+{
+ if (net == NET_UNROUTABLE)
+ return;
+ LOCK(cs_mapLocalHost);
+ vfLimited[net] = fLimited;
+}
+
+bool IsLimited(enum Network net)
+{
+ LOCK(cs_mapLocalHost);
+ return vfLimited[net];
+}
+
+bool IsLimited(const CNetAddr &addr)
+{
+ return IsLimited(addr.GetNetwork());
+}
+
+/** vote for a local address */
+bool SeenLocal(const CService& addr)
+{
+ {
+ LOCK(cs_mapLocalHost);
+ if (mapLocalHost.count(addr) == 0)
+ return false;
+ mapLocalHost[addr].nScore++;
+ }
+
+ AdvertizeLocal();
+
+ return true;
+}
+
+/** check whether a given address is potentially local */
+bool IsLocal(const CService& addr)
+{
+ LOCK(cs_mapLocalHost);
+ return mapLocalHost.count(addr) > 0;
+}
+/** check whether a given address is in a network we can probably connect to */
+bool IsReachable(const CNetAddr& addr)
+{
+ LOCK(cs_mapLocalHost);
+ enum Network net = addr.GetNetwork();
+ return vfReachable[net] && !vfLimited[net];
+}
bool GetMyExternalIP2(const CService& addrConnect, const char* pszGet, const char* pszKeyword, CNetAddr& ipRet)
{
@@ -251,33 +403,11 @@ bool GetMyExternalIP(CNetAddr& ipRet)
void ThreadGetMyExternalIP(void* parg)
{
- // Wait for IRC to get it first
- if (GetBoolArg("-irc", false))
- {
- for (int i = 0; i < 2 * 60; i++)
- {
- Sleep(1000);
- if (fGotExternalIP || fShutdown)
- return;
- }
- }
-
- // Fallback in case IRC fails to get it
+ CNetAddr addrLocalHost;
if (GetMyExternalIP(addrLocalHost))
{
printf("GetMyExternalIP() returned %s\n", addrLocalHost.ToStringIP().c_str());
- if (addrLocalHost.IsRoutable())
- {
- // If we already connected to a few before we had our IP, go back and addr them.
- // setAddrKnown automatically filters any duplicate sends.
- CAddress addr(addrLocalHost);
- addr.nTime = GetAdjustedTime();
- {
- LOCK(cs_vNodes);
- BOOST_FOREACH(CNode* pnode, vNodes)
- pnode->PushAddress(addr);
- }
- }
+ AddLocal(addrLocalHost, LOCAL_HTTP);
}
}
@@ -307,6 +437,15 @@ CNode* FindNode(const CNetAddr& ip)
return NULL;
}
+CNode* FindNode(std::string addrName)
+{
+ LOCK(cs_vNodes);
+ BOOST_FOREACH(CNode* pnode, vNodes)
+ if (pnode->addrName == addrName)
+ return (pnode);
+ return NULL;
+}
+
CNode* FindNode(const CService& addr)
{
{
@@ -318,35 +457,38 @@ CNode* FindNode(const CService& addr)
return NULL;
}
-CNode* ConnectNode(CAddress addrConnect, int64 nTimeout)
+CNode* ConnectNode(CAddress addrConnect, const char *pszDest, int64 nTimeout)
{
- if ((CNetAddr)addrConnect == (CNetAddr)addrLocalHost)
- return NULL;
+ if (pszDest == NULL) {
+ if (IsLocal(addrConnect))
+ return NULL;
- // Look for an existing connection
- CNode* pnode = FindNode((CService)addrConnect);
- if (pnode)
- {
- if (nTimeout != 0)
- pnode->AddRef(nTimeout);
- else
- pnode->AddRef();
- return pnode;
+ // Look for an existing connection
+ CNode* pnode = FindNode((CService)addrConnect);
+ if (pnode)
+ {
+ if (nTimeout != 0)
+ pnode->AddRef(nTimeout);
+ else
+ pnode->AddRef();
+ return pnode;
+ }
}
+
/// debug print
printf("trying connection %s lastseen=%.1fhrs\n",
- addrConnect.ToString().c_str(),
- (double)(addrConnect.nTime - GetAdjustedTime())/3600.0);
-
- addrman.Attempt(addrConnect);
+ pszDest ? pszDest : addrConnect.ToString().c_str(),
+ pszDest ? 0 : (double)(addrConnect.nTime - GetAdjustedTime())/3600.0);
// Connect
SOCKET hSocket;
- if (ConnectSocket(addrConnect, hSocket))
+ if (pszDest ? ConnectSocketByName(addrConnect, hSocket, pszDest, GetDefaultPort()) : ConnectSocket(addrConnect, hSocket))
{
+ addrman.Attempt(addrConnect);
+
/// debug print
- printf("connected %s\n", addrConnect.ToString().c_str());
+ printf("connected %s\n", pszDest ? pszDest : addrConnect.ToString().c_str());
// Set to nonblocking
#ifdef WIN32
@@ -359,19 +501,16 @@ CNode* ConnectNode(CAddress addrConnect, int64 nTimeout)
#endif
// Add node
- CNode* pnode = new CNode(hSocket, addrConnect, false);
+ CNode* pnode = new CNode(hSocket, addrConnect, pszDest ? pszDest : "", false);
if (nTimeout != 0)
pnode->AddRef(nTimeout);
else
pnode->AddRef();
+
{
LOCK(cs_vNodes);
vNodes.push_back(pnode);
}
- {
- WAITABLE_LOCK(csOutbound);
- nOutbound++;
- }
pnode->nTimeConnected = GetTime();
return pnode;
@@ -387,9 +526,7 @@ void CNode::CloseSocketDisconnect()
fDisconnect = true;
if (hSocket != INVALID_SOCKET)
{
- if (fDebug)
- printf("%s ", DateTimeStrFormat("%x %H:%M:%S", GetTime()).c_str());
- printf("disconnecting node %s\n", addr.ToString().c_str());
+ printf("disconnecting node %s\n", addrName.c_str());
closesocket(hSocket);
hSocket = INVALID_SOCKET;
vRecv.clear();
@@ -406,7 +543,7 @@ void CNode::PushVersion()
/// when NTP implemented, change to just nTime = GetAdjustedTime()
int64 nTime = (fInbound ? GetAdjustedTime() : GetTime());
CAddress addrYou = (fUseProxy ? CAddress(CService("0.0.0.0",0)) : addr);
- CAddress addrMe = (fUseProxy || !addrLocalHost.IsRoutable() ? CAddress(CService("0.0.0.0",0)) : addrLocalHost);
+ CAddress addrMe = GetLocalAddress(&addr);
RAND_bytes((unsigned char*)&nLocalHostNonce, sizeof(nLocalHostNonce));
PushMessage("version", PROTOCOL_VERSION, nLocalServices, nTime, addrYou, addrMe,
nLocalHostNonce, FormatSubVersion(CLIENT_NAME, CLIENT_VERSION, std::vector<string>()), nBestHeight);
@@ -444,7 +581,7 @@ bool CNode::Misbehaving(int howmuch)
{
if (addr.IsLocal())
{
- printf("Warning: local node %s misbehaving\n", addr.ToString().c_str());
+ printf("Warning: local node %s misbehaving\n", addrName.c_str());
return false;
}
@@ -458,7 +595,7 @@ bool CNode::Misbehaving(int howmuch)
setBanned[addr] = banTime;
}
CloseSocketDisconnect();
- printf("Disconnected %s for misbehavior (score=%d)\n", addr.ToString().c_str(), nMisbehavior);
+ printf("Disconnected %s for misbehavior (score=%d)\n", addrName.c_str(), nMisbehavior);
return true;
}
return false;
@@ -491,7 +628,7 @@ void ThreadSocketHandler(void* parg)
vnThreadsRunning[THREAD_SOCKETHANDLER]--;
throw; // support pthread_cancel()
}
- printf("ThreadSocketHandler exiting\n");
+ printf("ThreadSocketHandler exited\n");
}
void ThreadSocketHandler2(void* parg)
@@ -517,14 +654,8 @@ void ThreadSocketHandler2(void* parg)
// remove from vNodes
vNodes.erase(remove(vNodes.begin(), vNodes.end(), pnode), vNodes.end());
- if (!pnode->fInbound)
- {
- WAITABLE_LOCK(csOutbound);
- nOutbound--;
-
- // Connection slot(s) were removed, notify connection creator(s)
- NOTIFY(condOutbound);
- }
+ // release outbound grant (if any)
+ pnode->grantOutbound.Release();
// close socket and cleanup
pnode->CloseSocketDisconnect();
@@ -574,7 +705,7 @@ void ThreadSocketHandler2(void* parg)
if (vNodes.size() != nPrevNodeCount)
{
nPrevNodeCount = vNodes.size();
- MainFrameRepaint();
+ uiInterface.NotifyNumConnectionsChanged(vNodes.size());
}
@@ -593,9 +724,10 @@ void ThreadSocketHandler2(void* parg)
FD_ZERO(&fdsetError);
SOCKET hSocketMax = 0;
- if(hListenSocket != INVALID_SOCKET)
+ BOOST_FOREACH(SOCKET hListenSocket, vhListenSocket) {
FD_SET(hListenSocket, &fdsetRecv);
- hSocketMax = max(hSocketMax, hListenSocket);
+ hSocketMax = max(hSocketMax, hListenSocket);
+ }
{
LOCK(cs_vNodes);
BOOST_FOREACH(CNode* pnode, vNodes)
@@ -621,7 +753,7 @@ void ThreadSocketHandler2(void* parg)
if (nSelect == SOCKET_ERROR)
{
int nErr = WSAGetLastError();
- if (hSocketMax > -1)
+ if (hSocketMax != INVALID_SOCKET)
{
printf("socket select error %d\n", nErr);
for (unsigned int i = 0; i <= hSocketMax; i++)
@@ -636,16 +768,22 @@ void ThreadSocketHandler2(void* parg)
//
// Accept new connections
//
+ BOOST_FOREACH(SOCKET hListenSocket, vhListenSocket)
if (hListenSocket != INVALID_SOCKET && FD_ISSET(hListenSocket, &fdsetRecv))
{
- struct sockaddr_in sockaddr;
+#ifdef USE_IPV6
+ struct sockaddr_storage sockaddr;
+#else
+ struct sockaddr sockaddr;
+#endif
socklen_t len = sizeof(sockaddr);
SOCKET hSocket = accept(hListenSocket, (struct sockaddr*)&sockaddr, &len);
CAddress addr;
int nInbound = 0;
if (hSocket != INVALID_SOCKET)
- addr = CAddress(sockaddr);
+ if (!addr.SetSockAddr((const struct sockaddr*)&sockaddr))
+ printf("warning: unknown socket family\n");
{
LOCK(cs_vNodes);
@@ -675,7 +813,7 @@ void ThreadSocketHandler2(void* parg)
else
{
printf("accepted connection %s\n", addr.ToString().c_str());
- CNode* pnode = new CNode(hSocket, addr, true);
+ CNode* pnode = new CNode(hSocket, addr, "", true);
pnode->AddRef();
{
LOCK(cs_vNodes);
@@ -847,7 +985,7 @@ void ThreadMapPort(void* parg)
vnThreadsRunning[THREAD_UPNP]--;
PrintException(NULL, "ThreadMapPort()");
}
- printf("ThreadMapPort exiting\n");
+ printf("ThreadMapPort exited\n");
}
void ThreadMapPort2(void* parg)
@@ -878,8 +1016,7 @@ void ThreadMapPort2(void* parg)
r = UPNP_GetValidIGD(devlist, &urls, &data, lanaddr, sizeof(lanaddr));
if (r == 1)
{
- if (!addrLocalHost.IsRoutable())
- {
+ if (GetBoolArg("-discover", true)) {
char externalIPAddress[40];
r = UPNP_GetExternalIPAddress(urls.controlURL, data.first.servicetype, externalIPAddress);
if(r != UPNPCOMMAND_SUCCESS)
@@ -889,9 +1026,7 @@ void ThreadMapPort2(void* parg)
if(externalIPAddress[0])
{
printf("UPnP: ExternalIPAddress = %s\n", externalIPAddress);
- CAddress addrExternalFromUPnP(CService(externalIPAddress, 0), nLocalServices);
- if (addrExternalFromUPnP.IsRoutable())
- addrLocalHost = addrExternalFromUPnP;
+ AddLocal(CNetAddr(externalIPAddress), LOCAL_UPNP);
}
else
printf("UPnP: GetExternalIPAddress failed.\n");
@@ -1012,7 +1147,7 @@ void ThreadDNSAddressSeed(void* parg)
vnThreadsRunning[THREAD_DNSSEED]--;
throw; // support pthread_cancel()
}
- printf("ThreadDNSAddressSeed exiting\n");
+ printf("ThreadDNSAddressSeed exited\n");
}
void ThreadDNSAddressSeed2(void* parg)
@@ -1025,20 +1160,24 @@ void ThreadDNSAddressSeed2(void* parg)
printf("Loading addresses from DNS seeds (could take a while)\n");
for (unsigned int seed_idx = 0; seed_idx < ARRAYLEN(strDNSSeed); seed_idx++) {
- vector<CNetAddr> vaddr;
- vector<CAddress> vAdd;
- if (LookupHost(strDNSSeed[seed_idx][1], vaddr))
- {
- BOOST_FOREACH(CNetAddr& ip, vaddr)
+ if (fProxyNameLookup) {
+ AddOneShot(strDNSSeed[seed_idx][1]);
+ } else {
+ vector<CNetAddr> vaddr;
+ vector<CAddress> vAdd;
+ if (LookupHost(strDNSSeed[seed_idx][1], vaddr))
{
- int nOneDay = 24*3600;
- CAddress addr = CAddress(CService(ip, GetDefaultPort()));
- addr.nTime = GetTime() - 3*nOneDay - GetRand(4*nOneDay); // use a random age between 3 and 7 days old
- vAdd.push_back(addr);
- found++;
+ BOOST_FOREACH(CNetAddr& ip, vaddr)
+ {
+ int nOneDay = 24*3600;
+ CAddress addr = CAddress(CService(ip, GetDefaultPort()));
+ addr.nTime = GetTime() - 3*nOneDay - GetRand(4*nOneDay); // use a random age between 3 and 7 days old
+ vAdd.push_back(addr);
+ found++;
+ }
}
+ addrman.Add(vAdd, CNetAddr(strDNSSeed[seed_idx][0], true));
}
- addrman.Add(vAdd, CNetAddr(strDNSSeed[seed_idx][0], true));
}
}
@@ -1139,8 +1278,13 @@ unsigned int pnSeed[] =
void DumpAddresses()
{
+ int64 nStart = GetTimeMillis();
+
CAddrDB adb;
- adb.WriteAddrman(addrman);
+ adb.Write(addrman);
+
+ printf("Flushed %d addresses to peers.dat %"PRI64d"ms\n",
+ addrman.size(), GetTimeMillis() - nStart);
}
void ThreadDumpAddress2(void* parg)
@@ -1166,7 +1310,7 @@ void ThreadDumpAddress(void* parg)
catch (std::exception& e) {
PrintException(&e, "ThreadDumpAddress()");
}
- printf("ThreadDumpAddress exiting\n");
+ printf("ThreadDumpAddress exited\n");
}
void ThreadOpenConnections(void* parg)
@@ -1185,7 +1329,25 @@ void ThreadOpenConnections(void* parg)
vnThreadsRunning[THREAD_OPENCONNECTIONS]--;
PrintException(NULL, "ThreadOpenConnections()");
}
- printf("ThreadOpenConnections exiting\n");
+ printf("ThreadOpenConnections exited\n");
+}
+
+void static ProcessOneShot()
+{
+ string strDest;
+ {
+ LOCK(cs_vOneShots);
+ if (vOneShots.empty())
+ return;
+ strDest = vOneShots.front();
+ vOneShots.pop_front();
+ }
+ CAddress addr;
+ CSemaphoreGrant grant(*semOutbound, true);
+ if (grant) {
+ if (!OpenNetworkConnection(addr, &grant, strDest.c_str(), true))
+ AddOneShot(strDest);
+ }
}
void ThreadOpenConnections2(void* parg)
@@ -1197,11 +1359,11 @@ void ThreadOpenConnections2(void* parg)
{
for (int64 nLoop = 0;; nLoop++)
{
+ ProcessOneShot();
BOOST_FOREACH(string strAddr, mapMultiArgs["-connect"])
{
- CAddress addr(CService(strAddr, GetDefaultPort(), fAllowDNS));
- if (addr.IsValid())
- OpenNetworkConnection(addr);
+ CAddress addr;
+ OpenNetworkConnection(addr, NULL, strAddr.c_str());
for (int i = 0; i < 10 && i < nLoop; i++)
{
Sleep(500);
@@ -1216,19 +1378,17 @@ void ThreadOpenConnections2(void* parg)
int64 nStart = GetTime();
loop
{
+ ProcessOneShot();
+
vnThreadsRunning[THREAD_OPENCONNECTIONS]--;
Sleep(500);
vnThreadsRunning[THREAD_OPENCONNECTIONS]++;
if (fShutdown)
return;
- // Limit outbound connections
- int nMaxOutbound = min(MAX_OUTBOUND_CONNECTIONS, (int)GetArg("-maxconnections", 125));
+
vnThreadsRunning[THREAD_OPENCONNECTIONS]--;
- {
- WAITABLE_LOCK(csOutbound);
- WAIT(condOutbound, fShutdown || nOutbound < nMaxOutbound);
- }
+ CSemaphoreGrant grant(*semOutbound);
vnThreadsRunning[THREAD_OPENCONNECTIONS]++;
if (fShutdown)
return;
@@ -1261,11 +1421,15 @@ void ThreadOpenConnections2(void* parg)
// Only connect to one address per a.b.?.? range.
// Do this here so we don't have to critsect vNodes inside mapAddresses critsect.
+ int nOutbound = 0;
set<vector<unsigned char> > setConnected;
{
LOCK(cs_vNodes);
- BOOST_FOREACH(CNode* pnode, vNodes)
+ BOOST_FOREACH(CNode* pnode, vNodes) {
setConnected.insert(pnode->addr.GetGroup());
+ if (!pnode->fInbound)
+ nOutbound++;
+ }
}
int64 nANow = GetAdjustedTime();
@@ -1277,11 +1441,14 @@ void ThreadOpenConnections2(void* parg)
CAddress addr = addrman.Select(10 + min(nOutbound,8)*10);
// if we selected an invalid address, restart
- if (!addr.IsIPv4() || !addr.IsValid() || setConnected.count(addr.GetGroup()) || addr == addrLocalHost)
+ if (!addr.IsValid() || setConnected.count(addr.GetGroup()) || IsLocal(addr))
break;
nTries++;
+ if (IsLimited(addr))
+ continue;
+
// only consider very recently tried nodes after 30 failed attempts
if (nANow - addr.nLastTry < 600 && nTries < 30)
continue;
@@ -1295,7 +1462,7 @@ void ThreadOpenConnections2(void* parg)
}
if (addrConnect.IsValid())
- OpenNetworkConnection(addrConnect);
+ OpenNetworkConnection(addrConnect, &grant);
}
}
@@ -1315,7 +1482,7 @@ void ThreadOpenAddedConnections(void* parg)
vnThreadsRunning[THREAD_ADDEDCONNECTIONS]--;
PrintException(NULL, "ThreadOpenAddedConnections()");
}
- printf("ThreadOpenAddedConnections exiting\n");
+ printf("ThreadOpenAddedConnections exited\n");
}
void ThreadOpenAddedConnections2(void* parg)
@@ -1325,11 +1492,26 @@ void ThreadOpenAddedConnections2(void* parg)
if (mapArgs.count("-addnode") == 0)
return;
+ if (fProxyNameLookup) {
+ while(!fShutdown) {
+ BOOST_FOREACH(string& strAddNode, mapMultiArgs["-addnode"]) {
+ CAddress addr;
+ CSemaphoreGrant grant(*semOutbound);
+ OpenNetworkConnection(addr, &grant, strAddNode.c_str());
+ Sleep(500);
+ }
+ vnThreadsRunning[THREAD_ADDEDCONNECTIONS]--;
+ Sleep(120000); // Retry every 2 minutes
+ vnThreadsRunning[THREAD_ADDEDCONNECTIONS]++;
+ }
+ return;
+ }
+
vector<vector<CService> > vservAddressesToAdd(0);
BOOST_FOREACH(string& strAddNode, mapMultiArgs["-addnode"])
{
vector<CService> vservNode(0);
- if(Lookup(strAddNode.c_str(), vservNode, GetDefaultPort(), fAllowDNS, 0))
+ if(Lookup(strAddNode.c_str(), vservNode, GetDefaultPort(), fNameLookup, 0))
{
vservAddressesToAdd.push_back(vservNode);
{
@@ -1343,7 +1525,7 @@ void ThreadOpenAddedConnections2(void* parg)
{
vector<vector<CService> > vservConnectAddresses = vservAddressesToAdd;
// Attempt to connect to each IP for each addnode entry until at least one is successful per addnode entry
- // (keeping in mind that addnode entries can have many IPs if fAllowDNS)
+ // (keeping in mind that addnode entries can have many IPs if fNameLookup)
{
LOCK(cs_vNodes);
BOOST_FOREACH(CNode* pnode, vNodes)
@@ -1358,7 +1540,8 @@ void ThreadOpenAddedConnections2(void* parg)
}
BOOST_FOREACH(vector<CService>& vserv, vservConnectAddresses)
{
- OpenNetworkConnection(CAddress(*(vserv.begin())));
+ CSemaphoreGrant grant(*semOutbound);
+ OpenNetworkConnection(CAddress(*(vserv.begin())), &grant);
Sleep(500);
if (fShutdown)
return;
@@ -1373,25 +1556,34 @@ void ThreadOpenAddedConnections2(void* parg)
}
}
-bool OpenNetworkConnection(const CAddress& addrConnect)
+// if succesful, this moves the passed grant to the constructed node
+bool OpenNetworkConnection(const CAddress& addrConnect, CSemaphoreGrant *grantOutbound, const char *strDest, bool fOneShot)
{
//
// Initiate outbound network connection
//
if (fShutdown)
return false;
- if ((CNetAddr)addrConnect == (CNetAddr)addrLocalHost || !addrConnect.IsIPv4() ||
- FindNode((CNetAddr)addrConnect) || CNode::IsBanned(addrConnect))
+ if (!strDest)
+ if (IsLocal(addrConnect) ||
+ FindNode((CNetAddr)addrConnect) || CNode::IsBanned(addrConnect) ||
+ FindNode(addrConnect.ToStringIPPort().c_str()))
+ return false;
+ if (strDest && FindNode(strDest))
return false;
vnThreadsRunning[THREAD_OPENCONNECTIONS]--;
- CNode* pnode = ConnectNode(addrConnect);
+ CNode* pnode = ConnectNode(addrConnect, strDest);
vnThreadsRunning[THREAD_OPENCONNECTIONS]++;
if (fShutdown)
return false;
if (!pnode)
return false;
+ if (grantOutbound)
+ grantOutbound->MoveTo(pnode->grantOutbound);
pnode->fNetworkNode = true;
+ if (fOneShot)
+ pnode->fOneShot = true;
return true;
}
@@ -1419,7 +1611,7 @@ void ThreadMessageHandler(void* parg)
vnThreadsRunning[THREAD_MESSAGEHANDLER]--;
PrintException(NULL, "ThreadMessageHandler()");
}
- printf("ThreadMessageHandler exiting\n");
+ printf("ThreadMessageHandler exited\n");
}
void ThreadMessageHandler2(void* parg)
@@ -1485,11 +1677,10 @@ void ThreadMessageHandler2(void* parg)
-bool BindListenPort(string& strError)
+bool BindListenPort(const CService &addrBind, string& strError)
{
strError = "";
int nOne = 1;
- addrLocalHost.SetPort(GetListenPort());
#ifdef WIN32
// Initialize Windows Sockets
@@ -1504,7 +1695,20 @@ bool BindListenPort(string& strError)
#endif
// Create socket for listening for incoming connections
- hListenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
+#ifdef USE_IPV6
+ struct sockaddr_storage sockaddr;
+#else
+ struct sockaddr sockaddr;
+#endif
+ socklen_t len = sizeof(sockaddr);
+ if (!addrBind.GetSockAddr((struct sockaddr*)&sockaddr, &len))
+ {
+ strError = strprintf("Error: bind address family for %s not supported", addrBind.ToString().c_str());
+ printf("%s\n", strError.c_str());
+ return false;
+ }
+
+ SOCKET hListenSocket = socket(((struct sockaddr*)&sockaddr)->sa_family, SOCK_STREAM, IPPROTO_TCP);
if (hListenSocket == INVALID_SOCKET)
{
strError = strprintf("Error: Couldn't open socket for incoming connections (socket returned error %d)", WSAGetLastError());
@@ -1523,6 +1727,7 @@ bool BindListenPort(string& strError)
setsockopt(hListenSocket, SOL_SOCKET, SO_REUSEADDR, (void*)&nOne, sizeof(int));
#endif
+
#ifdef WIN32
// Set to nonblocking, incoming connections will also inherit this
if (ioctlsocket(hListenSocket, FIONBIO, (u_long*)&nOne) == SOCKET_ERROR)
@@ -1535,24 +1740,33 @@ bool BindListenPort(string& strError)
return false;
}
- // The sockaddr_in structure specifies the address family,
- // IP address, and port for the socket that is being bound
- struct sockaddr_in sockaddr;
- memset(&sockaddr, 0, sizeof(sockaddr));
- sockaddr.sin_family = AF_INET;
- sockaddr.sin_addr.s_addr = INADDR_ANY; // bind to all IPs on this computer
- sockaddr.sin_port = htons(GetListenPort());
- if (::bind(hListenSocket, (struct sockaddr*)&sockaddr, sizeof(sockaddr)) == SOCKET_ERROR)
+#ifdef USE_IPV6
+ // some systems don't have IPV6_V6ONLY but are always v6only; others do have the option
+ // and enable it by default or not. Try to enable it, if possible.
+ if (addrBind.IsIPv6()) {
+#ifdef IPV6_V6ONLY
+ setsockopt(hListenSocket, IPPROTO_IPV6, IPV6_V6ONLY, (void*)&nOne, sizeof(int));
+#endif
+#ifdef WIN32
+ int nProtLevel = 10 /* PROTECTION_LEVEL_UNRESTRICTED */;
+ int nParameterId = 23 /* IPV6_PROTECTION_LEVEl */;
+ // this call is allowed to fail
+ setsockopt(hListenSocket, IPPROTO_IPV6, nParameterId, (const char*)&nProtLevel, sizeof(int));
+#endif
+ }
+#endif
+
+ if (::bind(hListenSocket, (struct sockaddr*)&sockaddr, len) == SOCKET_ERROR)
{
int nErr = WSAGetLastError();
if (nErr == WSAEADDRINUSE)
- strError = strprintf(_("Unable to bind to port %d on this computer. Bitcoin is probably already running."), ntohs(sockaddr.sin_port));
+ strError = strprintf(_("Unable to bind to %s on this computer. Bitcoin is probably already running."), addrBind.ToString().c_str());
else
- strError = strprintf("Error: Unable to bind to port %d on this computer (bind returned error %d)", ntohs(sockaddr.sin_port), nErr);
+ strError = strprintf(_("Unable to bind to %s on this computer (bind returned error %d, %s)"), addrBind.ToString().c_str(), nErr, strerror(nErr));
printf("%s\n", strError.c_str());
return false;
}
- printf("Bound to port %d\n", ntohs(sockaddr.sin_port));
+ printf("Bound to %s\n", addrBind.ToString().c_str());
// Listen for incoming connections
if (listen(hListenSocket, SOMAXCONN) == SOCKET_ERROR)
@@ -1562,21 +1776,18 @@ bool BindListenPort(string& strError)
return false;
}
+ vhListenSocket.push_back(hListenSocket);
+
+ if (addrBind.IsRoutable() && GetBoolArg("-discover", true))
+ AddLocal(addrBind, LOCAL_BIND);
+
return true;
}
-void StartNode(void* parg)
+void static Discover()
{
-#ifdef USE_UPNP
-#if USE_UPNP
- fUseUPnP = GetBoolArg("-upnp", true);
-#else
- fUseUPnP = GetBoolArg("-upnp", false);
-#endif
-#endif
-
- if (pnodeLocalHost == NULL)
- pnodeLocalHost = new CNode(INVALID_SOCKET, CAddress(CService("127.0.0.1", 0), nLocalServices));
+ if (!GetBoolArg("-discover", true))
+ return;
#ifdef WIN32
// Get local host ip
@@ -1588,11 +1799,7 @@ void StartNode(void* parg)
{
BOOST_FOREACH (const CNetAddr &addr, vaddr)
{
- if (!addr.IsLocal())
- {
- addrLocalHost.SetIP(addr);
- break;
- }
+ AddLocal(addr, LOCAL_IF);
}
}
}
@@ -1607,43 +1814,53 @@ void StartNode(void* parg)
if ((ifa->ifa_flags & IFF_UP) == 0) continue;
if (strcmp(ifa->ifa_name, "lo") == 0) continue;
if (strcmp(ifa->ifa_name, "lo0") == 0) continue;
- char pszIP[100];
if (ifa->ifa_addr->sa_family == AF_INET)
{
struct sockaddr_in* s4 = (struct sockaddr_in*)(ifa->ifa_addr);
- if (inet_ntop(ifa->ifa_addr->sa_family, (void*)&(s4->sin_addr), pszIP, sizeof(pszIP)) != NULL)
- printf("ipv4 %s: %s\n", ifa->ifa_name, pszIP);
-
- // Take the first IP that isn't loopback 127.x.x.x
- CAddress addr(CService(s4->sin_addr, GetListenPort()), nLocalServices);
- if (addr.IsValid() && !addr.IsLocal())
- {
- addrLocalHost = addr;
- break;
- }
+ CNetAddr addr(s4->sin_addr);
+ if (AddLocal(addr, LOCAL_IF))
+ printf("IPv4 %s: %s\n", ifa->ifa_name, addr.ToString().c_str());
}
+#ifdef USE_IPV6
else if (ifa->ifa_addr->sa_family == AF_INET6)
{
struct sockaddr_in6* s6 = (struct sockaddr_in6*)(ifa->ifa_addr);
- if (inet_ntop(ifa->ifa_addr->sa_family, (void*)&(s6->sin6_addr), pszIP, sizeof(pszIP)) != NULL)
- printf("ipv6 %s: %s\n", ifa->ifa_name, pszIP);
+ CNetAddr addr(s6->sin6_addr);
+ if (AddLocal(addr, LOCAL_IF))
+ printf("IPv6 %s: %s\n", ifa->ifa_name, addr.ToString().c_str());
}
+#endif
}
freeifaddrs(myaddrs);
}
#endif
- printf("addrLocalHost = %s\n", addrLocalHost.ToString().c_str());
- if (fUseProxy || mapArgs.count("-connect") || fNoListen)
- {
- // Proxies can't take incoming connections
- addrLocalHost.SetIP(CNetAddr("0.0.0.0"));
- printf("addrLocalHost = %s\n", addrLocalHost.ToString().c_str());
- }
- else
+ if (!fUseProxy && !mapArgs.count("-connect") && !fNoListen)
{
CreateThread(ThreadGetMyExternalIP, NULL);
}
+}
+
+void StartNode(void* parg)
+{
+#ifdef USE_UPNP
+#if USE_UPNP
+ fUseUPnP = GetBoolArg("-upnp", true);
+#else
+ fUseUPnP = GetBoolArg("-upnp", false);
+#endif
+#endif
+
+ if (semOutbound == NULL) {
+ // initialize semaphore
+ int nMaxOutbound = min(MAX_OUTBOUND_CONNECTIONS, (int)GetArg("-maxconnections", 125));
+ semOutbound = new CSemaphore(nMaxOutbound);
+ }
+
+ if (pnodeLocalHost == NULL)
+ pnodeLocalHost = new CNode(INVALID_SOCKET, CAddress(CService("127.0.0.1", 0), nLocalServices));
+
+ Discover();
//
// Start threads
@@ -1693,7 +1910,9 @@ bool StopNode()
fShutdown = true;
nTransactionsUpdated++;
int64 nStart = GetTime();
- NOTIFY_ALL(condOutbound);
+ if (semOutbound)
+ for (int i=0; i<MAX_OUTBOUND_CONNECTIONS; i++)
+ semOutbound->post();
do
{
int nThreadsRunning = 0;
@@ -1709,12 +1928,13 @@ bool StopNode()
if (vnThreadsRunning[THREAD_OPENCONNECTIONS] > 0) printf("ThreadOpenConnections still running\n");
if (vnThreadsRunning[THREAD_MESSAGEHANDLER] > 0) printf("ThreadMessageHandler still running\n");
if (vnThreadsRunning[THREAD_MINER] > 0) printf("ThreadBitcoinMiner still running\n");
- if (vnThreadsRunning[THREAD_RPCSERVER] > 0) printf("ThreadRPCServer still running\n");
+ if (vnThreadsRunning[THREAD_RPCLISTENER] > 0) printf("ThreadRPCListener still running\n");
+ if (vnThreadsRunning[THREAD_RPCHANDLER] > 0) printf("ThreadsRPCServer still running\n");
if (fHaveUPnP && vnThreadsRunning[THREAD_UPNP] > 0) printf("ThreadMapPort still running\n");
if (vnThreadsRunning[THREAD_DNSSEED] > 0) printf("ThreadDNSAddressSeed still running\n");
if (vnThreadsRunning[THREAD_ADDEDCONNECTIONS] > 0) printf("ThreadOpenAddedConnections still running\n");
if (vnThreadsRunning[THREAD_DUMPADDRESS] > 0) printf("ThreadDumpAddresses still running\n");
- while (vnThreadsRunning[THREAD_MESSAGEHANDLER] > 0 || vnThreadsRunning[THREAD_RPCSERVER] > 0)
+ while (vnThreadsRunning[THREAD_MESSAGEHANDLER] > 0 || vnThreadsRunning[THREAD_RPCHANDLER] > 0)
Sleep(20);
Sleep(50);
DumpAddresses();
@@ -1733,9 +1953,10 @@ public:
BOOST_FOREACH(CNode* pnode, vNodes)
if (pnode->hSocket != INVALID_SOCKET)
closesocket(pnode->hSocket);
- if (hListenSocket != INVALID_SOCKET)
- if (closesocket(hListenSocket) == SOCKET_ERROR)
- printf("closesocket(hListenSocket) failed with error %d\n", WSAGetLastError());
+ BOOST_FOREACH(SOCKET hListenSocket, vhListenSocket)
+ if (hListenSocket != INVALID_SOCKET)
+ if (closesocket(hListenSocket) == SOCKET_ERROR)
+ printf("closesocket(hListenSocket) failed with error %d\n", WSAGetLastError());
#ifdef WIN32
// Shutdown Windows Sockets
diff --git a/src/net.h b/src/net.h
index bad49a9f8f..8075328b13 100644
--- a/src/net.h
+++ b/src/net.h
@@ -1,7 +1,7 @@
// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2012 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
-// file license.txt or http://www.opensource.org/licenses/mit-license.php.
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifndef BITCOIN_NET_H
#define BITCOIN_NET_H
@@ -19,7 +19,6 @@
#include "protocol.h"
#include "addrman.h"
-class CAddrDB;
class CRequestTracker;
class CNode;
class CBlockIndex;
@@ -30,19 +29,46 @@ extern int nBestHeight;
inline unsigned int ReceiveBufferSize() { return 1000*GetArg("-maxreceivebuffer", 10*1000); }
inline unsigned int SendBufferSize() { return 1000*GetArg("-maxsendbuffer", 10*1000); }
+void AddOneShot(std::string strDest);
bool RecvLine(SOCKET hSocket, std::string& strLine);
bool GetMyExternalIP(CNetAddr& ipRet);
void AddressCurrentlyConnected(const CService& addr);
CNode* FindNode(const CNetAddr& ip);
CNode* FindNode(const CService& ip);
-CNode* ConnectNode(CAddress addrConnect, int64 nTimeout=0);
+CNode* ConnectNode(CAddress addrConnect, const char *strDest = NULL, int64 nTimeout=0);
void MapPort(bool fMapPort);
-bool BindListenPort(std::string& strError=REF(std::string()));
+unsigned short GetListenPort();
+bool BindListenPort(const CService &bindAddr, std::string& strError=REF(std::string()));
void StartNode(void* parg);
bool StopNode();
enum
{
+ LOCAL_NONE, // unknown
+ LOCAL_IF, // address a local interface listens on
+ LOCAL_BIND, // address explicit bound to
+ LOCAL_UPNP, // address reported by UPnP
+ LOCAL_IRC, // address reported by IRC (deprecated)
+ LOCAL_HTTP, // address reported by whatismyip.com and similars
+ LOCAL_MANUAL, // address explicitly specified (-externalip=)
+
+ LOCAL_MAX
+};
+
+void SetLimited(enum Network net, bool fLimited = true);
+bool IsLimited(enum Network net);
+bool IsLimited(const CNetAddr& addr);
+bool AddLocal(const CService& addr, int nScore = LOCAL_NONE);
+bool AddLocal(const CNetAddr& addr, int nScore = LOCAL_NONE);
+bool SeenLocal(const CService& addr);
+bool IsLocal(const CService& addr);
+bool GetLocal(CService &addr, const CNetAddr *paddrPeer = NULL);
+bool IsReachable(const CNetAddr &addr);
+CAddress GetLocalAddress(const CNetAddr *paddrPeer = NULL);
+
+
+enum
+{
MSG_TX = 1,
MSG_BLOCK,
};
@@ -73,19 +99,18 @@ enum threadId
THREAD_OPENCONNECTIONS,
THREAD_MESSAGEHANDLER,
THREAD_MINER,
- THREAD_RPCSERVER,
+ THREAD_RPCLISTENER,
THREAD_UPNP,
THREAD_DNSSEED,
THREAD_ADDEDCONNECTIONS,
THREAD_DUMPADDRESS,
+ THREAD_RPCHANDLER,
THREAD_MAX
};
extern bool fClient;
-extern bool fAllowDNS;
extern uint64 nLocalServices;
-extern CAddress addrLocalHost;
extern uint64 nLocalHostNonce;
extern boost::array<int, THREAD_MAX> vnThreadsRunning;
extern CAddrMan addrman;
@@ -120,13 +145,17 @@ public:
int nHeaderStart;
unsigned int nMessageStart;
CAddress addr;
+ std::string addrName;
+ CService addrLocal;
int nVersion;
std::string strSubVer;
+ bool fOneShot;
bool fClient;
bool fInbound;
bool fNetworkNode;
bool fSuccessfullyConnected;
bool fDisconnect;
+ CSemaphoreGrant grantOutbound;
protected:
int nRefCount;
@@ -157,7 +186,7 @@ public:
CCriticalSection cs_inventory;
std::multimap<int64, CInv> mapAskFor;
- CNode(SOCKET hSocketIn, CAddress addrIn, bool fInboundIn=false) : vSend(SER_NETWORK, MIN_PROTO_VERSION), vRecv(SER_NETWORK, MIN_PROTO_VERSION)
+ CNode(SOCKET hSocketIn, CAddress addrIn, std::string addrNameIn = "", bool fInboundIn=false) : vSend(SER_NETWORK, MIN_PROTO_VERSION), vRecv(SER_NETWORK, MIN_PROTO_VERSION)
{
nServices = 0;
hSocket = hSocketIn;
@@ -168,8 +197,10 @@ public:
nHeaderStart = -1;
nMessageStart = -1;
addr = addrIn;
+ addrName = addrNameIn == "" ? addr.ToStringIPPort() : addrNameIn;
nVersion = 0;
strSubVer = "";
+ fOneShot = false;
fClient = false; // set by version message
fInbound = fInboundIn;
fNetworkNode = false;
@@ -287,10 +318,8 @@ public:
nHeaderStart = vSend.size();
vSend << CMessageHeader(pszCommand, 0);
nMessageStart = vSend.size();
- if (fDebug) {
- printf("%s ", DateTimeStrFormat("%x %H:%M:%S", GetTime()).c_str());
+ if (fDebug)
printf("sending: %s ", pszCommand);
- }
}
void AbortMessage()
diff --git a/src/netbase.cpp b/src/netbase.cpp
index 8b30ffc140..7de06eaef8 100644
--- a/src/netbase.cpp
+++ b/src/netbase.cpp
@@ -1,7 +1,7 @@
// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2012 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
-// file license.txt or http://www.opensource.org/licenses/mit-license.php.
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "netbase.h"
#include "util.h"
@@ -11,17 +11,36 @@
#endif
#include "strlcpy.h"
+#include <boost/algorithm/string/case_conv.hpp> // for to_lower()
using namespace std;
// Settings
+int nSocksVersion = 5;
int fUseProxy = false;
+bool fProxyNameLookup = false;
+bool fNameLookup = false;
CService addrProxy("127.0.0.1",9050);
int nConnectTimeout = 5000;
+static bool vfNoProxy[NET_MAX] = {};
static const unsigned char pchIPv4[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff };
+enum Network ParseNetwork(std::string net) {
+ boost::to_lower(net);
+ if (net == "ipv4") return NET_IPV4;
+ if (net == "ipv6") return NET_IPV6;
+ if (net == "tor") return NET_TOR;
+ if (net == "i2p") return NET_I2P;
+ return NET_UNROUTABLE;
+}
+
+void SetNoProxy(enum Network net, bool fNoProxy) {
+ assert(net >= 0 && net < NET_MAX);
+ vfNoProxy[net] = fNoProxy;
+}
+
bool static LookupIntern(const char *pszName, std::vector<CNetAddr>& vIP, unsigned int nMaxSolutions, bool fAllowLookup)
{
vIP.clear();
@@ -156,11 +175,169 @@ bool LookupNumeric(const char *pszName, CService& addr, int portDefault)
return Lookup(pszName, addr, portDefault, false);
}
-bool ConnectSocket(const CService &addrDest, SOCKET& hSocketRet, int nTimeout)
+bool static Socks4(const CService &addrDest, SOCKET& hSocket)
+{
+ printf("SOCKS4 connecting %s\n", addrDest.ToString().c_str());
+ if (!addrDest.IsIPv4())
+ {
+ closesocket(hSocket);
+ return error("Proxy destination is not IPv4");
+ }
+ char pszSocks4IP[] = "\4\1\0\0\0\0\0\0user";
+ struct sockaddr_in addr;
+ socklen_t len = sizeof(addr);
+ if (!addrDest.GetSockAddr((struct sockaddr*)&addr, &len) || addr.sin_family != AF_INET)
+ {
+ closesocket(hSocket);
+ return error("Cannot get proxy destination address");
+ }
+ memcpy(pszSocks4IP + 2, &addr.sin_port, 2);
+ memcpy(pszSocks4IP + 4, &addr.sin_addr, 4);
+ char* pszSocks4 = pszSocks4IP;
+ int nSize = sizeof(pszSocks4IP);
+
+ int ret = send(hSocket, pszSocks4, nSize, MSG_NOSIGNAL);
+ if (ret != nSize)
+ {
+ closesocket(hSocket);
+ return error("Error sending to proxy");
+ }
+ char pchRet[8];
+ if (recv(hSocket, pchRet, 8, 0) != 8)
+ {
+ closesocket(hSocket);
+ return error("Error reading proxy response");
+ }
+ if (pchRet[1] != 0x5a)
+ {
+ closesocket(hSocket);
+ if (pchRet[1] != 0x5b)
+ printf("ERROR: Proxy returned error %d\n", pchRet[1]);
+ return false;
+ }
+ printf("SOCKS4 connected %s\n", addrDest.ToString().c_str());
+ return true;
+}
+
+bool static Socks5(string strDest, int port, SOCKET& hSocket)
+{
+ printf("SOCKS5 connecting %s\n", strDest.c_str());
+ if (strDest.size() > 255)
+ {
+ closesocket(hSocket);
+ return error("Hostname too long");
+ }
+ char pszSocks5Init[] = "\5\1\0";
+ char *pszSocks5 = pszSocks5Init;
+ ssize_t nSize = sizeof(pszSocks5Init);
+
+ ssize_t ret = send(hSocket, pszSocks5, nSize, MSG_NOSIGNAL);
+ if (ret != nSize)
+ {
+ closesocket(hSocket);
+ return error("Error sending to proxy");
+ }
+ char pchRet1[2];
+ if (recv(hSocket, pchRet1, 2, 0) != 2)
+ {
+ closesocket(hSocket);
+ return error("Error reading proxy response");
+ }
+ if (pchRet1[0] != 0x05 || pchRet1[1] != 0x00)
+ {
+ closesocket(hSocket);
+ return error("Proxy failed to initialize");
+ }
+ string strSocks5("\5\1");
+ strSocks5 += '\000'; strSocks5 += '\003';
+ strSocks5 += static_cast<char>(std::min((int)strDest.size(), 255));
+ strSocks5 += strDest;
+ strSocks5 += static_cast<char>((port >> 8) & 0xFF);
+ strSocks5 += static_cast<char>((port >> 0) & 0xFF);
+ ret = send(hSocket, strSocks5.c_str(), strSocks5.size(), MSG_NOSIGNAL);
+ if (ret != (ssize_t)strSocks5.size())
+ {
+ closesocket(hSocket);
+ return error("Error sending to proxy");
+ }
+ char pchRet2[4];
+ if (recv(hSocket, pchRet2, 4, 0) != 4)
+ {
+ closesocket(hSocket);
+ return error("Error reading proxy response");
+ }
+ if (pchRet2[0] != 0x05)
+ {
+ closesocket(hSocket);
+ return error("Proxy failed to accept request");
+ }
+ if (pchRet2[1] != 0x00)
+ {
+ closesocket(hSocket);
+ switch (pchRet2[1])
+ {
+ case 0x01: return error("Proxy error: general failure");
+ case 0x02: return error("Proxy error: connection not allowed");
+ case 0x03: return error("Proxy error: network unreachable");
+ case 0x04: return error("Proxy error: host unreachable");
+ case 0x05: return error("Proxy error: connection refused");
+ case 0x06: return error("Proxy error: TTL expired");
+ case 0x07: return error("Proxy error: protocol error");
+ case 0x08: return error("Proxy error: address type not supported");
+ default: return error("Proxy error: unknown");
+ }
+ }
+ if (pchRet2[2] != 0x00)
+ {
+ closesocket(hSocket);
+ return error("Error: malformed proxy response");
+ }
+ char pchRet3[256];
+ switch (pchRet2[3])
+ {
+ case 0x01: ret = recv(hSocket, pchRet3, 4, 0) != 4; break;
+ case 0x04: ret = recv(hSocket, pchRet3, 16, 0) != 16; break;
+ case 0x03:
+ {
+ ret = recv(hSocket, pchRet3, 1, 0) != 1;
+ if (ret)
+ return error("Error reading from proxy");
+ int nRecv = pchRet3[0];
+ ret = recv(hSocket, pchRet3, nRecv, 0) != nRecv;
+ break;
+ }
+ default: closesocket(hSocket); return error("Error: malformed proxy response");
+ }
+ if (ret)
+ {
+ closesocket(hSocket);
+ return error("Error reading from proxy");
+ }
+ if (recv(hSocket, pchRet3, 2, 0) != 2)
+ {
+ closesocket(hSocket);
+ return error("Error reading from proxy");
+ }
+ printf("SOCKS5 connected %s\n", strDest.c_str());
+ return true;
+}
+
+bool static ConnectSocketDirectly(const CService &addrConnect, SOCKET& hSocketRet, int nTimeout)
{
hSocketRet = INVALID_SOCKET;
- SOCKET hSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
+#ifdef USE_IPV6
+ struct sockaddr_storage sockaddr;
+#else
+ struct sockaddr sockaddr;
+#endif
+ socklen_t len = sizeof(sockaddr);
+ if (!addrConnect.GetSockAddr((struct sockaddr*)&sockaddr, &len)) {
+ printf("Cannot connect to %s: unsupported network\n", addrConnect.ToString().c_str());
+ return false;
+ }
+
+ SOCKET hSocket = socket(((struct sockaddr*)&sockaddr)->sa_family, SOCK_STREAM, IPPROTO_TCP);
if (hSocket == INVALID_SOCKET)
return false;
#ifdef SO_NOSIGPIPE
@@ -168,13 +345,6 @@ bool ConnectSocket(const CService &addrDest, SOCKET& hSocketRet, int nTimeout)
setsockopt(hSocket, SOL_SOCKET, SO_NOSIGPIPE, (void*)&set, sizeof(int));
#endif
- bool fProxy = (fUseProxy && addrDest.IsRoutable());
- struct sockaddr_in sockaddr;
- if (fProxy)
- addrProxy.GetSockAddr(&sockaddr);
- else
- addrDest.GetSockAddr(&sockaddr);
-
#ifdef WIN32
u_long fNonblock = 1;
if (ioctlsocket(hSocket, FIONBIO, &fNonblock) == SOCKET_ERROR)
@@ -187,8 +357,7 @@ bool ConnectSocket(const CService &addrDest, SOCKET& hSocketRet, int nTimeout)
return false;
}
-
- if (connect(hSocket, (struct sockaddr*)&sockaddr, sizeof(sockaddr)) == SOCKET_ERROR)
+ if (connect(hSocket, (struct sockaddr*)&sockaddr, len) == SOCKET_ERROR)
{
// WSAEINVAL is here because some legacy version of winsock uses it
if (WSAGetLastError() == WSAEINPROGRESS || WSAGetLastError() == WSAEWOULDBLOCK || WSAGetLastError() == WSAEINVAL)
@@ -258,38 +427,78 @@ bool ConnectSocket(const CService &addrDest, SOCKET& hSocketRet, int nTimeout)
return false;
}
+ hSocketRet = hSocket;
+ return true;
+}
+
+bool ConnectSocket(const CService &addrDest, SOCKET& hSocketRet, int nTimeout)
+{
+ SOCKET hSocket = INVALID_SOCKET;
+ bool fProxy = (fUseProxy && addrDest.IsRoutable() && !vfNoProxy[addrDest.GetNetwork()]);
+
+ if (!ConnectSocketDirectly(fProxy ? addrProxy : addrDest, hSocket, nTimeout))
+ return false;
+
if (fProxy)
{
- printf("proxy connecting %s\n", addrDest.ToString().c_str());
- char pszSocks4IP[] = "\4\1\0\0\0\0\0\0user";
- struct sockaddr_in addr;
- addrDest.GetSockAddr(&addr);
- memcpy(pszSocks4IP + 2, &addr.sin_port, 2);
- memcpy(pszSocks4IP + 4, &addr.sin_addr, 4);
- char* pszSocks4 = pszSocks4IP;
- int nSize = sizeof(pszSocks4IP);
-
- int ret = send(hSocket, pszSocks4, nSize, MSG_NOSIGNAL);
- if (ret != nSize)
+ switch(nSocksVersion)
{
- closesocket(hSocket);
- return error("Error sending to proxy");
- }
- char pchRet[8];
- if (recv(hSocket, pchRet, 8, 0) != 8)
- {
- closesocket(hSocket);
- return error("Error reading proxy response");
+ case 4:
+ if (!Socks4(addrDest, hSocket))
+ return false;
+ break;
+
+ case 5:
+ default:
+ if (!Socks5(addrDest.ToStringIP(), addrDest.GetPort(), hSocket))
+ return false;
+ break;
+ }
+ }
+
+ hSocketRet = hSocket;
+ return true;
+}
+
+bool ConnectSocketByName(CService &addr, SOCKET& hSocketRet, const char *pszDest, int portDefault, int nTimeout)
+{
+ string strDest(pszDest);
+ int port = portDefault;
+
+ size_t colon = strDest.find_last_of(':');
+ if (colon != strDest.npos) {
+ char *endp = NULL;
+ int n = strtol(pszDest + colon + 1, &endp, 10);
+ if (endp && *endp == 0 && n >= 0) {
+ strDest = strDest.substr(0, colon);
+ if (n > 0 && n < 0x10000)
+ port = n;
}
- if (pchRet[1] != 0x5a)
+ }
+ if (strDest[0] == '[' && strDest[strDest.size()-1] == ']')
+ strDest = strDest.substr(1, strDest.size()-2);
+
+ SOCKET hSocket = INVALID_SOCKET;
+ CService addrResolved(CNetAddr(strDest, fNameLookup && !fProxyNameLookup), port);
+ if (addrResolved.IsValid()) {
+ addr = addrResolved;
+ return ConnectSocket(addr, hSocketRet, nTimeout);
+ }
+ addr = CService("0.0.0.0:0");
+ if (!fNameLookup)
+ return false;
+ if (!ConnectSocketDirectly(addrProxy, hSocket, nTimeout))
+ return false;
+
+ switch(nSocksVersion)
{
- closesocket(hSocket);
- if (pchRet[1] != 0x5b)
- printf("ERROR: Proxy returned error %d\n", pchRet[1]);
- return false;
+ case 4: return false;
+ case 5:
+ default:
+ if (!Socks5(strDest, port, hSocket))
+ return false;
+ break;
}
- printf("proxy connected %s\n", addrDest.ToString().c_str());
- }
hSocketRet = hSocket;
return true;
@@ -349,6 +558,11 @@ bool CNetAddr::IsIPv4() const
return (memcmp(ip, pchIPv4, sizeof(pchIPv4)) == 0);
}
+bool CNetAddr::IsIPv6() const
+{
+ return (!IsIPv4());
+}
+
bool CNetAddr::IsRFC1918() const
{
return IsIPv4() && (
@@ -405,6 +619,18 @@ bool CNetAddr::IsRFC4843() const
return (GetByte(15) == 0x20 && GetByte(14) == 0x01 && GetByte(13) == 0x00 && (GetByte(12) & 0xF0) == 0x10);
}
+bool CNetAddr::IsOnionCat() const
+{
+ static const unsigned char pchOnionCat[] = {0xFD,0x87,0xD8,0x7E,0xEB,0x43};
+ return (memcmp(ip, pchOnionCat, sizeof(pchOnionCat)) == 0);
+}
+
+bool CNetAddr::IsGarliCat() const
+{
+ static const unsigned char pchGarliCat[] = {0xFD,0x60,0xDB,0x4D,0xDD,0xB5};
+ return (memcmp(ip, pchGarliCat, sizeof(pchGarliCat)) == 0);
+}
+
bool CNetAddr::IsLocal() const
{
// IPv4 loopback
@@ -463,12 +689,41 @@ bool CNetAddr::IsValid() const
bool CNetAddr::IsRoutable() const
{
- return IsValid() && !(IsRFC1918() || IsRFC3927() || IsRFC4862() || IsRFC4193() || IsRFC4843() || IsLocal());
+ return IsValid() && !(IsRFC1918() || IsRFC3927() || IsRFC4862() || (IsRFC4193() && !IsOnionCat() && !IsGarliCat()) || IsRFC4843() || IsLocal());
}
-std::string CNetAddr::ToStringIP() const
+enum Network CNetAddr::GetNetwork() const
{
+ if (!IsRoutable())
+ return NET_UNROUTABLE;
+
if (IsIPv4())
+ return NET_IPV4;
+
+ if (IsOnionCat())
+ return NET_TOR;
+
+ if (IsGarliCat())
+ return NET_I2P;
+
+ return NET_IPV6;
+}
+
+std::string CNetAddr::ToStringIP() const
+{
+ CService serv(*this, 0);
+#ifdef USE_IPV6
+ struct sockaddr_storage sockaddr;
+#else
+ struct sockaddr sockaddr;
+#endif
+ socklen_t socklen = sizeof(sockaddr);
+ if (serv.GetSockAddr((struct sockaddr*)&sockaddr, &socklen)) {
+ char name[1025] = "";
+ if (!getnameinfo((const struct sockaddr*)&sockaddr, socklen, name, sizeof(name), NULL, 0, NI_NUMERICHOST))
+ return std::string(name);
+ }
+ if (IsIPv4())
return strprintf("%u.%u.%u.%u", GetByte(3), GetByte(2), GetByte(1), GetByte(0));
else
return strprintf("%x:%x:%x:%x:%x:%x:%x:%x",
@@ -519,40 +774,40 @@ bool CNetAddr::GetIn6Addr(struct in6_addr* pipv6Addr) const
std::vector<unsigned char> CNetAddr::GetGroup() const
{
std::vector<unsigned char> vchRet;
- int nClass = 0; // 0=IPv6, 1=IPv4, 254=local, 255=unroutable
+ int nClass = NET_IPV6;
int nStartByte = 0;
int nBits = 16;
// all local addresses belong to the same group
if (IsLocal())
{
- nClass = 254;
+ nClass = 255;
nBits = 0;
}
// all unroutable addresses belong to the same group
if (!IsRoutable())
{
- nClass = 255;
+ nClass = NET_UNROUTABLE;
nBits = 0;
}
// for IPv4 addresses, '1' + the 16 higher-order bits of the IP
// includes mapped IPv4, SIIT translated IPv4, and the well-known prefix
else if (IsIPv4() || IsRFC6145() || IsRFC6052())
{
- nClass = 1;
+ nClass = NET_IPV4;
nStartByte = 12;
}
// for 6to4 tunneled addresses, use the encapsulated IPv4 address
else if (IsRFC3964())
{
- nClass = 1;
+ nClass = NET_IPV4;
nStartByte = 2;
}
// for Teredo-tunneled IPv6 addresses, use the encapsulated IPv4 address
else if (IsRFC4380())
{
- vchRet.push_back(1);
+ vchRet.push_back(NET_IPV4);
vchRet.push_back(GetByte(3) ^ 0xFF);
vchRet.push_back(GetByte(2) ^ 0xFF);
return vchRet;
@@ -590,6 +845,29 @@ void CNetAddr::print() const
printf("CNetAddr(%s)\n", ToString().c_str());
}
+// for IPv6 partners: for unknown/Teredo partners: for IPv4 partners:
+// 0 - unroutable // 0 - unroutable // 0 - unroutable
+// 1 - teredo // 1 - teredo // 1 - ipv4
+// 2 - tunneled ipv6 // 2 - tunneled ipv6
+// 3 - ipv4 // 3 - ipv6
+// 4 - ipv6 // 4 - ipv4
+int CNetAddr::GetReachabilityFrom(const CNetAddr *paddrPartner) const
+{
+ if (!IsValid() || !IsRoutable())
+ return 0;
+ if (paddrPartner && paddrPartner->IsIPv4())
+ return IsIPv4() ? 1 : 0;
+ if (IsRFC4380())
+ return 1;
+ if (IsRFC3964() || IsRFC6052())
+ return 2;
+ bool fRealIPv6 = paddrPartner && !paddrPartner->IsRFC4380() && paddrPartner->IsValid() && paddrPartner->IsRoutable();
+ if (fRealIPv6)
+ return IsIPv4() ? 3 : 4;
+ else
+ return IsIPv4() ? 4 : 3;
+}
+
void CService::Init()
{
port = 0;
@@ -626,6 +904,22 @@ CService::CService(const struct sockaddr_in6 &addr) : CNetAddr(addr.sin6_addr),
}
#endif
+bool CService::SetSockAddr(const struct sockaddr *paddr)
+{
+ switch (paddr->sa_family) {
+ case AF_INET:
+ *this = CService(*(const struct sockaddr_in*)paddr);
+ return true;
+#ifdef USE_IPV6
+ case AF_INET6:
+ *this = CService(*(const struct sockaddr_in6*)paddr);
+ return true;
+#endif
+ default:
+ return false;
+ }
+}
+
CService::CService(const char *pszIpPort, bool fAllowLookup)
{
Init();
@@ -678,29 +972,36 @@ bool operator<(const CService& a, const CService& b)
return (CNetAddr)a < (CNetAddr)b || ((CNetAddr)a == (CNetAddr)b && a.port < b.port);
}
-bool CService::GetSockAddr(struct sockaddr_in* paddr) const
+bool CService::GetSockAddr(struct sockaddr* paddr, socklen_t *addrlen) const
{
- if (!IsIPv4())
- return false;
- memset(paddr, 0, sizeof(struct sockaddr_in));
- if (!GetInAddr(&paddr->sin_addr))
- return false;
- paddr->sin_family = AF_INET;
- paddr->sin_port = htons(port);
- return true;
-}
-
+ if (IsIPv4()) {
+ if (*addrlen < sizeof(struct sockaddr_in))
+ return false;
+ *addrlen = sizeof(struct sockaddr_in);
+ struct sockaddr_in *paddrin = (struct sockaddr_in*)paddr;
+ memset(paddrin, 0, *addrlen);
+ if (!GetInAddr(&paddrin->sin_addr))
+ return false;
+ paddrin->sin_family = AF_INET;
+ paddrin->sin_port = htons(port);
+ return true;
+ }
#ifdef USE_IPV6
-bool CService::GetSockAddr6(struct sockaddr_in6* paddr) const
-{
- memset(paddr, 0, sizeof(struct sockaddr_in6));
- if (!GetIn6Addr(&paddr->sin6_addr))
- return false;
- paddr->sin6_family = AF_INET6;
- paddr->sin6_port = htons(port);
- return true;
-}
+ if (IsIPv6()) {
+ if (*addrlen < sizeof(struct sockaddr_in6))
+ return false;
+ *addrlen = sizeof(struct sockaddr_in6);
+ struct sockaddr_in6 *paddrin6 = (struct sockaddr_in6*)paddr;
+ memset(paddrin6, 0, *addrlen);
+ if (!GetIn6Addr(&paddrin6->sin6_addr))
+ return false;
+ paddrin6->sin6_family = AF_INET6;
+ paddrin6->sin6_port = htons(port);
+ return true;
+ }
#endif
+ return false;
+}
std::vector<unsigned char> CService::GetKey() const
{
@@ -714,12 +1015,16 @@ std::vector<unsigned char> CService::GetKey() const
std::string CService::ToStringPort() const
{
- return strprintf(":%i", port);
+ return strprintf("%i", port);
}
std::string CService::ToStringIPPort() const
{
- return ToStringIP() + ToStringPort();
+ if (IsIPv4()) {
+ return ToStringIP() + ":" + ToStringPort();
+ } else {
+ return "[" + ToStringIP() + "]:" + ToStringPort();
+ }
}
std::string CService::ToString() const
diff --git a/src/netbase.h b/src/netbase.h
index 00b6850b2a..2cbc8bd8a2 100644
--- a/src/netbase.h
+++ b/src/netbase.h
@@ -1,6 +1,6 @@
// Copyright (c) 2009-2012 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
-// file license.txt or http://www.opensource.org/licenses/mit-license.php.
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifndef BITCOIN_NETBASE_H
#define BITCOIN_NETBASE_H
@@ -17,6 +17,20 @@ extern int nConnectTimeout;
#undef SetPort
#endif
+enum Network
+{
+ NET_UNROUTABLE,
+ NET_IPV4,
+ NET_IPV6,
+ NET_TOR,
+ NET_I2P,
+
+ NET_MAX
+};
+
+enum Network ParseNetwork(std::string net);
+void SetNoProxy(enum Network net, bool fNoProxy = true);
+
/** IP address (IPv6, or IPv4 using mapped IPv6 range (::FFFF:0:0/96)) */
class CNetAddr
{
@@ -31,6 +45,7 @@ class CNetAddr
void Init();
void SetIP(const CNetAddr& ip);
bool IsIPv4() const; // IPv4 mapped address (::FFFF:0:0/96, 0.0.0.0/0)
+ bool IsIPv6() const; // IPv6 address (not IPv4)
bool IsRFC1918() const; // IPv4 private networks (10.0.0.0/8, 192.168.0.0/16, 172.16.0.0/12)
bool IsRFC3849() const; // IPv6 documentation address (2001:0DB8::/32)
bool IsRFC3927() const; // IPv4 autoconfig (169.254.0.0/16)
@@ -41,16 +56,20 @@ class CNetAddr
bool IsRFC4862() const; // IPv6 autoconfig (FE80::/64)
bool IsRFC6052() const; // IPv6 well-known prefix (64:FF9B::/96)
bool IsRFC6145() const; // IPv6 IPv4-translated address (::FFFF:0:0:0/96)
+ bool IsOnionCat() const;
+ bool IsGarliCat() const;
bool IsLocal() const;
bool IsRoutable() const;
bool IsValid() const;
bool IsMulticast() const;
+ enum Network GetNetwork() const;
std::string ToString() const;
std::string ToStringIP() const;
int GetByte(int n) const;
int64 GetHash() const;
bool GetInAddr(struct in_addr* pipv4Addr) const;
std::vector<unsigned char> GetGroup() const;
+ int GetReachabilityFrom(const CNetAddr *paddrPartner = NULL) const;
void print() const;
#ifdef USE_IPV6
@@ -86,7 +105,8 @@ class CService : public CNetAddr
void Init();
void SetPort(unsigned short portIn);
unsigned short GetPort() const;
- bool GetSockAddr(struct sockaddr_in* paddr) const;
+ bool GetSockAddr(struct sockaddr* paddr, socklen_t *addrlen) const;
+ bool SetSockAddr(const struct sockaddr* paddr);
friend bool operator==(const CService& a, const CService& b);
friend bool operator!=(const CService& a, const CService& b);
friend bool operator<(const CService& a, const CService& b);
@@ -98,7 +118,6 @@ class CService : public CNetAddr
#ifdef USE_IPV6
CService(const struct in6_addr& ipv6Addr, unsigned short port);
- bool GetSockAddr6(struct sockaddr_in6* paddr) const;
CService(const struct sockaddr_in6& addr);
#endif
@@ -119,9 +138,13 @@ bool Lookup(const char *pszName, CService& addr, int portDefault = 0, bool fAllo
bool Lookup(const char *pszName, std::vector<CService>& vAddr, int portDefault = 0, bool fAllowLookup = true, unsigned int nMaxSolutions = 0);
bool LookupNumeric(const char *pszName, CService& addr, int portDefault = 0);
bool ConnectSocket(const CService &addr, SOCKET& hSocketRet, int nTimeout = nConnectTimeout);
+bool ConnectSocketByName(CService &addr, SOCKET& hSocketRet, const char *pszDest, int portDefault = 0, int nTimeout = nConnectTimeout);
// Settings
+extern int nSocksVersion;
extern int fUseProxy;
+extern bool fProxyNameLookup;
+extern bool fNameLookup;
extern CService addrProxy;
#endif
diff --git a/src/noui.cpp b/src/noui.cpp
index 08a08b439a..3ba7e729f5 100644
--- a/src/noui.cpp
+++ b/src/noui.cpp
@@ -1,44 +1,35 @@
// Copyright (c) 2010 Satoshi Nakamoto
// Copyright (c) 2009-2012 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
-// file license.txt or http://www.opensource.org/licenses/mit-license.php.
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "ui_interface.h"
+#include "init.h"
+#include "bitcoinrpc.h"
#include <string>
-#include "init.h"
-int ThreadSafeMessageBox(const std::string& message, const std::string& caption, int style)
+static int noui_ThreadSafeMessageBox(const std::string& message, const std::string& caption, int style)
{
printf("%s: %s\n", caption.c_str(), message.c_str());
fprintf(stderr, "%s: %s\n", caption.c_str(), message.c_str());
return 4;
}
-bool ThreadSafeAskFee(int64 nFeeRequired, const std::string& strCaption)
+static bool noui_ThreadSafeAskFee(int64 nFeeRequired, const std::string& strCaption)
{
return true;
}
-void MainFrameRepaint()
-{
-}
-
-void AddressBookRepaint()
-{
-}
-
-void InitMessage(const std::string &message)
-{
-}
-
-std::string _(const char* psz)
-{
- return psz;
-}
-
-void QueueShutdown()
+static void noui_QueueShutdown()
{
// Without UI, Shutdown can simply be started in a new thread
CreateThread(Shutdown, NULL);
}
+void noui_connect()
+{
+ // Connect bitcoind signal handlers
+ uiInterface.ThreadSafeMessageBox.connect(noui_ThreadSafeMessageBox);
+ uiInterface.ThreadSafeAskFee.connect(noui_ThreadSafeAskFee);
+ uiInterface.QueueShutdown.connect(noui_QueueShutdown);
+}
diff --git a/src/protocol.cpp b/src/protocol.cpp
index fda31966f2..d6e340e366 100644
--- a/src/protocol.cpp
+++ b/src/protocol.cpp
@@ -1,7 +1,7 @@
// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2012 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
-// file license.txt or http://www.opensource.org/licenses/mit-license.php.
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "protocol.h"
#include "util.h"
diff --git a/src/protocol.h b/src/protocol.h
index f7331c1923..b516f1b897 100644
--- a/src/protocol.h
+++ b/src/protocol.h
@@ -1,7 +1,7 @@
// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2012 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
-// file license.txt or http://www.opensource.org/licenses/mit-license.php.
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifndef __cplusplus
# error This header can only be compiled as C++.
diff --git a/src/qt/addressbookpage.cpp b/src/qt/addressbookpage.cpp
index 3e55c39e04..c207987561 100644
--- a/src/qt/addressbookpage.cpp
+++ b/src/qt/addressbookpage.cpp
@@ -58,25 +58,34 @@ AddressBookPage::AddressBookPage(Mode mode, Tabs tab, QWidget *parent) :
ui->signMessage->setVisible(true);
break;
}
- ui->tableView->setTabKeyNavigation(false);
- ui->tableView->setContextMenuPolicy(Qt::CustomContextMenu);
// Context menu actions
- QAction *copyAddressAction = new QAction(tr("Copy address"), this);
- QAction *copyLabelAction = new QAction(tr("Copy label"), this);
- QAction *editAction = new QAction(tr("Edit"), this);
- deleteAction = new QAction(tr("Delete"), this);
-
+ QAction *copyLabelAction = new QAction(tr("Copy &Label"), this);
+ QAction *copyAddressAction = new QAction(ui->copyToClipboard->text(), this);
+ QAction *editAction = new QAction(tr("&Edit"), this);
+ QAction *showQRCodeAction = new QAction(ui->showQRCode->text(), this);
+ QAction *signMessageAction = new QAction(ui->signMessage->text(), this);
+ deleteAction = new QAction(ui->deleteButton->text(), this);
+
+ // Build context menu
contextMenu = new QMenu();
contextMenu->addAction(copyAddressAction);
contextMenu->addAction(copyLabelAction);
contextMenu->addAction(editAction);
- contextMenu->addAction(deleteAction);
-
+ if(tab == SendingTab)
+ contextMenu->addAction(deleteAction);
+ contextMenu->addSeparator();
+ contextMenu->addAction(showQRCodeAction);
+ if(tab == ReceivingTab)
+ contextMenu->addAction(signMessageAction);
+
+ // Connect signals for context menu actions
connect(copyAddressAction, SIGNAL(triggered()), this, SLOT(on_copyToClipboard_clicked()));
connect(copyLabelAction, SIGNAL(triggered()), this, SLOT(onCopyLabelAction()));
connect(editAction, SIGNAL(triggered()), this, SLOT(onEditAction()));
connect(deleteAction, SIGNAL(triggered()), this, SLOT(on_deleteButton_clicked()));
+ connect(showQRCodeAction, SIGNAL(triggered()), this, SLOT(on_showQRCode_clicked()));
+ connect(signMessageAction, SIGNAL(triggered()), this, SLOT(on_signMessage_clicked()));
connect(ui->tableView, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(contextualMenu(QPoint)));
@@ -123,6 +132,10 @@ void AddressBookPage::setModel(AddressTableModel *model)
connect(ui->tableView->selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)),
this, SLOT(selectionChanged()));
+ // Select row for newly created address
+ connect(model, SIGNAL(rowsInserted(QModelIndex,int,int)),
+ this, SLOT(selectNewAddress(QModelIndex,int,int)));
+
if(mode == ForSending)
{
// Auto-select first row when in sending mode
@@ -184,20 +197,11 @@ void AddressBookPage::on_newAddressButton_clicked()
EditAddressDialog dlg(
tab == SendingTab ?
EditAddressDialog::NewSendingAddress :
- EditAddressDialog::NewReceivingAddress);
+ EditAddressDialog::NewReceivingAddress, this);
dlg.setModel(model);
if(dlg.exec())
{
- // Select row for newly created address
- QString address = dlg.getAddress();
- QModelIndexList lst = proxyModel->match(proxyModel->index(0,
- AddressTableModel::Address, QModelIndex()),
- Qt::EditRole, address, 1, Qt::MatchExactly);
- if(!lst.isEmpty())
- {
- ui->tableView->setFocus();
- ui->tableView->selectRow(lst.at(0).row());
- }
+ newAddressToSelect = dlg.getAddress();
}
}
@@ -315,6 +319,7 @@ void AddressBookPage::on_showQRCode_clicked()
QString address = index.data().toString(), label = index.sibling(index.row(), 0).data(Qt::EditRole).toString();
QRCodeDialog *dialog = new QRCodeDialog(address, label, tab == ReceivingTab, this);
+ dialog->setAttribute(Qt::WA_DeleteOnClose);
dialog->show();
}
#endif
@@ -328,3 +333,15 @@ void AddressBookPage::contextualMenu(const QPoint &point)
contextMenu->exec(QCursor::pos());
}
}
+
+void AddressBookPage::selectNewAddress(const QModelIndex &parent, int begin, int end)
+{
+ QModelIndex idx = proxyModel->mapFromSource(model->index(begin, AddressTableModel::Address, parent));
+ if(idx.isValid() && (idx.data(Qt::EditRole).toString() == newAddressToSelect))
+ {
+ // Select row of newly created address, once
+ ui->tableView->setFocus();
+ ui->tableView->selectRow(idx.row());
+ newAddressToSelect.clear();
+ }
+}
diff --git a/src/qt/addressbookpage.h b/src/qt/addressbookpage.h
index b2cf2db979..b2e91c7cb2 100644
--- a/src/qt/addressbookpage.h
+++ b/src/qt/addressbookpage.h
@@ -13,6 +13,7 @@ class QTableView;
class QItemSelection;
class QSortFilterProxyModel;
class QMenu;
+class QModelIndex;
QT_END_NAMESPACE
/** Widget that shows a list of sending or receiving addresses.
@@ -51,6 +52,7 @@ private:
QSortFilterProxyModel *proxyModel;
QMenu *contextMenu;
QAction *deleteAction;
+ QString newAddressToSelect;
private slots:
void on_deleteButton_clicked();
@@ -67,6 +69,9 @@ private slots:
void onCopyLabelAction();
/** Edit currently selected address entry */
void onEditAction();
+
+ /** New entry/entries were added to address table */
+ void selectNewAddress(const QModelIndex &parent, int begin, int end);
};
#endif // ADDRESSBOOKDIALOG_H
diff --git a/src/qt/addresstablemodel.cpp b/src/qt/addresstablemodel.cpp
index 7b95f51c04..75ea2c12c5 100644
--- a/src/qt/addresstablemodel.cpp
+++ b/src/qt/addresstablemodel.cpp
@@ -26,20 +26,36 @@ struct AddressTableEntry
type(type), label(label), address(address) {}
};
+struct AddressTableEntryLessThan
+{
+ bool operator()(const AddressTableEntry &a, const AddressTableEntry &b) const
+ {
+ return a.address < b.address;
+ }
+ bool operator()(const AddressTableEntry &a, const QString &b) const
+ {
+ return a.address < b;
+ }
+ bool operator()(const QString &a, const AddressTableEntry &b) const
+ {
+ return a < b.address;
+ }
+};
+
// Private implementation
class AddressTablePriv
{
public:
CWallet *wallet;
QList<AddressTableEntry> cachedAddressTable;
+ AddressTableModel *parent;
- AddressTablePriv(CWallet *wallet):
- wallet(wallet) {}
+ AddressTablePriv(CWallet *wallet, AddressTableModel *parent):
+ wallet(wallet), parent(parent) {}
void refreshAddressTable()
{
cachedAddressTable.clear();
-
{
LOCK(wallet->cs_wallet);
BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress, std::string)& item, wallet->mapAddressBook)
@@ -54,6 +70,53 @@ public:
}
}
+ void updateEntry(const QString &address, const QString &label, bool isMine, int status)
+ {
+ // Find address / label in model
+ QList<AddressTableEntry>::iterator lower = qLowerBound(
+ cachedAddressTable.begin(), cachedAddressTable.end(), address, AddressTableEntryLessThan());
+ QList<AddressTableEntry>::iterator upper = qUpperBound(
+ cachedAddressTable.begin(), cachedAddressTable.end(), address, AddressTableEntryLessThan());
+ int lowerIndex = (lower - cachedAddressTable.begin());
+ int upperIndex = (upper - cachedAddressTable.begin());
+ bool inModel = (lower != upper);
+ AddressTableEntry::Type newEntryType = isMine ? AddressTableEntry::Receiving : AddressTableEntry::Sending;
+
+ switch(status)
+ {
+ case CT_NEW:
+ if(inModel)
+ {
+ OutputDebugStringF("Warning: AddressTablePriv::updateEntry: Got CT_NOW, but entry is already in model\n");
+ break;
+ }
+ parent->beginInsertRows(QModelIndex(), lowerIndex, lowerIndex);
+ cachedAddressTable.insert(lowerIndex, AddressTableEntry(newEntryType, label, address));
+ parent->endInsertRows();
+ break;
+ case CT_UPDATED:
+ if(!inModel)
+ {
+ OutputDebugStringF("Warning: AddressTablePriv::updateEntry: Got CT_UPDATED, but entry is not in model\n");
+ break;
+ }
+ lower->type = newEntryType;
+ lower->label = label;
+ parent->emitDataChanged(lowerIndex);
+ break;
+ case CT_DELETED:
+ if(!inModel)
+ {
+ OutputDebugStringF("Warning: AddressTablePriv::updateEntry: Got CT_DELETED, but entry is not in model\n");
+ break;
+ }
+ parent->beginRemoveRows(QModelIndex(), lowerIndex, upperIndex-1);
+ cachedAddressTable.erase(lower, upper);
+ parent->endRemoveRows();
+ break;
+ }
+ }
+
int size()
{
return cachedAddressTable.size();
@@ -76,7 +139,7 @@ AddressTableModel::AddressTableModel(CWallet *wallet, WalletModel *parent) :
QAbstractTableModel(parent),walletModel(parent),wallet(wallet),priv(0)
{
columns << tr("Label") << tr("Address");
- priv = new AddressTablePriv(wallet);
+ priv = new AddressTablePriv(wallet, this);
priv->refreshAddressTable();
}
@@ -158,7 +221,6 @@ bool AddressTableModel::setData(const QModelIndex & index, const QVariant & valu
{
case Label:
wallet->SetAddressBookName(rec->address.toStdString(), value.toString().toStdString());
- rec->label = value.toString();
break;
case Address:
// Refuse to set invalid address, set error status and return false
@@ -177,12 +239,9 @@ bool AddressTableModel::setData(const QModelIndex & index, const QVariant & valu
// Add new entry with new address
wallet->SetAddressBookName(value.toString().toStdString(), rec->label.toStdString());
}
-
- rec->address = value.toString();
}
break;
}
- emit dataChanged(index, index);
return true;
}
@@ -232,12 +291,10 @@ QModelIndex AddressTableModel::index(int row, int column, const QModelIndex & pa
}
}
-void AddressTableModel::update()
+void AddressTableModel::updateEntry(const QString &address, const QString &label, bool isMine, int status)
{
// Update address book model from Bitcoin core
- beginResetModel();
- priv->refreshAddressTable();
- endResetModel();
+ priv->updateEntry(address, label, isMine, status);
}
QString AddressTableModel::addRow(const QString &type, const QString &label, const QString &address)
@@ -341,3 +398,7 @@ int AddressTableModel::lookupAddress(const QString &address) const
}
}
+void AddressTableModel::emitDataChanged(int idx)
+{
+ emit dataChanged(index(idx, 0, QModelIndex()), index(idx, columns.length()-1, QModelIndex()));
+}
diff --git a/src/qt/addresstablemodel.h b/src/qt/addresstablemodel.h
index 7fd07cfb81..42974e3e1f 100644
--- a/src/qt/addresstablemodel.h
+++ b/src/qt/addresstablemodel.h
@@ -74,13 +74,18 @@ private:
QStringList columns;
EditStatus editStatus;
+ /** Notify listeners that data changed. */
+ void emitDataChanged(int index);
+
signals:
void defaultAddressChanged(const QString &address);
public slots:
- /* Update address list from core. Invalidates any indices.
+ /* Update address list from core.
*/
- void update();
+ void updateEntry(const QString &address, const QString &label, bool isMine, int status);
+
+ friend class AddressTablePriv;
};
#endif // ADDRESSTABLEMODEL_H
diff --git a/src/qt/askpassphrasedialog.cpp b/src/qt/askpassphrasedialog.cpp
index 31e4040d1d..0a8ace09df 100644
--- a/src/qt/askpassphrasedialog.cpp
+++ b/src/qt/askpassphrasedialog.cpp
@@ -24,7 +24,6 @@ AskPassphraseDialog::AskPassphraseDialog(Mode mode, QWidget *parent) :
ui->passEdit1->installEventFilter(this);
ui->passEdit2->installEventFilter(this);
ui->passEdit3->installEventFilter(this);
- ui->capsLabel->clear();
switch(mode)
{
@@ -215,7 +214,7 @@ bool AskPassphraseDialog::event(QEvent *event)
bool AskPassphraseDialog::eventFilter(QObject *, QEvent *event)
{
- /* Detect Caps Lock.
+ /* Detect Caps Lock.
* There is no good OS-independent way to check a key state in Qt, but we
* can detect Caps Lock by checking for the following condition:
* Shift key is down and the result is a lower case character, or
diff --git a/src/qt/bitcoin.cpp b/src/qt/bitcoin.cpp
index 7c262e14cd..bdc6ea6ffd 100644
--- a/src/qt/bitcoin.cpp
+++ b/src/qt/bitcoin.cpp
@@ -6,6 +6,7 @@
#include "walletmodel.h"
#include "optionsmodel.h"
#include "guiutil.h"
+#include "guiconstants.h"
#include "init.h"
#include "ui_interface.h"
@@ -20,6 +21,7 @@
#include <QLibraryInfo>
#include <boost/interprocess/ipc/message_queue.hpp>
+#include <boost/algorithm/string/predicate.hpp>
#if defined(BITCOIN_NEED_QT_PLUGINS) && !defined(_BITCOIN_QT_PLUGINS_INCLUDED)
#define _BITCOIN_QT_PLUGINS_INCLUDED
@@ -35,15 +37,13 @@ Q_IMPORT_PLUGIN(qtaccessiblewidgets)
// Need a global reference for the notifications to find the GUI
static BitcoinGUI *guiref;
static QSplashScreen *splashref;
-static WalletModel *walletmodel;
-static ClientModel *clientmodel;
-int ThreadSafeMessageBox(const std::string& message, const std::string& caption, int style)
+static void ThreadSafeMessageBox(const std::string& message, const std::string& caption, int style)
{
// Message from network thread
if(guiref)
{
- bool modal = (style & wxMODAL);
+ bool modal = (style & CClientUIInterface::MODAL);
// in case of modal message, use blocking connection to wait for user to click OK
QMetaObject::invokeMethod(guiref, "error",
modal ? GUIUtil::blockingGUIThreadConnection() : Qt::QueuedConnection,
@@ -56,10 +56,9 @@ int ThreadSafeMessageBox(const std::string& message, const std::string& caption,
printf("%s: %s\n", caption.c_str(), message.c_str());
fprintf(stderr, "%s: %s\n", caption.c_str(), message.c_str());
}
- return 4;
}
-bool ThreadSafeAskFee(int64 nFeeRequired, const std::string& strCaption)
+static bool ThreadSafeAskFee(int64 nFeeRequired, const std::string& strCaption)
{
if(!guiref)
return false;
@@ -74,7 +73,7 @@ bool ThreadSafeAskFee(int64 nFeeRequired, const std::string& strCaption)
return payFee;
}
-void ThreadSafeHandleURI(const std::string& strURI)
+static void ThreadSafeHandleURI(const std::string& strURI)
{
if(!guiref)
return;
@@ -83,21 +82,7 @@ void ThreadSafeHandleURI(const std::string& strURI)
Q_ARG(QString, QString::fromStdString(strURI)));
}
-void MainFrameRepaint()
-{
- if(clientmodel)
- QMetaObject::invokeMethod(clientmodel, "update", Qt::QueuedConnection);
- if(walletmodel)
- QMetaObject::invokeMethod(walletmodel, "update", Qt::QueuedConnection);
-}
-
-void AddressBookRepaint()
-{
- if(walletmodel)
- QMetaObject::invokeMethod(walletmodel, "updateAddressList", Qt::QueuedConnection);
-}
-
-void InitMessage(const std::string &message)
+static void InitMessage(const std::string &message)
{
if(splashref)
{
@@ -106,7 +91,7 @@ void InitMessage(const std::string &message)
}
}
-void QueueShutdown()
+static void QueueShutdown()
{
QMetaObject::invokeMethod(QCoreApplication::instance(), "quit", Qt::QueuedConnection);
}
@@ -114,7 +99,7 @@ void QueueShutdown()
/*
Translate string to current locale using Qt.
*/
-std::string _(const char* psz)
+static std::string Translate(const char* psz)
{
return QCoreApplication::translate("bitcoin-core", psz).toStdString();
}
@@ -128,9 +113,54 @@ static void handleRunawayException(std::exception *e)
exit(1);
}
-#ifdef WIN32
-#define strncasecmp strnicmp
+/** Help message for Bitcoin-Qt, shown with --help. */
+class HelpMessageBox: public QMessageBox
+{
+ Q_OBJECT
+public:
+ HelpMessageBox(QWidget *parent = 0);
+
+ void exec();
+private:
+ QString header;
+ QString coreOptions;
+ QString uiOptions;
+};
+
+HelpMessageBox::HelpMessageBox(QWidget *parent):
+ QMessageBox(parent)
+{
+ header = tr("Bitcoin-Qt") + " " + tr("version") + " " +
+ QString::fromStdString(FormatFullVersion()) + "\n\n" +
+ tr("Usage:") + "\n" +
+ " bitcoin-qt [" + tr("options") + "] " + "\n";
+ coreOptions = QString::fromStdString(HelpMessage());
+ uiOptions = tr("UI options") + ":\n" +
+ " -lang=<lang> " + tr("Set language, for example \"de_DE\" (default: system locale)") + "\n" +
+ " -min " + tr("Start minimized") + "\n" +
+ " -splash " + tr("Show splash screen on startup (default: 1)") + "\n";
+
+ setWindowTitle(tr("Bitcoin-Qt"));
+ setTextFormat(Qt::PlainText);
+ // setMinimumWidth is ignored for QMessageBox so put in nonbreaking spaces to make it wider.
+ QChar em_space(0x2003);
+ setText(header + QString(em_space).repeated(40));
+ setDetailedText(coreOptions + "\n" + uiOptions);
+}
+#include "bitcoin.moc"
+
+void HelpMessageBox::exec()
+{
+#if defined(WIN32)
+ // On windows, show a message box, as there is no stderr in windowed applications
+ QMessageBox::exec();
+#else
+ // On other operating systems, the expected action is to print the message to the console.
+ QString strUsage = header + "\n" + coreOptions + "\n" + uiOptions;
+ fprintf(stderr, "%s", strUsage.toStdString().c_str());
#endif
+}
+
#ifndef BITCOIN_QT_TEST
int main(int argc, char *argv[])
{
@@ -140,7 +170,7 @@ int main(int argc, char *argv[])
// Do this early as we don't want to bother initializing if we are just calling IPC
for (int i = 1; i < argc; i++)
{
- if (strlen(argv[i]) > 7 && strncasecmp(argv[i], "bitcoin:", 8) == 0)
+ if (boost::algorithm::istarts_with(argv[i], "bitcoin:"))
{
const char *strURI = argv[i];
try {
@@ -164,6 +194,9 @@ int main(int argc, char *argv[])
Q_INIT_RESOURCE(bitcoin);
QApplication app(argc, argv);
+ // Install global event filter that makes sure that long tooltips can be word-wrapped
+ app.installEventFilter(new GUIUtil::ToolTipToRichTextFilter(TOOLTIP_WRAP_THRESHOLD, &app));
+
// Command-line options take precedence:
ParseParameters(argc, argv);
@@ -187,32 +220,50 @@ int main(int argc, char *argv[])
// ... then GUI settings:
OptionsModel optionsModel;
- // Get desired locale ("en_US") from command line or system locale
+ // Get desired locale (e.g. "de_DE") from command line or use system locale
QString lang_territory = QString::fromStdString(GetArg("-lang", QLocale::system().name().toStdString()));
- // Load language files for configured locale:
- // - First load the translator for the base language, without territory
- // - Then load the more specific locale translator
QString lang = lang_territory;
+ // Convert to "de" only by truncating "_DE"
+ lang.truncate(lang_territory.lastIndexOf('_'));
- lang.truncate(lang_territory.lastIndexOf('_')); // "en"
QTranslator qtTranslatorBase, qtTranslator, translatorBase, translator;
+ // Load language files for configured locale:
+ // - First load the translator for the base language, without territory
+ // - Then load the more specific locale translator
- qtTranslatorBase.load(QLibraryInfo::location(QLibraryInfo::TranslationsPath) + "/qt_" + lang);
- if (!qtTranslatorBase.isEmpty())
+ // Load e.g. qt_de.qm
+ if (qtTranslatorBase.load("qt_" + lang, QLibraryInfo::location(QLibraryInfo::TranslationsPath)))
app.installTranslator(&qtTranslatorBase);
- qtTranslator.load(QLibraryInfo::location(QLibraryInfo::TranslationsPath) + "/qt_" + lang_territory);
- if (!qtTranslator.isEmpty())
+ // Load e.g. qt_de_DE.qm
+ if (qtTranslator.load("qt_" + lang_territory, QLibraryInfo::location(QLibraryInfo::TranslationsPath)))
app.installTranslator(&qtTranslator);
- translatorBase.load(":/translations/"+lang);
- if (!translatorBase.isEmpty())
+ // Load e.g. bitcoin_de.qm (shortcut "de" needs to be defined in bitcoin.qrc)
+ if (translatorBase.load(lang, ":/translations/"))
app.installTranslator(&translatorBase);
- translator.load(":/translations/"+lang_territory);
- if (!translator.isEmpty())
+ // Load e.g. bitcoin_de_DE.qm (shortcut "de_DE" needs to be defined in bitcoin.qrc)
+ if (translator.load(lang_territory, ":/translations/"))
app.installTranslator(&translator);
+ // Subscribe to global signals from core
+ uiInterface.ThreadSafeMessageBox.connect(ThreadSafeMessageBox);
+ uiInterface.ThreadSafeAskFee.connect(ThreadSafeAskFee);
+ uiInterface.ThreadSafeHandleURI.connect(ThreadSafeHandleURI);
+ uiInterface.InitMessage.connect(InitMessage);
+ uiInterface.QueueShutdown.connect(QueueShutdown);
+ uiInterface.Translate.connect(Translate);
+
+ // Show help message immediately after parsing command-line options (for "-lang") and setting locale,
+ // but before showing splash screen.
+ if (mapArgs.count("-?") || mapArgs.count("--help"))
+ {
+ HelpMessageBox help;
+ help.exec();
+ return 1;
+ }
+
QSplashScreen splash(QPixmap(":/images/splash"), 0);
if (GetBoolArg("-splash", true) && !GetBoolArg("-min"))
{
@@ -227,9 +278,13 @@ int main(int argc, char *argv[])
try
{
+ // Regenerate startup link, to fix links to old versions
+ if (GUIUtil::GetStartOnSystemStartup())
+ GUIUtil::SetStartOnSystemStartup(true);
+
BitcoinGUI window;
guiref = &window;
- if(AppInit2(argc, argv))
+ if(AppInit2())
{
{
// Put this in a block, so that the Model objects are cleaned up before
@@ -241,9 +296,7 @@ int main(int argc, char *argv[])
splash.finish(&window);
ClientModel clientModel(&optionsModel);
- clientmodel = &clientModel;
WalletModel walletModel(pwalletMain, &optionsModel);
- walletmodel = &walletModel;
window.setClientModel(&clientModel);
window.setWalletModel(&walletModel);
@@ -257,17 +310,16 @@ int main(int argc, char *argv[])
{
window.show();
}
+#if !defined(MAC_OSX) && !defined(WIN32)
+// TODO: implement qtipcserver.cpp for Mac and Windows
// Place this here as guiref has to be defined if we dont want to lose URIs
ipcInit();
-#if !defined(MAC_OSX) && !defined(WIN32)
-// TODO: implement qtipcserver.cpp for Mac and Windows
-
// Check for URI in argv
for (int i = 1; i < argc; i++)
{
- if (strlen(argv[i]) > 7 && strncasecmp(argv[i], "bitcoin:", 8) == 0)
+ if (boost::algorithm::istarts_with(argv[i], "bitcoin:"))
{
const char *strURI = argv[i];
try {
@@ -281,11 +333,10 @@ int main(int argc, char *argv[])
#endif
app.exec();
+ window.hide();
window.setClientModel(0);
window.setWalletModel(0);
guiref = 0;
- clientmodel = 0;
- walletmodel = 0;
}
Shutdown(NULL);
}
diff --git a/src/qt/bitcoin.qrc b/src/qt/bitcoin.qrc
index e631a65155..a6a2112478 100644
--- a/src/qt/bitcoin.qrc
+++ b/src/qt/bitcoin.qrc
@@ -38,28 +38,32 @@
<file alias="lock_open">res/icons/lock_open.png</file>
<file alias="key">res/icons/key.png</file>
<file alias="filesave">res/icons/filesave.png</file>
+ <file alias="qrcode">res/icons/qrcode.png</file>
+ <file alias="debugwindow">res/icons/debugwindow.png</file>
</qresource>
<qresource prefix="/images">
<file alias="about">res/images/about.png</file>
<file alias="splash">res/images/splash2.jpg</file>
- <file alias="qrcode">res/images/qrcode.png</file>
</qresource>
<qresource prefix="/movies">
<file alias="update_spinner">res/movies/update_spinner.mng</file>
</qresource>
<qresource prefix="/translations">
+ <file alias="bg">locale/bitcoin_bg.qm</file>
<file alias="ca_ES">locale/bitcoin_ca_ES.qm</file>
<file alias="cs">locale/bitcoin_cs.qm</file>
<file alias="da">locale/bitcoin_da.qm</file>
<file alias="de">locale/bitcoin_de.qm</file>
+ <file alias="el_GR">locale/bitcoin_el_GR.qm</file>
<file alias="en">locale/bitcoin_en.qm</file>
- <file alias="es_CL">locale/bitcoin_es_CL.qm</file>
<file alias="es">locale/bitcoin_es.qm</file>
+ <file alias="es_CL">locale/bitcoin_es_CL.qm</file>
<file alias="et">locale/bitcoin_et.qm</file>
<file alias="eu_ES">locale/bitcoin_eu_ES.qm</file>
- <file alias="fa_IR">locale/bitcoin_fa_IR.qm</file>
<file alias="fa">locale/bitcoin_fa.qm</file>
+ <file alias="fa_IR">locale/bitcoin_fa_IR.qm</file>
<file alias="fi">locale/bitcoin_fi.qm</file>
+ <file alias="fr">locale/bitcoin_fr.qm</file>
<file alias="fr_CA">locale/bitcoin_fr_CA.qm</file>
<file alias="fr_FR">locale/bitcoin_fr_FR.qm</file>
<file alias="he">locale/bitcoin_he.qm</file>
@@ -71,6 +75,7 @@
<file alias="nl">locale/bitcoin_nl.qm</file>
<file alias="pl">locale/bitcoin_pl.qm</file>
<file alias="pt_BR">locale/bitcoin_pt_BR.qm</file>
+ <file alias="pt_PT">locale/bitcoin_pt_PT.qm</file>
<file alias="ro_RO">locale/bitcoin_ro_RO.qm</file>
<file alias="ru">locale/bitcoin_ru.qm</file>
<file alias="sk">locale/bitcoin_sk.qm</file>
diff --git a/src/qt/bitcoinaddressvalidator.cpp b/src/qt/bitcoinaddressvalidator.cpp
index 373877808f..d2b93e70f5 100644
--- a/src/qt/bitcoinaddressvalidator.cpp
+++ b/src/qt/bitcoinaddressvalidator.cpp
@@ -21,21 +21,31 @@ BitcoinAddressValidator::BitcoinAddressValidator(QObject *parent) :
QValidator::State BitcoinAddressValidator::validate(QString &input, int &pos) const
{
// Correction
- for(int idx=0; idx<input.size(); ++idx)
+ for(int idx=0; idx<input.size();)
{
- switch(input.at(idx).unicode())
+ bool removeChar = false;
+ QChar ch = input.at(idx);
+ // Corrections made are very conservative on purpose, to avoid
+ // users unexpectedly getting away with typos that would normally
+ // be detected, and thus sending to the wrong address.
+ switch(ch.unicode())
{
- case 'l':
- case 'I':
- input[idx] = QChar('1');
- break;
- case '0':
- case 'O':
- input[idx] = QChar('o');
+ // Qt categorizes these as "Other_Format" not "Separator_Space"
+ case 0x200B: // ZERO WIDTH SPACE
+ case 0xFEFF: // ZERO WIDTH NO-BREAK SPACE
+ removeChar = true;
break;
default:
break;
}
+ // Remove whitespace
+ if(ch.isSpace())
+ removeChar = true;
+ // To next character
+ if(removeChar)
+ input.remove(idx, 1);
+ else
+ ++idx;
}
// Validation
diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp
index bcf90917ed..9deaa4b6d3 100644
--- a/src/qt/bitcoingui.cpp
+++ b/src/qt/bitcoingui.cpp
@@ -1,14 +1,15 @@
/*
* Qt4 bitcoin GUI.
*
- * W.J. van der Laan 20011-2012
- * The Bitcoin Developers 20011-2012
+ * W.J. van der Laan 2011-2012
+ * The Bitcoin Developers 2011-2012
*/
#include "bitcoingui.h"
#include "transactiontablemodel.h"
#include "addressbookpage.h"
#include "sendcoinsdialog.h"
#include "messagepage.h"
+#include "verifymessagedialog.h"
#include "optionsdialog.h"
#include "aboutdialog.h"
#include "clientmodel.h"
@@ -24,6 +25,7 @@
#include "askpassphrasedialog.h"
#include "notificator.h"
#include "guiutil.h"
+#include "rpcconsole.h"
#ifdef Q_WS_MAC
#include "macdockiconhandler.h"
@@ -64,11 +66,13 @@ BitcoinGUI::BitcoinGUI(QWidget *parent):
changePassphraseAction(0),
aboutQtAction(0),
trayIcon(0),
- notificator(0)
+ notificator(0),
+ rpcConsole(0)
{
resize(850, 550);
setWindowTitle(tr("Bitcoin Wallet"));
#ifndef Q_WS_MAC
+ qApp->setWindowIcon(QIcon(":icons/bitcoin"));
setWindowIcon(QIcon(":icons/bitcoin"));
#else
setUnifiedTitleAndToolBarOnMac(true);
@@ -154,10 +158,14 @@ BitcoinGUI::BitcoinGUI(QWidget *parent):
// Clicking on a transaction on the overview page simply sends you to transaction history page
connect(overviewPage, SIGNAL(transactionClicked(QModelIndex)), this, SLOT(gotoHistoryPage()));
+ connect(overviewPage, SIGNAL(transactionClicked(QModelIndex)), transactionView, SLOT(focusTransaction(QModelIndex)));
// Doubleclicking on a transaction on the transaction history page shows details
connect(transactionView, SIGNAL(doubleClicked(QModelIndex)), transactionView, SLOT(showDetails()));
+ rpcConsole = new RPCConsole(this);
+ connect(openRPCConsoleAction, SIGNAL(triggered()), rpcConsole, SLOT(show()));
+
gotoOverviewPage();
}
@@ -199,12 +207,12 @@ void BitcoinGUI::createActions()
tabGroup->addAction(receiveCoinsAction);
sendCoinsAction = new QAction(QIcon(":/icons/send"), tr("&Send coins"), this);
- sendCoinsAction->setToolTip(tr("Send coins to a bitcoin address"));
+ sendCoinsAction->setToolTip(tr("Send coins to a Bitcoin address"));
sendCoinsAction->setCheckable(true);
sendCoinsAction->setShortcut(QKeySequence(Qt::ALT + Qt::Key_2));
tabGroup->addAction(sendCoinsAction);
- messageAction = new QAction(QIcon(":/icons/edit"), tr("Sign &message"), this);
+ messageAction = new QAction(QIcon(":/icons/edit"), tr("Sign &message..."), this);
messageAction->setToolTip(tr("Prove you control an address"));
#ifdef FIRST_CLASS_MESSAGING
messageAction->setCheckable(true);
@@ -235,19 +243,23 @@ void BitcoinGUI::createActions()
aboutQtAction->setToolTip(tr("Show information about Qt"));
aboutQtAction->setMenuRole(QAction::AboutQtRole);
optionsAction = new QAction(QIcon(":/icons/options"), tr("&Options..."), this);
- optionsAction->setToolTip(tr("Modify configuration options for bitcoin"));
+ optionsAction->setToolTip(tr("Modify configuration options for Bitcoin"));
optionsAction->setMenuRole(QAction::PreferencesRole);
toggleHideAction = new QAction(QIcon(":/icons/bitcoin"), tr("Show/Hide &Bitcoin"), this);
toggleHideAction->setToolTip(tr("Show or hide the Bitcoin window"));
exportAction = new QAction(QIcon(":/icons/export"), tr("&Export..."), this);
exportAction->setToolTip(tr("Export the data in the current tab to a file"));
- encryptWalletAction = new QAction(QIcon(":/icons/lock_closed"), tr("&Encrypt Wallet"), this);
+ encryptWalletAction = new QAction(QIcon(":/icons/lock_closed"), tr("&Encrypt Wallet..."), this);
encryptWalletAction->setToolTip(tr("Encrypt or decrypt wallet"));
encryptWalletAction->setCheckable(true);
- backupWalletAction = new QAction(QIcon(":/icons/filesave"), tr("&Backup Wallet"), this);
+ backupWalletAction = new QAction(QIcon(":/icons/filesave"), tr("&Backup Wallet..."), this);
backupWalletAction->setToolTip(tr("Backup wallet to another location"));
- changePassphraseAction = new QAction(QIcon(":/icons/key"), tr("&Change Passphrase"), this);
+ changePassphraseAction = new QAction(QIcon(":/icons/key"), tr("&Change Passphrase..."), this);
changePassphraseAction->setToolTip(tr("Change the passphrase used for wallet encryption"));
+ openRPCConsoleAction = new QAction(QIcon(":/icons/debugwindow"), tr("&Debug window"), this);
+ openRPCConsoleAction->setToolTip(tr("Open debugging and diagnostic console"));
+ verifyMessageAction = new QAction(QIcon(":/icons/transaction_0"), tr("&Verify message..."), this);
+ verifyMessageAction->setToolTip(tr("Verify a message signature"));
connect(quitAction, SIGNAL(triggered()), qApp, SLOT(quit()));
connect(optionsAction, SIGNAL(triggered()), this, SLOT(optionsClicked()));
@@ -257,6 +269,7 @@ void BitcoinGUI::createActions()
connect(encryptWalletAction, SIGNAL(triggered(bool)), this, SLOT(encryptWallet(bool)));
connect(backupWalletAction, SIGNAL(triggered()), this, SLOT(backupWallet()));
connect(changePassphraseAction, SIGNAL(triggered()), this, SLOT(changePassphrase()));
+ connect(verifyMessageAction, SIGNAL(triggered()), this, SLOT(verifyMessage()));
}
void BitcoinGUI::createMenuBar()
@@ -276,6 +289,7 @@ void BitcoinGUI::createMenuBar()
#ifndef FIRST_CLASS_MESSAGING
file->addAction(messageAction);
#endif
+ file->addAction(verifyMessageAction);
file->addSeparator();
file->addAction(quitAction);
@@ -286,6 +300,8 @@ void BitcoinGUI::createMenuBar()
settings->addAction(optionsAction);
QMenu *help = appMenuBar->addMenu(tr("&Help"));
+ help->addAction(openRPCConsoleAction);
+ help->addSeparator();
help->addAction(aboutAction);
help->addAction(aboutQtAction);
}
@@ -315,17 +331,18 @@ void BitcoinGUI::setClientModel(ClientModel *clientModel)
{
if(clientModel->isTestNet())
{
- QString title_testnet = windowTitle() + QString(" ") + tr("[testnet]");
- setWindowTitle(title_testnet);
+ setWindowTitle(windowTitle() + QString(" ") + tr("[testnet]"));
#ifndef Q_WS_MAC
+ qApp->setWindowIcon(QIcon(":icons/bitcoin_testnet"));
setWindowIcon(QIcon(":icons/bitcoin_testnet"));
#else
MacDockIconHandler::instance()->setIcon(QIcon(":icons/bitcoin_testnet"));
#endif
if(trayIcon)
{
- trayIcon->setToolTip(title_testnet);
+ trayIcon->setToolTip(tr("Bitcoin client") + QString(" ") + tr("[testnet]"));
trayIcon->setIcon(QIcon(":/icons/toolbar_testnet"));
+ toggleHideAction->setIcon(QIcon(":/icons/toolbar_testnet"));
}
}
@@ -333,11 +350,13 @@ void BitcoinGUI::setClientModel(ClientModel *clientModel)
setNumConnections(clientModel->getNumConnections());
connect(clientModel, SIGNAL(numConnectionsChanged(int)), this, SLOT(setNumConnections(int)));
- setNumBlocks(clientModel->getNumBlocks());
- connect(clientModel, SIGNAL(numBlocksChanged(int)), this, SLOT(setNumBlocks(int)));
+ setNumBlocks(clientModel->getNumBlocks(), clientModel->getNumBlocksOfPeers());
+ connect(clientModel, SIGNAL(numBlocksChanged(int,int)), this, SLOT(setNumBlocks(int,int)));
// Report errors from network/worker thread
- connect(clientModel, SIGNAL(error(QString,QString, bool)), this, SLOT(error(QString,QString,bool)));
+ connect(clientModel, SIGNAL(error(QString,QString,bool)), this, SLOT(error(QString,QString,bool)));
+
+ rpcConsole->setClientModel(clientModel);
}
}
@@ -391,13 +410,15 @@ void BitcoinGUI::createTrayIcon()
// Configuration of the tray icon (or dock icon) icon menu
trayIconMenu->addAction(toggleHideAction);
+ trayIconMenu->addAction(openRPCConsoleAction);
trayIconMenu->addSeparator();
trayIconMenu->addAction(messageAction);
+ trayIconMenu->addAction(verifyMessageAction);
#ifndef FIRST_CLASS_MESSAGING
trayIconMenu->addSeparator();
#endif
- trayIconMenu->addAction(receiveCoinsAction);
trayIconMenu->addAction(sendCoinsAction);
+ trayIconMenu->addAction(receiveCoinsAction);
trayIconMenu->addSeparator();
trayIconMenu->addAction(optionsAction);
#ifndef Q_WS_MAC // This is built-in on Mac
@@ -405,7 +426,7 @@ void BitcoinGUI::createTrayIcon()
trayIconMenu->addAction(quitAction);
#endif
- notificator = new Notificator(tr("bitcoin-qt"), trayIcon);
+ notificator = new Notificator(qApp->applicationName(), trayIcon);
}
#ifndef Q_WS_MAC
@@ -413,7 +434,7 @@ void BitcoinGUI::trayIconActivated(QSystemTrayIcon::ActivationReason reason)
{
if(reason == QSystemTrayIcon::Trigger)
{
- // Click on system tray icon triggers "show/hide bitcoin"
+ // Click on system tray icon triggers "show/hide Bitcoin"
toggleHideAction->trigger();
}
}
@@ -472,7 +493,7 @@ void BitcoinGUI::setNumConnections(int count)
labelConnectionsIcon->setToolTip(tr("%n active connection(s) to Bitcoin network", "", count));
}
-void BitcoinGUI::setNumBlocks(int count)
+void BitcoinGUI::setNumBlocks(int count, int nTotalBlocks)
{
// don't show / hide progressBar and it's label if we have no connection(s) to the network
if (!clientModel || clientModel->getNumConnections() == 0)
@@ -483,7 +504,6 @@ void BitcoinGUI::setNumBlocks(int count)
return;
}
- int nTotalBlocks = clientModel->getNumBlocksOfPeers();
QString tooltip;
if(count < nTotalBlocks)
@@ -551,22 +571,29 @@ void BitcoinGUI::setNumBlocks(int count)
// Set icon state: spinning if catching up, tick otherwise
if(secs < 90*60 && count >= nTotalBlocks)
{
- tooltip = tr("Up to date") + QString(".\n") + tooltip;
+ tooltip = tr("Up to date") + QString(".<br>") + tooltip;
labelBlocksIcon->setPixmap(QIcon(":/icons/synced").pixmap(STATUSBAR_ICONSIZE, STATUSBAR_ICONSIZE));
+
+ overviewPage->showOutOfSyncWarning(false);
}
else
{
- tooltip = tr("Catching up...") + QString("\n") + tooltip;
+ tooltip = tr("Catching up...") + QString("<br>") + tooltip;
labelBlocksIcon->setMovie(syncIconMovie);
syncIconMovie->start();
+
+ overviewPage->showOutOfSyncWarning(true);
}
if(!text.isEmpty())
{
- tooltip += QString("\n");
+ tooltip += QString("<br>");
tooltip += tr("Last received block was generated %1.").arg(text);
}
+ // Don't word-wrap this (fixed-width) tooltip
+ tooltip = QString("<nobr>") + tooltip + QString("</nobr>");
+
labelBlocksIcon->setToolTip(tooltip);
progressBarLabel->setToolTip(tooltip);
progressBar->setToolTip(tooltip);
@@ -625,7 +652,7 @@ void BitcoinGUI::askFee(qint64 nFeeRequired, bool *payFee)
"Do you want to pay the fee?").arg(
BitcoinUnits::formatWithUnit(BitcoinUnits::BTC, nFeeRequired));
QMessageBox::StandardButton retval = QMessageBox::question(
- this, tr("Sending..."), strMessage,
+ this, tr("Confirm transaction fee"), strMessage,
QMessageBox::Yes|QMessageBox::Cancel, QMessageBox::Yes);
*payFee = (retval == QMessageBox::Yes);
}
@@ -713,8 +740,11 @@ void BitcoinGUI::gotoSendCoinsPage()
disconnect(exportAction, SIGNAL(triggered()), 0, 0);
}
-void BitcoinGUI::gotoMessagePage()
+void BitcoinGUI::gotoMessagePage(QString addr)
{
+ if(!addr.isEmpty())
+ messagePage->setAddress(addr);
+
#ifdef FIRST_CLASS_MESSAGING
messageAction->setChecked(true);
centralWidget->setCurrentWidget(messagePage);
@@ -723,16 +753,9 @@ void BitcoinGUI::gotoMessagePage()
disconnect(exportAction, SIGNAL(triggered()), 0, 0);
#else
messagePage->show();
- messagePage->setFocus();
#endif
}
-void BitcoinGUI::gotoMessagePage(QString addr)
-{
- gotoMessagePage();
- messagePage->setAddress(addr);
-}
-
void BitcoinGUI::dragEnterEvent(QDragEnterEvent *event)
{
// Accept only URIs
@@ -825,6 +848,13 @@ void BitcoinGUI::changePassphrase()
dlg.exec();
}
+void BitcoinGUI::verifyMessage()
+{
+ VerifyMessageDialog *dlg = new VerifyMessageDialog(walletModel->getAddressTableModel(), this);
+ dlg->setAttribute(Qt::WA_DeleteOnClose);
+ dlg->show();
+}
+
void BitcoinGUI::unlockWallet()
{
if(!walletModel)
diff --git a/src/qt/bitcoingui.h b/src/qt/bitcoingui.h
index 2cce8d3459..8a7f6e541b 100644
--- a/src/qt/bitcoingui.h
+++ b/src/qt/bitcoingui.h
@@ -13,6 +13,7 @@ class AddressBookPage;
class SendCoinsDialog;
class MessagePage;
class Notificator;
+class RPCConsole;
QT_BEGIN_NAMESPACE
class QLabel;
@@ -45,7 +46,7 @@ public:
functionality.
*/
void setWalletModel(WalletModel *walletModel);
-
+
protected:
void changeEvent(QEvent *e);
void closeEvent(QCloseEvent *event);
@@ -78,6 +79,7 @@ private:
QAction *sendCoinsAction;
QAction *addressBookAction;
QAction *messageAction;
+ QAction *verifyMessageAction;
QAction *aboutAction;
QAction *receiveCoinsAction;
QAction *optionsAction;
@@ -87,10 +89,12 @@ private:
QAction *backupWalletAction;
QAction *changePassphraseAction;
QAction *aboutQtAction;
+ QAction *openRPCConsoleAction;
QSystemTrayIcon *trayIcon;
Notificator *notificator;
TransactionView *transactionView;
+ RPCConsole *rpcConsole;
QMovie *syncIconMovie;
@@ -107,7 +111,7 @@ public slots:
/** Set number of connections shown in the UI */
void setNumConnections(int count);
/** Set number of blocks shown in the UI */
- void setNumBlocks(int count);
+ void setNumBlocks(int count, int countOfPeers);
/** Set the encryption status as shown in the UI.
@param[in] status current encryption status
@see WalletModel::EncryptionStatus
@@ -127,8 +131,7 @@ public slots:
void askFee(qint64 nFeeRequired, bool *payFee);
void handleURI(QString strURI);
- void gotoMessagePage();
- void gotoMessagePage(QString);
+ void gotoMessagePage(QString addr = "");
private slots:
/** Switch to overview (home) page */
@@ -161,6 +164,8 @@ private slots:
void backupWallet();
/** Change encrypted wallet passphrase */
void changePassphrase();
+ /** Verify a message signature */
+ void verifyMessage();
/** Ask for pass phrase to unlock wallet temporarily */
void unlockWallet();
diff --git a/src/qt/bitcoinstrings.cpp b/src/qt/bitcoinstrings.cpp
index b25af1a210..ad17475816 100644
--- a/src/qt/bitcoinstrings.cpp
+++ b/src/qt/bitcoinstrings.cpp
@@ -6,34 +6,40 @@
#define UNUSED
#endif
static const char UNUSED *bitcoin_strings[] = {QT_TRANSLATE_NOOP("bitcoin-core", ""
-"Unable to bind to port %d on this computer. Bitcoin is probably already "
-"running."),
+"Unable to bind to %s on this computer. Bitcoin is probably already running."),
+QT_TRANSLATE_NOOP("bitcoin-core", "Unable to bind to %s on this computer (bind returned error %d, %s)"),
QT_TRANSLATE_NOOP("bitcoin-core", "Warning: Disk space is low "),
QT_TRANSLATE_NOOP("bitcoin-core", "Bitcoin version"),
QT_TRANSLATE_NOOP("bitcoin-core", "Usage:"),
QT_TRANSLATE_NOOP("bitcoin-core", "Send command to -server or bitcoind"),
QT_TRANSLATE_NOOP("bitcoin-core", "List commands"),
QT_TRANSLATE_NOOP("bitcoin-core", "Get help for a command"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Bitcoin"),
QT_TRANSLATE_NOOP("bitcoin-core", "Options:"),
QT_TRANSLATE_NOOP("bitcoin-core", "Specify configuration file (default: bitcoin.conf)"),
QT_TRANSLATE_NOOP("bitcoin-core", "Specify pid file (default: bitcoind.pid)"),
QT_TRANSLATE_NOOP("bitcoin-core", "Generate coins"),
QT_TRANSLATE_NOOP("bitcoin-core", "Don't generate coins"),
-QT_TRANSLATE_NOOP("bitcoin-core", "Start minimized"),
-QT_TRANSLATE_NOOP("bitcoin-core", "Show splash screen on startup (default: 1)"),
QT_TRANSLATE_NOOP("bitcoin-core", "Specify data directory"),
QT_TRANSLATE_NOOP("bitcoin-core", "Set database cache size in megabytes (default: 25)"),
QT_TRANSLATE_NOOP("bitcoin-core", "Set database disk log size in megabytes (default: 100)"),
QT_TRANSLATE_NOOP("bitcoin-core", "Specify connection timeout (in milliseconds)"),
-QT_TRANSLATE_NOOP("bitcoin-core", "Connect through socks4 proxy"),
-QT_TRANSLATE_NOOP("bitcoin-core", "Allow DNS lookups for addnode and connect"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Connect through socks proxy"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Select the version of socks proxy to use (4 or 5, 5 is default)"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Do not use proxy for connections to network <net> (IPv4 or IPv6)"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Allow DNS lookups for -addnode, -seednode and -connect"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Pass DNS requests to (SOCKS5) proxy"),
QT_TRANSLATE_NOOP("bitcoin-core", "Listen for connections on <port> (default: 8333 or testnet: 18333)"),
QT_TRANSLATE_NOOP("bitcoin-core", "Maintain at most <n> connections to peers (default: 125)"),
QT_TRANSLATE_NOOP("bitcoin-core", "Add a node to connect to and attempt to keep the connection open"),
QT_TRANSLATE_NOOP("bitcoin-core", "Connect only to the specified node"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Connect to a node to retrieve peer addresses, and disconnect"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Specify your own public address"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Only connect to nodes in network <net> (IPv4 or IPv6)"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Try to discover public IP address (default: 1)"),
QT_TRANSLATE_NOOP("bitcoin-core", "Find peers using internet relay chat (default: 0)"),
QT_TRANSLATE_NOOP("bitcoin-core", "Accept connections from outside (default: 1)"),
-QT_TRANSLATE_NOOP("bitcoin-core", "Set language, for example \"de_DE\" (default: system locale)"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Bind to given address. Use [host]:port notation for IPv6"),
QT_TRANSLATE_NOOP("bitcoin-core", "Find peers using DNS lookup (default: 1)"),
QT_TRANSLATE_NOOP("bitcoin-core", "Threshold for disconnecting misbehaving peers (default: 100)"),
QT_TRANSLATE_NOOP("bitcoin-core", ""
@@ -43,6 +49,8 @@ QT_TRANSLATE_NOOP("bitcoin-core", "Maximum per-connection receive buffer, <n>*10
QT_TRANSLATE_NOOP("bitcoin-core", "Maximum per-connection send buffer, <n>*1000 bytes (default: 10000)"),
QT_TRANSLATE_NOOP("bitcoin-core", "Use Universal Plug and Play to map the listening port (default: 1)"),
QT_TRANSLATE_NOOP("bitcoin-core", "Use Universal Plug and Play to map the listening port (default: 0)"),
+QT_TRANSLATE_NOOP("bitcoin-core", ""
+"Detach block and address databases. Increases shutdown time (default: 0)"),
QT_TRANSLATE_NOOP("bitcoin-core", "Fee per KB to add to transactions you send"),
QT_TRANSLATE_NOOP("bitcoin-core", "Accept command line and JSON-RPC commands"),
QT_TRANSLATE_NOOP("bitcoin-core", "Run in the background as a daemon and accept commands"),
@@ -64,6 +72,8 @@ QT_TRANSLATE_NOOP("bitcoin-core", "Set key pool size to <n> (default: 100)"),
QT_TRANSLATE_NOOP("bitcoin-core", "Rescan the block chain for missing wallet transactions"),
QT_TRANSLATE_NOOP("bitcoin-core", "How many blocks to check at startup (default: 2500, 0 = all)"),
QT_TRANSLATE_NOOP("bitcoin-core", "How thorough the block verification is (0-6, default: 1)"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Imports blocks from external blk000?.dat file"),
+QT_TRANSLATE_NOOP("bitcoin-core", "This help message"),
QT_TRANSLATE_NOOP("bitcoin-core", ""
"\n"
"SSL options: (see the Bitcoin Wiki for SSL setup instructions)"),
@@ -73,12 +83,9 @@ QT_TRANSLATE_NOOP("bitcoin-core", "Server private key (default: server.pem)"),
QT_TRANSLATE_NOOP("bitcoin-core", ""
"Acceptable ciphers (default: TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!AH:!3DES:"
"@STRENGTH)"),
-QT_TRANSLATE_NOOP("bitcoin-core", "This help message"),
-QT_TRANSLATE_NOOP("bitcoin-core", "Usage"),
QT_TRANSLATE_NOOP("bitcoin-core", ""
"Cannot obtain a lock on data directory %s. Bitcoin is probably already "
"running."),
-QT_TRANSLATE_NOOP("bitcoin-core", "Bitcoin"),
QT_TRANSLATE_NOOP("bitcoin-core", "Loading addresses..."),
QT_TRANSLATE_NOOP("bitcoin-core", "Error loading addr.dat"),
QT_TRANSLATE_NOOP("bitcoin-core", "Loading block index..."),
@@ -93,12 +100,18 @@ QT_TRANSLATE_NOOP("bitcoin-core", "Cannot initialize keypool"),
QT_TRANSLATE_NOOP("bitcoin-core", "Cannot write default address"),
QT_TRANSLATE_NOOP("bitcoin-core", "Rescanning..."),
QT_TRANSLATE_NOOP("bitcoin-core", "Done loading"),
-QT_TRANSLATE_NOOP("bitcoin-core", "Invalid -proxy address"),
-QT_TRANSLATE_NOOP("bitcoin-core", "Invalid amount for -paytxfee=<amount>"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Invalid -proxy address: '%s'"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Unknown network specified in -noproxy: '%s'"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Unknown network specified in -onlynet: '%s'"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Unknown -socks proxy version requested: %i"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Cannot resolve -bind address: '%s'"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Not listening on any port"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Cannot resolve -externalip address: '%s'"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Invalid amount for -paytxfee=<amount>: '%s'"),
QT_TRANSLATE_NOOP("bitcoin-core", ""
"Warning: -paytxfee is set very high. This is the transaction fee you will "
"pay if you send a transaction."),
-QT_TRANSLATE_NOOP("bitcoin-core", "Error: CreateThread(StartNode) failed"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Error: could not start node"),
QT_TRANSLATE_NOOP("bitcoin-core", "To use the %s option"),
QT_TRANSLATE_NOOP("bitcoin-core", ""
"%s, you must set a rpcpassword in the configuration file:\n"
diff --git a/src/qt/clientmodel.cpp b/src/qt/clientmodel.cpp
index cb602ce327..64fd2a9450 100644
--- a/src/qt/clientmodel.cpp
+++ b/src/qt/clientmodel.cpp
@@ -5,14 +5,30 @@
#include "transactiontablemodel.h"
#include "main.h"
+#include "ui_interface.h"
#include <QDateTime>
+#include <QTimer>
+
+static const int64 nClientStartupTime = GetTime();
ClientModel::ClientModel(OptionsModel *optionsModel, QObject *parent) :
QObject(parent), optionsModel(optionsModel),
- cachedNumConnections(0), cachedNumBlocks(0)
+ cachedNumBlocks(0), cachedNumBlocksOfPeers(0), pollTimer(0)
{
numBlocksAtStartup = -1;
+
+ pollTimer = new QTimer();
+ pollTimer->setInterval(MODEL_UPDATE_DELAY);
+ pollTimer->start();
+ connect(pollTimer, SIGNAL(timeout()), this, SLOT(updateTimer()));
+
+ subscribeToCoreSignals();
+}
+
+ClientModel::~ClientModel()
+{
+ unsubscribeFromCoreSignals();
}
int ClientModel::getNumConnections() const
@@ -36,27 +52,42 @@ QDateTime ClientModel::getLastBlockDate() const
return QDateTime::fromTime_t(pindexBest->GetBlockTime());
}
-void ClientModel::update()
+void ClientModel::updateTimer()
{
- int newNumConnections = getNumConnections();
+ // Some quantities (such as number of blocks) change so fast that we don't want to be notified for each change.
+ // Periodically check and update with a timer.
int newNumBlocks = getNumBlocks();
- QString newStatusBar = getStatusBarWarnings();
+ int newNumBlocksOfPeers = getNumBlocksOfPeers();
+
+ if(cachedNumBlocks != newNumBlocks || cachedNumBlocksOfPeers != newNumBlocksOfPeers)
+ emit numBlocksChanged(newNumBlocks, newNumBlocksOfPeers);
+
+ cachedNumBlocks = newNumBlocks;
+ cachedNumBlocksOfPeers = newNumBlocksOfPeers;
+}
- if(cachedNumConnections != newNumConnections)
- emit numConnectionsChanged(newNumConnections);
- if(cachedNumBlocks != newNumBlocks || cachedStatusBar != newStatusBar)
+void ClientModel::updateNumConnections(int numConnections)
+{
+ emit numConnectionsChanged(numConnections);
+}
+
+void ClientModel::updateAlert(const QString &hash, int status)
+{
+ // Show error message notification for new alert
+ if(status == CT_NEW)
{
- // Simply emit a numBlocksChanged for now in case the status message changes,
- // so that the view updates the status bar.
- // TODO: It should send a notification.
- // (However, this might generate looped notifications and needs to be thought through and tested carefully)
- // error(tr("Network Alert"), newStatusBar);
- emit numBlocksChanged(newNumBlocks);
+ uint256 hash_256;
+ hash_256.SetHex(hash.toStdString());
+ CAlert alert = CAlert::getAlertByHash(hash_256);
+ if(!alert.IsNull())
+ {
+ emit error(tr("Network Alert"), QString::fromStdString(alert.strStatusBar), false);
+ }
}
- cachedNumConnections = newNumConnections;
- cachedNumBlocks = newNumBlocks;
- cachedStatusBar = newStatusBar;
+ // Emit a numBlocksChanged when the status message changes,
+ // so that the view recomputes and updates the status bar.
+ emit numBlocksChanged(getNumBlocks(), getNumBlocksOfPeers());
}
bool ClientModel::isTestNet() const
@@ -93,3 +124,51 @@ QString ClientModel::formatBuildDate() const
{
return QString::fromStdString(CLIENT_DATE);
}
+
+QString ClientModel::clientName() const
+{
+ return QString::fromStdString(CLIENT_NAME);
+}
+
+QDateTime ClientModel::formatClientStartupTime() const
+{
+ return QDateTime::fromTime_t(nClientStartupTime);
+}
+
+// Handlers for core signals
+static void NotifyBlocksChanged(ClientModel *clientmodel)
+{
+ // This notification is too frequent. Don't trigger a signal.
+ // Don't remove it, though, as it might be useful later.
+}
+
+static void NotifyNumConnectionsChanged(ClientModel *clientmodel, int newNumConnections)
+{
+ // Too noisy: OutputDebugStringF("NotifyNumConnectionsChanged %i\n", newNumConnections);
+ QMetaObject::invokeMethod(clientmodel, "updateNumConnections", Qt::QueuedConnection,
+ Q_ARG(int, newNumConnections));
+}
+
+static void NotifyAlertChanged(ClientModel *clientmodel, const uint256 &hash, ChangeType status)
+{
+ OutputDebugStringF("NotifyAlertChanged %s status=%i\n", hash.GetHex().c_str(), status);
+ QMetaObject::invokeMethod(clientmodel, "updateAlert", Qt::QueuedConnection,
+ Q_ARG(QString, QString::fromStdString(hash.GetHex())),
+ Q_ARG(int, status));
+}
+
+void ClientModel::subscribeToCoreSignals()
+{
+ // Connect signals to client
+ uiInterface.NotifyBlocksChanged.connect(boost::bind(NotifyBlocksChanged, this));
+ uiInterface.NotifyNumConnectionsChanged.connect(boost::bind(NotifyNumConnectionsChanged, this, _1));
+ uiInterface.NotifyAlertChanged.connect(boost::bind(NotifyAlertChanged, this, _1, _2));
+}
+
+void ClientModel::unsubscribeFromCoreSignals()
+{
+ // Disconnect signals from client
+ 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 8e7431a2f3..0349c389c5 100644
--- a/src/qt/clientmodel.h
+++ b/src/qt/clientmodel.h
@@ -10,6 +10,7 @@ class CWallet;
QT_BEGIN_NAMESPACE
class QDateTime;
+class QTimer;
QT_END_NAMESPACE
/** Model for Bitcoin network client. */
@@ -18,6 +19,7 @@ class ClientModel : public QObject
Q_OBJECT
public:
explicit ClientModel(OptionsModel *optionsModel, QObject *parent = 0);
+ ~ClientModel();
OptionsModel *getOptionsModel();
@@ -38,27 +40,32 @@ public:
QString formatFullVersion() const;
QString formatBuildDate() const;
+ QString clientName() const;
+ QDateTime formatClientStartupTime() const;
private:
OptionsModel *optionsModel;
- int cachedNumConnections;
int cachedNumBlocks;
- QString cachedStatusBar;
+ int cachedNumBlocksOfPeers;
int numBlocksAtStartup;
+ QTimer *pollTimer;
+
+ void subscribeToCoreSignals();
+ void unsubscribeFromCoreSignals();
signals:
void numConnectionsChanged(int count);
- void numBlocksChanged(int count);
+ void numBlocksChanged(int count, int countOfPeers);
//! Asynchronous error notification
void error(const QString &title, const QString &message, bool modal);
public slots:
-
-private slots:
- void update();
+ void updateTimer();
+ void updateNumConnections(int numConnections);
+ void updateAlert(const QString &hash, int status);
};
#endif // CLIENTMODEL_H
diff --git a/src/qt/csvmodelwriter.cpp b/src/qt/csvmodelwriter.cpp
index 84578b3322..8a50bbab3f 100644
--- a/src/qt/csvmodelwriter.cpp
+++ b/src/qt/csvmodelwriter.cpp
@@ -27,8 +27,9 @@ void CSVModelWriter::addColumn(const QString &title, int column, int role)
static void writeValue(QTextStream &f, const QString &value)
{
- // TODO: quoting if " or \n in string
- f << "\"" << value << "\"";
+ QString escaped = value;
+ escaped.replace('"', "\"\"");
+ f << "\"" << escaped << "\"";
}
static void writeSep(QTextStream &f)
diff --git a/src/qt/editaddressdialog.cpp b/src/qt/editaddressdialog.cpp
index cecb8aecd7..0d88aa47cb 100644
--- a/src/qt/editaddressdialog.cpp
+++ b/src/qt/editaddressdialog.cpp
@@ -93,7 +93,7 @@ void EditAddressDialog::accept()
break;
case AddressTableModel::INVALID_ADDRESS:
QMessageBox::warning(this, windowTitle(),
- tr("The entered address \"%1\" is not a valid bitcoin address.").arg(ui->addressEdit->text()),
+ tr("The entered address \"%1\" is not a valid Bitcoin address.").arg(ui->addressEdit->text()),
QMessageBox::Ok, QMessageBox::Ok);
return;
case AddressTableModel::WALLET_UNLOCK_FAILURE:
diff --git a/src/qt/forms/aboutdialog.ui b/src/qt/forms/aboutdialog.ui
index 6e342e5e8a..21fc7b2019 100644
--- a/src/qt/forms/aboutdialog.ui
+++ b/src/qt/forms/aboutdialog.ui
@@ -22,9 +22,6 @@
<verstretch>0</verstretch>
</sizepolicy>
</property>
- <property name="text">
- <string/>
- </property>
<property name="pixmap">
<pixmap resource="../bitcoin.qrc">:/images/about</pixmap>
</property>
@@ -49,6 +46,9 @@
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLabel" name="label">
+ <property name="cursor">
+ <cursorShape>IBeamCursor</cursorShape>
+ </property>
<property name="text">
<string>&lt;b&gt;Bitcoin&lt;/b&gt; version</string>
</property>
@@ -59,6 +59,9 @@
</item>
<item>
<widget class="QLabel" name="versionLabel">
+ <property name="cursor">
+ <cursorShape>IBeamCursor</cursorShape>
+ </property>
<property name="text">
<string notr="true">0.3.666-beta</string>
</property>
@@ -87,6 +90,9 @@
</item>
<item>
<widget class="QLabel" name="label_2">
+ <property name="cursor">
+ <cursorShape>IBeamCursor</cursorShape>
+ </property>
<property name="text">
<string>Copyright © 2009-2012 Bitcoin Developers
diff --git a/src/qt/forms/addressbookpage.ui b/src/qt/forms/addressbookpage.ui
index b31a9ce997..bca0a8dcdb 100644
--- a/src/qt/forms/addressbookpage.ui
+++ b/src/qt/forms/addressbookpage.ui
@@ -29,9 +29,15 @@
</item>
<item>
<widget class="QTableView" name="tableView">
+ <property name="contextMenuPolicy">
+ <enum>Qt::CustomContextMenu</enum>
+ </property>
<property name="toolTip">
<string>Double-click to edit address or label</string>
</property>
+ <property name="tabKeyNavigation">
+ <bool>false</bool>
+ </property>
<property name="alternatingRowColors">
<bool>true</bool>
</property>
@@ -57,7 +63,7 @@
<string>Create a new address</string>
</property>
<property name="text">
- <string>&amp;New Address...</string>
+ <string>&amp;New Address</string>
</property>
<property name="icon">
<iconset resource="../bitcoin.qrc">
@@ -71,7 +77,7 @@
<string>Copy the currently selected address to the system clipboard</string>
</property>
<property name="text">
- <string>&amp;Copy to Clipboard</string>
+ <string>&amp;Copy Address</string>
</property>
<property name="icon">
<iconset resource="../bitcoin.qrc">
@@ -86,7 +92,7 @@
</property>
<property name="icon">
<iconset resource="../bitcoin.qrc">
- <normaloff>:/images/qrcode</normaloff>:/images/qrcode</iconset>
+ <normaloff>:/icons/qrcode</normaloff>:/icons/qrcode</iconset>
</property>
</widget>
</item>
diff --git a/src/qt/forms/askpassphrasedialog.ui b/src/qt/forms/askpassphrasedialog.ui
index 3f6b668e06..25169042a1 100644
--- a/src/qt/forms/askpassphrasedialog.ui
+++ b/src/qt/forms/askpassphrasedialog.ui
@@ -23,14 +23,11 @@
</size>
</property>
<property name="windowTitle">
- <string>Dialog</string>
+ <string>Passphrase Dialog</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QLabel" name="warningLabel">
- <property name="text">
- <string>TextLabel</string>
- </property>
<property name="textFormat">
<enum>Qt::RichText</enum>
</property>
@@ -44,57 +41,58 @@
<property name="fieldGrowthPolicy">
<enum>QFormLayout::AllNonFixedFieldsGrow</enum>
</property>
- <item row="1" column="0">
+ <item row="0" column="0">
<widget class="QLabel" name="passLabel1">
<property name="text">
<string>Enter passphrase</string>
</property>
</widget>
</item>
- <item row="1" column="1">
+ <item row="0" column="1">
<widget class="QLineEdit" name="passEdit1">
<property name="echoMode">
<enum>QLineEdit::Password</enum>
</property>
</widget>
</item>
- <item row="2" column="0">
+ <item row="1" column="0">
<widget class="QLabel" name="passLabel2">
<property name="text">
<string>New passphrase</string>
</property>
</widget>
</item>
- <item row="2" column="1">
+ <item row="1" column="1">
<widget class="QLineEdit" name="passEdit2">
<property name="echoMode">
<enum>QLineEdit::Password</enum>
</property>
</widget>
</item>
- <item row="3" column="0">
+ <item row="2" column="0">
<widget class="QLabel" name="passLabel3">
<property name="text">
<string>Repeat new passphrase</string>
</property>
</widget>
</item>
- <item row="3" column="1">
+ <item row="2" column="1">
<widget class="QLineEdit" name="passEdit3">
<property name="echoMode">
<enum>QLineEdit::Password</enum>
</property>
</widget>
</item>
- <item row="4" column="1">
+ <item row="3" column="1">
<widget class="QLabel" name="capsLabel">
- <property name="styleSheet">
- <string notr="true">#capsLabel {
- font: bold;
-}</string>
+ <property name="font">
+ <font>
+ <weight>75</weight>
+ <bold>true</bold>
+ </font>
</property>
<property name="text">
- <string>TextLabel</string>
+ <string/>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
diff --git a/src/qt/forms/messagepage.ui b/src/qt/forms/messagepage.ui
index ae1e062fca..0b685aae1d 100644
--- a/src/qt/forms/messagepage.ui
+++ b/src/qt/forms/messagepage.ui
@@ -11,7 +11,7 @@
</rect>
</property>
<property name="windowTitle">
- <string>Message</string>
+ <string>Sign Message</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
@@ -101,9 +101,6 @@
<italic>true</italic>
</font>
</property>
- <property name="text">
- <string>Click &quot;Sign Message&quot; to get signature</string>
- </property>
<property name="readOnly">
<bool>true</bool>
</property>
@@ -131,7 +128,7 @@
<string>Copy the current signature to the system clipboard</string>
</property>
<property name="text">
- <string>&amp;Copy to Clipboard</string>
+ <string>&amp;Copy Signature</string>
</property>
<property name="icon">
<iconset resource="../bitcoin.qrc">
@@ -140,6 +137,20 @@
</widget>
</item>
<item>
+ <widget class="QPushButton" name="clearButton">
+ <property name="toolTip">
+ <string>Reset all sign message fields</string>
+ </property>
+ <property name="text">
+ <string>Clear &amp;All</string>
+ </property>
+ <property name="icon">
+ <iconset resource="../bitcoin.qrc">
+ <normaloff>:/icons/remove</normaloff>:/icons/remove</iconset>
+ </property>
+ </widget>
+ </item>
+ <item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
diff --git a/src/qt/forms/overviewpage.ui b/src/qt/forms/overviewpage.ui
index cc67fae533..6573517b24 100644
--- a/src/qt/forms/overviewpage.ui
+++ b/src/qt/forms/overviewpage.ui
@@ -24,68 +24,141 @@
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
- <layout class="QFormLayout" name="formLayout_2">
- <property name="fieldGrowthPolicy">
- <enum>QFormLayout::AllNonFixedFieldsGrow</enum>
- </property>
- <property name="horizontalSpacing">
- <number>12</number>
- </property>
- <property name="verticalSpacing">
- <number>12</number>
- </property>
- <item row="2" column="0">
- <widget class="QLabel" name="label">
- <property name="text">
- <string>Balance:</string>
- </property>
- </widget>
- </item>
- <item row="2" column="1">
- <widget class="QLabel" name="labelBalance">
- <property name="text">
- <string>123.456 BTC</string>
- </property>
- </widget>
- </item>
- <item row="4" column="0">
- <widget class="QLabel" name="label_2">
- <property name="text">
- <string>Number of transactions:</string>
- </property>
- </widget>
- </item>
- <item row="4" column="1">
- <widget class="QLabel" name="labelNumTransactions">
- <property name="text">
- <string>0</string>
- </property>
- </widget>
+ <layout class="QVBoxLayout" name="verticalLayout_4">
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_4">
+ <item>
+ <widget class="QLabel" name="label_5">
+ <property name="font">
+ <font>
+ <pointsize>11</pointsize>
+ <weight>75</weight>
+ <bold>true</bold>
+ </font>
+ </property>
+ <property name="text">
+ <string>Wallet</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="labelWalletStatus">
+ <property name="toolTip">
+ <string>The displayed information may be out of date. Your wallet automatically synchronizes with the Bitcoin network after a connection is established, but this process has not completed yet.</string>
+ </property>
+ <property name="styleSheet">
+ <string notr="true">QLabel { color: red; }</string>
+ </property>
+ <property name="text">
+ <string notr="true">(out of sync)</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer_2">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
</item>
- <item row="3" column="0">
- <widget class="QLabel" name="label_3">
- <property name="text">
- <string>Unconfirmed:</string>
+ <item>
+ <layout class="QFormLayout" name="formLayout_2">
+ <property name="fieldGrowthPolicy">
+ <enum>QFormLayout::AllNonFixedFieldsGrow</enum>
</property>
- </widget>
- </item>
- <item row="3" column="1">
- <widget class="QLabel" name="labelUnconfirmed">
- <property name="text">
- <string>0 BTC</string>
+ <property name="horizontalSpacing">
+ <number>12</number>
</property>
- </widget>
- </item>
- <item row="1" column="0">
- <widget class="QLabel" name="label_5">
- <property name="text">
- <string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
-&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
-p, li { white-space: pre-wrap; }
-&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'Ubuntu'; font-size:11pt; font-weight:400; font-style:normal;&quot;&gt;
-&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;Wallet&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
+ <property name="verticalSpacing">
+ <number>12</number>
</property>
- </widget>
+ <item row="0" column="0">
+ <widget class="QLabel" name="label">
+ <property name="text">
+ <string>Balance:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="QLabel" name="labelBalance">
+ <property name="font">
+ <font>
+ <weight>75</weight>
+ <bold>true</bold>
+ </font>
+ </property>
+ <property name="cursor">
+ <cursorShape>IBeamCursor</cursorShape>
+ </property>
+ <property name="toolTip">
+ <string>Your current balance</string>
+ </property>
+ <property name="text">
+ <string notr="true">123.456 BTC</string>
+ </property>
+ <property name="textInteractionFlags">
+ <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0">
+ <widget class="QLabel" name="label_3">
+ <property name="text">
+ <string>Unconfirmed:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="QLabel" name="labelUnconfirmed">
+ <property name="font">
+ <font>
+ <weight>75</weight>
+ <bold>true</bold>
+ </font>
+ </property>
+ <property name="cursor">
+ <cursorShape>IBeamCursor</cursorShape>
+ </property>
+ <property name="toolTip">
+ <string>Total of transactions that have yet to be confirmed, and do not yet count toward the current balance</string>
+ </property>
+ <property name="text">
+ <string notr="true">0 BTC</string>
+ </property>
+ <property name="textInteractionFlags">
+ <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="0">
+ <widget class="QLabel" name="label_2">
+ <property name="text">
+ <string>Number of transactions:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="1">
+ <widget class="QLabel" name="labelNumTransactions">
+ <property name="toolTip">
+ <string>Total number of transactions in wallet</string>
+ </property>
+ <property name="text">
+ <string notr="true">0</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
</item>
</layout>
</widget>
@@ -117,14 +190,50 @@ p, li { white-space: pre-wrap; }
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
- <widget class="QLabel" name="label_4">
- <property name="text">
- <string>&lt;b&gt;Recent transactions&lt;/b&gt;</string>
- </property>
- </widget>
+ <layout class="QHBoxLayout" name="horizontalLayout_2">
+ <item>
+ <widget class="QLabel" name="label_4">
+ <property name="text">
+ <string>&lt;b&gt;Recent transactions&lt;/b&gt;</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="labelTransactionsStatus">
+ <property name="toolTip">
+ <string>The displayed information may be out of date. Your wallet automatically synchronizes with the Bitcoin network after a connection is established, but this process has not completed yet.</string>
+ </property>
+ <property name="styleSheet">
+ <string notr="true">QLabel { color: red; }</string>
+ </property>
+ <property name="text">
+ <string notr="true">(out of sync)</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
</item>
<item>
<widget class="QListView" name="listTransactions">
+ <property name="styleSheet">
+ <string notr="true">QListView { background: transparent; }</string>
+ </property>
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
@@ -134,6 +243,9 @@ p, li { white-space: pre-wrap; }
<property name="horizontalScrollBarPolicy">
<enum>Qt::ScrollBarAlwaysOff</enum>
</property>
+ <property name="selectionMode">
+ <enum>QAbstractItemView::NoSelection</enum>
+ </property>
</widget>
</item>
</layout>
diff --git a/src/qt/forms/qrcodedialog.ui b/src/qt/forms/qrcodedialog.ui
index 714b1d6cd8..6199b68749 100644
--- a/src/qt/forms/qrcodedialog.ui
+++ b/src/qt/forms/qrcodedialog.ui
@@ -6,12 +6,12 @@
<rect>
<x>0</x>
<y>0</y>
- <width>320</width>
- <height>404</height>
+ <width>334</width>
+ <height>425</height>
</rect>
</property>
<property name="windowTitle">
- <string>Dialog</string>
+ <string>QR Code Dialog</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_3">
<item>
diff --git a/src/qt/forms/rpcconsole.ui b/src/qt/forms/rpcconsole.ui
new file mode 100644
index 0000000000..cded274792
--- /dev/null
+++ b/src/qt/forms/rpcconsole.ui
@@ -0,0 +1,401 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>RPCConsole</class>
+ <widget class="QDialog" name="RPCConsole">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>706</width>
+ <height>446</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Bitcoin debug window</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout_2">
+ <item>
+ <widget class="QTabWidget" name="tabWidget">
+ <property name="currentIndex">
+ <number>0</number>
+ </property>
+ <widget class="QWidget" name="tab_info">
+ <attribute name="title">
+ <string>&amp;Information</string>
+ </attribute>
+ <layout class="QGridLayout" name="gridLayout" columnstretch="0,1">
+ <property name="horizontalSpacing">
+ <number>12</number>
+ </property>
+ <item row="0" column="0">
+ <widget class="QLabel" name="label_9">
+ <property name="font">
+ <font>
+ <weight>75</weight>
+ <bold>true</bold>
+ </font>
+ </property>
+ <property name="text">
+ <string>Client</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0">
+ <widget class="QLabel" name="label_5">
+ <property name="text">
+ <string>Client name</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="QLabel" name="clientName">
+ <property name="cursor">
+ <cursorShape>IBeamCursor</cursorShape>
+ </property>
+ <property name="text">
+ <string>N/A</string>
+ </property>
+ <property name="textFormat">
+ <enum>Qt::PlainText</enum>
+ </property>
+ <property name="textInteractionFlags">
+ <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="0">
+ <widget class="QLabel" name="label_6">
+ <property name="text">
+ <string>Client version</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="1">
+ <widget class="QLabel" name="clientVersion">
+ <property name="cursor">
+ <cursorShape>IBeamCursor</cursorShape>
+ </property>
+ <property name="text">
+ <string>N/A</string>
+ </property>
+ <property name="textFormat">
+ <enum>Qt::PlainText</enum>
+ </property>
+ <property name="textInteractionFlags">
+ <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="0">
+ <widget class="QLabel" name="label_12">
+ <property name="text">
+ <string>Build date</string>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="1">
+ <widget class="QLabel" name="buildDate">
+ <property name="cursor">
+ <cursorShape>IBeamCursor</cursorShape>
+ </property>
+ <property name="text">
+ <string>N/A</string>
+ </property>
+ <property name="textFormat">
+ <enum>Qt::PlainText</enum>
+ </property>
+ <property name="textInteractionFlags">
+ <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="0">
+ <widget class="QLabel" name="label_13">
+ <property name="text">
+ <string>Startup time</string>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="1">
+ <widget class="QLabel" name="startupTime">
+ <property name="cursor">
+ <cursorShape>IBeamCursor</cursorShape>
+ </property>
+ <property name="text">
+ <string>N/A</string>
+ </property>
+ <property name="textFormat">
+ <enum>Qt::PlainText</enum>
+ </property>
+ <property name="textInteractionFlags">
+ <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
+ </property>
+ </widget>
+ </item>
+ <item row="5" column="0">
+ <widget class="QLabel" name="label_11">
+ <property name="font">
+ <font>
+ <weight>75</weight>
+ <bold>true</bold>
+ </font>
+ </property>
+ <property name="text">
+ <string>Network</string>
+ </property>
+ </widget>
+ </item>
+ <item row="6" column="0">
+ <widget class="QLabel" name="label_7">
+ <property name="text">
+ <string>Number of connections</string>
+ </property>
+ </widget>
+ </item>
+ <item row="6" column="1">
+ <widget class="QLabel" name="numberOfConnections">
+ <property name="cursor">
+ <cursorShape>IBeamCursor</cursorShape>
+ </property>
+ <property name="text">
+ <string>N/A</string>
+ </property>
+ <property name="textFormat">
+ <enum>Qt::PlainText</enum>
+ </property>
+ <property name="textInteractionFlags">
+ <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
+ </property>
+ </widget>
+ </item>
+ <item row="7" column="0">
+ <widget class="QLabel" name="label_8">
+ <property name="text">
+ <string>On testnet</string>
+ </property>
+ </widget>
+ </item>
+ <item row="7" column="1">
+ <widget class="QCheckBox" name="isTestNet">
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ </widget>
+ </item>
+ <item row="8" column="0">
+ <widget class="QLabel" name="label_10">
+ <property name="font">
+ <font>
+ <weight>75</weight>
+ <bold>true</bold>
+ </font>
+ </property>
+ <property name="text">
+ <string>Block chain</string>
+ </property>
+ </widget>
+ </item>
+ <item row="9" column="0">
+ <widget class="QLabel" name="label_3">
+ <property name="text">
+ <string>Current number of blocks</string>
+ </property>
+ </widget>
+ </item>
+ <item row="9" column="1">
+ <widget class="QLabel" name="numberOfBlocks">
+ <property name="cursor">
+ <cursorShape>IBeamCursor</cursorShape>
+ </property>
+ <property name="text">
+ <string>N/A</string>
+ </property>
+ <property name="textFormat">
+ <enum>Qt::PlainText</enum>
+ </property>
+ <property name="textInteractionFlags">
+ <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
+ </property>
+ </widget>
+ </item>
+ <item row="10" column="0">
+ <widget class="QLabel" name="label_4">
+ <property name="text">
+ <string>Estimated total blocks</string>
+ </property>
+ </widget>
+ </item>
+ <item row="10" column="1">
+ <widget class="QLabel" name="totalBlocks">
+ <property name="cursor">
+ <cursorShape>IBeamCursor</cursorShape>
+ </property>
+ <property name="text">
+ <string>N/A</string>
+ </property>
+ <property name="textFormat">
+ <enum>Qt::PlainText</enum>
+ </property>
+ <property name="textInteractionFlags">
+ <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
+ </property>
+ </widget>
+ </item>
+ <item row="11" column="0">
+ <widget class="QLabel" name="label_2">
+ <property name="text">
+ <string>Last block time</string>
+ </property>
+ </widget>
+ </item>
+ <item row="11" column="1">
+ <widget class="QLabel" name="lastBlockTime">
+ <property name="cursor">
+ <cursorShape>IBeamCursor</cursorShape>
+ </property>
+ <property name="text">
+ <string>N/A</string>
+ </property>
+ <property name="textFormat">
+ <enum>Qt::PlainText</enum>
+ </property>
+ <property name="textInteractionFlags">
+ <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
+ </property>
+ </widget>
+ </item>
+ <item row="12" column="0">
+ <spacer name="verticalSpacer_2">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item row="13" column="0">
+ <widget class="QLabel" name="labelDebugLogfile">
+ <property name="font">
+ <font>
+ <weight>75</weight>
+ <bold>true</bold>
+ </font>
+ </property>
+ <property name="text">
+ <string>Debug logfile</string>
+ </property>
+ </widget>
+ </item>
+ <item row="14" column="0">
+ <widget class="QPushButton" name="openDebugLogfileButton">
+ <property name="toolTip">
+ <string>Open the Bitcoin debug logfile from the current data directory. This can take a few seconds for large logfiles.</string>
+ </property>
+ <property name="text">
+ <string>&amp;Open</string>
+ </property>
+ </widget>
+ </item>
+ <item row="15" column="0">
+ <spacer name="verticalSpacer">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QWidget" name="tab_console">
+ <attribute name="title">
+ <string>&amp;Console</string>
+ </attribute>
+ <layout class="QVBoxLayout" name="verticalLayout_3">
+ <property name="spacing">
+ <number>3</number>
+ </property>
+ <item>
+ <widget class="QTextEdit" name="messagesWidget">
+ <property name="minimumSize">
+ <size>
+ <width>0</width>
+ <height>100</height>
+ </size>
+ </property>
+ <property name="readOnly">
+ <bool>true</bool>
+ </property>
+ <property name="tabKeyNavigation" stdset="0">
+ <bool>false</bool>
+ </property>
+ <property name="columnCount" stdset="0">
+ <number>2</number>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <property name="spacing">
+ <number>3</number>
+ </property>
+ <item>
+ <widget class="QLabel" name="label">
+ <property name="text">
+ <string notr="true">&gt;</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLineEdit" name="lineEdit"/>
+ </item>
+ <item>
+ <widget class="QPushButton" name="clearButton">
+ <property name="maximumSize">
+ <size>
+ <width>24</width>
+ <height>24</height>
+ </size>
+ </property>
+ <property name="toolTip">
+ <string>Clear console</string>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="icon">
+ <iconset resource="../bitcoin.qrc">
+ <normaloff>:/icons/remove</normaloff>:/icons/remove</iconset>
+ </property>
+ <property name="shortcut">
+ <string notr="true">Ctrl+L</string>
+ </property>
+ <property name="autoDefault">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <resources>
+ <include location="../bitcoin.qrc"/>
+ </resources>
+ <connections/>
+</ui>
diff --git a/src/qt/forms/sendcoinsdialog.ui b/src/qt/forms/sendcoinsdialog.ui
index 04cf404ae3..023a72ac2b 100644
--- a/src/qt/forms/sendcoinsdialog.ui
+++ b/src/qt/forms/sendcoinsdialog.ui
@@ -64,7 +64,7 @@
<string>Send to multiple recipients at once</string>
</property>
<property name="text">
- <string>&amp;Add recipient...</string>
+ <string>&amp;Add Recipient</string>
</property>
<property name="icon">
<iconset resource="../bitcoin.qrc">
@@ -84,7 +84,7 @@
<string>Remove all transaction fields</string>
</property>
<property name="text">
- <string>Clear all</string>
+ <string>Clear &amp;All</string>
</property>
<property name="icon">
<iconset resource="../bitcoin.qrc">
diff --git a/src/qt/forms/transactiondescdialog.ui b/src/qt/forms/transactiondescdialog.ui
index 9a9f6db158..039cb082cc 100644
--- a/src/qt/forms/transactiondescdialog.ui
+++ b/src/qt/forms/transactiondescdialog.ui
@@ -6,8 +6,8 @@
<rect>
<x>0</x>
<y>0</y>
- <width>400</width>
- <height>300</height>
+ <width>600</width>
+ <height>250</height>
</rect>
</property>
<property name="windowTitle">
diff --git a/src/qt/forms/verifymessagedialog.ui b/src/qt/forms/verifymessagedialog.ui
new file mode 100644
index 0000000000..a7c99716e4
--- /dev/null
+++ b/src/qt/forms/verifymessagedialog.ui
@@ -0,0 +1,125 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>VerifyMessageDialog</class>
+ <widget class="QDialog" name="VerifyMessageDialog">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>494</width>
+ <height>342</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Verify Signed Message</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <widget class="QLabel" name="label">
+ <property name="text">
+ <string>Enter the message and signature below (be careful to correctly copy newlines, spaces, tabs and other invisible characters) to obtain the Bitcoin address used to sign the message.</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
+ </property>
+ <property name="wordWrap">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPlainTextEdit" name="edMessage"/>
+ </item>
+ <item>
+ <widget class="QLineEdit" name="lnSig">
+ <property name="text">
+ <string/>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLineEdit" name="lnAddress">
+ <property name="text">
+ <string/>
+ </property>
+ <property name="readOnly">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="lblStatus">
+ <property name="text">
+ <string/>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <item>
+ <widget class="QPushButton" name="verifyMessage">
+ <property name="toolTip">
+ <string>Verify a message and obtain the Bitcoin address used to sign the message</string>
+ </property>
+ <property name="text">
+ <string>&amp;Verify Message</string>
+ </property>
+ <property name="icon">
+ <iconset resource="../bitcoin.qrc">
+ <normaloff>:/icons/transaction_0</normaloff>:/icons/transaction_0</iconset>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="copyToClipboard">
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="toolTip">
+ <string>Copy the currently selected address to the system clipboard</string>
+ </property>
+ <property name="text">
+ <string>&amp;Copy Address</string>
+ </property>
+ <property name="icon">
+ <iconset resource="../bitcoin.qrc">
+ <normaloff>:/icons/editcopy</normaloff>:/icons/editcopy</iconset>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="clearButton">
+ <property name="toolTip">
+ <string>Reset all verify message fields</string>
+ </property>
+ <property name="text">
+ <string>Clear &amp;All</string>
+ </property>
+ <property name="icon">
+ <iconset resource="../bitcoin.qrc">
+ <normaloff>:/icons/remove</normaloff>:/icons/remove</iconset>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ <resources>
+ <include location="../bitcoin.qrc"/>
+ </resources>
+ <connections/>
+</ui>
diff --git a/src/qt/guiconstants.h b/src/qt/guiconstants.h
index 0cb507501a..54e9d644fe 100644
--- a/src/qt/guiconstants.h
+++ b/src/qt/guiconstants.h
@@ -20,4 +20,9 @@ static const int STATUSBAR_ICONSIZE = 16;
/* Transaction list -- bare address (without label) */
#define COLOR_BAREADDRESS QColor(140, 140, 140)
+/* Tooltips longer than this (in characters) are converted into rich text,
+ so that they can be word-wrapped.
+ */
+static const int TOOLTIP_WRAP_THRESHOLD = 80;
+
#endif // GUICONSTANTS_H
diff --git a/src/qt/guiutil.cpp b/src/qt/guiutil.cpp
index f1e8a5f1bc..22c0bfeebe 100644
--- a/src/qt/guiutil.cpp
+++ b/src/qt/guiutil.cpp
@@ -2,6 +2,7 @@
#include "bitcoinaddressvalidator.h"
#include "walletmodel.h"
#include "bitcoinunits.h"
+#include "util.h"
#include <QString>
#include <QDateTime>
@@ -17,6 +18,25 @@
#include <QDesktopServices>
#include <QThread>
+#include <boost/filesystem.hpp>
+#include <boost/filesystem/fstream.hpp>
+
+#ifdef WIN32
+#ifdef _WIN32_WINNT
+#undef _WIN32_WINNT
+#endif
+#define _WIN32_WINNT 0x0501
+#ifdef _WIN32_IE
+#undef _WIN32_IE
+#endif
+#define _WIN32_IE 0x0501
+#define WIN32_LEAN_AND_MEAN 1
+#ifndef NOMINMAX
+#define NOMINMAX
+#endif
+#include "shlwapi.h"
+#endif
+
namespace GUIUtil {
QString dateTimeStr(const QDateTime &date)
@@ -214,5 +234,184 @@ bool isObscured(QWidget *w)
&& checkPoint(QPoint(w->width()/2, w->height()/2), w));
}
+void openDebugLogfile()
+{
+ boost::filesystem::path pathDebug = GetDataDir() / "debug.log";
+
+#ifdef WIN32
+ if (boost::filesystem::exists(pathDebug))
+ /* Open debug.log with the associated application */
+ ShellExecuteA((HWND)0, (LPCSTR)"open", (LPCSTR)pathDebug.string().c_str(), NULL, NULL, SW_SHOWNORMAL);
+#endif
+}
+
+ToolTipToRichTextFilter::ToolTipToRichTextFilter(int size_threshold, QObject *parent) :
+ QObject(parent), size_threshold(size_threshold)
+{
+
+}
+
+bool ToolTipToRichTextFilter::eventFilter(QObject *obj, QEvent *evt)
+{
+ if(evt->type() == QEvent::ToolTipChange)
+ {
+ QWidget *widget = static_cast<QWidget*>(obj);
+ QString tooltip = widget->toolTip();
+ if(tooltip.size() > size_threshold && !tooltip.startsWith("<qt/>") && !Qt::mightBeRichText(tooltip))
+ {
+ // Prefix <qt/> to make sure Qt detects this as rich text
+ // Escape the current message as HTML and replace \n by <br>
+ tooltip = "<qt/>" + HtmlEscape(tooltip, true);
+ widget->setToolTip(tooltip);
+ return true;
+ }
+ }
+ return QObject::eventFilter(obj, evt);
+}
+
+#ifdef WIN32
+boost::filesystem::path static StartupShortcutPath()
+{
+ return GetSpecialFolderPath(CSIDL_STARTUP) / "Bitcoin.lnk";
+}
+
+bool GetStartOnSystemStartup()
+{
+ // check for Bitcoin.lnk
+ return boost::filesystem::exists(StartupShortcutPath());
+}
+
+bool SetStartOnSystemStartup(bool fAutoStart)
+{
+ // If the shortcut exists already, remove it for updating
+ boost::filesystem::remove(StartupShortcutPath());
+
+ if (fAutoStart)
+ {
+ CoInitialize(NULL);
+
+ // Get a pointer to the IShellLink interface.
+ IShellLink* psl = NULL;
+ HRESULT hres = CoCreateInstance(CLSID_ShellLink, NULL,
+ CLSCTX_INPROC_SERVER, IID_IShellLink,
+ reinterpret_cast<void**>(&psl));
+
+ if (SUCCEEDED(hres))
+ {
+ // Get the current executable path
+ TCHAR pszExePath[MAX_PATH];
+ GetModuleFileName(NULL, pszExePath, sizeof(pszExePath));
+
+ TCHAR pszArgs[5] = TEXT("-min");
+
+ // Set the path to the shortcut target
+ psl->SetPath(pszExePath);
+ PathRemoveFileSpec(pszExePath);
+ psl->SetWorkingDirectory(pszExePath);
+ psl->SetShowCmd(SW_SHOWMINNOACTIVE);
+ psl->SetArguments(pszArgs);
+
+ // Query IShellLink for the IPersistFile interface for
+ // saving the shortcut in persistent storage.
+ IPersistFile* ppf = NULL;
+ hres = psl->QueryInterface(IID_IPersistFile,
+ reinterpret_cast<void**>(&ppf));
+ if (SUCCEEDED(hres))
+ {
+ WCHAR pwsz[MAX_PATH];
+ // Ensure that the string is ANSI.
+ MultiByteToWideChar(CP_ACP, 0, StartupShortcutPath().string().c_str(), -1, pwsz, MAX_PATH);
+ // Save the link by calling IPersistFile::Save.
+ hres = ppf->Save(pwsz, TRUE);
+ ppf->Release();
+ psl->Release();
+ CoUninitialize();
+ return true;
+ }
+ psl->Release();
+ }
+ CoUninitialize();
+ return false;
+ }
+ return true;
+}
+
+#elif defined(LINUX)
+
+// Follow the Desktop Application Autostart Spec:
+// http://standards.freedesktop.org/autostart-spec/autostart-spec-latest.html
+
+boost::filesystem::path static GetAutostartDir()
+{
+ namespace fs = boost::filesystem;
+
+ char* pszConfigHome = getenv("XDG_CONFIG_HOME");
+ if (pszConfigHome) return fs::path(pszConfigHome) / "autostart";
+ char* pszHome = getenv("HOME");
+ if (pszHome) return fs::path(pszHome) / ".config" / "autostart";
+ return fs::path();
+}
+
+boost::filesystem::path static GetAutostartFilePath()
+{
+ return GetAutostartDir() / "bitcoin.desktop";
+}
+
+bool GetStartOnSystemStartup()
+{
+ boost::filesystem::ifstream optionFile(GetAutostartFilePath());
+ if (!optionFile.good())
+ return false;
+ // Scan through file for "Hidden=true":
+ std::string line;
+ while (!optionFile.eof())
+ {
+ getline(optionFile, line);
+ if (line.find("Hidden") != std::string::npos &&
+ line.find("true") != std::string::npos)
+ return false;
+ }
+ optionFile.close();
+
+ return true;
+}
+
+bool SetStartOnSystemStartup(bool fAutoStart)
+{
+ if (!fAutoStart)
+ boost::filesystem::remove(GetAutostartFilePath());
+ else
+ {
+ char pszExePath[MAX_PATH+1];
+ memset(pszExePath, 0, sizeof(pszExePath));
+ if (readlink("/proc/self/exe", pszExePath, sizeof(pszExePath)-1) == -1)
+ return false;
+
+ boost::filesystem::create_directories(GetAutostartDir());
+
+ boost::filesystem::ofstream optionFile(GetAutostartFilePath(), std::ios_base::out|std::ios_base::trunc);
+ if (!optionFile.good())
+ return false;
+ // Write a bitcoin.desktop file to the autostart directory:
+ optionFile << "[Desktop Entry]\n";
+ optionFile << "Type=Application\n";
+ optionFile << "Name=Bitcoin\n";
+ optionFile << "Exec=" << pszExePath << " -min\n";
+ optionFile << "Terminal=false\n";
+ optionFile << "Hidden=false\n";
+ optionFile.close();
+ }
+ return true;
+}
+#else
+
+// TODO: OSX startup stuff; see:
+// http://developer.apple.com/mac/library/documentation/MacOSX/Conceptual/BPSystemStartup/Articles/CustomLogin.html
+
+bool GetStartOnSystemStartup() { return false; }
+bool SetStartOnSystemStartup(bool fAutoStart) { return false; }
+
+#endif
+
} // namespace GUIUtil
diff --git a/src/qt/guiutil.h b/src/qt/guiutil.h
index ea1a4795c0..c5f9aae511 100644
--- a/src/qt/guiutil.h
+++ b/src/qt/guiutil.h
@@ -2,6 +2,7 @@
#define GUIUTIL_H
#include <QString>
+#include <QObject>
QT_BEGIN_NAMESPACE
class QFont;
@@ -21,7 +22,7 @@ namespace GUIUtil
QString dateTimeStr(const QDateTime &datetime);
QString dateTimeStr(qint64 nTime);
- // Render bitcoin addresses in monospace font
+ // Render Bitcoin addresses in monospace font
QFont bitcoinAddressFont();
// Set up widgets for address and amounts
@@ -69,6 +70,29 @@ namespace GUIUtil
// Determine whether a widget is hidden behind other windows
bool isObscured(QWidget *w);
+ // Open debug.log
+ void openDebugLogfile();
+
+ /** Qt event filter that intercepts ToolTipChange events, and replaces the tooltip with a rich text
+ representation if needed. This assures that Qt can word-wrap long tooltip messages.
+ Tooltips longer than the provided size threshold (in characters) are wrapped.
+ */
+ class ToolTipToRichTextFilter : public QObject
+ {
+ Q_OBJECT
+ public:
+ explicit ToolTipToRichTextFilter(int size_threshold, QObject *parent = 0);
+
+ protected:
+ bool eventFilter(QObject *obj, QEvent *evt);
+
+ private:
+ int size_threshold;
+ };
+
+ bool GetStartOnSystemStartup();
+ bool SetStartOnSystemStartup(bool fAutoStart);
+
} // namespace GUIUtil
#endif // GUIUTIL_H
diff --git a/src/qt/locale/bitcoin_bg.ts b/src/qt/locale/bitcoin_bg.ts
new file mode 100644
index 0000000000..7c8f606ef5
--- /dev/null
+++ b/src/qt/locale/bitcoin_bg.ts
@@ -0,0 +1,2247 @@
+<?xml version="1.0" ?><!DOCTYPE TS><TS language="bg" version="2.0">
+<defaultcodec>UTF-8</defaultcodec>
+<context>
+ <name>AboutDialog</name>
+ <message>
+ <location filename="../forms/aboutdialog.ui" line="14"/>
+ <source>About Bitcoin</source>
+ <translation>За Биткоин</translation>
+ </message>
+ <message>
+ <location filename="../forms/aboutdialog.ui" line="53"/>
+ <source>&lt;b&gt;Bitcoin&lt;/b&gt; version</source>
+ <translation>&lt;b&gt;Биткоин&lt;/b&gt; версия</translation>
+ </message>
+ <message>
+ <location filename="../forms/aboutdialog.ui" line="97"/>
+ <source>Copyright © 2009-2012 Bitcoin Developers
+
+This is experimental software.
+
+Distributed under the MIT/X11 software license, see the accompanying file license.txt or http://www.opensource.org/licenses/mit-license.php.
+
+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.</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
+ <name>AddressBookPage</name>
+ <message>
+ <location filename="../forms/addressbookpage.ui" line="14"/>
+ <source>Address Book</source>
+ <translation>Адреси</translation>
+ </message>
+ <message>
+ <location filename="../forms/addressbookpage.ui" line="20"/>
+ <source>These are your Bitcoin addresses for receiving payments. You may want to give a different one to each sender so you can keep track of who is paying you.</source>
+ <translation>Това са входящите адреси (за получаване на плащания). За прегледност може да предоставяте различен адрес за всяко плащане.</translation>
+ </message>
+ <message>
+ <location filename="../forms/addressbookpage.ui" line="36"/>
+ <source>Double-click to edit address or label</source>
+ <translation>Двоен клик за редакция на адрес или име</translation>
+ </message>
+ <message>
+ <location filename="../forms/addressbookpage.ui" line="63"/>
+ <source>Create a new address</source>
+ <translation>Създава нов адрес</translation>
+ </message>
+ <message>
+ <location filename="../forms/addressbookpage.ui" line="77"/>
+ <source>Copy the currently selected address to the system clipboard</source>
+ <translation>Копира избрания адрес</translation>
+ </message>
+ <message>
+ <location filename="../forms/addressbookpage.ui" line="66"/>
+ <source>&amp;New Address</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../forms/addressbookpage.ui" line="80"/>
+ <source>&amp;Copy Address</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../forms/addressbookpage.ui" line="91"/>
+ <source>Show &amp;QR Code</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../forms/addressbookpage.ui" line="102"/>
+ <source>Sign a message to prove you own this address</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../forms/addressbookpage.ui" line="105"/>
+ <source>&amp;Sign Message</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../forms/addressbookpage.ui" line="116"/>
+ <source>Delete the currently selected address from the list. Only sending addresses can be deleted.</source>
+ <translation>Изтрива избрания адрес. Не могат да се изтриват входящи адреси.</translation>
+ </message>
+ <message>
+ <location filename="../forms/addressbookpage.ui" line="119"/>
+ <source>&amp;Delete</source>
+ <translation>&amp;Изтрий</translation>
+ </message>
+ <message>
+ <location filename="../addressbookpage.cpp" line="63"/>
+ <source>Copy &amp;Label</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../addressbookpage.cpp" line="65"/>
+ <source>&amp;Edit</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../addressbookpage.cpp" line="297"/>
+ <source>Export Address Book Data</source>
+ <translation>Запазване на адреси</translation>
+ </message>
+ <message>
+ <location filename="../addressbookpage.cpp" line="298"/>
+ <source>Comma separated file (*.csv)</source>
+ <translation>CSV файл (*.csv)</translation>
+ </message>
+ <message>
+ <location filename="../addressbookpage.cpp" line="311"/>
+ <source>Error exporting</source>
+ <translation>Грешка при записа</translation>
+ </message>
+ <message>
+ <location filename="../addressbookpage.cpp" line="311"/>
+ <source>Could not write to file %1.</source>
+ <translation>Неуспешен запис в %1.</translation>
+ </message>
+</context>
+<context>
+ <name>AddressTableModel</name>
+ <message>
+ <location filename="../addresstablemodel.cpp" line="78"/>
+ <source>Label</source>
+ <translation>Име</translation>
+ </message>
+ <message>
+ <location filename="../addresstablemodel.cpp" line="78"/>
+ <source>Address</source>
+ <translation>Адрес</translation>
+ </message>
+ <message>
+ <location filename="../addresstablemodel.cpp" line="114"/>
+ <source>(no label)</source>
+ <translation>(без име)</translation>
+ </message>
+</context>
+<context>
+ <name>AskPassphraseDialog</name>
+ <message>
+ <location filename="../forms/askpassphrasedialog.ui" line="26"/>
+ <source>Dialog</source>
+ <translation>Dialog</translation>
+ </message>
+ <message>
+ <location filename="../forms/askpassphrasedialog.ui" line="32"/>
+ <location filename="../forms/askpassphrasedialog.ui" line="97"/>
+ <source>TextLabel</source>
+ <translation>TextLabel</translation>
+ </message>
+ <message>
+ <location filename="../forms/askpassphrasedialog.ui" line="50"/>
+ <source>Enter passphrase</source>
+ <translation>Парола</translation>
+ </message>
+ <message>
+ <location filename="../forms/askpassphrasedialog.ui" line="64"/>
+ <source>New passphrase</source>
+ <translation>Нова парола</translation>
+ </message>
+ <message>
+ <location filename="../forms/askpassphrasedialog.ui" line="78"/>
+ <source>Repeat new passphrase</source>
+ <translation>Още веднъж</translation>
+ </message>
+ <message>
+ <location filename="../askpassphrasedialog.cpp" line="34"/>
+ <source>Enter the new passphrase to the wallet.&lt;br/&gt;Please use a passphrase of &lt;b&gt;10 or more random characters&lt;/b&gt;, or &lt;b&gt;eight or more words&lt;/b&gt;.</source>
+ <translation>Въведете нова парола за портфейла.&lt;br/&gt;Моля използвайте &lt;b&gt;поне 10 случайни символа&lt;/b&gt;, или &lt;b&gt;8 или повече думи&lt;/b&gt;.</translation>
+ </message>
+ <message>
+ <location filename="../askpassphrasedialog.cpp" line="35"/>
+ <source>Encrypt wallet</source>
+ <translation>Криптиране на портфейла</translation>
+ </message>
+ <message>
+ <location filename="../askpassphrasedialog.cpp" line="38"/>
+ <source>This operation needs your wallet passphrase to unlock the wallet.</source>
+ <translation>Тази операция изисква Вашата парола за отключване на портфейла.</translation>
+ </message>
+ <message>
+ <location filename="../askpassphrasedialog.cpp" line="43"/>
+ <source>Unlock wallet</source>
+ <translation>Отключване на портфейла</translation>
+ </message>
+ <message>
+ <location filename="../askpassphrasedialog.cpp" line="46"/>
+ <source>This operation needs your wallet passphrase to decrypt the wallet.</source>
+ <translation>Тази операция изисква Вашата парола за декриптиране на портфейла.</translation>
+ </message>
+ <message>
+ <location filename="../askpassphrasedialog.cpp" line="51"/>
+ <source>Decrypt wallet</source>
+ <translation>Декриптиране на портфейла</translation>
+ </message>
+ <message>
+ <location filename="../askpassphrasedialog.cpp" line="54"/>
+ <source>Change passphrase</source>
+ <translation>Промяна на парола</translation>
+ </message>
+ <message>
+ <location filename="../askpassphrasedialog.cpp" line="55"/>
+ <source>Enter the old and new passphrase to the wallet.</source>
+ <translation>Въведете текущата и новата парола за портфейла.</translation>
+ </message>
+ <message>
+ <location filename="../askpassphrasedialog.cpp" line="101"/>
+ <source>Confirm wallet encryption</source>
+ <translation>Потвърждаване на криптирането</translation>
+ </message>
+ <message>
+ <location filename="../askpassphrasedialog.cpp" line="102"/>
+ <source>WARNING: If you encrypt your wallet and lose your passphrase, you will &lt;b&gt;LOSE ALL OF YOUR BITCOINS&lt;/b&gt;!
+Are you sure you wish to encrypt your wallet?</source>
+ <translation>ВНИМАНИЕ: Ако криптирате портфейла и забравите паролата &lt;b&gt;ЩЕ ЗАГУБИТЕ ВСИЧКИ КОИНИ&lt;/b&gt;!
+Сигурни ли сте, че искате да криптирате портфейла?</translation>
+ </message>
+ <message>
+ <location filename="../askpassphrasedialog.cpp" line="111"/>
+ <location filename="../askpassphrasedialog.cpp" line="160"/>
+ <source>Wallet encrypted</source>
+ <translation>Портфейлът е криптиран</translation>
+ </message>
+ <message>
+ <location filename="../askpassphrasedialog.cpp" line="112"/>
+ <source>Bitcoin will close now to finish the encryption process. Remember that encrypting your wallet cannot fully protect your bitcoins from being stolen by malware infecting your computer.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../askpassphrasedialog.cpp" line="208"/>
+ <location filename="../askpassphrasedialog.cpp" line="232"/>
+ <source>Warning: The Caps Lock key is on.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../askpassphrasedialog.cpp" line="117"/>
+ <location filename="../askpassphrasedialog.cpp" line="124"/>
+ <location filename="../askpassphrasedialog.cpp" line="166"/>
+ <location filename="../askpassphrasedialog.cpp" line="172"/>
+ <source>Wallet encryption failed</source>
+ <translation>Криптирането беше неуспешно</translation>
+ </message>
+ <message>
+ <location filename="../askpassphrasedialog.cpp" line="118"/>
+ <source>Wallet encryption failed due to an internal error. Your wallet was not encrypted.</source>
+ <translation>Криптирането на портфейла беше неуспешно поради неизвестен проблем. Портфейлът не е криптиран.</translation>
+ </message>
+ <message>
+ <location filename="../askpassphrasedialog.cpp" line="125"/>
+ <location filename="../askpassphrasedialog.cpp" line="173"/>
+ <source>The supplied passphrases do not match.</source>
+ <translation>Паролите не съвпадат</translation>
+ </message>
+ <message>
+ <location filename="../askpassphrasedialog.cpp" line="136"/>
+ <source>Wallet unlock failed</source>
+ <translation>Отключването беше неуспешно</translation>
+ </message>
+ <message>
+ <location filename="../askpassphrasedialog.cpp" line="137"/>
+ <location filename="../askpassphrasedialog.cpp" line="148"/>
+ <location filename="../askpassphrasedialog.cpp" line="167"/>
+ <source>The passphrase entered for the wallet decryption was incorrect.</source>
+ <translation>Паролата въведена за декриптиране на портфейла е грешна.</translation>
+ </message>
+ <message>
+ <location filename="../askpassphrasedialog.cpp" line="147"/>
+ <source>Wallet decryption failed</source>
+ <translation>Декриптирането беше неуспешно</translation>
+ </message>
+ <message>
+ <location filename="../askpassphrasedialog.cpp" line="161"/>
+ <source>Wallet passphrase was succesfully changed.</source>
+ <translation>Паролата за портфейла беше променена успешно.</translation>
+ </message>
+</context>
+<context>
+ <name>BitcoinGUI</name>
+ <message>
+ <location filename="../bitcoingui.cpp" line="72"/>
+ <source>Bitcoin Wallet</source>
+ <translation>Биткоин портфейл</translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="212"/>
+ <source>Sign &amp;message...</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="245"/>
+ <source>Show/Hide &amp;Bitcoin</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="507"/>
+ <source>Synchronizing with network...</source>
+ <translation>Синхронизиране с мрежата...</translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="182"/>
+ <source>&amp;Overview</source>
+ <translation>&amp;Баланс</translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="183"/>
+ <source>Show general overview of wallet</source>
+ <translation>Обобщена информация за портфейла</translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="188"/>
+ <source>&amp;Transactions</source>
+ <translation>&amp;Плащания</translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="189"/>
+ <source>Browse transaction history</source>
+ <translation>История на входящи и изходящи плащания</translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="194"/>
+ <source>&amp;Address Book</source>
+ <translation>&amp;Адреси</translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="195"/>
+ <source>Edit the list of stored addresses and labels</source>
+ <translation>Редактиране на адреси</translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="200"/>
+ <source>&amp;Receive coins</source>
+ <translation>&amp;Получаване</translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="201"/>
+ <source>Show the list of addresses for receiving payments</source>
+ <translation>Списък на адресите за получаване на плащания</translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="206"/>
+ <source>&amp;Send coins</source>
+ <translation>&amp;Изпращане</translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="207"/>
+ <source>Send coins to a bitcoin address</source>
+ <translation>Изпращане на коини</translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="213"/>
+ <source>Prove you control an address</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="232"/>
+ <source>E&amp;xit</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="233"/>
+ <source>Quit application</source>
+ <translation>Затваря приложението</translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="236"/>
+ <source>&amp;About %1</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="237"/>
+ <source>Show information about Bitcoin</source>
+ <translation>Показва информация за Биткоин</translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="239"/>
+ <source>About &amp;Qt</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="240"/>
+ <source>Show information about Qt</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="242"/>
+ <source>&amp;Options...</source>
+ <translation>&amp;Опции...</translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="243"/>
+ <source>Modify configuration options for bitcoin</source>
+ <translation>Конфигурационни опции</translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="249"/>
+ <source>&amp;Encrypt Wallet...</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="252"/>
+ <source>&amp;Backup Wallet...</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="254"/>
+ <source>&amp;Change Passphrase...</source>
+ <translation type="unfinished"/>
+ </message>
+ <message numerus="yes">
+ <location filename="../bitcoingui.cpp" line="509"/>
+ <source>~%n block(s) remaining</source>
+ <translation type="unfinished"><numerusform></numerusform><numerusform></numerusform></translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="520"/>
+ <source>Downloaded %1 of %2 blocks of transaction history (%3% done).</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="247"/>
+ <source>&amp;Export...</source>
+ <translation>&amp;Запазване...</translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="246"/>
+ <source>Show or hide the Bitcoin window</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="248"/>
+ <source>Export the data in the current tab to a file</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="250"/>
+ <source>Encrypt or decrypt wallet</source>
+ <translation>Криптира или декриптира портфейла</translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="253"/>
+ <source>Backup wallet to another location</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="255"/>
+ <source>Change the passphrase used for wallet encryption</source>
+ <translation>Променя паролата за портфейла</translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="256"/>
+ <source>&amp;Debug window</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="257"/>
+ <source>Open debugging and diagnostic console</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="280"/>
+ <source>&amp;File</source>
+ <translation>&amp;Файл</translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="289"/>
+ <source>&amp;Settings</source>
+ <translation>&amp;Настройки</translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="295"/>
+ <source>&amp;Help</source>
+ <translation>&amp;Помощ</translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="304"/>
+ <source>Tabs toolbar</source>
+ <translation>Раздели</translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="315"/>
+ <source>Actions toolbar</source>
+ <translation>Функции</translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="327"/>
+ <source>[testnet]</source>
+ <translation>[testnet]</translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="391"/>
+ <source>Bitcoin client</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="419"/>
+ <source>bitcoin-qt</source>
+ <translation>Биткоин</translation>
+ </message>
+ <message numerus="yes">
+ <location filename="../bitcoingui.cpp" line="483"/>
+ <source>%n active connection(s) to Bitcoin network</source>
+ <translation><numerusform>%n връзка към Биткоин мрежата</numerusform><numerusform>%n връзки към Биткоин мрежата</numerusform></translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="532"/>
+ <source>Downloaded %1 blocks of transaction history.</source>
+ <translation>%1 блока.</translation>
+ </message>
+ <message numerus="yes">
+ <location filename="../bitcoingui.cpp" line="547"/>
+ <source>%n second(s) ago</source>
+ <translation><numerusform>%n секунда</numerusform><numerusform>%n секунди</numerusform></translation>
+ </message>
+ <message numerus="yes">
+ <location filename="../bitcoingui.cpp" line="551"/>
+ <source>%n minute(s) ago</source>
+ <translation><numerusform>%n минута</numerusform><numerusform>%n минути</numerusform></translation>
+ </message>
+ <message numerus="yes">
+ <location filename="../bitcoingui.cpp" line="555"/>
+ <source>%n hour(s) ago</source>
+ <translation><numerusform>%n час</numerusform><numerusform>%n часа</numerusform></translation>
+ </message>
+ <message numerus="yes">
+ <location filename="../bitcoingui.cpp" line="559"/>
+ <source>%n day(s) ago</source>
+ <translation><numerusform>%n ден</numerusform><numerusform>%n дни</numerusform></translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="565"/>
+ <source>Up to date</source>
+ <translation>Синхронизиран</translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="570"/>
+ <source>Catching up...</source>
+ <translation>Зарежда блокове...</translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="578"/>
+ <source>Last received block was generated %1.</source>
+ <translation>Последният блок е от %1.</translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="634"/>
+ <source>This transaction is over the size limit. You can still send it for a fee of %1, which goes to the nodes that process your transaction and helps to support the network. Do you want to pay the fee?</source>
+ <translation>Размерът на плащането ще надвиши максималният размер на безплатно плащане. Можете да платите срещу такса от %1, която ще бъде получена от участниците в мрежата, обработващи плащания. Желаете ли да платите таксата?</translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="639"/>
+ <source>Confirm transaction fee</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="666"/>
+ <source>Sent transaction</source>
+ <translation>Изходящо плащане</translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="667"/>
+ <source>Incoming transaction</source>
+ <translation>Входящо плащане</translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="668"/>
+ <source>Date: %1
+Amount: %2
+Type: %3
+Address: %4
+</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="793"/>
+ <source>Wallet is &lt;b&gt;encrypted&lt;/b&gt; and currently &lt;b&gt;unlocked&lt;/b&gt;</source>
+ <translation>Портфейлът е &lt;b&gt;криптиран&lt;/b&gt; и &lt;b&gt;отключен&lt;/b&gt;</translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="801"/>
+ <source>Wallet is &lt;b&gt;encrypted&lt;/b&gt; and currently &lt;b&gt;locked&lt;/b&gt;</source>
+ <translation>Портфейлът е &lt;b&gt;криптиран&lt;/b&gt; и &lt;b&gt;заключен&lt;/b&gt;</translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="824"/>
+ <source>Backup Wallet</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="824"/>
+ <source>Wallet Data (*.dat)</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="827"/>
+ <source>Backup Failed</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="827"/>
+ <source>There was an error trying to save the wallet data to the new location.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../bitcoin.cpp" line="127"/>
+ <source>A fatal error occured. Bitcoin can no longer continue safely and will quit.</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
+ <name>DisplayOptionsPage</name>
+ <message>
+ <location filename="../optionsdialog.cpp" line="273"/>
+ <source>&amp;Unit to show amounts in: </source>
+ <translation>&amp;Показване на сумите в:</translation>
+ </message>
+ <message>
+ <location filename="../optionsdialog.cpp" line="277"/>
+ <source>Choose the default subdivision unit to show in the interface, and when sending coins</source>
+ <translation>Изберете мерна единица</translation>
+ </message>
+ <message>
+ <location filename="../optionsdialog.cpp" line="284"/>
+ <source>&amp;Display addresses in transaction list</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../optionsdialog.cpp" line="285"/>
+ <source>Whether to show Bitcoin addresses in the transaction list</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
+ <name>EditAddressDialog</name>
+ <message>
+ <location filename="../forms/editaddressdialog.ui" line="14"/>
+ <source>Edit Address</source>
+ <translation>Редактиране на адрес</translation>
+ </message>
+ <message>
+ <location filename="../forms/editaddressdialog.ui" line="25"/>
+ <source>&amp;Label</source>
+ <translation>&amp;Име</translation>
+ </message>
+ <message>
+ <location filename="../forms/editaddressdialog.ui" line="35"/>
+ <source>The label associated with this address book entry</source>
+ <translation>Името свързано с този запис в списъка с адреси</translation>
+ </message>
+ <message>
+ <location filename="../forms/editaddressdialog.ui" line="42"/>
+ <source>&amp;Address</source>
+ <translation>&amp;Адрес</translation>
+ </message>
+ <message>
+ <location filename="../forms/editaddressdialog.ui" line="52"/>
+ <source>The address associated with this address book entry. This can only be modified for sending addresses.</source>
+ <translation>Адресът свързан с този запис в списъка с адреси. Може да се променя само за изходящи адреси.</translation>
+ </message>
+ <message>
+ <location filename="../editaddressdialog.cpp" line="20"/>
+ <source>New receiving address</source>
+ <translation>Нов адрес за получаване</translation>
+ </message>
+ <message>
+ <location filename="../editaddressdialog.cpp" line="24"/>
+ <source>New sending address</source>
+ <translation>Нов адрес за изпращане</translation>
+ </message>
+ <message>
+ <location filename="../editaddressdialog.cpp" line="27"/>
+ <source>Edit receiving address</source>
+ <translation>Редактиране на входящ адрес</translation>
+ </message>
+ <message>
+ <location filename="../editaddressdialog.cpp" line="31"/>
+ <source>Edit sending address</source>
+ <translation>Редактиране на изходящ адрес</translation>
+ </message>
+ <message>
+ <location filename="../editaddressdialog.cpp" line="91"/>
+ <source>The entered address &quot;%1&quot; is already in the address book.</source>
+ <translation>Вече има адрес &quot;%1&quot; в списъка с адреси.</translation>
+ </message>
+ <message>
+ <location filename="../editaddressdialog.cpp" line="96"/>
+ <source>The entered address &quot;%1&quot; is not a valid bitcoin address.</source>
+ <translation>&quot;%1&quot; не е валиден биткоин адрес.</translation>
+ </message>
+ <message>
+ <location filename="../editaddressdialog.cpp" line="101"/>
+ <source>Could not unlock wallet.</source>
+ <translation>Отключването на портфейла беше неуспешно.</translation>
+ </message>
+ <message>
+ <location filename="../editaddressdialog.cpp" line="106"/>
+ <source>New key generation failed.</source>
+ <translation>Генерирането на ключ беше неуспешно.</translation>
+ </message>
+</context>
+<context>
+ <name>MainOptionsPage</name>
+ <message>
+ <location filename="../optionsdialog.cpp" line="171"/>
+ <source>&amp;Start Bitcoin on window system startup</source>
+ <translation>&amp;Автоматично стартиране на Биткоин</translation>
+ </message>
+ <message>
+ <location filename="../optionsdialog.cpp" line="172"/>
+ <source>Automatically start Bitcoin after the computer is turned on</source>
+ <translation>Биткоин портфейлът ще е наличен веднага след пускане на системата</translation>
+ </message>
+ <message>
+ <location filename="../optionsdialog.cpp" line="176"/>
+ <source>&amp;Minimize to the tray instead of the taskbar</source>
+ <translation>&amp;Минимизиране в системния трей</translation>
+ </message>
+ <message>
+ <location filename="../optionsdialog.cpp" line="177"/>
+ <source>Show only a tray icon after minimizing the window</source>
+ <translation>Остава видима само иконата долу вдясно</translation>
+ </message>
+ <message>
+ <location filename="../optionsdialog.cpp" line="185"/>
+ <source>Map port using &amp;UPnP</source>
+ <translation>Отваряне на входящия порт чрез &amp;UPnP</translation>
+ </message>
+ <message>
+ <location filename="../optionsdialog.cpp" line="186"/>
+ <source>Automatically open the Bitcoin client port on the router. This only works when your router supports UPnP and it is enabled.</source>
+ <translation>Автоматично отваряне на входящия Bitcoin порт. Работи само с рутери поддържащи UPnP.</translation>
+ </message>
+ <message>
+ <location filename="../optionsdialog.cpp" line="180"/>
+ <source>M&amp;inimize on close</source>
+ <translation>М&amp;инимизирай вместо затваряне</translation>
+ </message>
+ <message>
+ <location filename="../optionsdialog.cpp" line="181"/>
+ <source>Minimize instead of exit the application when the window is closed. When this option is enabled, the application will be closed only after selecting Quit in the menu.</source>
+ <translation>При затваряне на прозореца приложението остава минимизирано. Ако изберете тази опция, приложението може да се затвори само чрез Изход в менюто.</translation>
+ </message>
+ <message>
+ <location filename="../optionsdialog.cpp" line="189"/>
+ <source>&amp;Connect through SOCKS4 proxy:</source>
+ <translation>&amp;Използвай SOCKS4 прокси:</translation>
+ </message>
+ <message>
+ <location filename="../optionsdialog.cpp" line="190"/>
+ <source>Connect to the Bitcon network through a SOCKS4 proxy (e.g. when connecting through Tor)</source>
+ <translation>Свързване с Биткоин мрежата чрез SOCKS4 прокси сървър (например за да анонимизирате достъпа си чрез Тор)</translation>
+ </message>
+ <message>
+ <location filename="../optionsdialog.cpp" line="195"/>
+ <source>Proxy &amp;IP: </source>
+ <translation>Прокси &amp;IP: </translation>
+ </message>
+ <message>
+ <location filename="../optionsdialog.cpp" line="201"/>
+ <source>IP address of the proxy (e.g. 127.0.0.1)</source>
+ <translation>IP адрес на прокси сървъра (например 127.0.0.1)</translation>
+ </message>
+ <message>
+ <location filename="../optionsdialog.cpp" line="204"/>
+ <source>&amp;Port: </source>
+ <translation>&amp;Порт: </translation>
+ </message>
+ <message>
+ <location filename="../optionsdialog.cpp" line="210"/>
+ <source>Port of the proxy (e.g. 1234)</source>
+ <translation>Порт на прокси сървъра (например 1234)</translation>
+ </message>
+ <message>
+ <location filename="../optionsdialog.cpp" line="232"/>
+ <source>Detach databases at shutdown</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../optionsdialog.cpp" line="233"/>
+ <source>Detach block and address databases at shutdown. This means they can be moved to another data directory, but it slows down shutdown. The wallet is always detached.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../optionsdialog.cpp" line="222"/>
+ <source>Pay transaction &amp;fee</source>
+ <translation>&amp;Такса за изходящо плащане</translation>
+ </message>
+ <message>
+ <location filename="../optionsdialog.cpp" line="216"/>
+ <source>Optional transaction fee per kB that helps make sure your transactions are processed quickly. Most transactions are 1 kB. Fee 0.01 recommended.</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
+ <name>MessagePage</name>
+ <message>
+ <location filename="../forms/messagepage.ui" line="14"/>
+ <source>Message</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../forms/messagepage.ui" line="20"/>
+ <source>You can sign messages with your addresses to prove you own them. Be careful not to sign anything vague, as phishing attacks may try to trick you into signing your identity over to them. Only sign fully-detailed statements you agree to.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../forms/messagepage.ui" line="38"/>
+ <source>The address to sign the message with (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L)</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../forms/messagepage.ui" line="48"/>
+ <source>Choose adress from address book</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../forms/messagepage.ui" line="58"/>
+ <source>Alt+A</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../forms/messagepage.ui" line="71"/>
+ <source>Paste address from clipboard</source>
+ <translation>Вмъкни от клипборда</translation>
+ </message>
+ <message>
+ <location filename="../forms/messagepage.ui" line="81"/>
+ <source>Alt+P</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../forms/messagepage.ui" line="93"/>
+ <source>Enter the message you want to sign here</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../forms/messagepage.ui" line="128"/>
+ <source>Copy the current signature to the system clipboard</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../forms/messagepage.ui" line="131"/>
+ <source>&amp;Copy Signature</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../forms/messagepage.ui" line="142"/>
+ <source>Reset all sign message fields</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../forms/messagepage.ui" line="145"/>
+ <source>Clear &amp;All</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../messagepage.cpp" line="30"/>
+ <source>Click &quot;Sign Message&quot; to get signature</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../forms/messagepage.ui" line="114"/>
+ <source>Sign a message to prove you own this address</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../forms/messagepage.ui" line="117"/>
+ <source>&amp;Sign Message</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../messagepage.cpp" line="79"/>
+ <location filename="../messagepage.cpp" line="94"/>
+ <location filename="../messagepage.cpp" line="106"/>
+ <source>Error signing</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../messagepage.cpp" line="79"/>
+ <source>%1 is not a valid address.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../messagepage.cpp" line="94"/>
+ <source>Private key for %1 is not available.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../messagepage.cpp" line="106"/>
+ <source>Sign failed</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
+ <name>OptionsDialog</name>
+ <message>
+ <location filename="../optionsdialog.cpp" line="80"/>
+ <source>Main</source>
+ <translation>Общи</translation>
+ </message>
+ <message>
+ <location filename="../optionsdialog.cpp" line="85"/>
+ <source>Display</source>
+ <translation>Показване</translation>
+ </message>
+ <message>
+ <location filename="../optionsdialog.cpp" line="105"/>
+ <source>Options</source>
+ <translation>Опции</translation>
+ </message>
+</context>
+<context>
+ <name>OverviewPage</name>
+ <message>
+ <location filename="../forms/overviewpage.ui" line="14"/>
+ <source>Form</source>
+ <translation>Форма</translation>
+ </message>
+ <message>
+ <location filename="../forms/overviewpage.ui" line="40"/>
+ <source>Balance:</source>
+ <translation>Баланс:</translation>
+ </message>
+ <message>
+ <location filename="../forms/overviewpage.ui" line="47"/>
+ <source>123.456 BTC</source>
+ <translation>123.456 BTC</translation>
+ </message>
+ <message>
+ <location filename="../forms/overviewpage.ui" line="54"/>
+ <source>Number of transactions:</source>
+ <translation>Брой плащания:</translation>
+ </message>
+ <message>
+ <location filename="../forms/overviewpage.ui" line="61"/>
+ <source>0</source>
+ <translation>0</translation>
+ </message>
+ <message>
+ <location filename="../forms/overviewpage.ui" line="68"/>
+ <source>Unconfirmed:</source>
+ <translation>Непотвърдени:</translation>
+ </message>
+ <message>
+ <location filename="../forms/overviewpage.ui" line="75"/>
+ <source>0 BTC</source>
+ <translation>0 BTC</translation>
+ </message>
+ <message>
+ <location filename="../forms/overviewpage.ui" line="88"/>
+ <source>Wallet</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../forms/overviewpage.ui" line="124"/>
+ <source>&lt;b&gt;Recent transactions&lt;/b&gt;</source>
+ <translation>&lt;b&gt;Последни плащания&lt;/b&gt;</translation>
+ </message>
+ <message>
+ <location filename="../overviewpage.cpp" line="103"/>
+ <source>Your current balance</source>
+ <translation>Вашият текущ баланс</translation>
+ </message>
+ <message>
+ <location filename="../overviewpage.cpp" line="108"/>
+ <source>Total of transactions that have yet to be confirmed, and do not yet count toward the current balance</source>
+ <translation>Сборът на все още непотвърдените плащания, които не са част от текущия баланс</translation>
+ </message>
+ <message>
+ <location filename="../overviewpage.cpp" line="111"/>
+ <source>Total number of transactions in wallet</source>
+ <translation>Общ брой плащания в портфейла</translation>
+ </message>
+</context>
+<context>
+ <name>QRCodeDialog</name>
+ <message>
+ <location filename="../forms/qrcodedialog.ui" line="14"/>
+ <source>QR-Code Dialog</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../forms/qrcodedialog.ui" line="32"/>
+ <source>QR Code</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../forms/qrcodedialog.ui" line="55"/>
+ <source>Request Payment</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../forms/qrcodedialog.ui" line="70"/>
+ <source>Amount:</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../forms/qrcodedialog.ui" line="105"/>
+ <source>BTC</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../forms/qrcodedialog.ui" line="121"/>
+ <source>Label:</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../forms/qrcodedialog.ui" line="144"/>
+ <source>Message:</source>
+ <translation>Съобщение:</translation>
+ </message>
+ <message>
+ <location filename="../forms/qrcodedialog.ui" line="186"/>
+ <source>&amp;Save As...</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../qrcodedialog.cpp" line="46"/>
+ <source>Error encoding URI into QR Code.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../qrcodedialog.cpp" line="64"/>
+ <source>Resulting URI too long, try to reduce the text for label / message.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../qrcodedialog.cpp" line="121"/>
+ <source>Save QR Code</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../qrcodedialog.cpp" line="121"/>
+ <source>PNG Images (*.png)</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
+ <name>RPCConsole</name>
+ <message>
+ <location filename="../forms/rpcconsole.ui" line="14"/>
+ <source>Bitcoin debug window</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../forms/rpcconsole.ui" line="24"/>
+ <source>Information</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../forms/rpcconsole.ui" line="33"/>
+ <source>Client name</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../forms/rpcconsole.ui" line="40"/>
+ <location filename="../forms/rpcconsole.ui" line="60"/>
+ <location filename="../forms/rpcconsole.ui" line="106"/>
+ <location filename="../forms/rpcconsole.ui" line="156"/>
+ <location filename="../forms/rpcconsole.ui" line="176"/>
+ <location filename="../forms/rpcconsole.ui" line="196"/>
+ <location filename="../forms/rpcconsole.ui" line="229"/>
+ <source>N/A</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../forms/rpcconsole.ui" line="53"/>
+ <source>Client version</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../forms/rpcconsole.ui" line="79"/>
+ <source>Version</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../forms/rpcconsole.ui" line="92"/>
+ <source>Network</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../forms/rpcconsole.ui" line="99"/>
+ <source>Number of connections</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../forms/rpcconsole.ui" line="119"/>
+ <source>On testnet</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../forms/rpcconsole.ui" line="142"/>
+ <source>Block chain</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../forms/rpcconsole.ui" line="149"/>
+ <source>Current number of blocks</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../forms/rpcconsole.ui" line="169"/>
+ <source>Estimated total blocks</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../forms/rpcconsole.ui" line="189"/>
+ <source>Last block time</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../forms/rpcconsole.ui" line="222"/>
+ <source>Build date</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../forms/rpcconsole.ui" line="237"/>
+ <source>Console</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../forms/rpcconsole.ui" line="278"/>
+ <source>&gt;</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../forms/rpcconsole.ui" line="294"/>
+ <source>Clear console</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../rpcconsole.cpp" line="97"/>
+ <source>&amp;Copy</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../rpcconsole.cpp" line="195"/>
+ <source>Welcome to the bitcoin RPC console.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../rpcconsole.cpp" line="196"/>
+ <source>Use up and down arrows to navigate history, and Ctrl-L to clear screen.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../rpcconsole.cpp" line="197"/>
+ <source>Type &quot;help&quot; for an overview of available commands.</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
+ <name>SendCoinsDialog</name>
+ <message>
+ <location filename="../forms/sendcoinsdialog.ui" line="14"/>
+ <location filename="../sendcoinsdialog.cpp" line="122"/>
+ <location filename="../sendcoinsdialog.cpp" line="127"/>
+ <location filename="../sendcoinsdialog.cpp" line="132"/>
+ <location filename="../sendcoinsdialog.cpp" line="137"/>
+ <location filename="../sendcoinsdialog.cpp" line="143"/>
+ <location filename="../sendcoinsdialog.cpp" line="148"/>
+ <location filename="../sendcoinsdialog.cpp" line="153"/>
+ <source>Send Coins</source>
+ <translation>Изпращане</translation>
+ </message>
+ <message>
+ <location filename="../forms/sendcoinsdialog.ui" line="64"/>
+ <source>Send to multiple recipients at once</source>
+ <translation>Изпращане към повече от един получател</translation>
+ </message>
+ <message>
+ <location filename="../forms/sendcoinsdialog.ui" line="67"/>
+ <source>&amp;Add Recipient</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../forms/sendcoinsdialog.ui" line="84"/>
+ <source>Remove all transaction fields</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../forms/sendcoinsdialog.ui" line="87"/>
+ <source>Clear all</source>
+ <translation>Изчисти всички</translation>
+ </message>
+ <message>
+ <location filename="../forms/sendcoinsdialog.ui" line="106"/>
+ <source>Balance:</source>
+ <translation>Баланс:</translation>
+ </message>
+ <message>
+ <location filename="../forms/sendcoinsdialog.ui" line="113"/>
+ <source>123.456 BTC</source>
+ <translation>123.456 BTC</translation>
+ </message>
+ <message>
+ <location filename="../forms/sendcoinsdialog.ui" line="144"/>
+ <source>Confirm the send action</source>
+ <translation>Потвърдете изпращането</translation>
+ </message>
+ <message>
+ <location filename="../forms/sendcoinsdialog.ui" line="147"/>
+ <source>&amp;Send</source>
+ <translation>&amp;Изпращане</translation>
+ </message>
+ <message>
+ <location filename="../sendcoinsdialog.cpp" line="94"/>
+ <source>&lt;b&gt;%1&lt;/b&gt; to %2 (%3)</source>
+ <translation>&lt;b&gt;%1&lt;/b&gt; на %2 (%3)</translation>
+ </message>
+ <message>
+ <location filename="../sendcoinsdialog.cpp" line="99"/>
+ <source>Confirm send coins</source>
+ <translation>Потвърждаване</translation>
+ </message>
+ <message>
+ <location filename="../sendcoinsdialog.cpp" line="100"/>
+ <source>Are you sure you want to send %1?</source>
+ <translation>Сигурни ли сте, че искате да изпратите %1?</translation>
+ </message>
+ <message>
+ <location filename="../sendcoinsdialog.cpp" line="100"/>
+ <source> and </source>
+ <translation> и </translation>
+ </message>
+ <message>
+ <location filename="../sendcoinsdialog.cpp" line="123"/>
+ <source>The recepient address is not valid, please recheck.</source>
+ <translation>Адресът на получателя не е валиден, моля проверете пак.</translation>
+ </message>
+ <message>
+ <location filename="../sendcoinsdialog.cpp" line="128"/>
+ <source>The amount to pay must be larger than 0.</source>
+ <translation>Сумата трябва да е по-голяма от 0.</translation>
+ </message>
+ <message>
+ <location filename="../sendcoinsdialog.cpp" line="133"/>
+ <source>Amount exceeds your balance</source>
+ <translation>Сумата надвишава текущият баланс</translation>
+ </message>
+ <message>
+ <location filename="../sendcoinsdialog.cpp" line="138"/>
+ <source>Total exceeds your balance when the %1 transaction fee is included</source>
+ <translation>Сумата надвишава текущият баланс след добавянето на такса от %1</translation>
+ </message>
+ <message>
+ <location filename="../sendcoinsdialog.cpp" line="144"/>
+ <source>Duplicate address found, can only send to each address once in one send operation</source>
+ <translation>Открит е повторен адрес. Адрес може да се използва само веднъж при изпращане.</translation>
+ </message>
+ <message>
+ <location filename="../sendcoinsdialog.cpp" line="149"/>
+ <source>Error: Transaction creation failed </source>
+ <translation>Грешка: създаването на плащане беше неуспешно </translation>
+ </message>
+ <message>
+ <location filename="../sendcoinsdialog.cpp" line="154"/>
+ <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>Грешка: плащането беше отхвърлено. Това е възможно ако част от парите в портфейла са вече похарчени, например при паралелно използване на копие на wallet.dat</translation>
+ </message>
+</context>
+<context>
+ <name>SendCoinsEntry</name>
+ <message>
+ <location filename="../forms/sendcoinsentry.ui" line="14"/>
+ <source>Form</source>
+ <translation>Форма</translation>
+ </message>
+ <message>
+ <location filename="../forms/sendcoinsentry.ui" line="29"/>
+ <source>A&amp;mount:</source>
+ <translation>С&amp;ума:</translation>
+ </message>
+ <message>
+ <location filename="../forms/sendcoinsentry.ui" line="42"/>
+ <source>Pay &amp;To:</source>
+ <translation>Плати &amp;На:</translation>
+ </message>
+ <message>
+ <location filename="../forms/sendcoinsentry.ui" line="66"/>
+ <location filename="../sendcoinsentry.cpp" line="25"/>
+ <source>Enter a label for this address to add it to your address book</source>
+ <translation>Въведете име за този адрес, за да го добавите в списъка с адреси</translation>
+ </message>
+ <message>
+ <location filename="../forms/sendcoinsentry.ui" line="75"/>
+ <source>&amp;Label:</source>
+ <translation>&amp;Име:</translation>
+ </message>
+ <message>
+ <location filename="../forms/sendcoinsentry.ui" line="93"/>
+ <source>The address to send the payment to (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L)</source>
+ <translation>Адресът, към който да се направи плащането (например 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L)</translation>
+ </message>
+ <message>
+ <location filename="../forms/sendcoinsentry.ui" line="103"/>
+ <source>Choose address from address book</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../forms/sendcoinsentry.ui" line="113"/>
+ <source>Alt+A</source>
+ <translation>Alt+A</translation>
+ </message>
+ <message>
+ <location filename="../forms/sendcoinsentry.ui" line="120"/>
+ <source>Paste address from clipboard</source>
+ <translation>Вмъкни от клипборда</translation>
+ </message>
+ <message>
+ <location filename="../forms/sendcoinsentry.ui" line="130"/>
+ <source>Alt+P</source>
+ <translation>Alt+P</translation>
+ </message>
+ <message>
+ <location filename="../forms/sendcoinsentry.ui" line="137"/>
+ <source>Remove this recipient</source>
+ <translation>Махни този получател</translation>
+ </message>
+ <message>
+ <location filename="../sendcoinsentry.cpp" line="26"/>
+ <source>Enter a Bitcoin address (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L)</source>
+ <translation>Въведете Биткоин адрес (например 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L)</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionDesc</name>
+ <message>
+ <location filename="../transactiondesc.cpp" line="20"/>
+ <source>Open for %1 blocks</source>
+ <translation>Подлежи на промяна за %1 блока</translation>
+ </message>
+ <message>
+ <location filename="../transactiondesc.cpp" line="22"/>
+ <source>Open until %1</source>
+ <translation>Подлежи на промяна до %1</translation>
+ </message>
+ <message>
+ <location filename="../transactiondesc.cpp" line="28"/>
+ <source>%1/offline?</source>
+ <translation>%1/офлайн?</translation>
+ </message>
+ <message>
+ <location filename="../transactiondesc.cpp" line="30"/>
+ <source>%1/unconfirmed</source>
+ <translation>%1/непотвърдено</translation>
+ </message>
+ <message>
+ <location filename="../transactiondesc.cpp" line="32"/>
+ <source>%1 confirmations</source>
+ <translation>включено в %1 блока</translation>
+ </message>
+ <message>
+ <location filename="../transactiondesc.cpp" line="50"/>
+ <source>&lt;b&gt;Status:&lt;/b&gt; </source>
+ <translation>&lt;b&gt;Състояние:&lt;/b&gt; </translation>
+ </message>
+ <message>
+ <location filename="../transactiondesc.cpp" line="55"/>
+ <source>, has not been successfully broadcast yet</source>
+ <translation>, все още не е изпратено</translation>
+ </message>
+ <message>
+ <location filename="../transactiondesc.cpp" line="57"/>
+ <source>, broadcast through %1 node</source>
+ <translation>, изпратено през %1 участник в мрежата</translation>
+ </message>
+ <message>
+ <location filename="../transactiondesc.cpp" line="59"/>
+ <source>, broadcast through %1 nodes</source>
+ <translation>, изпратено през %1 участници в мрежата</translation>
+ </message>
+ <message>
+ <location filename="../transactiondesc.cpp" line="63"/>
+ <source>&lt;b&gt;Date:&lt;/b&gt; </source>
+ <translation>&lt;b&gt;Дата:&lt;/b&gt; </translation>
+ </message>
+ <message>
+ <location filename="../transactiondesc.cpp" line="70"/>
+ <source>&lt;b&gt;Source:&lt;/b&gt; Generated&lt;br&gt;</source>
+ <translation>&lt;b&gt;Източник:&lt;/b&gt; Генерирани&lt;br&gt;</translation>
+ </message>
+ <message>
+ <location filename="../transactiondesc.cpp" line="76"/>
+ <location filename="../transactiondesc.cpp" line="93"/>
+ <source>&lt;b&gt;From:&lt;/b&gt; </source>
+ <translation>&lt;b&gt;От:&lt;/b&gt; </translation>
+ </message>
+ <message>
+ <location filename="../transactiondesc.cpp" line="93"/>
+ <source>unknown</source>
+ <translation>неизвестен</translation>
+ </message>
+ <message>
+ <location filename="../transactiondesc.cpp" line="94"/>
+ <location filename="../transactiondesc.cpp" line="117"/>
+ <location filename="../transactiondesc.cpp" line="176"/>
+ <source>&lt;b&gt;To:&lt;/b&gt; </source>
+ <translation>&lt;b&gt;Към:&lt;/b&gt; </translation>
+ </message>
+ <message>
+ <location filename="../transactiondesc.cpp" line="97"/>
+ <source> (yours, label: </source>
+ <translation> (собствен, име: </translation>
+ </message>
+ <message>
+ <location filename="../transactiondesc.cpp" line="99"/>
+ <source> (yours)</source>
+ <translation> (собствен)</translation>
+ </message>
+ <message>
+ <location filename="../transactiondesc.cpp" line="134"/>
+ <location filename="../transactiondesc.cpp" line="148"/>
+ <location filename="../transactiondesc.cpp" line="193"/>
+ <location filename="../transactiondesc.cpp" line="210"/>
+ <source>&lt;b&gt;Credit:&lt;/b&gt; </source>
+ <translation>&lt;b&gt;Кредит:&lt;/b&gt; </translation>
+ </message>
+ <message>
+ <location filename="../transactiondesc.cpp" line="136"/>
+ <source>(%1 matures in %2 more blocks)</source>
+ <translation>(%1 достъпни след %2 блока)</translation>
+ </message>
+ <message>
+ <location filename="../transactiondesc.cpp" line="140"/>
+ <source>(not accepted)</source>
+ <translation>(отхвърлен от мрежата)</translation>
+ </message>
+ <message>
+ <location filename="../transactiondesc.cpp" line="184"/>
+ <location filename="../transactiondesc.cpp" line="192"/>
+ <location filename="../transactiondesc.cpp" line="207"/>
+ <source>&lt;b&gt;Debit:&lt;/b&gt; </source>
+ <translation>&lt;b&gt;Дебит:&lt;/b&gt; </translation>
+ </message>
+ <message>
+ <location filename="../transactiondesc.cpp" line="198"/>
+ <source>&lt;b&gt;Transaction fee:&lt;/b&gt; </source>
+ <translation>&lt;b&gt;Такса:&lt;/b&gt; </translation>
+ </message>
+ <message>
+ <location filename="../transactiondesc.cpp" line="214"/>
+ <source>&lt;b&gt;Net amount:&lt;/b&gt; </source>
+ <translation>&lt;b&gt;Сума нето:&lt;/b&gt; </translation>
+ </message>
+ <message>
+ <location filename="../transactiondesc.cpp" line="220"/>
+ <source>Message:</source>
+ <translation>Съобщение:</translation>
+ </message>
+ <message>
+ <location filename="../transactiondesc.cpp" line="222"/>
+ <source>Comment:</source>
+ <translation>Коментар:</translation>
+ </message>
+ <message>
+ <location filename="../transactiondesc.cpp" line="224"/>
+ <source>Transaction ID:</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../transactiondesc.cpp" line="227"/>
+ <source>Generated coins must wait 120 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, it will change to &quot;not accepted&quot; and not be spendable. This may occasionally happen if another node generates a block within a few seconds of yours.</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
+ <name>TransactionDescDialog</name>
+ <message>
+ <location filename="../forms/transactiondescdialog.ui" line="14"/>
+ <source>Transaction details</source>
+ <translation>Подробности за плащане</translation>
+ </message>
+ <message>
+ <location filename="../forms/transactiondescdialog.ui" line="20"/>
+ <source>This pane shows a detailed description of the transaction</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
+ <name>TransactionTableModel</name>
+ <message>
+ <location filename="../transactiontablemodel.cpp" line="214"/>
+ <source>Date</source>
+ <translation>Дата</translation>
+ </message>
+ <message>
+ <location filename="../transactiontablemodel.cpp" line="214"/>
+ <source>Type</source>
+ <translation>Тип</translation>
+ </message>
+ <message>
+ <location filename="../transactiontablemodel.cpp" line="214"/>
+ <source>Address</source>
+ <translation>Адрес</translation>
+ </message>
+ <message>
+ <location filename="../transactiontablemodel.cpp" line="214"/>
+ <source>Amount</source>
+ <translation>Сума</translation>
+ </message>
+ <message numerus="yes">
+ <location filename="../transactiontablemodel.cpp" line="275"/>
+ <source>Open for %n block(s)</source>
+ <translation type="unfinished"><numerusform></numerusform><numerusform></numerusform></translation>
+ </message>
+ <message>
+ <location filename="../transactiontablemodel.cpp" line="278"/>
+ <source>Open until %1</source>
+ <translation>Подлежи на промяна до %1</translation>
+ </message>
+ <message>
+ <location filename="../transactiontablemodel.cpp" line="281"/>
+ <source>Offline (%1 confirmations)</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../transactiontablemodel.cpp" line="284"/>
+ <source>Unconfirmed (%1 of %2 confirmations)</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../transactiontablemodel.cpp" line="287"/>
+ <source>Confirmed (%1 confirmations)</source>
+ <translation type="unfinished"/>
+ </message>
+ <message numerus="yes">
+ <location filename="../transactiontablemodel.cpp" line="295"/>
+ <source>Mined balance will be available in %n more blocks</source>
+ <translation type="unfinished"><numerusform></numerusform><numerusform></numerusform></translation>
+ </message>
+ <message>
+ <location filename="../transactiontablemodel.cpp" line="301"/>
+ <source>This block was not received by any other nodes and will probably not be accepted!</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../transactiontablemodel.cpp" line="304"/>
+ <source>Generated but not accepted</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../transactiontablemodel.cpp" line="347"/>
+ <source>Received with</source>
+ <translation>Получаване</translation>
+ </message>
+ <message>
+ <location filename="../transactiontablemodel.cpp" line="349"/>
+ <source>Received from</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../transactiontablemodel.cpp" line="352"/>
+ <source>Sent to</source>
+ <translation>Изпращане</translation>
+ </message>
+ <message>
+ <location filename="../transactiontablemodel.cpp" line="354"/>
+ <source>Payment to yourself</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../transactiontablemodel.cpp" line="356"/>
+ <source>Mined</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../transactiontablemodel.cpp" line="394"/>
+ <source>(n/a)</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../transactiontablemodel.cpp" line="593"/>
+ <source>Transaction status. Hover over this field to show number of confirmations.</source>
+ <translation>Състояние на плащането. Задръжте върху това поле за брой потвърждения.</translation>
+ </message>
+ <message>
+ <location filename="../transactiontablemodel.cpp" line="595"/>
+ <source>Date and time that the transaction was received.</source>
+ <translation>Дата и час на получаване.</translation>
+ </message>
+ <message>
+ <location filename="../transactiontablemodel.cpp" line="597"/>
+ <source>Type of transaction.</source>
+ <translation>Тип плащане.</translation>
+ </message>
+ <message>
+ <location filename="../transactiontablemodel.cpp" line="599"/>
+ <source>Destination address of transaction.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../transactiontablemodel.cpp" line="601"/>
+ <source>Amount removed from or added to balance.</source>
+ <translation>Сума извадена или добавена към баланса.</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionView</name>
+ <message>
+ <location filename="../transactionview.cpp" line="55"/>
+ <location filename="../transactionview.cpp" line="71"/>
+ <source>All</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../transactionview.cpp" line="56"/>
+ <source>Today</source>
+ <translation>Днес</translation>
+ </message>
+ <message>
+ <location filename="../transactionview.cpp" line="57"/>
+ <source>This week</source>
+ <translation>Тази седмица</translation>
+ </message>
+ <message>
+ <location filename="../transactionview.cpp" line="58"/>
+ <source>This month</source>
+ <translation>Този месец</translation>
+ </message>
+ <message>
+ <location filename="../transactionview.cpp" line="59"/>
+ <source>Last month</source>
+ <translation>Предния месец</translation>
+ </message>
+ <message>
+ <location filename="../transactionview.cpp" line="60"/>
+ <source>This year</source>
+ <translation>Тази година</translation>
+ </message>
+ <message>
+ <location filename="../transactionview.cpp" line="61"/>
+ <source>Range...</source>
+ <translation>Интервал...</translation>
+ </message>
+ <message>
+ <location filename="../transactionview.cpp" line="72"/>
+ <source>Received with</source>
+ <translation>Получаване</translation>
+ </message>
+ <message>
+ <location filename="../transactionview.cpp" line="74"/>
+ <source>Sent to</source>
+ <translation>Изпращане</translation>
+ </message>
+ <message>
+ <location filename="../transactionview.cpp" line="76"/>
+ <source>To yourself</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../transactionview.cpp" line="77"/>
+ <source>Mined</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../transactionview.cpp" line="78"/>
+ <source>Other</source>
+ <translation>Други</translation>
+ </message>
+ <message>
+ <location filename="../transactionview.cpp" line="84"/>
+ <source>Enter address or label to search</source>
+ <translation>Търсене по адрес или име</translation>
+ </message>
+ <message>
+ <location filename="../transactionview.cpp" line="90"/>
+ <source>Min amount</source>
+ <translation>Минимална сума</translation>
+ </message>
+ <message>
+ <location filename="../transactionview.cpp" line="124"/>
+ <source>Copy address</source>
+ <translation>Копирай адрес</translation>
+ </message>
+ <message>
+ <location filename="../transactionview.cpp" line="125"/>
+ <source>Copy label</source>
+ <translation>Копирай име</translation>
+ </message>
+ <message>
+ <location filename="../transactionview.cpp" line="126"/>
+ <source>Copy amount</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../transactionview.cpp" line="127"/>
+ <source>Edit label</source>
+ <translation>Редактирай име</translation>
+ </message>
+ <message>
+ <location filename="../transactionview.cpp" line="128"/>
+ <source>Show transaction details</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../transactionview.cpp" line="268"/>
+ <source>Export Transaction Data</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../transactionview.cpp" line="269"/>
+ <source>Comma separated file (*.csv)</source>
+ <translation>CSV файл (*.csv)</translation>
+ </message>
+ <message>
+ <location filename="../transactionview.cpp" line="277"/>
+ <source>Confirmed</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../transactionview.cpp" line="278"/>
+ <source>Date</source>
+ <translation>Дата</translation>
+ </message>
+ <message>
+ <location filename="../transactionview.cpp" line="279"/>
+ <source>Type</source>
+ <translation>Тип</translation>
+ </message>
+ <message>
+ <location filename="../transactionview.cpp" line="280"/>
+ <source>Label</source>
+ <translation>Име</translation>
+ </message>
+ <message>
+ <location filename="../transactionview.cpp" line="281"/>
+ <source>Address</source>
+ <translation>Адрес</translation>
+ </message>
+ <message>
+ <location filename="../transactionview.cpp" line="282"/>
+ <source>Amount</source>
+ <translation>Сума</translation>
+ </message>
+ <message>
+ <location filename="../transactionview.cpp" line="283"/>
+ <source>ID</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../transactionview.cpp" line="287"/>
+ <source>Error exporting</source>
+ <translation>Грешка при записа</translation>
+ </message>
+ <message>
+ <location filename="../transactionview.cpp" line="287"/>
+ <source>Could not write to file %1.</source>
+ <translation>Неуспешен запис в %1.</translation>
+ </message>
+ <message>
+ <location filename="../transactionview.cpp" line="382"/>
+ <source>Range:</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../transactionview.cpp" line="390"/>
+ <source>to</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
+ <name>WalletModel</name>
+ <message>
+ <location filename="../walletmodel.cpp" line="142"/>
+ <source>Sending...</source>
+ <translation>Изпращане...</translation>
+ </message>
+</context>
+<context>
+ <name>bitcoin-core</name>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="12"/>
+ <source>Bitcoin version</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="13"/>
+ <source>Usage:</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="14"/>
+ <source>Send command to -server or bitcoind</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="15"/>
+ <source>List commands</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="16"/>
+ <source>Get help for a command</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="17"/>
+ <source>Options:</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="18"/>
+ <source>Specify configuration file (default: bitcoin.conf)</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="19"/>
+ <source>Specify pid file (default: bitcoind.pid)</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="20"/>
+ <source>Generate coins</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="21"/>
+ <source>Don&apos;t generate coins</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="22"/>
+ <source>Start minimized</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="23"/>
+ <source>Show splash screen on startup (default: 1)</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="24"/>
+ <source>Specify data directory</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="25"/>
+ <source>Set database cache size in megabytes (default: 25)</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="26"/>
+ <source>Set database disk log size in megabytes (default: 100)</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="27"/>
+ <source>Specify connection timeout (in milliseconds)</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="28"/>
+ <source>Connect through socks4 proxy</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="29"/>
+ <source>Allow DNS lookups for addnode and connect</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="30"/>
+ <source>Listen for connections on &lt;port&gt; (default: 8333 or testnet: 18333)</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="31"/>
+ <source>Maintain at most &lt;n&gt; connections to peers (default: 125)</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="33"/>
+ <source>Connect only to the specified node</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="38"/>
+ <source>Threshold for disconnecting misbehaving peers (default: 100)</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="39"/>
+ <source>Number of seconds to keep misbehaving peers from reconnecting (default: 86400)</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="42"/>
+ <source>Maximum per-connection receive buffer, &lt;n&gt;*1000 bytes (default: 10000)</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="43"/>
+ <source>Maximum per-connection send buffer, &lt;n&gt;*1000 bytes (default: 10000)</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="47"/>
+ <source>Accept command line and JSON-RPC commands</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="48"/>
+ <source>Run in the background as a daemon and accept commands</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="49"/>
+ <source>Use the test network</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="50"/>
+ <source>Output extra debugging information</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="51"/>
+ <source>Prepend debug output with timestamp</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="52"/>
+ <source>Send trace/debug info to console instead of debug.log file</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="53"/>
+ <source>Send trace/debug info to debugger</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="54"/>
+ <source>Username for JSON-RPC connections</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="55"/>
+ <source>Password for JSON-RPC connections</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="56"/>
+ <source>Listen for JSON-RPC connections on &lt;port&gt; (default: 8332)</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="57"/>
+ <source>Allow JSON-RPC connections from specified IP address</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="58"/>
+ <source>Send commands to node running on &lt;ip&gt; (default: 127.0.0.1)</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="59"/>
+ <source>Execute command when the best block changes (%s in cmd is replaced by block hash)</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="62"/>
+ <source>Upgrade wallet to latest format</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="63"/>
+ <source>Set key pool size to &lt;n&gt; (default: 100)</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="64"/>
+ <source>Rescan the block chain for missing wallet transactions</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="65"/>
+ <source>How many blocks to check at startup (default: 2500, 0 = all)</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="66"/>
+ <source>How thorough the block verification is (0-6, default: 1)</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="67"/>
+ <source>
+SSL options: (see the Bitcoin Wiki for SSL setup instructions)</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="70"/>
+ <source>Use OpenSSL (https) for JSON-RPC connections</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="71"/>
+ <source>Server certificate file (default: server.cert)</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="72"/>
+ <source>Server private key (default: server.pem)</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="73"/>
+ <source>Acceptable ciphers (default: TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!AH:!3DES:@STRENGTH)</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="76"/>
+ <source>This help message</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="77"/>
+ <source>Usage</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="78"/>
+ <source>Cannot obtain a lock on data directory %s. Bitcoin is probably already running.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="81"/>
+ <source>Bitcoin</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="82"/>
+ <source>Loading addresses...</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="83"/>
+ <source>Error loading addr.dat</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="85"/>
+ <source>Error loading blkindex.dat</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="87"/>
+ <source>Error loading wallet.dat: Wallet corrupted</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="88"/>
+ <source>Error loading wallet.dat: Wallet requires newer version of Bitcoin</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="89"/>
+ <source>Wallet needed to be rewritten: restart Bitcoin to complete</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="90"/>
+ <source>Error loading wallet.dat</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="122"/>
+ <source>Error: Wallet locked, unable to create transaction </source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="123"/>
+ <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 type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="126"/>
+ <source>Error: Transaction creation failed </source>
+ <translation>Грешка: създаването на плащане беше неуспешно </translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="127"/>
+ <source>Sending...</source>
+ <translation>Изпращане...</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="128"/>
+ <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>Грешка: плащането беше отхвърлено. Това е възможно ако част от парите в портфейла са вече похарчени, например при паралелно използване на копие на wallet.dat</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="132"/>
+ <source>Invalid amount</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="133"/>
+ <source>Insufficient funds</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="84"/>
+ <source>Loading block index...</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="32"/>
+ <source>Add a node to connect to and attempt to keep the connection open</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="34"/>
+ <source>Find peers using internet relay chat (default: 0)</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="35"/>
+ <source>Accept connections from outside (default: 1)</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="36"/>
+ <source>Set language, for example &quot;de_DE&quot; (default: system locale)</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="37"/>
+ <source>Find peers using DNS lookup (default: 1)</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="44"/>
+ <source>Use Universal Plug and Play to map the listening port (default: 1)</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="45"/>
+ <source>Use Universal Plug and Play to map the listening port (default: 0)</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="46"/>
+ <source>Fee per KB to add to transactions you send</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="86"/>
+ <source>Loading wallet...</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="91"/>
+ <source>Cannot downgrade wallet</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="92"/>
+ <source>Cannot initialize keypool</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="93"/>
+ <source>Cannot write default address</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="94"/>
+ <source>Rescanning...</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="95"/>
+ <source>Done loading</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="96"/>
+ <source>Invalid -proxy address</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="97"/>
+ <source>Invalid amount for -paytxfee=&lt;amount&gt;</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="98"/>
+ <source>Warning: -paytxfee is set very high. This is the transaction fee you will pay if you send a transaction.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="101"/>
+ <source>Error: CreateThread(StartNode) failed</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="11"/>
+ <source>Warning: Disk space is low </source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="8"/>
+ <source>Unable to bind to port %d on this computer. Bitcoin is probably already running.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="102"/>
+ <source>To use the %s option</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="103"/>
+ <source>%s, you must set a rpcpassword in the configuration file:
+ %s
+It is recommended you use the following random password:
+rpcuser=bitcoinrpc
+rpcpassword=%s
+(you do not need to remember this password)
+If the file does not exist, create it with owner-readable-only file permissions.
+</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="112"/>
+ <source>Error</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="113"/>
+ <source>An error occured while setting up the RPC port %i for listening: %s</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="114"/>
+ <source>You must set rpcpassword=&lt;password&gt; in the configuration file:
+%s
+If the file does not exist, create it with owner-readable-only file permissions.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="119"/>
+ <source>Warning: Please check that your computer&apos;s date and time are correct. If your clock is wrong Bitcoin will not work properly.</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+</TS> \ No newline at end of file
diff --git a/src/qt/locale/bitcoin_el_GR.ts b/src/qt/locale/bitcoin_el_GR.ts
new file mode 100644
index 0000000000..1309a78d4d
--- /dev/null
+++ b/src/qt/locale/bitcoin_el_GR.ts
@@ -0,0 +1,2269 @@
+<?xml version="1.0" ?><!DOCTYPE TS><TS language="el_GR" version="2.0">
+<defaultcodec>UTF-8</defaultcodec>
+<context>
+ <name>AboutDialog</name>
+ <message>
+ <location filename="../forms/aboutdialog.ui" line="14"/>
+ <source>About Bitcoin</source>
+ <translation>Σχετικα:Bitcoin</translation>
+ </message>
+ <message>
+ <location filename="../forms/aboutdialog.ui" line="53"/>
+ <source>&lt;b&gt;Bitcoin&lt;/b&gt; version</source>
+ <translation>&lt;b&gt;Bitcoin&lt;/b&gt;έκδοση</translation>
+ </message>
+ <message>
+ <location filename="../forms/aboutdialog.ui" line="97"/>
+ <source>Copyright © 2009-2012 Bitcoin Developers
+
+This is experimental software.
+
+Distributed under the MIT/X11 software license, see the accompanying file license.txt or http://www.opensource.org/licenses/mit-license.php.
+
+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.</source>
+ <translation>Copyright © 2009-2012 Προγραμματιστές του Bitcoin
+
+Αυτό ειναι πειραματικο λογισμικο.
+
+Διανέμεται κατω από άδεια MIT/X11 , δες το συνοδεύων αρχειο license.txt ή http://www.opensource.org/licenses/mit-license.php.
+
+Αυτό προϊόν περιλαμβάνει λογισμικο ανεπτυγμενο από το OpenSSL Project για χρήση στο OpenSSL Toolkit (http://www.openssl.org/) και κρυπτογραφικο κωδικα γραμένο από τον by Eric Young (eay@cryptsoft.com) και λογισμικο UPnP γραμένο από τον Thomas Bernard.</translation>
+ </message>
+</context>
+<context>
+ <name>AddressBookPage</name>
+ <message>
+ <location filename="../forms/addressbookpage.ui" line="14"/>
+ <source>Address Book</source>
+ <translation>Βιβλίο Διευθύνσεων</translation>
+ </message>
+ <message>
+ <location filename="../forms/addressbookpage.ui" line="20"/>
+ <source>These are your Bitcoin addresses for receiving payments. You may want to give a different one to each sender so you can keep track of who is paying you.</source>
+ <translation>Αυτές είναι οι διευθύνσεις Bitcoin για την παραλαβή πληρωμών. Μπορεί να θέλετε να δίνετε διαφορετική διεύθυνση σε κάθε αποστολέα έτσι ώστε να μπορείτε να παρακολουθείτε ποιος σας πληρώνει.</translation>
+ </message>
+ <message>
+ <location filename="../forms/addressbookpage.ui" line="36"/>
+ <source>Double-click to edit address or label</source>
+ <translation>Διπλό-κλικ για επεξεργασία της διεύθυνσης ή της ετικέτας</translation>
+ </message>
+ <message>
+ <location filename="../forms/addressbookpage.ui" line="63"/>
+ <source>Create a new address</source>
+ <translation>Δημιούργησε νέα διεύθυνση</translation>
+ </message>
+ <message>
+ <location filename="../forms/addressbookpage.ui" line="77"/>
+ <source>Copy the currently selected address to the system clipboard</source>
+ <translation>Αντέγραψε την επιλεγμένη διεύθυνση στο πρόχειρο του συστήματος</translation>
+ </message>
+ <message>
+ <location filename="../forms/addressbookpage.ui" line="66"/>
+ <source>&amp;New Address</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../forms/addressbookpage.ui" line="80"/>
+ <source>&amp;Copy Address</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../forms/addressbookpage.ui" line="91"/>
+ <source>Show &amp;QR Code</source>
+ <translation>Δείξε &amp;QR κωδικα</translation>
+ </message>
+ <message>
+ <location filename="../forms/addressbookpage.ui" line="102"/>
+ <source>Sign a message to prove you own this address</source>
+ <translation>Υπέγραψε ένα μήνυμα για να αποδείξεις ότι σου ανήκει η διεύθυνση</translation>
+ </message>
+ <message>
+ <location filename="../forms/addressbookpage.ui" line="105"/>
+ <source>&amp;Sign Message</source>
+ <translation>&amp;Υπέγραψε το μήνυμα</translation>
+ </message>
+ <message>
+ <location filename="../forms/addressbookpage.ui" line="116"/>
+ <source>Delete the currently selected address from the list. Only sending addresses can be deleted.</source>
+ <translation>Διέγραψε την επιλεγμένη διεύθυνση από την λίστα. Μόνο διευθύνσεις αποστολής μπορούν να διαγραφούν.</translation>
+ </message>
+ <message>
+ <location filename="../forms/addressbookpage.ui" line="119"/>
+ <source>&amp;Delete</source>
+ <translation>&amp;Διαγραφή</translation>
+ </message>
+ <message>
+ <location filename="../addressbookpage.cpp" line="63"/>
+ <source>Copy &amp;Label</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../addressbookpage.cpp" line="65"/>
+ <source>&amp;Edit</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../addressbookpage.cpp" line="297"/>
+ <source>Export Address Book Data</source>
+ <translation>Εξαγωγή Δεδομενων Βιβλίου Διευθύνσεων</translation>
+ </message>
+ <message>
+ <location filename="../addressbookpage.cpp" line="298"/>
+ <source>Comma separated file (*.csv)</source>
+ <translation>Αρχείο οριοθετημένο με κόμματα (*.csv)</translation>
+ </message>
+ <message>
+ <location filename="../addressbookpage.cpp" line="311"/>
+ <source>Error exporting</source>
+ <translation>Εξαγωγή λαθών</translation>
+ </message>
+ <message>
+ <location filename="../addressbookpage.cpp" line="311"/>
+ <source>Could not write to file %1.</source>
+ <translation>Δεν μπόρεσα να γράψω στο αρχείο %1.</translation>
+ </message>
+</context>
+<context>
+ <name>AddressTableModel</name>
+ <message>
+ <location filename="../addresstablemodel.cpp" line="78"/>
+ <source>Label</source>
+ <translation>Ετικέτα</translation>
+ </message>
+ <message>
+ <location filename="../addresstablemodel.cpp" line="78"/>
+ <source>Address</source>
+ <translation>Διεύθυνση</translation>
+ </message>
+ <message>
+ <location filename="../addresstablemodel.cpp" line="114"/>
+ <source>(no label)</source>
+ <translation>(χωρίς ετικέτα)</translation>
+ </message>
+</context>
+<context>
+ <name>AskPassphraseDialog</name>
+ <message>
+ <location filename="../forms/askpassphrasedialog.ui" line="26"/>
+ <source>Dialog</source>
+ <translation>Διάλογος</translation>
+ </message>
+ <message>
+ <location filename="../forms/askpassphrasedialog.ui" line="32"/>
+ <location filename="../forms/askpassphrasedialog.ui" line="97"/>
+ <source>TextLabel</source>
+ <translation>ΚειμενοΕτικετας</translation>
+ </message>
+ <message>
+ <location filename="../forms/askpassphrasedialog.ui" line="50"/>
+ <source>Enter passphrase</source>
+ <translation>Βάλτε κωδικό πρόσβασης</translation>
+ </message>
+ <message>
+ <location filename="../forms/askpassphrasedialog.ui" line="64"/>
+ <source>New passphrase</source>
+ <translation>Νέος κωδικός πρόσβασης</translation>
+ </message>
+ <message>
+ <location filename="../forms/askpassphrasedialog.ui" line="78"/>
+ <source>Repeat new passphrase</source>
+ <translation>Επανέλαβε τον νέο κωδικό πρόσβασης</translation>
+ </message>
+ <message>
+ <location filename="../askpassphrasedialog.cpp" line="34"/>
+ <source>Enter the new passphrase to the wallet.&lt;br/&gt;Please use a passphrase of &lt;b&gt;10 or more random characters&lt;/b&gt;, or &lt;b&gt;eight or more words&lt;/b&gt;.</source>
+ <translation>Εισάγετε τον νέο κωδικό πρόσβασης στον πορτοφόλι &lt;br/&gt; Παρακαλώ χρησιμοποιείστε ένα κωδικό με &lt;b&gt; 10 ή περισσότερους τυχαίους χαρακτήρες&lt;/b&gt; ή &lt;b&gt; οχτώ ή παραπάνω λέξεις&lt;/b&gt;.</translation>
+ </message>
+ <message>
+ <location filename="../askpassphrasedialog.cpp" line="35"/>
+ <source>Encrypt wallet</source>
+ <translation>Κρυπτογράφησε το πορτοφόλι</translation>
+ </message>
+ <message>
+ <location filename="../askpassphrasedialog.cpp" line="38"/>
+ <source>This operation needs your wallet passphrase to unlock the wallet.</source>
+ <translation>Αυτη η ενεργεία χρειάζεται τον κωδικό του πορτοφολιού για να ξεκλειδώσει το πορτοφόλι.</translation>
+ </message>
+ <message>
+ <location filename="../askpassphrasedialog.cpp" line="43"/>
+ <source>Unlock wallet</source>
+ <translation>Ξεκλειδωσε το πορτοφολι</translation>
+ </message>
+ <message>
+ <location filename="../askpassphrasedialog.cpp" line="46"/>
+ <source>This operation needs your wallet passphrase to decrypt the wallet.</source>
+ <translation>Αυτη η ενεργεια χρειάζεται τον κωδικο του πορτοφολιου για να αποκρυπτογραφησειι το πορτοφολι.</translation>
+ </message>
+ <message>
+ <location filename="../askpassphrasedialog.cpp" line="51"/>
+ <source>Decrypt wallet</source>
+ <translation>Αποκρυπτογράφησε το πορτοφολι</translation>
+ </message>
+ <message>
+ <location filename="../askpassphrasedialog.cpp" line="54"/>
+ <source>Change passphrase</source>
+ <translation>Άλλαξε κωδικο πρόσβασης</translation>
+ </message>
+ <message>
+ <location filename="../askpassphrasedialog.cpp" line="55"/>
+ <source>Enter the old and new passphrase to the wallet.</source>
+ <translation>Εισάγετε τον παλιό και τον νεο κωδικο στο πορτοφολι.</translation>
+ </message>
+ <message>
+ <location filename="../askpassphrasedialog.cpp" line="101"/>
+ <source>Confirm wallet encryption</source>
+ <translation>Επιβεβαίωσε την κρυπτογραφηση του πορτοφολιού</translation>
+ </message>
+ <message>
+ <location filename="../askpassphrasedialog.cpp" line="102"/>
+ <source>WARNING: If you encrypt your wallet and lose your passphrase, you will &lt;b&gt;LOSE ALL OF YOUR BITCOINS&lt;/b&gt;!
+Are you sure you wish to encrypt your wallet?</source>
+ <translation>Προσοχη: Εαν κρυπτογραφησεις το πορτοφολι σου και χάσεις τον κωδικο σου θα χάσεις &lt;b&gt; ΟΛΑ ΣΟΥ ΤΑ BITCOINS&lt;/b&gt;!
+Είσαι σίγουρος ότι θέλεις να κρυπτογραφησεις το πορτοφολι;</translation>
+ </message>
+ <message>
+ <location filename="../askpassphrasedialog.cpp" line="111"/>
+ <location filename="../askpassphrasedialog.cpp" line="160"/>
+ <source>Wallet encrypted</source>
+ <translation>Κρυπτογραφημενο πορτοφολι</translation>
+ </message>
+ <message>
+ <location filename="../askpassphrasedialog.cpp" line="112"/>
+ <source>Bitcoin will close now to finish the encryption process. Remember that encrypting your wallet cannot fully protect your bitcoins from being stolen by malware infecting your computer.</source>
+ <translation>Το Bitcoin θα κλεισει τώρα για να τελειώσει την διαδικασία κρυπτογραφησης. Θυμησου ότι κρυπτογραφώντας το πορτοφολι σου δεν μπορείς να προστατέψεις πλήρως τα bitcoins σου από κλοπή στην περίπτωση όπου μολυνθεί ο υπολογιστής σου με κακόβουλο λογισμικο.</translation>
+ </message>
+ <message>
+ <location filename="../askpassphrasedialog.cpp" line="208"/>
+ <location filename="../askpassphrasedialog.cpp" line="232"/>
+ <source>Warning: The Caps Lock key is on.</source>
+ <translation>Προσοχη: το πλήκτρο Caps Lock είναι ενεργο.</translation>
+ </message>
+ <message>
+ <location filename="../askpassphrasedialog.cpp" line="117"/>
+ <location filename="../askpassphrasedialog.cpp" line="124"/>
+ <location filename="../askpassphrasedialog.cpp" line="166"/>
+ <location filename="../askpassphrasedialog.cpp" line="172"/>
+ <source>Wallet encryption failed</source>
+ <translation>Η κρυπτογραφηση του πορτοφολιού απέτυχε</translation>
+ </message>
+ <message>
+ <location filename="../askpassphrasedialog.cpp" line="118"/>
+ <source>Wallet encryption failed due to an internal error. Your wallet was not encrypted.</source>
+ <translation>Η κρυπτογράφηση του πορτοφολιού απέτυχε λογω εσωτερικού σφάλματος. Το πορτοφολι δεν κρυπτογραφηθηκε.</translation>
+ </message>
+ <message>
+ <location filename="../askpassphrasedialog.cpp" line="125"/>
+ <location filename="../askpassphrasedialog.cpp" line="173"/>
+ <source>The supplied passphrases do not match.</source>
+ <translation>Οι εισαχθέντες κωδικοί δεν ταιριάζουν.</translation>
+ </message>
+ <message>
+ <location filename="../askpassphrasedialog.cpp" line="136"/>
+ <source>Wallet unlock failed</source>
+ <translation>το ξεκλείδωμα του πορτοφολιού απέτυχε</translation>
+ </message>
+ <message>
+ <location filename="../askpassphrasedialog.cpp" line="137"/>
+ <location filename="../askpassphrasedialog.cpp" line="148"/>
+ <location filename="../askpassphrasedialog.cpp" line="167"/>
+ <source>The passphrase entered for the wallet decryption was incorrect.</source>
+ <translation>Ο κωδικος που εισήχθη για την αποκρυπτογραφηση του πορτοφολιού ήταν λαθος.</translation>
+ </message>
+ <message>
+ <location filename="../askpassphrasedialog.cpp" line="147"/>
+ <source>Wallet decryption failed</source>
+ <translation>Η αποκρυπτογραφηση του πορτοφολιού απέτυχε</translation>
+ </message>
+ <message>
+ <location filename="../askpassphrasedialog.cpp" line="161"/>
+ <source>Wallet passphrase was succesfully changed.</source>
+ <translation>Ο κωδικος του πορτοφολιού άλλαξε με επιτυχία.</translation>
+ </message>
+</context>
+<context>
+ <name>BitcoinGUI</name>
+ <message>
+ <location filename="../bitcoingui.cpp" line="72"/>
+ <source>Bitcoin Wallet</source>
+ <translation>Πορτοφολι Bitcoin</translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="212"/>
+ <source>Sign &amp;message...</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="245"/>
+ <source>Show/Hide &amp;Bitcoin</source>
+ <translation>Εμφάνισε/Κρύψε &amp;Bitcoin</translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="507"/>
+ <source>Synchronizing with network...</source>
+ <translation>Συγχρονισμός με το δίκτυο...</translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="182"/>
+ <source>&amp;Overview</source>
+ <translation>&amp;Επισκόπηση</translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="183"/>
+ <source>Show general overview of wallet</source>
+ <translation>Εμφάνισε γενική εικονα του πορτοφολιού</translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="188"/>
+ <source>&amp;Transactions</source>
+ <translation>&amp;Συναλλαγές</translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="189"/>
+ <source>Browse transaction history</source>
+ <translation>Περιήγηση στο ιστορικο συνναλαγων</translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="194"/>
+ <source>&amp;Address Book</source>
+ <translation>&amp;Βιβλίο Διευθύνσεων</translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="195"/>
+ <source>Edit the list of stored addresses and labels</source>
+ <translation>Εξεργασια της λιστας των αποθηκευμενων διευθύνσεων και ετικετων</translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="200"/>
+ <source>&amp;Receive coins</source>
+ <translation>&amp;Παραλαβή νομισματων</translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="201"/>
+ <source>Show the list of addresses for receiving payments</source>
+ <translation>Εμφάνισε την λίστα των διευθύνσεων για την παραλαβή πληρωμων</translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="206"/>
+ <source>&amp;Send coins</source>
+ <translation>&amp;Αποστολη νομισματων</translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="207"/>
+ <source>Send coins to a bitcoin address</source>
+ <translation>Στείλε νομισματα σε μια διεύθυνση bitcoin</translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="213"/>
+ <source>Prove you control an address</source>
+ <translation>Απέδειξε ότι ελέγχεις μια διεύθυνση</translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="232"/>
+ <source>E&amp;xit</source>
+ <translation>Έ&amp;ξοδος</translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="233"/>
+ <source>Quit application</source>
+ <translation>Εξοδος από την εφαρμογή</translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="236"/>
+ <source>&amp;About %1</source>
+ <translation>&amp;Περί %1</translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="237"/>
+ <source>Show information about Bitcoin</source>
+ <translation>Εμφάνισε πληροφορίες σχετικά με το Bitcoin</translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="239"/>
+ <source>About &amp;Qt</source>
+ <translation>Σχετικά με &amp;Qt</translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="240"/>
+ <source>Show information about Qt</source>
+ <translation>Εμφάνισε πληροφορίες σχετικά με Qt</translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="242"/>
+ <source>&amp;Options...</source>
+ <translation>&amp;Επιλογές...</translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="243"/>
+ <source>Modify configuration options for bitcoin</source>
+ <translation>Επεργασία ρυθμισεων επιλογών για το Bitcoin</translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="249"/>
+ <source>&amp;Encrypt Wallet...</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="252"/>
+ <source>&amp;Backup Wallet...</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="254"/>
+ <source>&amp;Change Passphrase...</source>
+ <translation type="unfinished"/>
+ </message>
+ <message numerus="yes">
+ <location filename="../bitcoingui.cpp" line="509"/>
+ <source>~%n block(s) remaining</source>
+ <translation><numerusform>~%n μπλοκ απέμεινε</numerusform><numerusform>~%n μπλοκ απέμειναν</numerusform></translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="520"/>
+ <source>Downloaded %1 of %2 blocks of transaction history (%3% done).</source>
+ <translation>Κατέβηκαν %1 από %2 μπλοκ του ιστορικού συναλλαγών (%3% ολοκληρώθηκαν)</translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="247"/>
+ <source>&amp;Export...</source>
+ <translation>&amp;Εξαγωγή</translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="246"/>
+ <source>Show or hide the Bitcoin window</source>
+ <translation>Εμφάνισε ή κρύψε το παράθυρο Bitcoin</translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="248"/>
+ <source>Export the data in the current tab to a file</source>
+ <translation>Εξαγωγή δεδομένων καρτέλας σε αρχείο</translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="250"/>
+ <source>Encrypt or decrypt wallet</source>
+ <translation>Κρυπτογράφηση ή αποκρυπτογράφηση πορτοφολιού</translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="253"/>
+ <source>Backup wallet to another location</source>
+ <translation>Δημιουργία αντιγράφου ασφαλείας πορτοφολιού σε άλλη τοποθεσία</translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="255"/>
+ <source>Change the passphrase used for wallet encryption</source>
+ <translation>Αλλαγή του κωδικού κρυπτογράφησης του πορτοφολιού</translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="256"/>
+ <source>&amp;Debug window</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="257"/>
+ <source>Open debugging and diagnostic console</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="280"/>
+ <source>&amp;File</source>
+ <translation>&amp;Αρχείο</translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="289"/>
+ <source>&amp;Settings</source>
+ <translation>&amp;Ρυθμίσεις</translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="295"/>
+ <source>&amp;Help</source>
+ <translation>&amp;Βοήθεια</translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="304"/>
+ <source>Tabs toolbar</source>
+ <translation>Εργαλειοθήκη καρτελών</translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="315"/>
+ <source>Actions toolbar</source>
+ <translation>Εργαλειοθήκη ενεργειών</translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="327"/>
+ <source>[testnet]</source>
+ <translation>[testnet]</translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="391"/>
+ <source>Bitcoin client</source>
+ <translation>Πελάτης Bitcoin</translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="419"/>
+ <source>bitcoin-qt</source>
+ <translation>bitcoin-qt</translation>
+ </message>
+ <message numerus="yes">
+ <location filename="../bitcoingui.cpp" line="483"/>
+ <source>%n active connection(s) to Bitcoin network</source>
+ <translation><numerusform>%n ενεργή σύνδεση στο δίκτυο Bitcoin</numerusform><numerusform>%n ενεργές συνδέσεις στο δίκτυο Βitcoin</numerusform></translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="532"/>
+ <source>Downloaded %1 blocks of transaction history.</source>
+ <translation>Έγινε λήψη %1 μπλοκ ιστορικού συναλλαγών</translation>
+ </message>
+ <message numerus="yes">
+ <location filename="../bitcoingui.cpp" line="547"/>
+ <source>%n second(s) ago</source>
+ <translation><numerusform>%n δευτερόλεπτο πριν</numerusform><numerusform>%n δευτερόλεπτα πριν</numerusform></translation>
+ </message>
+ <message numerus="yes">
+ <location filename="../bitcoingui.cpp" line="551"/>
+ <source>%n minute(s) ago</source>
+ <translation><numerusform>%n λεπτό πριν</numerusform><numerusform>%n λεπτά πριν</numerusform></translation>
+ </message>
+ <message numerus="yes">
+ <location filename="../bitcoingui.cpp" line="555"/>
+ <source>%n hour(s) ago</source>
+ <translation><numerusform>%n ώρα πριν</numerusform><numerusform>%n ώρες πριν</numerusform></translation>
+ </message>
+ <message numerus="yes">
+ <location filename="../bitcoingui.cpp" line="559"/>
+ <source>%n day(s) ago</source>
+ <translation><numerusform>%n ημέρα πριν</numerusform><numerusform>%n ημέρες πριν</numerusform></translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="565"/>
+ <source>Up to date</source>
+ <translation>Ενημερωμένο</translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="570"/>
+ <source>Catching up...</source>
+ <translation>Ενημέρωση...</translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="578"/>
+ <source>Last received block was generated %1.</source>
+ <translation>Το τελευταίο μπλοκ που ελήφθη %1.</translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="634"/>
+ <source>This transaction is over the size limit. You can still send it for a fee of %1, which goes to the nodes that process your transaction and helps to support the network. Do you want to pay the fee?</source>
+ <translation>Η συναλλαγή ξεπερνάει το όριο.
+Μπορεί να ολοκληρωθεί με μια αμοιβή των %1, η οποία αποδίδεται στους κόμβους που επεξεργάζονται τις συναλλαγές και βοηθούν στην υποστήριξη του δικτύου.
+Θέλετε να συνεχίσετε;</translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="639"/>
+ <source>Confirm transaction fee</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="666"/>
+ <source>Sent transaction</source>
+ <translation>Η συναλλαγή απεστάλη</translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="667"/>
+ <source>Incoming transaction</source>
+ <translation>Εισερχόμενη συναλλαγή</translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="668"/>
+ <source>Date: %1
+Amount: %2
+Type: %3
+Address: %4
+</source>
+ <translation>Ημερομηνία: %1
+Ποσό: %2
+Τύπος: %3
+Διεύθυνση: %4
+</translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="793"/>
+ <source>Wallet is &lt;b&gt;encrypted&lt;/b&gt; and currently &lt;b&gt;unlocked&lt;/b&gt;</source>
+ <translation>Το πορτοφόλι είναι &lt;b&gt;κρυπτογραφημένο&lt;/b&gt; και &lt;b&gt;ξεκλείδωτο&lt;/b&gt;</translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="801"/>
+ <source>Wallet is &lt;b&gt;encrypted&lt;/b&gt; and currently &lt;b&gt;locked&lt;/b&gt;</source>
+ <translation>Το πορτοφόλι είναι &lt;b&gt;κρυπτογραφημένο&lt;/b&gt; και &lt;b&gt;κλειδωμένο&lt;/b&gt;</translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="824"/>
+ <source>Backup Wallet</source>
+ <translation>Αντίγραφο ασφαλείας του πορτοφολιού</translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="824"/>
+ <source>Wallet Data (*.dat)</source>
+ <translation>Αρχεία δεδομένων πορτοφολιού (*.dat)</translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="827"/>
+ <source>Backup Failed</source>
+ <translation>Αποτυχία κατά τη δημιουργία αντιγράφου</translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="827"/>
+ <source>There was an error trying to save the wallet data to the new location.</source>
+ <translation>Παρουσιάστηκε σφάλμα κατά την αποθήκευση των δεδομένων πορτοφολιού στη νέα τοποθεσία.</translation>
+ </message>
+ <message>
+ <location filename="../bitcoin.cpp" line="127"/>
+ <source>A fatal error occured. Bitcoin can no longer continue safely and will quit.</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
+ <name>DisplayOptionsPage</name>
+ <message>
+ <location filename="../optionsdialog.cpp" line="273"/>
+ <source>&amp;Unit to show amounts in: </source>
+ <translation>&amp;Μονάδα μέτρησης:</translation>
+ </message>
+ <message>
+ <location filename="../optionsdialog.cpp" line="277"/>
+ <source>Choose the default subdivision unit to show in the interface, and when sending coins</source>
+ <translation>Επιλέξτε τη μονάδα υποδιαίρεσης που θα εμφανίζεται</translation>
+ </message>
+ <message>
+ <location filename="../optionsdialog.cpp" line="284"/>
+ <source>&amp;Display addresses in transaction list</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../optionsdialog.cpp" line="285"/>
+ <source>Whether to show Bitcoin addresses in the transaction list</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
+ <name>EditAddressDialog</name>
+ <message>
+ <location filename="../forms/editaddressdialog.ui" line="14"/>
+ <source>Edit Address</source>
+ <translation>Επεξεργασία Διεύθυνσης</translation>
+ </message>
+ <message>
+ <location filename="../forms/editaddressdialog.ui" line="25"/>
+ <source>&amp;Label</source>
+ <translation>&amp;Επιγραφή</translation>
+ </message>
+ <message>
+ <location filename="../forms/editaddressdialog.ui" line="35"/>
+ <source>The label associated with this address book entry</source>
+ <translation>Η επιγραφή που σχετίζεται με αυτή την καταχώρηση του βιβλίου διευθύνσεων</translation>
+ </message>
+ <message>
+ <location filename="../forms/editaddressdialog.ui" line="42"/>
+ <source>&amp;Address</source>
+ <translation>&amp;Διεύθυνση</translation>
+ </message>
+ <message>
+ <location filename="../forms/editaddressdialog.ui" line="52"/>
+ <source>The address associated with this address book entry. This can only be modified for sending addresses.</source>
+ <translation>Η διεύθυνση που σχετίζεται με αυτή την καταχώρηση του βιβλίου διευθύνσεων. Μπορεί να τροποποιηθεί μόνο για τις διευθύνσεις αποστολής.</translation>
+ </message>
+ <message>
+ <location filename="../editaddressdialog.cpp" line="20"/>
+ <source>New receiving address</source>
+ <translation>Νέα διεύθυνση λήψης</translation>
+ </message>
+ <message>
+ <location filename="../editaddressdialog.cpp" line="24"/>
+ <source>New sending address</source>
+ <translation>Νέα διεύθυνση αποστολής</translation>
+ </message>
+ <message>
+ <location filename="../editaddressdialog.cpp" line="27"/>
+ <source>Edit receiving address</source>
+ <translation>Επεξεργασία διεύθυνσης λήψης</translation>
+ </message>
+ <message>
+ <location filename="../editaddressdialog.cpp" line="31"/>
+ <source>Edit sending address</source>
+ <translation>Επεξεργασία διεύθυνσης αποστολής</translation>
+ </message>
+ <message>
+ <location filename="../editaddressdialog.cpp" line="91"/>
+ <source>The entered address &quot;%1&quot; is already in the address book.</source>
+ <translation>Η διεύθυνση &quot;%1&quot; βρίσκεται ήδη στο βιβλίο διευθύνσεων.</translation>
+ </message>
+ <message>
+ <location filename="../editaddressdialog.cpp" line="96"/>
+ <source>The entered address &quot;%1&quot; is not a valid bitcoin address.</source>
+ <translation>Η διεύθυνση &quot;%1&quot; δεν είναι έγκυρη Bitcoin διεύθυνση.</translation>
+ </message>
+ <message>
+ <location filename="../editaddressdialog.cpp" line="101"/>
+ <source>Could not unlock wallet.</source>
+ <translation>Δεν είναι δυνατό το ξεκλείδωμα του πορτοφολιού.</translation>
+ </message>
+ <message>
+ <location filename="../editaddressdialog.cpp" line="106"/>
+ <source>New key generation failed.</source>
+ <translation>Η δημιουργία νέου κλειδιού απέτυχε.</translation>
+ </message>
+</context>
+<context>
+ <name>MainOptionsPage</name>
+ <message>
+ <location filename="../optionsdialog.cpp" line="171"/>
+ <source>&amp;Start Bitcoin on window system startup</source>
+ <translation>&amp;Έναρξη Βιtcoin κατά την εκκίνηση του συστήματος</translation>
+ </message>
+ <message>
+ <location filename="../optionsdialog.cpp" line="172"/>
+ <source>Automatically start Bitcoin after the computer is turned on</source>
+ <translation>Αυτόματη έναρξη Βitcoin με το ξεκίνημα του υπολογιστή</translation>
+ </message>
+ <message>
+ <location filename="../optionsdialog.cpp" line="176"/>
+ <source>&amp;Minimize to the tray instead of the taskbar</source>
+ <translation>&amp;Ελαχιστοποίηση στην περιοχή ειδοποιήσεων αντί της γραμμής εργασιών</translation>
+ </message>
+ <message>
+ <location filename="../optionsdialog.cpp" line="177"/>
+ <source>Show only a tray icon after minimizing the window</source>
+ <translation>Εμφάνιση εικονιδίου στην περιοχή ειδοποιήσεων μόνο κατά την ελαχιστοποίηση</translation>
+ </message>
+ <message>
+ <location filename="../optionsdialog.cpp" line="185"/>
+ <source>Map port using &amp;UPnP</source>
+ <translation>Απόδοση θυρών με χρήστη &amp;UPnP</translation>
+ </message>
+ <message>
+ <location filename="../optionsdialog.cpp" line="186"/>
+ <source>Automatically open the Bitcoin client port on the router. This only works when your router supports UPnP and it is enabled.</source>
+ <translation>Αυτόματο άνοιγμα των θυρών Bitcoin στον δρομολογητή. Λειτουργεί μόνο αν ο δρομολογητής σας υποστηρίζει τη λειτουργία UPnP.</translation>
+ </message>
+ <message>
+ <location filename="../optionsdialog.cpp" line="180"/>
+ <source>M&amp;inimize on close</source>
+ <translation>Ε&amp;λαχιστοποίηση κατά το κλείσιμο</translation>
+ </message>
+ <message>
+ <location filename="../optionsdialog.cpp" line="181"/>
+ <source>Minimize instead of exit the application when the window is closed. When this option is enabled, the application will be closed only after selecting Quit in the menu.</source>
+ <translation>Ελαχιστοποίηση αντί για έξοδο κατά το κλείσιμο του παραθύρου</translation>
+ </message>
+ <message>
+ <location filename="../optionsdialog.cpp" line="189"/>
+ <source>&amp;Connect through SOCKS4 proxy:</source>
+ <translation>&amp;Σύνδεση μέσω SOCKS4 διαμεσολαβητή</translation>
+ </message>
+ <message>
+ <location filename="../optionsdialog.cpp" line="190"/>
+ <source>Connect to the Bitcon network through a SOCKS4 proxy (e.g. when connecting through Tor)</source>
+ <translation>Σύνδεση στο Bitcoin δίκτυο μέσω διαμεσολαβητή SOCKS4 (π.χ. για σύνδεση μέσω Tor)</translation>
+ </message>
+ <message>
+ <location filename="../optionsdialog.cpp" line="195"/>
+ <source>Proxy &amp;IP: </source>
+ <translation>&amp;IP διαμεσολαβητή:</translation>
+ </message>
+ <message>
+ <location filename="../optionsdialog.cpp" line="201"/>
+ <source>IP address of the proxy (e.g. 127.0.0.1)</source>
+ <translation>Διεύθυνση IP του διαμεσολαβητή (π.χ. 127.0.0.1)</translation>
+ </message>
+ <message>
+ <location filename="../optionsdialog.cpp" line="204"/>
+ <source>&amp;Port: </source>
+ <translation>&amp;Θύρα:</translation>
+ </message>
+ <message>
+ <location filename="../optionsdialog.cpp" line="210"/>
+ <source>Port of the proxy (e.g. 1234)</source>
+ <translation>Η θύρα του διαμεσολαβητή (π.χ. 1234)</translation>
+ </message>
+ <message>
+ <location filename="../optionsdialog.cpp" line="232"/>
+ <source>Detach databases at shutdown</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../optionsdialog.cpp" line="233"/>
+ <source>Detach block and address databases at shutdown. This means they can be moved to another data directory, but it slows down shutdown. The wallet is always detached.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../optionsdialog.cpp" line="222"/>
+ <source>Pay transaction &amp;fee</source>
+ <translation>Αμοιβή &amp;συναλλαγής</translation>
+ </message>
+ <message>
+ <location filename="../optionsdialog.cpp" line="216"/>
+ <source>Optional transaction fee per kB that helps make sure your transactions are processed quickly. Most transactions are 1 kB. Fee 0.01 recommended.</source>
+ <translation>Η προαιρετική αμοιβή για κάθε kB επισπεύδει την επεξεργασία των συναλλαγών σας. Οι περισσότερες συναλλαγές είναι 1 kB. Προτείνεται αμοιβή 0.01.</translation>
+ </message>
+</context>
+<context>
+ <name>MessagePage</name>
+ <message>
+ <location filename="../forms/messagepage.ui" line="14"/>
+ <source>Message</source>
+ <translation>Μήνυμα</translation>
+ </message>
+ <message>
+ <location filename="../forms/messagepage.ui" line="20"/>
+ <source>You can sign messages with your addresses to prove you own them. Be careful not to sign anything vague, as phishing attacks may try to trick you into signing your identity over to them. Only sign fully-detailed statements you agree to.</source>
+ <translation>Μπορείτε να υπογράφετε μηνύματα με τις διευθύνσεις σας, ώστε ν&apos; αποδεικνύετε πως αυτές σας ανήκουν. Αποφεύγετε να υπογράφετε κάτι αόριστο καθώς ενδέχεται να εξαπατηθείτε. Υπογράφετε μόνο πλήρης δηλώσεις με τις οποίες συμφωνείτε.</translation>
+ </message>
+ <message>
+ <location filename="../forms/messagepage.ui" line="38"/>
+ <source>The address to sign the message with (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L)</source>
+ <translation>Η διεύθυνση που θα υπογραφεί μαζί με το μήνυμα (π.χ. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L)</translation>
+ </message>
+ <message>
+ <location filename="../forms/messagepage.ui" line="48"/>
+ <source>Choose adress from address book</source>
+ <translation>Αντιγραφή διεύθυνσης από το βιβλίο διευθύνσεων</translation>
+ </message>
+ <message>
+ <location filename="../forms/messagepage.ui" line="58"/>
+ <source>Alt+A</source>
+ <translation>Alt+A</translation>
+ </message>
+ <message>
+ <location filename="../forms/messagepage.ui" line="71"/>
+ <source>Paste address from clipboard</source>
+ <translation>Επικόλληση διεύθυνσης από το βιβλίο διευθύνσεων</translation>
+ </message>
+ <message>
+ <location filename="../forms/messagepage.ui" line="81"/>
+ <source>Alt+P</source>
+ <translation>Alt+P</translation>
+ </message>
+ <message>
+ <location filename="../forms/messagepage.ui" line="93"/>
+ <source>Enter the message you want to sign here</source>
+ <translation>Εισάγετε εδώ το μήνυμα που θέλετε να υπογράψετε</translation>
+ </message>
+ <message>
+ <location filename="../forms/messagepage.ui" line="128"/>
+ <source>Copy the current signature to the system clipboard</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../forms/messagepage.ui" line="131"/>
+ <source>&amp;Copy Signature</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../forms/messagepage.ui" line="142"/>
+ <source>Reset all sign message fields</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../forms/messagepage.ui" line="145"/>
+ <source>Clear &amp;All</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../messagepage.cpp" line="30"/>
+ <source>Click &quot;Sign Message&quot; to get signature</source>
+ <translation>Κάντε κλικ στο &quot;Υπογραφή Μηνύματος&quot; για να λάβετε την υπογραφή</translation>
+ </message>
+ <message>
+ <location filename="../forms/messagepage.ui" line="114"/>
+ <source>Sign a message to prove you own this address</source>
+ <translation>Υπογράψτε ένα μήνυμα για να βεβαιώσετε πως είστε ο κάτοχος αυτής της διεύθυνσης</translation>
+ </message>
+ <message>
+ <location filename="../forms/messagepage.ui" line="117"/>
+ <source>&amp;Sign Message</source>
+ <translation>&amp;Υπογραφή Μηνύματος</translation>
+ </message>
+ <message>
+ <location filename="../messagepage.cpp" line="79"/>
+ <location filename="../messagepage.cpp" line="94"/>
+ <location filename="../messagepage.cpp" line="106"/>
+ <source>Error signing</source>
+ <translation>Σφάλμα υπογραφής</translation>
+ </message>
+ <message>
+ <location filename="../messagepage.cpp" line="79"/>
+ <source>%1 is not a valid address.</source>
+ <translation>Η %1 δεν είναι έγκυρη διεύθυνση.</translation>
+ </message>
+ <message>
+ <location filename="../messagepage.cpp" line="94"/>
+ <source>Private key for %1 is not available.</source>
+ <translation>Το προσωπικό κλειδί της %1 δεν είναι διαθέσιμο.</translation>
+ </message>
+ <message>
+ <location filename="../messagepage.cpp" line="106"/>
+ <source>Sign failed</source>
+ <translation>Αποτυχία υπογραφής</translation>
+ </message>
+</context>
+<context>
+ <name>OptionsDialog</name>
+ <message>
+ <location filename="../optionsdialog.cpp" line="80"/>
+ <source>Main</source>
+ <translation>Βασικές</translation>
+ </message>
+ <message>
+ <location filename="../optionsdialog.cpp" line="85"/>
+ <source>Display</source>
+ <translation>Απεικόνισης</translation>
+ </message>
+ <message>
+ <location filename="../optionsdialog.cpp" line="105"/>
+ <source>Options</source>
+ <translation>Ρυθμίσεις</translation>
+ </message>
+</context>
+<context>
+ <name>OverviewPage</name>
+ <message>
+ <location filename="../forms/overviewpage.ui" line="14"/>
+ <source>Form</source>
+ <translation>Φόρμα</translation>
+ </message>
+ <message>
+ <location filename="../forms/overviewpage.ui" line="40"/>
+ <source>Balance:</source>
+ <translation>Υπόλοιπο</translation>
+ </message>
+ <message>
+ <location filename="../forms/overviewpage.ui" line="47"/>
+ <source>123.456 BTC</source>
+ <translation>123,456 BTC</translation>
+ </message>
+ <message>
+ <location filename="../forms/overviewpage.ui" line="54"/>
+ <source>Number of transactions:</source>
+ <translation>Αριθμός συναλλαγών</translation>
+ </message>
+ <message>
+ <location filename="../forms/overviewpage.ui" line="61"/>
+ <source>0</source>
+ <translation>0</translation>
+ </message>
+ <message>
+ <location filename="../forms/overviewpage.ui" line="68"/>
+ <source>Unconfirmed:</source>
+ <translation>Ανεπιβεβαίωτες</translation>
+ </message>
+ <message>
+ <location filename="../forms/overviewpage.ui" line="75"/>
+ <source>0 BTC</source>
+ <translation>0 BTC</translation>
+ </message>
+ <message>
+ <location filename="../forms/overviewpage.ui" line="88"/>
+ <source>Wallet</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../forms/overviewpage.ui" line="124"/>
+ <source>&lt;b&gt;Recent transactions&lt;/b&gt;</source>
+ <translation>&lt;b&gt;Πρόσφατες συναλλαγές&lt;/b&gt;</translation>
+ </message>
+ <message>
+ <location filename="../overviewpage.cpp" line="103"/>
+ <source>Your current balance</source>
+ <translation>Το τρέχον υπόλοιπο</translation>
+ </message>
+ <message>
+ <location filename="../overviewpage.cpp" line="108"/>
+ <source>Total of transactions that have yet to be confirmed, and do not yet count toward the current balance</source>
+ <translation>Το άθροισμα των συναλλαγών που δεν έχουν ακόμα επιβεβαιωθεί και δεν προσμετρώνται στο τρέχον υπόλοιπό σας</translation>
+ </message>
+ <message>
+ <location filename="../overviewpage.cpp" line="111"/>
+ <source>Total number of transactions in wallet</source>
+ <translation>Σύνολο συναλλαγών στο πορτοφόλι</translation>
+ </message>
+</context>
+<context>
+ <name>QRCodeDialog</name>
+ <message>
+ <location filename="../forms/qrcodedialog.ui" line="14"/>
+ <source>QR-Code Dialog</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../forms/qrcodedialog.ui" line="32"/>
+ <source>QR Code</source>
+ <translation>Κώδικας QR</translation>
+ </message>
+ <message>
+ <location filename="../forms/qrcodedialog.ui" line="55"/>
+ <source>Request Payment</source>
+ <translation>Αίτηση πληρωμής</translation>
+ </message>
+ <message>
+ <location filename="../forms/qrcodedialog.ui" line="70"/>
+ <source>Amount:</source>
+ <translation>Ποσό:</translation>
+ </message>
+ <message>
+ <location filename="../forms/qrcodedialog.ui" line="105"/>
+ <source>BTC</source>
+ <translation>BTC</translation>
+ </message>
+ <message>
+ <location filename="../forms/qrcodedialog.ui" line="121"/>
+ <source>Label:</source>
+ <translation>Επιγραφή:</translation>
+ </message>
+ <message>
+ <location filename="../forms/qrcodedialog.ui" line="144"/>
+ <source>Message:</source>
+ <translation>Μήνυμα:</translation>
+ </message>
+ <message>
+ <location filename="../forms/qrcodedialog.ui" line="186"/>
+ <source>&amp;Save As...</source>
+ <translation>&amp;Αποθήκευση ως...</translation>
+ </message>
+ <message>
+ <location filename="../qrcodedialog.cpp" line="46"/>
+ <source>Error encoding URI into QR Code.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../qrcodedialog.cpp" line="64"/>
+ <source>Resulting URI too long, try to reduce the text for label / message.</source>
+ <translation>Το αποτέλεσμα της διεύθυνσης είναι πολύ μεγάλο. Μειώστε το μέγεθος για το κείμενο της ετικέτας/ μηνύματος.</translation>
+ </message>
+ <message>
+ <location filename="../qrcodedialog.cpp" line="121"/>
+ <source>Save QR Code</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../qrcodedialog.cpp" line="121"/>
+ <source>PNG Images (*.png)</source>
+ <translation>Εικόνες PNG (*.png)</translation>
+ </message>
+</context>
+<context>
+ <name>RPCConsole</name>
+ <message>
+ <location filename="../forms/rpcconsole.ui" line="14"/>
+ <source>Bitcoin debug window</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../forms/rpcconsole.ui" line="24"/>
+ <source>Information</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../forms/rpcconsole.ui" line="33"/>
+ <source>Client name</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../forms/rpcconsole.ui" line="40"/>
+ <location filename="../forms/rpcconsole.ui" line="60"/>
+ <location filename="../forms/rpcconsole.ui" line="106"/>
+ <location filename="../forms/rpcconsole.ui" line="156"/>
+ <location filename="../forms/rpcconsole.ui" line="176"/>
+ <location filename="../forms/rpcconsole.ui" line="196"/>
+ <location filename="../forms/rpcconsole.ui" line="229"/>
+ <source>N/A</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../forms/rpcconsole.ui" line="53"/>
+ <source>Client version</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../forms/rpcconsole.ui" line="79"/>
+ <source>Version</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../forms/rpcconsole.ui" line="92"/>
+ <source>Network</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../forms/rpcconsole.ui" line="99"/>
+ <source>Number of connections</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../forms/rpcconsole.ui" line="119"/>
+ <source>On testnet</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../forms/rpcconsole.ui" line="142"/>
+ <source>Block chain</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../forms/rpcconsole.ui" line="149"/>
+ <source>Current number of blocks</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../forms/rpcconsole.ui" line="169"/>
+ <source>Estimated total blocks</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../forms/rpcconsole.ui" line="189"/>
+ <source>Last block time</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../forms/rpcconsole.ui" line="222"/>
+ <source>Build date</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../forms/rpcconsole.ui" line="237"/>
+ <source>Console</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../forms/rpcconsole.ui" line="278"/>
+ <source>&gt;</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../forms/rpcconsole.ui" line="294"/>
+ <source>Clear console</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../rpcconsole.cpp" line="97"/>
+ <source>&amp;Copy</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../rpcconsole.cpp" line="195"/>
+ <source>Welcome to the bitcoin RPC console.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../rpcconsole.cpp" line="196"/>
+ <source>Use up and down arrows to navigate history, and Ctrl-L to clear screen.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../rpcconsole.cpp" line="197"/>
+ <source>Type &quot;help&quot; for an overview of available commands.</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
+ <name>SendCoinsDialog</name>
+ <message>
+ <location filename="../forms/sendcoinsdialog.ui" line="14"/>
+ <location filename="../sendcoinsdialog.cpp" line="122"/>
+ <location filename="../sendcoinsdialog.cpp" line="127"/>
+ <location filename="../sendcoinsdialog.cpp" line="132"/>
+ <location filename="../sendcoinsdialog.cpp" line="137"/>
+ <location filename="../sendcoinsdialog.cpp" line="143"/>
+ <location filename="../sendcoinsdialog.cpp" line="148"/>
+ <location filename="../sendcoinsdialog.cpp" line="153"/>
+ <source>Send Coins</source>
+ <translation>Αποστολή νομισμάτων</translation>
+ </message>
+ <message>
+ <location filename="../forms/sendcoinsdialog.ui" line="64"/>
+ <source>Send to multiple recipients at once</source>
+ <translation>Αποστολή σε πολλούς αποδέκτες ταυτόχρονα</translation>
+ </message>
+ <message>
+ <location filename="../forms/sendcoinsdialog.ui" line="67"/>
+ <source>&amp;Add Recipient</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../forms/sendcoinsdialog.ui" line="84"/>
+ <source>Remove all transaction fields</source>
+ <translation>Διαγραφή όλων των πεδίων συναλλαγής</translation>
+ </message>
+ <message>
+ <location filename="../forms/sendcoinsdialog.ui" line="87"/>
+ <source>Clear all</source>
+ <translation>Καθαρισμός όλων</translation>
+ </message>
+ <message>
+ <location filename="../forms/sendcoinsdialog.ui" line="106"/>
+ <source>Balance:</source>
+ <translation>Υπόλοιπο:</translation>
+ </message>
+ <message>
+ <location filename="../forms/sendcoinsdialog.ui" line="113"/>
+ <source>123.456 BTC</source>
+ <translation>123,456 BTC</translation>
+ </message>
+ <message>
+ <location filename="../forms/sendcoinsdialog.ui" line="144"/>
+ <source>Confirm the send action</source>
+ <translation>Επιβεβαίωση αποστολής</translation>
+ </message>
+ <message>
+ <location filename="../forms/sendcoinsdialog.ui" line="147"/>
+ <source>&amp;Send</source>
+ <translation>&amp;Αποστολή</translation>
+ </message>
+ <message>
+ <location filename="../sendcoinsdialog.cpp" line="94"/>
+ <source>&lt;b&gt;%1&lt;/b&gt; to %2 (%3)</source>
+ <translation>&lt;b&gt;%1&lt;/b&gt; σε %2 (%3)</translation>
+ </message>
+ <message>
+ <location filename="../sendcoinsdialog.cpp" line="99"/>
+ <source>Confirm send coins</source>
+ <translation>Επιβεβαίωση αποστολής νομισμάτων</translation>
+ </message>
+ <message>
+ <location filename="../sendcoinsdialog.cpp" line="100"/>
+ <source>Are you sure you want to send %1?</source>
+ <translation>Είστε βέβαιοι για την αποστολή %1;</translation>
+ </message>
+ <message>
+ <location filename="../sendcoinsdialog.cpp" line="100"/>
+ <source> and </source>
+ <translation>και</translation>
+ </message>
+ <message>
+ <location filename="../sendcoinsdialog.cpp" line="123"/>
+ <source>The recepient address is not valid, please recheck.</source>
+ <translation>Η διεύθυνση του αποδέκτη δεν είναι σωστή. Παρακαλώ ελέγξτε ξανά.</translation>
+ </message>
+ <message>
+ <location filename="../sendcoinsdialog.cpp" line="128"/>
+ <source>The amount to pay must be larger than 0.</source>
+ <translation>Το ποσό πληρωμής πρέπει να είναι μεγαλύτερο από 0.</translation>
+ </message>
+ <message>
+ <location filename="../sendcoinsdialog.cpp" line="133"/>
+ <source>Amount exceeds your balance</source>
+ <translation>Το ποσό υπερβαίνει το υπόλοιπό σας</translation>
+ </message>
+ <message>
+ <location filename="../sendcoinsdialog.cpp" line="138"/>
+ <source>Total exceeds your balance when the %1 transaction fee is included</source>
+ <translation>Το σύνολο υπερβαίνει το υπόλοιπό σας όταν συμπεριληφθεί και η αμοιβή %1</translation>
+ </message>
+ <message>
+ <location filename="../sendcoinsdialog.cpp" line="144"/>
+ <source>Duplicate address found, can only send to each address once in one send operation</source>
+ <translation>Βρέθηκε η ίδια διεύθυνση δύο φορές. Επιτρέπεται μία μόνο εγγραφή για κάθε διεύθυνση, σε κάθε διαδικασία αποστολής.</translation>
+ </message>
+ <message>
+ <location filename="../sendcoinsdialog.cpp" line="149"/>
+ <source>Error: Transaction creation failed </source>
+ <translation>Σφάλμα: Η δημιουργία της συναλλαγής απέτυχε</translation>
+ </message>
+ <message>
+ <location filename="../sendcoinsdialog.cpp" line="154"/>
+ <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>Σφάλμα: Η συναλλαγή απορρίφθηκε.
+Αυτό ίσως οφείλεται στο ότι τα νομίσματά σας έχουν ήδη ξοδευτεί, π.χ. με την αντιγραφή του wallet.dat σε άλλο σύστημα και την χρήση τους εκεί, χωρίς η συναλλαγή να έχει καταγραφεί στο παρόν σύστημα.</translation>
+ </message>
+</context>
+<context>
+ <name>SendCoinsEntry</name>
+ <message>
+ <location filename="../forms/sendcoinsentry.ui" line="14"/>
+ <source>Form</source>
+ <translation>Φόρμα</translation>
+ </message>
+ <message>
+ <location filename="../forms/sendcoinsentry.ui" line="29"/>
+ <source>A&amp;mount:</source>
+ <translation>&amp;Ποσό:</translation>
+ </message>
+ <message>
+ <location filename="../forms/sendcoinsentry.ui" line="42"/>
+ <source>Pay &amp;To:</source>
+ <translation>Πληρωμή &amp;σε:</translation>
+ </message>
+ <message>
+ <location filename="../forms/sendcoinsentry.ui" line="66"/>
+ <location filename="../sendcoinsentry.cpp" line="25"/>
+ <source>Enter a label for this address to add it to your address book</source>
+ <translation>Εισάγετε μια επιγραφή για αυτή τη διεύθυνση ώστε να καταχωρηθεί στο βιβλίο διευθύνσεων</translation>
+ </message>
+ <message>
+ <location filename="../forms/sendcoinsentry.ui" line="75"/>
+ <source>&amp;Label:</source>
+ <translation>&amp;Επιγραφή</translation>
+ </message>
+ <message>
+ <location filename="../forms/sendcoinsentry.ui" line="93"/>
+ <source>The address to send the payment to (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L)</source>
+ <translation>Η διεύθυνση γι&apos; αποστολή πληρωμής
+(π.χ. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L)</translation>
+ </message>
+ <message>
+ <location filename="../forms/sendcoinsentry.ui" line="103"/>
+ <source>Choose address from address book</source>
+ <translation>Επιλογή διεύθυνσης από το βιβλίο διευθύνσεων</translation>
+ </message>
+ <message>
+ <location filename="../forms/sendcoinsentry.ui" line="113"/>
+ <source>Alt+A</source>
+ <translation>Alt+A</translation>
+ </message>
+ <message>
+ <location filename="../forms/sendcoinsentry.ui" line="120"/>
+ <source>Paste address from clipboard</source>
+ <translation>Επικόλληση διεύθυνσης από το πρόχειρο</translation>
+ </message>
+ <message>
+ <location filename="../forms/sendcoinsentry.ui" line="130"/>
+ <source>Alt+P</source>
+ <translation>Alt+P</translation>
+ </message>
+ <message>
+ <location filename="../forms/sendcoinsentry.ui" line="137"/>
+ <source>Remove this recipient</source>
+ <translation>Αφαίρεση αποδέκτη</translation>
+ </message>
+ <message>
+ <location filename="../sendcoinsentry.cpp" line="26"/>
+ <source>Enter a Bitcoin address (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L)</source>
+ <translation>Εισάγετε μια διεύθυνση Bitcoin (π.χ. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L)</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionDesc</name>
+ <message>
+ <location filename="../transactiondesc.cpp" line="20"/>
+ <source>Open for %1 blocks</source>
+ <translation>Ανοιχτό για %1 μπλοκ</translation>
+ </message>
+ <message>
+ <location filename="../transactiondesc.cpp" line="22"/>
+ <source>Open until %1</source>
+ <translation>Ανοιχτό μέχρι %1</translation>
+ </message>
+ <message>
+ <location filename="../transactiondesc.cpp" line="28"/>
+ <source>%1/offline?</source>
+ <translation>%1/χωρίς σύνδεση;</translation>
+ </message>
+ <message>
+ <location filename="../transactiondesc.cpp" line="30"/>
+ <source>%1/unconfirmed</source>
+ <translation>%1/χωρίς επιβεβαίωση</translation>
+ </message>
+ <message>
+ <location filename="../transactiondesc.cpp" line="32"/>
+ <source>%1 confirmations</source>
+ <translation>%1 επιβεβαιώσεις</translation>
+ </message>
+ <message>
+ <location filename="../transactiondesc.cpp" line="50"/>
+ <source>&lt;b&gt;Status:&lt;/b&gt; </source>
+ <translation>&lt;b&gt;Κατάσταση:&lt;/b&gt;</translation>
+ </message>
+ <message>
+ <location filename="../transactiondesc.cpp" line="55"/>
+ <source>, has not been successfully broadcast yet</source>
+ <translation>, δεν έχει ακόμα μεταδοθεί μ&apos; επιτυχία</translation>
+ </message>
+ <message>
+ <location filename="../transactiondesc.cpp" line="57"/>
+ <source>, broadcast through %1 node</source>
+ <translation>, έχει μεταδοθεί μέσω %1 κόμβου</translation>
+ </message>
+ <message>
+ <location filename="../transactiondesc.cpp" line="59"/>
+ <source>, broadcast through %1 nodes</source>
+ <translation>, έχει μεταδοθεί μέσω %1 κόμβων</translation>
+ </message>
+ <message>
+ <location filename="../transactiondesc.cpp" line="63"/>
+ <source>&lt;b&gt;Date:&lt;/b&gt; </source>
+ <translation>&lt;b&gt;Ημερομηνία:&lt;/b&gt; </translation>
+ </message>
+ <message>
+ <location filename="../transactiondesc.cpp" line="70"/>
+ <source>&lt;b&gt;Source:&lt;/b&gt; Generated&lt;br&gt;</source>
+ <translation>&lt;b&gt;Προέλευση:&lt;/b&gt; Δημιουργία&lt;br&gt;</translation>
+ </message>
+ <message>
+ <location filename="../transactiondesc.cpp" line="76"/>
+ <location filename="../transactiondesc.cpp" line="93"/>
+ <source>&lt;b&gt;From:&lt;/b&gt; </source>
+ <translation>&lt;b&gt;Από:&lt;/b&gt; </translation>
+ </message>
+ <message>
+ <location filename="../transactiondesc.cpp" line="93"/>
+ <source>unknown</source>
+ <translation>άγνωστο</translation>
+ </message>
+ <message>
+ <location filename="../transactiondesc.cpp" line="94"/>
+ <location filename="../transactiondesc.cpp" line="117"/>
+ <location filename="../transactiondesc.cpp" line="176"/>
+ <source>&lt;b&gt;To:&lt;/b&gt; </source>
+ <translation>&lt;b&gt;Προς:&lt;/b&gt; </translation>
+ </message>
+ <message>
+ <location filename="../transactiondesc.cpp" line="97"/>
+ <source> (yours, label: </source>
+ <translation> (δικές σας, επιγραφή: </translation>
+ </message>
+ <message>
+ <location filename="../transactiondesc.cpp" line="99"/>
+ <source> (yours)</source>
+ <translation> (δικές σας)</translation>
+ </message>
+ <message>
+ <location filename="../transactiondesc.cpp" line="134"/>
+ <location filename="../transactiondesc.cpp" line="148"/>
+ <location filename="../transactiondesc.cpp" line="193"/>
+ <location filename="../transactiondesc.cpp" line="210"/>
+ <source>&lt;b&gt;Credit:&lt;/b&gt; </source>
+ <translation>&lt;b&gt;Πίστωση:&lt;/b&gt; </translation>
+ </message>
+ <message>
+ <location filename="../transactiondesc.cpp" line="136"/>
+ <source>(%1 matures in %2 more blocks)</source>
+ <translation>(%1 ωρίμανση σε %2 επιπλέον μπλοκ)</translation>
+ </message>
+ <message>
+ <location filename="../transactiondesc.cpp" line="140"/>
+ <source>(not accepted)</source>
+ <translation>(μη αποδεκτό)</translation>
+ </message>
+ <message>
+ <location filename="../transactiondesc.cpp" line="184"/>
+ <location filename="../transactiondesc.cpp" line="192"/>
+ <location filename="../transactiondesc.cpp" line="207"/>
+ <source>&lt;b&gt;Debit:&lt;/b&gt; </source>
+ <translation>&lt;b&gt;Χρέωση:&lt;/b&gt; </translation>
+ </message>
+ <message>
+ <location filename="../transactiondesc.cpp" line="198"/>
+ <source>&lt;b&gt;Transaction fee:&lt;/b&gt; </source>
+ <translation>&lt;b&gt;Αμοιβή συναλλαγής:&lt;/b&gt; </translation>
+ </message>
+ <message>
+ <location filename="../transactiondesc.cpp" line="214"/>
+ <source>&lt;b&gt;Net amount:&lt;/b&gt; </source>
+ <translation>&lt;b&gt;Καθαρό ποσό:&lt;/b&gt; </translation>
+ </message>
+ <message>
+ <location filename="../transactiondesc.cpp" line="220"/>
+ <source>Message:</source>
+ <translation>Μήνυμα:</translation>
+ </message>
+ <message>
+ <location filename="../transactiondesc.cpp" line="222"/>
+ <source>Comment:</source>
+ <translation>Σχόλιο:</translation>
+ </message>
+ <message>
+ <location filename="../transactiondesc.cpp" line="224"/>
+ <source>Transaction ID:</source>
+ <translation>ID Συναλλαγής:</translation>
+ </message>
+ <message>
+ <location filename="../transactiondesc.cpp" line="227"/>
+ <source>Generated coins must wait 120 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, it will change to &quot;not accepted&quot; and not be spendable. This may occasionally happen if another node generates a block within a few seconds of yours.</source>
+ <translation>Πρέπει να περιμένετε 120 μπλοκ πριν μπορέσετε να χρησιμοποιήσετε τα νομίσματα που έχετε δημιουργήσει. Το μπλοκ που δημιουργήσατε μεταδόθηκε στο δίκτυο για να συμπεριληφθεί στην αλυσίδα των μπλοκ. Αν δεν μπει σε αυτή θα μετατραπεί σε &quot;μη αποδεκτό&quot; και δε θα μπορεί να καταναλωθεί. Αυτό συμβαίνει σπάνια όταν κάποιος άλλος κόμβος δημιουργήσει ένα μπλοκ λίγα δευτερόλεπτα πριν από εσάς.</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionDescDialog</name>
+ <message>
+ <location filename="../forms/transactiondescdialog.ui" line="14"/>
+ <source>Transaction details</source>
+ <translation>Λεπτομέρειες συναλλαγής</translation>
+ </message>
+ <message>
+ <location filename="../forms/transactiondescdialog.ui" line="20"/>
+ <source>This pane shows a detailed description of the transaction</source>
+ <translation>Αυτό το παράθυρο δείχνει μια λεπτομερή περιγραφή της συναλλαγής</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionTableModel</name>
+ <message>
+ <location filename="../transactiontablemodel.cpp" line="214"/>
+ <source>Date</source>
+ <translation>Ημερομηνία</translation>
+ </message>
+ <message>
+ <location filename="../transactiontablemodel.cpp" line="214"/>
+ <source>Type</source>
+ <translation>Τύπος</translation>
+ </message>
+ <message>
+ <location filename="../transactiontablemodel.cpp" line="214"/>
+ <source>Address</source>
+ <translation>Διεύθυνση</translation>
+ </message>
+ <message>
+ <location filename="../transactiontablemodel.cpp" line="214"/>
+ <source>Amount</source>
+ <translation>Ποσό</translation>
+ </message>
+ <message numerus="yes">
+ <location filename="../transactiontablemodel.cpp" line="275"/>
+ <source>Open for %n block(s)</source>
+ <translation><numerusform>Ανοιχτό για %n μπλοκ</numerusform><numerusform>Ανοιχτό για %n μπλοκ</numerusform></translation>
+ </message>
+ <message>
+ <location filename="../transactiontablemodel.cpp" line="278"/>
+ <source>Open until %1</source>
+ <translation>Ανοιχτό μέχρι %1</translation>
+ </message>
+ <message>
+ <location filename="../transactiontablemodel.cpp" line="281"/>
+ <source>Offline (%1 confirmations)</source>
+ <translation>Χωρίς σύνδεση (%1 επικυρώσεις)</translation>
+ </message>
+ <message>
+ <location filename="../transactiontablemodel.cpp" line="284"/>
+ <source>Unconfirmed (%1 of %2 confirmations)</source>
+ <translation>Χωρίς επιβεβαίωση (%1 από %2 επικυρώσεις)</translation>
+ </message>
+ <message>
+ <location filename="../transactiontablemodel.cpp" line="287"/>
+ <source>Confirmed (%1 confirmations)</source>
+ <translation>Επικυρωμένη (%1 επικυρώσεις)</translation>
+ </message>
+ <message numerus="yes">
+ <location filename="../transactiontablemodel.cpp" line="295"/>
+ <source>Mined balance will be available in %n more blocks</source>
+ <translation><numerusform>Το υπόλοιπο από την εξόρυξη θα είναι διαθέσιμο μετά από %n μπλοκ</numerusform><numerusform>Το υπόλοιπο από την εξόρυξη θα είναι διαθέσιμο μετά από %n μπλοκ</numerusform></translation>
+ </message>
+ <message>
+ <location filename="../transactiontablemodel.cpp" line="301"/>
+ <source>This block was not received by any other nodes and will probably not be accepted!</source>
+ <translation>Αυτό το μπλοκ δεν έχει παραληφθεί από κανέναν άλλο κόμβο και κατά πάσα πιθανότητα θα απορριφθεί!</translation>
+ </message>
+ <message>
+ <location filename="../transactiontablemodel.cpp" line="304"/>
+ <source>Generated but not accepted</source>
+ <translation>Δημιουργήθηκε αλλά απορρίφθηκε</translation>
+ </message>
+ <message>
+ <location filename="../transactiontablemodel.cpp" line="347"/>
+ <source>Received with</source>
+ <translation>Παραλαβή με</translation>
+ </message>
+ <message>
+ <location filename="../transactiontablemodel.cpp" line="349"/>
+ <source>Received from</source>
+ <translation>Ελήφθη από</translation>
+ </message>
+ <message>
+ <location filename="../transactiontablemodel.cpp" line="352"/>
+ <source>Sent to</source>
+ <translation>Αποστολή προς</translation>
+ </message>
+ <message>
+ <location filename="../transactiontablemodel.cpp" line="354"/>
+ <source>Payment to yourself</source>
+ <translation>Πληρωμή προς εσάς</translation>
+ </message>
+ <message>
+ <location filename="../transactiontablemodel.cpp" line="356"/>
+ <source>Mined</source>
+ <translation>Εξόρυξη</translation>
+ </message>
+ <message>
+ <location filename="../transactiontablemodel.cpp" line="394"/>
+ <source>(n/a)</source>
+ <translation>(δ/α)</translation>
+ </message>
+ <message>
+ <location filename="../transactiontablemodel.cpp" line="593"/>
+ <source>Transaction status. Hover over this field to show number of confirmations.</source>
+ <translation>Κατάσταση συναλλαγής. Πηγαίνετε το ποντίκι πάνω από αυτό το πεδίο για να δείτε τον αριθμό των επικυρώσεων</translation>
+ </message>
+ <message>
+ <location filename="../transactiontablemodel.cpp" line="595"/>
+ <source>Date and time that the transaction was received.</source>
+ <translation>Ημερομηνία κι ώρα λήψης της συναλλαγής.</translation>
+ </message>
+ <message>
+ <location filename="../transactiontablemodel.cpp" line="597"/>
+ <source>Type of transaction.</source>
+ <translation>Είδος συναλλαγής.</translation>
+ </message>
+ <message>
+ <location filename="../transactiontablemodel.cpp" line="599"/>
+ <source>Destination address of transaction.</source>
+ <translation>Διεύθυνση αποστολής της συναλλαγής.</translation>
+ </message>
+ <message>
+ <location filename="../transactiontablemodel.cpp" line="601"/>
+ <source>Amount removed from or added to balance.</source>
+ <translation>Ποσό που αφαιρέθηκε ή προστέθηκε στο υπόλοιπο.</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionView</name>
+ <message>
+ <location filename="../transactionview.cpp" line="55"/>
+ <location filename="../transactionview.cpp" line="71"/>
+ <source>All</source>
+ <translation>Όλα</translation>
+ </message>
+ <message>
+ <location filename="../transactionview.cpp" line="56"/>
+ <source>Today</source>
+ <translation>Σήμερα</translation>
+ </message>
+ <message>
+ <location filename="../transactionview.cpp" line="57"/>
+ <source>This week</source>
+ <translation>Αυτή την εβδομάδα</translation>
+ </message>
+ <message>
+ <location filename="../transactionview.cpp" line="58"/>
+ <source>This month</source>
+ <translation>Αυτόν τον μήνα</translation>
+ </message>
+ <message>
+ <location filename="../transactionview.cpp" line="59"/>
+ <source>Last month</source>
+ <translation>Τον προηγούμενο μήνα</translation>
+ </message>
+ <message>
+ <location filename="../transactionview.cpp" line="60"/>
+ <source>This year</source>
+ <translation>Αυτό το έτος</translation>
+ </message>
+ <message>
+ <location filename="../transactionview.cpp" line="61"/>
+ <source>Range...</source>
+ <translation>Έκταση...</translation>
+ </message>
+ <message>
+ <location filename="../transactionview.cpp" line="72"/>
+ <source>Received with</source>
+ <translation>Ελήφθη με</translation>
+ </message>
+ <message>
+ <location filename="../transactionview.cpp" line="74"/>
+ <source>Sent to</source>
+ <translation>Απεστάλη προς</translation>
+ </message>
+ <message>
+ <location filename="../transactionview.cpp" line="76"/>
+ <source>To yourself</source>
+ <translation>Προς εσάς</translation>
+ </message>
+ <message>
+ <location filename="../transactionview.cpp" line="77"/>
+ <source>Mined</source>
+ <translation>Εξόρυξη</translation>
+ </message>
+ <message>
+ <location filename="../transactionview.cpp" line="78"/>
+ <source>Other</source>
+ <translation>Άλλο</translation>
+ </message>
+ <message>
+ <location filename="../transactionview.cpp" line="84"/>
+ <source>Enter address or label to search</source>
+ <translation>Αναζήτηση με βάση τη διεύθυνση ή την επιγραφή</translation>
+ </message>
+ <message>
+ <location filename="../transactionview.cpp" line="90"/>
+ <source>Min amount</source>
+ <translation>Ελάχιστο ποσό</translation>
+ </message>
+ <message>
+ <location filename="../transactionview.cpp" line="124"/>
+ <source>Copy address</source>
+ <translation>Αντιγραφή διεύθυνσης</translation>
+ </message>
+ <message>
+ <location filename="../transactionview.cpp" line="125"/>
+ <source>Copy label</source>
+ <translation>Αντιγραφή επιγραφής</translation>
+ </message>
+ <message>
+ <location filename="../transactionview.cpp" line="126"/>
+ <source>Copy amount</source>
+ <translation>Αντιγραφή ποσού</translation>
+ </message>
+ <message>
+ <location filename="../transactionview.cpp" line="127"/>
+ <source>Edit label</source>
+ <translation>Επεξεργασία επιγραφής</translation>
+ </message>
+ <message>
+ <location filename="../transactionview.cpp" line="128"/>
+ <source>Show transaction details</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../transactionview.cpp" line="268"/>
+ <source>Export Transaction Data</source>
+ <translation>Εξαγωγή Στοιχείων Συναλλαγών</translation>
+ </message>
+ <message>
+ <location filename="../transactionview.cpp" line="269"/>
+ <source>Comma separated file (*.csv)</source>
+ <translation>Αρχείο οριοθετημένο με κόμματα (*.csv)</translation>
+ </message>
+ <message>
+ <location filename="../transactionview.cpp" line="277"/>
+ <source>Confirmed</source>
+ <translation>Επικυρωμένες</translation>
+ </message>
+ <message>
+ <location filename="../transactionview.cpp" line="278"/>
+ <source>Date</source>
+ <translation>Ημερομηνία</translation>
+ </message>
+ <message>
+ <location filename="../transactionview.cpp" line="279"/>
+ <source>Type</source>
+ <translation>Τύπος</translation>
+ </message>
+ <message>
+ <location filename="../transactionview.cpp" line="280"/>
+ <source>Label</source>
+ <translation>Επιγραφή</translation>
+ </message>
+ <message>
+ <location filename="../transactionview.cpp" line="281"/>
+ <source>Address</source>
+ <translation>Διεύθυνση</translation>
+ </message>
+ <message>
+ <location filename="../transactionview.cpp" line="282"/>
+ <source>Amount</source>
+ <translation>Ποσό</translation>
+ </message>
+ <message>
+ <location filename="../transactionview.cpp" line="283"/>
+ <source>ID</source>
+ <translation>ID</translation>
+ </message>
+ <message>
+ <location filename="../transactionview.cpp" line="287"/>
+ <source>Error exporting</source>
+ <translation>Σφάλμα εξαγωγής</translation>
+ </message>
+ <message>
+ <location filename="../transactionview.cpp" line="287"/>
+ <source>Could not write to file %1.</source>
+ <translation>Αδυναμία εγγραφής στο αρχείο %1.</translation>
+ </message>
+ <message>
+ <location filename="../transactionview.cpp" line="382"/>
+ <source>Range:</source>
+ <translation>Έκταση:</translation>
+ </message>
+ <message>
+ <location filename="../transactionview.cpp" line="390"/>
+ <source>to</source>
+ <translation>έως</translation>
+ </message>
+</context>
+<context>
+ <name>WalletModel</name>
+ <message>
+ <location filename="../walletmodel.cpp" line="142"/>
+ <source>Sending...</source>
+ <translation>Αποστολή...</translation>
+ </message>
+</context>
+<context>
+ <name>bitcoin-core</name>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="12"/>
+ <source>Bitcoin version</source>
+ <translation>Έκδοση Bitcoin</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="13"/>
+ <source>Usage:</source>
+ <translation>Χρήση:</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="14"/>
+ <source>Send command to -server or bitcoind</source>
+ <translation>Αποστολή εντολής στον εξυπηρετητή ή στο bitcoind</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="15"/>
+ <source>List commands</source>
+ <translation>Λίστα εντολών</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="16"/>
+ <source>Get help for a command</source>
+ <translation>Επεξήγηση εντολής</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="17"/>
+ <source>Options:</source>
+ <translation>Επιλογές:</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="18"/>
+ <source>Specify configuration file (default: bitcoin.conf)</source>
+ <translation>Ορίστε αρχείο ρυθμίσεων (προεπιλογή: bitcoin.conf)</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="19"/>
+ <source>Specify pid file (default: bitcoind.pid)</source>
+ <translation>Ορίστε αρχείο pid (προεπιλογή: bitcoind.pid)</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="20"/>
+ <source>Generate coins</source>
+ <translation>Δημιουργία νομισμάτων</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="21"/>
+ <source>Don&apos;t generate coins</source>
+ <translation>Άρνηση δημιουργίας νομισμάτων</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="22"/>
+ <source>Start minimized</source>
+ <translation>Έναρξη ελαχιστοποιημένο</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="23"/>
+ <source>Show splash screen on startup (default: 1)</source>
+ <translation>Εμφάνισε την οθόνη εκκίνησης κατά την εκκίνηση(προεπιλογή:1)</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="24"/>
+ <source>Specify data directory</source>
+ <translation>Ορισμός φακέλου δεδομένων</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="25"/>
+ <source>Set database cache size in megabytes (default: 25)</source>
+ <translation>Όρισε το μέγεθος της βάσης προσωρινής αποθήκευσης σε megabytes(προεπιλογή:25)</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="26"/>
+ <source>Set database disk log size in megabytes (default: 100)</source>
+ <translation>Όρισε το μέγεθος της βάσης ιστορικού σε megabytes (προεπιλογή:100)</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="27"/>
+ <source>Specify connection timeout (in milliseconds)</source>
+ <translation>Ορισμός λήξης χρονικού ορίου (σε χιλιοστά του δευτερολέπτου)</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="28"/>
+ <source>Connect through socks4 proxy</source>
+ <translation>Σύνδεση μέσω διαμεσολαβητή SOCKS4</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="29"/>
+ <source>Allow DNS lookups for addnode and connect</source>
+ <translation>Να επιτρέπονται οι έλεγχοι DNS για προσθήκη και σύνδεση κόμβων</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="30"/>
+ <source>Listen for connections on &lt;port&gt; (default: 8333 or testnet: 18333)</source>
+ <translation>Εισερχόμενες συνδέσεις στη θύρα &lt;port&gt; (προεπιλογή: 8333 ή στο testnet: 18333)</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="31"/>
+ <source>Maintain at most &lt;n&gt; connections to peers (default: 125)</source>
+ <translation>Μέγιστες αριθμός συνδέσεων με τους peers &lt;n&gt; (προεπιλογή: 125)</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="33"/>
+ <source>Connect only to the specified node</source>
+ <translation>Σύνδεση μόνο με ορισμένο κόμβο</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="38"/>
+ <source>Threshold for disconnecting misbehaving peers (default: 100)</source>
+ <translation>Όριο αποσύνδεσης προβληματικών peers (προεπιλογή: 100)</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="39"/>
+ <source>Number of seconds to keep misbehaving peers from reconnecting (default: 86400)</source>
+ <translation>Δευτερόλεπτα πριν επιτραπεί ξανά η σύνδεση των προβληματικών peers (προεπιλογή: 86400)</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="42"/>
+ <source>Maximum per-connection receive buffer, &lt;n&gt;*1000 bytes (default: 10000)</source>
+ <translation>Μέγιστος buffer λήψης ανά σύνδεση, &lt;n&gt;*1000 bytes (προεπιλογή: 10000)</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="43"/>
+ <source>Maximum per-connection send buffer, &lt;n&gt;*1000 bytes (default: 10000)</source>
+ <translation>Μέγιστος buffer αποστολής ανά σύνδεση, &lt;n&gt;*1000 bytes (προεπιλογή: 10000)</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="47"/>
+ <source>Accept command line and JSON-RPC commands</source>
+ <translation>Αποδοχή εντολών κονσόλας και JSON-RPC</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="48"/>
+ <source>Run in the background as a daemon and accept commands</source>
+ <translation>Εκτέλεση στο παρασκήνιο κι αποδοχή εντολών</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="49"/>
+ <source>Use the test network</source>
+ <translation>Χρήση του δοκιμαστικού δικτύου</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="50"/>
+ <source>Output extra debugging information</source>
+ <translation>Έξοδος επιπλέον πληροφοριών εντοπισμού σφαλμάτων</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="51"/>
+ <source>Prepend debug output with timestamp</source>
+ <translation>Χρονοσφραγίδα πληροφοριών εντοπισμού σφαλμάτων</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="52"/>
+ <source>Send trace/debug info to console instead of debug.log file</source>
+ <translation>Αποστολή πληροφοριών εντοπισμού σφαλμάτων στην κονσόλα αντί του αρχείου debug.log</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="53"/>
+ <source>Send trace/debug info to debugger</source>
+ <translation>Αποστολή πληροφοριών εντοπισμού σφαλμάτων στον debugger</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="54"/>
+ <source>Username for JSON-RPC connections</source>
+ <translation>Όνομα χρήστη για τις συνδέσεις JSON-RPC</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="55"/>
+ <source>Password for JSON-RPC connections</source>
+ <translation>Κωδικός για τις συνδέσεις JSON-RPC</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="56"/>
+ <source>Listen for JSON-RPC connections on &lt;port&gt; (default: 8332)</source>
+ <translation>Εισερχόμενες συνδέσεις JSON-RPC στη θύρα &lt;port&gt; (προεπιλογή: 8332)</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="57"/>
+ <source>Allow JSON-RPC connections from specified IP address</source>
+ <translation>Αποδοχή συνδέσεων JSON-RPC από συγκεκριμένη διεύθυνση IP</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="58"/>
+ <source>Send commands to node running on &lt;ip&gt; (default: 127.0.0.1)</source>
+ <translation>Αποστολή εντολών στον κόμβο &lt;ip&gt; (προεπιλογή: 127.0.0.1)</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="59"/>
+ <source>Execute command when the best block changes (%s in cmd is replaced by block hash)</source>
+ <translation>Εκτέλεσε την εντολή όταν το καλύτερο μπλοκ αλλάξει(%s στην εντολή αντικαθίσταται από το hash του μπλοκ)</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="62"/>
+ <source>Upgrade wallet to latest format</source>
+ <translation>Αναβάθμισε το πορτοφόλι στην τελευταία έκδοση</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="63"/>
+ <source>Set key pool size to &lt;n&gt; (default: 100)</source>
+ <translation>Όριο πλήθους κλειδιών pool &lt;n&gt; (προεπιλογή: 100)</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="64"/>
+ <source>Rescan the block chain for missing wallet transactions</source>
+ <translation>Επανέλεγχος της αλυσίδας μπλοκ για απούσες συναλλαγές</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="65"/>
+ <source>How many blocks to check at startup (default: 2500, 0 = all)</source>
+ <translation>Πόσα μπλοκ να ελέγχω κατά την εκκίνηση (προεπιλογή:2500,0=όλα)</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="66"/>
+ <source>How thorough the block verification is (0-6, default: 1)</source>
+ <translation>Πόσο εξονυχιστική να είναι η επιβεβαίωση του μπλοκ(0-6, προεπιλογή:1)</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="67"/>
+ <source>
+SSL options: (see the Bitcoin Wiki for SSL setup instructions)</source>
+ <translation>
+Ρυθμίσεις SSL: (ανατρέξτε στο Bitcoin Wiki για οδηγίες ρυθμίσεων SSL)</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="70"/>
+ <source>Use OpenSSL (https) for JSON-RPC connections</source>
+ <translation>Χρήση του OpenSSL (https) για συνδέσεις JSON-RPC</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="71"/>
+ <source>Server certificate file (default: server.cert)</source>
+ <translation>Αρχείο πιστοποιητικού του διακομιστή (προεπιλογή: server.cert)</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="72"/>
+ <source>Server private key (default: server.pem)</source>
+ <translation>Προσωπικό κλειδί του διακομιστή (προεπιλογή: server.pem)</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="73"/>
+ <source>Acceptable ciphers (default: TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!AH:!3DES:@STRENGTH)</source>
+ <translation>Αποδεκτά κρυπτογραφήματα (προεπιλογή: TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!AH:!3DES:@STRENGTH)</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="76"/>
+ <source>This help message</source>
+ <translation>Αυτό το κείμενο βοήθειας</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="77"/>
+ <source>Usage</source>
+ <translation>Χρήση</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="78"/>
+ <source>Cannot obtain a lock on data directory %s. Bitcoin is probably already running.</source>
+ <translation>Αδυναμία κλειδώματος του φακέλου δεδομένων %s. Πιθανώς το Bitcoin να είναι ήδη ενεργό.</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="81"/>
+ <source>Bitcoin</source>
+ <translation>Bitcoin</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="82"/>
+ <source>Loading addresses...</source>
+ <translation>Φόρτωση διευθύνσεων...</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="83"/>
+ <source>Error loading addr.dat</source>
+ <translation>Σφάλμα φόρτωσης addr.dat</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="85"/>
+ <source>Error loading blkindex.dat</source>
+ <translation>Σφάλμα φόρτωσης blkindex.dat</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="87"/>
+ <source>Error loading wallet.dat: Wallet corrupted</source>
+ <translation>Σφάλμα φόρτωσης wallet.dat: Κατεστραμμένο Πορτοφόλι</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="88"/>
+ <source>Error loading wallet.dat: Wallet requires newer version of Bitcoin</source>
+ <translation>Σφάλμα φόρτωσης wallet.dat: Το Πορτοφόλι απαιτεί μια νεότερη έκδοση του Bitcoin</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="89"/>
+ <source>Wallet needed to be rewritten: restart Bitcoin to complete</source>
+ <translation>Απαιτείται η επανεγγραφή του Πορτοφολιού, η οποία θα ολοκληρωθεί στην επανεκκίνηση του Bitcoin</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="90"/>
+ <source>Error loading wallet.dat</source>
+ <translation>Σφάλμα φόρτωσης αρχείου wallet.dat</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="122"/>
+ <source>Error: Wallet locked, unable to create transaction </source>
+ <translation>Σφάλμα: το πορτοφόλι είναι κλειδωμένο, δεν μπορεί να δημιουργηθεί συναλλαγή</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="123"/>
+ <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>Σφάλμα: Αυτή η συναλλαγή απαιτεί αμοιβή συναλλαγής τουλάχιστον %s λόγω του μεγέθους, πολυπλοκότητας ή της χρήσης πρόσφατης παραλαβής κεφαλαίου</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="126"/>
+ <source>Error: Transaction creation failed </source>
+ <translation>Σφάλμα: Η δημιουργία της συναλλαγής απέτυχε</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="127"/>
+ <source>Sending...</source>
+ <translation>Αποστολή...</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="128"/>
+ <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>Σφάλμα: Η συναλλαγή απορρίφθηκε.
+Αυτό ίσως οφείλεται στο ότι τα νομίσματά σας έχουν ήδη ξοδευτεί, π.χ. με την αντιγραφή του wallet.dat σε άλλο σύστημα και την χρήση τους εκεί, χωρίς η συναλλαγή να έχει καταγραφεί στο παρόν σύστημα.</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="132"/>
+ <source>Invalid amount</source>
+ <translation>Λάθος ποσότητα</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="133"/>
+ <source>Insufficient funds</source>
+ <translation>Ανεπαρκές κεφάλαιο</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="84"/>
+ <source>Loading block index...</source>
+ <translation>Φόρτωση ευρετηρίου μπλοκ...</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="32"/>
+ <source>Add a node to connect to and attempt to keep the connection open</source>
+ <translation>Προσέθεσε ένα κόμβο για σύνδεση και προσπάθησε να κρατήσεις την σύνδεση ανοιχτή</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="34"/>
+ <source>Find peers using internet relay chat (default: 0)</source>
+ <translation>Βρες ομότιμους υπολογιστές χρησιμοποιώντας internet relay chat(Προεπιλογή:0)</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="35"/>
+ <source>Accept connections from outside (default: 1)</source>
+ <translation>Να δέχεσαι συνδέσεις από έξω(προεπιλογή:1)</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="36"/>
+ <source>Set language, for example &quot;de_DE&quot; (default: system locale)</source>
+ <translation>Όρισε γλώσσα, για παράδειγμα &quot;de_DE&quot;(προεπιλογή:τοπικές ρυθμίσεις)</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="37"/>
+ <source>Find peers using DNS lookup (default: 1)</source>
+ <translation>Βρες ομότιμους υπολογιστές χρησιμοποιώντας αναζήτηση DNS(προεπιλογή:1)</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="44"/>
+ <source>Use Universal Plug and Play to map the listening port (default: 1)</source>
+ <translation>Χρησιμοποίησε Universal Plug and Play για την χρήση της πόρτας αναμονής (προεπιλογή:1)</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="45"/>
+ <source>Use Universal Plug and Play to map the listening port (default: 0)</source>
+ <translation>Χρησιμοποίησε Universal Plug and Play για την χρήση της πόρτας αναμονής (προεπιλογή:0)</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="46"/>
+ <source>Fee per KB to add to transactions you send</source>
+ <translation>Αμοιβή ανά KB που θα προστίθεται στις συναλλαγές που στέλνεις</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="86"/>
+ <source>Loading wallet...</source>
+ <translation>Φόρτωση πορτοφολιού...</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="91"/>
+ <source>Cannot downgrade wallet</source>
+ <translation>Δεν μπορώ να υποβαθμίσω το πορτοφόλι</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="92"/>
+ <source>Cannot initialize keypool</source>
+ <translation>Δεν μπορώ αν αρχικοποιήσω την λίστα κλειδιών</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="93"/>
+ <source>Cannot write default address</source>
+ <translation>Δεν μπορώ να γράψω την προεπιλεγμένη διεύθυνση</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="94"/>
+ <source>Rescanning...</source>
+ <translation>Ανίχνευση...</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="95"/>
+ <source>Done loading</source>
+ <translation>Η φόρτωση ολοκληρώθηκε</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="96"/>
+ <source>Invalid -proxy address</source>
+ <translation>Μη έγκυρη διεύθυνση διαμεσολαβητή</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="97"/>
+ <source>Invalid amount for -paytxfee=&lt;amount&gt;</source>
+ <translation>Μη έγκυρο ποσό για την παράμετρο -paytxfee=&lt;amount&gt;</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="98"/>
+ <source>Warning: -paytxfee is set very high. This is the transaction fee you will pay if you send a transaction.</source>
+ <translation>Προειδοποίηση: Η παράμετρος -paytxfee είναι πολύ υψηλή. Πρόκειται για την αμοιβή που θα πληρώνετε για κάθε συναλλαγή που θα στέλνετε.</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="101"/>
+ <source>Error: CreateThread(StartNode) failed</source>
+ <translation>Error: CreateThread(StartNode) failed</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="11"/>
+ <source>Warning: Disk space is low </source>
+ <translation>Προειδοποίηση: Χαμηλός χώρος στο δίσκο </translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="8"/>
+ <source>Unable to bind to port %d on this computer. Bitcoin is probably already running.</source>
+ <translation>Αδύνατη η σύνδεση με τη θύρα %d αυτού του υπολογιστή. Το Bitcoin είναι πιθανώς ήδη ενεργό.</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="102"/>
+ <source>To use the %s option</source>
+ <translation>Χρήση της %s επιλογής</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="103"/>
+ <source>%s, you must set a rpcpassword in the configuration file:
+ %s
+It is recommended you use the following random password:
+rpcuser=bitcoinrpc
+rpcpassword=%s
+(you do not need to remember this password)
+If the file does not exist, create it with owner-readable-only file permissions.
+</source>
+ <translation>%s, πρέπει να βάλεις ένα κωδικό στο αρχείο παραμέτρων: %s
+Προτείνεται να χρησιμοποιήσεις τον παρακάτω τυχαίο κωδικό:
+rpcuser=bitcoinrpc
+rpcpassword=%s
+(δεν χρειάζεται να θυμάσαι αυτόν τον κωδικό)
+Εάν το αρχείο δεν υπάρχει, δημιούργησε το με δικαιώματα μόνο για ανάγνωση από τον δημιουργό.</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="112"/>
+ <source>Error</source>
+ <translation>Σφάλμα</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="113"/>
+ <source>An error occured while setting up the RPC port %i for listening: %s</source>
+ <translation>Ένα σφάλμα συνέβη καθώς προετοιμαζόταν η πόρτα RPC %i για αναμονή:%s </translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="114"/>
+ <source>You must set rpcpassword=&lt;password&gt; in the configuration file:
+%s
+If the file does not exist, create it with owner-readable-only file permissions.</source>
+ <translation>Πρέπει να βάλεις ένα κωδικό στο αρχείο παραμέτρων: %s
+Εάν το αρχείο δεν υπάρχει, δημιούργησε το με δικαιώματα μόνο για ανάγνωση από τον δημιουργό</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="119"/>
+ <source>Warning: Please check that your computer&apos;s date and time are correct. If your clock is wrong Bitcoin will not work properly.</source>
+ <translation>Προειδοποίηση: Παρακαλώ βεβαιωθείτε πως η ημερομηνία κι ώρα του συστήματός σας είναι σωστές. Αν το ρολόι του υπολογιστή σας πάει λάθος, ενδέχεται να μη λειτουργεί σωστά το Bitcoin.</translation>
+ </message>
+</context>
+</TS> \ No newline at end of file
diff --git a/src/qt/locale/bitcoin_en.ts b/src/qt/locale/bitcoin_en.ts
index 53ba23b11c..5628db1229 100644
--- a/src/qt/locale/bitcoin_en.ts
+++ b/src/qt/locale/bitcoin_en.ts
@@ -15,7 +15,7 @@
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../forms/aboutdialog.ui" line="91"/>
+ <location filename="../forms/aboutdialog.ui" line="97"/>
<source>Copyright © 2009-2012 Bitcoin Developers
This is experimental software.
@@ -39,92 +39,82 @@ This product includes software developed by the OpenSSL Project for use in the O
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../forms/addressbookpage.ui" line="33"/>
+ <location filename="../forms/addressbookpage.ui" line="36"/>
<source>Double-click to edit address or label</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../forms/addressbookpage.ui" line="57"/>
+ <location filename="../forms/addressbookpage.ui" line="63"/>
<source>Create a new address</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../forms/addressbookpage.ui" line="60"/>
- <source>&amp;New Address...</source>
+ <location filename="../forms/addressbookpage.ui" line="77"/>
+ <source>Copy the currently selected address to the system clipboard</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../forms/addressbookpage.ui" line="71"/>
- <source>Copy the currently selected address to the system clipboard</source>
+ <location filename="../forms/addressbookpage.ui" line="66"/>
+ <source>&amp;New Address</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../forms/addressbookpage.ui" line="74"/>
- <source>&amp;Copy to Clipboard</source>
+ <location filename="../forms/addressbookpage.ui" line="80"/>
+ <source>&amp;Copy Address</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../forms/addressbookpage.ui" line="85"/>
+ <location filename="../forms/addressbookpage.ui" line="91"/>
<source>Show &amp;QR Code</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../forms/addressbookpage.ui" line="96"/>
+ <location filename="../forms/addressbookpage.ui" line="102"/>
<source>Sign a message to prove you own this address</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../forms/addressbookpage.ui" line="99"/>
+ <location filename="../forms/addressbookpage.ui" line="105"/>
<source>&amp;Sign Message</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../forms/addressbookpage.ui" line="110"/>
+ <location filename="../forms/addressbookpage.ui" line="116"/>
<source>Delete the currently selected address from the list. Only sending addresses can be deleted.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../forms/addressbookpage.ui" line="113"/>
+ <location filename="../forms/addressbookpage.ui" line="119"/>
<source>&amp;Delete</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../addressbookpage.cpp" line="65"/>
- <source>Copy address</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location filename="../addressbookpage.cpp" line="66"/>
- <source>Copy label</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location filename="../addressbookpage.cpp" line="67"/>
- <source>Edit</source>
+ <location filename="../addressbookpage.cpp" line="63"/>
+ <source>Copy &amp;Label</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../addressbookpage.cpp" line="68"/>
- <source>Delete</source>
+ <location filename="../addressbookpage.cpp" line="65"/>
+ <source>&amp;Edit</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../addressbookpage.cpp" line="288"/>
+ <location filename="../addressbookpage.cpp" line="297"/>
<source>Export Address Book Data</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../addressbookpage.cpp" line="289"/>
+ <location filename="../addressbookpage.cpp" line="298"/>
<source>Comma separated file (*.csv)</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../addressbookpage.cpp" line="302"/>
+ <location filename="../addressbookpage.cpp" line="311"/>
<source>Error exporting</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../addressbookpage.cpp" line="302"/>
+ <location filename="../addressbookpage.cpp" line="311"/>
<source>Could not write to file %1.</source>
<translation type="unfinished"></translation>
</message>
@@ -132,17 +122,17 @@ This product includes software developed by the OpenSSL Project for use in the O
<context>
<name>AddressTableModel</name>
<message>
- <location filename="../addresstablemodel.cpp" line="77"/>
+ <location filename="../addresstablemodel.cpp" line="78"/>
<source>Label</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../addresstablemodel.cpp" line="77"/>
+ <location filename="../addresstablemodel.cpp" line="78"/>
<source>Address</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../addresstablemodel.cpp" line="113"/>
+ <location filename="../addresstablemodel.cpp" line="114"/>
<source>(no label)</source>
<translation type="unfinished"></translation>
</message>
@@ -151,136 +141,130 @@ This product includes software developed by the OpenSSL Project for use in the O
<name>AskPassphraseDialog</name>
<message>
<location filename="../forms/askpassphrasedialog.ui" line="26"/>
- <source>Dialog</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location filename="../forms/askpassphrasedialog.ui" line="32"/>
- <location filename="../forms/askpassphrasedialog.ui" line="97"/>
- <source>TextLabel</source>
+ <source>Passphrase Dialog</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../forms/askpassphrasedialog.ui" line="50"/>
+ <location filename="../forms/askpassphrasedialog.ui" line="47"/>
<source>Enter passphrase</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../forms/askpassphrasedialog.ui" line="64"/>
+ <location filename="../forms/askpassphrasedialog.ui" line="61"/>
<source>New passphrase</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../forms/askpassphrasedialog.ui" line="78"/>
+ <location filename="../forms/askpassphrasedialog.ui" line="75"/>
<source>Repeat new passphrase</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../askpassphrasedialog.cpp" line="34"/>
+ <location filename="../askpassphrasedialog.cpp" line="33"/>
<source>Enter the new passphrase to the wallet.&lt;br/&gt;Please use a passphrase of &lt;b&gt;10 or more random characters&lt;/b&gt;, or &lt;b&gt;eight or more words&lt;/b&gt;.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../askpassphrasedialog.cpp" line="35"/>
+ <location filename="../askpassphrasedialog.cpp" line="34"/>
<source>Encrypt wallet</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../askpassphrasedialog.cpp" line="38"/>
+ <location filename="../askpassphrasedialog.cpp" line="37"/>
<source>This operation needs your wallet passphrase to unlock the wallet.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../askpassphrasedialog.cpp" line="43"/>
+ <location filename="../askpassphrasedialog.cpp" line="42"/>
<source>Unlock wallet</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../askpassphrasedialog.cpp" line="46"/>
+ <location filename="../askpassphrasedialog.cpp" line="45"/>
<source>This operation needs your wallet passphrase to decrypt the wallet.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../askpassphrasedialog.cpp" line="51"/>
+ <location filename="../askpassphrasedialog.cpp" line="50"/>
<source>Decrypt wallet</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../askpassphrasedialog.cpp" line="54"/>
+ <location filename="../askpassphrasedialog.cpp" line="53"/>
<source>Change passphrase</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../askpassphrasedialog.cpp" line="55"/>
+ <location filename="../askpassphrasedialog.cpp" line="54"/>
<source>Enter the old and new passphrase to the wallet.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../askpassphrasedialog.cpp" line="101"/>
+ <location filename="../askpassphrasedialog.cpp" line="100"/>
<source>Confirm wallet encryption</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../askpassphrasedialog.cpp" line="102"/>
+ <location filename="../askpassphrasedialog.cpp" line="101"/>
<source>WARNING: If you encrypt your wallet and lose your passphrase, you will &lt;b&gt;LOSE ALL OF YOUR BITCOINS&lt;/b&gt;!
Are you sure you wish to encrypt your wallet?</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../askpassphrasedialog.cpp" line="111"/>
- <location filename="../askpassphrasedialog.cpp" line="160"/>
+ <location filename="../askpassphrasedialog.cpp" line="110"/>
+ <location filename="../askpassphrasedialog.cpp" line="159"/>
<source>Wallet encrypted</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../askpassphrasedialog.cpp" line="112"/>
+ <location filename="../askpassphrasedialog.cpp" line="111"/>
<source>Bitcoin will close now to finish the encryption process. Remember that encrypting your wallet cannot fully protect your bitcoins from being stolen by malware infecting your computer.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../askpassphrasedialog.cpp" line="208"/>
- <location filename="../askpassphrasedialog.cpp" line="232"/>
+ <location filename="../askpassphrasedialog.cpp" line="207"/>
+ <location filename="../askpassphrasedialog.cpp" line="231"/>
<source>Warning: The Caps Lock key is on.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../askpassphrasedialog.cpp" line="117"/>
- <location filename="../askpassphrasedialog.cpp" line="124"/>
- <location filename="../askpassphrasedialog.cpp" line="166"/>
- <location filename="../askpassphrasedialog.cpp" line="172"/>
+ <location filename="../askpassphrasedialog.cpp" line="116"/>
+ <location filename="../askpassphrasedialog.cpp" line="123"/>
+ <location filename="../askpassphrasedialog.cpp" line="165"/>
+ <location filename="../askpassphrasedialog.cpp" line="171"/>
<source>Wallet encryption failed</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../askpassphrasedialog.cpp" line="118"/>
+ <location filename="../askpassphrasedialog.cpp" line="117"/>
<source>Wallet encryption failed due to an internal error. Your wallet was not encrypted.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../askpassphrasedialog.cpp" line="125"/>
- <location filename="../askpassphrasedialog.cpp" line="173"/>
+ <location filename="../askpassphrasedialog.cpp" line="124"/>
+ <location filename="../askpassphrasedialog.cpp" line="172"/>
<source>The supplied passphrases do not match.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../askpassphrasedialog.cpp" line="136"/>
+ <location filename="../askpassphrasedialog.cpp" line="135"/>
<source>Wallet unlock failed</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../askpassphrasedialog.cpp" line="137"/>
- <location filename="../askpassphrasedialog.cpp" line="148"/>
- <location filename="../askpassphrasedialog.cpp" line="167"/>
+ <location filename="../askpassphrasedialog.cpp" line="136"/>
+ <location filename="../askpassphrasedialog.cpp" line="147"/>
+ <location filename="../askpassphrasedialog.cpp" line="166"/>
<source>The passphrase entered for the wallet decryption was incorrect.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../askpassphrasedialog.cpp" line="147"/>
+ <location filename="../askpassphrasedialog.cpp" line="146"/>
<source>Wallet decryption failed</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../askpassphrasedialog.cpp" line="161"/>
+ <location filename="../askpassphrasedialog.cpp" line="160"/>
<source>Wallet passphrase was succesfully changed.</source>
<translation type="unfinished"></translation>
</message>
@@ -288,122 +272,137 @@ Are you sure you wish to encrypt your wallet?</source>
<context>
<name>BitcoinGUI</name>
<message>
- <location filename="../bitcoingui.cpp" line="70"/>
+ <location filename="../bitcoingui.cpp" line="73"/>
<source>Bitcoin Wallet</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../bitcoingui.cpp" line="243"/>
+ <location filename="../bitcoingui.cpp" line="215"/>
+ <source>Sign &amp;message...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="248"/>
<source>Show/Hide &amp;Bitcoin</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../bitcoingui.cpp" line="499"/>
+ <location filename="../bitcoingui.cpp" line="517"/>
<source>Synchronizing with network...</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../bitcoingui.cpp" line="180"/>
+ <location filename="../bitcoingui.cpp" line="185"/>
<source>&amp;Overview</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../bitcoingui.cpp" line="181"/>
+ <location filename="../bitcoingui.cpp" line="186"/>
<source>Show general overview of wallet</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../bitcoingui.cpp" line="186"/>
+ <location filename="../bitcoingui.cpp" line="191"/>
<source>&amp;Transactions</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../bitcoingui.cpp" line="187"/>
+ <location filename="../bitcoingui.cpp" line="192"/>
<source>Browse transaction history</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../bitcoingui.cpp" line="192"/>
+ <location filename="../bitcoingui.cpp" line="197"/>
<source>&amp;Address Book</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../bitcoingui.cpp" line="193"/>
+ <location filename="../bitcoingui.cpp" line="198"/>
<source>Edit the list of stored addresses and labels</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../bitcoingui.cpp" line="198"/>
+ <location filename="../bitcoingui.cpp" line="203"/>
<source>&amp;Receive coins</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../bitcoingui.cpp" line="199"/>
+ <location filename="../bitcoingui.cpp" line="204"/>
<source>Show the list of addresses for receiving payments</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../bitcoingui.cpp" line="204"/>
+ <location filename="../bitcoingui.cpp" line="209"/>
<source>&amp;Send coins</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../bitcoingui.cpp" line="205"/>
- <source>Send coins to a bitcoin address</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<location filename="../bitcoingui.cpp" line="210"/>
- <source>Sign &amp;message</source>
+ <source>Send coins to a bitcoin address</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../bitcoingui.cpp" line="211"/>
+ <location filename="../bitcoingui.cpp" line="216"/>
<source>Prove you control an address</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../bitcoingui.cpp" line="230"/>
+ <location filename="../bitcoingui.cpp" line="235"/>
<source>E&amp;xit</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../bitcoingui.cpp" line="231"/>
+ <location filename="../bitcoingui.cpp" line="236"/>
<source>Quit application</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../bitcoingui.cpp" line="234"/>
+ <location filename="../bitcoingui.cpp" line="239"/>
<source>&amp;About %1</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../bitcoingui.cpp" line="235"/>
+ <location filename="../bitcoingui.cpp" line="240"/>
<source>Show information about Bitcoin</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../bitcoingui.cpp" line="237"/>
+ <location filename="../bitcoingui.cpp" line="242"/>
<source>About &amp;Qt</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../bitcoingui.cpp" line="238"/>
+ <location filename="../bitcoingui.cpp" line="243"/>
<source>Show information about Qt</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../bitcoingui.cpp" line="240"/>
+ <location filename="../bitcoingui.cpp" line="245"/>
<source>&amp;Options...</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../bitcoingui.cpp" line="241"/>
+ <location filename="../bitcoingui.cpp" line="246"/>
<source>Modify configuration options for bitcoin</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="252"/>
+ <source>&amp;Encrypt Wallet...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="255"/>
+ <source>&amp;Backup Wallet...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="257"/>
+ <source>&amp;Change Passphrase...</source>
+ <translation type="unfinished"></translation>
+ </message>
<message numerus="yes">
- <location filename="../bitcoingui.cpp" line="501"/>
+ <location filename="../bitcoingui.cpp" line="519"/>
<source>~%n block(s) remaining</source>
<translation>
<numerusform>~%n block remaining</numerusform>
@@ -411,97 +410,104 @@ Are you sure you wish to encrypt your wallet?</source>
</translation>
</message>
<message>
- <location filename="../bitcoingui.cpp" line="512"/>
+ <location filename="../bitcoingui.cpp" line="530"/>
<source>Downloaded %1 of %2 blocks of transaction history (%3% done).</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../bitcoingui.cpp" line="245"/>
+ <location filename="../bitcoingui.cpp" line="250"/>
<source>&amp;Export...</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../bitcoingui.cpp" line="244"/>
+ <location filename="../bitcoingui.cpp" line="249"/>
<source>Show or hide the Bitcoin window</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../bitcoingui.cpp" line="246"/>
+ <location filename="../bitcoingui.cpp" line="251"/>
<source>Export the data in the current tab to a file</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../bitcoingui.cpp" line="247"/>
- <source>&amp;Encrypt Wallet</source>
+ <location filename="../bitcoingui.cpp" line="253"/>
+ <source>Encrypt or decrypt wallet</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../bitcoingui.cpp" line="248"/>
- <source>Encrypt or decrypt wallet</source>
+ <location filename="../bitcoingui.cpp" line="256"/>
+ <source>Backup wallet to another location</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../bitcoingui.cpp" line="250"/>
- <source>&amp;Backup Wallet</source>
+ <location filename="../bitcoingui.cpp" line="258"/>
+ <source>Change the passphrase used for wallet encryption</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../bitcoingui.cpp" line="251"/>
- <source>Backup wallet to another location</source>
+ <location filename="../bitcoingui.cpp" line="259"/>
+ <source>&amp;Debug window</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../bitcoingui.cpp" line="252"/>
- <source>&amp;Change Passphrase</source>
+ <location filename="../bitcoingui.cpp" line="260"/>
+ <source>Open debugging and diagnostic console</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../bitcoingui.cpp" line="253"/>
- <source>Change the passphrase used for wallet encryption</source>
+ <location filename="../bitcoingui.cpp" line="261"/>
+ <source>&amp;Verify message...</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="262"/>
+ <source>Verify a message signature</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../bitcoingui.cpp" line="276"/>
+ <location filename="../bitcoingui.cpp" line="286"/>
<source>&amp;File</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../bitcoingui.cpp" line="285"/>
+ <location filename="../bitcoingui.cpp" line="296"/>
<source>&amp;Settings</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../bitcoingui.cpp" line="291"/>
+ <location filename="../bitcoingui.cpp" line="302"/>
<source>&amp;Help</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../bitcoingui.cpp" line="298"/>
+ <location filename="../bitcoingui.cpp" line="311"/>
<source>Tabs toolbar</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../bitcoingui.cpp" line="309"/>
+ <location filename="../bitcoingui.cpp" line="322"/>
<source>Actions toolbar</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../bitcoingui.cpp" line="321"/>
+ <location filename="../bitcoingui.cpp" line="334"/>
+ <location filename="../bitcoingui.cpp" line="343"/>
<source>[testnet]</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../bitcoingui.cpp" line="383"/>
+ <location filename="../bitcoingui.cpp" line="343"/>
+ <location filename="../bitcoingui.cpp" line="399"/>
<source>Bitcoin client</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../bitcoingui.cpp" line="411"/>
+ <location filename="../bitcoingui.cpp" line="429"/>
<source>bitcoin-qt</source>
<translation type="unfinished"></translation>
</message>
<message numerus="yes">
- <location filename="../bitcoingui.cpp" line="475"/>
+ <location filename="../bitcoingui.cpp" line="493"/>
<source>%n active connection(s) to Bitcoin network</source>
<translation>
<numerusform>%n active connection to Bitcoin network</numerusform>
@@ -509,12 +515,12 @@ Are you sure you wish to encrypt your wallet?</source>
</translation>
</message>
<message>
- <location filename="../bitcoingui.cpp" line="524"/>
+ <location filename="../bitcoingui.cpp" line="542"/>
<source>Downloaded %1 blocks of transaction history.</source>
<translation type="unfinished"></translation>
</message>
<message numerus="yes">
- <location filename="../bitcoingui.cpp" line="539"/>
+ <location filename="../bitcoingui.cpp" line="557"/>
<source>%n second(s) ago</source>
<translation>
<numerusform>%n second ago</numerusform>
@@ -522,7 +528,7 @@ Are you sure you wish to encrypt your wallet?</source>
</translation>
</message>
<message numerus="yes">
- <location filename="../bitcoingui.cpp" line="543"/>
+ <location filename="../bitcoingui.cpp" line="561"/>
<source>%n minute(s) ago</source>
<translation>
<numerusform>%n minute ago</numerusform>
@@ -530,7 +536,7 @@ Are you sure you wish to encrypt your wallet?</source>
</translation>
</message>
<message numerus="yes">
- <location filename="../bitcoingui.cpp" line="547"/>
+ <location filename="../bitcoingui.cpp" line="565"/>
<source>%n hour(s) ago</source>
<translation>
<numerusform>%n hour ago</numerusform>
@@ -538,7 +544,7 @@ Are you sure you wish to encrypt your wallet?</source>
</translation>
</message>
<message numerus="yes">
- <location filename="../bitcoingui.cpp" line="551"/>
+ <location filename="../bitcoingui.cpp" line="569"/>
<source>%n day(s) ago</source>
<translation>
<numerusform>%n day ago</numerusform>
@@ -546,42 +552,42 @@ Are you sure you wish to encrypt your wallet?</source>
</translation>
</message>
<message>
- <location filename="../bitcoingui.cpp" line="557"/>
+ <location filename="../bitcoingui.cpp" line="575"/>
<source>Up to date</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../bitcoingui.cpp" line="562"/>
+ <location filename="../bitcoingui.cpp" line="580"/>
<source>Catching up...</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../bitcoingui.cpp" line="570"/>
+ <location filename="../bitcoingui.cpp" line="588"/>
<source>Last received block was generated %1.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../bitcoingui.cpp" line="626"/>
+ <location filename="../bitcoingui.cpp" line="647"/>
<source>This transaction is over the size limit. You can still send it for a fee of %1, which goes to the nodes that process your transaction and helps to support the network. Do you want to pay the fee?</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../bitcoingui.cpp" line="631"/>
- <source>Sending...</source>
+ <location filename="../bitcoingui.cpp" line="652"/>
+ <source>Confirm transaction fee</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../bitcoingui.cpp" line="658"/>
+ <location filename="../bitcoingui.cpp" line="679"/>
<source>Sent transaction</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../bitcoingui.cpp" line="659"/>
+ <location filename="../bitcoingui.cpp" line="680"/>
<source>Incoming transaction</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../bitcoingui.cpp" line="660"/>
+ <location filename="../bitcoingui.cpp" line="681"/>
<source>Date: %1
Amount: %2
Type: %3
@@ -590,51 +596,91 @@ Address: %4
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../bitcoingui.cpp" line="785"/>
+ <location filename="../bitcoingui.cpp" line="802"/>
<source>Wallet is &lt;b&gt;encrypted&lt;/b&gt; and currently &lt;b&gt;unlocked&lt;/b&gt;</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../bitcoingui.cpp" line="793"/>
+ <location filename="../bitcoingui.cpp" line="810"/>
<source>Wallet is &lt;b&gt;encrypted&lt;/b&gt; and currently &lt;b&gt;locked&lt;/b&gt;</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../bitcoingui.cpp" line="816"/>
+ <location filename="../bitcoingui.cpp" line="833"/>
<source>Backup Wallet</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../bitcoingui.cpp" line="816"/>
+ <location filename="../bitcoingui.cpp" line="833"/>
<source>Wallet Data (*.dat)</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../bitcoingui.cpp" line="819"/>
+ <location filename="../bitcoingui.cpp" line="836"/>
<source>Backup Failed</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../bitcoingui.cpp" line="819"/>
+ <location filename="../bitcoingui.cpp" line="836"/>
<source>There was an error trying to save the wallet data to the new location.</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <location filename="../bitcoin.cpp" line="128"/>
+ <source>A fatal error occured. Bitcoin can no longer continue safely and will quit.</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>DisplayOptionsPage</name>
<message>
- <location filename="../optionsdialog.cpp" line="268"/>
+ <location filename="../optionsdialog.cpp" line="246"/>
+ <source>Display</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../optionsdialog.cpp" line="252"/>
+ <source>User Interface &amp;Language: </source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../optionsdialog.cpp" line="257"/>
+ <source>default</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../optionsdialog.cpp" line="263"/>
+ <source>The user interface language can be set here. This setting will only take effect after restarting Bitcoin.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../optionsdialog.cpp" line="273"/>
<source>&amp;Unit to show amounts in: </source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../optionsdialog.cpp" line="272"/>
+ <location filename="../optionsdialog.cpp" line="277"/>
<source>Choose the default subdivision unit to show in the interface, and when sending coins</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../optionsdialog.cpp" line="279"/>
- <source>Display addresses in transaction list</source>
+ <location filename="../optionsdialog.cpp" line="284"/>
+ <source>&amp;Display addresses in transaction list</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../optionsdialog.cpp" line="285"/>
+ <source>Whether to show Bitcoin addresses in the transaction list</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../optionsdialog.cpp" line="303"/>
+ <source>Warning</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../optionsdialog.cpp" line="303"/>
+ <source>This setting will take effect after restarting Bitcoin.</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -707,90 +753,79 @@ Address: %4
</message>
</context>
<context>
- <name>MainOptionsPage</name>
- <message>
- <location filename="../optionsdialog.cpp" line="170"/>
- <source>&amp;Start Bitcoin on window system startup</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location filename="../optionsdialog.cpp" line="171"/>
- <source>Automatically start Bitcoin after the computer is turned on</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location filename="../optionsdialog.cpp" line="175"/>
- <source>&amp;Minimize to the tray instead of the taskbar</source>
- <translation type="unfinished"></translation>
- </message>
+ <name>HelpMessageBox</name>
<message>
- <location filename="../optionsdialog.cpp" line="176"/>
- <source>Show only a tray icon after minimizing the window</source>
+ <location filename="../bitcoin.cpp" line="149"/>
+ <location filename="../bitcoin.cpp" line="159"/>
+ <source>Bitcoin-Qt</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../optionsdialog.cpp" line="184"/>
- <source>Map port using &amp;UPnP</source>
+ <location filename="../bitcoin.cpp" line="149"/>
+ <source>version</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../optionsdialog.cpp" line="185"/>
- <source>Automatically open the Bitcoin client port on the router. This only works when your router supports UPnP and it is enabled.</source>
+ <location filename="../bitcoin.cpp" line="151"/>
+ <source>Usage:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../optionsdialog.cpp" line="179"/>
- <source>M&amp;inimize on close</source>
+ <location filename="../bitcoin.cpp" line="154"/>
+ <source>UI options</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../optionsdialog.cpp" line="180"/>
- <source>Minimize instead of exit the application when the window is closed. When this option is enabled, the application will be closed only after selecting Quit in the menu.</source>
+ <location filename="../bitcoin.cpp" line="155"/>
+ <source>Set language, for example &quot;de_DE&quot; (default: system locale)</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../optionsdialog.cpp" line="188"/>
- <source>&amp;Connect through SOCKS4 proxy:</source>
+ <location filename="../bitcoin.cpp" line="156"/>
+ <source>Start minimized</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../optionsdialog.cpp" line="189"/>
- <source>Connect to the Bitcon network through a SOCKS4 proxy (e.g. when connecting through Tor)</source>
+ <location filename="../bitcoin.cpp" line="157"/>
+ <source>Show splash screen on startup (default: 1)</source>
<translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>MainOptionsPage</name>
<message>
- <location filename="../optionsdialog.cpp" line="194"/>
- <source>Proxy &amp;IP: </source>
+ <location filename="../optionsdialog.cpp" line="227"/>
+ <source>Detach block and address databases at shutdown. This means they can be moved to another data directory, but it slows down shutdown. The wallet is always detached.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../optionsdialog.cpp" line="200"/>
- <source>IP address of the proxy (e.g. 127.0.0.1)</source>
+ <location filename="../optionsdialog.cpp" line="212"/>
+ <source>Pay transaction &amp;fee</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../optionsdialog.cpp" line="203"/>
- <source>&amp;Port: </source>
+ <location filename="../optionsdialog.cpp" line="204"/>
+ <source>Main</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../optionsdialog.cpp" line="209"/>
- <source>Port of the proxy (e.g. 1234)</source>
+ <location filename="../optionsdialog.cpp" line="206"/>
+ <source>Optional transaction fee per kB that helps make sure your transactions are processed quickly. Most transactions are 1 kB. Fee 0.01 recommended.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../optionsdialog.cpp" line="215"/>
- <source>Optional transaction fee per kB that helps make sure your transactions are processed quickly. Most transactions are 1 kB. Fee 0.01 recommended.</source>
+ <location filename="../optionsdialog.cpp" line="222"/>
+ <source>&amp;Start Bitcoin on system login</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../optionsdialog.cpp" line="221"/>
- <source>Pay transaction &amp;fee</source>
+ <location filename="../optionsdialog.cpp" line="223"/>
+ <source>Automatically start Bitcoin after logging in to the system</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../optionsdialog.cpp" line="224"/>
- <source>Optional transaction fee per kB that helps make sure your transactions are processed quickly. Most transactions are 1 kB. Fee 0.01 recommended.</source>
+ <location filename="../optionsdialog.cpp" line="226"/>
+ <source>&amp;Detach databases at shutdown</source>
<translation type="unfinished"></translation>
</message>
</context>
@@ -798,7 +833,7 @@ Address: %4
<name>MessagePage</name>
<message>
<location filename="../forms/messagepage.ui" line="14"/>
- <source>Message</source>
+ <source>Sign Message Dialog</source>
<translation type="unfinished"></translation>
</message>
<message>
@@ -837,67 +872,120 @@ Address: %4
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../forms/messagepage.ui" line="105"/>
- <source>Click &quot;Sign Message&quot; to get signature</source>
+ <location filename="../forms/messagepage.ui" line="128"/>
+ <source>Copy the current signature to the system clipboard</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../forms/messagepage.ui" line="117"/>
- <source>Sign a message to prove you own this address</source>
+ <location filename="../forms/messagepage.ui" line="131"/>
+ <source>&amp;Copy Signature</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../forms/messagepage.ui" line="120"/>
- <source>&amp;Sign Message</source>
+ <location filename="../forms/messagepage.ui" line="142"/>
+ <source>Reset all sign message fields</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../forms/messagepage.ui" line="131"/>
- <source>Copy the currently selected address to the system clipboard</source>
+ <location filename="../forms/messagepage.ui" line="145"/>
+ <source>Clear &amp;All</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../messagepage.cpp" line="30"/>
+ <source>Click &quot;Sign Message&quot; to get signature</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../forms/messagepage.ui" line="114"/>
+ <source>Sign a message to prove you own this address</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../forms/messagepage.ui" line="117"/>
+ <source>&amp;Sign Message</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../forms/messagepage.ui" line="134"/>
- <source>&amp;Copy to Clipboard</source>
+ <location filename="../messagepage.cpp" line="29"/>
+ <source>Enter a Bitcoin address (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L)</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../messagepage.cpp" line="74"/>
- <location filename="../messagepage.cpp" line="89"/>
- <location filename="../messagepage.cpp" line="101"/>
+ <location filename="../messagepage.cpp" line="82"/>
+ <location filename="../messagepage.cpp" line="97"/>
+ <location filename="../messagepage.cpp" line="109"/>
<source>Error signing</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../messagepage.cpp" line="74"/>
+ <location filename="../messagepage.cpp" line="82"/>
<source>%1 is not a valid address.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../messagepage.cpp" line="89"/>
+ <location filename="../messagepage.cpp" line="97"/>
<source>Private key for %1 is not available.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../messagepage.cpp" line="101"/>
+ <location filename="../messagepage.cpp" line="109"/>
<source>Sign failed</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
- <name>OptionsDialog</name>
+ <name>NetworkOptionsPage</name>
<message>
- <location filename="../optionsdialog.cpp" line="79"/>
- <source>Main</source>
+ <location filename="../optionsdialog.cpp" line="345"/>
+ <source>Network</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../optionsdialog.cpp" line="84"/>
- <source>Display</source>
+ <location filename="../optionsdialog.cpp" line="347"/>
+ <source>Map port using &amp;UPnP</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../optionsdialog.cpp" line="348"/>
+ <source>Automatically open the Bitcoin client port on the router. This only works when your router supports UPnP and it is enabled.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../optionsdialog.cpp" line="351"/>
+ <source>&amp;Connect through SOCKS4 proxy:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../optionsdialog.cpp" line="352"/>
+ <source>Connect to the Bitcon network through a SOCKS4 proxy (e.g. when connecting through Tor)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../optionsdialog.cpp" line="357"/>
+ <source>Proxy &amp;IP: </source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../optionsdialog.cpp" line="104"/>
+ <location filename="../optionsdialog.cpp" line="363"/>
+ <source>IP address of the proxy (e.g. 127.0.0.1)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../optionsdialog.cpp" line="366"/>
+ <source>&amp;Port: </source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../optionsdialog.cpp" line="372"/>
+ <source>Port of the proxy (e.g. 1234)</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>OptionsDialog</name>
+ <message>
+ <location filename="../optionsdialog.cpp" line="135"/>
<source>Options</source>
<translation type="unfinished"></translation>
</message>
@@ -915,56 +1003,42 @@ Address: %4
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../forms/overviewpage.ui" line="47"/>
- <source>123.456 BTC</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location filename="../forms/overviewpage.ui" line="54"/>
+ <location filename="../forms/overviewpage.ui" line="69"/>
<source>Number of transactions:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../forms/overviewpage.ui" line="61"/>
+ <location filename="../forms/overviewpage.ui" line="79"/>
<source>0</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../forms/overviewpage.ui" line="68"/>
+ <location filename="../forms/overviewpage.ui" line="86"/>
<source>Unconfirmed:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../forms/overviewpage.ui" line="75"/>
- <source>0 BTC</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location filename="../forms/overviewpage.ui" line="82"/>
- <source>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
-&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
-p, li { white-space: pre-wrap; }
-&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:&apos;Ubuntu&apos;; font-size:11pt; font-weight:400; font-style:normal;&quot;&gt;
-&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;Wallet&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <location filename="../forms/overviewpage.ui" line="122"/>
+ <source>Wallet</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../forms/overviewpage.ui" line="122"/>
+ <location filename="../forms/overviewpage.ui" line="158"/>
<source>&lt;b&gt;Recent transactions&lt;/b&gt;</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../overviewpage.cpp" line="103"/>
+ <location filename="../forms/overviewpage.ui" line="56"/>
<source>Your current balance</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../overviewpage.cpp" line="108"/>
+ <location filename="../forms/overviewpage.ui" line="102"/>
<source>Total of transactions that have yet to be confirmed, and do not yet count toward the current balance</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../overviewpage.cpp" line="111"/>
+ <location filename="../forms/overviewpage.ui" line="76"/>
<source>Total number of transactions in wallet</source>
<translation type="unfinished"></translation>
</message>
@@ -973,7 +1047,7 @@ p, li { white-space: pre-wrap; }
<name>QRCodeDialog</name>
<message>
<location filename="../forms/qrcodedialog.ui" line="14"/>
- <source>Dialog</source>
+ <source>QR Code Dialog</source>
<translation type="unfinished"></translation>
</message>
<message>
@@ -1012,22 +1086,143 @@ p, li { white-space: pre-wrap; }
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../qrcodedialog.cpp" line="59"/>
+ <location filename="../qrcodedialog.cpp" line="45"/>
+ <source>Error encoding URI into QR Code.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../qrcodedialog.cpp" line="63"/>
<source>Resulting URI too long, try to reduce the text for label / message.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../qrcodedialog.cpp" line="116"/>
- <source>Save Image...</source>
+ <location filename="../qrcodedialog.cpp" line="120"/>
+ <source>Save QR Code</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../qrcodedialog.cpp" line="116"/>
+ <location filename="../qrcodedialog.cpp" line="120"/>
<source>PNG Images (*.png)</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
+ <name>RPCConsole</name>
+ <message>
+ <location filename="../forms/rpcconsole.ui" line="14"/>
+ <source>Bitcoin debug window</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../forms/rpcconsole.ui" line="46"/>
+ <source>Client name</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../forms/rpcconsole.ui" line="56"/>
+ <location filename="../forms/rpcconsole.ui" line="79"/>
+ <location filename="../forms/rpcconsole.ui" line="102"/>
+ <location filename="../forms/rpcconsole.ui" line="125"/>
+ <location filename="../forms/rpcconsole.ui" line="161"/>
+ <location filename="../forms/rpcconsole.ui" line="214"/>
+ <location filename="../forms/rpcconsole.ui" line="237"/>
+ <location filename="../forms/rpcconsole.ui" line="260"/>
+ <location filename="../rpcconsole.cpp" line="242"/>
+ <source>N/A</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../forms/rpcconsole.ui" line="69"/>
+ <source>Client version</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../forms/rpcconsole.ui" line="24"/>
+ <source>&amp;Information</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../forms/rpcconsole.ui" line="39"/>
+ <source>Client</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../forms/rpcconsole.ui" line="115"/>
+ <source>Startup time</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../forms/rpcconsole.ui" line="144"/>
+ <source>Network</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../forms/rpcconsole.ui" line="151"/>
+ <source>Number of connections</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../forms/rpcconsole.ui" line="174"/>
+ <source>On testnet</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../forms/rpcconsole.ui" line="197"/>
+ <source>Block chain</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../forms/rpcconsole.ui" line="204"/>
+ <source>Current number of blocks</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../forms/rpcconsole.ui" line="227"/>
+ <source>Estimated total blocks</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../forms/rpcconsole.ui" line="250"/>
+ <source>Last block time</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../forms/rpcconsole.ui" line="292"/>
+ <source>Debug logfile</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../forms/rpcconsole.ui" line="299"/>
+ <source>Open the Bitcoin debug logfile from the current data directory. This can take a few seconds for large logfiles.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../forms/rpcconsole.ui" line="302"/>
+ <source>&amp;Open</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../forms/rpcconsole.ui" line="323"/>
+ <source>&amp;Console</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../forms/rpcconsole.ui" line="92"/>
+ <source>Build date</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../forms/rpcconsole.ui" line="372"/>
+ <source>Clear console</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../rpcconsole.cpp" line="210"/>
+ <source>Welcome to the Bitcoin RPC console.&lt;br&gt;Use up and down arrows to navigate history, and &lt;b&gt;Ctrl-L&lt;/b&gt; to clear screen.&lt;br&gt;Type &lt;b&gt;help&lt;/b&gt; for an overview of available commands.</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>SendCoinsDialog</name>
<message>
<location filename="../forms/sendcoinsdialog.ui" line="14"/>
@@ -1048,7 +1243,7 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<location filename="../forms/sendcoinsdialog.ui" line="67"/>
- <source>&amp;Add recipient...</source>
+ <source>&amp;Add Recipient</source>
<translation type="unfinished"></translation>
</message>
<message>
@@ -1058,7 +1253,7 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<location filename="../forms/sendcoinsdialog.ui" line="87"/>
- <source>Clear all</source>
+ <source>Clear &amp;All</source>
<translation type="unfinished"></translation>
</message>
<message>
@@ -1113,27 +1308,27 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<location filename="../sendcoinsdialog.cpp" line="133"/>
- <source>Amount exceeds your balance</source>
+ <source>The amount exceeds your balance.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../sendcoinsdialog.cpp" line="138"/>
- <source>Total exceeds your balance when the %1 transaction fee is included</source>
+ <source>The total exceeds your balance when the %1 transaction fee is included.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../sendcoinsdialog.cpp" line="144"/>
- <source>Duplicate address found, can only send to each address once in one send operation</source>
+ <source>Duplicate address found, can only send to each address once per send operation.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../sendcoinsdialog.cpp" line="149"/>
- <source>Error: Transaction creation failed </source>
+ <source>Error: Transaction creation failed.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../sendcoinsdialog.cpp" line="154"/>
- <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>
+ <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>
</message>
</context>
@@ -1156,7 +1351,7 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<location filename="../forms/sendcoinsentry.ui" line="66"/>
- <location filename="../sendcoinsentry.cpp" line="26"/>
+ <location filename="../sendcoinsentry.cpp" line="25"/>
<source>Enter a label for this address to add it to your address book</source>
<translation type="unfinished"></translation>
</message>
@@ -1196,7 +1391,7 @@ p, li { white-space: pre-wrap; }
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../sendcoinsentry.cpp" line="25"/>
+ <location filename="../sendcoinsentry.cpp" line="26"/>
<source>Enter a Bitcoin address (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L)</source>
<translation type="unfinished"></translation>
</message>
@@ -1204,140 +1399,140 @@ p, li { white-space: pre-wrap; }
<context>
<name>TransactionDesc</name>
<message>
- <location filename="../transactiondesc.cpp" line="18"/>
+ <location filename="../transactiondesc.cpp" line="20"/>
<source>Open for %1 blocks</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../transactiondesc.cpp" line="20"/>
+ <location filename="../transactiondesc.cpp" line="22"/>
<source>Open until %1</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../transactiondesc.cpp" line="26"/>
+ <location filename="../transactiondesc.cpp" line="28"/>
<source>%1/offline?</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../transactiondesc.cpp" line="28"/>
+ <location filename="../transactiondesc.cpp" line="30"/>
<source>%1/unconfirmed</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../transactiondesc.cpp" line="30"/>
+ <location filename="../transactiondesc.cpp" line="32"/>
<source>%1 confirmations</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../transactiondesc.cpp" line="48"/>
+ <location filename="../transactiondesc.cpp" line="50"/>
<source>&lt;b&gt;Status:&lt;/b&gt; </source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../transactiondesc.cpp" line="53"/>
+ <location filename="../transactiondesc.cpp" line="55"/>
<source>, has not been successfully broadcast yet</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../transactiondesc.cpp" line="55"/>
+ <location filename="../transactiondesc.cpp" line="57"/>
<source>, broadcast through %1 node</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../transactiondesc.cpp" line="57"/>
+ <location filename="../transactiondesc.cpp" line="59"/>
<source>, broadcast through %1 nodes</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../transactiondesc.cpp" line="61"/>
+ <location filename="../transactiondesc.cpp" line="63"/>
<source>&lt;b&gt;Date:&lt;/b&gt; </source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../transactiondesc.cpp" line="68"/>
+ <location filename="../transactiondesc.cpp" line="70"/>
<source>&lt;b&gt;Source:&lt;/b&gt; Generated&lt;br&gt;</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../transactiondesc.cpp" line="74"/>
- <location filename="../transactiondesc.cpp" line="91"/>
+ <location filename="../transactiondesc.cpp" line="76"/>
+ <location filename="../transactiondesc.cpp" line="93"/>
<source>&lt;b&gt;From:&lt;/b&gt; </source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../transactiondesc.cpp" line="91"/>
+ <location filename="../transactiondesc.cpp" line="93"/>
<source>unknown</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../transactiondesc.cpp" line="92"/>
- <location filename="../transactiondesc.cpp" line="115"/>
- <location filename="../transactiondesc.cpp" line="174"/>
+ <location filename="../transactiondesc.cpp" line="94"/>
+ <location filename="../transactiondesc.cpp" line="117"/>
+ <location filename="../transactiondesc.cpp" line="176"/>
<source>&lt;b&gt;To:&lt;/b&gt; </source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../transactiondesc.cpp" line="95"/>
+ <location filename="../transactiondesc.cpp" line="97"/>
<source> (yours, label: </source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../transactiondesc.cpp" line="97"/>
+ <location filename="../transactiondesc.cpp" line="99"/>
<source> (yours)</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../transactiondesc.cpp" line="132"/>
- <location filename="../transactiondesc.cpp" line="146"/>
- <location filename="../transactiondesc.cpp" line="191"/>
- <location filename="../transactiondesc.cpp" line="208"/>
+ <location filename="../transactiondesc.cpp" line="134"/>
+ <location filename="../transactiondesc.cpp" line="148"/>
+ <location filename="../transactiondesc.cpp" line="193"/>
+ <location filename="../transactiondesc.cpp" line="210"/>
<source>&lt;b&gt;Credit:&lt;/b&gt; </source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../transactiondesc.cpp" line="134"/>
+ <location filename="../transactiondesc.cpp" line="136"/>
<source>(%1 matures in %2 more blocks)</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../transactiondesc.cpp" line="138"/>
+ <location filename="../transactiondesc.cpp" line="140"/>
<source>(not accepted)</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../transactiondesc.cpp" line="182"/>
- <location filename="../transactiondesc.cpp" line="190"/>
- <location filename="../transactiondesc.cpp" line="205"/>
+ <location filename="../transactiondesc.cpp" line="184"/>
+ <location filename="../transactiondesc.cpp" line="192"/>
+ <location filename="../transactiondesc.cpp" line="207"/>
<source>&lt;b&gt;Debit:&lt;/b&gt; </source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../transactiondesc.cpp" line="196"/>
+ <location filename="../transactiondesc.cpp" line="198"/>
<source>&lt;b&gt;Transaction fee:&lt;/b&gt; </source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../transactiondesc.cpp" line="212"/>
+ <location filename="../transactiondesc.cpp" line="214"/>
<source>&lt;b&gt;Net amount:&lt;/b&gt; </source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../transactiondesc.cpp" line="218"/>
+ <location filename="../transactiondesc.cpp" line="220"/>
<source>Message:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../transactiondesc.cpp" line="220"/>
+ <location filename="../transactiondesc.cpp" line="222"/>
<source>Comment:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../transactiondesc.cpp" line="222"/>
+ <location filename="../transactiondesc.cpp" line="224"/>
<source>Transaction ID:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../transactiondesc.cpp" line="225"/>
+ <location filename="../transactiondesc.cpp" line="227"/>
<source>Generated coins must wait 120 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, it will change to &quot;not accepted&quot; and not be spendable. This may occasionally happen if another node generates a block within a few seconds of yours.</source>
<translation type="unfinished"></translation>
</message>
@@ -1358,27 +1553,27 @@ p, li { white-space: pre-wrap; }
<context>
<name>TransactionTableModel</name>
<message>
- <location filename="../transactiontablemodel.cpp" line="213"/>
+ <location filename="../transactiontablemodel.cpp" line="214"/>
<source>Date</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../transactiontablemodel.cpp" line="213"/>
+ <location filename="../transactiontablemodel.cpp" line="214"/>
<source>Type</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../transactiontablemodel.cpp" line="213"/>
+ <location filename="../transactiontablemodel.cpp" line="214"/>
<source>Address</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../transactiontablemodel.cpp" line="213"/>
+ <location filename="../transactiontablemodel.cpp" line="214"/>
<source>Amount</source>
<translation type="unfinished"></translation>
</message>
<message numerus="yes">
- <location filename="../transactiontablemodel.cpp" line="274"/>
+ <location filename="../transactiontablemodel.cpp" line="275"/>
<source>Open for %n block(s)</source>
<translation>
<numerusform>Open for %n block</numerusform>
@@ -1386,27 +1581,27 @@ p, li { white-space: pre-wrap; }
</translation>
</message>
<message>
- <location filename="../transactiontablemodel.cpp" line="277"/>
+ <location filename="../transactiontablemodel.cpp" line="278"/>
<source>Open until %1</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../transactiontablemodel.cpp" line="280"/>
+ <location filename="../transactiontablemodel.cpp" line="281"/>
<source>Offline (%1 confirmations)</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../transactiontablemodel.cpp" line="283"/>
+ <location filename="../transactiontablemodel.cpp" line="284"/>
<source>Unconfirmed (%1 of %2 confirmations)</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../transactiontablemodel.cpp" line="286"/>
+ <location filename="../transactiontablemodel.cpp" line="287"/>
<source>Confirmed (%1 confirmations)</source>
<translation type="unfinished"></translation>
</message>
<message numerus="yes">
- <location filename="../transactiontablemodel.cpp" line="294"/>
+ <location filename="../transactiontablemodel.cpp" line="295"/>
<source>Mined balance will be available in %n more blocks</source>
<translation>
<numerusform>Mined balance will be available in %n more block</numerusform>
@@ -1414,67 +1609,67 @@ p, li { white-space: pre-wrap; }
</translation>
</message>
<message>
- <location filename="../transactiontablemodel.cpp" line="300"/>
+ <location filename="../transactiontablemodel.cpp" line="301"/>
<source>This block was not received by any other nodes and will probably not be accepted!</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../transactiontablemodel.cpp" line="303"/>
+ <location filename="../transactiontablemodel.cpp" line="304"/>
<source>Generated but not accepted</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../transactiontablemodel.cpp" line="346"/>
+ <location filename="../transactiontablemodel.cpp" line="347"/>
<source>Received with</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../transactiontablemodel.cpp" line="348"/>
+ <location filename="../transactiontablemodel.cpp" line="349"/>
<source>Received from</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../transactiontablemodel.cpp" line="351"/>
+ <location filename="../transactiontablemodel.cpp" line="352"/>
<source>Sent to</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../transactiontablemodel.cpp" line="353"/>
+ <location filename="../transactiontablemodel.cpp" line="354"/>
<source>Payment to yourself</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../transactiontablemodel.cpp" line="355"/>
+ <location filename="../transactiontablemodel.cpp" line="356"/>
<source>Mined</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../transactiontablemodel.cpp" line="393"/>
+ <location filename="../transactiontablemodel.cpp" line="394"/>
<source>(n/a)</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../transactiontablemodel.cpp" line="592"/>
+ <location filename="../transactiontablemodel.cpp" line="593"/>
<source>Transaction status. Hover over this field to show number of confirmations.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../transactiontablemodel.cpp" line="594"/>
+ <location filename="../transactiontablemodel.cpp" line="595"/>
<source>Date and time that the transaction was received.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../transactiontablemodel.cpp" line="596"/>
+ <location filename="../transactiontablemodel.cpp" line="597"/>
<source>Type of transaction.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../transactiontablemodel.cpp" line="598"/>
+ <location filename="../transactiontablemodel.cpp" line="599"/>
<source>Destination address of transaction.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../transactiontablemodel.cpp" line="600"/>
+ <location filename="../transactiontablemodel.cpp" line="601"/>
<source>Amount removed from or added to balance.</source>
<translation type="unfinished"></translation>
</message>
@@ -1543,559 +1738,731 @@ p, li { white-space: pre-wrap; }
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../transactionview.cpp" line="84"/>
+ <location filename="../transactionview.cpp" line="85"/>
<source>Enter address or label to search</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../transactionview.cpp" line="90"/>
+ <location filename="../transactionview.cpp" line="92"/>
<source>Min amount</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../transactionview.cpp" line="124"/>
+ <location filename="../transactionview.cpp" line="126"/>
<source>Copy address</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../transactionview.cpp" line="125"/>
+ <location filename="../transactionview.cpp" line="127"/>
<source>Copy label</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../transactionview.cpp" line="126"/>
+ <location filename="../transactionview.cpp" line="128"/>
<source>Copy amount</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../transactionview.cpp" line="127"/>
+ <location filename="../transactionview.cpp" line="129"/>
<source>Edit label</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../transactionview.cpp" line="128"/>
- <source>Show details...</source>
+ <location filename="../transactionview.cpp" line="130"/>
+ <source>Show transaction details</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../transactionview.cpp" line="268"/>
+ <location filename="../transactionview.cpp" line="270"/>
<source>Export Transaction Data</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../transactionview.cpp" line="269"/>
+ <location filename="../transactionview.cpp" line="271"/>
<source>Comma separated file (*.csv)</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../transactionview.cpp" line="277"/>
+ <location filename="../transactionview.cpp" line="279"/>
<source>Confirmed</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../transactionview.cpp" line="278"/>
+ <location filename="../transactionview.cpp" line="280"/>
<source>Date</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../transactionview.cpp" line="279"/>
+ <location filename="../transactionview.cpp" line="281"/>
<source>Type</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../transactionview.cpp" line="280"/>
+ <location filename="../transactionview.cpp" line="282"/>
<source>Label</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../transactionview.cpp" line="281"/>
+ <location filename="../transactionview.cpp" line="283"/>
<source>Address</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../transactionview.cpp" line="282"/>
+ <location filename="../transactionview.cpp" line="284"/>
<source>Amount</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../transactionview.cpp" line="283"/>
+ <location filename="../transactionview.cpp" line="285"/>
<source>ID</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../transactionview.cpp" line="287"/>
+ <location filename="../transactionview.cpp" line="289"/>
<source>Error exporting</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../transactionview.cpp" line="287"/>
+ <location filename="../transactionview.cpp" line="289"/>
<source>Could not write to file %1.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../transactionview.cpp" line="382"/>
+ <location filename="../transactionview.cpp" line="384"/>
<source>Range:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../transactionview.cpp" line="390"/>
+ <location filename="../transactionview.cpp" line="392"/>
<source>to</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
+ <name>VerifyMessageDialog</name>
+ <message>
+ <location filename="../forms/verifymessagedialog.ui" line="14"/>
+ <source>Verify Signed Message</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../forms/verifymessagedialog.ui" line="20"/>
+ <source>Enter the message and signature below (be careful to correctly copy newlines, spaces, tabs and other invisible characters) to obtain the Bitcoin address used to sign the message.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../forms/verifymessagedialog.ui" line="62"/>
+ <source>Verify a message and obtain the Bitcoin address used to sign the message</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../forms/verifymessagedialog.ui" line="65"/>
+ <source>&amp;Verify Message</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../forms/verifymessagedialog.ui" line="79"/>
+ <source>Copy the currently selected address to the system clipboard</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../forms/verifymessagedialog.ui" line="82"/>
+ <source>&amp;Copy Address</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../forms/verifymessagedialog.ui" line="93"/>
+ <source>Reset all verify message fields</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../forms/verifymessagedialog.ui" line="96"/>
+ <source>Clear &amp;All</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../verifymessagedialog.cpp" line="27"/>
+ <source>Enter Bitcoin signature</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../verifymessagedialog.cpp" line="28"/>
+ <source>Click &quot;Apply&quot; to obtain address</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../verifymessagedialog.cpp" line="54"/>
+ <location filename="../verifymessagedialog.cpp" line="61"/>
+ <source>Invalid Signature</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../verifymessagedialog.cpp" line="54"/>
+ <source>The signature could not be decoded. Please check the signature and try again.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../verifymessagedialog.cpp" line="61"/>
+ <source>The signature did not match the message digest. Please check the signature and try again.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../verifymessagedialog.cpp" line="71"/>
+ <source>Address not found in address book.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../verifymessagedialog.cpp" line="71"/>
+ <source>Address found in address book: %1</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>WalletModel</name>
<message>
- <location filename="../walletmodel.cpp" line="143"/>
+ <location filename="../walletmodel.cpp" line="142"/>
<source>Sending...</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
- <name>bitcoin-core</name>
+ <name>WindowOptionsPage</name>
<message>
- <location filename="../bitcoinstrings.cpp" line="7"/>
- <source>Bitcoin version</source>
+ <location filename="../optionsdialog.cpp" line="313"/>
+ <source>Window</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../bitcoinstrings.cpp" line="8"/>
- <source>Usage:</source>
+ <location filename="../optionsdialog.cpp" line="316"/>
+ <source>&amp;Minimize to the tray instead of the taskbar</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../bitcoinstrings.cpp" line="9"/>
- <source>Send command to -server or bitcoind</source>
+ <location filename="../optionsdialog.cpp" line="317"/>
+ <source>Show only a tray icon after minimizing the window</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../bitcoinstrings.cpp" line="10"/>
- <source>List commands</source>
+ <location filename="../optionsdialog.cpp" line="320"/>
+ <source>M&amp;inimize on close</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../bitcoinstrings.cpp" line="11"/>
- <source>Get help for a command</source>
+ <location filename="../optionsdialog.cpp" line="321"/>
+ <source>Minimize instead of exit the application when the window is closed. When this option is enabled, the application will be closed only after selecting Quit in the menu.</source>
<translation type="unfinished"></translation>
</message>
+</context>
+<context>
+ <name>bitcoin-core</name>
<message>
<location filename="../bitcoinstrings.cpp" line="12"/>
- <source>Options:</source>
+ <source>Bitcoin version</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../bitcoinstrings.cpp" line="13"/>
- <source>Specify configuration file (default: bitcoin.conf)</source>
+ <source>Usage:</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../bitcoinstrings.cpp" line="14"/>
- <source>Specify pid file (default: bitcoind.pid)</source>
+ <source>Send command to -server or bitcoind</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../bitcoinstrings.cpp" line="15"/>
- <source>Generate coins</source>
+ <source>List commands</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../bitcoinstrings.cpp" line="16"/>
- <source>Don&apos;t generate coins</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location filename="../bitcoinstrings.cpp" line="17"/>
- <source>Start minimized</source>
+ <source>Get help for a command</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../bitcoinstrings.cpp" line="18"/>
- <source>Show splash screen on startup (default: 1)</source>
+ <source>Options:</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../bitcoinstrings.cpp" line="19"/>
- <source>Specify data directory</source>
+ <source>Specify configuration file (default: bitcoin.conf)</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../bitcoinstrings.cpp" line="20"/>
- <source>Set database cache size in megabytes (default: 25)</source>
+ <source>Specify pid file (default: bitcoind.pid)</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../bitcoinstrings.cpp" line="21"/>
- <source>Set database disk log size in megabytes (default: 100)</source>
+ <source>Generate coins</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../bitcoinstrings.cpp" line="22"/>
- <source>Specify connection timeout (in milliseconds)</source>
+ <source>Don&apos;t generate coins</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../bitcoinstrings.cpp" line="23"/>
- <source>Connect through socks4 proxy</source>
+ <source>Specify data directory</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../bitcoinstrings.cpp" line="24"/>
- <source>Allow DNS lookups for addnode and connect</source>
+ <source>Set database cache size in megabytes (default: 25)</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../bitcoinstrings.cpp" line="25"/>
- <source>Listen for connections on &lt;port&gt; (default: 8333 or testnet: 18333)</source>
+ <source>Set database disk log size in megabytes (default: 100)</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../bitcoinstrings.cpp" line="26"/>
+ <source>Specify connection timeout (in milliseconds)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="32"/>
+ <source>Listen for connections on &lt;port&gt; (default: 8333 or testnet: 18333)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="33"/>
<source>Maintain at most &lt;n&gt; connections to peers (default: 125)</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../bitcoinstrings.cpp" line="28"/>
+ <location filename="../bitcoinstrings.cpp" line="35"/>
<source>Connect only to the specified node</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../bitcoinstrings.cpp" line="33"/>
+ <location filename="../bitcoinstrings.cpp" line="36"/>
+ <source>Connect to a node to retrieve peer addresses, and disconnect</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="37"/>
+ <source>Specify your own public address</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="38"/>
+ <source>Only connect to nodes in network &lt;net&gt; (IPv4 or IPv6)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="39"/>
+ <source>Try to discover public IP address (default: 1)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="42"/>
+ <source>Bind to given address. Use [host]:port notation for IPv6</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="44"/>
<source>Threshold for disconnecting misbehaving peers (default: 100)</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../bitcoinstrings.cpp" line="34"/>
+ <location filename="../bitcoinstrings.cpp" line="45"/>
<source>Number of seconds to keep misbehaving peers from reconnecting (default: 86400)</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../bitcoinstrings.cpp" line="37"/>
+ <location filename="../bitcoinstrings.cpp" line="48"/>
<source>Maximum per-connection receive buffer, &lt;n&gt;*1000 bytes (default: 10000)</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../bitcoinstrings.cpp" line="38"/>
+ <location filename="../bitcoinstrings.cpp" line="49"/>
<source>Maximum per-connection send buffer, &lt;n&gt;*1000 bytes (default: 10000)</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../bitcoinstrings.cpp" line="42"/>
+ <location filename="../bitcoinstrings.cpp" line="52"/>
+ <source>Detach block and address databases. Increases shutdown time (default: 0)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="55"/>
<source>Accept command line and JSON-RPC commands</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../bitcoinstrings.cpp" line="43"/>
+ <location filename="../bitcoinstrings.cpp" line="56"/>
<source>Run in the background as a daemon and accept commands</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../bitcoinstrings.cpp" line="44"/>
+ <location filename="../bitcoinstrings.cpp" line="57"/>
<source>Use the test network</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../bitcoinstrings.cpp" line="45"/>
+ <location filename="../bitcoinstrings.cpp" line="58"/>
<source>Output extra debugging information</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../bitcoinstrings.cpp" line="46"/>
+ <location filename="../bitcoinstrings.cpp" line="59"/>
<source>Prepend debug output with timestamp</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../bitcoinstrings.cpp" line="47"/>
+ <location filename="../bitcoinstrings.cpp" line="60"/>
<source>Send trace/debug info to console instead of debug.log file</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../bitcoinstrings.cpp" line="48"/>
+ <location filename="../bitcoinstrings.cpp" line="61"/>
<source>Send trace/debug info to debugger</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../bitcoinstrings.cpp" line="49"/>
+ <location filename="../bitcoinstrings.cpp" line="62"/>
<source>Username for JSON-RPC connections</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../bitcoinstrings.cpp" line="50"/>
+ <location filename="../bitcoinstrings.cpp" line="63"/>
<source>Password for JSON-RPC connections</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../bitcoinstrings.cpp" line="51"/>
+ <location filename="../bitcoinstrings.cpp" line="64"/>
<source>Listen for JSON-RPC connections on &lt;port&gt; (default: 8332)</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../bitcoinstrings.cpp" line="52"/>
+ <location filename="../bitcoinstrings.cpp" line="65"/>
<source>Allow JSON-RPC connections from specified IP address</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../bitcoinstrings.cpp" line="53"/>
+ <location filename="../bitcoinstrings.cpp" line="66"/>
<source>Send commands to node running on &lt;ip&gt; (default: 127.0.0.1)</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../bitcoinstrings.cpp" line="54"/>
+ <location filename="../bitcoinstrings.cpp" line="67"/>
<source>Execute command when the best block changes (%s in cmd is replaced by block hash)</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../bitcoinstrings.cpp" line="57"/>
+ <location filename="../bitcoinstrings.cpp" line="70"/>
<source>Upgrade wallet to latest format</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../bitcoinstrings.cpp" line="58"/>
+ <location filename="../bitcoinstrings.cpp" line="71"/>
<source>Set key pool size to &lt;n&gt; (default: 100)</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../bitcoinstrings.cpp" line="59"/>
+ <location filename="../bitcoinstrings.cpp" line="72"/>
<source>Rescan the block chain for missing wallet transactions</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../bitcoinstrings.cpp" line="60"/>
+ <location filename="../bitcoinstrings.cpp" line="73"/>
<source>How many blocks to check at startup (default: 2500, 0 = all)</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../bitcoinstrings.cpp" line="61"/>
+ <location filename="../bitcoinstrings.cpp" line="74"/>
<source>How thorough the block verification is (0-6, default: 1)</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../bitcoinstrings.cpp" line="62"/>
+ <location filename="../bitcoinstrings.cpp" line="75"/>
+ <source>Imports blocks from external blk000?.dat file</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="77"/>
<source>
SSL options: (see the Bitcoin Wiki for SSL setup instructions)</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../bitcoinstrings.cpp" line="65"/>
+ <location filename="../bitcoinstrings.cpp" line="80"/>
<source>Use OpenSSL (https) for JSON-RPC connections</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../bitcoinstrings.cpp" line="66"/>
+ <location filename="../bitcoinstrings.cpp" line="81"/>
<source>Server certificate file (default: server.cert)</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../bitcoinstrings.cpp" line="67"/>
+ <location filename="../bitcoinstrings.cpp" line="82"/>
<source>Server private key (default: server.pem)</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../bitcoinstrings.cpp" line="68"/>
+ <location filename="../bitcoinstrings.cpp" line="83"/>
<source>Acceptable ciphers (default: TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!AH:!3DES:@STRENGTH)</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../bitcoinstrings.cpp" line="71"/>
+ <location filename="../bitcoinstrings.cpp" line="76"/>
<source>This help message</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../bitcoinstrings.cpp" line="72"/>
- <source>Usage</source>
+ <location filename="../bitcoinstrings.cpp" line="86"/>
+ <source>Cannot obtain a lock on data directory %s. Bitcoin is probably already running.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../bitcoinstrings.cpp" line="73"/>
- <source>Cannot obtain a lock on data directory %s. Bitcoin is probably already running.</source>
+ <location filename="../bitcoinstrings.cpp" line="17"/>
+ <source>Bitcoin</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../bitcoinstrings.cpp" line="76"/>
- <source>Bitcoin</source>
+ <location filename="../bitcoinstrings.cpp" line="8"/>
+ <source>Unable to bind to %s on this computer. Bitcoin is probably already running.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../bitcoinstrings.cpp" line="77"/>
+ <location filename="../bitcoinstrings.cpp" line="10"/>
+ <source>Unable to bind to %s on this computer (bind returned error %d, %s)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="27"/>
+ <source>Connect through socks proxy</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="28"/>
+ <source>Select the version of socks proxy to use (4 or 5, 5 is default)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="29"/>
+ <source>Do not use proxy for connections to network &lt;net&gt; (IPv4 or IPv6)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="30"/>
+ <source>Allow DNS lookups for -addnode, -seednode and -connect</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="31"/>
+ <source>Pass DNS requests to (SOCKS5) proxy</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="89"/>
<source>Loading addresses...</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../bitcoinstrings.cpp" line="78"/>
+ <location filename="../bitcoinstrings.cpp" line="90"/>
<source>Error loading addr.dat</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../bitcoinstrings.cpp" line="80"/>
+ <location filename="../bitcoinstrings.cpp" line="92"/>
<source>Error loading blkindex.dat</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../bitcoinstrings.cpp" line="82"/>
+ <location filename="../bitcoinstrings.cpp" line="94"/>
<source>Error loading wallet.dat: Wallet corrupted</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../bitcoinstrings.cpp" line="83"/>
+ <location filename="../bitcoinstrings.cpp" line="95"/>
<source>Error loading wallet.dat: Wallet requires newer version of Bitcoin</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../bitcoinstrings.cpp" line="84"/>
+ <location filename="../bitcoinstrings.cpp" line="96"/>
<source>Wallet needed to be rewritten: restart Bitcoin to complete</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../bitcoinstrings.cpp" line="85"/>
+ <location filename="../bitcoinstrings.cpp" line="97"/>
<source>Error loading wallet.dat</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../bitcoinstrings.cpp" line="117"/>
+ <location filename="../bitcoinstrings.cpp" line="103"/>
+ <source>Invalid -proxy address: &apos;%s&apos;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="104"/>
+ <source>Unknown network specified in -noproxy: &apos;%s&apos;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="105"/>
+ <source>Unknown network specified in -onlynet: &apos;%s&apos;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="106"/>
+ <source>Unknown -socks proxy version requested: %i</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="107"/>
+ <source>Cannot resolve -bind address: &apos;%s&apos;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="108"/>
+ <source>Not listening on any port</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="109"/>
+ <source>Cannot resolve -externalip address: &apos;%s&apos;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="110"/>
+ <source>Invalid amount for -paytxfee=&lt;amount&gt;: &apos;%s&apos;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="114"/>
+ <source>Error: could not start node</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="135"/>
<source>Error: Wallet locked, unable to create transaction </source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../bitcoinstrings.cpp" line="118"/>
+ <location filename="../bitcoinstrings.cpp" line="136"/>
<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 type="unfinished"></translation>
</message>
<message>
- <location filename="../bitcoinstrings.cpp" line="121"/>
+ <location filename="../bitcoinstrings.cpp" line="139"/>
<source>Error: Transaction creation failed </source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../bitcoinstrings.cpp" line="122"/>
+ <location filename="../bitcoinstrings.cpp" line="140"/>
<source>Sending...</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../bitcoinstrings.cpp" line="123"/>
+ <location filename="../bitcoinstrings.cpp" line="141"/>
<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>
</message>
<message>
- <location filename="../bitcoinstrings.cpp" line="127"/>
+ <location filename="../bitcoinstrings.cpp" line="145"/>
<source>Invalid amount</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../bitcoinstrings.cpp" line="128"/>
+ <location filename="../bitcoinstrings.cpp" line="146"/>
<source>Insufficient funds</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../bitcoinstrings.cpp" line="79"/>
+ <location filename="../bitcoinstrings.cpp" line="91"/>
<source>Loading block index...</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../bitcoinstrings.cpp" line="27"/>
+ <location filename="../bitcoinstrings.cpp" line="34"/>
<source>Add a node to connect to and attempt to keep the connection open</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../bitcoinstrings.cpp" line="29"/>
+ <location filename="../bitcoinstrings.cpp" line="40"/>
<source>Find peers using internet relay chat (default: 0)</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../bitcoinstrings.cpp" line="30"/>
+ <location filename="../bitcoinstrings.cpp" line="41"/>
<source>Accept connections from outside (default: 1)</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../bitcoinstrings.cpp" line="31"/>
- <source>Set language, for example &quot;de_DE&quot; (default: system locale)</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location filename="../bitcoinstrings.cpp" line="32"/>
+ <location filename="../bitcoinstrings.cpp" line="43"/>
<source>Find peers using DNS lookup (default: 1)</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../bitcoinstrings.cpp" line="39"/>
+ <location filename="../bitcoinstrings.cpp" line="50"/>
<source>Use Universal Plug and Play to map the listening port (default: 1)</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../bitcoinstrings.cpp" line="40"/>
+ <location filename="../bitcoinstrings.cpp" line="51"/>
<source>Use Universal Plug and Play to map the listening port (default: 0)</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../bitcoinstrings.cpp" line="41"/>
+ <location filename="../bitcoinstrings.cpp" line="54"/>
<source>Fee per KB to add to transactions you send</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../bitcoinstrings.cpp" line="81"/>
+ <location filename="../bitcoinstrings.cpp" line="93"/>
<source>Loading wallet...</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../bitcoinstrings.cpp" line="86"/>
+ <location filename="../bitcoinstrings.cpp" line="98"/>
<source>Cannot downgrade wallet</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../bitcoinstrings.cpp" line="87"/>
+ <location filename="../bitcoinstrings.cpp" line="99"/>
<source>Cannot initialize keypool</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../bitcoinstrings.cpp" line="88"/>
+ <location filename="../bitcoinstrings.cpp" line="100"/>
<source>Cannot write default address</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../bitcoinstrings.cpp" line="89"/>
+ <location filename="../bitcoinstrings.cpp" line="101"/>
<source>Rescanning...</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../bitcoinstrings.cpp" line="90"/>
+ <location filename="../bitcoinstrings.cpp" line="102"/>
<source>Done loading</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../bitcoinstrings.cpp" line="91"/>
- <source>Invalid -proxy address</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location filename="../bitcoinstrings.cpp" line="92"/>
- <source>Invalid amount for -paytxfee=&lt;amount&gt;</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location filename="../bitcoinstrings.cpp" line="93"/>
+ <location filename="../bitcoinstrings.cpp" line="111"/>
<source>Warning: -paytxfee is set very high. This is the transaction fee you will pay if you send a transaction.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../bitcoinstrings.cpp" line="96"/>
- <source>Error: CreateThread(StartNode) failed</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location filename="../bitcoinstrings.cpp" line="6"/>
+ <location filename="../bitcoinstrings.cpp" line="11"/>
<source>Warning: Disk space is low </source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../bitcoinstrings.cpp" line="3"/>
- <source>Unable to bind to port %d on this computer. Bitcoin is probably already running.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location filename="../bitcoinstrings.cpp" line="97"/>
+ <location filename="../bitcoinstrings.cpp" line="115"/>
<source>To use the %s option</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../bitcoinstrings.cpp" line="98"/>
+ <location filename="../bitcoinstrings.cpp" line="116"/>
<source>%s, you must set a rpcpassword in the configuration file:
%s
It is recommended you use the following random password:
@@ -2107,24 +2474,24 @@ If the file does not exist, create it with owner-readable-only file permissions.
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../bitcoinstrings.cpp" line="107"/>
+ <location filename="../bitcoinstrings.cpp" line="125"/>
<source>Error</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../bitcoinstrings.cpp" line="108"/>
+ <location filename="../bitcoinstrings.cpp" line="126"/>
<source>An error occured while setting up the RPC port %i for listening: %s</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../bitcoinstrings.cpp" line="109"/>
+ <location filename="../bitcoinstrings.cpp" line="127"/>
<source>You must set rpcpassword=&lt;password&gt; in the configuration file:
%s
If the file does not exist, create it with owner-readable-only file permissions.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../bitcoinstrings.cpp" line="114"/>
+ <location filename="../bitcoinstrings.cpp" line="132"/>
<source>Warning: Please check that your computer&apos;s date and time are correct. If your clock is wrong Bitcoin will not work properly.</source>
<translation type="unfinished"></translation>
</message>
diff --git a/src/qt/locale/bitcoin_fr.ts b/src/qt/locale/bitcoin_fr.ts
new file mode 100644
index 0000000000..0fa1585227
--- /dev/null
+++ b/src/qt/locale/bitcoin_fr.ts
@@ -0,0 +1,2267 @@
+<?xml version="1.0" ?><!DOCTYPE TS><TS language="fr" version="2.0">
+<defaultcodec>UTF-8</defaultcodec>
+<context>
+ <name>AboutDialog</name>
+ <message>
+ <location filename="../forms/aboutdialog.ui" line="14"/>
+ <source>About Bitcoin</source>
+ <translation>À propos de Bitcoin</translation>
+ </message>
+ <message>
+ <location filename="../forms/aboutdialog.ui" line="53"/>
+ <source>&lt;b&gt;Bitcoin&lt;/b&gt; version</source>
+ <translation>&lt;b&gt;Bitcoin&lt;/b&gt; version</translation>
+ </message>
+ <message>
+ <location filename="../forms/aboutdialog.ui" line="97"/>
+ <source>Copyright © 2009-2012 Bitcoin Developers
+
+This is experimental software.
+
+Distributed under the MIT/X11 software license, see the accompanying file license.txt or http://www.opensource.org/licenses/mit-license.php.
+
+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.</source>
+ <translation>Copyright © 2009-2012 Développeurs de Bitcoin
+
+Ce logiciel est en phase expérimentale.
+
+Distribué sous licence MIT/X11, voir le fichier license.txt ou http://www.opensource.org/licenses/mit-license.php.
+
+Ce produit comprend des logiciels développés par le projet OpenSSL pour être utilisés dans la boîte à outils OpenSSL (http://www.openssl.org/), un logiciel cryptographique écrit par Eric Young (eay@cryptsoft.com) et un logiciel UPnP écrit par Thomas Bernard.</translation>
+ </message>
+</context>
+<context>
+ <name>AddressBookPage</name>
+ <message>
+ <location filename="../forms/addressbookpage.ui" line="14"/>
+ <source>Address Book</source>
+ <translation>Carnet d&apos;adresses</translation>
+ </message>
+ <message>
+ <location filename="../forms/addressbookpage.ui" line="20"/>
+ <source>These are your Bitcoin addresses for receiving payments. You may want to give a different one to each sender so you can keep track of who is paying you.</source>
+ <translation>Voici vos adresses Bitcoin qui vous permettent de recevoir des paiements. Vous pouvez donner une adresse différente à chaque expéditeur afin de savoir qui vous paye.</translation>
+ </message>
+ <message>
+ <location filename="../forms/addressbookpage.ui" line="36"/>
+ <source>Double-click to edit address or label</source>
+ <translation>Double cliquez afin de modifier l&apos;adresse ou l&apos;étiquette</translation>
+ </message>
+ <message>
+ <location filename="../forms/addressbookpage.ui" line="63"/>
+ <source>Create a new address</source>
+ <translation>Créer une nouvelle adresse</translation>
+ </message>
+ <message>
+ <location filename="../forms/addressbookpage.ui" line="77"/>
+ <source>Copy the currently selected address to the system clipboard</source>
+ <translation>Copier l&apos;adresse surlignée dans votre presse-papiers</translation>
+ </message>
+ <message>
+ <location filename="../forms/addressbookpage.ui" line="66"/>
+ <source>&amp;New Address</source>
+ <translation>&amp;Nouvelle adresse</translation>
+ </message>
+ <message>
+ <location filename="../forms/addressbookpage.ui" line="80"/>
+ <source>&amp;Copy Address</source>
+ <translation>&amp;Copier l&apos;adresse</translation>
+ </message>
+ <message>
+ <location filename="../forms/addressbookpage.ui" line="91"/>
+ <source>Show &amp;QR Code</source>
+ <translation>Afficher le &amp;QR Code</translation>
+ </message>
+ <message>
+ <location filename="../forms/addressbookpage.ui" line="102"/>
+ <source>Sign a message to prove you own this address</source>
+ <translation>Signer un message pour prouver que vous détenez cette adresse</translation>
+ </message>
+ <message>
+ <location filename="../forms/addressbookpage.ui" line="105"/>
+ <source>&amp;Sign Message</source>
+ <translation>&amp;Signer un message</translation>
+ </message>
+ <message>
+ <location filename="../forms/addressbookpage.ui" line="116"/>
+ <source>Delete the currently selected address from the list. Only sending addresses can be deleted.</source>
+ <translation>Supprimer l&apos;adresse sélectionnée dans la liste. Seules les adresses d&apos;envoi peuvent être supprimées.</translation>
+ </message>
+ <message>
+ <location filename="../forms/addressbookpage.ui" line="119"/>
+ <source>&amp;Delete</source>
+ <translation>&amp;Supprimer</translation>
+ </message>
+ <message>
+ <location filename="../addressbookpage.cpp" line="63"/>
+ <source>Copy &amp;Label</source>
+ <translation>Copier l&apos;é&amp;tiquette</translation>
+ </message>
+ <message>
+ <location filename="../addressbookpage.cpp" line="65"/>
+ <source>&amp;Edit</source>
+ <translation>&amp;Éditer</translation>
+ </message>
+ <message>
+ <location filename="../addressbookpage.cpp" line="297"/>
+ <source>Export Address Book Data</source>
+ <translation>Exporter les données du carnet d&apos;adresses</translation>
+ </message>
+ <message>
+ <location filename="../addressbookpage.cpp" line="298"/>
+ <source>Comma separated file (*.csv)</source>
+ <translation>Valeurs séparées par des virgules (*.csv)</translation>
+ </message>
+ <message>
+ <location filename="../addressbookpage.cpp" line="311"/>
+ <source>Error exporting</source>
+ <translation>Erreur lors de l&apos;exportation</translation>
+ </message>
+ <message>
+ <location filename="../addressbookpage.cpp" line="311"/>
+ <source>Could not write to file %1.</source>
+ <translation>Impossible d&apos;écrire sur le fichier %1.</translation>
+ </message>
+</context>
+<context>
+ <name>AddressTableModel</name>
+ <message>
+ <location filename="../addresstablemodel.cpp" line="78"/>
+ <source>Label</source>
+ <translation>Étiquette</translation>
+ </message>
+ <message>
+ <location filename="../addresstablemodel.cpp" line="78"/>
+ <source>Address</source>
+ <translation>Adresse</translation>
+ </message>
+ <message>
+ <location filename="../addresstablemodel.cpp" line="114"/>
+ <source>(no label)</source>
+ <translation>(aucune étiquette)</translation>
+ </message>
+</context>
+<context>
+ <name>AskPassphraseDialog</name>
+ <message>
+ <location filename="../forms/askpassphrasedialog.ui" line="26"/>
+ <source>Dialog</source>
+ <translation>Dialogue</translation>
+ </message>
+ <message>
+ <location filename="../forms/askpassphrasedialog.ui" line="32"/>
+ <location filename="../forms/askpassphrasedialog.ui" line="97"/>
+ <source>TextLabel</source>
+ <translation>TextLabel</translation>
+ </message>
+ <message>
+ <location filename="../forms/askpassphrasedialog.ui" line="50"/>
+ <source>Enter passphrase</source>
+ <translation>Entrez la phrase de passe</translation>
+ </message>
+ <message>
+ <location filename="../forms/askpassphrasedialog.ui" line="64"/>
+ <source>New passphrase</source>
+ <translation>Nouvelle phrase de passe</translation>
+ </message>
+ <message>
+ <location filename="../forms/askpassphrasedialog.ui" line="78"/>
+ <source>Repeat new passphrase</source>
+ <translation>Répétez la phrase de passe</translation>
+ </message>
+ <message>
+ <location filename="../askpassphrasedialog.cpp" line="34"/>
+ <source>Enter the new passphrase to the wallet.&lt;br/&gt;Please use a passphrase of &lt;b&gt;10 or more random characters&lt;/b&gt;, or &lt;b&gt;eight or more words&lt;/b&gt;.</source>
+ <translation>Entrez une nouvelle phrase de passe pour le porte-monnaie.&lt;br/&gt;Veuillez utiliser une phrase de &lt;b&gt;10 caractères au hasard ou plus&lt;/b&gt; ou bien de &lt;b&gt;huit mots ou plus&lt;/b&gt;.</translation>
+ </message>
+ <message>
+ <location filename="../askpassphrasedialog.cpp" line="35"/>
+ <source>Encrypt wallet</source>
+ <translation>Chiffrer le porte-monnaie</translation>
+ </message>
+ <message>
+ <location filename="../askpassphrasedialog.cpp" line="38"/>
+ <source>This operation needs your wallet passphrase to unlock the wallet.</source>
+ <translation>Cette opération nécessite votre phrase de passe pour déverrouiller le porte-monnaie.</translation>
+ </message>
+ <message>
+ <location filename="../askpassphrasedialog.cpp" line="43"/>
+ <source>Unlock wallet</source>
+ <translation>Déverrouiller le porte-monnaie</translation>
+ </message>
+ <message>
+ <location filename="../askpassphrasedialog.cpp" line="46"/>
+ <source>This operation needs your wallet passphrase to decrypt the wallet.</source>
+ <translation>Cette opération nécessite votre phrase de passe pour décrypter le porte-monnaie.</translation>
+ </message>
+ <message>
+ <location filename="../askpassphrasedialog.cpp" line="51"/>
+ <source>Decrypt wallet</source>
+ <translation>Décrypter le porte-monnaie</translation>
+ </message>
+ <message>
+ <location filename="../askpassphrasedialog.cpp" line="54"/>
+ <source>Change passphrase</source>
+ <translation>Changer la phrase de passe</translation>
+ </message>
+ <message>
+ <location filename="../askpassphrasedialog.cpp" line="55"/>
+ <source>Enter the old and new passphrase to the wallet.</source>
+ <translation>Entrez l’ancienne phrase de passe pour le porte-monnaie ainsi que la nouvelle.</translation>
+ </message>
+ <message>
+ <location filename="../askpassphrasedialog.cpp" line="101"/>
+ <source>Confirm wallet encryption</source>
+ <translation>Confirmer le chiffrement du porte-monnaie</translation>
+ </message>
+ <message>
+ <location filename="../askpassphrasedialog.cpp" line="102"/>
+ <source>WARNING: If you encrypt your wallet and lose your passphrase, you will &lt;b&gt;LOSE ALL OF YOUR BITCOINS&lt;/b&gt;!
+Are you sure you wish to encrypt your wallet?</source>
+ <translation>ATTENTION : Si vous chiffrez votre porte-monnaie et perdez votre phrase de passe, vous &lt;b&gt;PERDREZ TOUS VOS BITCOINS&lt;/b&gt; !
+Êtes-vous sûr de vouloir chiffrer votre porte-monnaie ?</translation>
+ </message>
+ <message>
+ <location filename="../askpassphrasedialog.cpp" line="111"/>
+ <location filename="../askpassphrasedialog.cpp" line="160"/>
+ <source>Wallet encrypted</source>
+ <translation>Porte-monnaie chiffré</translation>
+ </message>
+ <message>
+ <location filename="../askpassphrasedialog.cpp" line="112"/>
+ <source>Bitcoin will close now to finish the encryption process. Remember that encrypting your wallet cannot fully protect your bitcoins from being stolen by malware infecting your computer.</source>
+ <translation>Bitcoin va à présent se fermer pour terminer la procédure de cryptage. N&apos;oubliez pas que le chiffrement de votre porte-monnaie ne peut pas fournir une protection totale contre le vol par des logiciels malveillants qui infecteraient votre ordinateur.</translation>
+ </message>
+ <message>
+ <location filename="../askpassphrasedialog.cpp" line="208"/>
+ <location filename="../askpassphrasedialog.cpp" line="232"/>
+ <source>Warning: The Caps Lock key is on.</source>
+ <translation>Attention : la touche Verrouiller Maj est activée.</translation>
+ </message>
+ <message>
+ <location filename="../askpassphrasedialog.cpp" line="117"/>
+ <location filename="../askpassphrasedialog.cpp" line="124"/>
+ <location filename="../askpassphrasedialog.cpp" line="166"/>
+ <location filename="../askpassphrasedialog.cpp" line="172"/>
+ <source>Wallet encryption failed</source>
+ <translation>Le chiffrement du porte-monnaie a échoué</translation>
+ </message>
+ <message>
+ <location filename="../askpassphrasedialog.cpp" line="118"/>
+ <source>Wallet encryption failed due to an internal error. Your wallet was not encrypted.</source>
+ <translation>Le chiffrement du porte-monnaie a échoué en raison d&apos;une erreur interne. Votre porte-monnaie n&apos;a pas été chiffré.</translation>
+ </message>
+ <message>
+ <location filename="../askpassphrasedialog.cpp" line="125"/>
+ <location filename="../askpassphrasedialog.cpp" line="173"/>
+ <source>The supplied passphrases do not match.</source>
+ <translation>Les phrases de passe entrées ne correspondent pas.</translation>
+ </message>
+ <message>
+ <location filename="../askpassphrasedialog.cpp" line="136"/>
+ <source>Wallet unlock failed</source>
+ <translation>Le déverrouillage du porte-monnaie a échoué</translation>
+ </message>
+ <message>
+ <location filename="../askpassphrasedialog.cpp" line="137"/>
+ <location filename="../askpassphrasedialog.cpp" line="148"/>
+ <location filename="../askpassphrasedialog.cpp" line="167"/>
+ <source>The passphrase entered for the wallet decryption was incorrect.</source>
+ <translation>La phrase de passe entrée pour décrypter le porte-monnaie était incorrecte.</translation>
+ </message>
+ <message>
+ <location filename="../askpassphrasedialog.cpp" line="147"/>
+ <source>Wallet decryption failed</source>
+ <translation>Le décryptage du porte-monnaie a échoué</translation>
+ </message>
+ <message>
+ <location filename="../askpassphrasedialog.cpp" line="161"/>
+ <source>Wallet passphrase was succesfully changed.</source>
+ <translation>La phrase de passe du porte-monnaie a été modifiée avec succès.</translation>
+ </message>
+</context>
+<context>
+ <name>BitcoinGUI</name>
+ <message>
+ <location filename="../bitcoingui.cpp" line="72"/>
+ <source>Bitcoin Wallet</source>
+ <translation>Porte-monnaie Bitcoin</translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="212"/>
+ <source>Sign &amp;message...</source>
+ <translation>Signer le &amp;message...</translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="245"/>
+ <source>Show/Hide &amp;Bitcoin</source>
+ <translation>Afficher/Cacher &amp;Bitcoin</translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="507"/>
+ <source>Synchronizing with network...</source>
+ <translation>Synchronisation avec le réseau...</translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="182"/>
+ <source>&amp;Overview</source>
+ <translation>&amp;Vue d&apos;ensemble</translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="183"/>
+ <source>Show general overview of wallet</source>
+ <translation>Affiche une vue d&apos;ensemble du porte-monnaie</translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="188"/>
+ <source>&amp;Transactions</source>
+ <translation>&amp;Transactions</translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="189"/>
+ <source>Browse transaction history</source>
+ <translation>Permet de parcourir l&apos;historique des transactions</translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="194"/>
+ <source>&amp;Address Book</source>
+ <translation>Carnet d&apos;&amp;adresses</translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="195"/>
+ <source>Edit the list of stored addresses and labels</source>
+ <translation>Éditer la liste des adresses et des étiquettes stockées</translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="200"/>
+ <source>&amp;Receive coins</source>
+ <translation>&amp;Recevoir des pièces</translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="201"/>
+ <source>Show the list of addresses for receiving payments</source>
+ <translation>Affiche la liste des adresses pour recevoir des paiements</translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="206"/>
+ <source>&amp;Send coins</source>
+ <translation>&amp;Envoyer des pièces</translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="207"/>
+ <source>Send coins to a bitcoin address</source>
+ <translation>Envoyer des pièces à une adresse Bitcoin</translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="213"/>
+ <source>Prove you control an address</source>
+ <translation>Prouver que vous contrôlez une adresse</translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="232"/>
+ <source>E&amp;xit</source>
+ <translation>Q&amp;uitter</translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="233"/>
+ <source>Quit application</source>
+ <translation>Quitter l&apos;application</translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="236"/>
+ <source>&amp;About %1</source>
+ <translation>&amp;À propos de %1</translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="237"/>
+ <source>Show information about Bitcoin</source>
+ <translation>Afficher des informations à propos de Bitcoin</translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="239"/>
+ <source>About &amp;Qt</source>
+ <translation>À propos de &amp;Qt</translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="240"/>
+ <source>Show information about Qt</source>
+ <translation>Afficher des informations sur Qt</translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="242"/>
+ <source>&amp;Options...</source>
+ <translation>&amp;Options...</translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="243"/>
+ <source>Modify configuration options for bitcoin</source>
+ <translation>Modifier les options de configuration de Bitcoin</translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="249"/>
+ <source>&amp;Encrypt Wallet...</source>
+ <translation>&amp;Chiffrer le porte-monnaie...</translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="252"/>
+ <source>&amp;Backup Wallet...</source>
+ <translation>&amp;Sauvegarder le porte-monnaie...</translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="254"/>
+ <source>&amp;Change Passphrase...</source>
+ <translation>&amp;Modifier la phrase de passe...</translation>
+ </message>
+ <message numerus="yes">
+ <location filename="../bitcoingui.cpp" line="509"/>
+ <source>~%n block(s) remaining</source>
+ <translation><numerusform>~%n bloc restant</numerusform><numerusform>~%n blocs restants</numerusform></translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="520"/>
+ <source>Downloaded %1 of %2 blocks of transaction history (%3% done).</source>
+ <translation>%1 blocs de l&apos;historique des transactions sur %2 téléchargés (%3% effectué).</translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="247"/>
+ <source>&amp;Export...</source>
+ <translation>&amp;Exporter...</translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="246"/>
+ <source>Show or hide the Bitcoin window</source>
+ <translation>Afficher ou cacher la fenêtre Bitcoin</translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="248"/>
+ <source>Export the data in the current tab to a file</source>
+ <translation>Exporter les données de l&apos;onglet courant vers un fichier</translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="250"/>
+ <source>Encrypt or decrypt wallet</source>
+ <translation>Chiffrer ou décrypter le porte-monnaie</translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="253"/>
+ <source>Backup wallet to another location</source>
+ <translation>Sauvegarder le porte-monnaie à un autre emplacement</translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="255"/>
+ <source>Change the passphrase used for wallet encryption</source>
+ <translation>Modifier la phrase de passe utilisée pour le cryptage du porte-monnaie</translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="256"/>
+ <source>&amp;Debug window</source>
+ <translation>Fenêtre de &amp;débogage</translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="257"/>
+ <source>Open debugging and diagnostic console</source>
+ <translation>Ouvrir une console de débogage et de diagnostic</translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="280"/>
+ <source>&amp;File</source>
+ <translation>&amp;Fichier</translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="289"/>
+ <source>&amp;Settings</source>
+ <translation>&amp;Réglages</translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="295"/>
+ <source>&amp;Help</source>
+ <translation>&amp;Aide</translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="304"/>
+ <source>Tabs toolbar</source>
+ <translation>Barre d&apos;outils des onglets</translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="315"/>
+ <source>Actions toolbar</source>
+ <translation>Barre d&apos;outils des actions</translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="327"/>
+ <source>[testnet]</source>
+ <translation>[testnet]</translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="391"/>
+ <source>Bitcoin client</source>
+ <translation>Client Bitcoin</translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="419"/>
+ <source>bitcoin-qt</source>
+ <translation>bitcoin-qt</translation>
+ </message>
+ <message numerus="yes">
+ <location filename="../bitcoingui.cpp" line="483"/>
+ <source>%n active connection(s) to Bitcoin network</source>
+ <translation><numerusform>%n connexion active avec le réseau Bitcoin</numerusform><numerusform>%n connexions actives avec le réseau Bitcoin</numerusform></translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="532"/>
+ <source>Downloaded %1 blocks of transaction history.</source>
+ <translation>%1 blocs de l&apos;historique des transactions téléchargés.</translation>
+ </message>
+ <message numerus="yes">
+ <location filename="../bitcoingui.cpp" line="547"/>
+ <source>%n second(s) ago</source>
+ <translation><numerusform>il y a %n seconde</numerusform><numerusform>il y a %n secondes</numerusform></translation>
+ </message>
+ <message numerus="yes">
+ <location filename="../bitcoingui.cpp" line="551"/>
+ <source>%n minute(s) ago</source>
+ <translation><numerusform>il y a %n minute</numerusform><numerusform>il y a %n minutes</numerusform></translation>
+ </message>
+ <message numerus="yes">
+ <location filename="../bitcoingui.cpp" line="555"/>
+ <source>%n hour(s) ago</source>
+ <translation><numerusform>il y a %n heure</numerusform><numerusform>il y a %n heures</numerusform></translation>
+ </message>
+ <message numerus="yes">
+ <location filename="../bitcoingui.cpp" line="559"/>
+ <source>%n day(s) ago</source>
+ <translation><numerusform>il y a %n jour</numerusform><numerusform>il y a %n jours</numerusform></translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="565"/>
+ <source>Up to date</source>
+ <translation>À jour</translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="570"/>
+ <source>Catching up...</source>
+ <translation>Rattrapage...</translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="578"/>
+ <source>Last received block was generated %1.</source>
+ <translation>Le dernier bloc reçu a été généré %1.</translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="634"/>
+ <source>This transaction is over the size limit. You can still send it for a fee of %1, which goes to the nodes that process your transaction and helps to support the network. Do you want to pay the fee?</source>
+ <translation>Cette transaction dépasse la limite de taille. Vous pouvez quand même l&apos;envoyer en vous acquittant de frais d&apos;un montant de %1, qui iront aux nœuds qui traiteront la transaction et aideront à soutenir le réseau. Voulez-vous payer les frais ?</translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="639"/>
+ <source>Confirm transaction fee</source>
+ <translation>Confirmer les frais de transaction</translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="666"/>
+ <source>Sent transaction</source>
+ <translation>Transaction envoyée</translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="667"/>
+ <source>Incoming transaction</source>
+ <translation>Transaction entrante</translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="668"/>
+ <source>Date: %1
+Amount: %2
+Type: %3
+Address: %4
+</source>
+ <translation>Date : %1
+Montant : %2
+Type : %3
+Adresse : %4
+</translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="793"/>
+ <source>Wallet is &lt;b&gt;encrypted&lt;/b&gt; and currently &lt;b&gt;unlocked&lt;/b&gt;</source>
+ <translation>Le porte-monnaie est &lt;b&gt;chiffré&lt;/b&gt; et est actuellement &lt;b&gt;déverrouillé&lt;/b&gt;</translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="801"/>
+ <source>Wallet is &lt;b&gt;encrypted&lt;/b&gt; and currently &lt;b&gt;locked&lt;/b&gt;</source>
+ <translation>Le porte-monnaie est &lt;b&gt;chiffré&lt;/b&gt; et est actuellement &lt;b&gt;verrouillé&lt;/b&gt;</translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="824"/>
+ <source>Backup Wallet</source>
+ <translation>Sauvegarder le porte-monnaie</translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="824"/>
+ <source>Wallet Data (*.dat)</source>
+ <translation>Données de porte-monnaie (*.dat)</translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="827"/>
+ <source>Backup Failed</source>
+ <translation>La sauvegarde a échoué</translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="827"/>
+ <source>There was an error trying to save the wallet data to the new location.</source>
+ <translation>Une erreur est survenue lors de l&apos;enregistrement des données de porte-monnaie à un autre emplacement.</translation>
+ </message>
+ <message>
+ <location filename="../bitcoin.cpp" line="127"/>
+ <source>A fatal error occured. Bitcoin can no longer continue safely and will quit.</source>
+ <translation>Une erreur fatale est survenue. Bitcoin ne peut plus continuer à fonctionner de façon sûre et va s&apos;arrêter.</translation>
+ </message>
+</context>
+<context>
+ <name>DisplayOptionsPage</name>
+ <message>
+ <location filename="../optionsdialog.cpp" line="273"/>
+ <source>&amp;Unit to show amounts in: </source>
+ <translation>&amp;Unité d&apos;affichage des montants : </translation>
+ </message>
+ <message>
+ <location filename="../optionsdialog.cpp" line="277"/>
+ <source>Choose the default subdivision unit to show in the interface, and when sending coins</source>
+ <translation>Choisissez la sous-unité par défaut pour l&apos;affichage dans l&apos;interface et lors de l&apos;envoi de pièces</translation>
+ </message>
+ <message>
+ <location filename="../optionsdialog.cpp" line="284"/>
+ <source>&amp;Display addresses in transaction list</source>
+ <translation>&amp;Afficher les adresses sur la liste des transactions</translation>
+ </message>
+ <message>
+ <location filename="../optionsdialog.cpp" line="285"/>
+ <source>Whether to show Bitcoin addresses in the transaction list</source>
+ <translation>Détermine si les adresses Bitcoin seront affichées sur la liste des transactions</translation>
+ </message>
+</context>
+<context>
+ <name>EditAddressDialog</name>
+ <message>
+ <location filename="../forms/editaddressdialog.ui" line="14"/>
+ <source>Edit Address</source>
+ <translation>Éditer l&apos;adresse</translation>
+ </message>
+ <message>
+ <location filename="../forms/editaddressdialog.ui" line="25"/>
+ <source>&amp;Label</source>
+ <translation>&amp;Étiquette</translation>
+ </message>
+ <message>
+ <location filename="../forms/editaddressdialog.ui" line="35"/>
+ <source>The label associated with this address book entry</source>
+ <translation>L&apos;étiquette associée à cette entrée du carnet d&apos;adresses</translation>
+ </message>
+ <message>
+ <location filename="../forms/editaddressdialog.ui" line="42"/>
+ <source>&amp;Address</source>
+ <translation>&amp;Adresse</translation>
+ </message>
+ <message>
+ <location filename="../forms/editaddressdialog.ui" line="52"/>
+ <source>The address associated with this address book entry. This can only be modified for sending addresses.</source>
+ <translation>L&apos;adresse associée avec cette entrée du carnet d&apos;adresses. Ne peut être modifiée que pour les adresses d&apos;envoi.</translation>
+ </message>
+ <message>
+ <location filename="../editaddressdialog.cpp" line="20"/>
+ <source>New receiving address</source>
+ <translation>Nouvelle adresse de réception</translation>
+ </message>
+ <message>
+ <location filename="../editaddressdialog.cpp" line="24"/>
+ <source>New sending address</source>
+ <translation>Nouvelle adresse d&apos;envoi</translation>
+ </message>
+ <message>
+ <location filename="../editaddressdialog.cpp" line="27"/>
+ <source>Edit receiving address</source>
+ <translation>Éditer l&apos;adresse de réception</translation>
+ </message>
+ <message>
+ <location filename="../editaddressdialog.cpp" line="31"/>
+ <source>Edit sending address</source>
+ <translation>Éditer l&apos;adresse d&apos;envoi</translation>
+ </message>
+ <message>
+ <location filename="../editaddressdialog.cpp" line="91"/>
+ <source>The entered address &quot;%1&quot; is already in the address book.</source>
+ <translation>L&apos;adresse fournie « %1 » est déjà présente dans le carnet d&apos;adresses.</translation>
+ </message>
+ <message>
+ <location filename="../editaddressdialog.cpp" line="96"/>
+ <source>The entered address &quot;%1&quot; is not a valid bitcoin address.</source>
+ <translation>L&apos;adresse fournie « %1 » n&apos;est pas une adresse Bitcoin valide.</translation>
+ </message>
+ <message>
+ <location filename="../editaddressdialog.cpp" line="101"/>
+ <source>Could not unlock wallet.</source>
+ <translation>Impossible de déverrouiller le porte-monnaie.</translation>
+ </message>
+ <message>
+ <location filename="../editaddressdialog.cpp" line="106"/>
+ <source>New key generation failed.</source>
+ <translation>Échec de la génération de la nouvelle clef.</translation>
+ </message>
+</context>
+<context>
+ <name>MainOptionsPage</name>
+ <message>
+ <location filename="../optionsdialog.cpp" line="171"/>
+ <source>&amp;Start Bitcoin on window system startup</source>
+ <translation>&amp;Démarrer Bitcoin avec le système de fenêtres</translation>
+ </message>
+ <message>
+ <location filename="../optionsdialog.cpp" line="172"/>
+ <source>Automatically start Bitcoin after the computer is turned on</source>
+ <translation>Lancer automatiquement Bitcoin lorsque l&apos;ordinateur est allumé</translation>
+ </message>
+ <message>
+ <location filename="../optionsdialog.cpp" line="176"/>
+ <source>&amp;Minimize to the tray instead of the taskbar</source>
+ <translation>&amp;Minimiser dans la barre système au lieu de la barre des tâches</translation>
+ </message>
+ <message>
+ <location filename="../optionsdialog.cpp" line="177"/>
+ <source>Show only a tray icon after minimizing the window</source>
+ <translation>Montrer uniquement une icône système après minimisation</translation>
+ </message>
+ <message>
+ <location filename="../optionsdialog.cpp" line="185"/>
+ <source>Map port using &amp;UPnP</source>
+ <translation>Ouvrir le port avec l&apos;&amp;UPnP</translation>
+ </message>
+ <message>
+ <location filename="../optionsdialog.cpp" line="186"/>
+ <source>Automatically open the Bitcoin client port on the router. This only works when your router supports UPnP and it is enabled.</source>
+ <translation>Ouvrir le port du client Bitcoin automatiquement sur le routeur. Cela ne fonctionne que si votre routeur supporte l&apos;UPnP et si la fonctionnalité est activée.</translation>
+ </message>
+ <message>
+ <location filename="../optionsdialog.cpp" line="180"/>
+ <source>M&amp;inimize on close</source>
+ <translation>Mi&amp;nimiser lors de la fermeture</translation>
+ </message>
+ <message>
+ <location filename="../optionsdialog.cpp" line="181"/>
+ <source>Minimize instead of exit the application when the window is closed. When this option is enabled, the application will be closed only after selecting Quit in the menu.</source>
+ <translation>Minimiser au lieu quitter l&apos;application lorsque la fenêtre est fermée. Lorsque cette option est activée, l&apos;application ne pourra être fermée qu&apos;en sélectionnant Quitter dans le menu déroulant.</translation>
+ </message>
+ <message>
+ <location filename="../optionsdialog.cpp" line="189"/>
+ <source>&amp;Connect through SOCKS4 proxy:</source>
+ <translation>&amp;Connexion à travers un proxy SOCKS4 :</translation>
+ </message>
+ <message>
+ <location filename="../optionsdialog.cpp" line="190"/>
+ <source>Connect to the Bitcon network through a SOCKS4 proxy (e.g. when connecting through Tor)</source>
+ <translation>Connexion au réseau Bitcoin à travers un proxy SOCKS4 (par ex. lors d&apos;une connexion via Tor)</translation>
+ </message>
+ <message>
+ <location filename="../optionsdialog.cpp" line="195"/>
+ <source>Proxy &amp;IP: </source>
+ <translation>&amp;IP du proxy : </translation>
+ </message>
+ <message>
+ <location filename="../optionsdialog.cpp" line="201"/>
+ <source>IP address of the proxy (e.g. 127.0.0.1)</source>
+ <translation>Adresse IP du proxy (par ex. 127.0.0.1)</translation>
+ </message>
+ <message>
+ <location filename="../optionsdialog.cpp" line="204"/>
+ <source>&amp;Port: </source>
+ <translation>&amp;Port : </translation>
+ </message>
+ <message>
+ <location filename="../optionsdialog.cpp" line="210"/>
+ <source>Port of the proxy (e.g. 1234)</source>
+ <translation>Port du proxy (par ex. 1234)</translation>
+ </message>
+ <message>
+ <location filename="../optionsdialog.cpp" line="232"/>
+ <source>Detach databases at shutdown</source>
+ <translation>Détacher les bases de données lors de la fermeture</translation>
+ </message>
+ <message>
+ <location filename="../optionsdialog.cpp" line="233"/>
+ <source>Detach block and address databases at shutdown. This means they can be moved to another data directory, but it slows down shutdown. The wallet is always detached.</source>
+ <translation>Détacher les bases de données des blocs et des adresses lors de la fermeture. Cela permet de les déplacer dans un autre répertoire de données mais ralentit la fermeture. Le porte-monnaie est toujours détaché.</translation>
+ </message>
+ <message>
+ <location filename="../optionsdialog.cpp" line="222"/>
+ <source>Pay transaction &amp;fee</source>
+ <translation>Payer des &amp;frais de transaction</translation>
+ </message>
+ <message>
+ <location filename="../optionsdialog.cpp" line="216"/>
+ <source>Optional transaction fee per kB that helps make sure your transactions are processed quickly. Most transactions are 1 kB. Fee 0.01 recommended.</source>
+ <translation>Frais de transaction optionnels par ko qui aident à garantir un traitement rapide des transactions. La plupart des transactions occupent 1 ko. Des frais de 0.01 sont recommandés.</translation>
+ </message>
+</context>
+<context>
+ <name>MessagePage</name>
+ <message>
+ <location filename="../forms/messagepage.ui" line="14"/>
+ <source>Message</source>
+ <translation>Message</translation>
+ </message>
+ <message>
+ <location filename="../forms/messagepage.ui" line="20"/>
+ <source>You can sign messages with your addresses to prove you own them. Be careful not to sign anything vague, as phishing attacks may try to trick you into signing your identity over to them. Only sign fully-detailed statements you agree to.</source>
+ <translation>Vous pouvez signer des messages avec vos adresses pour prouver que les détenez. Faites attention à ne pas signer quoi que ce soit de vague car des attaques d&apos;hameçonnage peuvent essayer d&apos;obtenir votre identité par votre signature. Ne signez que des déclarations entièrement détaillées et avec lesquelles vous serez d&apos;accord.</translation>
+ </message>
+ <message>
+ <location filename="../forms/messagepage.ui" line="38"/>
+ <source>The address to sign the message with (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L)</source>
+ <translation>L&apos;adresse avec laquelle le message sera signé ( par ex. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L)</translation>
+ </message>
+ <message>
+ <location filename="../forms/messagepage.ui" line="48"/>
+ <source>Choose adress from address book</source>
+ <translation>Choisir une adresse depuis le carnet d&apos;adresses</translation>
+ </message>
+ <message>
+ <location filename="../forms/messagepage.ui" line="58"/>
+ <source>Alt+A</source>
+ <translation>Alt+A</translation>
+ </message>
+ <message>
+ <location filename="../forms/messagepage.ui" line="71"/>
+ <source>Paste address from clipboard</source>
+ <translation>Coller une adresse depuis le presse-papiers</translation>
+ </message>
+ <message>
+ <location filename="../forms/messagepage.ui" line="81"/>
+ <source>Alt+P</source>
+ <translation>Alt+P</translation>
+ </message>
+ <message>
+ <location filename="../forms/messagepage.ui" line="93"/>
+ <source>Enter the message you want to sign here</source>
+ <translation>Entrez ici le message que vous désirez signer</translation>
+ </message>
+ <message>
+ <location filename="../forms/messagepage.ui" line="128"/>
+ <source>Copy the current signature to the system clipboard</source>
+ <translation>Copier la signature actuelle dans le presse-papiers</translation>
+ </message>
+ <message>
+ <location filename="../forms/messagepage.ui" line="131"/>
+ <source>&amp;Copy Signature</source>
+ <translation>&amp;Copier la signature</translation>
+ </message>
+ <message>
+ <location filename="../forms/messagepage.ui" line="142"/>
+ <source>Reset all sign message fields</source>
+ <translation>Remettre à zéro tous les champs de signature de message</translation>
+ </message>
+ <message>
+ <location filename="../forms/messagepage.ui" line="145"/>
+ <source>Clear &amp;All</source>
+ <translation>&amp;Tout nettoyer</translation>
+ </message>
+ <message>
+ <location filename="../messagepage.cpp" line="30"/>
+ <source>Click &quot;Sign Message&quot; to get signature</source>
+ <translation>Cliquez sur « Signer le message » pour obtenir la signature</translation>
+ </message>
+ <message>
+ <location filename="../forms/messagepage.ui" line="114"/>
+ <source>Sign a message to prove you own this address</source>
+ <translation>Signer le message pour prouver que vous détenez cette adresse</translation>
+ </message>
+ <message>
+ <location filename="../forms/messagepage.ui" line="117"/>
+ <source>&amp;Sign Message</source>
+ <translation>&amp;Signer le message</translation>
+ </message>
+ <message>
+ <location filename="../messagepage.cpp" line="79"/>
+ <location filename="../messagepage.cpp" line="94"/>
+ <location filename="../messagepage.cpp" line="106"/>
+ <source>Error signing</source>
+ <translation>Une erreur est survenue lors de la signature</translation>
+ </message>
+ <message>
+ <location filename="../messagepage.cpp" line="79"/>
+ <source>%1 is not a valid address.</source>
+ <translation>%1 n&apos;est pas une adresse valide.</translation>
+ </message>
+ <message>
+ <location filename="../messagepage.cpp" line="94"/>
+ <source>Private key for %1 is not available.</source>
+ <translation>La clef privée pour %1 n&apos;est pas disponible.</translation>
+ </message>
+ <message>
+ <location filename="../messagepage.cpp" line="106"/>
+ <source>Sign failed</source>
+ <translation>Échec de la signature</translation>
+ </message>
+</context>
+<context>
+ <name>OptionsDialog</name>
+ <message>
+ <location filename="../optionsdialog.cpp" line="80"/>
+ <source>Main</source>
+ <translation>Principal</translation>
+ </message>
+ <message>
+ <location filename="../optionsdialog.cpp" line="85"/>
+ <source>Display</source>
+ <translation>Affichage</translation>
+ </message>
+ <message>
+ <location filename="../optionsdialog.cpp" line="105"/>
+ <source>Options</source>
+ <translation>Options</translation>
+ </message>
+</context>
+<context>
+ <name>OverviewPage</name>
+ <message>
+ <location filename="../forms/overviewpage.ui" line="14"/>
+ <source>Form</source>
+ <translation>Formulaire</translation>
+ </message>
+ <message>
+ <location filename="../forms/overviewpage.ui" line="40"/>
+ <source>Balance:</source>
+ <translation>Solde :</translation>
+ </message>
+ <message>
+ <location filename="../forms/overviewpage.ui" line="47"/>
+ <source>123.456 BTC</source>
+ <translation>123.456 BTC</translation>
+ </message>
+ <message>
+ <location filename="../forms/overviewpage.ui" line="54"/>
+ <source>Number of transactions:</source>
+ <translation>Nombre de transactions :</translation>
+ </message>
+ <message>
+ <location filename="../forms/overviewpage.ui" line="61"/>
+ <source>0</source>
+ <translation>0</translation>
+ </message>
+ <message>
+ <location filename="../forms/overviewpage.ui" line="68"/>
+ <source>Unconfirmed:</source>
+ <translation>Non confirmé :</translation>
+ </message>
+ <message>
+ <location filename="../forms/overviewpage.ui" line="75"/>
+ <source>0 BTC</source>
+ <translation>0 BTC</translation>
+ </message>
+ <message>
+ <location filename="../forms/overviewpage.ui" line="88"/>
+ <source>Wallet</source>
+ <translation>Porte-monnaie</translation>
+ </message>
+ <message>
+ <location filename="../forms/overviewpage.ui" line="124"/>
+ <source>&lt;b&gt;Recent transactions&lt;/b&gt;</source>
+ <translation>&lt;b&gt;Transactions récentes&lt;/b&gt;</translation>
+ </message>
+ <message>
+ <location filename="../overviewpage.cpp" line="103"/>
+ <source>Your current balance</source>
+ <translation>Votre solde actuel</translation>
+ </message>
+ <message>
+ <location filename="../overviewpage.cpp" line="108"/>
+ <source>Total of transactions that have yet to be confirmed, and do not yet count toward the current balance</source>
+ <translation>Total des transactions qui doivent encore être confirmées et qui ne sont pas prises en compte pour le solde actuel</translation>
+ </message>
+ <message>
+ <location filename="../overviewpage.cpp" line="111"/>
+ <source>Total number of transactions in wallet</source>
+ <translation>Nombre total de transactions dans le porte-monnaie</translation>
+ </message>
+</context>
+<context>
+ <name>QRCodeDialog</name>
+ <message>
+ <location filename="../forms/qrcodedialog.ui" line="14"/>
+ <source>QR-Code Dialog</source>
+ <translation>Dialogue de QR Code</translation>
+ </message>
+ <message>
+ <location filename="../forms/qrcodedialog.ui" line="32"/>
+ <source>QR Code</source>
+ <translation>QR Code</translation>
+ </message>
+ <message>
+ <location filename="../forms/qrcodedialog.ui" line="55"/>
+ <source>Request Payment</source>
+ <translation>Demande de paiement</translation>
+ </message>
+ <message>
+ <location filename="../forms/qrcodedialog.ui" line="70"/>
+ <source>Amount:</source>
+ <translation>Montant :</translation>
+ </message>
+ <message>
+ <location filename="../forms/qrcodedialog.ui" line="105"/>
+ <source>BTC</source>
+ <translation>BTC</translation>
+ </message>
+ <message>
+ <location filename="../forms/qrcodedialog.ui" line="121"/>
+ <source>Label:</source>
+ <translation>Étiquette :</translation>
+ </message>
+ <message>
+ <location filename="../forms/qrcodedialog.ui" line="144"/>
+ <source>Message:</source>
+ <translation>Message :</translation>
+ </message>
+ <message>
+ <location filename="../forms/qrcodedialog.ui" line="186"/>
+ <source>&amp;Save As...</source>
+ <translation>&amp;Enregistrer sous...</translation>
+ </message>
+ <message>
+ <location filename="../qrcodedialog.cpp" line="46"/>
+ <source>Error encoding URI into QR Code.</source>
+ <translation>Erreur de l&apos;encodage de l&apos;URI dans le QR Code.</translation>
+ </message>
+ <message>
+ <location filename="../qrcodedialog.cpp" line="64"/>
+ <source>Resulting URI too long, try to reduce the text for label / message.</source>
+ <translation>L&apos;URI résultant est trop long, essayez avec un texte d&apos;étiquette ou de message plus court.</translation>
+ </message>
+ <message>
+ <location filename="../qrcodedialog.cpp" line="121"/>
+ <source>Save QR Code</source>
+ <translation>Sauvegarder le QR Code</translation>
+ </message>
+ <message>
+ <location filename="../qrcodedialog.cpp" line="121"/>
+ <source>PNG Images (*.png)</source>
+ <translation>Images PNG (*.png)</translation>
+ </message>
+</context>
+<context>
+ <name>RPCConsole</name>
+ <message>
+ <location filename="../forms/rpcconsole.ui" line="14"/>
+ <source>Bitcoin debug window</source>
+ <translation>Fenêtre de débogage de Bitcoin</translation>
+ </message>
+ <message>
+ <location filename="../forms/rpcconsole.ui" line="24"/>
+ <source>Information</source>
+ <translation>Informations</translation>
+ </message>
+ <message>
+ <location filename="../forms/rpcconsole.ui" line="33"/>
+ <source>Client name</source>
+ <translation>Nom du client</translation>
+ </message>
+ <message>
+ <location filename="../forms/rpcconsole.ui" line="40"/>
+ <location filename="../forms/rpcconsole.ui" line="60"/>
+ <location filename="../forms/rpcconsole.ui" line="106"/>
+ <location filename="../forms/rpcconsole.ui" line="156"/>
+ <location filename="../forms/rpcconsole.ui" line="176"/>
+ <location filename="../forms/rpcconsole.ui" line="196"/>
+ <location filename="../forms/rpcconsole.ui" line="229"/>
+ <source>N/A</source>
+ <translation>Indisponible</translation>
+ </message>
+ <message>
+ <location filename="../forms/rpcconsole.ui" line="53"/>
+ <source>Client version</source>
+ <translation>Version du client</translation>
+ </message>
+ <message>
+ <location filename="../forms/rpcconsole.ui" line="79"/>
+ <source>Version</source>
+ <translation>Version</translation>
+ </message>
+ <message>
+ <location filename="../forms/rpcconsole.ui" line="92"/>
+ <source>Network</source>
+ <translation>Réseau</translation>
+ </message>
+ <message>
+ <location filename="../forms/rpcconsole.ui" line="99"/>
+ <source>Number of connections</source>
+ <translation>Nombre de connexions</translation>
+ </message>
+ <message>
+ <location filename="../forms/rpcconsole.ui" line="119"/>
+ <source>On testnet</source>
+ <translation>Sur testnet</translation>
+ </message>
+ <message>
+ <location filename="../forms/rpcconsole.ui" line="142"/>
+ <source>Block chain</source>
+ <translation>Chaîne de blocs</translation>
+ </message>
+ <message>
+ <location filename="../forms/rpcconsole.ui" line="149"/>
+ <source>Current number of blocks</source>
+ <translation>Nombre actuel de blocs</translation>
+ </message>
+ <message>
+ <location filename="../forms/rpcconsole.ui" line="169"/>
+ <source>Estimated total blocks</source>
+ <translation>Nombre total estimé de blocs</translation>
+ </message>
+ <message>
+ <location filename="../forms/rpcconsole.ui" line="189"/>
+ <source>Last block time</source>
+ <translation>Horodatage du dernier bloc</translation>
+ </message>
+ <message>
+ <location filename="../forms/rpcconsole.ui" line="222"/>
+ <source>Build date</source>
+ <translation>Date de compilation</translation>
+ </message>
+ <message>
+ <location filename="../forms/rpcconsole.ui" line="237"/>
+ <source>Console</source>
+ <translation>Console</translation>
+ </message>
+ <message>
+ <location filename="../forms/rpcconsole.ui" line="278"/>
+ <source>&gt;</source>
+ <translation>&gt;</translation>
+ </message>
+ <message>
+ <location filename="../forms/rpcconsole.ui" line="294"/>
+ <source>Clear console</source>
+ <translation>Nettoyer la console</translation>
+ </message>
+ <message>
+ <location filename="../rpcconsole.cpp" line="97"/>
+ <source>&amp;Copy</source>
+ <translation>&amp;Copier</translation>
+ </message>
+ <message>
+ <location filename="../rpcconsole.cpp" line="195"/>
+ <source>Welcome to the bitcoin RPC console.</source>
+ <translation>Bienvenue sur la console RPC de Bitcoin.</translation>
+ </message>
+ <message>
+ <location filename="../rpcconsole.cpp" line="196"/>
+ <source>Use up and down arrows to navigate history, and Ctrl-L to clear screen.</source>
+ <translation>Utilisez les touches de curseur pour naviguer dans l&apos;historique et Ctrl-L pour effacer l&apos;écran.</translation>
+ </message>
+ <message>
+ <location filename="../rpcconsole.cpp" line="197"/>
+ <source>Type &quot;help&quot; for an overview of available commands.</source>
+ <translation>Tapez « help » pour afficher une vue générale des commandes disponibles.</translation>
+ </message>
+</context>
+<context>
+ <name>SendCoinsDialog</name>
+ <message>
+ <location filename="../forms/sendcoinsdialog.ui" line="14"/>
+ <location filename="../sendcoinsdialog.cpp" line="122"/>
+ <location filename="../sendcoinsdialog.cpp" line="127"/>
+ <location filename="../sendcoinsdialog.cpp" line="132"/>
+ <location filename="../sendcoinsdialog.cpp" line="137"/>
+ <location filename="../sendcoinsdialog.cpp" line="143"/>
+ <location filename="../sendcoinsdialog.cpp" line="148"/>
+ <location filename="../sendcoinsdialog.cpp" line="153"/>
+ <source>Send Coins</source>
+ <translation>Envoyer des pièces</translation>
+ </message>
+ <message>
+ <location filename="../forms/sendcoinsdialog.ui" line="64"/>
+ <source>Send to multiple recipients at once</source>
+ <translation>Envoyer des pièces à plusieurs destinataires à la fois</translation>
+ </message>
+ <message>
+ <location filename="../forms/sendcoinsdialog.ui" line="67"/>
+ <source>&amp;Add Recipient</source>
+ <translation>&amp;Ajouter un destinataire</translation>
+ </message>
+ <message>
+ <location filename="../forms/sendcoinsdialog.ui" line="84"/>
+ <source>Remove all transaction fields</source>
+ <translation>Enlever tous les champs de transaction</translation>
+ </message>
+ <message>
+ <location filename="../forms/sendcoinsdialog.ui" line="87"/>
+ <source>Clear all</source>
+ <translation>Tout effacer</translation>
+ </message>
+ <message>
+ <location filename="../forms/sendcoinsdialog.ui" line="106"/>
+ <source>Balance:</source>
+ <translation>Solde :</translation>
+ </message>
+ <message>
+ <location filename="../forms/sendcoinsdialog.ui" line="113"/>
+ <source>123.456 BTC</source>
+ <translation>123.456 BTC</translation>
+ </message>
+ <message>
+ <location filename="../forms/sendcoinsdialog.ui" line="144"/>
+ <source>Confirm the send action</source>
+ <translation>Confirmer l&apos;action d&apos;envoi</translation>
+ </message>
+ <message>
+ <location filename="../forms/sendcoinsdialog.ui" line="147"/>
+ <source>&amp;Send</source>
+ <translation>&amp;Envoyer</translation>
+ </message>
+ <message>
+ <location filename="../sendcoinsdialog.cpp" line="94"/>
+ <source>&lt;b&gt;%1&lt;/b&gt; to %2 (%3)</source>
+ <translation>&lt;b&gt;%1&lt;/b&gt; à %2 (%3)</translation>
+ </message>
+ <message>
+ <location filename="../sendcoinsdialog.cpp" line="99"/>
+ <source>Confirm send coins</source>
+ <translation>Confirmer l&apos;envoi des pièces</translation>
+ </message>
+ <message>
+ <location filename="../sendcoinsdialog.cpp" line="100"/>
+ <source>Are you sure you want to send %1?</source>
+ <translation>Êtes-vous sûr de vouloir envoyer %1 ?</translation>
+ </message>
+ <message>
+ <location filename="../sendcoinsdialog.cpp" line="100"/>
+ <source> and </source>
+ <translation> et </translation>
+ </message>
+ <message>
+ <location filename="../sendcoinsdialog.cpp" line="123"/>
+ <source>The recepient address is not valid, please recheck.</source>
+ <translation>L&apos;adresse du destinataire n&apos;est pas valide, veuillez la vérifier.</translation>
+ </message>
+ <message>
+ <location filename="../sendcoinsdialog.cpp" line="128"/>
+ <source>The amount to pay must be larger than 0.</source>
+ <translation>Le montant à payer doit être supérieur à 0.</translation>
+ </message>
+ <message>
+ <location filename="../sendcoinsdialog.cpp" line="133"/>
+ <source>Amount exceeds your balance</source>
+ <translation>Le montant dépasse votre solde</translation>
+ </message>
+ <message>
+ <location filename="../sendcoinsdialog.cpp" line="138"/>
+ <source>Total exceeds your balance when the %1 transaction fee is included</source>
+ <translation>Le total dépasse votre solde lorsque les frais de transaction de %1 sont inclus</translation>
+ </message>
+ <message>
+ <location filename="../sendcoinsdialog.cpp" line="144"/>
+ <source>Duplicate address found, can only send to each address once in one send operation</source>
+ <translation>Adresse dupliquée trouvée, un seul envoi par adresse est possible à chaque opération d&apos;envoi</translation>
+ </message>
+ <message>
+ <location filename="../sendcoinsdialog.cpp" line="149"/>
+ <source>Error: Transaction creation failed </source>
+ <translation>Erreur : échec de la création de la transaction </translation>
+ </message>
+ <message>
+ <location filename="../sendcoinsdialog.cpp" line="154"/>
+ <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>Erreur : la transaction a été rejetée. Cela peut arriver si certaines pièces de votre porte-monnaie ont déjà été dépensées, par exemple si vous avez utilisé une copie de wallet.dat et si des pièces ont été dépensées avec cette copie sans être marquées comme telles ici.</translation>
+ </message>
+</context>
+<context>
+ <name>SendCoinsEntry</name>
+ <message>
+ <location filename="../forms/sendcoinsentry.ui" line="14"/>
+ <source>Form</source>
+ <translation>Formulaire</translation>
+ </message>
+ <message>
+ <location filename="../forms/sendcoinsentry.ui" line="29"/>
+ <source>A&amp;mount:</source>
+ <translation>&amp;Montant :</translation>
+ </message>
+ <message>
+ <location filename="../forms/sendcoinsentry.ui" line="42"/>
+ <source>Pay &amp;To:</source>
+ <translation>Payer &amp;à :</translation>
+ </message>
+ <message>
+ <location filename="../forms/sendcoinsentry.ui" line="66"/>
+ <location filename="../sendcoinsentry.cpp" line="25"/>
+ <source>Enter a label for this address to add it to your address book</source>
+ <translation>Entrez une étiquette pour cette adresse afin de l&apos;ajouter à votre carnet d&apos;adresses</translation>
+ </message>
+ <message>
+ <location filename="../forms/sendcoinsentry.ui" line="75"/>
+ <source>&amp;Label:</source>
+ <translation>&amp;Étiquette :</translation>
+ </message>
+ <message>
+ <location filename="../forms/sendcoinsentry.ui" line="93"/>
+ <source>The address to send the payment to (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L)</source>
+ <translation>L&apos;adresse à laquelle le paiement sera envoyé (par ex. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L)</translation>
+ </message>
+ <message>
+ <location filename="../forms/sendcoinsentry.ui" line="103"/>
+ <source>Choose address from address book</source>
+ <translation>Choisir une adresse dans le carnet d&apos;adresses</translation>
+ </message>
+ <message>
+ <location filename="../forms/sendcoinsentry.ui" line="113"/>
+ <source>Alt+A</source>
+ <translation>Alt+A</translation>
+ </message>
+ <message>
+ <location filename="../forms/sendcoinsentry.ui" line="120"/>
+ <source>Paste address from clipboard</source>
+ <translation>Coller une adresse depuis le presse-papiers</translation>
+ </message>
+ <message>
+ <location filename="../forms/sendcoinsentry.ui" line="130"/>
+ <source>Alt+P</source>
+ <translation>Alt+P</translation>
+ </message>
+ <message>
+ <location filename="../forms/sendcoinsentry.ui" line="137"/>
+ <source>Remove this recipient</source>
+ <translation>Enlever ce destinataire</translation>
+ </message>
+ <message>
+ <location filename="../sendcoinsentry.cpp" line="26"/>
+ <source>Enter a Bitcoin address (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L)</source>
+ <translation>Entrez une adresse Bitcoin (par ex. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L)</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionDesc</name>
+ <message>
+ <location filename="../transactiondesc.cpp" line="20"/>
+ <source>Open for %1 blocks</source>
+ <translation>Ouvert pour %1 blocs</translation>
+ </message>
+ <message>
+ <location filename="../transactiondesc.cpp" line="22"/>
+ <source>Open until %1</source>
+ <translation>Ouvert jusqu&apos;à %1</translation>
+ </message>
+ <message>
+ <location filename="../transactiondesc.cpp" line="28"/>
+ <source>%1/offline?</source>
+ <translation>%1/hors ligne ?</translation>
+ </message>
+ <message>
+ <location filename="../transactiondesc.cpp" line="30"/>
+ <source>%1/unconfirmed</source>
+ <translation>%1/non confirmée</translation>
+ </message>
+ <message>
+ <location filename="../transactiondesc.cpp" line="32"/>
+ <source>%1 confirmations</source>
+ <translation>%1 confirmations</translation>
+ </message>
+ <message>
+ <location filename="../transactiondesc.cpp" line="50"/>
+ <source>&lt;b&gt;Status:&lt;/b&gt; </source>
+ <translation>&lt;b&gt;État :&lt;/b&gt; </translation>
+ </message>
+ <message>
+ <location filename="../transactiondesc.cpp" line="55"/>
+ <source>, has not been successfully broadcast yet</source>
+ <translation>, n&apos;a pas encore été diffusée avec succès</translation>
+ </message>
+ <message>
+ <location filename="../transactiondesc.cpp" line="57"/>
+ <source>, broadcast through %1 node</source>
+ <translation>, diffusée à travers %1 nœud</translation>
+ </message>
+ <message>
+ <location filename="../transactiondesc.cpp" line="59"/>
+ <source>, broadcast through %1 nodes</source>
+ <translation>, diffusée à travers %1 nœuds</translation>
+ </message>
+ <message>
+ <location filename="../transactiondesc.cpp" line="63"/>
+ <source>&lt;b&gt;Date:&lt;/b&gt; </source>
+ <translation>&lt;b&gt;Date :&lt;/b&gt; </translation>
+ </message>
+ <message>
+ <location filename="../transactiondesc.cpp" line="70"/>
+ <source>&lt;b&gt;Source:&lt;/b&gt; Generated&lt;br&gt;</source>
+ <translation>&lt;b&gt;Source :&lt;/b&gt; Généré&lt;br&gt;</translation>
+ </message>
+ <message>
+ <location filename="../transactiondesc.cpp" line="76"/>
+ <location filename="../transactiondesc.cpp" line="93"/>
+ <source>&lt;b&gt;From:&lt;/b&gt; </source>
+ <translation>&lt;b&gt;De :&lt;/b&gt; </translation>
+ </message>
+ <message>
+ <location filename="../transactiondesc.cpp" line="93"/>
+ <source>unknown</source>
+ <translation>inconnu</translation>
+ </message>
+ <message>
+ <location filename="../transactiondesc.cpp" line="94"/>
+ <location filename="../transactiondesc.cpp" line="117"/>
+ <location filename="../transactiondesc.cpp" line="176"/>
+ <source>&lt;b&gt;To:&lt;/b&gt; </source>
+ <translation>&lt;b&gt;À :&lt;/b&gt; </translation>
+ </message>
+ <message>
+ <location filename="../transactiondesc.cpp" line="97"/>
+ <source> (yours, label: </source>
+ <translation> (vôtre, étiquette : </translation>
+ </message>
+ <message>
+ <location filename="../transactiondesc.cpp" line="99"/>
+ <source> (yours)</source>
+ <translation> (vôtre)</translation>
+ </message>
+ <message>
+ <location filename="../transactiondesc.cpp" line="134"/>
+ <location filename="../transactiondesc.cpp" line="148"/>
+ <location filename="../transactiondesc.cpp" line="193"/>
+ <location filename="../transactiondesc.cpp" line="210"/>
+ <source>&lt;b&gt;Credit:&lt;/b&gt; </source>
+ <translation>&lt;b&gt;Crédit : &lt;/b&gt; </translation>
+ </message>
+ <message>
+ <location filename="../transactiondesc.cpp" line="136"/>
+ <source>(%1 matures in %2 more blocks)</source>
+ <translation>(%1 sera considérée comme mûre suite à %2 blocs de plus)</translation>
+ </message>
+ <message>
+ <location filename="../transactiondesc.cpp" line="140"/>
+ <source>(not accepted)</source>
+ <translation>(pas accepté)</translation>
+ </message>
+ <message>
+ <location filename="../transactiondesc.cpp" line="184"/>
+ <location filename="../transactiondesc.cpp" line="192"/>
+ <location filename="../transactiondesc.cpp" line="207"/>
+ <source>&lt;b&gt;Debit:&lt;/b&gt; </source>
+ <translation>&lt;b&gt;Débit : &lt;/b&gt; </translation>
+ </message>
+ <message>
+ <location filename="../transactiondesc.cpp" line="198"/>
+ <source>&lt;b&gt;Transaction fee:&lt;/b&gt; </source>
+ <translation>&lt;b&gt;Frais de transaction :&lt;/b&gt; </translation>
+ </message>
+ <message>
+ <location filename="../transactiondesc.cpp" line="214"/>
+ <source>&lt;b&gt;Net amount:&lt;/b&gt; </source>
+ <translation>&lt;b&gt;Montant net :&lt;/b&gt; </translation>
+ </message>
+ <message>
+ <location filename="../transactiondesc.cpp" line="220"/>
+ <source>Message:</source>
+ <translation>Message :</translation>
+ </message>
+ <message>
+ <location filename="../transactiondesc.cpp" line="222"/>
+ <source>Comment:</source>
+ <translation>Commentaire :</translation>
+ </message>
+ <message>
+ <location filename="../transactiondesc.cpp" line="224"/>
+ <source>Transaction ID:</source>
+ <translation>ID de la transaction :</translation>
+ </message>
+ <message>
+ <location filename="../transactiondesc.cpp" line="227"/>
+ <source>Generated coins must wait 120 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, it will change to &quot;not accepted&quot; and not be spendable. This may occasionally happen if another node generates a block within a few seconds of yours.</source>
+ <translation>Les pièces générées doivent attendre 120 blocs avant de pouvoir être dépensées. Lorsque vous avez généré ce bloc, il a été diffusé sur le réseau pour être ajouté à la chaîne des blocs. S&apos;il échoue a intégrer la chaîne, il sera modifié en « pas accepté » et il ne sera pas possible de le dépenser. Cela peut arriver occasionnellement si un autre nœud génère un bloc quelques secondes avant ou après vous.</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionDescDialog</name>
+ <message>
+ <location filename="../forms/transactiondescdialog.ui" line="14"/>
+ <source>Transaction details</source>
+ <translation>Détails de la transaction</translation>
+ </message>
+ <message>
+ <location filename="../forms/transactiondescdialog.ui" line="20"/>
+ <source>This pane shows a detailed description of the transaction</source>
+ <translation>Ce panneau affiche une description détaillée de la transaction</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionTableModel</name>
+ <message>
+ <location filename="../transactiontablemodel.cpp" line="214"/>
+ <source>Date</source>
+ <translation>Date</translation>
+ </message>
+ <message>
+ <location filename="../transactiontablemodel.cpp" line="214"/>
+ <source>Type</source>
+ <translation>Type</translation>
+ </message>
+ <message>
+ <location filename="../transactiontablemodel.cpp" line="214"/>
+ <source>Address</source>
+ <translation>Adresse</translation>
+ </message>
+ <message>
+ <location filename="../transactiontablemodel.cpp" line="214"/>
+ <source>Amount</source>
+ <translation>Montant</translation>
+ </message>
+ <message numerus="yes">
+ <location filename="../transactiontablemodel.cpp" line="275"/>
+ <source>Open for %n block(s)</source>
+ <translation><numerusform>Ouvert pour %n bloc</numerusform><numerusform>Ouvert pour %n blocs</numerusform></translation>
+ </message>
+ <message>
+ <location filename="../transactiontablemodel.cpp" line="278"/>
+ <source>Open until %1</source>
+ <translation>Ouvert jusqu&apos;à %1</translation>
+ </message>
+ <message>
+ <location filename="../transactiontablemodel.cpp" line="281"/>
+ <source>Offline (%1 confirmations)</source>
+ <translation>Hors ligne (%1 confirmations)</translation>
+ </message>
+ <message>
+ <location filename="../transactiontablemodel.cpp" line="284"/>
+ <source>Unconfirmed (%1 of %2 confirmations)</source>
+ <translation>Non confirmée (%1 confirmations sur un total de %2)</translation>
+ </message>
+ <message>
+ <location filename="../transactiontablemodel.cpp" line="287"/>
+ <source>Confirmed (%1 confirmations)</source>
+ <translation>Confirmée (%1 confirmations)</translation>
+ </message>
+ <message numerus="yes">
+ <location filename="../transactiontablemodel.cpp" line="295"/>
+ <source>Mined balance will be available in %n more blocks</source>
+ <translation><numerusform>Le solde d&apos;extraction (mined) sera disponible dans %n bloc</numerusform><numerusform>Le solde d&apos;extraction (mined) sera disponible dans %n blocs</numerusform></translation>
+ </message>
+ <message>
+ <location filename="../transactiontablemodel.cpp" line="301"/>
+ <source>This block was not received by any other nodes and will probably not be accepted!</source>
+ <translation>Ce bloc n&apos;a été reçu par aucun autre nœud et ne sera probablement pas accepté !</translation>
+ </message>
+ <message>
+ <location filename="../transactiontablemodel.cpp" line="304"/>
+ <source>Generated but not accepted</source>
+ <translation>Généré mais pas accepté</translation>
+ </message>
+ <message>
+ <location filename="../transactiontablemodel.cpp" line="347"/>
+ <source>Received with</source>
+ <translation>Reçue avec</translation>
+ </message>
+ <message>
+ <location filename="../transactiontablemodel.cpp" line="349"/>
+ <source>Received from</source>
+ <translation>Reçue de</translation>
+ </message>
+ <message>
+ <location filename="../transactiontablemodel.cpp" line="352"/>
+ <source>Sent to</source>
+ <translation>Envoyée à</translation>
+ </message>
+ <message>
+ <location filename="../transactiontablemodel.cpp" line="354"/>
+ <source>Payment to yourself</source>
+ <translation>Paiement à vous-même</translation>
+ </message>
+ <message>
+ <location filename="../transactiontablemodel.cpp" line="356"/>
+ <source>Mined</source>
+ <translation>Extraction</translation>
+ </message>
+ <message>
+ <location filename="../transactiontablemodel.cpp" line="394"/>
+ <source>(n/a)</source>
+ <translation>(indisponible)</translation>
+ </message>
+ <message>
+ <location filename="../transactiontablemodel.cpp" line="593"/>
+ <source>Transaction status. Hover over this field to show number of confirmations.</source>
+ <translation>État de la transaction. Laissez le pointeur de la souris sur ce champ pour voir le nombre de confirmations.</translation>
+ </message>
+ <message>
+ <location filename="../transactiontablemodel.cpp" line="595"/>
+ <source>Date and time that the transaction was received.</source>
+ <translation>Date et heure de réception de la transaction.</translation>
+ </message>
+ <message>
+ <location filename="../transactiontablemodel.cpp" line="597"/>
+ <source>Type of transaction.</source>
+ <translation>Type de transaction.</translation>
+ </message>
+ <message>
+ <location filename="../transactiontablemodel.cpp" line="599"/>
+ <source>Destination address of transaction.</source>
+ <translation>L&apos;adresse de destination de la transaction.</translation>
+ </message>
+ <message>
+ <location filename="../transactiontablemodel.cpp" line="601"/>
+ <source>Amount removed from or added to balance.</source>
+ <translation>Montant ajouté au ou enlevé du solde.</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionView</name>
+ <message>
+ <location filename="../transactionview.cpp" line="55"/>
+ <location filename="../transactionview.cpp" line="71"/>
+ <source>All</source>
+ <translation>Toutes</translation>
+ </message>
+ <message>
+ <location filename="../transactionview.cpp" line="56"/>
+ <source>Today</source>
+ <translation>Aujourd&apos;hui</translation>
+ </message>
+ <message>
+ <location filename="../transactionview.cpp" line="57"/>
+ <source>This week</source>
+ <translation>Cette semaine</translation>
+ </message>
+ <message>
+ <location filename="../transactionview.cpp" line="58"/>
+ <source>This month</source>
+ <translation>Ce mois</translation>
+ </message>
+ <message>
+ <location filename="../transactionview.cpp" line="59"/>
+ <source>Last month</source>
+ <translation>Mois dernier</translation>
+ </message>
+ <message>
+ <location filename="../transactionview.cpp" line="60"/>
+ <source>This year</source>
+ <translation>Cette année</translation>
+ </message>
+ <message>
+ <location filename="../transactionview.cpp" line="61"/>
+ <source>Range...</source>
+ <translation>Intervalle...</translation>
+ </message>
+ <message>
+ <location filename="../transactionview.cpp" line="72"/>
+ <source>Received with</source>
+ <translation>Reçues avec</translation>
+ </message>
+ <message>
+ <location filename="../transactionview.cpp" line="74"/>
+ <source>Sent to</source>
+ <translation>Envoyées à</translation>
+ </message>
+ <message>
+ <location filename="../transactionview.cpp" line="76"/>
+ <source>To yourself</source>
+ <translation>À vous-même</translation>
+ </message>
+ <message>
+ <location filename="../transactionview.cpp" line="77"/>
+ <source>Mined</source>
+ <translation>Extraction</translation>
+ </message>
+ <message>
+ <location filename="../transactionview.cpp" line="78"/>
+ <source>Other</source>
+ <translation>Autres</translation>
+ </message>
+ <message>
+ <location filename="../transactionview.cpp" line="84"/>
+ <source>Enter address or label to search</source>
+ <translation>Entrez une adresse ou une étiquette à rechercher</translation>
+ </message>
+ <message>
+ <location filename="../transactionview.cpp" line="90"/>
+ <source>Min amount</source>
+ <translation>Montant min</translation>
+ </message>
+ <message>
+ <location filename="../transactionview.cpp" line="124"/>
+ <source>Copy address</source>
+ <translation>Copier l&apos;adresse</translation>
+ </message>
+ <message>
+ <location filename="../transactionview.cpp" line="125"/>
+ <source>Copy label</source>
+ <translation>Copier l&apos;étiquette</translation>
+ </message>
+ <message>
+ <location filename="../transactionview.cpp" line="126"/>
+ <source>Copy amount</source>
+ <translation>Copier le montant</translation>
+ </message>
+ <message>
+ <location filename="../transactionview.cpp" line="127"/>
+ <source>Edit label</source>
+ <translation>Éditer l&apos;étiquette</translation>
+ </message>
+ <message>
+ <location filename="../transactionview.cpp" line="128"/>
+ <source>Show transaction details</source>
+ <translation>Afficher les détails de la transaction</translation>
+ </message>
+ <message>
+ <location filename="../transactionview.cpp" line="268"/>
+ <source>Export Transaction Data</source>
+ <translation>Exporter les données des transactions</translation>
+ </message>
+ <message>
+ <location filename="../transactionview.cpp" line="269"/>
+ <source>Comma separated file (*.csv)</source>
+ <translation>Valeurs séparées par des virgules (*.csv)</translation>
+ </message>
+ <message>
+ <location filename="../transactionview.cpp" line="277"/>
+ <source>Confirmed</source>
+ <translation>Confirmée</translation>
+ </message>
+ <message>
+ <location filename="../transactionview.cpp" line="278"/>
+ <source>Date</source>
+ <translation>Date</translation>
+ </message>
+ <message>
+ <location filename="../transactionview.cpp" line="279"/>
+ <source>Type</source>
+ <translation>Type</translation>
+ </message>
+ <message>
+ <location filename="../transactionview.cpp" line="280"/>
+ <source>Label</source>
+ <translation>Étiquette</translation>
+ </message>
+ <message>
+ <location filename="../transactionview.cpp" line="281"/>
+ <source>Address</source>
+ <translation>Adresse</translation>
+ </message>
+ <message>
+ <location filename="../transactionview.cpp" line="282"/>
+ <source>Amount</source>
+ <translation>Montant</translation>
+ </message>
+ <message>
+ <location filename="../transactionview.cpp" line="283"/>
+ <source>ID</source>
+ <translation>ID</translation>
+ </message>
+ <message>
+ <location filename="../transactionview.cpp" line="287"/>
+ <source>Error exporting</source>
+ <translation>Erreur lors de l&apos;exportation</translation>
+ </message>
+ <message>
+ <location filename="../transactionview.cpp" line="287"/>
+ <source>Could not write to file %1.</source>
+ <translation>Impossible d&apos;écrire sur le fichier %1.</translation>
+ </message>
+ <message>
+ <location filename="../transactionview.cpp" line="382"/>
+ <source>Range:</source>
+ <translation>Intervalle :</translation>
+ </message>
+ <message>
+ <location filename="../transactionview.cpp" line="390"/>
+ <source>to</source>
+ <translation>à</translation>
+ </message>
+</context>
+<context>
+ <name>WalletModel</name>
+ <message>
+ <location filename="../walletmodel.cpp" line="142"/>
+ <source>Sending...</source>
+ <translation>Envoi en cours...</translation>
+ </message>
+</context>
+<context>
+ <name>bitcoin-core</name>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="12"/>
+ <source>Bitcoin version</source>
+ <translation>Version de Bitcoin</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="13"/>
+ <source>Usage:</source>
+ <translation>Utilisation :</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="14"/>
+ <source>Send command to -server or bitcoind</source>
+ <translation>Envoyer une commande à -server ou à bitcoind</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="15"/>
+ <source>List commands</source>
+ <translation>Lister les commandes</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="16"/>
+ <source>Get help for a command</source>
+ <translation>Obtenir de l&apos;aide pour une commande</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="17"/>
+ <source>Options:</source>
+ <translation>Options :</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="18"/>
+ <source>Specify configuration file (default: bitcoin.conf)</source>
+ <translation>Spécifier le fichier de configuration (par défaut : bitcoin.conf)</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="19"/>
+ <source>Specify pid file (default: bitcoind.pid)</source>
+ <translation>Spécifier le fichier pid (par défaut : bitcoind.pid)</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="20"/>
+ <source>Generate coins</source>
+ <translation>Générer des pièces</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="21"/>
+ <source>Don&apos;t generate coins</source>
+ <translation>Ne pas générer de pièces</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="22"/>
+ <source>Start minimized</source>
+ <translation>Démarrer sous forme minimisée</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="23"/>
+ <source>Show splash screen on startup (default: 1)</source>
+ <translation>Afficher l&apos;écran d&apos;accueil au démarrage (par défaut : 1)</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="24"/>
+ <source>Specify data directory</source>
+ <translation>Spécifier le répertoire de données</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="25"/>
+ <source>Set database cache size in megabytes (default: 25)</source>
+ <translation>Définir la taille du tampon en mégaoctets (par défaut :25)</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="26"/>
+ <source>Set database disk log size in megabytes (default: 100)</source>
+ <translation>Définir la taille du journal de la base de données sur le disque en mégaoctets (par défaut : 100)</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="27"/>
+ <source>Specify connection timeout (in milliseconds)</source>
+ <translation>Spécifier le délai d&apos;expiration de la connexion (en millisecondes)</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="28"/>
+ <source>Connect through socks4 proxy</source>
+ <translation>Connexion via un proxy socks4</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="29"/>
+ <source>Allow DNS lookups for addnode and connect</source>
+ <translation>Autoriser les recherches DNS pour l&apos;ajout de nœuds et la connexion</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="30"/>
+ <source>Listen for connections on &lt;port&gt; (default: 8333 or testnet: 18333)</source>
+ <translation>Écouter les connexions sur le &lt;port&gt; (par défaut : 8333 ou testnet : 18333)</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="31"/>
+ <source>Maintain at most &lt;n&gt; connections to peers (default: 125)</source>
+ <translation>Garder au plus &lt;n&gt; connexions avec les pairs (par défaut : 125)</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="33"/>
+ <source>Connect only to the specified node</source>
+ <translation>Ne se connecter qu&apos;au nœud spécifié</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="38"/>
+ <source>Threshold for disconnecting misbehaving peers (default: 100)</source>
+ <translation>Seuil de déconnexion des pairs de mauvaise qualité (par défaut : 100)</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="39"/>
+ <source>Number of seconds to keep misbehaving peers from reconnecting (default: 86400)</source>
+ <translation>Délai en secondes de refus de reconnexion aux pairs de mauvaise qualité (par défaut : 86400)</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="42"/>
+ <source>Maximum per-connection receive buffer, &lt;n&gt;*1000 bytes (default: 10000)</source>
+ <translation>Tampon maximal de réception par connexion, &lt;n&gt;*1000 octets (par défaut : 10000)</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="43"/>
+ <source>Maximum per-connection send buffer, &lt;n&gt;*1000 bytes (default: 10000)</source>
+ <translation>Tampon maximal d&apos;envoi par connexion, &lt;n&gt;*1000 octets (par défaut : 10000)</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="47"/>
+ <source>Accept command line and JSON-RPC commands</source>
+ <translation>Accepter les commandes de JSON-RPC et de la ligne de commande</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="48"/>
+ <source>Run in the background as a daemon and accept commands</source>
+ <translation>Fonctionner en arrière-plan en tant que démon et accepter les commandes</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="49"/>
+ <source>Use the test network</source>
+ <translation>Utiliser le réseau de test</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="50"/>
+ <source>Output extra debugging information</source>
+ <translation>Informations de débogage supplémentaires</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="51"/>
+ <source>Prepend debug output with timestamp</source>
+ <translation>Faire précéder les données de débogage par un horodatage</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="52"/>
+ <source>Send trace/debug info to console instead of debug.log file</source>
+ <translation>Envoyer les informations de débogage/trace à la console au lieu du fichier debug.log</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="53"/>
+ <source>Send trace/debug info to debugger</source>
+ <translation>Envoyer les informations de débogage/trace au débogueur</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="54"/>
+ <source>Username for JSON-RPC connections</source>
+ <translation>Nom d&apos;utilisateur pour les connexions JSON-RPC</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="55"/>
+ <source>Password for JSON-RPC connections</source>
+ <translation>Mot de passe pour les connexions JSON-RPC</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="56"/>
+ <source>Listen for JSON-RPC connections on &lt;port&gt; (default: 8332)</source>
+ <translation>Écouter les connexions JSON-RPC sur le &lt;port&gt; (par défaut : 8332)</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="57"/>
+ <source>Allow JSON-RPC connections from specified IP address</source>
+ <translation>Autoriser les connexions JSON-RPC depuis l&apos;adresse IP spécifiée</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="58"/>
+ <source>Send commands to node running on &lt;ip&gt; (default: 127.0.0.1)</source>
+ <translation>Envoyer des commandes au nœud fonctionnant à &lt;ip&gt; (par défaut : 127.0.0.1)</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="59"/>
+ <source>Execute command when the best block changes (%s in cmd is replaced by block hash)</source>
+ <translation>Exécuter la commande lorsque le meilleur bloc change (%s est remplacé par le hachage du bloc dans cmd)</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="62"/>
+ <source>Upgrade wallet to latest format</source>
+ <translation>Mettre à jour le format du porte-monnaie</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="63"/>
+ <source>Set key pool size to &lt;n&gt; (default: 100)</source>
+ <translation>Régler la taille de la plage de clefs sur &lt;n&gt; (par défaut : 100)</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="64"/>
+ <source>Rescan the block chain for missing wallet transactions</source>
+ <translation>Réanalyser la chaîne de blocs pour les transactions de porte-monnaie manquantes</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="65"/>
+ <source>How many blocks to check at startup (default: 2500, 0 = all)</source>
+ <translation>Nombre de blocs à tester au démarrage (par défaut : 2500, 0 = tous)</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="66"/>
+ <source>How thorough the block verification is (0-6, default: 1)</source>
+ <translation>Profondeur de la vérification des blocs (0-6, par défaut : 1)</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="67"/>
+ <source>
+SSL options: (see the Bitcoin Wiki for SSL setup instructions)</source>
+ <translation>
+Options SSL : (cf. le wiki Bitcoin pour les réglages SSL)</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="70"/>
+ <source>Use OpenSSL (https) for JSON-RPC connections</source>
+ <translation>Utiliser OpenSSL (https) pour les connexions JSON-RPC</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="71"/>
+ <source>Server certificate file (default: server.cert)</source>
+ <translation>Fichier de certificat serveur (par défaut : server.cert)</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="72"/>
+ <source>Server private key (default: server.pem)</source>
+ <translation>Clef privée du serveur (par défaut : server.pem)</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="73"/>
+ <source>Acceptable ciphers (default: TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!AH:!3DES:@STRENGTH)</source>
+ <translation>Clefs de chiffrement acceptables (par défaut : TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!AH:!3DES:@STRENGTH)</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="76"/>
+ <source>This help message</source>
+ <translation>Ce message d&apos;aide</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="77"/>
+ <source>Usage</source>
+ <translation>Utilisation</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="78"/>
+ <source>Cannot obtain a lock on data directory %s. Bitcoin is probably already running.</source>
+ <translation>Impossible d&apos;obtenir un verrou sur le répertoire de données %s. Bitcoin fonctionne probablement déjà.</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="81"/>
+ <source>Bitcoin</source>
+ <translation>Bitcoin</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="82"/>
+ <source>Loading addresses...</source>
+ <translation>Chargement des adresses...</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="83"/>
+ <source>Error loading addr.dat</source>
+ <translation>Erreur lors du chargement de addr.dat</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="85"/>
+ <source>Error loading blkindex.dat</source>
+ <translation>Erreur lors du chargement de blkindex.dat</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="87"/>
+ <source>Error loading wallet.dat: Wallet corrupted</source>
+ <translation>Erreur lors du chargement de wallet.dat : porte-monnaie corrompu</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="88"/>
+ <source>Error loading wallet.dat: Wallet requires newer version of Bitcoin</source>
+ <translation>Erreur lors du chargement de wallet.dat : le porte-monnaie nécessite une version plus récente de Bitcoin</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="89"/>
+ <source>Wallet needed to be rewritten: restart Bitcoin to complete</source>
+ <translation>Le porte-monnaie nécessitait une réécriture. Veuillez redémarrer Bitcoin pour terminer l&apos;opération</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="90"/>
+ <source>Error loading wallet.dat</source>
+ <translation>Erreur lors du chargement de wallet.dat</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="122"/>
+ <source>Error: Wallet locked, unable to create transaction </source>
+ <translation>Erreur : le porte-monnaie est verrouillé, impossible de créer la transaction </translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="123"/>
+ <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>Erreur : cette transaction nécessite des frais de transaction d&apos;au moins %s en raison de son montant, de sa complexité ou parce que des fonds reçus récemment sont utilisés </translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="126"/>
+ <source>Error: Transaction creation failed </source>
+ <translation>Erreur : échec de la création de la transaction </translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="127"/>
+ <source>Sending...</source>
+ <translation>Envoi en cours...</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="128"/>
+ <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>Erreur : la transaction a été rejetée. Cela peut arriver si certaines pièces de votre porte-monnaie ont déjà été dépensées, par exemple si vous avez utilisé une copie de wallet.dat et si des pièces ont été dépensées avec cette copie sans être marquées comme telles ici.</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="132"/>
+ <source>Invalid amount</source>
+ <translation>Montant invalide</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="133"/>
+ <source>Insufficient funds</source>
+ <translation>Fonds insuffisants</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="84"/>
+ <source>Loading block index...</source>
+ <translation>Chargement de l&apos;index des blocs...</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="32"/>
+ <source>Add a node to connect to and attempt to keep the connection open</source>
+ <translation>Ajouter un nœud auquel se connecter et tenter de garder la connexion ouverte</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="34"/>
+ <source>Find peers using internet relay chat (default: 0)</source>
+ <translation>Trouver des pairs en utilisant Internet Relay Chat (par défaut : 0)</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="35"/>
+ <source>Accept connections from outside (default: 1)</source>
+ <translation>Accepter les connexions entrantes (par défaut : 1)</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="36"/>
+ <source>Set language, for example &quot;de_DE&quot; (default: system locale)</source>
+ <translation>Définir la langue, par exemple « de_DE » (par défaut : la langue du système)</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="37"/>
+ <source>Find peers using DNS lookup (default: 1)</source>
+ <translation>Trouver des pairs en utilisant la recherche DNS (par défaut : 1)</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="44"/>
+ <source>Use Universal Plug and Play to map the listening port (default: 1)</source>
+ <translation>Utiliser Universal Plug and Play pour rediriger le port d&apos;écoute (par défaut : 1)</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="45"/>
+ <source>Use Universal Plug and Play to map the listening port (default: 0)</source>
+ <translation>Utiliser Universal Plug and Play pour rediriger le port d&apos;écoute (par défaut : 0)</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="46"/>
+ <source>Fee per KB to add to transactions you send</source>
+ <translation>Frais par Ko à ajouter aux transactions que vous enverrez</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="86"/>
+ <source>Loading wallet...</source>
+ <translation>Chargement du porte-monnaie...</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="91"/>
+ <source>Cannot downgrade wallet</source>
+ <translation>Impossible de revenir à une version antérieure du porte-monnaie</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="92"/>
+ <source>Cannot initialize keypool</source>
+ <translation>Impossible d&apos;initialiser le keypool</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="93"/>
+ <source>Cannot write default address</source>
+ <translation>Impossible d&apos;écrire l&apos;adresse par défaut</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="94"/>
+ <source>Rescanning...</source>
+ <translation>Nouvelle analyse...</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="95"/>
+ <source>Done loading</source>
+ <translation>Chargement terminé</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="96"/>
+ <source>Invalid -proxy address</source>
+ <translation>Adresse -proxy invalide</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="97"/>
+ <source>Invalid amount for -paytxfee=&lt;amount&gt;</source>
+ <translation>Montant invalide pour -paytxfee=&lt;montant&gt;</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="98"/>
+ <source>Warning: -paytxfee is set very high. This is the transaction fee you will pay if you send a transaction.</source>
+ <translation>Attention : -paytxfee est réglée sur un montant très élevé. Il s&apos;agit des frais de transaction que vous payerez si vous envoyez une transaction.</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="101"/>
+ <source>Error: CreateThread(StartNode) failed</source>
+ <translation>Erreur : CreateThread(StartNode) a échoué</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="11"/>
+ <source>Warning: Disk space is low </source>
+ <translation>Attention : l&apos;espace disque est faible</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="8"/>
+ <source>Unable to bind to port %d on this computer. Bitcoin is probably already running.</source>
+ <translation>Impossible de s&apos;attacher au port %d sur cet ordinateur. Bitcoin fonctionne probablement déjà.</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="102"/>
+ <source>To use the %s option</source>
+ <translation>Pour utiliser l&apos;option %s</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="103"/>
+ <source>%s, you must set a rpcpassword in the configuration file:
+ %s
+It is recommended you use the following random password:
+rpcuser=bitcoinrpc
+rpcpassword=%s
+(you do not need to remember this password)
+If the file does not exist, create it with owner-readable-only file permissions.
+</source>
+ <translation>%s, vous devez établir un mot de passe rpc dans le fichier de configuration :
+ %s
+Il est recommandé d&apos;utiliser le mot de passe aléatoire suivant :
+rcpuser=bitcoinrpc
+rpcpassword=%s
+(vous n&apos;avez pas besoin de mémoriser ce mot de passe)
+Si le fichier n&apos;existe pas, créez-le avec les droits de lecture accordés au propriétaire.
+</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="112"/>
+ <source>Error</source>
+ <translation>Erreur</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="113"/>
+ <source>An error occured while setting up the RPC port %i for listening: %s</source>
+ <translation>Une erreur est survenue lors de mise en place du port RPC d&apos;écoute %i : %s</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="114"/>
+ <source>You must set rpcpassword=&lt;password&gt; in the configuration file:
+%s
+If the file does not exist, create it with owner-readable-only file permissions.</source>
+ <translation>Vous devez ajouter la ligne rpcpassword=&lt;mot-de-passe&gt; au fichier de configuration :
+%s
+Si le fichier n&apos;existe pas, créez-le avec les droits de lecture seule accordés au propriétaire.</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="119"/>
+ <source>Warning: Please check that your computer&apos;s date and time are correct. If your clock is wrong Bitcoin will not work properly.</source>
+ <translation>Attention : veuillez vérifier que l&apos;heure et la date de votre ordinateur sont correctes. Si votre horloge n&apos;est pas à l&apos;heure, Bitcoin ne fonctionnera pas correctement.</translation>
+ </message>
+</context>
+</TS> \ No newline at end of file
diff --git a/src/qt/locale/bitcoin_pt_PT.ts b/src/qt/locale/bitcoin_pt_PT.ts
new file mode 100644
index 0000000000..a727f4ee21
--- /dev/null
+++ b/src/qt/locale/bitcoin_pt_PT.ts
@@ -0,0 +1,2265 @@
+<?xml version="1.0" ?><!DOCTYPE TS><TS language="pt_PT" version="2.0">
+<defaultcodec>UTF-8</defaultcodec>
+<context>
+ <name>AboutDialog</name>
+ <message>
+ <location filename="../forms/aboutdialog.ui" line="14"/>
+ <source>About Bitcoin</source>
+ <translation>Sobre o Bitcoin</translation>
+ </message>
+ <message>
+ <location filename="../forms/aboutdialog.ui" line="53"/>
+ <source>&lt;b&gt;Bitcoin&lt;/b&gt; version</source>
+ <translation>&lt;b&gt;Bitcoin&lt;/b&gt; versão</translation>
+ </message>
+ <message>
+ <location filename="../forms/aboutdialog.ui" line="97"/>
+ <source>Copyright © 2009-2012 Bitcoin Developers
+
+This is experimental software.
+
+Distributed under the MIT/X11 software license, see the accompanying file license.txt or http://www.opensource.org/licenses/mit-license.php.
+
+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.</source>
+ <translation>Todos os direitos reservados © 2009-2012 Programadores Bitcoin
+
+Este é um programa experimental.
+
+Distribuído sobre uma licença de software MIT/X11, por favor verifique o ficheiro anexo license.txt ou http://www.opensource.org/licenses/mit-license.php.
+
+Este produto inclui software desenvolvido pelo Projecto OpenSSL para uso no OpenSSL Toolkit (http://www.openssl.org/), software criptográfico escrito por Eric Young (eay@cryptsoft.com) e software UPnP escrito por Thomas Bernard.</translation>
+ </message>
+</context>
+<context>
+ <name>AddressBookPage</name>
+ <message>
+ <location filename="../forms/addressbookpage.ui" line="14"/>
+ <source>Address Book</source>
+ <translation>Livro de endereços</translation>
+ </message>
+ <message>
+ <location filename="../forms/addressbookpage.ui" line="20"/>
+ <source>These are your Bitcoin addresses for receiving payments. You may want to give a different one to each sender so you can keep track of who is paying you.</source>
+ <translation>Estes são os seus endereços Bitcoin para receber pagamentos. Poderá enviar um endereço diferente para cada remetente para poder identificar os pagamentos.</translation>
+ </message>
+ <message>
+ <location filename="../forms/addressbookpage.ui" line="36"/>
+ <source>Double-click to edit address or label</source>
+ <translation>Clique duas vezes para editar o endereço ou o rótulo</translation>
+ </message>
+ <message>
+ <location filename="../forms/addressbookpage.ui" line="63"/>
+ <source>Create a new address</source>
+ <translation>Criar um novo endereço</translation>
+ </message>
+ <message>
+ <location filename="../forms/addressbookpage.ui" line="77"/>
+ <source>Copy the currently selected address to the system clipboard</source>
+ <translation>Copie o endereço selecionado para a área de transferência</translation>
+ </message>
+ <message>
+ <location filename="../forms/addressbookpage.ui" line="66"/>
+ <source>&amp;New Address</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../forms/addressbookpage.ui" line="80"/>
+ <source>&amp;Copy Address</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../forms/addressbookpage.ui" line="91"/>
+ <source>Show &amp;QR Code</source>
+ <translation>Mostrar &amp;Código QR</translation>
+ </message>
+ <message>
+ <location filename="../forms/addressbookpage.ui" line="102"/>
+ <source>Sign a message to prove you own this address</source>
+ <translation>Assine uma mensagem para provar que é dono deste endereço</translation>
+ </message>
+ <message>
+ <location filename="../forms/addressbookpage.ui" line="105"/>
+ <source>&amp;Sign Message</source>
+ <translation>&amp;Assinar Mensagem</translation>
+ </message>
+ <message>
+ <location filename="../forms/addressbookpage.ui" line="116"/>
+ <source>Delete the currently selected address from the list. Only sending addresses can be deleted.</source>
+ <translation>Eliminar o endereço selecionado da lista. Apenas endereços de envio podem ser eliminados.</translation>
+ </message>
+ <message>
+ <location filename="../forms/addressbookpage.ui" line="119"/>
+ <source>&amp;Delete</source>
+ <translation>&amp;Eliminar</translation>
+ </message>
+ <message>
+ <location filename="../addressbookpage.cpp" line="63"/>
+ <source>Copy &amp;Label</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../addressbookpage.cpp" line="65"/>
+ <source>&amp;Edit</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../addressbookpage.cpp" line="297"/>
+ <source>Export Address Book Data</source>
+ <translation>Exportar de dados do Livro de Endereços</translation>
+ </message>
+ <message>
+ <location filename="../addressbookpage.cpp" line="298"/>
+ <source>Comma separated file (*.csv)</source>
+ <translation>Ficheiro separado por vírgulas (*.csv)</translation>
+ </message>
+ <message>
+ <location filename="../addressbookpage.cpp" line="311"/>
+ <source>Error exporting</source>
+ <translation>Erro ao exportar</translation>
+ </message>
+ <message>
+ <location filename="../addressbookpage.cpp" line="311"/>
+ <source>Could not write to file %1.</source>
+ <translation>Could not write to file %1.</translation>
+ </message>
+</context>
+<context>
+ <name>AddressTableModel</name>
+ <message>
+ <location filename="../addresstablemodel.cpp" line="78"/>
+ <source>Label</source>
+ <translation>Rótulo</translation>
+ </message>
+ <message>
+ <location filename="../addresstablemodel.cpp" line="78"/>
+ <source>Address</source>
+ <translation>Endereço</translation>
+ </message>
+ <message>
+ <location filename="../addresstablemodel.cpp" line="114"/>
+ <source>(no label)</source>
+ <translation>(Sem rótulo)</translation>
+ </message>
+</context>
+<context>
+ <name>AskPassphraseDialog</name>
+ <message>
+ <location filename="../forms/askpassphrasedialog.ui" line="26"/>
+ <source>Dialog</source>
+ <translation>Diálogo</translation>
+ </message>
+ <message>
+ <location filename="../forms/askpassphrasedialog.ui" line="32"/>
+ <location filename="../forms/askpassphrasedialog.ui" line="97"/>
+ <source>TextLabel</source>
+ <translation>TextoDoRótulo</translation>
+ </message>
+ <message>
+ <location filename="../forms/askpassphrasedialog.ui" line="50"/>
+ <source>Enter passphrase</source>
+ <translation>Escreva a frase de segurança</translation>
+ </message>
+ <message>
+ <location filename="../forms/askpassphrasedialog.ui" line="64"/>
+ <source>New passphrase</source>
+ <translation>Nova frase de segurança</translation>
+ </message>
+ <message>
+ <location filename="../forms/askpassphrasedialog.ui" line="78"/>
+ <source>Repeat new passphrase</source>
+ <translation>Repita a nova frase de segurança</translation>
+ </message>
+ <message>
+ <location filename="../askpassphrasedialog.cpp" line="34"/>
+ <source>Enter the new passphrase to the wallet.&lt;br/&gt;Please use a passphrase of &lt;b&gt;10 or more random characters&lt;/b&gt;, or &lt;b&gt;eight or more words&lt;/b&gt;.</source>
+ <translation>Escreva a nova frase de seguraça da sua carteira. &lt;br/&gt; Por favor, use uma frase de &lt;b&gt;10 ou mais caracteres aleatórios,&lt;/b&gt; ou &lt;b&gt;oito ou mais palavras.&lt;/b&gt;</translation>
+ </message>
+ <message>
+ <location filename="../askpassphrasedialog.cpp" line="35"/>
+ <source>Encrypt wallet</source>
+ <translation>Encriptar carteira</translation>
+ </message>
+ <message>
+ <location filename="../askpassphrasedialog.cpp" line="38"/>
+ <source>This operation needs your wallet passphrase to unlock the wallet.</source>
+ <translation>A sua frase de segurança é necessária para desbloquear a carteira.</translation>
+ </message>
+ <message>
+ <location filename="../askpassphrasedialog.cpp" line="43"/>
+ <source>Unlock wallet</source>
+ <translation>Desbloquear carteira</translation>
+ </message>
+ <message>
+ <location filename="../askpassphrasedialog.cpp" line="46"/>
+ <source>This operation needs your wallet passphrase to decrypt the wallet.</source>
+ <translation>A sua frase de segurança é necessária para desencriptar a carteira.</translation>
+ </message>
+ <message>
+ <location filename="../askpassphrasedialog.cpp" line="51"/>
+ <source>Decrypt wallet</source>
+ <translation>Desencriptar carteira</translation>
+ </message>
+ <message>
+ <location filename="../askpassphrasedialog.cpp" line="54"/>
+ <source>Change passphrase</source>
+ <translation>Alterar frase de segurança</translation>
+ </message>
+ <message>
+ <location filename="../askpassphrasedialog.cpp" line="55"/>
+ <source>Enter the old and new passphrase to the wallet.</source>
+ <translation>Escreva a frase de segurança antiga seguida da nova para a carteira.</translation>
+ </message>
+ <message>
+ <location filename="../askpassphrasedialog.cpp" line="101"/>
+ <source>Confirm wallet encryption</source>
+ <translation>Confirmar encriptação da carteira</translation>
+ </message>
+ <message>
+ <location filename="../askpassphrasedialog.cpp" line="102"/>
+ <source>WARNING: If you encrypt your wallet and lose your passphrase, you will &lt;b&gt;LOSE ALL OF YOUR BITCOINS&lt;/b&gt;!
+Are you sure you wish to encrypt your wallet?</source>
+ <translation>AVISO: Se encriptar a carteira e perder a sua senha irá &lt;b&gt;perder todos os seus BITCOINS!&lt;/b&gt; Tem a certeza de que deseja encriptar a carteira?</translation>
+ </message>
+ <message>
+ <location filename="../askpassphrasedialog.cpp" line="111"/>
+ <location filename="../askpassphrasedialog.cpp" line="160"/>
+ <source>Wallet encrypted</source>
+ <translation>Carteira encriptada</translation>
+ </message>
+ <message>
+ <location filename="../askpassphrasedialog.cpp" line="112"/>
+ <source>Bitcoin will close now to finish the encryption process. Remember that encrypting your wallet cannot fully protect your bitcoins from being stolen by malware infecting your computer.</source>
+ <translation>O cliente Bitcoin irá agora ser fechado para terminar o processo de encriptação. Recorde que a encriptação da sua carteira não protegerá totalmente os seus bitcoins de serem roubados por programas maliciosos que infectem o seu computador.</translation>
+ </message>
+ <message>
+ <location filename="../askpassphrasedialog.cpp" line="208"/>
+ <location filename="../askpassphrasedialog.cpp" line="232"/>
+ <source>Warning: The Caps Lock key is on.</source>
+ <translation>Atenção: A tecla Caps Lock está activa.</translation>
+ </message>
+ <message>
+ <location filename="../askpassphrasedialog.cpp" line="117"/>
+ <location filename="../askpassphrasedialog.cpp" line="124"/>
+ <location filename="../askpassphrasedialog.cpp" line="166"/>
+ <location filename="../askpassphrasedialog.cpp" line="172"/>
+ <source>Wallet encryption failed</source>
+ <translation>A encriptação da carteira falhou</translation>
+ </message>
+ <message>
+ <location filename="../askpassphrasedialog.cpp" line="118"/>
+ <source>Wallet encryption failed due to an internal error. Your wallet was not encrypted.</source>
+ <translation>A encriptação da carteira falhou devido a um erro interno. A carteira não foi encriptada.</translation>
+ </message>
+ <message>
+ <location filename="../askpassphrasedialog.cpp" line="125"/>
+ <location filename="../askpassphrasedialog.cpp" line="173"/>
+ <source>The supplied passphrases do not match.</source>
+ <translation>As frases de segurança fornecidas não coincidem.</translation>
+ </message>
+ <message>
+ <location filename="../askpassphrasedialog.cpp" line="136"/>
+ <source>Wallet unlock failed</source>
+ <translation>O desbloqueio da carteira falhou</translation>
+ </message>
+ <message>
+ <location filename="../askpassphrasedialog.cpp" line="137"/>
+ <location filename="../askpassphrasedialog.cpp" line="148"/>
+ <location filename="../askpassphrasedialog.cpp" line="167"/>
+ <source>The passphrase entered for the wallet decryption was incorrect.</source>
+ <translation>A frase de segurança introduzida para a desencriptação da carteira estava incorreta.</translation>
+ </message>
+ <message>
+ <location filename="../askpassphrasedialog.cpp" line="147"/>
+ <source>Wallet decryption failed</source>
+ <translation>A desencriptação da carteira falhou</translation>
+ </message>
+ <message>
+ <location filename="../askpassphrasedialog.cpp" line="161"/>
+ <source>Wallet passphrase was succesfully changed.</source>
+ <translation>A frase de segurança da carteira foi alterada com êxito.</translation>
+ </message>
+</context>
+<context>
+ <name>BitcoinGUI</name>
+ <message>
+ <location filename="../bitcoingui.cpp" line="72"/>
+ <source>Bitcoin Wallet</source>
+ <translation>Carteira Bitcoin</translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="212"/>
+ <source>Sign &amp;message...</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="245"/>
+ <source>Show/Hide &amp;Bitcoin</source>
+ <translation>Mostrar/Ocultar &amp;Bitcoin</translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="507"/>
+ <source>Synchronizing with network...</source>
+ <translation>Sincronizando com a rede...</translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="182"/>
+ <source>&amp;Overview</source>
+ <translation>&amp;Visão geral</translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="183"/>
+ <source>Show general overview of wallet</source>
+ <translation>Mostrar visão geral da carteira</translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="188"/>
+ <source>&amp;Transactions</source>
+ <translation>&amp;Transações</translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="189"/>
+ <source>Browse transaction history</source>
+ <translation>Navegar pelo histórico de transações</translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="194"/>
+ <source>&amp;Address Book</source>
+ <translation>&amp;Livro de endereços</translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="195"/>
+ <source>Edit the list of stored addresses and labels</source>
+ <translation>Editar a lista de endereços e rótulos</translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="200"/>
+ <source>&amp;Receive coins</source>
+ <translation>&amp;Receber moedas</translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="201"/>
+ <source>Show the list of addresses for receiving payments</source>
+ <translation>Mostrar a lista de endereços para receber pagamentos</translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="206"/>
+ <source>&amp;Send coins</source>
+ <translation>&amp;Enviar moedas</translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="207"/>
+ <source>Send coins to a bitcoin address</source>
+ <translation>Enviar moedas para um endereço bitcoin</translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="213"/>
+ <source>Prove you control an address</source>
+ <translation>Prove que controla um endereço</translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="232"/>
+ <source>E&amp;xit</source>
+ <translation>S&amp;air</translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="233"/>
+ <source>Quit application</source>
+ <translation>Sair da aplicação</translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="236"/>
+ <source>&amp;About %1</source>
+ <translation>&amp;Acerca de %1</translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="237"/>
+ <source>Show information about Bitcoin</source>
+ <translation>Mostrar informação sobre Bitcoin</translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="239"/>
+ <source>About &amp;Qt</source>
+ <translation>Sobre &amp;Qt</translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="240"/>
+ <source>Show information about Qt</source>
+ <translation>Mostrar informação sobre Qt</translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="242"/>
+ <source>&amp;Options...</source>
+ <translation>&amp;Opções...</translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="243"/>
+ <source>Modify configuration options for bitcoin</source>
+ <translation>Modificar configuração para bitcoin</translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="249"/>
+ <source>&amp;Encrypt Wallet...</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="252"/>
+ <source>&amp;Backup Wallet...</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="254"/>
+ <source>&amp;Change Passphrase...</source>
+ <translation type="unfinished"/>
+ </message>
+ <message numerus="yes">
+ <location filename="../bitcoingui.cpp" line="509"/>
+ <source>~%n block(s) remaining</source>
+ <translation><numerusform>~%n bloco restante</numerusform><numerusform>~%n blocos restantes</numerusform></translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="520"/>
+ <source>Downloaded %1 of %2 blocks of transaction history (%3% done).</source>
+ <translation>Recuperados %1 de %2 blocos do histórico de transações (%3% completo)</translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="247"/>
+ <source>&amp;Export...</source>
+ <translation>&amp;Exportar...</translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="246"/>
+ <source>Show or hide the Bitcoin window</source>
+ <translation>Mostrar ou Ocultar a janela Bitcoin</translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="248"/>
+ <source>Export the data in the current tab to a file</source>
+ <translation>Exportar os dados no separador actual para um ficheiro</translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="250"/>
+ <source>Encrypt or decrypt wallet</source>
+ <translation>Encriptar ou desencriptar carteira</translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="253"/>
+ <source>Backup wallet to another location</source>
+ <translation>Faça uma cópia de segurança da carteira para outra localização</translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="255"/>
+ <source>Change the passphrase used for wallet encryption</source>
+ <translation>Mudar a frase de segurança utilizada na encriptação da carteira</translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="256"/>
+ <source>&amp;Debug window</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="257"/>
+ <source>Open debugging and diagnostic console</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="280"/>
+ <source>&amp;File</source>
+ <translation>&amp;Ficheiro</translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="289"/>
+ <source>&amp;Settings</source>
+ <translation>&amp;Configurações</translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="295"/>
+ <source>&amp;Help</source>
+ <translation>&amp;Ajuda</translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="304"/>
+ <source>Tabs toolbar</source>
+ <translation>Barra de separadores</translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="315"/>
+ <source>Actions toolbar</source>
+ <translation>Barra de ações</translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="327"/>
+ <source>[testnet]</source>
+ <translation>[testnet]</translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="391"/>
+ <source>Bitcoin client</source>
+ <translation>Cliente Bitcoin</translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="419"/>
+ <source>bitcoin-qt</source>
+ <translation>bitcoin-qt</translation>
+ </message>
+ <message numerus="yes">
+ <location filename="../bitcoingui.cpp" line="483"/>
+ <source>%n active connection(s) to Bitcoin network</source>
+ <translation><numerusform>%n ligação ativa à rede Bitcoin</numerusform><numerusform>%n ligações ativas à rede Bitcoin</numerusform></translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="532"/>
+ <source>Downloaded %1 blocks of transaction history.</source>
+ <translation>Recuperados %1 blocos do histórico de transações.</translation>
+ </message>
+ <message numerus="yes">
+ <location filename="../bitcoingui.cpp" line="547"/>
+ <source>%n second(s) ago</source>
+ <translation><numerusform>%n segundo</numerusform><numerusform>%n segundos</numerusform></translation>
+ </message>
+ <message numerus="yes">
+ <location filename="../bitcoingui.cpp" line="551"/>
+ <source>%n minute(s) ago</source>
+ <translation><numerusform>%n minutos</numerusform><numerusform>%n minutos</numerusform></translation>
+ </message>
+ <message numerus="yes">
+ <location filename="../bitcoingui.cpp" line="555"/>
+ <source>%n hour(s) ago</source>
+ <translation><numerusform>%n hora</numerusform><numerusform>%n horas</numerusform></translation>
+ </message>
+ <message numerus="yes">
+ <location filename="../bitcoingui.cpp" line="559"/>
+ <source>%n day(s) ago</source>
+ <translation><numerusform>%n dia</numerusform><numerusform>%n dias</numerusform></translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="565"/>
+ <source>Up to date</source>
+ <translation>Atualizado</translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="570"/>
+ <source>Catching up...</source>
+ <translation>Recuperando...</translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="578"/>
+ <source>Last received block was generated %1.</source>
+ <translation>Último bloco recebido foi gerado há %1.</translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="634"/>
+ <source>This transaction is over the size limit. You can still send it for a fee of %1, which goes to the nodes that process your transaction and helps to support the network. Do you want to pay the fee?</source>
+ <translation>Esta transação tem um tamanho superior ao limite máximo. Poderá enviá-la pagando uma taxa de %1 que será entregue ao nó que processar a sua transação e ajudará a suportar a rede. Deseja pagar a taxa?</translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="639"/>
+ <source>Confirm transaction fee</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="666"/>
+ <source>Sent transaction</source>
+ <translation>Transação enviada</translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="667"/>
+ <source>Incoming transaction</source>
+ <translation>Transação recebida</translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="668"/>
+ <source>Date: %1
+Amount: %2
+Type: %3
+Address: %4
+</source>
+ <translation>Data: %1
+Quantidade: %2
+Tipo: %3
+Endereço: %4</translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="793"/>
+ <source>Wallet is &lt;b&gt;encrypted&lt;/b&gt; and currently &lt;b&gt;unlocked&lt;/b&gt;</source>
+ <translation>A carteira está &lt;b&gt;encriptada&lt;/b&gt; e atualmente &lt;b&gt;desbloqueada&lt;/b&gt;</translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="801"/>
+ <source>Wallet is &lt;b&gt;encrypted&lt;/b&gt; and currently &lt;b&gt;locked&lt;/b&gt;</source>
+ <translation>A carteira está &lt;b&gt;encriptada&lt;/b&gt; e atualmente &lt;b&gt;bloqueada&lt;/b&gt;</translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="824"/>
+ <source>Backup Wallet</source>
+ <translation>Cópia de Segurança da Carteira</translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="824"/>
+ <source>Wallet Data (*.dat)</source>
+ <translation>Dados da Carteira (*.dat)</translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="827"/>
+ <source>Backup Failed</source>
+ <translation>Cópia de Segurança Falhada</translation>
+ </message>
+ <message>
+ <location filename="../bitcoingui.cpp" line="827"/>
+ <source>There was an error trying to save the wallet data to the new location.</source>
+ <translation>Ocorreu um erro ao tentar guardar os dados da carteira na nova localização.</translation>
+ </message>
+ <message>
+ <location filename="../bitcoin.cpp" line="127"/>
+ <source>A fatal error occured. Bitcoin can no longer continue safely and will quit.</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
+ <name>DisplayOptionsPage</name>
+ <message>
+ <location filename="../optionsdialog.cpp" line="273"/>
+ <source>&amp;Unit to show amounts in: </source>
+ <translation>&amp;Unidade a usar: </translation>
+ </message>
+ <message>
+ <location filename="../optionsdialog.cpp" line="277"/>
+ <source>Choose the default subdivision unit to show in the interface, and when sending coins</source>
+ <translation>Escolha a subdivisão unitária a ser mostrada por defeito na aplicação e ao enviar moedas</translation>
+ </message>
+ <message>
+ <location filename="../optionsdialog.cpp" line="284"/>
+ <source>&amp;Display addresses in transaction list</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../optionsdialog.cpp" line="285"/>
+ <source>Whether to show Bitcoin addresses in the transaction list</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
+ <name>EditAddressDialog</name>
+ <message>
+ <location filename="../forms/editaddressdialog.ui" line="14"/>
+ <source>Edit Address</source>
+ <translation>Editar Endereço</translation>
+ </message>
+ <message>
+ <location filename="../forms/editaddressdialog.ui" line="25"/>
+ <source>&amp;Label</source>
+ <translation>&amp;Rótulo</translation>
+ </message>
+ <message>
+ <location filename="../forms/editaddressdialog.ui" line="35"/>
+ <source>The label associated with this address book entry</source>
+ <translation>O rótulo a ser associado com esta entrada do livro de endereços</translation>
+ </message>
+ <message>
+ <location filename="../forms/editaddressdialog.ui" line="42"/>
+ <source>&amp;Address</source>
+ <translation>&amp;Endereço</translation>
+ </message>
+ <message>
+ <location filename="../forms/editaddressdialog.ui" line="52"/>
+ <source>The address associated with this address book entry. This can only be modified for sending addresses.</source>
+ <translation>O endereço associado com esta entrada do livro de endereços. Apenas poderá ser modificado para endereços de saída.</translation>
+ </message>
+ <message>
+ <location filename="../editaddressdialog.cpp" line="20"/>
+ <source>New receiving address</source>
+ <translation>Novo endereço de entrada</translation>
+ </message>
+ <message>
+ <location filename="../editaddressdialog.cpp" line="24"/>
+ <source>New sending address</source>
+ <translation>Novo endereço de saída</translation>
+ </message>
+ <message>
+ <location filename="../editaddressdialog.cpp" line="27"/>
+ <source>Edit receiving address</source>
+ <translation>&amp;Ajuda</translation>
+ </message>
+ <message>
+ <location filename="../editaddressdialog.cpp" line="31"/>
+ <source>Edit sending address</source>
+ <translation>Editar endereço de saída</translation>
+ </message>
+ <message>
+ <location filename="../editaddressdialog.cpp" line="91"/>
+ <source>The entered address &quot;%1&quot; is already in the address book.</source>
+ <translation>O endereço introduzido &quot;%1&quot; já se encontra no livro de endereços.</translation>
+ </message>
+ <message>
+ <location filename="../editaddressdialog.cpp" line="96"/>
+ <source>The entered address &quot;%1&quot; is not a valid bitcoin address.</source>
+ <translation>O endereço introduzido &quot;%1&quot; não é um endereço bitcoin válido.</translation>
+ </message>
+ <message>
+ <location filename="../editaddressdialog.cpp" line="101"/>
+ <source>Could not unlock wallet.</source>
+ <translation>Impossível desbloquear carteira.</translation>
+ </message>
+ <message>
+ <location filename="../editaddressdialog.cpp" line="106"/>
+ <source>New key generation failed.</source>
+ <translation>Falha ao gerar nova chave.</translation>
+ </message>
+</context>
+<context>
+ <name>MainOptionsPage</name>
+ <message>
+ <location filename="../optionsdialog.cpp" line="171"/>
+ <source>&amp;Start Bitcoin on window system startup</source>
+ <translation>&amp;Iniciar Bitcoin ao iniciar o sistema</translation>
+ </message>
+ <message>
+ <location filename="../optionsdialog.cpp" line="172"/>
+ <source>Automatically start Bitcoin after the computer is turned on</source>
+ <translation>Começar o Bitcoin automaticamente ao iniciar o computador</translation>
+ </message>
+ <message>
+ <location filename="../optionsdialog.cpp" line="176"/>
+ <source>&amp;Minimize to the tray instead of the taskbar</source>
+ <translation>&amp;Minimizar para a bandeja e não para a barra de ferramentas</translation>
+ </message>
+ <message>
+ <location filename="../optionsdialog.cpp" line="177"/>
+ <source>Show only a tray icon after minimizing the window</source>
+ <translation>Apenas mostrar o ícone da bandeja depois de minimizar a janela</translation>
+ </message>
+ <message>
+ <location filename="../optionsdialog.cpp" line="185"/>
+ <source>Map port using &amp;UPnP</source>
+ <translation>Mapear porta usando &amp;UPnP</translation>
+ </message>
+ <message>
+ <location filename="../optionsdialog.cpp" line="186"/>
+ <source>Automatically open the Bitcoin client port on the router. This only works when your router supports UPnP and it is enabled.</source>
+ <translation>Abrir a porta do cliente bitcoin automaticamente no seu router. Isto penas funciona se o seu router suportar UPnP e este se encontrar ligado.</translation>
+ </message>
+ <message>
+ <location filename="../optionsdialog.cpp" line="180"/>
+ <source>M&amp;inimize on close</source>
+ <translation>M&amp;inimizar ao fechar</translation>
+ </message>
+ <message>
+ <location filename="../optionsdialog.cpp" line="181"/>
+ <source>Minimize instead of exit the application when the window is closed. When this option is enabled, the application will be closed only after selecting Quit in the menu.</source>
+ <translation>Minimize ao invés de sair da aplicação quando a janela é fechada. Com esta opção selecionada, a aplicação apenas será encerrada quando escolher Sair da aplicação no menú.</translation>
+ </message>
+ <message>
+ <location filename="../optionsdialog.cpp" line="189"/>
+ <source>&amp;Connect through SOCKS4 proxy:</source>
+ <translation>&amp;Ligar através de proxy SOCKS4:</translation>
+ </message>
+ <message>
+ <location filename="../optionsdialog.cpp" line="190"/>
+ <source>Connect to the Bitcon network through a SOCKS4 proxy (e.g. when connecting through Tor)</source>
+ <translation>Ligar à rede Bitcoin através de um proxy SOCKS4 (p.ex. quando ligar através de Tor)</translation>
+ </message>
+ <message>
+ <location filename="../optionsdialog.cpp" line="195"/>
+ <source>Proxy &amp;IP: </source>
+ <translation>&amp;IP do Proxy: </translation>
+ </message>
+ <message>
+ <location filename="../optionsdialog.cpp" line="201"/>
+ <source>IP address of the proxy (e.g. 127.0.0.1)</source>
+ <translation>Endereço IP do proxy (p.ex. 127.0.0.1)</translation>
+ </message>
+ <message>
+ <location filename="../optionsdialog.cpp" line="204"/>
+ <source>&amp;Port: </source>
+ <translation>&amp;Porta: </translation>
+ </message>
+ <message>
+ <location filename="../optionsdialog.cpp" line="210"/>
+ <source>Port of the proxy (e.g. 1234)</source>
+ <translation>Porta do proxy (p.ex. 1234)</translation>
+ </message>
+ <message>
+ <location filename="../optionsdialog.cpp" line="232"/>
+ <source>Detach databases at shutdown</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../optionsdialog.cpp" line="233"/>
+ <source>Detach block and address databases at shutdown. This means they can be moved to another data directory, but it slows down shutdown. The wallet is always detached.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../optionsdialog.cpp" line="222"/>
+ <source>Pay transaction &amp;fee</source>
+ <translation>Pagar &amp;taxa de transação</translation>
+ </message>
+ <message>
+ <location filename="../optionsdialog.cpp" line="216"/>
+ <source>Optional transaction fee per kB that helps make sure your transactions are processed quickly. Most transactions are 1 kB. Fee 0.01 recommended.</source>
+ <translation>Taxa de transação opcional por kB que ajuda a assegurar que as suas transações serão processadas rapidamente. A maioria das transações tem 1 kB. Taxa de 0.01 recomendada.</translation>
+ </message>
+</context>
+<context>
+ <name>MessagePage</name>
+ <message>
+ <location filename="../forms/messagepage.ui" line="14"/>
+ <source>Message</source>
+ <translation>Mensagem</translation>
+ </message>
+ <message>
+ <location filename="../forms/messagepage.ui" line="20"/>
+ <source>You can sign messages with your addresses to prove you own them. Be careful not to sign anything vague, as phishing attacks may try to trick you into signing your identity over to them. Only sign fully-detailed statements you agree to.</source>
+ <translation>Pode assinar mensagens com os seus endereços para provar que são seus. Tenha atenção ao assinar mensagens ambíguas, pois ataques de phishing podem tentar enganá-lo, de modo a assinar a sua identidade para os atacantes. Apenas assine declarações completamente detalhadas com as quais concorde.</translation>
+ </message>
+ <message>
+ <location filename="../forms/messagepage.ui" line="38"/>
+ <source>The address to sign the message with (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L)</source>
+ <translation>O endereço a utilizar para assinar a mensagem (p.ex. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L)</translation>
+ </message>
+ <message>
+ <location filename="../forms/messagepage.ui" line="48"/>
+ <source>Choose adress from address book</source>
+ <translation>Escolher endereço </translation>
+ </message>
+ <message>
+ <location filename="../forms/messagepage.ui" line="58"/>
+ <source>Alt+A</source>
+ <translation>Alt+A</translation>
+ </message>
+ <message>
+ <location filename="../forms/messagepage.ui" line="71"/>
+ <source>Paste address from clipboard</source>
+ <translation>Paste address from clipboard</translation>
+ </message>
+ <message>
+ <location filename="../forms/messagepage.ui" line="81"/>
+ <source>Alt+P</source>
+ <translation>Alt+P</translation>
+ </message>
+ <message>
+ <location filename="../forms/messagepage.ui" line="93"/>
+ <source>Enter the message you want to sign here</source>
+ <translation>Escreva aqui a mensagem que deseja assinar</translation>
+ </message>
+ <message>
+ <location filename="../forms/messagepage.ui" line="128"/>
+ <source>Copy the current signature to the system clipboard</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../forms/messagepage.ui" line="131"/>
+ <source>&amp;Copy Signature</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../forms/messagepage.ui" line="142"/>
+ <source>Reset all sign message fields</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../forms/messagepage.ui" line="145"/>
+ <source>Clear &amp;All</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../messagepage.cpp" line="30"/>
+ <source>Click &quot;Sign Message&quot; to get signature</source>
+ <translation>Clique &quot;Assinar mensagem&quot; para aceder á assinatura</translation>
+ </message>
+ <message>
+ <location filename="../forms/messagepage.ui" line="114"/>
+ <source>Sign a message to prove you own this address</source>
+ <translation>Assine uma mensagem para provar que é dono deste endereço</translation>
+ </message>
+ <message>
+ <location filename="../forms/messagepage.ui" line="117"/>
+ <source>&amp;Sign Message</source>
+ <translation>&amp;Assinar Mensagem</translation>
+ </message>
+ <message>
+ <location filename="../messagepage.cpp" line="79"/>
+ <location filename="../messagepage.cpp" line="94"/>
+ <location filename="../messagepage.cpp" line="106"/>
+ <source>Error signing</source>
+ <translation>Erro ao assinar</translation>
+ </message>
+ <message>
+ <location filename="../messagepage.cpp" line="79"/>
+ <source>%1 is not a valid address.</source>
+ <translation>%1 não é um endereço válido.</translation>
+ </message>
+ <message>
+ <location filename="../messagepage.cpp" line="94"/>
+ <source>Private key for %1 is not available.</source>
+ <translation>A chave privada para %1 não está disponível.</translation>
+ </message>
+ <message>
+ <location filename="../messagepage.cpp" line="106"/>
+ <source>Sign failed</source>
+ <translation>Falha ao assinar</translation>
+ </message>
+</context>
+<context>
+ <name>OptionsDialog</name>
+ <message>
+ <location filename="../optionsdialog.cpp" line="80"/>
+ <source>Main</source>
+ <translation>Geral</translation>
+ </message>
+ <message>
+ <location filename="../optionsdialog.cpp" line="85"/>
+ <source>Display</source>
+ <translation>Janela</translation>
+ </message>
+ <message>
+ <location filename="../optionsdialog.cpp" line="105"/>
+ <source>Options</source>
+ <translation>Opções</translation>
+ </message>
+</context>
+<context>
+ <name>OverviewPage</name>
+ <message>
+ <location filename="../forms/overviewpage.ui" line="14"/>
+ <source>Form</source>
+ <translation>Formulário</translation>
+ </message>
+ <message>
+ <location filename="../forms/overviewpage.ui" line="40"/>
+ <source>Balance:</source>
+ <translation>Saldo:</translation>
+ </message>
+ <message>
+ <location filename="../forms/overviewpage.ui" line="47"/>
+ <source>123.456 BTC</source>
+ <translation>123.456 BTC</translation>
+ </message>
+ <message>
+ <location filename="../forms/overviewpage.ui" line="54"/>
+ <source>Number of transactions:</source>
+ <translation>Número de transações:</translation>
+ </message>
+ <message>
+ <location filename="../forms/overviewpage.ui" line="61"/>
+ <source>0</source>
+ <translation>0</translation>
+ </message>
+ <message>
+ <location filename="../forms/overviewpage.ui" line="68"/>
+ <source>Unconfirmed:</source>
+ <translation>Não confirmado:</translation>
+ </message>
+ <message>
+ <location filename="../forms/overviewpage.ui" line="75"/>
+ <source>0 BTC</source>
+ <translation>0 BTC</translation>
+ </message>
+ <message>
+ <location filename="../forms/overviewpage.ui" line="88"/>
+ <source>Wallet</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../forms/overviewpage.ui" line="124"/>
+ <source>&lt;b&gt;Recent transactions&lt;/b&gt;</source>
+ <translation>&lt;b&gt;Transações recentes&lt;/b&gt;</translation>
+ </message>
+ <message>
+ <location filename="../overviewpage.cpp" line="103"/>
+ <source>Your current balance</source>
+ <translation>O seu saldo actual</translation>
+ </message>
+ <message>
+ <location filename="../overviewpage.cpp" line="108"/>
+ <source>Total of transactions that have yet to be confirmed, and do not yet count toward the current balance</source>
+ <translation>Total de transações ainda não confirmadas, e que não estão contabilizadas ainda no seu saldo actual</translation>
+ </message>
+ <message>
+ <location filename="../overviewpage.cpp" line="111"/>
+ <source>Total number of transactions in wallet</source>
+ <translation>Número total de transações na carteira</translation>
+ </message>
+</context>
+<context>
+ <name>QRCodeDialog</name>
+ <message>
+ <location filename="../forms/qrcodedialog.ui" line="14"/>
+ <source>QR-Code Dialog</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../forms/qrcodedialog.ui" line="32"/>
+ <source>QR Code</source>
+ <translation>Código QR</translation>
+ </message>
+ <message>
+ <location filename="../forms/qrcodedialog.ui" line="55"/>
+ <source>Request Payment</source>
+ <translation>Requisitar Pagamento</translation>
+ </message>
+ <message>
+ <location filename="../forms/qrcodedialog.ui" line="70"/>
+ <source>Amount:</source>
+ <translation>Quantia:</translation>
+ </message>
+ <message>
+ <location filename="../forms/qrcodedialog.ui" line="105"/>
+ <source>BTC</source>
+ <translation>BTC</translation>
+ </message>
+ <message>
+ <location filename="../forms/qrcodedialog.ui" line="121"/>
+ <source>Label:</source>
+ <translation>Rótulo:</translation>
+ </message>
+ <message>
+ <location filename="../forms/qrcodedialog.ui" line="144"/>
+ <source>Message:</source>
+ <translation>Message:</translation>
+ </message>
+ <message>
+ <location filename="../forms/qrcodedialog.ui" line="186"/>
+ <source>&amp;Save As...</source>
+ <translation>&amp;Salvar Como...</translation>
+ </message>
+ <message>
+ <location filename="../qrcodedialog.cpp" line="46"/>
+ <source>Error encoding URI into QR Code.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../qrcodedialog.cpp" line="64"/>
+ <source>Resulting URI too long, try to reduce the text for label / message.</source>
+ <translation>URI resultante muito longo. Tente reduzir o texto do rótulo / mensagem.</translation>
+ </message>
+ <message>
+ <location filename="../qrcodedialog.cpp" line="121"/>
+ <source>Save QR Code</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../qrcodedialog.cpp" line="121"/>
+ <source>PNG Images (*.png)</source>
+ <translation>Imagens PNG (*.png)</translation>
+ </message>
+</context>
+<context>
+ <name>RPCConsole</name>
+ <message>
+ <location filename="../forms/rpcconsole.ui" line="14"/>
+ <source>Bitcoin debug window</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../forms/rpcconsole.ui" line="24"/>
+ <source>Information</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../forms/rpcconsole.ui" line="33"/>
+ <source>Client name</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../forms/rpcconsole.ui" line="40"/>
+ <location filename="../forms/rpcconsole.ui" line="60"/>
+ <location filename="../forms/rpcconsole.ui" line="106"/>
+ <location filename="../forms/rpcconsole.ui" line="156"/>
+ <location filename="../forms/rpcconsole.ui" line="176"/>
+ <location filename="../forms/rpcconsole.ui" line="196"/>
+ <location filename="../forms/rpcconsole.ui" line="229"/>
+ <source>N/A</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../forms/rpcconsole.ui" line="53"/>
+ <source>Client version</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../forms/rpcconsole.ui" line="79"/>
+ <source>Version</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../forms/rpcconsole.ui" line="92"/>
+ <source>Network</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../forms/rpcconsole.ui" line="99"/>
+ <source>Number of connections</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../forms/rpcconsole.ui" line="119"/>
+ <source>On testnet</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../forms/rpcconsole.ui" line="142"/>
+ <source>Block chain</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../forms/rpcconsole.ui" line="149"/>
+ <source>Current number of blocks</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../forms/rpcconsole.ui" line="169"/>
+ <source>Estimated total blocks</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../forms/rpcconsole.ui" line="189"/>
+ <source>Last block time</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../forms/rpcconsole.ui" line="222"/>
+ <source>Build date</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../forms/rpcconsole.ui" line="237"/>
+ <source>Console</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../forms/rpcconsole.ui" line="278"/>
+ <source>&gt;</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../forms/rpcconsole.ui" line="294"/>
+ <source>Clear console</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../rpcconsole.cpp" line="97"/>
+ <source>&amp;Copy</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../rpcconsole.cpp" line="195"/>
+ <source>Welcome to the bitcoin RPC console.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../rpcconsole.cpp" line="196"/>
+ <source>Use up and down arrows to navigate history, and Ctrl-L to clear screen.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../rpcconsole.cpp" line="197"/>
+ <source>Type &quot;help&quot; for an overview of available commands.</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
+ <name>SendCoinsDialog</name>
+ <message>
+ <location filename="../forms/sendcoinsdialog.ui" line="14"/>
+ <location filename="../sendcoinsdialog.cpp" line="122"/>
+ <location filename="../sendcoinsdialog.cpp" line="127"/>
+ <location filename="../sendcoinsdialog.cpp" line="132"/>
+ <location filename="../sendcoinsdialog.cpp" line="137"/>
+ <location filename="../sendcoinsdialog.cpp" line="143"/>
+ <location filename="../sendcoinsdialog.cpp" line="148"/>
+ <location filename="../sendcoinsdialog.cpp" line="153"/>
+ <source>Send Coins</source>
+ <translation>Enviar Moedas</translation>
+ </message>
+ <message>
+ <location filename="../forms/sendcoinsdialog.ui" line="64"/>
+ <source>Send to multiple recipients at once</source>
+ <translation>Enviar para múltiplos destinatários de uma vez</translation>
+ </message>
+ <message>
+ <location filename="../forms/sendcoinsdialog.ui" line="67"/>
+ <source>&amp;Add Recipient</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../forms/sendcoinsdialog.ui" line="84"/>
+ <source>Remove all transaction fields</source>
+ <translation>Remover todos os campos da transação</translation>
+ </message>
+ <message>
+ <location filename="../forms/sendcoinsdialog.ui" line="87"/>
+ <source>Clear all</source>
+ <translation>Apagar tudo</translation>
+ </message>
+ <message>
+ <location filename="../forms/sendcoinsdialog.ui" line="106"/>
+ <source>Balance:</source>
+ <translation>Saldo:</translation>
+ </message>
+ <message>
+ <location filename="../forms/sendcoinsdialog.ui" line="113"/>
+ <source>123.456 BTC</source>
+ <translation>123.456 BTC</translation>
+ </message>
+ <message>
+ <location filename="../forms/sendcoinsdialog.ui" line="144"/>
+ <source>Confirm the send action</source>
+ <translation>Confirme ação de envio</translation>
+ </message>
+ <message>
+ <location filename="../forms/sendcoinsdialog.ui" line="147"/>
+ <source>&amp;Send</source>
+ <translation>&amp;Enviar</translation>
+ </message>
+ <message>
+ <location filename="../sendcoinsdialog.cpp" line="94"/>
+ <source>&lt;b&gt;%1&lt;/b&gt; to %2 (%3)</source>
+ <translation>&lt;b&gt;%1&lt;/b&gt; para %2 (%3)</translation>
+ </message>
+ <message>
+ <location filename="../sendcoinsdialog.cpp" line="99"/>
+ <source>Confirm send coins</source>
+ <translation>Confirme envio de moedas</translation>
+ </message>
+ <message>
+ <location filename="../sendcoinsdialog.cpp" line="100"/>
+ <source>Are you sure you want to send %1?</source>
+ <translation>Tem a certeza que deseja enviar %1?</translation>
+ </message>
+ <message>
+ <location filename="../sendcoinsdialog.cpp" line="100"/>
+ <source> and </source>
+ <translation> e </translation>
+ </message>
+ <message>
+ <location filename="../sendcoinsdialog.cpp" line="123"/>
+ <source>The recepient address is not valid, please recheck.</source>
+ <translation>O endereço de destino não é válido, por favor verifique.</translation>
+ </message>
+ <message>
+ <location filename="../sendcoinsdialog.cpp" line="128"/>
+ <source>The amount to pay must be larger than 0.</source>
+ <translation>A quantia a pagar deverá ser maior que 0.</translation>
+ </message>
+ <message>
+ <location filename="../sendcoinsdialog.cpp" line="133"/>
+ <source>Amount exceeds your balance</source>
+ <translation>A quantia excede o seu saldo</translation>
+ </message>
+ <message>
+ <location filename="../sendcoinsdialog.cpp" line="138"/>
+ <source>Total exceeds your balance when the %1 transaction fee is included</source>
+ <translation>O total excede o seu saldo quando a taxa de transação de %1 for incluída</translation>
+ </message>
+ <message>
+ <location filename="../sendcoinsdialog.cpp" line="144"/>
+ <source>Duplicate address found, can only send to each address once in one send operation</source>
+ <translation>Endereço duplicado encontrado, apenas poderá enviar uma vez para cada endereço por cada operação de envio</translation>
+ </message>
+ <message>
+ <location filename="../sendcoinsdialog.cpp" line="149"/>
+ <source>Error: Transaction creation failed </source>
+ <translation>Erro: Criação da transação falhou </translation>
+ </message>
+ <message>
+ <location filename="../sendcoinsdialog.cpp" line="154"/>
+ <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>Erro: A transação foi rejeitada. Isso poderá acontecer se algumas das moedas na sua carteira já tiverem sido gastas, se por exemplo tiver usado uma cópia do ficheiro wallet.dat e as moedas foram gastas na cópia mas não foram marcadas como gastas aqui.</translation>
+ </message>
+</context>
+<context>
+ <name>SendCoinsEntry</name>
+ <message>
+ <location filename="../forms/sendcoinsentry.ui" line="14"/>
+ <source>Form</source>
+ <translation>Formulário</translation>
+ </message>
+ <message>
+ <location filename="../forms/sendcoinsentry.ui" line="29"/>
+ <source>A&amp;mount:</source>
+ <translation>Q&amp;uantia:</translation>
+ </message>
+ <message>
+ <location filename="../forms/sendcoinsentry.ui" line="42"/>
+ <source>Pay &amp;To:</source>
+ <translation>Pagar &amp;A:</translation>
+ </message>
+ <message>
+ <location filename="../forms/sendcoinsentry.ui" line="66"/>
+ <location filename="../sendcoinsentry.cpp" line="25"/>
+ <source>Enter a label for this address to add it to your address book</source>
+ <translation>Escreva um rótulo para este endereço para o adicionar ao seu livro de endereços</translation>
+ </message>
+ <message>
+ <location filename="../forms/sendcoinsentry.ui" line="75"/>
+ <source>&amp;Label:</source>
+ <translation>&amp;Rótulo:</translation>
+ </message>
+ <message>
+ <location filename="../forms/sendcoinsentry.ui" line="93"/>
+ <source>The address to send the payment to (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L)</source>
+ <translation>O endereço para onde enviar o pagamento (p.ex. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L)</translation>
+ </message>
+ <message>
+ <location filename="../forms/sendcoinsentry.ui" line="103"/>
+ <source>Choose address from address book</source>
+ <translation>Escolher endereço do livro de endereços</translation>
+ </message>
+ <message>
+ <location filename="../forms/sendcoinsentry.ui" line="113"/>
+ <source>Alt+A</source>
+ <translation>Alt+A</translation>
+ </message>
+ <message>
+ <location filename="../forms/sendcoinsentry.ui" line="120"/>
+ <source>Paste address from clipboard</source>
+ <translation>Cole endereço da área de transferência</translation>
+ </message>
+ <message>
+ <location filename="../forms/sendcoinsentry.ui" line="130"/>
+ <source>Alt+P</source>
+ <translation>Alt+P</translation>
+ </message>
+ <message>
+ <location filename="../forms/sendcoinsentry.ui" line="137"/>
+ <source>Remove this recipient</source>
+ <translation>Remover este destinatário</translation>
+ </message>
+ <message>
+ <location filename="../sendcoinsentry.cpp" line="26"/>
+ <source>Enter a Bitcoin address (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L)</source>
+ <translation>Introduza um endereço Bitcoin (p.ex. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L)</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionDesc</name>
+ <message>
+ <location filename="../transactiondesc.cpp" line="20"/>
+ <source>Open for %1 blocks</source>
+ <translation>Aberto para %1 blocos</translation>
+ </message>
+ <message>
+ <location filename="../transactiondesc.cpp" line="22"/>
+ <source>Open until %1</source>
+ <translation>Aberto até %1</translation>
+ </message>
+ <message>
+ <location filename="../transactiondesc.cpp" line="28"/>
+ <source>%1/offline?</source>
+ <translation>%1/desligado?</translation>
+ </message>
+ <message>
+ <location filename="../transactiondesc.cpp" line="30"/>
+ <source>%1/unconfirmed</source>
+ <translation>%1/não confirmada</translation>
+ </message>
+ <message>
+ <location filename="../transactiondesc.cpp" line="32"/>
+ <source>%1 confirmations</source>
+ <translation>%1 confirmações</translation>
+ </message>
+ <message>
+ <location filename="../transactiondesc.cpp" line="50"/>
+ <source>&lt;b&gt;Status:&lt;/b&gt; </source>
+ <translation>&lt;b&gt;Estado:&lt;/b&gt; </translation>
+ </message>
+ <message>
+ <location filename="../transactiondesc.cpp" line="55"/>
+ <source>, has not been successfully broadcast yet</source>
+ <translation>, ainda não foi transmitida com sucesso</translation>
+ </message>
+ <message>
+ <location filename="../transactiondesc.cpp" line="57"/>
+ <source>, broadcast through %1 node</source>
+ <translation>, transmitida através de %1 nó</translation>
+ </message>
+ <message>
+ <location filename="../transactiondesc.cpp" line="59"/>
+ <source>, broadcast through %1 nodes</source>
+ <translation>, transmitida através de %1 nós</translation>
+ </message>
+ <message>
+ <location filename="../transactiondesc.cpp" line="63"/>
+ <source>&lt;b&gt;Date:&lt;/b&gt; </source>
+ <translation>&lt;b&gt;Data:&lt;/b&gt; </translation>
+ </message>
+ <message>
+ <location filename="../transactiondesc.cpp" line="70"/>
+ <source>&lt;b&gt;Source:&lt;/b&gt; Generated&lt;br&gt;</source>
+ <translation>&lt;b&gt;Fonte:&lt;/b&gt; Geradas&lt;br&gt;</translation>
+ </message>
+ <message>
+ <location filename="../transactiondesc.cpp" line="76"/>
+ <location filename="../transactiondesc.cpp" line="93"/>
+ <source>&lt;b&gt;From:&lt;/b&gt; </source>
+ <translation>&lt;b&gt;De:&lt;/b&gt; </translation>
+ </message>
+ <message>
+ <location filename="../transactiondesc.cpp" line="93"/>
+ <source>unknown</source>
+ <translation>desconhecido</translation>
+ </message>
+ <message>
+ <location filename="../transactiondesc.cpp" line="94"/>
+ <location filename="../transactiondesc.cpp" line="117"/>
+ <location filename="../transactiondesc.cpp" line="176"/>
+ <source>&lt;b&gt;To:&lt;/b&gt; </source>
+ <translation>&lt;b&gt;Para:&lt;/b&gt; </translation>
+ </message>
+ <message>
+ <location filename="../transactiondesc.cpp" line="97"/>
+ <source> (yours, label: </source>
+ <translation> (seu, rótulo: </translation>
+ </message>
+ <message>
+ <location filename="../transactiondesc.cpp" line="99"/>
+ <source> (yours)</source>
+ <translation> (seu)</translation>
+ </message>
+ <message>
+ <location filename="../transactiondesc.cpp" line="134"/>
+ <location filename="../transactiondesc.cpp" line="148"/>
+ <location filename="../transactiondesc.cpp" line="193"/>
+ <location filename="../transactiondesc.cpp" line="210"/>
+ <source>&lt;b&gt;Credit:&lt;/b&gt; </source>
+ <translation>&lt;b&gt;Crédito:&lt;/b&gt; </translation>
+ </message>
+ <message>
+ <location filename="../transactiondesc.cpp" line="136"/>
+ <source>(%1 matures in %2 more blocks)</source>
+ <translation>(%1 matura daqui por %2 blocos)</translation>
+ </message>
+ <message>
+ <location filename="../transactiondesc.cpp" line="140"/>
+ <source>(not accepted)</source>
+ <translation>(não aceite)</translation>
+ </message>
+ <message>
+ <location filename="../transactiondesc.cpp" line="184"/>
+ <location filename="../transactiondesc.cpp" line="192"/>
+ <location filename="../transactiondesc.cpp" line="207"/>
+ <source>&lt;b&gt;Debit:&lt;/b&gt; </source>
+ <translation>&lt;b&gt;Débito:&lt;/b&gt; </translation>
+ </message>
+ <message>
+ <location filename="../transactiondesc.cpp" line="198"/>
+ <source>&lt;b&gt;Transaction fee:&lt;/b&gt; </source>
+ <translation>&lt;b&gt;Taxa de transação:&lt;/b&gt; </translation>
+ </message>
+ <message>
+ <location filename="../transactiondesc.cpp" line="214"/>
+ <source>&lt;b&gt;Net amount:&lt;/b&gt; </source>
+ <translation>&lt;b&gt;Valor líquido:&lt;/b&gt; </translation>
+ </message>
+ <message>
+ <location filename="../transactiondesc.cpp" line="220"/>
+ <source>Message:</source>
+ <translation>Mensagem:</translation>
+ </message>
+ <message>
+ <location filename="../transactiondesc.cpp" line="222"/>
+ <source>Comment:</source>
+ <translation>Comentário:</translation>
+ </message>
+ <message>
+ <location filename="../transactiondesc.cpp" line="224"/>
+ <source>Transaction ID:</source>
+ <translation>ID da Transação:</translation>
+ </message>
+ <message>
+ <location filename="../transactiondesc.cpp" line="227"/>
+ <source>Generated coins must wait 120 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, it will change to &quot;not accepted&quot; and not be spendable. This may occasionally happen if another node generates a block within a few seconds of yours.</source>
+ <translation>Moedas geradas deverão maturar por 120 blocos antes de poderem ser gastas. Quando gerou este bloco, ele foi transmitido para a rede para ser incluído na cadeia de blocos. Se a inclusão na cadeia de blocos falhar, irá mudar o estado para &quot;não aceite&quot; e as moedas não poderão ser gastas. Isto poderá acontecer ocasionalmente se outro nó da rede gerar um bloco a poucos segundos de diferença do seu.</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionDescDialog</name>
+ <message>
+ <location filename="../forms/transactiondescdialog.ui" line="14"/>
+ <source>Transaction details</source>
+ <translation>Detalhes da transação</translation>
+ </message>
+ <message>
+ <location filename="../forms/transactiondescdialog.ui" line="20"/>
+ <source>This pane shows a detailed description of the transaction</source>
+ <translation>Esta janela mostra uma descrição detalhada da transação</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionTableModel</name>
+ <message>
+ <location filename="../transactiontablemodel.cpp" line="214"/>
+ <source>Date</source>
+ <translation>Data</translation>
+ </message>
+ <message>
+ <location filename="../transactiontablemodel.cpp" line="214"/>
+ <source>Type</source>
+ <translation>Tipo</translation>
+ </message>
+ <message>
+ <location filename="../transactiontablemodel.cpp" line="214"/>
+ <source>Address</source>
+ <translation>Endereço</translation>
+ </message>
+ <message>
+ <location filename="../transactiontablemodel.cpp" line="214"/>
+ <source>Amount</source>
+ <translation>Quantia</translation>
+ </message>
+ <message numerus="yes">
+ <location filename="../transactiontablemodel.cpp" line="275"/>
+ <source>Open for %n block(s)</source>
+ <translation><numerusform>Aberto para %n bloco</numerusform><numerusform>Aberto para %n blocos</numerusform></translation>
+ </message>
+ <message>
+ <location filename="../transactiontablemodel.cpp" line="278"/>
+ <source>Open until %1</source>
+ <translation>Aberto até %1</translation>
+ </message>
+ <message>
+ <location filename="../transactiontablemodel.cpp" line="281"/>
+ <source>Offline (%1 confirmations)</source>
+ <translation>Desligado (%1 confirmação)</translation>
+ </message>
+ <message>
+ <location filename="../transactiontablemodel.cpp" line="284"/>
+ <source>Unconfirmed (%1 of %2 confirmations)</source>
+ <translation>Não confirmada (%1 de %2 confirmações)</translation>
+ </message>
+ <message>
+ <location filename="../transactiontablemodel.cpp" line="287"/>
+ <source>Confirmed (%1 confirmations)</source>
+ <translation>Confirmada (%1 confirmação)</translation>
+ </message>
+ <message numerus="yes">
+ <location filename="../transactiontablemodel.cpp" line="295"/>
+ <source>Mined balance will be available in %n more blocks</source>
+ <translation><numerusform>Saldo minado estará disponível daqui por %n bloco</numerusform><numerusform>Saldo minado estará disponível daqui por %n blocos</numerusform></translation>
+ </message>
+ <message>
+ <location filename="../transactiontablemodel.cpp" line="301"/>
+ <source>This block was not received by any other nodes and will probably not be accepted!</source>
+ <translation>Este bloco não foi recebido por outros nós e provavelmente não será aceite pela rede!</translation>
+ </message>
+ <message>
+ <location filename="../transactiontablemodel.cpp" line="304"/>
+ <source>Generated but not accepted</source>
+ <translation>Gerado mas não aceite</translation>
+ </message>
+ <message>
+ <location filename="../transactiontablemodel.cpp" line="347"/>
+ <source>Received with</source>
+ <translation>Recebido com</translation>
+ </message>
+ <message>
+ <location filename="../transactiontablemodel.cpp" line="349"/>
+ <source>Received from</source>
+ <translation>Recebido de</translation>
+ </message>
+ <message>
+ <location filename="../transactiontablemodel.cpp" line="352"/>
+ <source>Sent to</source>
+ <translation>Enviado para</translation>
+ </message>
+ <message>
+ <location filename="../transactiontablemodel.cpp" line="354"/>
+ <source>Payment to yourself</source>
+ <translation>Pagamento ao próprio</translation>
+ </message>
+ <message>
+ <location filename="../transactiontablemodel.cpp" line="356"/>
+ <source>Mined</source>
+ <translation>Minado</translation>
+ </message>
+ <message>
+ <location filename="../transactiontablemodel.cpp" line="394"/>
+ <source>(n/a)</source>
+ <translation>(n/d)</translation>
+ </message>
+ <message>
+ <location filename="../transactiontablemodel.cpp" line="593"/>
+ <source>Transaction status. Hover over this field to show number of confirmations.</source>
+ <translation>Estado da transação. Pairar por cima deste campo para mostrar o número de confirmações.</translation>
+ </message>
+ <message>
+ <location filename="../transactiontablemodel.cpp" line="595"/>
+ <source>Date and time that the transaction was received.</source>
+ <translation>Data e hora a que esta transação foi recebida.</translation>
+ </message>
+ <message>
+ <location filename="../transactiontablemodel.cpp" line="597"/>
+ <source>Type of transaction.</source>
+ <translation>Tipo de transação.</translation>
+ </message>
+ <message>
+ <location filename="../transactiontablemodel.cpp" line="599"/>
+ <source>Destination address of transaction.</source>
+ <translation>Endereço de destino da transação.</translation>
+ </message>
+ <message>
+ <location filename="../transactiontablemodel.cpp" line="601"/>
+ <source>Amount removed from or added to balance.</source>
+ <translation>Quantia retirada ou adicionada ao saldo.</translation>
+ </message>
+</context>
+<context>
+ <name>TransactionView</name>
+ <message>
+ <location filename="../transactionview.cpp" line="55"/>
+ <location filename="../transactionview.cpp" line="71"/>
+ <source>All</source>
+ <translation>Todas</translation>
+ </message>
+ <message>
+ <location filename="../transactionview.cpp" line="56"/>
+ <source>Today</source>
+ <translation>Hoje</translation>
+ </message>
+ <message>
+ <location filename="../transactionview.cpp" line="57"/>
+ <source>This week</source>
+ <translation>Esta semana</translation>
+ </message>
+ <message>
+ <location filename="../transactionview.cpp" line="58"/>
+ <source>This month</source>
+ <translation>Este mês</translation>
+ </message>
+ <message>
+ <location filename="../transactionview.cpp" line="59"/>
+ <source>Last month</source>
+ <translation>Mês passado</translation>
+ </message>
+ <message>
+ <location filename="../transactionview.cpp" line="60"/>
+ <source>This year</source>
+ <translation>Este ano</translation>
+ </message>
+ <message>
+ <location filename="../transactionview.cpp" line="61"/>
+ <source>Range...</source>
+ <translation>Período...</translation>
+ </message>
+ <message>
+ <location filename="../transactionview.cpp" line="72"/>
+ <source>Received with</source>
+ <translation>Recebida com</translation>
+ </message>
+ <message>
+ <location filename="../transactionview.cpp" line="74"/>
+ <source>Sent to</source>
+ <translation>Enviada para</translation>
+ </message>
+ <message>
+ <location filename="../transactionview.cpp" line="76"/>
+ <source>To yourself</source>
+ <translation>Para si</translation>
+ </message>
+ <message>
+ <location filename="../transactionview.cpp" line="77"/>
+ <source>Mined</source>
+ <translation>Minadas</translation>
+ </message>
+ <message>
+ <location filename="../transactionview.cpp" line="78"/>
+ <source>Other</source>
+ <translation>Outras</translation>
+ </message>
+ <message>
+ <location filename="../transactionview.cpp" line="84"/>
+ <source>Enter address or label to search</source>
+ <translation>Escreva endereço ou rótulo a procurar</translation>
+ </message>
+ <message>
+ <location filename="../transactionview.cpp" line="90"/>
+ <source>Min amount</source>
+ <translation>Quantia mínima</translation>
+ </message>
+ <message>
+ <location filename="../transactionview.cpp" line="124"/>
+ <source>Copy address</source>
+ <translation>Copiar endereço</translation>
+ </message>
+ <message>
+ <location filename="../transactionview.cpp" line="125"/>
+ <source>Copy label</source>
+ <translation>Copiar rótulo</translation>
+ </message>
+ <message>
+ <location filename="../transactionview.cpp" line="126"/>
+ <source>Copy amount</source>
+ <translation>Copiar quantia</translation>
+ </message>
+ <message>
+ <location filename="../transactionview.cpp" line="127"/>
+ <source>Edit label</source>
+ <translation>Editar rótulo</translation>
+ </message>
+ <message>
+ <location filename="../transactionview.cpp" line="128"/>
+ <source>Show transaction details</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../transactionview.cpp" line="268"/>
+ <source>Export Transaction Data</source>
+ <translation>Exportar Dados das Transações</translation>
+ </message>
+ <message>
+ <location filename="../transactionview.cpp" line="269"/>
+ <source>Comma separated file (*.csv)</source>
+ <translation>Ficheiro separado por vírgula (*.csv)</translation>
+ </message>
+ <message>
+ <location filename="../transactionview.cpp" line="277"/>
+ <source>Confirmed</source>
+ <translation>Confirmada</translation>
+ </message>
+ <message>
+ <location filename="../transactionview.cpp" line="278"/>
+ <source>Date</source>
+ <translation>Data</translation>
+ </message>
+ <message>
+ <location filename="../transactionview.cpp" line="279"/>
+ <source>Type</source>
+ <translation>Tipo</translation>
+ </message>
+ <message>
+ <location filename="../transactionview.cpp" line="280"/>
+ <source>Label</source>
+ <translation>Rótulo</translation>
+ </message>
+ <message>
+ <location filename="../transactionview.cpp" line="281"/>
+ <source>Address</source>
+ <translation>Endereço</translation>
+ </message>
+ <message>
+ <location filename="../transactionview.cpp" line="282"/>
+ <source>Amount</source>
+ <translation>Quantia</translation>
+ </message>
+ <message>
+ <location filename="../transactionview.cpp" line="283"/>
+ <source>ID</source>
+ <translation>ID</translation>
+ </message>
+ <message>
+ <location filename="../transactionview.cpp" line="287"/>
+ <source>Error exporting</source>
+ <translation>Erro ao exportar</translation>
+ </message>
+ <message>
+ <location filename="../transactionview.cpp" line="287"/>
+ <source>Could not write to file %1.</source>
+ <translation>Impossível escrever para o ficheiro %1.</translation>
+ </message>
+ <message>
+ <location filename="../transactionview.cpp" line="382"/>
+ <source>Range:</source>
+ <translation>Período:</translation>
+ </message>
+ <message>
+ <location filename="../transactionview.cpp" line="390"/>
+ <source>to</source>
+ <translation>até</translation>
+ </message>
+</context>
+<context>
+ <name>WalletModel</name>
+ <message>
+ <location filename="../walletmodel.cpp" line="142"/>
+ <source>Sending...</source>
+ <translation>Enviando...</translation>
+ </message>
+</context>
+<context>
+ <name>bitcoin-core</name>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="12"/>
+ <source>Bitcoin version</source>
+ <translation>Versão Bitcoin</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="13"/>
+ <source>Usage:</source>
+ <translation>Utilização:</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="14"/>
+ <source>Send command to -server or bitcoind</source>
+ <translation>Enviar comando para -server ou bitcoind</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="15"/>
+ <source>List commands</source>
+ <translation>Listar comandos</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="16"/>
+ <source>Get help for a command</source>
+ <translation>Obter ajuda para um comando</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="17"/>
+ <source>Options:</source>
+ <translation>Opções:</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="18"/>
+ <source>Specify configuration file (default: bitcoin.conf)</source>
+ <translation>Especificar ficheiro de configuração (por defeito: bitcoin.conf)</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="19"/>
+ <source>Specify pid file (default: bitcoind.pid)</source>
+ <translation>Especificar ficheiro pid (por defeito: bitcoind.pid)</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="20"/>
+ <source>Generate coins</source>
+ <translation>Gerar moedas</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="21"/>
+ <source>Don&apos;t generate coins</source>
+ <translation>Não gerar moedas</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="22"/>
+ <source>Start minimized</source>
+ <translation>Iniciar minimizado</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="23"/>
+ <source>Show splash screen on startup (default: 1)</source>
+ <translation>Mostrar animação ao iniciar (por defeito: 1)</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="24"/>
+ <source>Specify data directory</source>
+ <translation>Especificar pasta de dados</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="25"/>
+ <source>Set database cache size in megabytes (default: 25)</source>
+ <translation>Definir o tamanho da cache de base de dados em megabytes (por defeito: 25)</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="26"/>
+ <source>Set database disk log size in megabytes (default: 100)</source>
+ <translation>Definir o tamanho de registo do disco de base de dados em megabytes (por defeito: 100)</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="27"/>
+ <source>Specify connection timeout (in milliseconds)</source>
+ <translation>Especificar tempo de espera da ligação (em millisegundos)</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="28"/>
+ <source>Connect through socks4 proxy</source>
+ <translation>Ligar através de um proxy socks4</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="29"/>
+ <source>Allow DNS lookups for addnode and connect</source>
+ <translation>Permitir procuras DNS para adicionar nós e ligação</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="30"/>
+ <source>Listen for connections on &lt;port&gt; (default: 8333 or testnet: 18333)</source>
+ <translation>Escute por ligações em &lt;port&gt; (por defeito: 8333 ou testnet: 18333)</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="31"/>
+ <source>Maintain at most &lt;n&gt; connections to peers (default: 125)</source>
+ <translation>Manter no máximo &lt;n&gt; ligações a outros nós da rede (por defeito: 125)</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="33"/>
+ <source>Connect only to the specified node</source>
+ <translation>Apenas ligar ao nó especificado</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="38"/>
+ <source>Threshold for disconnecting misbehaving peers (default: 100)</source>
+ <translation>Tolerância para desligar nós mal-formados (por defeito: 100)</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="39"/>
+ <source>Number of seconds to keep misbehaving peers from reconnecting (default: 86400)</source>
+ <translation>Número de segundos a impedir que nós mal-formados se liguem de novo (por defeito: 86400)</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="42"/>
+ <source>Maximum per-connection receive buffer, &lt;n&gt;*1000 bytes (default: 10000)</source>
+ <translation>Armazenamento intermédio de recepção por ligação, &lt;n&gt;*1000 bytes (por defeito: 10000)</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="43"/>
+ <source>Maximum per-connection send buffer, &lt;n&gt;*1000 bytes (default: 10000)</source>
+ <translation>Armazenamento intermédio de envio por ligação, &lt;n&gt;*1000 bytes (por defeito: 10000)</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="47"/>
+ <source>Accept command line and JSON-RPC commands</source>
+ <translation>Aceitar comandos da consola e JSON-RPC</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="48"/>
+ <source>Run in the background as a daemon and accept commands</source>
+ <translation>Correr o processo como um daemon e aceitar comandos</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="49"/>
+ <source>Use the test network</source>
+ <translation>Utilizar a rede de testes - testnet</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="50"/>
+ <source>Output extra debugging information</source>
+ <translation>Produzir informação de depuração extraordinária</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="51"/>
+ <source>Prepend debug output with timestamp</source>
+ <translation>Preceder informação de depuração com selo temporal</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="52"/>
+ <source>Send trace/debug info to console instead of debug.log file</source>
+ <translation>Enviar informação de rastreio/depuração para a consola e não para o ficheiro debug.log</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="53"/>
+ <source>Send trace/debug info to debugger</source>
+ <translation>Enviar informação de rastreio/depuração para o depurador</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="54"/>
+ <source>Username for JSON-RPC connections</source>
+ <translation>Nome de utilizador para ligações JSON-RPC</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="55"/>
+ <source>Password for JSON-RPC connections</source>
+ <translation>Palavra-passe para ligações JSON-RPC</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="56"/>
+ <source>Listen for JSON-RPC connections on &lt;port&gt; (default: 8332)</source>
+ <translation>Escutar por ligações JSON-RPC na porta &lt;port&gt; (por defeito: 8332)</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="57"/>
+ <source>Allow JSON-RPC connections from specified IP address</source>
+ <translation>Permitir ligações JSON-RPC do endereço IP especificado</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="58"/>
+ <source>Send commands to node running on &lt;ip&gt; (default: 127.0.0.1)</source>
+ <translation>Enviar comandos para o nó a correr em &lt;ip&gt; (por defeito: 127.0.0.1)</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="59"/>
+ <source>Execute command when the best block changes (%s in cmd is replaced by block hash)</source>
+ <translation>Executar comando quando mudar o melhor bloco (na consola, %s é substituído pela hash do bloco)</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="62"/>
+ <source>Upgrade wallet to latest format</source>
+ <translation>Atualize a carteira para o formato mais recente</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="63"/>
+ <source>Set key pool size to &lt;n&gt; (default: 100)</source>
+ <translation>Definir o tamanho da memória de chaves para &lt;n&gt; (por defeito: 100)</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="64"/>
+ <source>Rescan the block chain for missing wallet transactions</source>
+ <translation>Reexaminar a cadeia de blocos para transações em falta na carteira</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="65"/>
+ <source>How many blocks to check at startup (default: 2500, 0 = all)</source>
+ <translation>Verificar quantos blocos ao iniciar (por defeito: 2500, 0 = todos)</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="66"/>
+ <source>How thorough the block verification is (0-6, default: 1)</source>
+ <translation>Minuciosidade da verificação de blocos é (0-6, por defeito: 1)</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="67"/>
+ <source>
+SSL options: (see the Bitcoin Wiki for SSL setup instructions)</source>
+ <translation>
+Opções SSL: (ver a Wiki Bitcoin para instruções de configuração SSL)</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="70"/>
+ <source>Use OpenSSL (https) for JSON-RPC connections</source>
+ <translation>Usar OpenSSL (https) para ligações JSON-RPC</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="71"/>
+ <source>Server certificate file (default: server.cert)</source>
+ <translation>Ficheiro de certificado do servidor (por defeito: server.cert)</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="72"/>
+ <source>Server private key (default: server.pem)</source>
+ <translation>Chave privada do servidor (por defeito: server.pem)</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="73"/>
+ <source>Acceptable ciphers (default: TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!AH:!3DES:@STRENGTH)</source>
+ <translation>Cifras aceitáveis (por defeito: TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!AH:!3DES:@STRENGTH)</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="76"/>
+ <source>This help message</source>
+ <translation>Esta mensagem de ajuda</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="77"/>
+ <source>Usage</source>
+ <translation>Uso</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="78"/>
+ <source>Cannot obtain a lock on data directory %s. Bitcoin is probably already running.</source>
+ <translation>Impossível trancar a pasta de dados %s. Provavelmente o Bitcoin já está a ser executado.</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="81"/>
+ <source>Bitcoin</source>
+ <translation>Bitcoin</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="82"/>
+ <source>Loading addresses...</source>
+ <translation>A carregar endereços...</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="83"/>
+ <source>Error loading addr.dat</source>
+ <translation>Erro ao carregar addr.dat</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="85"/>
+ <source>Error loading blkindex.dat</source>
+ <translation>Erro ao carregar blkindex.dat</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="87"/>
+ <source>Error loading wallet.dat: Wallet corrupted</source>
+ <translation>Erro ao carregar wallet.dat: Carteira danificada</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="88"/>
+ <source>Error loading wallet.dat: Wallet requires newer version of Bitcoin</source>
+ <translation>Erro ao carregar wallet.dat: A Carteira requer uma versão mais recente do Bitcoin</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="89"/>
+ <source>Wallet needed to be rewritten: restart Bitcoin to complete</source>
+ <translation>A Carteira precisou ser reescrita: reinicie o Bitcoin para completar</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="90"/>
+ <source>Error loading wallet.dat</source>
+ <translation>Erro ao carregar wallet.dat</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="122"/>
+ <source>Error: Wallet locked, unable to create transaction </source>
+ <translation>Erro: Carteira bloqueada, incapaz de criar transação </translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="123"/>
+ <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>Erro: Esta transação requer uma taxa de transação mínima de %s devido á sua quantia, complexidade, ou uso de fundos recebidos recentemente </translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="126"/>
+ <source>Error: Transaction creation failed </source>
+ <translation>Error: Transaction creation failed </translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="127"/>
+ <source>Sending...</source>
+ <translation>Enviando...</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="128"/>
+ <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>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.</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="132"/>
+ <source>Invalid amount</source>
+ <translation>Quantia inválida</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="133"/>
+ <source>Insufficient funds</source>
+ <translation>Insufficient funds</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="84"/>
+ <source>Loading block index...</source>
+ <translation>A carregar índice de blocos...</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="32"/>
+ <source>Add a node to connect to and attempt to keep the connection open</source>
+ <translation>Adicione um nó ao qual se ligar e tentar manter a ligação aberta</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="34"/>
+ <source>Find peers using internet relay chat (default: 0)</source>
+ <translation>Encontrar pares usando IRC (por defeito: 0)</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="35"/>
+ <source>Accept connections from outside (default: 1)</source>
+ <translation>Aceitar ligações externas (por defeito: 1)</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="36"/>
+ <source>Set language, for example &quot;de_DE&quot; (default: system locale)</source>
+ <translation>Definir linguagem, por exemplo &quot;pt_PT&quot; (por defeito: linguagem do sistema)</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="37"/>
+ <source>Find peers using DNS lookup (default: 1)</source>
+ <translation>Encontrar pares usando procura DNS (por defeito: 1)</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="44"/>
+ <source>Use Universal Plug and Play to map the listening port (default: 1)</source>
+ <translation>Usar Universal Plug and Play para mapear porta de escuta (por defeito: 1)</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="45"/>
+ <source>Use Universal Plug and Play to map the listening port (default: 0)</source>
+ <translation>Usar Universal Plug and Play para mapear porta de escuta (por defeito: 0)</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="46"/>
+ <source>Fee per KB to add to transactions you send</source>
+ <translation>Fee per KB to add to transactions you send</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="86"/>
+ <source>Loading wallet...</source>
+ <translation>A carregar carteira...</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="91"/>
+ <source>Cannot downgrade wallet</source>
+ <translation>Impossível mudar a carteira para uma versão anterior</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="92"/>
+ <source>Cannot initialize keypool</source>
+ <translation>Impossível inicializar keypool</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="93"/>
+ <source>Cannot write default address</source>
+ <translation>Impossível escrever endereço por defeito</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="94"/>
+ <source>Rescanning...</source>
+ <translation>Reexaminando...</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="95"/>
+ <source>Done loading</source>
+ <translation>Carregamento completo</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="96"/>
+ <source>Invalid -proxy address</source>
+ <translation>Endereço -proxy inválido</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="97"/>
+ <source>Invalid amount for -paytxfee=&lt;amount&gt;</source>
+ <translation>Quantia inválida para -paytxfee=&lt;amount&gt;</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="98"/>
+ <source>Warning: -paytxfee is set very high. This is the transaction fee you will pay if you send a transaction.</source>
+ <translation>Atenção: -paytxfee está definida com um valor muito alto. Esta é a taxa que irá pagar se enviar uma transação.</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="101"/>
+ <source>Error: CreateThread(StartNode) failed</source>
+ <translation>Erro: Criação de segmento(StartNode) falhou</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="11"/>
+ <source>Warning: Disk space is low </source>
+ <translation>Atenção: Pouco espaço em disco </translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="8"/>
+ <source>Unable to bind to port %d on this computer. Bitcoin is probably already running.</source>
+ <translation>Incapaz de vincular à porta %d neste computador. Provavelmente o Bitcoin já está a funcionar.</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="102"/>
+ <source>To use the %s option</source>
+ <translation>Para usar a opção %s</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="103"/>
+ <source>%s, you must set a rpcpassword in the configuration file:
+ %s
+It is recommended you use the following random password:
+rpcuser=bitcoinrpc
+rpcpassword=%s
+(you do not need to remember this password)
+If the file does not exist, create it with owner-readable-only file permissions.
+</source>
+ <translation>%s, deverá definir uma palavra-passe de RPC no ficheiro de configuração :
+ %s
+É recomendado que use a seguinte palavra-passe aleatória:
+rpcuser=bitcoinrpc
+rpcpassword=%s
+(não precisa recordar esta palavra-passe)
+Se o ficheiro não existir, crie-o com permissões de leitura apenas para o dono.
+</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="112"/>
+ <source>Error</source>
+ <translation>Erro</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="113"/>
+ <source>An error occured while setting up the RPC port %i for listening: %s</source>
+ <translation>Ocorreu um erro ao definir a porta de escuta %i do serviço RPC: %s</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="114"/>
+ <source>You must set rpcpassword=&lt;password&gt; in the configuration file:
+%s
+If the file does not exist, create it with owner-readable-only file permissions.</source>
+ <translation>Deverá definir rpcpassword=&lt;password&gt; no ficheiro de configuração:
+%s
+Se o ficheiro não existir, crie-o com permissões de leitura apenas para o dono.</translation>
+ </message>
+ <message>
+ <location filename="../bitcoinstrings.cpp" line="119"/>
+ <source>Warning: Please check that your computer&apos;s date and time are correct. If your clock is wrong Bitcoin will not work properly.</source>
+ <translation>Atenção: Por favor verifique que a data e hora do seu computador estão correctas. Se o seu relógio não estiver certo o Bitcoin não irá funcionar correctamente.</translation>
+ </message>
+</context>
+</TS> \ No newline at end of file
diff --git a/src/qt/messagepage.cpp b/src/qt/messagepage.cpp
index 18bb64fe6c..1f895e28ff 100644
--- a/src/qt/messagepage.cpp
+++ b/src/qt/messagepage.cpp
@@ -10,7 +10,6 @@
#include "main.h"
#include "wallet.h"
#include "init.h"
-#include "util.h"
#include "messagepage.h"
#include "ui_messagepage.h"
@@ -25,7 +24,16 @@ MessagePage::MessagePage(QWidget *parent) :
{
ui->setupUi(this);
+#if (QT_VERSION >= 0x040700)
+ /* Do not move this to the XML file, Qt before 4.7 will choke on it */
+ ui->signFrom->setPlaceholderText(tr("Enter a Bitcoin address (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L)"));
+ ui->signature->setPlaceholderText(tr("Click \"Sign Message\" to get signature"));
+#endif
+
GUIUtil::setupAddressWidget(ui->signFrom, this);
+ ui->signature->installEventFilter(this);
+
+ ui->signFrom->setFocus();
}
MessagePage::~MessagePage()
@@ -105,3 +113,23 @@ void MessagePage::on_signMessage_clicked()
ui->signature->setText(QString::fromStdString(EncodeBase64(&vchSig[0], vchSig.size())));
ui->signature->setFont(GUIUtil::bitcoinAddressFont());
}
+
+void MessagePage::on_clearButton_clicked()
+{
+ ui->signFrom->clear();
+ ui->message->clear();
+ ui->signature->clear();
+
+ ui->signFrom->setFocus();
+}
+
+bool MessagePage::eventFilter(QObject *object, QEvent *event)
+{
+ if(object == ui->signature && (event->type() == QEvent::MouseButtonPress ||
+ event->type() == QEvent::FocusIn))
+ {
+ ui->signature->selectAll();
+ return true;
+ }
+ return QDialog::eventFilter(object, event);
+}
diff --git a/src/qt/messagepage.h b/src/qt/messagepage.h
index 55e6228124..d668ae98d0 100644
--- a/src/qt/messagepage.h
+++ b/src/qt/messagepage.h
@@ -23,6 +23,9 @@ public:
void setAddress(QString);
+protected:
+ bool eventFilter(QObject *object, QEvent *event);
+
private:
Ui::MessagePage *ui;
WalletModel *model;
@@ -33,6 +36,7 @@ private slots:
void on_signMessage_clicked();
void on_copyToClipboard_clicked();
+ void on_clearButton_clicked();
};
#endif // MESSAGEPAGE_H
diff --git a/src/qt/optionsdialog.cpp b/src/qt/optionsdialog.cpp
index 59c44ac5f9..7c6ad087cb 100644
--- a/src/qt/optionsdialog.cpp
+++ b/src/qt/optionsdialog.cpp
@@ -19,73 +19,103 @@
#include <QDoubleValidator>
#include <QRegExpValidator>
#include <QDialogButtonBox>
+#include <QDir>
+#include <QMessageBox>
-/* First page of options */
-class MainOptionsPage : public QWidget
+class OptionsPage: public QWidget
+{
+ Q_OBJECT
+public:
+ explicit OptionsPage(QWidget *parent=0): QWidget(parent) {}
+
+ virtual void setMapper(MonitoredDataMapper *mapper) = 0;
+};
+
+class MainOptionsPage: public OptionsPage
{
Q_OBJECT
public:
explicit MainOptionsPage(QWidget *parent=0);
- void setMapper(MonitoredDataMapper *mapper);
+ virtual void setMapper(MonitoredDataMapper *mapper);
private:
+ BitcoinAmountField *fee_edit;
QCheckBox *bitcoin_at_startup;
+ QCheckBox *detach_database;
+};
+
+class WindowOptionsPage: public OptionsPage
+{
+ Q_OBJECT
+public:
+ explicit WindowOptionsPage(QWidget *parent=0);
+
+ virtual void setMapper(MonitoredDataMapper *mapper);
+private:
#ifndef Q_WS_MAC
QCheckBox *minimize_to_tray;
-#endif
- QCheckBox *map_port_upnp;
-#ifndef Q_WS_MAC
QCheckBox *minimize_on_close;
#endif
- QCheckBox *connect_socks4;
- QCheckBox *detach_database;
- QLineEdit *proxy_ip;
- QLineEdit *proxy_port;
- BitcoinAmountField *fee_edit;
-
-signals:
-
-public slots:
-
};
-class DisplayOptionsPage : public QWidget
+class DisplayOptionsPage: public OptionsPage
{
Q_OBJECT
public:
explicit DisplayOptionsPage(QWidget *parent=0);
- void setMapper(MonitoredDataMapper *mapper);
+ virtual void setMapper(MonitoredDataMapper *mapper);
private:
+ QValueComboBox *lang;
QValueComboBox *unit;
QCheckBox *display_addresses;
-signals:
+ bool restart_warning_displayed;
+private slots:
+ void showRestartWarning();
+};
-public slots:
+class NetworkOptionsPage: public OptionsPage
+{
+ Q_OBJECT
+public:
+ explicit NetworkOptionsPage(QWidget *parent=0);
+ virtual void setMapper(MonitoredDataMapper *mapper);
+private:
+ QCheckBox *map_port_upnp;
+ QCheckBox *connect_socks4;
+ QLineEdit *proxy_ip;
+ QLineEdit *proxy_port;
};
+
#include "optionsdialog.moc"
OptionsDialog::OptionsDialog(QWidget *parent):
QDialog(parent), contents_widget(0), pages_widget(0),
- model(0), main_page(0), display_page(0)
+ model(0)
{
contents_widget = new QListWidget();
contents_widget->setMaximumWidth(128);
pages_widget = new QStackedWidget();
- pages_widget->setMinimumWidth(300);
+ pages_widget->setMinimumWidth(500);
+ pages_widget->setMinimumHeight(300);
- QListWidgetItem *item_main = new QListWidgetItem(tr("Main"));
- contents_widget->addItem(item_main);
- main_page = new MainOptionsPage(this);
- pages_widget->addWidget(main_page);
+ pages.append(new MainOptionsPage(this));
+ pages.append(new NetworkOptionsPage(this));
+#ifndef Q_WS_MAC
+ /* Hide Window options on Mac as there are currently none available */
+ pages.append(new WindowOptionsPage(this));
+#endif
+ pages.append(new DisplayOptionsPage(this));
- QListWidgetItem *item_display = new QListWidgetItem(tr("Display"));
- contents_widget->addItem(item_display);
- display_page = new DisplayOptionsPage(this);
- pages_widget->addWidget(display_page);
+ foreach(OptionsPage *page, pages)
+ {
+ QListWidgetItem *item = new QListWidgetItem(page->windowTitle());
+ contents_widget->addItem(item);
+ pages_widget->addWidget(page);
+ }
contents_widget->setCurrentRow(0);
@@ -125,8 +155,11 @@ void OptionsDialog::setModel(OptionsModel *model)
this->model = model;
mapper->setModel(model);
- main_page->setMapper(mapper);
- display_page->setMapper(mapper);
+
+ foreach(OptionsPage *page, pages)
+ {
+ page->setMapper(mapper);
+ }
mapper->toFirst();
}
@@ -163,15 +196,122 @@ void OptionsDialog::disableApply()
apply_button->setEnabled(false);
}
+/* Main options */
MainOptionsPage::MainOptionsPage(QWidget *parent):
- QWidget(parent)
+ OptionsPage(parent)
{
QVBoxLayout *layout = new QVBoxLayout();
+ setWindowTitle(tr("Main"));
+
+ QLabel *fee_help = new QLabel(tr("Optional transaction fee per kB that helps make sure your transactions are processed quickly. Most transactions are 1 kB. Fee 0.01 recommended."));
+ fee_help->setWordWrap(true);
+ layout->addWidget(fee_help);
+
+ QHBoxLayout *fee_hbox = new QHBoxLayout();
+ fee_hbox->addSpacing(18);
+ QLabel *fee_label = new QLabel(tr("Pay transaction &fee"));
+ fee_hbox->addWidget(fee_label);
+ fee_edit = new BitcoinAmountField();
+
+ fee_label->setBuddy(fee_edit);
+ fee_hbox->addWidget(fee_edit);
+ fee_hbox->addStretch(1);
+
+ layout->addLayout(fee_hbox);
- bitcoin_at_startup = new QCheckBox(tr("&Start Bitcoin on window system startup"));
- bitcoin_at_startup->setToolTip(tr("Automatically start Bitcoin after the computer is turned on"));
+ bitcoin_at_startup = new QCheckBox(tr("&Start Bitcoin on system login"));
+ bitcoin_at_startup->setToolTip(tr("Automatically start Bitcoin after logging in to the system"));
layout->addWidget(bitcoin_at_startup);
+ detach_database = new QCheckBox(tr("&Detach databases at shutdown"));
+ detach_database->setToolTip(tr("Detach block and address databases at shutdown. This means they can be moved to another data directory, but it slows down shutdown. The wallet is always detached."));
+ layout->addWidget(detach_database);
+
+ layout->addStretch(1); // Extra space at bottom
+ setLayout(layout);
+}
+
+void MainOptionsPage::setMapper(MonitoredDataMapper *mapper)
+{
+ // Map model to widgets
+ mapper->addMapping(fee_edit, OptionsModel::Fee);
+ mapper->addMapping(bitcoin_at_startup, OptionsModel::StartAtStartup);
+ mapper->addMapping(detach_database, OptionsModel::DetachDatabases);
+}
+
+/* Display options */
+DisplayOptionsPage::DisplayOptionsPage(QWidget *parent):
+ OptionsPage(parent), restart_warning_displayed(false)
+{
+ setWindowTitle(tr("Display"));
+
+ QVBoxLayout *layout = new QVBoxLayout();
+
+ QHBoxLayout *lang_hbox = new QHBoxLayout();
+ lang_hbox->addSpacing(18);
+ QLabel *lang_label = new QLabel(tr("User Interface &Language:"));
+ lang_hbox->addWidget(lang_label);
+ lang = new QValueComboBox(this);
+ // Make list of languages
+ QDir translations(":translations");
+ lang->addItem(QString("(") + tr("default") + QString(")"), QVariant(""));
+ foreach(const QString &langStr, translations.entryList())
+ {
+ lang->addItem(langStr, QVariant(langStr));
+ }
+
+ lang->setToolTip(tr("The user interface language can be set here. This setting will only take effect after restarting Bitcoin."));
+ connect(lang, SIGNAL(activated(int)), this, SLOT(showRestartWarning()));
+
+ lang_label->setBuddy(lang);
+ lang_hbox->addWidget(lang);
+
+ layout->addLayout(lang_hbox);
+
+ QHBoxLayout *unit_hbox = new QHBoxLayout();
+ unit_hbox->addSpacing(18);
+ QLabel *unit_label = new QLabel(tr("&Unit to show amounts in:"));
+ unit_hbox->addWidget(unit_label);
+ unit = new QValueComboBox(this);
+ unit->setModel(new BitcoinUnits(this));
+ unit->setToolTip(tr("Choose the default subdivision unit to show in the interface, and when sending coins"));
+
+ unit_label->setBuddy(unit);
+ unit_hbox->addWidget(unit);
+
+ layout->addLayout(unit_hbox);
+
+ display_addresses = new QCheckBox(tr("&Display addresses in transaction list"), this);
+ display_addresses->setToolTip(tr("Whether to show Bitcoin addresses in the transaction list"));
+ layout->addWidget(display_addresses);
+
+ layout->addStretch();
+ setLayout(layout);
+}
+
+void DisplayOptionsPage::setMapper(MonitoredDataMapper *mapper)
+{
+ mapper->addMapping(lang, OptionsModel::Language);
+ mapper->addMapping(unit, OptionsModel::DisplayUnit);
+ mapper->addMapping(display_addresses, OptionsModel::DisplayAddresses);
+}
+
+void DisplayOptionsPage::showRestartWarning()
+{
+ if(!restart_warning_displayed)
+ {
+ QMessageBox::warning(this, tr("Warning"), tr("This setting will take effect after restarting Bitcoin."), QMessageBox::Ok);
+ restart_warning_displayed = true;
+ }
+}
+
+/* Window options */
+WindowOptionsPage::WindowOptionsPage(QWidget *parent):
+ OptionsPage(parent)
+{
+ QVBoxLayout *layout = new QVBoxLayout();
+ setWindowTitle(tr("Window"));
+
#ifndef Q_WS_MAC
minimize_to_tray = new QCheckBox(tr("&Minimize to the tray instead of the taskbar"));
minimize_to_tray->setToolTip(tr("Show only a tray icon after minimizing the window"));
@@ -182,6 +322,28 @@ MainOptionsPage::MainOptionsPage(QWidget *parent):
layout->addWidget(minimize_on_close);
#endif
+ layout->addStretch(1); // Extra space at bottom
+ setLayout(layout);
+}
+
+void WindowOptionsPage::setMapper(MonitoredDataMapper *mapper)
+{
+ // Map model to widgets
+#ifndef Q_WS_MAC
+ mapper->addMapping(minimize_to_tray, OptionsModel::MinimizeToTray);
+#endif
+#ifndef Q_WS_MAC
+ mapper->addMapping(minimize_on_close, OptionsModel::MinimizeOnClose);
+#endif
+}
+
+/* Network options */
+NetworkOptionsPage::NetworkOptionsPage(QWidget *parent):
+ OptionsPage(parent)
+{
+ QVBoxLayout *layout = new QVBoxLayout();
+ setWindowTitle(tr("Network"));
+
map_port_upnp = new QCheckBox(tr("Map port using &UPnP"));
map_port_upnp->setToolTip(tr("Automatically open the Bitcoin client port on the router. This only works when your router supports UPnP and it is enabled."));
layout->addWidget(map_port_upnp);
@@ -192,7 +354,7 @@ MainOptionsPage::MainOptionsPage(QWidget *parent):
QHBoxLayout *proxy_hbox = new QHBoxLayout();
proxy_hbox->addSpacing(18);
- QLabel *proxy_ip_label = new QLabel(tr("Proxy &IP: "));
+ QLabel *proxy_ip_label = new QLabel(tr("Proxy &IP:"));
proxy_hbox->addWidget(proxy_ip_label);
proxy_ip = new QLineEdit();
proxy_ip->setMaximumWidth(140);
@@ -201,7 +363,7 @@ MainOptionsPage::MainOptionsPage(QWidget *parent):
proxy_ip->setToolTip(tr("IP address of the proxy (e.g. 127.0.0.1)"));
proxy_ip_label->setBuddy(proxy_ip);
proxy_hbox->addWidget(proxy_ip);
- QLabel *proxy_port_label = new QLabel(tr("&Port: "));
+ QLabel *proxy_port_label = new QLabel(tr("&Port:"));
proxy_hbox->addWidget(proxy_port_label);
proxy_port = new QLineEdit();
proxy_port->setMaximumWidth(55);
@@ -211,31 +373,9 @@ MainOptionsPage::MainOptionsPage(QWidget *parent):
proxy_port_label->setBuddy(proxy_port);
proxy_hbox->addWidget(proxy_port);
proxy_hbox->addStretch(1);
-
layout->addLayout(proxy_hbox);
- QLabel *fee_help = new QLabel(tr("Optional transaction fee per kB that helps make sure your transactions are processed quickly. Most transactions are 1 kB. Fee 0.01 recommended."));
- fee_help->setWordWrap(true);
- layout->addWidget(fee_help);
-
- QHBoxLayout *fee_hbox = new QHBoxLayout();
- fee_hbox->addSpacing(18);
- QLabel *fee_label = new QLabel(tr("Pay transaction &fee"));
- fee_hbox->addWidget(fee_label);
- fee_edit = new BitcoinAmountField();
- fee_edit->setToolTip(tr("Optional transaction fee per kB that helps make sure your transactions are processed quickly. Most transactions are 1 kB. Fee 0.01 recommended."));
-
- fee_label->setBuddy(fee_edit);
- fee_hbox->addWidget(fee_edit);
- fee_hbox->addStretch(1);
-
- layout->addLayout(fee_hbox);
-
- detach_database = new QCheckBox(tr("Detach databases at shutdown"));
- detach_database->setToolTip(tr("Detach block and address databases at shutdown. This means they can be moved to another data directory, but it slows down shutdown. The wallet is always detached."));
- layout->addWidget(detach_database);
layout->addStretch(1); // Extra space at bottom
-
setLayout(layout);
connect(connect_socks4, SIGNAL(toggled(bool)), proxy_ip, SLOT(setEnabled(bool)));
@@ -246,53 +386,11 @@ MainOptionsPage::MainOptionsPage(QWidget *parent):
#endif
}
-void MainOptionsPage::setMapper(MonitoredDataMapper *mapper)
+void NetworkOptionsPage::setMapper(MonitoredDataMapper *mapper)
{
// Map model to widgets
- mapper->addMapping(bitcoin_at_startup, OptionsModel::StartAtStartup);
-#ifndef Q_WS_MAC
- mapper->addMapping(minimize_to_tray, OptionsModel::MinimizeToTray);
-#endif
mapper->addMapping(map_port_upnp, OptionsModel::MapPortUPnP);
-#ifndef Q_WS_MAC
- mapper->addMapping(minimize_on_close, OptionsModel::MinimizeOnClose);
-#endif
mapper->addMapping(connect_socks4, OptionsModel::ConnectSOCKS4);
mapper->addMapping(proxy_ip, OptionsModel::ProxyIP);
mapper->addMapping(proxy_port, OptionsModel::ProxyPort);
- mapper->addMapping(fee_edit, OptionsModel::Fee);
- mapper->addMapping(detach_database, OptionsModel::DetachDatabases);
-}
-
-DisplayOptionsPage::DisplayOptionsPage(QWidget *parent):
- QWidget(parent)
-{
- QVBoxLayout *layout = new QVBoxLayout();
-
- QHBoxLayout *unit_hbox = new QHBoxLayout();
- unit_hbox->addSpacing(18);
- QLabel *unit_label = new QLabel(tr("&Unit to show amounts in: "));
- unit_hbox->addWidget(unit_label);
- unit = new QValueComboBox(this);
- unit->setModel(new BitcoinUnits(this));
- unit->setToolTip(tr("Choose the default subdivision unit to show in the interface, and when sending coins"));
-
- unit_label->setBuddy(unit);
- unit_hbox->addWidget(unit);
-
- layout->addLayout(unit_hbox);
-
- display_addresses = new QCheckBox(tr("&Display addresses in transaction list"), this);
- display_addresses->setToolTip(tr("Whether to show Bitcoin addresses in the transaction list"));
- layout->addWidget(display_addresses);
-
- layout->addStretch();
-
- setLayout(layout);
-}
-
-void DisplayOptionsPage::setMapper(MonitoredDataMapper *mapper)
-{
- mapper->addMapping(unit, OptionsModel::DisplayUnit);
- mapper->addMapping(display_addresses, OptionsModel::DisplayAddresses);
}
diff --git a/src/qt/optionsdialog.h b/src/qt/optionsdialog.h
index 9e1f87c646..ea0cbb8bfc 100644
--- a/src/qt/optionsdialog.h
+++ b/src/qt/optionsdialog.h
@@ -2,6 +2,7 @@
#define OPTIONSDIALOG_H
#include <QDialog>
+#include <QList>
QT_BEGIN_NAMESPACE
class QStackedWidget;
@@ -10,8 +11,7 @@ class QListWidgetItem;
class QPushButton;
QT_END_NAMESPACE
class OptionsModel;
-class MainOptionsPage;
-class DisplayOptionsPage;
+class OptionsPage;
class MonitoredDataMapper;
/** Preferences dialog. */
@@ -43,11 +43,7 @@ private:
MonitoredDataMapper *mapper;
QPushButton *apply_button;
- // Pages
- MainOptionsPage *main_page;
- DisplayOptionsPage *display_page;
-
- void setupMainPage();
+ QList<OptionsPage*> pages;
};
#endif // OPTIONSDIALOG_H
diff --git a/src/qt/optionsmodel.cpp b/src/qt/optionsmodel.cpp
index 5bba308cf2..9f1c6447ae 100644
--- a/src/qt/optionsmodel.cpp
+++ b/src/qt/optionsmodel.cpp
@@ -4,6 +4,7 @@
#include "init.h"
#include "walletdb.h"
+#include "guiutil.h"
OptionsModel::OptionsModel(QObject *parent) :
QAbstractListModel(parent)
@@ -21,8 +22,9 @@ void OptionsModel::Init()
fMinimizeToTray = settings.value("fMinimizeToTray", false).toBool();
fMinimizeOnClose = settings.value("fMinimizeOnClose", false).toBool();
nTransactionFee = settings.value("nTransactionFee").toLongLong();
+ language = settings.value("language", "").toString();
- // These are shared with core bitcoin; we want
+ // These are shared with core Bitcoin; we want
// command-line options to override the GUI settings:
if (settings.contains("fUseUPnP"))
SoftSetBoolArg("-upnp", settings.value("fUseUPnP").toBool());
@@ -30,6 +32,8 @@ void OptionsModel::Init()
SoftSetArg("-proxy", settings.value("addrProxy").toString().toStdString());
if (settings.contains("detachDB"))
SoftSetBoolArg("-detachdb", settings.value("detachDB").toBool());
+ if (!language.isEmpty())
+ SoftSetArg("-lang", language.toStdString());
}
bool OptionsModel::Upgrade()
@@ -104,7 +108,7 @@ QVariant OptionsModel::data(const QModelIndex & index, int role) const
switch(index.row())
{
case StartAtStartup:
- return QVariant(GetStartOnSystemStartup());
+ return QVariant(GUIUtil::GetStartOnSystemStartup());
case MinimizeToTray:
return QVariant(fMinimizeToTray);
case MapPortUPnP:
@@ -125,6 +129,8 @@ QVariant OptionsModel::data(const QModelIndex & index, int role) const
return QVariant(bDisplayAddresses);
case DetachDatabases:
return QVariant(fDetachDB);
+ case Language:
+ return settings.value("language", "");
default:
return QVariant();
}
@@ -141,7 +147,7 @@ bool OptionsModel::setData(const QModelIndex & index, const QVariant & value, in
switch(index.row())
{
case StartAtStartup:
- successful = SetStartOnSystemStartup(value.toBool());
+ successful = GUIUtil::SetStartOnSystemStartup(value.toBool());
break;
case MinimizeToTray:
fMinimizeToTray = value.toBool();
@@ -213,6 +219,10 @@ bool OptionsModel::setData(const QModelIndex & index, const QVariant & value, in
settings.setValue("detachDB", fDetachDB);
}
break;
+ case Language: {
+ settings.setValue("language", value);
+ }
+ break;
default:
break;
}
diff --git a/src/qt/optionsmodel.h b/src/qt/optionsmodel.h
index da4e86f104..c0374689c6 100644
--- a/src/qt/optionsmodel.h
+++ b/src/qt/optionsmodel.h
@@ -3,8 +3,8 @@
#include <QAbstractListModel>
-/** Interface from QT to configuration data structure for bitcoin client.
- To QT, the options are presented as a list with the different options
+/** Interface from Qt to configuration data structure for Bitcoin client.
+ To Qt, the options are presented as a list with the different options
laid out vertically.
This can be changed to a tree once the settings become sufficiently
complex.
@@ -27,6 +27,7 @@ public:
DisplayUnit, // BitcoinUnits::Unit
DisplayAddresses, // bool
DetachDatabases, // bool
+ Language, // QString
OptionIDRowCount,
};
@@ -45,11 +46,13 @@ public:
bool getMinimizeOnClose();
int getDisplayUnit();
bool getDisplayAddresses();
+ QString getLanguage() { return language; }
private:
int nDisplayUnit;
bool bDisplayAddresses;
bool fMinimizeToTray;
bool fMinimizeOnClose;
+ QString language;
signals:
void displayUnitChanged(int unit);
diff --git a/src/qt/overviewpage.cpp b/src/qt/overviewpage.cpp
index 5b5a8f5271..d7bcc6f45e 100644
--- a/src/qt/overviewpage.cpp
+++ b/src/qt/overviewpage.cpp
@@ -94,31 +94,30 @@ OverviewPage::OverviewPage(QWidget *parent) :
ui(new Ui::OverviewPage),
currentBalance(-1),
currentUnconfirmedBalance(-1),
- txdelegate(new TxViewDelegate())
+ txdelegate(new TxViewDelegate()), filter(0)
{
ui->setupUi(this);
- // Balance: <balance>
- ui->labelBalance->setFont(QFont("Monospace", -1, QFont::Bold));
- ui->labelBalance->setToolTip(tr("Your current balance"));
- ui->labelBalance->setTextInteractionFlags(Qt::TextSelectableByMouse|Qt::TextSelectableByKeyboard);
-
- // Unconfirmed balance: <balance>
- ui->labelUnconfirmed->setFont(QFont("Monospace", -1, QFont::Bold));
- ui->labelUnconfirmed->setToolTip(tr("Total of transactions that have yet to be confirmed, and do not yet count toward the current balance"));
- ui->labelUnconfirmed->setTextInteractionFlags(Qt::TextSelectableByMouse|Qt::TextSelectableByKeyboard);
-
- ui->labelNumTransactions->setToolTip(tr("Total number of transactions in wallet"));
-
// Recent transactions
- ui->listTransactions->setStyleSheet("QListView { background:transparent }");
ui->listTransactions->setItemDelegate(txdelegate);
ui->listTransactions->setIconSize(QSize(DECORATION_SIZE, DECORATION_SIZE));
- ui->listTransactions->setSelectionMode(QAbstractItemView::NoSelection);
ui->listTransactions->setMinimumHeight(NUM_ITEMS * (DECORATION_SIZE + 2));
ui->listTransactions->setAttribute(Qt::WA_MacShowFocusRect, false);
- connect(ui->listTransactions, SIGNAL(clicked(QModelIndex)), this, SIGNAL(transactionClicked(QModelIndex)));
+ connect(ui->listTransactions, SIGNAL(clicked(QModelIndex)), this, SLOT(handleTransactionClicked(QModelIndex)));
+
+ // init "out of sync" warning labels
+ ui->labelWalletStatus->setText("(" + tr("out of sync") + ")");
+ ui->labelTransactionsStatus->setText("(" + tr("out of sync") + ")");
+
+ // start with displaying the "out of sync" warnings
+ showOutOfSyncWarning(true);
+}
+
+void OverviewPage::handleTransactionClicked(const QModelIndex &index)
+{
+ if(filter)
+ emit transactionClicked(filter->mapToSource(index));
}
OverviewPage::~OverviewPage()
@@ -146,7 +145,7 @@ void OverviewPage::setModel(WalletModel *model)
if(model)
{
// Set up transaction list
- TransactionFilterProxy *filter = new TransactionFilterProxy();
+ filter = new TransactionFilterProxy();
filter->setSourceModel(model->getTransactionTableModel());
filter->setLimit(NUM_ITEMS);
filter->setDynamicSortFilter(true);
@@ -177,3 +176,9 @@ void OverviewPage::displayUnitChanged()
txdelegate->unit = model->getOptionsModel()->getDisplayUnit();
ui->listTransactions->update();
}
+
+void OverviewPage::showOutOfSyncWarning(bool fShow)
+{
+ ui->labelWalletStatus->setVisible(fShow);
+ ui->labelTransactionsStatus->setVisible(fShow);
+}
diff --git a/src/qt/overviewpage.h b/src/qt/overviewpage.h
index 1199227168..208b324feb 100644
--- a/src/qt/overviewpage.h
+++ b/src/qt/overviewpage.h
@@ -12,6 +12,7 @@ namespace Ui {
}
class WalletModel;
class TxViewDelegate;
+class TransactionFilterProxy;
/** Overview ("home") page widget */
class OverviewPage : public QWidget
@@ -23,6 +24,7 @@ public:
~OverviewPage();
void setModel(WalletModel *model);
+ void showOutOfSyncWarning(bool fShow);
public slots:
void setBalance(qint64 balance, qint64 unconfirmedBalance);
@@ -38,9 +40,11 @@ private:
qint64 currentUnconfirmedBalance;
TxViewDelegate *txdelegate;
+ TransactionFilterProxy *filter;
private slots:
void displayUnitChanged();
+ void handleTransactionClicked(const QModelIndex &index);
};
#endif // OVERVIEWPAGE_H
diff --git a/src/qt/qrcodedialog.cpp b/src/qt/qrcodedialog.cpp
index 2a428fb79e..32e5462cee 100644
--- a/src/qt/qrcodedialog.cpp
+++ b/src/qt/qrcodedialog.cpp
@@ -15,7 +15,6 @@ QRCodeDialog::QRCodeDialog(const QString &addr, const QString &label, bool enabl
{
ui->setupUi(this);
setWindowTitle(QString("%1").arg(address));
- setAttribute(Qt::WA_DeleteOnClose);
ui->chkReqPayment->setVisible(enableReq);
ui->lnReqAmount->setVisible(enableReq);
@@ -118,7 +117,7 @@ void QRCodeDialog::on_lnMessage_textChanged(const QString &arg1)
void QRCodeDialog::on_btnSaveAs_clicked()
{
- QString fn = GUIUtil::getSaveFileName(this, tr("Save Image..."), QString(), tr("PNG Images (*.png)"));
+ QString fn = GUIUtil::getSaveFileName(this, tr("Save QR Code"), QString(), tr("PNG Images (*.png)"));
if (!fn.isEmpty())
myImage.scaled(EXPORT_IMAGE_SIZE, EXPORT_IMAGE_SIZE).save(fn);
}
diff --git a/src/qt/qtipcserver.cpp b/src/qt/qtipcserver.cpp
index 102ac0ff4e..3d7d90e902 100644
--- a/src/qt/qtipcserver.cpp
+++ b/src/qt/qtipcserver.cpp
@@ -8,7 +8,6 @@
#include <boost/date_time/posix_time/posix_time.hpp>
#include "ui_interface.h"
-#include "util.h"
#include "qtipcserver.h"
using namespace boost::interprocess;
@@ -32,7 +31,7 @@ void ipcThread(void* parg)
ptime d = boost::posix_time::microsec_clock::universal_time() + millisec(100);
if(mq->timed_receive(&strBuf, sizeof(strBuf), nSize, nPriority, d))
{
- ThreadSafeHandleURI(std::string(strBuf, nSize));
+ uiInterface.ThreadSafeHandleURI(std::string(strBuf, nSize));
Sleep(1000);
}
if (fShutdown)
@@ -70,7 +69,7 @@ void ipcInit()
ptime d = boost::posix_time::microsec_clock::universal_time() + millisec(1);
if(mq->timed_receive(&strBuf, sizeof(strBuf), nSize, nPriority, d))
{
- ThreadSafeHandleURI(std::string(strBuf, nSize));
+ uiInterface.ThreadSafeHandleURI(std::string(strBuf, nSize));
}
else
break;
diff --git a/src/qt/qvaluecombobox.cpp b/src/qt/qvaluecombobox.cpp
index c0ad8c12e5..d7ce3d0130 100644
--- a/src/qt/qvaluecombobox.cpp
+++ b/src/qt/qvaluecombobox.cpp
@@ -6,12 +6,12 @@ QValueComboBox::QValueComboBox(QWidget *parent) :
connect(this, SIGNAL(currentIndexChanged(int)), this, SLOT(handleSelectionChanged(int)));
}
-int QValueComboBox::value() const
+QVariant QValueComboBox::value() const
{
- return itemData(currentIndex(), role).toInt();
+ return itemData(currentIndex(), role);
}
-void QValueComboBox::setValue(int value)
+void QValueComboBox::setValue(const QVariant &value)
{
setCurrentIndex(findData(value, role));
}
diff --git a/src/qt/qvaluecombobox.h b/src/qt/qvaluecombobox.h
index 11f342d71c..1a47bb6565 100644
--- a/src/qt/qvaluecombobox.h
+++ b/src/qt/qvaluecombobox.h
@@ -2,19 +2,20 @@
#define QVALUECOMBOBOX_H
#include <QComboBox>
+#include <QVariant>
/* QComboBox that can be used with QDataWidgetMapper to select ordinal values from a model. */
class QValueComboBox : public QComboBox
{
Q_OBJECT
- Q_PROPERTY(int value READ value WRITE setValue NOTIFY valueChanged USER true)
+ Q_PROPERTY(QVariant value READ value WRITE setValue NOTIFY valueChanged USER true)
public:
explicit QValueComboBox(QWidget *parent = 0);
- int value() const;
- void setValue(int value);
+ QVariant value() const;
+ void setValue(const QVariant &value);
- /** Specify model role to use as ordinal value */
+ /** Specify model role to use as ordinal value (defaults to Qt::UserRole) */
void setRole(int role);
signals:
diff --git a/src/qt/res/icons/debugwindow.png b/src/qt/res/icons/debugwindow.png
new file mode 100644
index 0000000000..1712adf0e7
--- /dev/null
+++ b/src/qt/res/icons/debugwindow.png
Binary files differ
diff --git a/src/qt/res/icons/qrcode.png b/src/qt/res/icons/qrcode.png
new file mode 100644
index 0000000000..a8d97174b3
--- /dev/null
+++ b/src/qt/res/icons/qrcode.png
Binary files differ
diff --git a/src/qt/res/images/qrcode.png b/src/qt/res/images/qrcode.png
deleted file mode 100644
index c89a49bbce..0000000000
--- a/src/qt/res/images/qrcode.png
+++ /dev/null
Binary files differ
diff --git a/src/qt/rpcconsole.cpp b/src/qt/rpcconsole.cpp
new file mode 100644
index 0000000000..7029ee33bc
--- /dev/null
+++ b/src/qt/rpcconsole.cpp
@@ -0,0 +1,328 @@
+#include "rpcconsole.h"
+#include "ui_rpcconsole.h"
+
+#include "clientmodel.h"
+#include "bitcoinrpc.h"
+#include "guiutil.h"
+
+#include <QTime>
+#include <QTimer>
+#include <QThread>
+#include <QTextEdit>
+#include <QKeyEvent>
+#include <QUrl>
+#include <QScrollBar>
+
+#include <boost/tokenizer.hpp>
+
+// TODO: make it possible to filter out categories (esp debug messages when implemented)
+// TODO: receive errors and debug messages through ClientModel
+
+const int CONSOLE_SCROLLBACK = 50;
+const int CONSOLE_HISTORY = 50;
+
+const QSize ICON_SIZE(24, 24);
+
+const struct {
+ const char *url;
+ const char *source;
+} ICON_MAPPING[] = {
+ {"cmd-request", ":/icons/tx_input"},
+ {"cmd-reply", ":/icons/tx_output"},
+ {"cmd-error", ":/icons/tx_output"},
+ {"misc", ":/icons/tx_inout"},
+ {NULL, NULL}
+};
+
+/* Object for executing console RPC commands in a separate thread.
+*/
+class RPCExecutor: public QObject
+{
+ Q_OBJECT
+public slots:
+ void start();
+ void request(const QString &command);
+signals:
+ void reply(int category, const QString &command);
+};
+
+#include "rpcconsole.moc"
+
+void RPCExecutor::start()
+{
+ // Nothing to do
+}
+
+void RPCExecutor::request(const QString &command)
+{
+ // Parse shell-like command line into separate arguments
+ std::string strMethod;
+ std::vector<std::string> strParams;
+ try {
+ boost::escaped_list_separator<char> els('\\',' ','\"');
+ std::string strCommand = command.toStdString();
+ boost::tokenizer<boost::escaped_list_separator<char> > tok(strCommand, els);
+
+ int n = 0;
+ for(boost::tokenizer<boost::escaped_list_separator<char> >::iterator beg=tok.begin(); beg!=tok.end();++beg,++n)
+ {
+ if(n == 0) // First parameter is the command
+ strMethod = *beg;
+ else
+ strParams.push_back(*beg);
+ }
+ }
+ catch(boost::escaped_list_error &e)
+ {
+ emit reply(RPCConsole::CMD_ERROR, QString("Parse error"));
+ return;
+ }
+
+ try {
+ std::string strPrint;
+ json_spirit::Value result = tableRPC.execute(strMethod, RPCConvertValues(strMethod, strParams));
+
+ // Format result reply
+ if (result.type() == json_spirit::null_type)
+ strPrint = "";
+ else if (result.type() == json_spirit::str_type)
+ strPrint = result.get_str();
+ else
+ strPrint = write_string(result, true);
+
+ emit reply(RPCConsole::CMD_REPLY, QString::fromStdString(strPrint));
+ }
+ catch (json_spirit::Object& objError)
+ {
+ emit reply(RPCConsole::CMD_ERROR, QString::fromStdString(write_string(json_spirit::Value(objError), false)));
+ }
+ catch (std::exception& e)
+ {
+ emit reply(RPCConsole::CMD_ERROR, QString("Error: ") + QString::fromStdString(e.what()));
+ }
+}
+
+RPCConsole::RPCConsole(QWidget *parent) :
+ QDialog(parent),
+ ui(new Ui::RPCConsole),
+ historyPtr(0)
+{
+ ui->setupUi(this);
+
+#ifdef WIN32
+ ui->openDebugLogfileButton->setIcon(QIcon(":/icons/export"));
+#else
+ // Show Debug logfile label and Open button only for Windows
+ ui->labelDebugLogfile->setVisible(false);
+ ui->openDebugLogfileButton->setVisible(false);
+#endif
+
+ // Install event filter for up and down arrow
+ ui->lineEdit->installEventFilter(this);
+
+ connect(ui->clearButton, SIGNAL(clicked()), this, SLOT(clear()));
+
+ startExecutor();
+
+ clear();
+}
+
+RPCConsole::~RPCConsole()
+{
+ emit stopExecutor();
+ delete ui;
+}
+
+bool RPCConsole::eventFilter(QObject* obj, QEvent *event)
+{
+ if(obj == ui->lineEdit)
+ {
+ if(event->type() == QEvent::KeyPress)
+ {
+ QKeyEvent *key = static_cast<QKeyEvent*>(event);
+ switch(key->key())
+ {
+ case Qt::Key_Up: browseHistory(-1); return true;
+ case Qt::Key_Down: browseHistory(1); return true;
+ }
+ }
+ }
+ return QDialog::eventFilter(obj, event);
+}
+
+void RPCConsole::setClientModel(ClientModel *model)
+{
+ this->clientModel = model;
+ if(model)
+ {
+ // Subscribe to information, replies, messages, errors
+ connect(model, SIGNAL(numConnectionsChanged(int)), this, SLOT(setNumConnections(int)));
+ connect(model, SIGNAL(numBlocksChanged(int,int)), this, SLOT(setNumBlocks(int,int)));
+
+ // Provide initial values
+ ui->clientVersion->setText(model->formatFullVersion());
+ ui->clientName->setText(model->clientName());
+ ui->buildDate->setText(model->formatBuildDate());
+ ui->startupTime->setText(model->formatClientStartupTime().toString());
+
+ setNumConnections(model->getNumConnections());
+ ui->isTestNet->setChecked(model->isTestNet());
+
+ setNumBlocks(model->getNumBlocks(), model->getNumBlocksOfPeers());
+ }
+}
+
+static QString categoryClass(int category)
+{
+ switch(category)
+ {
+ case RPCConsole::CMD_REQUEST: return "cmd-request"; break;
+ case RPCConsole::CMD_REPLY: return "cmd-reply"; break;
+ case RPCConsole::CMD_ERROR: return "cmd-error"; break;
+ default: return "misc";
+ }
+}
+
+void RPCConsole::clear()
+{
+ ui->messagesWidget->clear();
+ ui->lineEdit->clear();
+ ui->lineEdit->setFocus();
+
+ // Add smoothly scaled icon images.
+ // (when using width/height on an img, Qt uses nearest instead of linear interpolation)
+ for(int i=0; ICON_MAPPING[i].url; ++i)
+ {
+ ui->messagesWidget->document()->addResource(
+ QTextDocument::ImageResource,
+ QUrl(ICON_MAPPING[i].url),
+ QImage(ICON_MAPPING[i].source).scaled(ICON_SIZE, Qt::IgnoreAspectRatio, Qt::SmoothTransformation));
+ }
+
+ // Set default style sheet
+ ui->messagesWidget->document()->setDefaultStyleSheet(
+ "table { }"
+ "td.time { color: #808080; padding-top: 3px; } "
+ "td.message { font-family: Monospace; font-size: 12px; } "
+ "td.cmd-request { color: #006060; } "
+ "td.cmd-error { color: red; } "
+ "b { color: #006060; } "
+ );
+
+ message(CMD_REPLY, (tr("Welcome to the Bitcoin RPC console.") + "<br>" +
+ tr("Use up and down arrows to navigate history, and <b>Ctrl-L</b> to clear screen.") + "<br>" +
+ tr("Type <b>help</b> for an overview of available commands.")), true);
+}
+
+void RPCConsole::message(int category, const QString &message, bool html)
+{
+ QTime time = QTime::currentTime();
+ QString timeString = time.toString();
+ QString out;
+ out += "<table><tr><td class=\"time\" width=\"65\">" + timeString + "</td>";
+ out += "<td class=\"icon\" width=\"32\"><img src=\"" + categoryClass(category) + "\"></td>";
+ out += "<td class=\"message " + categoryClass(category) + "\" valign=\"middle\">";
+ if(html)
+ out += message;
+ else
+ out += GUIUtil::HtmlEscape(message, true);
+ out += "</td></tr></table>";
+ ui->messagesWidget->append(out);
+}
+
+void RPCConsole::setNumConnections(int count)
+{
+ ui->numberOfConnections->setText(QString::number(count));
+}
+
+void RPCConsole::setNumBlocks(int count, int countOfPeers)
+{
+ ui->numberOfBlocks->setText(QString::number(count));
+ ui->totalBlocks->setText(QString::number(countOfPeers));
+ if(clientModel)
+ {
+ // If there is no current number available display N/A instead of 0, which can't ever be true
+ ui->totalBlocks->setText(clientModel->getNumBlocksOfPeers() == 0 ? tr("N/A") : QString::number(clientModel->getNumBlocksOfPeers()));
+ ui->lastBlockTime->setText(clientModel->getLastBlockDate().toString());
+ }
+}
+
+void RPCConsole::on_lineEdit_returnPressed()
+{
+ QString cmd = ui->lineEdit->text();
+ ui->lineEdit->clear();
+
+ if(!cmd.isEmpty())
+ {
+ message(CMD_REQUEST, cmd);
+ emit cmdRequest(cmd);
+ // Truncate history from current position
+ history.erase(history.begin() + historyPtr, history.end());
+ // Append command to history
+ history.append(cmd);
+ // Enforce maximum history size
+ while(history.size() > CONSOLE_HISTORY)
+ history.removeFirst();
+ // Set pointer to end of history
+ historyPtr = history.size();
+ // Scroll console view to end
+ scrollToEnd();
+ }
+}
+
+void RPCConsole::browseHistory(int offset)
+{
+ historyPtr += offset;
+ if(historyPtr < 0)
+ historyPtr = 0;
+ if(historyPtr > history.size())
+ historyPtr = history.size();
+ QString cmd;
+ if(historyPtr < history.size())
+ cmd = history.at(historyPtr);
+ ui->lineEdit->setText(cmd);
+}
+
+void RPCConsole::startExecutor()
+{
+ QThread* thread = new QThread;
+ RPCExecutor *executor = new RPCExecutor();
+ executor->moveToThread(thread);
+
+ // Notify executor when thread started (in executor thread)
+ connect(thread, SIGNAL(started()), executor, SLOT(start()));
+ // Replies from executor object must go to this object
+ connect(executor, SIGNAL(reply(int,QString)), this, SLOT(message(int,QString)));
+ // Requests from this object must go to executor
+ connect(this, SIGNAL(cmdRequest(QString)), executor, SLOT(request(QString)));
+ // On stopExecutor signal
+ // - queue executor for deletion (in execution thread)
+ // - quit the Qt event loop in the execution thread
+ connect(this, SIGNAL(stopExecutor()), executor, SLOT(deleteLater()));
+ connect(this, SIGNAL(stopExecutor()), thread, SLOT(quit()));
+ // Queue the thread for deletion (in this thread) when it is finished
+ connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));
+
+ // Default implementation of QThread::run() simply spins up an event loop in the thread,
+ // which is what we want.
+ thread->start();
+}
+
+void RPCConsole::on_tabWidget_currentChanged(int index)
+{
+ if(ui->tabWidget->widget(index) == ui->tab_console)
+ {
+ ui->lineEdit->setFocus();
+ }
+}
+
+void RPCConsole::on_openDebugLogfileButton_clicked()
+{
+ GUIUtil::openDebugLogfile();
+}
+
+void RPCConsole::scrollToEnd()
+{
+ QScrollBar *scrollbar = ui->messagesWidget->verticalScrollBar();
+ scrollbar->setValue(scrollbar->maximum());
+}
diff --git a/src/qt/rpcconsole.h b/src/qt/rpcconsole.h
new file mode 100644
index 0000000000..4b71cdb988
--- /dev/null
+++ b/src/qt/rpcconsole.h
@@ -0,0 +1,64 @@
+#ifndef RPCCONSOLE_H
+#define RPCCONSOLE_H
+
+#include <QDialog>
+
+namespace Ui {
+ class RPCConsole;
+}
+class ClientModel;
+
+/** Local Bitcoin RPC console. */
+class RPCConsole: public QDialog
+{
+ Q_OBJECT
+
+public:
+ explicit RPCConsole(QWidget *parent = 0);
+ ~RPCConsole();
+
+ void setClientModel(ClientModel *model);
+
+ enum MessageClass {
+ MC_ERROR,
+ MC_DEBUG,
+ CMD_REQUEST,
+ CMD_REPLY,
+ CMD_ERROR
+ };
+
+protected:
+ virtual bool eventFilter(QObject* obj, QEvent *event);
+
+private slots:
+ void on_lineEdit_returnPressed();
+ void on_tabWidget_currentChanged(int index);
+ /** open the debug.log from the current datadir */
+ void on_openDebugLogfileButton_clicked();
+
+public slots:
+ void clear();
+ void message(int category, const QString &message, bool html = false);
+ /** Set number of connections shown in the UI */
+ void setNumConnections(int count);
+ /** Set number of blocks shown in the UI */
+ void setNumBlocks(int count, int countOfPeers);
+ /** Go forward or back in history */
+ void browseHistory(int offset);
+ /** Scroll console view to end */
+ void scrollToEnd();
+signals:
+ // For RPC command executor
+ void stopExecutor();
+ void cmdRequest(const QString &command);
+
+private:
+ Ui::RPCConsole *ui;
+ ClientModel *clientModel;
+ QStringList history;
+ int historyPtr;
+
+ void startExecutor();
+};
+
+#endif // RPCCONSOLE_H
diff --git a/src/qt/sendcoinsdialog.cpp b/src/qt/sendcoinsdialog.cpp
index b4029aa0d2..f6a3047a2b 100644
--- a/src/qt/sendcoinsdialog.cpp
+++ b/src/qt/sendcoinsdialog.cpp
@@ -130,28 +130,28 @@ void SendCoinsDialog::on_sendButton_clicked()
break;
case WalletModel::AmountExceedsBalance:
QMessageBox::warning(this, tr("Send Coins"),
- tr("Amount exceeds your balance"),
+ tr("The amount exceeds your balance."),
QMessageBox::Ok, QMessageBox::Ok);
break;
case WalletModel::AmountWithFeeExceedsBalance:
QMessageBox::warning(this, tr("Send Coins"),
- tr("Total exceeds your balance when the %1 transaction fee is included").
+ tr("The total exceeds your balance when the %1 transaction fee is included.").
arg(BitcoinUnits::formatWithUnit(BitcoinUnits::BTC, sendstatus.fee)),
QMessageBox::Ok, QMessageBox::Ok);
break;
case WalletModel::DuplicateAddress:
QMessageBox::warning(this, tr("Send Coins"),
- tr("Duplicate address found, can only send to each address once in one send operation"),
+ tr("Duplicate address found, can only send to each address once per send operation."),
QMessageBox::Ok, QMessageBox::Ok);
break;
case WalletModel::TransactionCreationFailed:
QMessageBox::warning(this, tr("Send Coins"),
- tr("Error: Transaction creation failed "),
+ tr("Error: Transaction creation failed."),
QMessageBox::Ok, QMessageBox::Ok);
break;
case WalletModel::TransactionCommitFailed:
QMessageBox::warning(this, tr("Send Coins"),
- tr("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."),
+ tr("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."),
QMessageBox::Ok, QMessageBox::Ok);
break;
case WalletModel::Aborted: // User aborted, nothing to do
diff --git a/src/qt/sendcoinsentry.cpp b/src/qt/sendcoinsentry.cpp
index c8242d8352..5960597c77 100644
--- a/src/qt/sendcoinsentry.cpp
+++ b/src/qt/sendcoinsentry.cpp
@@ -20,10 +20,10 @@ SendCoinsEntry::SendCoinsEntry(QWidget *parent) :
#ifdef Q_WS_MAC
ui->payToLayout->setSpacing(4);
#endif
-
#if QT_VERSION >= 0x040700
- ui->payTo->setPlaceholderText(tr("Enter a Bitcoin address (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L)"));
+ /* Do not move this to the XML file, Qt before 4.7 will choke on it */
ui->addAsLabel->setPlaceholderText(tr("Enter a label for this address to add it to your address book"));
+ ui->payTo->setPlaceholderText(tr("Enter a Bitcoin address (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L)"));
#endif
setFocusPolicy(Qt::TabFocus);
setFocusProxy(ui->payTo);
diff --git a/src/qt/transactionrecord.cpp b/src/qt/transactionrecord.cpp
index 90fc5b7da3..017244ffd0 100644
--- a/src/qt/transactionrecord.cpp
+++ b/src/qt/transactionrecord.cpp
@@ -40,114 +40,111 @@ QList<TransactionRecord> TransactionRecord::decomposeTransaction(const CWallet *
uint256 hash = wtx.GetHash();
std::map<std::string, std::string> mapValue = wtx.mapValue;
- if (showTransaction(wtx))
+ if (nNet > 0 || wtx.IsCoinBase())
{
- if (nNet > 0 || wtx.IsCoinBase())
+ //
+ // Credit
+ //
+ BOOST_FOREACH(const CTxOut& txout, wtx.vout)
{
- //
- // Credit
- //
- BOOST_FOREACH(const CTxOut& txout, wtx.vout)
+ if(wallet->IsMine(txout))
{
- if(wallet->IsMine(txout))
+ TransactionRecord sub(hash, nTime);
+ CBitcoinAddress address;
+ sub.idx = parts.size(); // sequence number
+ sub.credit = txout.nValue;
+ if (wtx.IsCoinBase())
{
- TransactionRecord sub(hash, nTime);
- CBitcoinAddress address;
- sub.idx = parts.size(); // sequence number
- sub.credit = txout.nValue;
- if (wtx.IsCoinBase())
- {
- // Generated
- sub.type = TransactionRecord::Generated;
- }
- else if (ExtractAddress(txout.scriptPubKey, address) && wallet->HaveKey(address))
- {
- // Received by Bitcoin Address
- sub.type = TransactionRecord::RecvWithAddress;
- sub.address = address.ToString();
- }
- else
- {
- // Received by IP connection (deprecated features), or a multisignature or other non-simple transaction
- sub.type = TransactionRecord::RecvFromOther;
- sub.address = mapValue["from"];
- }
-
- parts.append(sub);
+ // Generated
+ sub.type = TransactionRecord::Generated;
}
+ else if (ExtractAddress(txout.scriptPubKey, address) && wallet->HaveKey(address))
+ {
+ // Received by Bitcoin Address
+ sub.type = TransactionRecord::RecvWithAddress;
+ sub.address = address.ToString();
+ }
+ else
+ {
+ // Received by IP connection (deprecated features), or a multisignature or other non-simple transaction
+ sub.type = TransactionRecord::RecvFromOther;
+ sub.address = mapValue["from"];
+ }
+
+ parts.append(sub);
}
}
- else
+ }
+ else
+ {
+ bool fAllFromMe = true;
+ BOOST_FOREACH(const CTxIn& txin, wtx.vin)
+ fAllFromMe = fAllFromMe && wallet->IsMine(txin);
+
+ bool fAllToMe = true;
+ BOOST_FOREACH(const CTxOut& txout, wtx.vout)
+ fAllToMe = fAllToMe && wallet->IsMine(txout);
+
+ if (fAllFromMe && fAllToMe)
{
- bool fAllFromMe = true;
- BOOST_FOREACH(const CTxIn& txin, wtx.vin)
- fAllFromMe = fAllFromMe && wallet->IsMine(txin);
+ // Payment to self
+ int64 nChange = wtx.GetChange();
- bool fAllToMe = true;
- BOOST_FOREACH(const CTxOut& txout, wtx.vout)
- fAllToMe = fAllToMe && wallet->IsMine(txout);
+ parts.append(TransactionRecord(hash, nTime, TransactionRecord::SendToSelf, "",
+ -(nDebit - nChange), nCredit - nChange));
+ }
+ else if (fAllFromMe)
+ {
+ //
+ // Debit
+ //
+ int64 nTxFee = nDebit - wtx.GetValueOut();
- if (fAllFromMe && fAllToMe)
+ for (unsigned int nOut = 0; nOut < wtx.vout.size(); nOut++)
{
- // Payment to self
- int64 nChange = wtx.GetChange();
+ const CTxOut& txout = wtx.vout[nOut];
+ TransactionRecord sub(hash, nTime);
+ sub.idx = parts.size();
- parts.append(TransactionRecord(hash, nTime, TransactionRecord::SendToSelf, "",
- -(nDebit - nChange), nCredit - nChange));
- }
- else if (fAllFromMe)
- {
- //
- // Debit
- //
- int64 nTxFee = nDebit - wtx.GetValueOut();
+ if(wallet->IsMine(txout))
+ {
+ // Ignore parts sent to self, as this is usually the change
+ // from a transaction sent back to our own address.
+ continue;
+ }
- for (int nOut = 0; nOut < wtx.vout.size(); nOut++)
+ CBitcoinAddress address;
+ if (ExtractAddress(txout.scriptPubKey, address))
{
- const CTxOut& txout = wtx.vout[nOut];
- TransactionRecord sub(hash, nTime);
- sub.idx = parts.size();
-
- if(wallet->IsMine(txout))
- {
- // Ignore parts sent to self, as this is usually the change
- // from a transaction sent back to our own address.
- continue;
- }
-
- CBitcoinAddress address;
- if (ExtractAddress(txout.scriptPubKey, address))
- {
- // Sent to Bitcoin Address
- sub.type = TransactionRecord::SendToAddress;
- sub.address = address.ToString();
- }
- else
- {
- // Sent to IP, or other non-address transaction like OP_EVAL
- sub.type = TransactionRecord::SendToOther;
- sub.address = mapValue["to"];
- }
-
- int64 nValue = txout.nValue;
- /* Add fee to first output */
- if (nTxFee > 0)
- {
- nValue += nTxFee;
- nTxFee = 0;
- }
- sub.debit = -nValue;
-
- parts.append(sub);
+ // Sent to Bitcoin Address
+ sub.type = TransactionRecord::SendToAddress;
+ sub.address = address.ToString();
}
+ else
+ {
+ // Sent to IP, or other non-address transaction like OP_EVAL
+ sub.type = TransactionRecord::SendToOther;
+ sub.address = mapValue["to"];
+ }
+
+ int64 nValue = txout.nValue;
+ /* Add fee to first output */
+ if (nTxFee > 0)
+ {
+ nValue += nTxFee;
+ nTxFee = 0;
+ }
+ sub.debit = -nValue;
+
+ parts.append(sub);
}
- else
- {
- //
- // Mixed debit transaction, can't break down payees
- //
- parts.append(TransactionRecord(hash, nTime, TransactionRecord::Other, "", nNet, 0));
- }
+ }
+ else
+ {
+ //
+ // Mixed debit transaction, can't break down payees
+ //
+ parts.append(TransactionRecord(hash, nTime, TransactionRecord::Other, "", nNet, 0));
}
}
diff --git a/src/qt/transactiontablemodel.cpp b/src/qt/transactiontablemodel.cpp
index 5f505f444e..d36bb495a0 100644
--- a/src/qt/transactiontablemodel.cpp
+++ b/src/qt/transactiontablemodel.cpp
@@ -9,6 +9,7 @@
#include "bitcoinunits.h"
#include "wallet.h"
+#include "ui_interface.h"
#include <QLocale>
#include <QList>
@@ -66,15 +67,14 @@ public:
*/
void refreshWallet()
{
-#ifdef WALLET_UPDATE_DEBUG
- qDebug() << "refreshWallet";
-#endif
+ OutputDebugStringF("refreshWallet\n");
cachedWallet.clear();
{
LOCK(wallet->cs_wallet);
for(std::map<uint256, CWalletTx>::iterator it = wallet->mapWallet.begin(); it != wallet->mapWallet.end(); ++it)
{
- cachedWallet.append(TransactionRecord::decomposeTransaction(wallet, it->second));
+ if(TransactionRecord::showTransaction(it->second))
+ cachedWallet.append(TransactionRecord::decomposeTransaction(wallet, it->second));
}
}
}
@@ -82,49 +82,55 @@ public:
/* Update our model of the wallet incrementally, to synchronize our model of the wallet
with that of the core.
- Call with list of hashes of transactions that were added, removed or changed.
+ Call with transaction that was added, removed or changed.
*/
- void updateWallet(const QList<uint256> &updated)
+ void updateWallet(const uint256 &hash, int status)
{
- // Walk through updated transactions, update model as needed.
-#ifdef WALLET_UPDATE_DEBUG
- qDebug() << "updateWallet";
-#endif
- // Sort update list, and iterate through it in reverse, so that model updates
- // can be emitted from end to beginning (so that earlier updates will not influence
- // the indices of latter ones).
- QList<uint256> updated_sorted = updated;
- qSort(updated_sorted);
-
+ OutputDebugStringF("updateWallet %s %i\n", hash.ToString().c_str(), status);
{
LOCK(wallet->cs_wallet);
- for(int update_idx = updated_sorted.size()-1; update_idx >= 0; --update_idx)
+
+ // Find transaction in wallet
+ std::map<uint256, CWalletTx>::iterator mi = wallet->mapWallet.find(hash);
+ bool inWallet = mi != wallet->mapWallet.end();
+
+ // Find bounds of this transaction in model
+ QList<TransactionRecord>::iterator lower = qLowerBound(
+ cachedWallet.begin(), cachedWallet.end(), hash, TxLessThan());
+ QList<TransactionRecord>::iterator upper = qUpperBound(
+ cachedWallet.begin(), cachedWallet.end(), hash, TxLessThan());
+ int lowerIndex = (lower - cachedWallet.begin());
+ int upperIndex = (upper - cachedWallet.begin());
+ bool inModel = (lower != upper);
+
+ // Determine whether to show transaction or not
+ bool showTransaction = (inWallet && TransactionRecord::showTransaction(mi->second));
+
+ if(status == CT_UPDATED)
{
- const uint256 &hash = updated_sorted.at(update_idx);
- // Find transaction in wallet
- std::map<uint256, CWalletTx>::iterator mi = wallet->mapWallet.find(hash);
- bool inWallet = mi != wallet->mapWallet.end();
- // Find bounds of this transaction in model
- QList<TransactionRecord>::iterator lower = qLowerBound(
- cachedWallet.begin(), cachedWallet.end(), hash, TxLessThan());
- QList<TransactionRecord>::iterator upper = qUpperBound(
- cachedWallet.begin(), cachedWallet.end(), hash, TxLessThan());
- int lowerIndex = (lower - cachedWallet.begin());
- int upperIndex = (upper - cachedWallet.begin());
-
- // Determine if transaction is in model already
- bool inModel = false;
- if(lower != upper)
- {
- inModel = true;
- }
+ if(showTransaction && !inModel)
+ status = CT_NEW; /* Not in model, but want to show, treat as new */
+ if(!showTransaction && inModel)
+ status = CT_DELETED; /* In model, but want to hide, treat as deleted */
+ }
-#ifdef WALLET_UPDATE_DEBUG
- qDebug() << " " << QString::fromStdString(hash.ToString()) << inWallet << " " << inModel
- << lowerIndex << "-" << upperIndex;
-#endif
+ OutputDebugStringF(" inWallet=%i inModel=%i Index=%i-%i showTransaction=%i derivedStatus=%i\n",
+ inWallet, inModel, lowerIndex, upperIndex, showTransaction, status);
- if(inWallet && !inModel)
+ switch(status)
+ {
+ case CT_NEW:
+ if(inModel)
+ {
+ OutputDebugStringF("Warning: updateWallet: Got CT_NEW, but transaction is already in model\n");
+ break;
+ }
+ if(!inWallet)
+ {
+ OutputDebugStringF("Warning: updateWallet: Got CT_NEW, but transaction is not in wallet\n");
+ break;
+ }
+ if(showTransaction)
{
// Added -- insert at the right position
QList<TransactionRecord> toInsert =
@@ -141,17 +147,22 @@ public:
parent->endInsertRows();
}
}
- else if(!inWallet && inModel)
- {
- // Removed -- remove entire transaction from table
- parent->beginRemoveRows(QModelIndex(), lowerIndex, upperIndex-1);
- cachedWallet.erase(lower, upper);
- parent->endRemoveRows();
- }
- else if(inWallet && inModel)
+ break;
+ case CT_DELETED:
+ if(!inModel)
{
- // Updated -- nothing to do, status update will take care of this
+ OutputDebugStringF("Warning: updateWallet: Got CT_DELETED, but transaction is not in model\n");
+ break;
}
+ // Removed -- remove entire transaction from table
+ parent->beginRemoveRows(QModelIndex(), lowerIndex, upperIndex-1);
+ cachedWallet.erase(lower, upper);
+ parent->endRemoveRows();
+ break;
+ case CT_UPDATED:
+ // Miscellaneous updates -- nothing to do, status update will take care of this, and is only computed for
+ // visible transactions.
+ break;
}
}
}
@@ -209,14 +220,15 @@ TransactionTableModel::TransactionTableModel(CWallet* wallet, WalletModel *paren
QAbstractTableModel(parent),
wallet(wallet),
walletModel(parent),
- priv(new TransactionTablePriv(wallet, this))
+ priv(new TransactionTablePriv(wallet, this)),
+ cachedNumBlocks(0)
{
columns << QString() << tr("Date") << tr("Type") << tr("Address") << tr("Amount");
priv->refreshWallet();
QTimer *timer = new QTimer(this);
- connect(timer, SIGNAL(timeout()), this, SLOT(update()));
+ connect(timer, SIGNAL(timeout()), this, SLOT(updateConfirmations()));
timer->start(MODEL_UPDATE_DELAY);
}
@@ -225,29 +237,23 @@ TransactionTableModel::~TransactionTableModel()
delete priv;
}
-void TransactionTableModel::update()
+void TransactionTableModel::updateTransaction(const QString &hash, int status)
{
- QList<uint256> updated;
+ uint256 updated;
+ updated.SetHex(hash.toStdString());
- // Check if there are changes to wallet map
- {
- TRY_LOCK(wallet->cs_wallet, lockWallet);
- if (lockWallet && !wallet->vWalletUpdated.empty())
- {
- BOOST_FOREACH(uint256 hash, wallet->vWalletUpdated)
- {
- updated.append(hash);
- }
- wallet->vWalletUpdated.clear();
- }
- }
+ priv->updateWallet(updated, status);
+}
- if(!updated.empty())
+void TransactionTableModel::updateConfirmations()
+{
+ if(nBestHeight != cachedNumBlocks)
{
- priv->updateWallet(updated);
-
- // Status (number of confirmations) and (possibly) description
- // columns changed for all rows.
+ cachedNumBlocks = nBestHeight;
+ // Blocks came in since last poll.
+ // Invalidate status (number of confirmations) and (possibly) description
+ // for all rows. Qt is smart enough to only actually request the data for the
+ // visible rows.
emit dataChanged(index(0, Status), index(priv->size()-1, Status));
emit dataChanged(index(0, ToAddress), index(priv->size()-1, ToAddress));
}
diff --git a/src/qt/transactiontablemodel.h b/src/qt/transactiontablemodel.h
index db88a0604f..0aafa70915 100644
--- a/src/qt/transactiontablemodel.h
+++ b/src/qt/transactiontablemodel.h
@@ -60,6 +60,7 @@ private:
WalletModel *walletModel;
QStringList columns;
TransactionTablePriv *priv;
+ int cachedNumBlocks;
QString lookupAddress(const std::string &address, bool tooltip) const;
QVariant addressColor(const TransactionRecord *wtx) const;
@@ -72,8 +73,9 @@ private:
QVariant txStatusDecoration(const TransactionRecord *wtx) const;
QVariant txAddressDecoration(const TransactionRecord *wtx) const;
-private slots:
- void update();
+public slots:
+ void updateTransaction(const QString &hash, int status);
+ void updateConfirmations();
friend class TransactionTablePriv;
};
diff --git a/src/qt/transactionview.cpp b/src/qt/transactionview.cpp
index eaed48bfdf..a0e7dd4e77 100644
--- a/src/qt/transactionview.cpp
+++ b/src/qt/transactionview.cpp
@@ -81,12 +81,14 @@ TransactionView::TransactionView(QWidget *parent) :
addressWidget = new QLineEdit(this);
#if QT_VERSION >= 0x040700
+ /* Do not move this to the XML file, Qt before 4.7 will choke on it */
addressWidget->setPlaceholderText(tr("Enter address or label to search"));
#endif
hlayout->addWidget(addressWidget);
amountWidget = new QLineEdit(this);
#if QT_VERSION >= 0x040700
+ /* Do not move this to the XML file, Qt before 4.7 will choke on it */
amountWidget->setPlaceholderText(tr("Min amount"));
#endif
#ifdef Q_WS_MAC
@@ -125,7 +127,7 @@ TransactionView::TransactionView(QWidget *parent) :
QAction *copyLabelAction = new QAction(tr("Copy label"), this);
QAction *copyAmountAction = new QAction(tr("Copy amount"), this);
QAction *editLabelAction = new QAction(tr("Edit label"), this);
- QAction *showDetailsAction = new QAction(tr("Show details..."), this);
+ QAction *showDetailsAction = new QAction(tr("Show transaction details"), this);
contextMenu = new QMenu();
contextMenu->addAction(copyAddressAction);
@@ -415,3 +417,13 @@ void TransactionView::dateRangeChanged()
QDateTime(dateFrom->date()),
QDateTime(dateTo->date()).addDays(1));
}
+
+void TransactionView::focusTransaction(const QModelIndex &idx)
+{
+ if(!transactionProxyModel)
+ return;
+ QModelIndex targetIdx = transactionProxyModel->mapFromSource(idx);
+ transactionView->scrollTo(targetIdx);
+ transactionView->setCurrentIndex(targetIdx);
+ transactionView->setFocus();
+}
diff --git a/src/qt/transactionview.h b/src/qt/transactionview.h
index bc6e1e4e05..4ade3ecd5f 100644
--- a/src/qt/transactionview.h
+++ b/src/qt/transactionview.h
@@ -75,6 +75,7 @@ public slots:
void changedPrefix(const QString &prefix);
void changedAmount(const QString &amount);
void exportClicked();
+ void focusTransaction(const QModelIndex&);
};
diff --git a/src/qt/verifymessagedialog.cpp b/src/qt/verifymessagedialog.cpp
new file mode 100644
index 0000000000..0bac24820c
--- /dev/null
+++ b/src/qt/verifymessagedialog.cpp
@@ -0,0 +1,104 @@
+#include "verifymessagedialog.h"
+#include "ui_verifymessagedialog.h"
+
+#include <string>
+#include <vector>
+
+#include <QDialogButtonBox>
+#include <QAbstractButton>
+#include <QClipboard>
+#include <QMessageBox>
+
+#include "main.h"
+#include "wallet.h"
+#include "walletmodel.h"
+#include "addresstablemodel.h"
+#include "guiutil.h"
+
+VerifyMessageDialog::VerifyMessageDialog(AddressTableModel *addressModel, QWidget *parent) :
+ QDialog(parent),
+ ui(new Ui::VerifyMessageDialog),
+ model(addressModel)
+{
+ ui->setupUi(this);
+
+#if (QT_VERSION >= 0x040700)
+ /* Do not move this to the XML file, Qt before 4.7 will choke on it */
+ ui->lnSig->setPlaceholderText(tr("Enter Bitcoin signature"));
+ ui->lnAddress->setPlaceholderText(tr("Click \"Verify Message\" to obtain address"));
+#endif
+
+ GUIUtil::setupAddressWidget(ui->lnAddress, this);
+ ui->lnAddress->installEventFilter(this);
+
+ ui->edMessage->setFocus();
+}
+
+VerifyMessageDialog::~VerifyMessageDialog()
+{
+ delete ui;
+}
+
+bool VerifyMessageDialog::checkAddress()
+{
+ CDataStream ss(SER_GETHASH, 0);
+ ss << strMessageMagic;
+ ss << ui->edMessage->document()->toPlainText().toStdString();
+ uint256 hash = Hash(ss.begin(), ss.end());
+
+ bool invalid = true;
+ std::vector<unsigned char> vchSig = DecodeBase64(ui->lnSig->text().toStdString().c_str(), &invalid);
+
+ if(invalid)
+ {
+ QMessageBox::warning(this, tr("Invalid Signature"), tr("The signature could not be decoded. Please check the signature and try again."));
+ return false;
+ }
+
+ CKey key;
+ if(!key.SetCompactSignature(hash, vchSig))
+ {
+ QMessageBox::warning(this, tr("Invalid Signature"), tr("The signature did not match the message digest. Please check the signature and try again."));
+ return false;
+ }
+
+ CBitcoinAddress address(key.GetPubKey());
+ QString qStringAddress = QString::fromStdString(address.ToString());
+ ui->lnAddress->setText(qStringAddress);
+ ui->copyToClipboard->setEnabled(true);
+
+ QString label = model->labelForAddress(qStringAddress);
+ ui->lblStatus->setText(label.isEmpty() ? tr("Address not found in address book.") : tr("Address found in address book: %1").arg(label));
+ return true;
+}
+
+void VerifyMessageDialog::on_verifyMessage_clicked()
+{
+ checkAddress();
+}
+
+void VerifyMessageDialog::on_copyToClipboard_clicked()
+{
+ QApplication::clipboard()->setText(ui->lnAddress->text());
+}
+
+void VerifyMessageDialog::on_clearButton_clicked()
+{
+ ui->edMessage->clear();
+ ui->lnSig->clear();
+ ui->lnAddress->clear();
+ ui->lblStatus->clear();
+
+ ui->edMessage->setFocus();
+}
+
+bool VerifyMessageDialog::eventFilter(QObject *object, QEvent *event)
+{
+ if(object == ui->lnAddress && (event->type() == QEvent::MouseButtonPress ||
+ event->type() == QEvent::FocusIn))
+ {
+ ui->lnAddress->selectAll();
+ return true;
+ }
+ return QDialog::eventFilter(object, event);
+}
diff --git a/src/qt/verifymessagedialog.h b/src/qt/verifymessagedialog.h
new file mode 100644
index 0000000000..9a3fb43415
--- /dev/null
+++ b/src/qt/verifymessagedialog.h
@@ -0,0 +1,37 @@
+#ifndef VERIFYMESSAGEDIALOG_H
+#define VERIFYMESSAGEDIALOG_H
+
+#include <QDialog>
+
+namespace Ui {
+ class VerifyMessageDialog;
+}
+class AddressTableModel;
+
+QT_BEGIN_NAMESPACE
+QT_END_NAMESPACE
+
+class VerifyMessageDialog : public QDialog
+{
+ Q_OBJECT
+
+public:
+ explicit VerifyMessageDialog(AddressTableModel *addressModel, QWidget *parent = 0);
+ ~VerifyMessageDialog();
+
+protected:
+ bool eventFilter(QObject *object, QEvent *event);
+
+private:
+ bool checkAddress();
+
+ Ui::VerifyMessageDialog *ui;
+ AddressTableModel *model;
+
+private slots:
+ void on_verifyMessage_clicked();
+ void on_copyToClipboard_clicked();
+ void on_clearButton_clicked();
+};
+
+#endif // VERIFYMESSAGEDIALOG_H
diff --git a/src/qt/walletmodel.cpp b/src/qt/walletmodel.cpp
index a915274da3..b89c3dba33 100644
--- a/src/qt/walletmodel.cpp
+++ b/src/qt/walletmodel.cpp
@@ -18,6 +18,13 @@ WalletModel::WalletModel(CWallet *wallet, OptionsModel *optionsModel, QObject *p
{
addressTableModel = new AddressTableModel(wallet, this);
transactionTableModel = new TransactionTableModel(wallet, this);
+
+ subscribeToCoreSignals();
+}
+
+WalletModel::~WalletModel()
+{
+ unsubscribeFromCoreSignals();
}
qint64 WalletModel::getBalance() const
@@ -40,30 +47,38 @@ int WalletModel::getNumTransactions() const
return numTransactions;
}
-void WalletModel::update()
+void WalletModel::updateStatus()
+{
+ EncryptionStatus newEncryptionStatus = getEncryptionStatus();
+
+ if(cachedEncryptionStatus != newEncryptionStatus)
+ emit encryptionStatusChanged(newEncryptionStatus);
+}
+
+void WalletModel::updateTransaction(const QString &hash, int status)
{
+ if(transactionTableModel)
+ transactionTableModel->updateTransaction(hash, status);
+
+ // Balance and number of transactions might have changed
qint64 newBalance = getBalance();
qint64 newUnconfirmedBalance = getUnconfirmedBalance();
int newNumTransactions = getNumTransactions();
- EncryptionStatus newEncryptionStatus = getEncryptionStatus();
if(cachedBalance != newBalance || cachedUnconfirmedBalance != newUnconfirmedBalance)
emit balanceChanged(newBalance, newUnconfirmedBalance);
-
if(cachedNumTransactions != newNumTransactions)
emit numTransactionsChanged(newNumTransactions);
- if(cachedEncryptionStatus != newEncryptionStatus)
- emit encryptionStatusChanged(newEncryptionStatus);
-
cachedBalance = newBalance;
cachedUnconfirmedBalance = newUnconfirmedBalance;
cachedNumTransactions = newNumTransactions;
}
-void WalletModel::updateAddressList()
+void WalletModel::updateAddressBook(const QString &address, const QString &label, bool isMine, int status)
{
- addressTableModel->update();
+ if(addressTableModel)
+ addressTableModel->updateEntry(address, label, isMine, status);
}
bool WalletModel::validateAddress(const QString &address)
@@ -139,7 +154,7 @@ WalletModel::SendCoinsReturn WalletModel::sendCoins(const QList<SendCoinsRecipie
}
return TransactionCreationFailed;
}
- if(!ThreadSafeAskFee(nFeeRequired, tr("Sending...").toStdString()))
+ if(!uiInterface.ThreadSafeAskFee(nFeeRequired, tr("Sending...").toStdString()))
{
return Aborted;
}
@@ -150,14 +165,21 @@ WalletModel::SendCoinsReturn WalletModel::sendCoins(const QList<SendCoinsRecipie
hex = QString::fromStdString(wtx.GetHash().GetHex());
}
- // Add addresses that we've sent to to the address book
+ // Add addresses / update labels that we've sent to to the address book
foreach(const SendCoinsRecipient &rcp, recipients)
{
std::string strAddress = rcp.address.toStdString();
+ std::string strLabel = rcp.label.toStdString();
{
LOCK(wallet->cs_wallet);
- if (!wallet->mapAddressBook.count(strAddress))
- wallet->SetAddressBookName(strAddress, rcp.label.toStdString());
+
+ std::map<CBitcoinAddress, std::string>::iterator mi = wallet->mapAddressBook.find(strAddress);
+
+ // Check if we have a new address or an updated label
+ if (mi == wallet->mapAddressBook.end() || mi->second != strLabel)
+ {
+ wallet->SetAddressBookName(strAddress, strLabel);
+ }
}
}
@@ -239,6 +261,47 @@ bool WalletModel::backupWallet(const QString &filename)
return BackupWallet(*wallet, filename.toLocal8Bit().data());
}
+// Handlers for core signals
+static void NotifyKeyStoreStatusChanged(WalletModel *walletmodel, CCryptoKeyStore *wallet)
+{
+ OutputDebugStringF("NotifyKeyStoreStatusChanged\n");
+ QMetaObject::invokeMethod(walletmodel, "updateStatus", Qt::QueuedConnection);
+}
+
+static void NotifyAddressBookChanged(WalletModel *walletmodel, CWallet *wallet, const std::string &address, const std::string &label, bool isMine, ChangeType status)
+{
+ OutputDebugStringF("NotifyAddressBookChanged %s %s isMine=%i status=%i\n", address.c_str(), label.c_str(), isMine, status);
+ QMetaObject::invokeMethod(walletmodel, "updateAddressBook", Qt::QueuedConnection,
+ Q_ARG(QString, QString::fromStdString(address)),
+ Q_ARG(QString, QString::fromStdString(label)),
+ Q_ARG(bool, isMine),
+ Q_ARG(int, status));
+}
+
+static void NotifyTransactionChanged(WalletModel *walletmodel, CWallet *wallet, const uint256 &hash, ChangeType status)
+{
+ OutputDebugStringF("NotifyTransactionChanged %s status=%i\n", hash.GetHex().c_str(), status);
+ QMetaObject::invokeMethod(walletmodel, "updateTransaction", Qt::QueuedConnection,
+ Q_ARG(QString, QString::fromStdString(hash.GetHex())),
+ Q_ARG(int, status));
+}
+
+void WalletModel::subscribeToCoreSignals()
+{
+ // Connect signals to wallet
+ wallet->NotifyStatusChanged.connect(boost::bind(&NotifyKeyStoreStatusChanged, this, _1));
+ wallet->NotifyAddressBookChanged.connect(boost::bind(NotifyAddressBookChanged, this, _1, _2, _3, _4, _5));
+ wallet->NotifyTransactionChanged.connect(boost::bind(NotifyTransactionChanged, this, _1, _2, _3));
+}
+
+void WalletModel::unsubscribeFromCoreSignals()
+{
+ // Disconnect signals from wallet
+ wallet->NotifyStatusChanged.disconnect(boost::bind(&NotifyKeyStoreStatusChanged, this, _1));
+ wallet->NotifyAddressBookChanged.disconnect(boost::bind(NotifyAddressBookChanged, this, _1, _2, _3, _4, _5));
+ wallet->NotifyTransactionChanged.disconnect(boost::bind(NotifyTransactionChanged, this, _1, _2, _3));
+}
+
// WalletModel::UnlockContext implementation
WalletModel::UnlockContext WalletModel::requestUnlock()
{
diff --git a/src/qt/walletmodel.h b/src/qt/walletmodel.h
index 6c47f61bef..8b615ffe8e 100644
--- a/src/qt/walletmodel.h
+++ b/src/qt/walletmodel.h
@@ -24,6 +24,7 @@ class WalletModel : public QObject
Q_OBJECT
public:
explicit WalletModel(CWallet *wallet, OptionsModel *optionsModel, QObject *parent = 0);
+ ~WalletModel();
enum StatusCode // Returned by sendCoins
{
@@ -118,6 +119,8 @@ private:
qint64 cachedNumTransactions;
EncryptionStatus cachedEncryptionStatus;
+ void subscribeToCoreSignals();
+ void unsubscribeFromCoreSignals();
signals:
// Signal that balance in wallet changed
void balanceChanged(qint64 balance, qint64 unconfirmedBalance);
@@ -137,8 +140,12 @@ signals:
void error(const QString &title, const QString &message, bool modal);
public slots:
- void update();
- void updateAddressList();
+ /* Wallet status might have changed */
+ void updateStatus();
+ /* New transaction, or transaction changed status */
+ void updateTransaction(const QString &hash, int status);
+ /* New, updated or removed address book entry */
+ void updateAddressBook(const QString &address, const QString &label, bool isMine, int status);
};
diff --git a/src/rpcdump.cpp b/src/rpcdump.cpp
index 1bc87e9217..5fa24f638d 100644
--- a/src/rpcdump.cpp
+++ b/src/rpcdump.cpp
@@ -1,6 +1,6 @@
// Copyright (c) 2009-2012 Bitcoin Developers
// Distributed under the MIT/X11 software license, see the accompanying
-// file license.txt or http://www.opensource.org/licenses/mit-license.php.
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "init.h" // for pwalletMain
#include "bitcoinrpc.h"
@@ -73,8 +73,6 @@ Value importprivkey(const Array& params, bool fHelp)
pwalletMain->ReacceptWalletTransactions();
}
- MainFrameRepaint();
-
return Value::null;
}
@@ -88,7 +86,7 @@ Value dumpprivkey(const Array& params, bool fHelp)
string strAddress = params[0].get_str();
CBitcoinAddress address;
if (!address.SetString(strAddress))
- throw JSONRPCError(-5, "Invalid bitcoin address");
+ throw JSONRPCError(-5, "Invalid Bitcoin address");
CSecret vchSecret;
bool fCompressed;
if (!pwalletMain->GetSecret(address, vchSecret, fCompressed))
diff --git a/src/script.cpp b/src/script.cpp
index 65e9b7c9a2..f7c2d316f2 100644
--- a/src/script.cpp
+++ b/src/script.cpp
@@ -1,7 +1,7 @@
// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2012 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
-// file license.txt or http://www.opensource.org/licenses/mit-license.php.
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include <boost/foreach.hpp>
using namespace std;
@@ -940,7 +940,7 @@ bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, co
// ([sig ...] num_of_signatures [pubkey ...] num_of_pubkeys -- bool)
int i = 1;
- if (stack.size() < i)
+ if ((int)stack.size() < i)
return false;
int nKeysCount = CastToBigNum(stacktop(-i)).getint();
@@ -951,7 +951,7 @@ bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, co
return false;
int ikey = ++i;
i += nKeysCount;
- if (stack.size() < i)
+ if ((int)stack.size() < i)
return false;
int nSigsCount = CastToBigNum(stacktop(-i)).getint();
@@ -959,7 +959,7 @@ bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, co
return false;
int isig = ++i;
i += nSigsCount;
- if (stack.size() < i)
+ if ((int)stack.size() < i)
return false;
// Subset of script starting at the most recent codeseparator
diff --git a/src/script.h b/src/script.h
index e41e09b6b3..5397a1972f 100644
--- a/src/script.h
+++ b/src/script.h
@@ -1,7 +1,7 @@
// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2012 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
-// file license.txt or http://www.opensource.org/licenses/mit-license.php.
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifndef H_BITCOIN_SCRIPT
#define H_BITCOIN_SCRIPT
diff --git a/src/serialize.h b/src/serialize.h
index fe2aebe7f5..349a40bfe8 100644
--- a/src/serialize.h
+++ b/src/serialize.h
@@ -1,7 +1,7 @@
// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2012 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
-// file license.txt or http://www.opensource.org/licenses/mit-license.php.
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifndef BITCOIN_SERIALIZE_H
#define BITCOIN_SERIALIZE_H
diff --git a/src/sync.cpp b/src/sync.cpp
new file mode 100644
index 0000000000..f2403a43f2
--- /dev/null
+++ b/src/sync.cpp
@@ -0,0 +1,120 @@
+// Copyright (c) 2011-2012 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 "sync.h"
+#include "util.h"
+
+#include <boost/foreach.hpp>
+
+#ifdef DEBUG_LOCKORDER
+//
+// Early deadlock detection.
+// Problem being solved:
+// Thread 1 locks A, then B, then C
+// Thread 2 locks D, then C, then A
+// --> may result in deadlock between the two threads, depending on when they run.
+// Solution implemented here:
+// Keep track of pairs of locks: (A before B), (A before C), etc.
+// Complain if any thread trys to lock in a different order.
+//
+
+struct CLockLocation
+{
+ CLockLocation(const char* pszName, const char* pszFile, int nLine)
+ {
+ mutexName = pszName;
+ sourceFile = pszFile;
+ sourceLine = nLine;
+ }
+
+ std::string ToString() const
+ {
+ return mutexName+" "+sourceFile+":"+itostr(sourceLine);
+ }
+
+private:
+ std::string mutexName;
+ std::string sourceFile;
+ int sourceLine;
+};
+
+typedef std::vector< std::pair<void*, CLockLocation> > LockStack;
+
+static boost::mutex dd_mutex;
+static std::map<std::pair<void*, void*>, LockStack> lockorders;
+static boost::thread_specific_ptr<LockStack> lockstack;
+
+
+static void potential_deadlock_detected(const std::pair<void*, void*>& mismatch, const LockStack& s1, const LockStack& s2)
+{
+ printf("POTENTIAL DEADLOCK DETECTED\n");
+ printf("Previous lock order was:\n");
+ BOOST_FOREACH(const PAIRTYPE(void*, CLockLocation)& i, s2)
+ {
+ if (i.first == mismatch.first) printf(" (1)");
+ if (i.first == mismatch.second) printf(" (2)");
+ printf(" %s\n", i.second.ToString().c_str());
+ }
+ printf("Current lock order is:\n");
+ BOOST_FOREACH(const PAIRTYPE(void*, CLockLocation)& i, s1)
+ {
+ if (i.first == mismatch.first) printf(" (1)");
+ if (i.first == mismatch.second) printf(" (2)");
+ printf(" %s\n", i.second.ToString().c_str());
+ }
+}
+
+static void push_lock(void* c, const CLockLocation& locklocation, bool fTry)
+{
+ if (lockstack.get() == NULL)
+ lockstack.reset(new LockStack);
+
+ if (fDebug) printf("Locking: %s\n", locklocation.ToString().c_str());
+ dd_mutex.lock();
+
+ (*lockstack).push_back(std::make_pair(c, locklocation));
+
+ if (!fTry) {
+ BOOST_FOREACH(const PAIRTYPE(void*, CLockLocation)& i, (*lockstack)) {
+ if (i.first == c) break;
+
+ std::pair<void*, void*> p1 = std::make_pair(i.first, c);
+ if (lockorders.count(p1))
+ continue;
+ lockorders[p1] = (*lockstack);
+
+ std::pair<void*, void*> p2 = std::make_pair(c, i.first);
+ if (lockorders.count(p2))
+ {
+ potential_deadlock_detected(p1, lockorders[p2], lockorders[p1]);
+ break;
+ }
+ }
+ }
+ dd_mutex.unlock();
+}
+
+static void pop_lock()
+{
+ if (fDebug)
+ {
+ const CLockLocation& locklocation = (*lockstack).rbegin()->second;
+ printf("Unlocked: %s\n", locklocation.ToString().c_str());
+ }
+ dd_mutex.lock();
+ (*lockstack).pop_back();
+ dd_mutex.unlock();
+}
+
+void EnterCritical(const char* pszName, const char* pszFile, int nLine, void* cs, bool fTry)
+{
+ push_lock(cs, CLockLocation(pszName, pszFile, nLine), fTry);
+}
+
+void LeaveCritical()
+{
+ pop_lock();
+}
+
+#endif /* DEBUG_LOCKORDER */
diff --git a/src/sync.h b/src/sync.h
new file mode 100644
index 0000000000..dffe4f6ee8
--- /dev/null
+++ b/src/sync.h
@@ -0,0 +1,209 @@
+// Copyright (c) 2009-2010 Satoshi Nakamoto
+// Copyright (c) 2009-2012 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 BITCOIN_SYNC_H
+#define BITCOIN_SYNC_H
+
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/recursive_mutex.hpp>
+#include <boost/thread/locks.hpp>
+#include <boost/thread/condition_variable.hpp>
+
+
+
+
+/** Wrapped boost mutex: supports recursive locking, but no waiting */
+typedef boost::recursive_mutex CCriticalSection;
+
+/** Wrapped boost mutex: supports waiting but not recursive locking */
+typedef boost::mutex CWaitableCriticalSection;
+
+#ifdef DEBUG_LOCKORDER
+void EnterCritical(const char* pszName, const char* pszFile, int nLine, void* cs, bool fTry = false);
+void LeaveCritical();
+#else
+void static inline EnterCritical(const char* pszName, const char* pszFile, int nLine, void* cs, bool fTry = false) {}
+void static inline LeaveCritical() {}
+#endif
+
+/** Wrapper around boost::interprocess::scoped_lock */
+template<typename Mutex>
+class CMutexLock
+{
+private:
+ boost::unique_lock<Mutex> lock;
+public:
+
+ void Enter(const char* pszName, const char* pszFile, int nLine)
+ {
+ if (!lock.owns_lock())
+ {
+ EnterCritical(pszName, pszFile, nLine, (void*)(lock.mutex()));
+#ifdef DEBUG_LOCKCONTENTION
+ if (!lock.try_lock())
+ {
+ printf("LOCKCONTENTION: %s\n", pszName);
+ printf("Locker: %s:%d\n", pszFile, nLine);
+#endif
+ lock.lock();
+#ifdef DEBUG_LOCKCONTENTION
+ }
+#endif
+ }
+ }
+
+ void Leave()
+ {
+ if (lock.owns_lock())
+ {
+ lock.unlock();
+ LeaveCritical();
+ }
+ }
+
+ bool TryEnter(const char* pszName, const char* pszFile, int nLine)
+ {
+ if (!lock.owns_lock())
+ {
+ EnterCritical(pszName, pszFile, nLine, (void*)(lock.mutex()), true);
+ lock.try_lock();
+ if (!lock.owns_lock())
+ LeaveCritical();
+ }
+ return lock.owns_lock();
+ }
+
+ CMutexLock(Mutex& mutexIn, const char* pszName, const char* pszFile, int nLine, bool fTry = false) : lock(mutexIn, boost::defer_lock)
+ {
+ if (fTry)
+ TryEnter(pszName, pszFile, nLine);
+ else
+ Enter(pszName, pszFile, nLine);
+ }
+
+ ~CMutexLock()
+ {
+ if (lock.owns_lock())
+ LeaveCritical();
+ }
+
+ operator bool()
+ {
+ return lock.owns_lock();
+ }
+
+ boost::unique_lock<Mutex> &GetLock()
+ {
+ return lock;
+ }
+};
+
+typedef CMutexLock<CCriticalSection> CCriticalBlock;
+
+#define LOCK(cs) CCriticalBlock criticalblock(cs, #cs, __FILE__, __LINE__)
+#define LOCK2(cs1,cs2) CCriticalBlock criticalblock1(cs1, #cs1, __FILE__, __LINE__),criticalblock2(cs2, #cs2, __FILE__, __LINE__)
+#define TRY_LOCK(cs,name) CCriticalBlock name(cs, #cs, __FILE__, __LINE__, true)
+
+#define ENTER_CRITICAL_SECTION(cs) \
+ { \
+ EnterCritical(#cs, __FILE__, __LINE__, (void*)(&cs)); \
+ (cs).lock(); \
+ }
+
+#define LEAVE_CRITICAL_SECTION(cs) \
+ { \
+ (cs).unlock(); \
+ LeaveCritical(); \
+ }
+
+class CSemaphore
+{
+private:
+ boost::condition_variable condition;
+ boost::mutex mutex;
+ int value;
+
+public:
+ CSemaphore(int init) : value(init) {}
+
+ void wait() {
+ boost::unique_lock<boost::mutex> lock(mutex);
+ while (value < 1) {
+ condition.wait(lock);
+ }
+ value--;
+ }
+
+ bool try_wait() {
+ boost::unique_lock<boost::mutex> lock(mutex);
+ if (value < 1)
+ return false;
+ value--;
+ return true;
+ }
+
+ void post() {
+ {
+ boost::unique_lock<boost::mutex> lock(mutex);
+ value++;
+ }
+ condition.notify_one();
+ }
+};
+
+/** RAII-style semaphore lock */
+class CSemaphoreGrant
+{
+private:
+ CSemaphore *sem;
+ bool fHaveGrant;
+
+public:
+ void Acquire() {
+ if (fHaveGrant)
+ return;
+ sem->wait();
+ fHaveGrant = true;
+ }
+
+ void Release() {
+ if (!fHaveGrant)
+ return;
+ sem->post();
+ fHaveGrant = false;
+ }
+
+ bool TryAcquire() {
+ if (!fHaveGrant && sem->try_wait())
+ fHaveGrant = true;
+ return fHaveGrant;
+ }
+
+ void MoveTo(CSemaphoreGrant &grant) {
+ grant.Release();
+ grant.sem = sem;
+ grant.fHaveGrant = fHaveGrant;
+ sem = NULL;
+ fHaveGrant = false;
+ }
+
+ CSemaphoreGrant() : sem(NULL), fHaveGrant(false) {}
+
+ CSemaphoreGrant(CSemaphore &sema, bool fTry = false) : sem(&sema), fHaveGrant(false) {
+ if (fTry)
+ TryAcquire();
+ else
+ Acquire();
+ }
+
+ ~CSemaphoreGrant() {
+ Release();
+ }
+
+ operator bool() {
+ return fHaveGrant;
+ }
+};
+#endif
+
diff --git a/src/test/DoS_tests.cpp b/src/test/DoS_tests.cpp
index 4ee2e94834..7defd23f80 100644
--- a/src/test/DoS_tests.cpp
+++ b/src/test/DoS_tests.cpp
@@ -34,13 +34,13 @@ BOOST_AUTO_TEST_CASE(DoS_banning)
{
CNode::ClearBanned();
CAddress addr1(ip(0xa0b0c001));
- CNode dummyNode1(INVALID_SOCKET, addr1, true);
+ CNode dummyNode1(INVALID_SOCKET, addr1, "", true);
dummyNode1.Misbehaving(100); // Should get banned
BOOST_CHECK(CNode::IsBanned(addr1));
BOOST_CHECK(!CNode::IsBanned(ip(0xa0b0c001|0x0000ff00))); // Different ip, not banned
CAddress addr2(ip(0xa0b0c002));
- CNode dummyNode2(INVALID_SOCKET, addr2, true);
+ CNode dummyNode2(INVALID_SOCKET, addr2, "", true);
dummyNode2.Misbehaving(50);
BOOST_CHECK(!CNode::IsBanned(addr2)); // 2 not banned yet...
BOOST_CHECK(CNode::IsBanned(addr1)); // ... but 1 still should be
@@ -53,7 +53,7 @@ BOOST_AUTO_TEST_CASE(DoS_banscore)
CNode::ClearBanned();
mapArgs["-banscore"] = "111"; // because 11 is my favorite number
CAddress addr1(ip(0xa0b0c001));
- CNode dummyNode1(INVALID_SOCKET, addr1, true);
+ CNode dummyNode1(INVALID_SOCKET, addr1, "", true);
dummyNode1.Misbehaving(100);
BOOST_CHECK(!CNode::IsBanned(addr1));
dummyNode1.Misbehaving(10);
@@ -70,7 +70,7 @@ BOOST_AUTO_TEST_CASE(DoS_bantime)
SetMockTime(nStartTime); // Overrides future calls to GetTime()
CAddress addr(ip(0xa0b0c001));
- CNode dummyNode(INVALID_SOCKET, addr, true);
+ CNode dummyNode(INVALID_SOCKET, addr, "", true);
dummyNode.Misbehaving(100);
BOOST_CHECK(CNode::IsBanned(addr));
diff --git a/src/test/base58_tests.cpp b/src/test/base58_tests.cpp
index d52ac74982..de4096cd39 100644
--- a/src/test/base58_tests.cpp
+++ b/src/test/base58_tests.cpp
@@ -67,7 +67,7 @@ const char *vstrOut[] = {
BOOST_AUTO_TEST_CASE(base58_EncodeBase58)
{
- for (int i=0; i<sizeof(vstrIn)/sizeof(vstrIn[0]); i++)
+ for (unsigned int i=0; i<sizeof(vstrIn)/sizeof(vstrIn[0]); i++)
{
BOOST_CHECK_EQUAL(EncodeBase58(vstrIn[i].data, vstrIn[i].data + vstrIn[i].size), vstrOut[i]);
}
@@ -76,7 +76,7 @@ BOOST_AUTO_TEST_CASE(base58_EncodeBase58)
BOOST_AUTO_TEST_CASE(base58_DecodeBase58)
{
std::vector<unsigned char> result;
- for (int i=0; i<sizeof(vstrIn)/sizeof(vstrIn[0]); i++)
+ for (unsigned int i=0; i<sizeof(vstrIn)/sizeof(vstrIn[0]); i++)
{
std::vector<unsigned char> expected(vstrIn[i].data, vstrIn[i].data + vstrIn[i].size);
BOOST_CHECK(DecodeBase58(vstrOut[i], result));
diff --git a/src/test/base64_tests.cpp b/src/test/base64_tests.cpp
index fff30ef5eb..c5a053e2eb 100644
--- a/src/test/base64_tests.cpp
+++ b/src/test/base64_tests.cpp
@@ -10,7 +10,7 @@ BOOST_AUTO_TEST_CASE(base64_testvectors)
{
static const std::string vstrIn[] = {"","f","fo","foo","foob","fooba","foobar"};
static const std::string vstrOut[] = {"","Zg==","Zm8=","Zm9v","Zm9vYg==","Zm9vYmE=","Zm9vYmFy"};
- for (int i=0; i<sizeof(vstrIn)/sizeof(vstrIn[0]); i++)
+ for (unsigned int i=0; i<sizeof(vstrIn)/sizeof(vstrIn[0]); i++)
{
std::string strEnc = EncodeBase64(vstrIn[i]);
BOOST_CHECK(strEnc == vstrOut[i]);
diff --git a/src/test/test_bitcoin.cpp b/src/test/test_bitcoin.cpp
index 7ff7545ab4..bf597c9b73 100644
--- a/src/test/test_bitcoin.cpp
+++ b/src/test/test_bitcoin.cpp
@@ -5,11 +5,15 @@
#include "wallet.h"
CWallet* pwalletMain;
+CClientUIInterface uiInterface;
extern bool fPrintToConsole;
+extern void noui_connect();
+
struct TestingSetup {
TestingSetup() {
fPrintToConsole = true; // don't want to write to debug.log file
+ noui_connect();
pwalletMain = new CWallet();
RegisterWallet(pwalletMain);
}
diff --git a/src/test/util_tests.cpp b/src/test/util_tests.cpp
index 0393edb1a7..2bfda61675 100644
--- a/src/test/util_tests.cpp
+++ b/src/test/util_tests.cpp
@@ -105,7 +105,7 @@ BOOST_AUTO_TEST_CASE(util_DateTimeStrFormat)
{
BOOST_CHECK_EQUAL(DateTimeStrFormat("%x %H:%M:%S", 0), "01/01/70 00:00:00");
BOOST_CHECK_EQUAL(DateTimeStrFormat("%x %H:%M:%S", 0x7FFFFFFF), "01/19/38 03:14:07");
- // Formats used within bitcoin
+ // Formats used within Bitcoin
BOOST_CHECK_EQUAL(DateTimeStrFormat("%x %H:%M:%S", 1317425777), "09/30/11 23:36:17");
BOOST_CHECK_EQUAL(DateTimeStrFormat("%x %H:%M", 1317425777), "09/30/11 23:36");
}
diff --git a/src/ui_interface.h b/src/ui_interface.h
index 514768086d..b94446cc20 100644
--- a/src/ui_interface.h
+++ b/src/ui_interface.h
@@ -1,50 +1,104 @@
// Copyright (c) 2010 Satoshi Nakamoto
// Distributed under the MIT/X11 software license, see the accompanying
-// file license.txt or http://www.opensource.org/licenses/mit-license.php.
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifndef BITCOIN_UI_INTERFACE_H
#define BITCOIN_UI_INTERFACE_H
#include <string>
#include "util.h" // for int64
+#include <boost/signals2/signal.hpp>
+#include <boost/signals2/last_value.hpp>
-#define wxYES 0x00000002
-#define wxOK 0x00000004
-#define wxNO 0x00000008
-#define wxYES_NO (wxYES|wxNO)
-#define wxCANCEL 0x00000010
-#define wxAPPLY 0x00000020
-#define wxCLOSE 0x00000040
-#define wxOK_DEFAULT 0x00000000
-#define wxYES_DEFAULT 0x00000000
-#define wxNO_DEFAULT 0x00000080
-#define wxCANCEL_DEFAULT 0x80000000
-#define wxICON_EXCLAMATION 0x00000100
-#define wxICON_HAND 0x00000200
-#define wxICON_WARNING wxICON_EXCLAMATION
-#define wxICON_ERROR wxICON_HAND
-#define wxICON_QUESTION 0x00000400
-#define wxICON_INFORMATION 0x00000800
-#define wxICON_STOP wxICON_HAND
-#define wxICON_ASTERISK wxICON_INFORMATION
-#define wxICON_MASK (0x00000100|0x00000200|0x00000400|0x00000800)
-#define wxFORWARD 0x00001000
-#define wxBACKWARD 0x00002000
-#define wxRESET 0x00004000
-#define wxHELP 0x00008000
-#define wxMORE 0x00010000
-#define wxSETUP 0x00020000
-// Force blocking, modal message box dialog (not just notification)
-#define wxMODAL 0x00040000
-
-/* These UI communication functions are implemented in bitcoin.cpp (for ui) and noui.cpp (no ui) */
-
-extern int ThreadSafeMessageBox(const std::string& message, const std::string& caption, int style=wxOK);
-extern bool ThreadSafeAskFee(int64 nFeeRequired, const std::string& strCaption);
-extern void ThreadSafeHandleURI(const std::string& strURI);
-extern void MainFrameRepaint();
-extern void AddressBookRepaint();
-extern void QueueShutdown();
-extern void InitMessage(const std::string &message);
-extern std::string _(const char* psz);
+class CBasicKeyStore;
+class CWallet;
+class uint256;
+
+/** General change type (added, updated, removed). */
+enum ChangeType
+{
+ CT_NEW,
+ CT_UPDATED,
+ CT_DELETED
+};
+
+/** Signals for UI communication. */
+class CClientUIInterface
+{
+public:
+ /** Flags for CClientUIInterface::ThreadSafeMessageBox */
+ enum MessageBoxFlags
+ {
+ YES = 0x00000002,
+ OK = 0x00000004,
+ NO = 0x00000008,
+ YES_NO = (YES|NO),
+ CANCEL = 0x00000010,
+ APPLY = 0x00000020,
+ CLOSE = 0x00000040,
+ OK_DEFAULT = 0x00000000,
+ YES_DEFAULT = 0x00000000,
+ NO_DEFAULT = 0x00000080,
+ CANCEL_DEFAULT = 0x80000000,
+ ICON_EXCLAMATION = 0x00000100,
+ ICON_HAND = 0x00000200,
+ ICON_WARNING = ICON_EXCLAMATION,
+ ICON_ERROR = ICON_HAND,
+ ICON_QUESTION = 0x00000400,
+ ICON_INFORMATION = 0x00000800,
+ ICON_STOP = ICON_HAND,
+ ICON_ASTERISK = ICON_INFORMATION,
+ ICON_MASK = (0x00000100|0x00000200|0x00000400|0x00000800),
+ FORWARD = 0x00001000,
+ BACKWARD = 0x00002000,
+ RESET = 0x00004000,
+ HELP = 0x00008000,
+ MORE = 0x00010000,
+ SETUP = 0x00020000,
+ // Force blocking, modal message box dialog (not just OS notification)
+ MODAL = 0x00040000
+ };
+
+ /** Show message box. */
+ boost::signals2::signal<void (const std::string& message, const std::string& caption, int style)> ThreadSafeMessageBox;
+
+ /** Ask the user whether he want to pay a fee or not. */
+ boost::signals2::signal<bool (int64 nFeeRequired, const std::string& strCaption), boost::signals2::last_value<bool> > ThreadSafeAskFee;
+
+ /** Handle an URL passed on the command line. */
+ boost::signals2::signal<void (const std::string& strURI)> ThreadSafeHandleURI;
+
+ /** Progress message during initialization. */
+ boost::signals2::signal<void (const std::string &message)> InitMessage;
+
+ /** Initiate client shutdown. */
+ boost::signals2::signal<void ()> QueueShutdown;
+
+ /** Translate a message to the native language of the user. */
+ boost::signals2::signal<std::string (const char* psz)> Translate;
+
+ /** Block chain changed. */
+ boost::signals2::signal<void ()> NotifyBlocksChanged;
+
+ /** Number of network connections changed. */
+ boost::signals2::signal<void (int newNumConnections)> NotifyNumConnectionsChanged;
+
+ /**
+ * New, updated or cancelled alert.
+ * @note called with lock cs_mapAlerts held.
+ */
+ boost::signals2::signal<void (const uint256 &hash, ChangeType status)> NotifyAlertChanged;
+};
+
+extern CClientUIInterface uiInterface;
+
+/**
+ * Translation function: Call Translate signal on UI interface, which returns a boost::optional result.
+ * If no translation slot is registered, nothing is returned, and simply return the input.
+ */
+inline std::string _(const char* psz)
+{
+ boost::optional<std::string> rv = uiInterface.Translate(psz);
+ return rv ? (*rv) : psz;
+}
#endif
diff --git a/src/uint256.h b/src/uint256.h
index 9966a14ed7..fc5ed26592 100644
--- a/src/uint256.h
+++ b/src/uint256.h
@@ -1,7 +1,7 @@
// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2012 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
-// file license.txt or http://www.opensource.org/licenses/mit-license.php.
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifndef BITCOIN_UINT256_H
#define BITCOIN_UINT256_H
diff --git a/src/util.cpp b/src/util.cpp
index d8804c7291..08e3625b3d 100644
--- a/src/util.cpp
+++ b/src/util.cpp
@@ -1,9 +1,10 @@
// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2012 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
-// file license.txt or http://www.opensource.org/licenses/mit-license.php.
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "util.h"
+#include "sync.h"
#include "strlcpy.h"
#include "version.h"
#include "ui_interface.h"
@@ -23,11 +24,11 @@ namespace boost {
#include <boost/program_options/parsers.hpp>
#include <boost/filesystem.hpp>
#include <boost/filesystem/fstream.hpp>
-#include <boost/interprocess/sync/interprocess_mutex.hpp>
-#include <boost/interprocess/sync/interprocess_recursive_mutex.hpp>
#include <boost/foreach.hpp>
+#include <boost/thread.hpp>
#include <openssl/crypto.h>
#include <openssl/rand.h>
+#include <stdarg.h>
#ifdef WIN32
#ifdef _MSC_VER
@@ -43,17 +44,16 @@ namespace boost {
#ifdef _WIN32_IE
#undef _WIN32_IE
#endif
-#define _WIN32_IE 0x0400
+#define _WIN32_IE 0x0501
#define WIN32_LEAN_AND_MEAN 1
#ifndef NOMINMAX
#define NOMINMAX
#endif
+#include <io.h> /* for _commit */
#include "shlobj.h"
-#include "shlwapi.h"
#endif
using namespace std;
-using namespace boost;
map<string, string> mapArgs;
map<string, vector<string> > mapMultiArgs;
@@ -70,15 +70,17 @@ bool fTestNet = false;
bool fNoListen = false;
bool fLogTimestamps = false;
CMedianFilter<int64> vTimeOffsets(200,0);
+bool fReopenDebugLog = false;
// Init openssl library multithreading support
-static boost::interprocess::interprocess_mutex** ppmutexOpenSSL;
+static CCriticalSection** ppmutexOpenSSL;
void locking_callback(int mode, int i, const char* file, int line)
{
- if (mode & CRYPTO_LOCK)
- ppmutexOpenSSL[i]->lock();
- else
- ppmutexOpenSSL[i]->unlock();
+ if (mode & CRYPTO_LOCK) {
+ ENTER_CRITICAL_SECTION(*ppmutexOpenSSL[i]);
+ } else {
+ LEAVE_CRITICAL_SECTION(*ppmutexOpenSSL[i]);
+ }
}
// Init
@@ -88,9 +90,9 @@ public:
CInit()
{
// Init openssl library multithreading support
- ppmutexOpenSSL = (boost::interprocess::interprocess_mutex**)OPENSSL_malloc(CRYPTO_num_locks() * sizeof(boost::interprocess::interprocess_mutex*));
+ ppmutexOpenSSL = (CCriticalSection**)OPENSSL_malloc(CRYPTO_num_locks() * sizeof(CCriticalSection*));
for (int i = 0; i < CRYPTO_num_locks(); i++)
- ppmutexOpenSSL[i] = new boost::interprocess::interprocess_mutex();
+ ppmutexOpenSSL[i] = new CCriticalSection();
CRYPTO_set_locking_callback(locking_callback);
#ifdef WIN32
@@ -149,7 +151,7 @@ void RandAddSeedPerfmon()
{
RAND_add(pdata, nSize, nSize/100.0);
memset(pdata, 0, nSize);
- printf("%s RandAddSeed() %d bytes\n", DateTimeStrFormat("%x %H:%M", GetTime()).c_str(), nSize);
+ printf("RandAddSeed() %d bytes\n", nSize);
}
#endif
}
@@ -188,8 +190,6 @@ uint256 GetRandHash()
-
-
inline int OutputDebugStringF(const char* pszFormat, ...)
{
int ret = 0;
@@ -215,6 +215,16 @@ inline int OutputDebugStringF(const char* pszFormat, ...)
if (fileout)
{
static bool fStartedNewLine = true;
+ static boost::mutex mutexDebugLog;
+ boost::mutex::scoped_lock scoped_lock(mutexDebugLog);
+
+ // reopen the log file, if requested
+ if (fReopenDebugLog) {
+ fReopenDebugLog = false;
+ boost::filesystem::path pathDebug = GetDataDir() / "debug.log";
+ if (freopen(pathDebug.string().c_str(),"a",fileout) != NULL)
+ setbuf(fileout, NULL); // unbuffered
+ }
// Debug print useful for profiling
if (fLogTimestamps && fStartedNewLine)
@@ -236,68 +246,30 @@ inline int OutputDebugStringF(const char* pszFormat, ...)
{
static CCriticalSection cs_OutputDebugStringF;
- // accumulate a line at a time
+ // accumulate and output a line at a time
{
LOCK(cs_OutputDebugStringF);
- static char pszBuffer[50000];
- static char* pend;
- if (pend == NULL)
- pend = pszBuffer;
+ static std::string buffer;
+
va_list arg_ptr;
va_start(arg_ptr, pszFormat);
- int limit = END(pszBuffer) - pend - 2;
- int ret = _vsnprintf(pend, limit, pszFormat, arg_ptr);
+ buffer += vstrprintf(pszFormat, arg_ptr);
va_end(arg_ptr);
- if (ret < 0 || ret >= limit)
- {
- pend = END(pszBuffer) - 2;
- *pend++ = '\n';
- }
- else
- pend += ret;
- *pend = '\0';
- char* p1 = pszBuffer;
- char* p2;
- while ((p2 = strchr(p1, '\n')))
+
+ int line_start = 0, line_end;
+ while((line_end = buffer.find('\n', line_start)) != -1)
{
- p2++;
- char c = *p2;
- *p2 = '\0';
- OutputDebugStringA(p1);
- *p2 = c;
- p1 = p2;
+ OutputDebugStringA(buffer.substr(line_start, line_end - line_start).c_str());
+ line_start = line_end + 1;
}
- if (p1 != pszBuffer)
- memmove(pszBuffer, p1, pend - p1 + 1);
- pend -= (p1 - pszBuffer);
+ buffer.erase(0, line_start);
}
}
#endif
return ret;
}
-
-// Safer snprintf
-// - prints up to limit-1 characters
-// - output string is always null terminated even if limit reached
-// - return value is the number of characters actually printed
-int my_snprintf(char* buffer, size_t limit, const char* format, ...)
-{
- if (limit == 0)
- return 0;
- va_list arg_ptr;
- va_start(arg_ptr, format);
- int ret = _vsnprintf(buffer, limit, format, arg_ptr);
- va_end(arg_ptr);
- if (ret < 0 || ret >= (int)limit)
- {
- ret = limit - 1;
- buffer[limit-1] = 0;
- }
- return ret;
-}
-
-string real_strprintf(const std::string &format, int dummy, ...)
+string vstrprintf(const std::string &format, va_list ap)
{
char buffer[50000];
char* p = buffer;
@@ -306,7 +278,7 @@ string real_strprintf(const std::string &format, int dummy, ...)
loop
{
va_list arg_ptr;
- va_start(arg_ptr, dummy);
+ va_copy(arg_ptr, ap);
ret = _vsnprintf(p, limit, format.c_str(), arg_ptr);
va_end(arg_ptr);
if (ret >= 0 && ret < limit)
@@ -324,19 +296,22 @@ string real_strprintf(const std::string &format, int dummy, ...)
return str;
}
+string real_strprintf(const std::string &format, int dummy, ...)
+{
+ va_list arg_ptr;
+ va_start(arg_ptr, dummy);
+ string str = vstrprintf(format, arg_ptr);
+ va_end(arg_ptr);
+ return str;
+}
+
bool error(const char *format, ...)
{
- char buffer[50000];
- int limit = sizeof(buffer);
va_list arg_ptr;
va_start(arg_ptr, format);
- int ret = _vsnprintf(buffer, limit, format, arg_ptr);
+ std::string str = vstrprintf(format, arg_ptr);
va_end(arg_ptr);
- if (ret < 0 || ret >= limit)
- {
- buffer[limit-1] = 0;
- }
- printf("ERROR: %s\n", buffer);
+ printf("ERROR: %s\n", str.c_str());
return false;
}
@@ -500,7 +475,7 @@ static void InterpretNegativeSetting(string name, map<string, string>& mapSettin
}
}
-void ParseParameters(int argc, const char*const argv[])
+void ParseParameters(int argc, const char* const argv[])
{
mapArgs.clear();
mapMultiArgs.clear();
@@ -764,81 +739,55 @@ bool WildcardMatch(const string& str, const string& mask)
-void FormatException(char* pszMessage, std::exception* pex, const char* pszThread)
+static std::string FormatException(std::exception* pex, const char* pszThread)
{
#ifdef WIN32
- char pszModule[MAX_PATH];
- pszModule[0] = '\0';
+ char pszModule[MAX_PATH] = "";
GetModuleFileNameA(NULL, pszModule, sizeof(pszModule));
#else
const char* pszModule = "bitcoin";
#endif
if (pex)
- snprintf(pszMessage, 1000,
+ return strprintf(
"EXCEPTION: %s \n%s \n%s in %s \n", typeid(*pex).name(), pex->what(), pszModule, pszThread);
else
- snprintf(pszMessage, 1000,
+ return strprintf(
"UNKNOWN EXCEPTION \n%s in %s \n", pszModule, pszThread);
}
void LogException(std::exception* pex, const char* pszThread)
{
- char pszMessage[10000];
- FormatException(pszMessage, pex, pszThread);
- printf("\n%s", pszMessage);
+ std::string message = FormatException(pex, pszThread);
+ printf("\n%s", message.c_str());
}
void PrintException(std::exception* pex, const char* pszThread)
{
- char pszMessage[10000];
- FormatException(pszMessage, pex, pszThread);
- printf("\n\n************************\n%s\n", pszMessage);
- fprintf(stderr, "\n\n************************\n%s\n", pszMessage);
- strMiscWarning = pszMessage;
+ std::string message = FormatException(pex, pszThread);
+ printf("\n\n************************\n%s\n", message.c_str());
+ fprintf(stderr, "\n\n************************\n%s\n", message.c_str());
+ strMiscWarning = message;
throw;
}
void PrintExceptionContinue(std::exception* pex, const char* pszThread)
{
- char pszMessage[10000];
- FormatException(pszMessage, pex, pszThread);
- printf("\n\n************************\n%s\n", pszMessage);
- fprintf(stderr, "\n\n************************\n%s\n", pszMessage);
- strMiscWarning = pszMessage;
-}
-
-#ifdef WIN32
-boost::filesystem::path MyGetSpecialFolderPath(int nFolder, bool fCreate)
-{
- namespace fs = boost::filesystem;
-
- char pszPath[MAX_PATH] = "";
- if(SHGetSpecialFolderPathA(NULL, pszPath, nFolder, fCreate))
- {
- return fs::path(pszPath);
- }
- else if (nFolder == CSIDL_STARTUP)
- {
- return fs::path(getenv("USERPROFILE")) / "Start Menu" / "Programs" / "Startup";
- }
- else if (nFolder == CSIDL_APPDATA)
- {
- return fs::path(getenv("APPDATA"));
- }
- return fs::path("");
+ std::string message = FormatException(pex, pszThread);
+ printf("\n\n************************\n%s\n", message.c_str());
+ fprintf(stderr, "\n\n************************\n%s\n", message.c_str());
+ strMiscWarning = message;
}
-#endif
boost::filesystem::path GetDefaultDataDir()
{
namespace fs = boost::filesystem;
-
- // Windows: C:\Documents and Settings\username\Application Data\Bitcoin
+ // Windows < Vista: C:\Documents and Settings\Username\Application Data\Bitcoin
+ // Windows >= Vista: C:\Users\Username\AppData\Roaming\Bitcoin
// Mac: ~/Library/Application Support/Bitcoin
// Unix: ~/.bitcoin
#ifdef WIN32
// Windows
- return MyGetSpecialFolderPath(CSIDL_APPDATA, true) / "Bitcoin";
+ return GetSpecialFolderPath(CSIDL_APPDATA) / "Bitcoin";
#else
fs::path pathRet;
char* pszHome = getenv("HOME");
@@ -849,7 +798,7 @@ boost::filesystem::path GetDefaultDataDir()
#ifdef MAC_OSX
// Mac
pathRet /= "Library/Application Support";
- filesystem::create_directory(pathRet);
+ fs::create_directory(pathRet);
return pathRet / "Bitcoin";
#else
// Unix
@@ -895,9 +844,7 @@ const boost::filesystem::path &GetDataDir(bool fNetSpecific)
boost::filesystem::path GetConfigFile()
{
- namespace fs = boost::filesystem;
-
- fs::path pathConfigFile(GetArg("-conf", "bitcoin.conf"));
+ boost::filesystem::path pathConfigFile(GetArg("-conf", "bitcoin.conf"));
if (!pathConfigFile.is_complete()) pathConfigFile = GetDataDir(false) / pathConfigFile;
return pathConfigFile;
}
@@ -905,24 +852,21 @@ boost::filesystem::path GetConfigFile()
void ReadConfigFile(map<string, string>& mapSettingsRet,
map<string, vector<string> >& mapMultiSettingsRet)
{
- namespace fs = boost::filesystem;
- namespace pod = boost::program_options::detail;
-
- fs::ifstream streamConfig(GetConfigFile());
+ boost::filesystem::ifstream streamConfig(GetConfigFile());
if (!streamConfig.good())
return; // No bitcoin.conf file is OK
set<string> setOptions;
setOptions.insert("*");
- for (pod::config_file_iterator it(streamConfig, setOptions), end; it != end; ++it)
+ for (boost::program_options::detail::config_file_iterator it(streamConfig, setOptions), end; it != end; ++it)
{
// Don't overwrite existing settings so command line settings override bitcoin.conf
string strKey = string("-") + it->string_key;
if (mapSettingsRet.count(strKey) == 0)
{
mapSettingsRet[strKey] = it->value[0];
- // interpret nofoo=1 as foo=0 (and nofoo=0 as foo=1) as long as foo not set)
+ // interpret nofoo=1 as foo=0 (and nofoo=0 as foo=1) as long as foo not set)
InterpretNegativeSetting(strKey, mapSettingsRet);
}
mapMultiSettingsRet[strKey].push_back(it->value[0]);
@@ -931,9 +875,7 @@ void ReadConfigFile(map<string, string>& mapSettingsRet,
boost::filesystem::path GetPidFile()
{
- namespace fs = boost::filesystem;
-
- fs::path pathPidFile(GetArg("-pid", "bitcoind.pid"));
+ boost::filesystem::path pathPidFile(GetArg("-pid", "bitcoind.pid"));
if (!pathPidFile.is_complete()) pathPidFile = GetDataDir() / pathPidFile;
return pathPidFile;
}
@@ -948,6 +890,27 @@ void CreatePidFile(const boost::filesystem::path &path, pid_t pid)
}
}
+bool RenameOver(boost::filesystem::path src, boost::filesystem::path dest)
+{
+#ifdef WIN32
+ return MoveFileExA(src.string().c_str(), dest.string().c_str(),
+ MOVEFILE_REPLACE_EXISTING);
+#else
+ int rc = std::rename(src.string().c_str(), dest.string().c_str());
+ return (rc == 0);
+#endif /* WIN32 */
+}
+
+void FileCommit(FILE *fileout)
+{
+ fflush(fileout); // harmless if redundantly called
+#ifdef WIN32
+ _commit(_fileno(fileout));
+#else
+ fsync(fileno(fileout));
+#endif
+}
+
int GetFilesize(FILE* file)
{
int nSavePos = ftell(file);
@@ -1055,7 +1018,7 @@ void AddTimeData(const CNetAddr& ip, int64 nTime)
string strMessage = _("Warning: Please check that your computer's date and time are correct. If your clock is wrong Bitcoin will not work properly.");
strMiscWarning = strMessage;
printf("*** %s\n", strMessage.c_str());
- ThreadSafeMessageBox(strMessage+" ", string("Bitcoin"), wxOK | wxICON_EXCLAMATION);
+ uiInterface.ThreadSafeMessageBox(strMessage+" ", string("Bitcoin"), CClientUIInterface::OK | CClientUIInterface::ICON_EXCLAMATION);
}
}
}
@@ -1101,258 +1064,18 @@ std::string FormatSubVersion(const std::string& name, int nClientVersion, const
}
#ifdef WIN32
-boost::filesystem::path static StartupShortcutPath()
-{
- return MyGetSpecialFolderPath(CSIDL_STARTUP, true) / "Bitcoin.lnk";
-}
-
-bool GetStartOnSystemStartup()
-{
- return filesystem::exists(StartupShortcutPath());
-}
-
-bool SetStartOnSystemStartup(bool fAutoStart)
-{
- // If the shortcut exists already, remove it for updating
- boost::filesystem::remove(StartupShortcutPath());
-
- if (fAutoStart)
- {
- CoInitialize(NULL);
-
- // Get a pointer to the IShellLink interface.
- IShellLink* psl = NULL;
- HRESULT hres = CoCreateInstance(CLSID_ShellLink, NULL,
- CLSCTX_INPROC_SERVER, IID_IShellLink,
- reinterpret_cast<void**>(&psl));
-
- if (SUCCEEDED(hres))
- {
- // Get the current executable path
- TCHAR pszExePath[MAX_PATH];
- GetModuleFileName(NULL, pszExePath, sizeof(pszExePath));
-
- TCHAR pszArgs[5] = TEXT("-min");
-
- // Set the path to the shortcut target
- psl->SetPath(pszExePath);
- PathRemoveFileSpec(pszExePath);
- psl->SetWorkingDirectory(pszExePath);
- psl->SetShowCmd(SW_SHOWMINNOACTIVE);
- psl->SetArguments(pszArgs);
-
- // Query IShellLink for the IPersistFile interface for
- // saving the shortcut in persistent storage.
- IPersistFile* ppf = NULL;
- hres = psl->QueryInterface(IID_IPersistFile,
- reinterpret_cast<void**>(&ppf));
- if (SUCCEEDED(hres))
- {
- WCHAR pwsz[MAX_PATH];
- // Ensure that the string is ANSI.
- MultiByteToWideChar(CP_ACP, 0, StartupShortcutPath().string().c_str(), -1, pwsz, MAX_PATH);
- // Save the link by calling IPersistFile::Save.
- hres = ppf->Save(pwsz, TRUE);
- ppf->Release();
- psl->Release();
- CoUninitialize();
- return true;
- }
- psl->Release();
- }
- CoUninitialize();
- return false;
- }
- return true;
-}
-
-#elif defined(LINUX)
-
-// Follow the Desktop Application Autostart Spec:
-// http://standards.freedesktop.org/autostart-spec/autostart-spec-latest.html
-
-boost::filesystem::path static GetAutostartDir()
+boost::filesystem::path GetSpecialFolderPath(int nFolder, bool fCreate)
{
namespace fs = boost::filesystem;
- char* pszConfigHome = getenv("XDG_CONFIG_HOME");
- if (pszConfigHome) return fs::path(pszConfigHome) / "autostart";
- char* pszHome = getenv("HOME");
- if (pszHome) return fs::path(pszHome) / ".config" / "autostart";
- return fs::path();
-}
-
-boost::filesystem::path static GetAutostartFilePath()
-{
- return GetAutostartDir() / "bitcoin.desktop";
-}
+ char pszPath[MAX_PATH] = "";
-bool GetStartOnSystemStartup()
-{
- boost::filesystem::ifstream optionFile(GetAutostartFilePath());
- if (!optionFile.good())
- return false;
- // Scan through file for "Hidden=true":
- string line;
- while (!optionFile.eof())
+ if(SHGetSpecialFolderPathA(NULL, pszPath, nFolder, fCreate))
{
- getline(optionFile, line);
- if (line.find("Hidden") != string::npos &&
- line.find("true") != string::npos)
- return false;
+ return fs::path(pszPath);
}
- optionFile.close();
-
- return true;
-}
-bool SetStartOnSystemStartup(bool fAutoStart)
-{
- if (!fAutoStart)
- boost::filesystem::remove(GetAutostartFilePath());
- else
- {
- char pszExePath[MAX_PATH+1];
- memset(pszExePath, 0, sizeof(pszExePath));
- if (readlink("/proc/self/exe", pszExePath, sizeof(pszExePath)-1) == -1)
- return false;
-
- boost::filesystem::create_directories(GetAutostartDir());
-
- boost::filesystem::ofstream optionFile(GetAutostartFilePath(), ios_base::out|ios_base::trunc);
- if (!optionFile.good())
- return false;
- // Write a bitcoin.desktop file to the autostart directory:
- optionFile << "[Desktop Entry]\n";
- optionFile << "Type=Application\n";
- optionFile << "Name=Bitcoin\n";
- optionFile << "Exec=" << pszExePath << " -min\n";
- optionFile << "Terminal=false\n";
- optionFile << "Hidden=false\n";
- optionFile.close();
- }
- return true;
+ printf("SHGetSpecialFolderPathA() failed, could not obtain requested path.\n");
+ return fs::path("");
}
-#else
-
-// TODO: OSX startup stuff; see:
-// http://developer.apple.com/mac/library/documentation/MacOSX/Conceptual/BPSystemStartup/Articles/CustomLogin.html
-
-bool GetStartOnSystemStartup() { return false; }
-bool SetStartOnSystemStartup(bool fAutoStart) { return false; }
-
#endif
-
-
-
-#ifdef DEBUG_LOCKORDER
-//
-// Early deadlock detection.
-// Problem being solved:
-// Thread 1 locks A, then B, then C
-// Thread 2 locks D, then C, then A
-// --> may result in deadlock between the two threads, depending on when they run.
-// Solution implemented here:
-// Keep track of pairs of locks: (A before B), (A before C), etc.
-// Complain if any thread trys to lock in a different order.
-//
-
-struct CLockLocation
-{
- CLockLocation(const char* pszName, const char* pszFile, int nLine)
- {
- mutexName = pszName;
- sourceFile = pszFile;
- sourceLine = nLine;
- }
-
- std::string ToString() const
- {
- return mutexName+" "+sourceFile+":"+itostr(sourceLine);
- }
-
-private:
- std::string mutexName;
- std::string sourceFile;
- int sourceLine;
-};
-
-typedef std::vector< std::pair<void*, CLockLocation> > LockStack;
-
-static boost::interprocess::interprocess_mutex dd_mutex;
-static std::map<std::pair<void*, void*>, LockStack> lockorders;
-static boost::thread_specific_ptr<LockStack> lockstack;
-
-
-static void potential_deadlock_detected(const std::pair<void*, void*>& mismatch, const LockStack& s1, const LockStack& s2)
-{
- printf("POTENTIAL DEADLOCK DETECTED\n");
- printf("Previous lock order was:\n");
- BOOST_FOREACH(const PAIRTYPE(void*, CLockLocation)& i, s2)
- {
- if (i.first == mismatch.first) printf(" (1)");
- if (i.first == mismatch.second) printf(" (2)");
- printf(" %s\n", i.second.ToString().c_str());
- }
- printf("Current lock order is:\n");
- BOOST_FOREACH(const PAIRTYPE(void*, CLockLocation)& i, s1)
- {
- if (i.first == mismatch.first) printf(" (1)");
- if (i.first == mismatch.second) printf(" (2)");
- printf(" %s\n", i.second.ToString().c_str());
- }
-}
-
-static void push_lock(void* c, const CLockLocation& locklocation, bool fTry)
-{
- bool fOrderOK = true;
- if (lockstack.get() == NULL)
- lockstack.reset(new LockStack);
-
- if (fDebug) printf("Locking: %s\n", locklocation.ToString().c_str());
- dd_mutex.lock();
-
- (*lockstack).push_back(std::make_pair(c, locklocation));
-
- if (!fTry) BOOST_FOREACH(const PAIRTYPE(void*, CLockLocation)& i, (*lockstack))
- {
- if (i.first == c) break;
-
- std::pair<void*, void*> p1 = std::make_pair(i.first, c);
- if (lockorders.count(p1))
- continue;
- lockorders[p1] = (*lockstack);
-
- std::pair<void*, void*> p2 = std::make_pair(c, i.first);
- if (lockorders.count(p2))
- {
- potential_deadlock_detected(p1, lockorders[p2], lockorders[p1]);
- break;
- }
- }
- dd_mutex.unlock();
-}
-
-static void pop_lock()
-{
- if (fDebug)
- {
- const CLockLocation& locklocation = (*lockstack).rbegin()->second;
- printf("Unlocked: %s\n", locklocation.ToString().c_str());
- }
- dd_mutex.lock();
- (*lockstack).pop_back();
- dd_mutex.unlock();
-}
-
-void EnterCritical(const char* pszName, const char* pszFile, int nLine, void* cs, bool fTry)
-{
- push_lock(cs, CLockLocation(pszName, pszFile, nLine), fTry);
-}
-
-void LeaveCritical()
-{
- pop_lock();
-}
-
-#endif /* DEBUG_LOCKORDER */
diff --git a/src/util.h b/src/util.h
index 01f09747c4..5b58147ce6 100644
--- a/src/util.h
+++ b/src/util.h
@@ -1,7 +1,7 @@
// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2012 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
-// file license.txt or http://www.opensource.org/licenses/mit-license.php.
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifndef BITCOIN_UTIL_H
#define BITCOIN_UTIL_H
@@ -21,10 +21,6 @@ typedef int pid_t; /* define for windows compatiblity */
#include <boost/thread.hpp>
#include <boost/filesystem.hpp>
#include <boost/filesystem/path.hpp>
-#include <boost/interprocess/sync/interprocess_recursive_mutex.hpp>
-#include <boost/interprocess/sync/scoped_lock.hpp>
-#include <boost/interprocess/sync/interprocess_condition.hpp>
-#include <boost/interprocess/sync/lock_options.hpp>
#include <boost/date_time/gregorian/gregorian_types.hpp>
#include <boost/date_time/posix_time/posix_time_types.hpp>
@@ -47,11 +43,6 @@ static const int64 CENT = 1000000;
#define ARRAYLEN(array) (sizeof(array)/sizeof((array)[0]))
#define printf OutputDebugStringF
-#ifdef snprintf
-#undef snprintf
-#endif
-#define snprintf my_snprintf
-
#ifndef PRI64d
#if defined(_MSC_VER) || defined(__MSVCRT__)
#define PRI64d "I64d"
@@ -125,6 +116,7 @@ extern std::string strMiscWarning;
extern bool fTestNet;
extern bool fNoListen;
extern bool fLogTimestamps;
+extern bool fReopenDebugLog;
void RandAddSeed();
void RandAddSeedPerfmon();
@@ -137,6 +129,7 @@ int my_snprintf(char* buffer, size_t limit, const char* format, ...);
*/
std::string real_strprintf(const std::string &format, int dummy, ...);
#define strprintf(format, ...) real_strprintf(format, 0, __VA_ARGS__)
+std::string vstrprintf(const std::string &format, va_list ap);
bool error(const char *format, ...);
void LogException(std::exception* pex, const char* pszThread);
@@ -156,15 +149,18 @@ std::string EncodeBase64(const std::string& str);
void ParseParameters(int argc, const char*const argv[]);
bool WildcardMatch(const char* psz, const char* mask);
bool WildcardMatch(const std::string& str, const std::string& mask);
+void FileCommit(FILE *fileout);
int GetFilesize(FILE* file);
+bool RenameOver(boost::filesystem::path src, boost::filesystem::path dest);
boost::filesystem::path GetDefaultDataDir();
const boost::filesystem::path &GetDataDir(bool fNetSpecific = true);
boost::filesystem::path GetConfigFile();
boost::filesystem::path GetPidFile();
void CreatePidFile(const boost::filesystem::path &path, pid_t pid);
void ReadConfigFile(std::map<std::string, std::string>& mapSettingsRet, std::map<std::string, std::vector<std::string> >& mapMultiSettingsRet);
-bool GetStartOnSystemStartup();
-bool SetStartOnSystemStartup(bool fAutoStart);
+#ifdef WIN32
+boost::filesystem::path GetSpecialFolderPath(int nFolder, bool fCreate = true);
+#endif
void ShrinkDebugFile();
int GetRandInt(int nMax);
uint64 GetRand(uint64 nMax);
@@ -184,125 +180,6 @@ void AddTimeData(const CNetAddr& ip, int64 nTime);
-
-
-/** Wrapped boost mutex: supports recursive locking, but no waiting */
-typedef boost::interprocess::interprocess_recursive_mutex CCriticalSection;
-
-/** Wrapped boost mutex: supports waiting but not recursive locking */
-typedef boost::interprocess::interprocess_mutex CWaitableCriticalSection;
-
-#ifdef DEBUG_LOCKORDER
-void EnterCritical(const char* pszName, const char* pszFile, int nLine, void* cs, bool fTry = false);
-void LeaveCritical();
-#else
-void static inline EnterCritical(const char* pszName, const char* pszFile, int nLine, void* cs, bool fTry = false) {}
-void static inline LeaveCritical() {}
-#endif
-
-/** Wrapper around boost::interprocess::scoped_lock */
-template<typename Mutex>
-class CMutexLock
-{
-private:
- boost::interprocess::scoped_lock<Mutex> lock;
-public:
-
- void Enter(const char* pszName, const char* pszFile, int nLine)
- {
- if (!lock.owns())
- {
- EnterCritical(pszName, pszFile, nLine, (void*)(lock.mutex()));
-#ifdef DEBUG_LOCKCONTENTION
- if (!lock.try_lock())
- {
- printf("LOCKCONTENTION: %s\n", pszName);
- printf("Locker: %s:%d\n", pszFile, nLine);
- }
-#endif
- lock.lock();
- }
- }
-
- void Leave()
- {
- if (lock.owns())
- {
- lock.unlock();
- LeaveCritical();
- }
- }
-
- bool TryEnter(const char* pszName, const char* pszFile, int nLine)
- {
- if (!lock.owns())
- {
- EnterCritical(pszName, pszFile, nLine, (void*)(lock.mutex()), true);
- lock.try_lock();
- if (!lock.owns())
- LeaveCritical();
- }
- return lock.owns();
- }
-
- CMutexLock(Mutex& mutexIn, const char* pszName, const char* pszFile, int nLine, bool fTry = false) : lock(mutexIn, boost::interprocess::defer_lock)
- {
- if (fTry)
- TryEnter(pszName, pszFile, nLine);
- else
- Enter(pszName, pszFile, nLine);
- }
-
- ~CMutexLock()
- {
- if (lock.owns())
- LeaveCritical();
- }
-
- operator bool()
- {
- return lock.owns();
- }
-
- boost::interprocess::scoped_lock<Mutex> &GetLock()
- {
- return lock;
- }
-};
-
-typedef CMutexLock<CCriticalSection> CCriticalBlock;
-typedef CMutexLock<CWaitableCriticalSection> CWaitableCriticalBlock;
-typedef boost::interprocess::interprocess_condition CConditionVariable;
-
-/** Wait for a given condition inside a WAITABLE_CRITICAL_BLOCK */
-#define WAIT(name,condition) \
- do { while(!(condition)) { (name).wait(waitablecriticalblock.GetLock()); } } while(0)
-
-/** Notify waiting threads that a condition may hold now */
-#define NOTIFY(name) \
- do { (name).notify_one(); } while(0)
-
-#define NOTIFY_ALL(name) \
- do { (name).notify_all(); } while(0)
-
-#define LOCK(cs) CCriticalBlock criticalblock(cs, #cs, __FILE__, __LINE__)
-#define LOCK2(cs1,cs2) CCriticalBlock criticalblock1(cs1, #cs1, __FILE__, __LINE__),criticalblock2(cs2, #cs2, __FILE__, __LINE__)
-#define TRY_LOCK(cs,name) CCriticalBlock name(cs, #cs, __FILE__, __LINE__, true)
-#define WAITABLE_LOCK(cs) CWaitableCriticalBlock waitablecriticalblock(cs, #cs, __FILE__, __LINE__)
-
-#define ENTER_CRITICAL_SECTION(cs) \
- { \
- EnterCritical(#cs, __FILE__, __LINE__, (void*)(&cs)); \
- (cs).lock(); \
- }
-
-#define LEAVE_CRITICAL_SECTION(cs) \
- { \
- (cs).unlock(); \
- LeaveCritical(); \
- }
-
-
inline std::string i64tostr(int64 n)
{
return strprintf("%"PRI64d, n);
diff --git a/src/version.cpp b/src/version.cpp
index 0c1e8bfa80..60b7aae2e5 100644
--- a/src/version.cpp
+++ b/src/version.cpp
@@ -1,6 +1,6 @@
// Copyright (c) 2012 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
-// file license.txt or http://www.opensource.org/licenses/mit-license.php.
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include <string>
#include "version.h"
diff --git a/src/version.h b/src/version.h
index 9b92bd618e..c0d53e8b91 100644
--- a/src/version.h
+++ b/src/version.h
@@ -1,6 +1,6 @@
// Copyright (c) 2012 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
-// file license.txt or http://www.opensource.org/licenses/mit-license.php.
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifndef BITCOIN_VERSION_H
#define BITCOIN_VERSION_H
@@ -10,10 +10,11 @@
// client versioning
//
-static const int CLIENT_VERSION_MAJOR = 0;
-static const int CLIENT_VERSION_MINOR = 6;
-static const int CLIENT_VERSION_REVISION = 1;
-static const int CLIENT_VERSION_BUILD = 3;
+// These need to be macro's, as version.cpp's voodoo requires it
+#define CLIENT_VERSION_MAJOR 0
+#define CLIENT_VERSION_MINOR 6
+#define CLIENT_VERSION_REVISION 99
+#define CLIENT_VERSION_BUILD 0
static const int CLIENT_VERSION =
1000000 * CLIENT_VERSION_MAJOR
diff --git a/src/wallet.cpp b/src/wallet.cpp
index 998909897f..62f663c0dc 100644
--- a/src/wallet.cpp
+++ b/src/wallet.cpp
@@ -1,7 +1,7 @@
// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2012 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
-// file license.txt or http://www.opensource.org/licenses/mit-license.php.
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "wallet.h"
#include "walletdb.h"
@@ -242,7 +242,8 @@ bool CWallet::EncryptWallet(const SecureString& strWalletPassphrase)
if (fFileBacked)
{
pwalletdbEncryption = new CWalletDB(strWalletFile);
- pwalletdbEncryption->TxnBegin();
+ if (!pwalletdbEncryption->TxnBegin())
+ return false;
pwalletdbEncryption->WriteMasterKey(nMasterKeyMaxID, kMasterKey);
}
@@ -273,7 +274,9 @@ bool CWallet::EncryptWallet(const SecureString& strWalletPassphrase)
// Need to completely rewrite the wallet file; if we don't, bdb might keep
// bits of the unencrypted private key in slack space in the database file.
CDB::Rewrite(strWalletFile);
+
}
+ NotifyStatusChanged(this);
return true;
}
@@ -296,7 +299,7 @@ void CWallet::WalletUpdateSpent(const CTransaction &tx)
printf("WalletUpdateSpent found spent coin %sbc %s\n", FormatMoney(wtx.GetCredit()).c_str(), wtx.GetHash().ToString().c_str());
wtx.MarkSpent(txin.prevout.n);
wtx.WriteToDisk();
- vWalletUpdated.push_back(txin.prevout.hash);
+ NotifyTransactionChanged(this, txin.prevout.hash, CT_UPDATED);
}
}
}
@@ -372,15 +375,12 @@ bool CWallet::AddToWallet(const CWalletTx& wtxIn)
}
}
#endif
- // Notify UI
- vWalletUpdated.push_back(hash);
-
// since AddToWallet is called directly for self-originating transactions, check for consumption of own coins
WalletUpdateSpent(wtx);
- }
- // Refresh UI
- MainFrameRepaint();
+ // Notify UI of new or updated transaction
+ NotifyTransactionChanged(this, hash, fInsertedNew ? CT_NEW : CT_UPDATED);
+ }
return true;
}
@@ -1182,7 +1182,7 @@ bool CWallet::CommitTransaction(CWalletTx& wtxNew, CReserveKey& reservekey)
coin.BindWallet(this);
coin.MarkSpent(txin.prevout.n);
coin.WriteToDisk();
- vWalletUpdated.push_back(coin.GetHash());
+ NotifyTransactionChanged(this, coin.GetHash(), CT_UPDATED);
}
if (fFileBacked)
@@ -1201,7 +1201,6 @@ bool CWallet::CommitTransaction(CWalletTx& wtxNew, CReserveKey& reservekey)
}
wtxNew.RelayWalletTransaction();
}
- MainFrameRepaint();
return true;
}
@@ -1230,13 +1229,12 @@ string CWallet::SendMoney(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew,
return strError;
}
- if (fAskFee && !ThreadSafeAskFee(nFeeRequired, _("Sending...")))
+ if (fAskFee && !uiInterface.ThreadSafeAskFee(nFeeRequired, _("Sending...")))
return "ABORTED";
if (!CommitTransaction(wtxNew, reservekey))
return _("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.");
- MainFrameRepaint();
return "";
}
@@ -1250,7 +1248,7 @@ string CWallet::SendMoneyToBitcoinAddress(const CBitcoinAddress& address, int64
if (nValue + nTransactionFee > GetBalance())
return _("Insufficient funds");
- // Parse bitcoin address
+ // Parse Bitcoin address
CScript scriptPubKey;
scriptPubKey.SetBitcoinAddress(address);
@@ -1289,8 +1287,9 @@ int CWallet::LoadWallet(bool& fFirstRunRet)
bool CWallet::SetAddressBookName(const CBitcoinAddress& address, const string& strName)
{
+ std::map<CBitcoinAddress, std::string>::iterator mi = mapAddressBook.find(address);
mapAddressBook[address] = strName;
- AddressBookRepaint();
+ NotifyAddressBookChanged(this, address.ToString(), strName, HaveKey(address), (mi == mapAddressBook.end()) ? CT_NEW : CT_UPDATED);
if (!fFileBacked)
return false;
return CWalletDB(strWalletFile).WriteName(address.ToString(), strName);
@@ -1299,7 +1298,7 @@ bool CWallet::SetAddressBookName(const CBitcoinAddress& address, const string& s
bool CWallet::DelAddressBookName(const CBitcoinAddress& address)
{
mapAddressBook.erase(address);
- AddressBookRepaint();
+ NotifyAddressBookChanged(this, address.ToString(), "", HaveKey(address), CT_DELETED);
if (!fFileBacked)
return false;
return CWalletDB(strWalletFile).EraseName(address.ToString());
@@ -1557,3 +1556,14 @@ void CWallet::GetAllReserveAddresses(set<CBitcoinAddress>& setAddress)
setAddress.insert(address);
}
}
+
+void CWallet::UpdatedTransaction(const uint256 &hashTx)
+{
+ {
+ LOCK(cs_wallet);
+ // Only notify UI if this transaction is in this wallet
+ map<uint256, CWalletTx>::const_iterator mi = mapWallet.find(hashTx);
+ if (mi != mapWallet.end())
+ NotifyTransactionChanged(this, hashTx, CT_UPDATED);
+ }
+}
diff --git a/src/wallet.h b/src/wallet.h
index 44c11e2ec4..57633c4aa3 100644
--- a/src/wallet.h
+++ b/src/wallet.h
@@ -1,7 +1,7 @@
// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2012 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
-// file license.txt or http://www.opensource.org/licenses/mit-license.php.
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifndef BITCOIN_WALLET_H
#define BITCOIN_WALLET_H
@@ -9,6 +9,7 @@
#include "key.h"
#include "keystore.h"
#include "script.h"
+#include "ui_interface.h"
class CWalletTx;
class CReserveKey;
@@ -102,8 +103,6 @@ public:
}
std::map<uint256, CWalletTx> mapWallet;
- std::vector<uint256> vWalletUpdated;
-
std::map<uint256, int> mapRequestCount;
std::map<CBitcoinAddress, std::string> mapAddressBook;
@@ -232,13 +231,7 @@ public:
bool DelAddressBookName(const CBitcoinAddress& address);
- void UpdatedTransaction(const uint256 &hashTx)
- {
- {
- LOCK(cs_wallet);
- vWalletUpdated.push_back(hashTx);
- }
- }
+ void UpdatedTransaction(const uint256 &hashTx);
void PrintWallet(const CBlock& block);
@@ -269,6 +262,16 @@ public:
// get the current wallet format (the oldest client version guaranteed to understand this wallet)
int GetVersion() { return nWalletVersion; }
+
+ /** Address book entry changed.
+ * @note called with lock cs_wallet held.
+ */
+ boost::signals2::signal<void (CWallet *wallet, const std::string &address, const std::string &label, bool isMine, ChangeType status)> NotifyAddressBookChanged;
+
+ /** Wallet transaction added, removed or updated.
+ * @note called with lock cs_wallet held.
+ */
+ boost::signals2::signal<void (CWallet *wallet, const uint256 &hashTx, ChangeType status)> NotifyTransactionChanged;
};
/** A key allocated from the key pool. */
diff --git a/src/walletdb.cpp b/src/walletdb.cpp
index 709ecac184..86cab4ab2b 100644
--- a/src/walletdb.cpp
+++ b/src/walletdb.cpp
@@ -1,7 +1,7 @@
// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2012 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
-// file license.txt or http://www.opensource.org/licenses/mit-license.php.
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "walletdb.h"
#include "wallet.h"
@@ -189,7 +189,7 @@ int CWalletDB::LoadWallet(CWallet* pwallet)
//// debug print
//printf("LoadWallet %s\n", wtx.GetHash().ToString().c_str());
- //printf(" %12I64d %s %s %s\n",
+ //printf(" %12"PRI64d" %s %s %s\n",
// wtx.vout[0].nValue,
// DateTimeStrFormat("%x %H:%M:%S", wtx.GetBlockTime()).c_str(),
// wtx.hashBlock.ToString().substr(0,20).c_str(),
@@ -367,7 +367,6 @@ void ThreadFlushWalletDB(void* parg)
map<string, int>::iterator mi = mapFileUseCount.find(strFile);
if (mi != mapFileUseCount.end())
{
- printf("%s ", DateTimeStrFormat("%x %H:%M:%S", GetTime()).c_str());
printf("Flushing wallet.dat\n");
nLastFlushed = nWalletDBUpdated;
int64 nStart = GetTimeMillis();
diff --git a/src/walletdb.h b/src/walletdb.h
index 46ba7967ca..dee1750262 100644
--- a/src/walletdb.h
+++ b/src/walletdb.h
@@ -1,7 +1,7 @@
// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2012 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
-// file license.txt or http://www.opensource.org/licenses/mit-license.php.
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifndef BITCOIN_WALLETDB_H
#define BITCOIN_WALLETDB_H