diff options
267 files changed, 25655 insertions, 25003 deletions
diff --git a/.gitignore b/.gitignore index aeeef170e6..66f93867d8 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,19 @@ src/bitcoin src/bitcoind .*.swp *.*~* +*.bak +*.rej +*.orig +*.o +*.patch +.bitcoin +#compilation and Qt preprocessor part +*.qm +Makefile +bitcoin-qt +#resources cpp +qrc_*.cpp +#qt creator +*.pro.user +#mac specific +.DS_Store diff --git a/INSTALL b/INSTALL new file mode 100644 index 0000000000..6989d8902d --- /dev/null +++ b/INSTALL @@ -0,0 +1,9 @@ +Building Bitcoin + +See doc/readme-qt.rst for instructions on building Bitcoin QT, +the intended-for-end-users, nice-graphical-interface, reference +implementation of Bitcoin. + +See doc/build-*.txt for instructions on building bitcoind, +the intended-for-services, no-graphical-interface, reference +implementation of Bitcoin. @@ -1,16 +1,42 @@ + Bitcoin integration/staging tree Development process =================== -Developers work in their own trees, then submit pull requests when they think their feature or bug fix is ready. +Developers work in their own trees, then submit pull requests when +they think their feature or bug fix is ready. + +If it is a simple/trivial/non-controversial change, then one of the +bitcoin development team members simply pulls it. + +If it is a more complicated or potentially controversial +change, then the patch submitter will be asked to start a +discussion (if they haven't already) on the mailing list: +http://sourceforge.net/mailarchive/forum.php?forum_name=bitcoin-development + +The patch will be accepted if there is broad consensus that it is a +good thing. Developers should expect to rework and resubmit patches +if they don't match the project's coding conventions (see coding.txt) +or are controversial. -If it is a simple/trivial/non-controversial change, then one of the bitcoin development team members simply pulls it. +The master branch is regularly built and tested, but is not guaranteed +to be completely stable. Tags are regularly created to indicate new +official, stable release versions of Bitcoin. If you would like to +help test the Bitcoin core, please contact QA@BitcoinTesting.org. -If it is a more complicated or potentially controversial change, then the patch submitter will be asked to start a discussion (if they haven't already) on the development forums: http://www.bitcoin.org/smf/index.php?board=6.0 -The patch will be accepted if there is broad consensus that it is a good thing. Developers should expect to rework and resubmit patches if they don't match the project's coding conventions (see coding.txt) or are controversial. +Feature branches are created when there are major new features being +worked on by several people. -The master branch is regularly built and tested (by who? need people willing to be quality assurance testers), and periodically pushed to the subversion repo to become the official, stable, released bitcoin. +From time to time a pull request will become outdated. If this occurs, and +the pull is no longer automatically mergeable; a comment on the pull will +be used to issue a warning of closure. The pull will be closed 15 days +after the warning if action is not taken by the author. Pull requests closed +in this manner will have their corresponding issue labeled 'stagnant'. +Issues with no commits will be given a similar warning, and closed after +15 days from their last activity. Issues closed in this manner will be +labeled 'stale'. -Feature branches are created when there are major new features being worked on by several people. +Requests to reopen closed pull requests and/or issues can be submitted to +QA@BitcoinTesting.org.
\ No newline at end of file diff --git a/bitcoin-qt.pro b/bitcoin-qt.pro new file mode 100644 index 0000000000..9b2a193acc --- /dev/null +++ b/bitcoin-qt.pro @@ -0,0 +1,227 @@ +TEMPLATE = app +TARGET = +INCLUDEPATH += src src/json src/qt +DEFINES += QT_GUI +CONFIG += no_include_pwd + +# for boost 1.37, add -mt to the boost libraries +# use: qmake BOOST_LIB_SUFFIX=-mt +# or when linking against a specific BerkelyDB version: BDB_LIB_SUFFIX=-4.8 + +# Dependency library locations can be customized with BOOST_INCLUDE_PATH, +# BOOST_LIB_PATH, BDB_INCLUDE_PATH, BDB_LIB_PATH +# OPENSSL_INCLUDE_PATH and OPENSSL_LIB_PATH respectively + +OBJECTS_DIR = build +MOC_DIR = build +UI_DIR = build + +# use: qmake "USE_UPNP=0" (disable by default) or "USE_UPNP=1" (enable by default) +# miniupnpc (http://miniupnp.free.fr/files/) must be installed +count(USE_UPNP, 1) { + message(Building with UPNP support) + DEFINES += USE_UPNP=$$USE_UPNP + LIBS += -lminiupnpc +} + +# use: qmake "USE_DBUS=1" +contains(USE_DBUS, 1) { + message(Building with DBUS (Freedesktop notifications) support) + DEFINES += USE_DBUS + QT += dbus +} + +# use: qmake "USE_SSL=1" +contains(USE_DBUS, 1) { + message(Building with SSL support for RPC) + DEFINES += USE_SSL +} + +# for extra security against potential buffer overflows +QMAKE_CXXFLAGS += -fstack-protector +QMAKE_LFLAGS += -fstack-protector + +# disable quite some warnings because bitcoin core "sins" a lot +QMAKE_CXXFLAGS_WARN_ON = -fdiagnostics-show-option -Wall -Wno-invalid-offsetof -Wno-unused-variable -Wno-unused-parameter -Wno-sign-compare -Wno-char-subscripts -Wno-unused-value -Wno-sequence-point -Wno-parentheses -Wno-unknown-pragmas -Wno-switch + +# Input +DEPENDPATH += src/qt src src json/include +HEADERS += src/qt/bitcoingui.h \ + src/qt/transactiontablemodel.h \ + src/qt/addresstablemodel.h \ + src/qt/optionsdialog.h \ + src/qt/sendcoinsdialog.h \ + src/qt/addressbookpage.h \ + src/qt/aboutdialog.h \ + src/qt/editaddressdialog.h \ + src/qt/bitcoinaddressvalidator.h \ + src/base58.h \ + src/bignum.h \ + src/util.h \ + src/uint256.h \ + src/serialize.h \ + src/strlcpy.h \ + src/main.h \ + src/net.h \ + src/key.h \ + src/db.h \ + src/script.h \ + src/noui.h \ + src/init.h \ + src/headers.h \ + src/irc.h \ + src/json/json_spirit_writer_template.h \ + src/json/json_spirit_writer.h \ + src/json/json_spirit_value.h \ + src/json/json_spirit_utils.h \ + src/json/json_spirit_stream_reader.h \ + src/json/json_spirit_reader_template.h \ + src/json/json_spirit_reader.h \ + src/json/json_spirit_error_position.h \ + src/json/json_spirit.h \ + src/qt/clientmodel.h \ + src/qt/guiutil.h \ + src/qt/transactionrecord.h \ + src/qt/guiconstants.h \ + src/qt/optionsmodel.h \ + src/qt/monitoreddatamapper.h \ + src/qtui.h \ + src/qt/transactiondesc.h \ + src/qt/transactiondescdialog.h \ + src/qt/bitcoinamountfield.h \ + src/wallet.h \ + src/keystore.h \ + src/qt/transactionfilterproxy.h \ + src/qt/transactionview.h \ + src/qt/walletmodel.h \ + src/bitcoinrpc.h \ + src/qt/overviewpage.h \ + src/qt/csvmodelwriter.h \ + src/crypter.h \ + src/qt/sendcoinsentry.h \ + src/qt/qvalidatedlineedit.h \ + src/qt/bitcoinunits.h \ + src/qt/qvaluecombobox.h \ + src/qt/askpassphrasedialog.h \ + src/protocol.h \ + src/qt/notificator.h + +SOURCES += src/qt/bitcoin.cpp src/qt/bitcoingui.cpp \ + src/qt/transactiontablemodel.cpp \ + src/qt/addresstablemodel.cpp \ + src/qt/optionsdialog.cpp \ + src/qt/sendcoinsdialog.cpp \ + src/qt/addressbookpage.cpp \ + src/qt/aboutdialog.cpp \ + src/qt/editaddressdialog.cpp \ + src/qt/bitcoinaddressvalidator.cpp \ + src/util.cpp \ + src/script.cpp \ + src/main.cpp \ + src/init.cpp \ + src/net.cpp \ + src/irc.cpp \ + src/db.cpp \ + src/json/json_spirit_writer.cpp \ + src/json/json_spirit_value.cpp \ + src/json/json_spirit_reader.cpp \ + src/qt/clientmodel.cpp \ + src/qt/guiutil.cpp \ + src/qt/transactionrecord.cpp \ + src/qt/optionsmodel.cpp \ + src/qt/monitoreddatamapper.cpp \ + src/qt/transactiondesc.cpp \ + src/qt/transactiondescdialog.cpp \ + src/qt/bitcoinstrings.cpp \ + src/qt/bitcoinamountfield.cpp \ + src/wallet.cpp \ + src/keystore.cpp \ + src/qt/transactionfilterproxy.cpp \ + src/qt/transactionview.cpp \ + src/qt/walletmodel.cpp \ + src/bitcoinrpc.cpp \ + src/qt/overviewpage.cpp \ + src/qt/csvmodelwriter.cpp \ + src/crypter.cpp \ + src/qt/sendcoinsentry.cpp \ + src/qt/qvalidatedlineedit.cpp \ + src/qt/bitcoinunits.cpp \ + src/qt/qvaluecombobox.cpp \ + src/qt/askpassphrasedialog.cpp \ + src/protocol.cpp \ + src/qt/notificator.cpp + +RESOURCES += \ + src/qt/bitcoin.qrc + +FORMS += \ + src/qt/forms/sendcoinsdialog.ui \ + src/qt/forms/addressbookpage.ui \ + src/qt/forms/aboutdialog.ui \ + src/qt/forms/editaddressdialog.ui \ + src/qt/forms/transactiondescdialog.ui \ + src/qt/forms/overviewpage.ui \ + src/qt/forms/sendcoinsentry.ui \ + src/qt/forms/askpassphrasedialog.ui + +CODECFORTR = UTF-8 + +# for lrelease/lupdate +TRANSLATIONS = src/qt/locale/bitcoin_nl.ts src/qt/locale/bitcoin_de.ts \ + src/qt/locale/bitcoin_ru.ts + +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 +# 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.CONFIG = no_link +QMAKE_EXTRA_COMPILERS += TSQM +PRE_TARGETDEPS += compiler_TSQM_make_all + +# "Other files" to show in Qt Creator +OTHER_FILES += \ + doc/*.rst doc/*.txt doc/README README.md + +# platform specific defaults, if not overridden on command line +isEmpty(BOOST_LIB_SUFFIX) { + macx:BOOST_LIB_SUFFIX = -mt + windows:BOOST_LIB_SUFFIX = -mgw44-mt-1_43 +} + +isEmpty(BDB_LIB_PATH) { + macx:BDB_LIB_PATH = /opt/local/lib/db48 +} + +isEmpty(BDB_INCLUDE_PATH) { + macx:BDB_INCLUDE_PATH = /opt/local/include/db48 +} + +isEmpty(BOOST_LIB_PATH) { + macx:BOOST_LIB_PATH = /opt/local/lib +} + +isEmpty(BOOST_INCLUDE_PATH) { + macx:BOOST_INCLUDE_PATH = /opt/local/include +} + +windows:LIBS += -lws2_32 -lgdi32 +windows:DEFINES += __WXMSW__ +windows:RC_FILE = src/qt/res/bitcoin-qt.rc + +macx:DEFINES += __WXMAC_OSX__ MSG_NOSIGNAL=0 BOOST_FILESYSTEM_VERSION=3 +macx:ICON = src/qt/res/icons/bitcoin.icns +macx:TARGET = "Bitcoin Qt" + +# Set libraries and includes at end, to use platform-defined defaults if not overridden +INCLUDEPATH += $$BOOST_INCLUDE_PATH $$BDB_INCLUDE_PATH $$OPENSSL_INCLUDE_PATH +LIBS += $$join(BOOST_LIB_PATH,,-L,) $$join(BDB_LIB_PATH,,-L,) $$join(OPENSSL_LIB_PATH,,-L,) +LIBS += -lssl -lcrypto -ldb_cxx$$BDB_LIB_SUFFIX +LIBS += -lboost_system$$BOOST_LIB_SUFFIX -lboost_filesystem$$BOOST_LIB_SUFFIX -lboost_program_options$$BOOST_LIB_SUFFIX -lboost_thread$$BOOST_LIB_SUFFIX + +system($$QMAKE_LRELEASE -silent $$_PRO_FILE_) diff --git a/contrib/Bitcoin.app/Contents/Info.plist b/contrib/Bitcoin.app/Contents/Info.plist index 9a2eccc280..d5a278a570 100644 --- a/contrib/Bitcoin.app/Contents/Info.plist +++ b/contrib/Bitcoin.app/Contents/Info.plist @@ -17,11 +17,11 @@ <key>CFBundlePackageType</key> <string>APPL</string> <key>CFBundleShortVersionString</key> - <string>0.3.24</string> + <string>0.4.1</string> <key>CFBundleSignature</key> <string>????</string> <key>CFBundleVersion</key> - <string>324</string> + <string>400</string> <key>LSMinimumSystemVersion</key> <string>10.5</string> <key>CFBundleIconFile</key> diff --git a/contrib/BitcoinTemplate.dmg b/contrib/BitcoinTemplate.dmg Binary files differnew file mode 100644 index 0000000000..ca86308e05 --- /dev/null +++ b/contrib/BitcoinTemplate.dmg diff --git a/contrib/bitrpc/bitrpc.py b/contrib/bitrpc/bitrpc.py new file mode 100644 index 0000000000..b02b299177 --- /dev/null +++ b/contrib/bitrpc/bitrpc.py @@ -0,0 +1,324 @@ +from jsonrpc import ServiceProxy +import sys +import string + +# ===== BEGIN USER SETTINGS ===== +# if you do not set these you will be prompted for a password for every command +rpcuser = "" +rpcpass = "" +# ====== END USER SETTINGS ====== + + +if rpcpass == "": + access = ServiceProxy("http://127.0.0.1:8332") +else: + access = ServiceProxy("http://"+rpcuser+":"+rpcpass+"@127.0.0.1:8332") +cmd = sys.argv[1].lower() + +if cmd == "backupwallet": + try: + path = raw_input("Enter destination path/filename: ") + print access.backupwallet(path) + except: + print "\n---An error occurred---\n" + +elif cmd == "getaccount": + try: + addr = raw_input("Enter a Bitcoin address: ") + print access.getaccount(addr) + except: + print "\n---An error occurred---\n" + +elif cmd == "getaccountaddress": + try: + acct = raw_input("Enter an account name: ") + print access.getaccountaddress(acct) + except: + print "\n---An error occurred---\n" + +elif cmd == "getaddressesbyaccount": + try: + acct = raw_input("Enter an account name: ") + print access.getaddressesbyaccount(acct) + except: + print "\n---An error occurred---\n" + +elif cmd == "getbalance": + try: + acct = raw_input("Enter an account (optional): ") + mc = raw_input("Minimum confirmations (optional): ") + try: + print access.getbalance(acct, mc) + except: + print access.getbalance() + except: + print "\n---An error occurred---\n" + +elif cmd == "getblockbycount": + try: + height = raw_input("Height: ") + print access.getblockbycount(height) + except: + print "\n---An error occurred---\n" + +elif cmd == "getblockcount": + try: + print access.getblockcount() + except: + print "\n---An error occurred---\n" + +elif cmd == "getblocknumber": + try: + print access.getblocknumber() + except: + print "\n---An error occurred---\n" + +elif cmd == "getconnectioncount": + try: + print access.getconnectioncount() + except: + print "\n---An error occurred---\n" + +elif cmd == "getdifficulty": + try: + print access.getdifficulty() + except: + print "\n---An error occurred---\n" + +elif cmd == "getgenerate": + try: + print access.getgenerate() + except: + print "\n---An error occurred---\n" + +elif cmd == "gethashespersec": + try: + print access.gethashespersec() + except: + print "\n---An error occurred---\n" + +elif cmd == "getinfo": + try: + print access.getinfo() + except: + print "\n---An error occurred---\n" + +elif cmd == "getnewaddress": + try: + acct = raw_input("Enter an account name: ") + try: + print access.getnewaddress(acct) + except: + print access.getnewaddress() + except: + print "\n---An error occurred---\n" + +elif cmd == "getreceivedbyaccount": + try: + acct = raw_input("Enter an account (optional): ") + mc = raw_input("Minimum confirmations (optional): ") + try: + print access.getreceivedbyaccount(acct, mc) + except: + print access.getreceivedbyaccount() + except: + print "\n---An error occurred---\n" + +elif cmd == "getreceivedbyaddress": + try: + addr = raw_input("Enter a Bitcoin address (optional): ") + mc = raw_input("Minimum confirmations (optional): ") + try: + print access.getreceivedbyaddress(addr, mc) + except: + print access.getreceivedbyaddress() + except: + print "\n---An error occurred---\n" + +elif cmd == "gettransaction": + try: + txid = raw_input("Enter a transaction ID: ") + print access.gettransaction(txid) + except: + print "\n---An error occurred---\n" + +elif cmd == "getwork": + try: + data = raw_input("Data (optional): ") + try: + print access.gettransaction(data) + except: + print access.gettransaction() + except: + print "\n---An error occurred---\n" + +elif cmd == "help": + try: + cmd = raw_input("Command (optional): ") + try: + print access.help(cmd) + except: + print access.help() + except: + print "\n---An error occurred---\n" + +elif cmd == "listaccounts": + try: + mc = raw_input("Minimum confirmations (optional): ") + try: + print access.listaccounts(mc) + except: + print access.listaccounts() + except: + print "\n---An error occurred---\n" + +elif cmd == "listreceivedbyaccount": + try: + mc = raw_input("Minimum confirmations (optional): ") + incemp = raw_input("Include empty? (true/false, optional): ") + try: + print access.listreceivedbyaccount(mc, incemp) + except: + print access.listreceivedbyaccount() + except: + print "\n---An error occurred---\n" + +elif cmd == "listreceivedbyaddress": + try: + mc = raw_input("Minimum confirmations (optional): ") + incemp = raw_input("Include empty? (true/false, optional): ") + try: + print access.listreceivedbyaddress(mc, incemp) + except: + print access.listreceivedbyaddress() + except: + print "\n---An error occurred---\n" + +elif cmd == "listtransactions": + try: + acct = raw_input("Account (optional): ") + count = raw_input("Number of transactions (optional): ") + frm = raw_input("Skip (optional):") + try: + print access.listtransactions(acct, count, frm) + except: + print access.listtransactions() + except: + print "\n---An error occurred---\n" + +elif cmd == "move": + try: + frm = raw_input("From: ") + to = raw_input("To: ") + amt = raw_input("Amount:") + mc = raw_input("Minimum confirmations (optional): ") + comment = raw_input("Comment (optional): ") + try: + print access.move(frm, to, amt, mc, comment) + except: + print access.move(frm, to, amt) + except: + print "\n---An error occurred---\n" + +elif cmd == "sendfrom": + try: + frm = raw_input("From: ") + to = raw_input("To: ") + amt = raw_input("Amount:") + mc = raw_input("Minimum confirmations (optional): ") + comment = raw_input("Comment (optional): ") + commentto = raw_input("Comment-to (optional): ") + try: + print access.sendfrom(frm, to, amt, mc, comment, commentto) + except: + print access.sendfrom(frm, to, amt) + except: + print "\n---An error occurred---\n" + +elif cmd == "sendmany": + try: + frm = raw_input("From: ") + to = raw_input("To (in format address1:amount1,address2:amount2,...): ") + mc = raw_input("Minimum confirmations (optional): ") + comment = raw_input("Comment (optional): ") + try: + print access.sendmany(frm,to,mc,comment) + except: + print access.sendmany(frm,to) + except: + print "\n---An error occurred---\n" + +elif cmd == "sendtoaddress": + try: + to = raw_input("To (in format address1:amount1,address2:amount2,...): ") + amt = raw_input("Amount:") + comment = raw_input("Comment (optional): ") + commentto = raw_input("Comment-to (optional): ") + try: + print access.sendtoaddress(to,amt,comment,commentto) + except: + print access.sendtoaddress(to,amt) + except: + print "\n---An error occurred---\n" + +elif cmd == "setaccount": + try: + addr = raw_input("Address: ") + acct = raw_input("Account:") + print access.setaccount(addr,acct) + except: + print "\n---An error occurred---\n" + +elif cmd == "setgenerate": + try: + gen= raw_input("Generate? (true/false): ") + cpus = raw_input("Max processors/cores (-1 for unlimited, optional):") + try: + print access.setgenerate(gen, cpus) + except: + print access.setgenerate(gen) + except: + print "\n---An error occurred---\n" + +elif cmd == "settxfee": + try: + amt = raw_input("Amount:") + print access.settxfee(amt) + except: + print "\n---An error occurred---\n" + +elif cmd == "stop": + try: + print access.stop() + except: + print "\n---An error occurred---\n" + +elif cmd == "validateaddress": + try: + addr = raw_input("Address: ") + print access.validateaddress(addr) + except: + print "\n---An error occurred---\n" + +elif cmd == "walletpassphrase": + try: + pwd = raw_input("Enter wallet passphrase: ") + access.walletpassphrase(pwd, 60) + print "\n---Wallet unlocked---\n" + except: + print "\n---An error occurred---\n" + +elif cmd == "walletpassphrasechange": + try: + pwd = raw_input("Enter old wallet passphrase: ") + pwd2 = raw_input("Enter new wallet passphrase: ") + access.walletpassphrasechange(pwd, pwd2) + print + print "\n---Passphrase changed---\n" + except: + print + print "\n---An error occurred---\n" + print + +else: + print "Command not found or not supported"
\ No newline at end of file diff --git a/contrib/create_osx_dmg.sh b/contrib/create_osx_dmg.sh new file mode 100755 index 0000000000..af164e56cf --- /dev/null +++ b/contrib/create_osx_dmg.sh @@ -0,0 +1,60 @@ +#!/usr/bin/env bash +# +# Creates a Bitcoin.dmg OSX file from the contrib/BitcoinTemplate.dmg file +# +# Recipe from: http://digital-sushi.org/entry/how-to-create-a-disk-image-installer-for-apple-mac-os-x/ +# +# To make a prettier BitcoinTemplate.dmg: +# + open (mount) BitcoinTemplate.dmg +# + change the file properties, icon positions, background image, etc +# + eject, then commit the changed BitcoinTemplate.dmg +# + +CWD=$(pwd) + +if [ $# -lt 1 ]; then + if [ $(basename $CWD) == "contrib" ] + then + TOP=$(dirname $CWD) + else + echo "Usage: $0 /path/to/bitcoin/tree" + exit 1 + fi +else + TOP=$1 +fi + +CONTRIB=$TOP/contrib +BUILD_DIR=/tmp/bitcoin_osx_build + +# First, compile bitcoin and bitcoind +cd "$TOP/src" +if [ ! -e bitcoin ]; then make -f makefile.osx bitcoin; fi +if [ ! -e bitcoind ]; then make -f makefile.osx bitcoind; fi +strip bitcoin bitcoind + +mkdir -p "$BUILD_DIR" +cd "$BUILD_DIR" + +rm -f Bitcoin.sparseimage +hdiutil convert "$CONTRIB/BitcoinTemplate.dmg" -format UDSP -o Bitcoin +hdiutil mount Bitcoin.sparseimage + +# Copy over placeholders in /Volumes/Bitcoin +cp "$TOP/src/bitcoind" /Volumes/Bitcoin/ +cp "$TOP/src/bitcoin" /Volumes/Bitcoin/Bitcoin.app/Contents/MacOS/ + +# Create source code .zip +cd "$TOP" +git archive -o /Volumes/Bitcoin/bitcoin.zip $(git branch 2>/dev/null|grep -e ^* | cut -d ' ' -f 2) + +# Fix permissions +chmod -Rf go-w /Volumes/Bitcoin + +cd "$BUILD_DIR" +hdiutil eject /Volumes/Bitcoin +rm -f "$CWD/Bitcoin.dmg" +hdiutil convert Bitcoin.sparseimage -format UDBZ -o "$CWD/Bitcoin.dmg" + +cd "$CWD" +rm -rf "$BUILD_DIR" diff --git a/contrib/gitian-descriptors/boost-win32.yml b/contrib/gitian-descriptors/boost-win32.yml new file mode 100644 index 0000000000..61ea50e4fe --- /dev/null +++ b/contrib/gitian-descriptors/boost-win32.yml @@ -0,0 +1,38 @@ +--- +name: "boost" +suites: +- "lucid" +architectures: +- "i386" +packages: +- "mingw32" +- "faketime" +- "zip" +reference_datetime: "2011-01-30 00:00:00" +remotes: [] +files: +- "boost_1_47_0.tar.bz2" +script: | + TMPDIR="$HOME/tmpdir" + mkdir -p $TMPDIR/bin/$GBUILD_BITS $TMPDIR/include + tar xjf boost_1_47_0.tar.bz2 + cd boost_1_47_0 + echo "using gcc : 4.4 : i586-mingw32msvc-g++ + : + <rc>i586-mingw32msvc-windres + <archiver>i586-mingw32msvc-ar + <cxxflags>-frandom-seed=boost1 + ;" > user-config.jam + ./bootstrap.sh --without-icu + ./bjam toolset=gcc target-os=windows threadapi=win32 threading=multi variant=release link=static --user-config=user-config.jam --without-mpi --without-python -sNO_BZIP2=1 -sNO_ZLIB=1 --layout=tagged --build-type=complete $MAKEOPTS stage + for lib in chrono date_time exception filesystem graph iostreams math_c99f math_c99l math_c99 math_tr1f math_tr1l math_tr1 prg_exec_monitor program_options random regex serialization signals system test_exec_monitor thread_win32 unit_test_framework wave wserialization; do + mkdir $lib + (cd $lib ; ar xf ../stage/lib/libboost_${lib}-mt-s.a) + mv $lib $TMPDIR/bin/$GBUILD_BITS + done + cp -a boost $TMPDIR/include + cd $TMPDIR + export LD_PRELOAD=/usr/lib/faketime/libfaketime.so.1 + export FAKETIME=$REFERENCE_DATETIME + zip -r boost-win32-1.47.0-gitian.zip * + cp boost-win32-1.47.0-gitian.zip $OUTDIR diff --git a/contrib/gitian-descriptors/gitian-win32.yml b/contrib/gitian-descriptors/gitian-win32.yml new file mode 100644 index 0000000000..52b10bc33f --- /dev/null +++ b/contrib/gitian-descriptors/gitian-win32.yml @@ -0,0 +1,92 @@ +--- +name: "bitcoin" +suites: +- "lucid" +architectures: +- "i386" +packages: +- "mingw32" +- "git-core" +- "unzip" +- "nsis" +- "faketime" +- "wine" +reference_datetime: "2011-01-30 00:00:00" +remotes: +- "url": "https://github.com/bitcoin/bitcoin.git" + "dir": "bitcoin" +files: +- "wxwidgets-win32-2.9.2-gitian.zip" +- "boost-win32-1.47.0-gitian.zip" +- "openssl-1.0.0d.tar.gz" +- "db-4.8.30.NC.tar.gz" +- "miniupnpc-1.6.tar.gz" +script: | + # + mkdir wxWidgets-2.9.2 + cd wxWidgets-2.9.2 + mkdir lib + unzip ../wxwidgets-win32-2.9.2-gitian.zip + cd bin/$GBUILD_BITS + for lib in wx_mswu; do + i586-mingw32msvc-ar rc ../../lib/lib${lib}-2.9-i586-mingw32msvc.a $lib/*.o + i586-mingw32msvc-ranlib ../../lib/lib${lib}-2.9-i586-mingw32msvc.a + done + cp -a wx ../../lib + cd ../.. + mv include/wx-2.9/wx include + cd .. + # + mkdir boost_1_47_0 + cd boost_1_47_0 + mkdir -p stage/lib + unzip ../boost-win32-1.47.0-gitian.zip + cd bin/$GBUILD_BITS + for lib in *; do + i586-mingw32msvc-ar rc ../../stage/lib/libboost_${lib}-mt-s.a $lib/*.o + i586-mingw32msvc-ranlib ../../stage/lib/libboost_${lib}-mt-s.a + done + cd ../.. + mv include/boost . + cd .. + # + tar xzf openssl-1.0.0d.tar.gz + cd openssl-1.0.0d + ./Configure --cross-compile-prefix=i586-mingw32msvc- mingw + make + cd .. + # + tar xzf db-4.8.30.NC.tar.gz + cd db-4.8.30.NC/build_unix + ../dist/configure --enable-mingw --enable-cxx --host=i586-mingw32msvc CFLAGS="-I/usr/i586-mingw32msvc/include" + make $MAKEOPTS + cd ../.. + # + tar xzf miniupnpc-1.6.tar.gz + cd miniupnpc-1.6 + sed 's/dllwrap -k --driver-name gcc/$(DLLWRAP) -k --driver-name $(CC)/' -i Makefile.mingw + sed 's|wingenminiupnpcstrings $< $@|./wingenminiupnpcstrings $< $@|' -i Makefile.mingw + make -f Makefile.mingw DLLWRAP=i586-mingw32msvc-dllwrap CC=i586-mingw32msvc-gcc AR=i586-mingw32msvc-ar + cd .. + mv miniupnpc-1.6 miniupnpc + # + cd bitcoin + mkdir -p $OUTDIR/src + cp -a . $OUTDIR/src + rm -rf $OUTDIR/src/.git + cp -a $OUTDIR/src/locale $OUTDIR + cp $OUTDIR/src/doc/README_windows.txt $OUTDIR/readme.txt + cp $OUTDIR/src/COPYING $OUTDIR/license.txt + cd src + sed 's/$(DEBUGFLAGS)/-frandom-seed=bitcoin/' -i makefile.linux-mingw + export LD_PRELOAD=/usr/lib/faketime/libfaketime.so.1 + export FAKETIME=$REFERENCE_DATETIME + export TZ=UTC + make -f makefile.linux-mingw $MAKEOPTS DEPSDIR=$HOME/build bitcoin.exe USE_UPNP=1 + make -f makefile.linux-mingw $MAKEOPTS DEPSDIR=$HOME/build bitcoind.exe USE_UPNP=0 + i586-mingw32msvc-strip bitcoin.exe + i586-mingw32msvc-strip bitcoind.exe + makensis ../share/setup.nsi + cp bitcoin.exe ../share/bitcoin-*-win32-setup.exe $OUTDIR/ + mkdir $OUTDIR/daemon + cp bitcoind.exe $OUTDIR/daemon diff --git a/contrib/gitian.yml b/contrib/gitian-descriptors/gitian.yml index 90be8934fa..efa9cb8c10 100644 --- a/contrib/gitian.yml +++ b/contrib/gitian-descriptors/gitian.yml @@ -6,40 +6,42 @@ architectures: - "i386" - "amd64" packages: -- "libdb4.7++-dev" +- "libdb4.8++-dev" - "libxxf86vm-dev" - "libgtk2.0-dev" - "libboost-all-dev" - "libssl-dev" - "git-core" +- "unzip" reference_datetime: "2011-01-30 00:00:00" remotes: - "url": "https://github.com/bitcoin/bitcoin.git" "dir": "bitcoin" files: -- "wxWidgets-2.9.1.tar.bz2" -- "miniupnpc-1.5.tar.gz" -- "toplevel.h.diff" -- "toplevel.cpp.diff" +- "wxWidgets-2.9.2-x64-gitian.zip" +- "wxWidgets-2.9.2-x32-gitian.zip" +- "miniupnpc-1.6.tar.gz" script: | INSTDIR="$HOME/install" export LIBRARY_PATH="$INSTDIR/lib" # - tar xzf miniupnpc-1.5.tar.gz - cd miniupnpc-1.5 + tar xzf miniupnpc-1.6.tar.gz + cd miniupnpc-1.6 INSTALLPREFIX=$INSTDIR make $MAKEOPTS install cd .. # - tar xjf wxWidgets-2.9.1.tar.bz2 - cd wxWidgets-2.9.1 - cd include/wx/gtk - patch < ../../../../toplevel.h.diff - cd ../../../src/gtk - patch < ../../../toplevel.cpp.diff - cd ../.. - ./configure --prefix=$INSTDIR --enable-monolithic --disable-shared - perl -i -p -e "s/__TIME__/\"$REFERENCE_TIME\"/;s/__DATE__/\"$REFERENCE_DATE\"/" include/wx/chartype.h - make $MAKEOPTS install + mkdir -p $INSTDIR/bin $INSTDIR/lib/wx $INSTDIR/include + mkdir wxWidgets-2.9.2 + cd wxWidgets-2.9.2 + unzip ../wxWidgets-2.9.2-x32-gitian.zip + unzip -o ../wxWidgets-2.9.2-x64-gitian.zip + cp -a bin/$GBUILD_BITS/wx/config/gtk2-unicode-static-2.9 $INSTDIR/bin/wx-config + for lib in wx_gtk2u wxregexu wxtiff; do + ar rc $INSTDIR/lib/lib${lib}-2.9.a bin/$GBUILD_BITS/$lib/*.o + ranlib $INSTDIR/lib/lib${lib}-2.9.a + done + cp -a include/wx-2.9/* $INSTDIR/include + cp -a bin/$GBUILD_BITS/wx/include $INSTDIR/lib/wx cd .. # cd bitcoin @@ -50,7 +52,7 @@ script: | cp $OUTDIR/src/doc/README $OUTDIR cp $OUTDIR/src/COPYING $OUTDIR cd src - sed 's/$(DEBUGFLAGS)//' < makefile.unix > makefile.unix.2 && mv makefile.unix.2 makefile.unix + sed 's/$(DEBUGFLAGS)//' -i makefile.unix PATH=$INSTDIR/bin:$PATH make -f makefile.unix CXX="g++ -I$INSTDIR/include -L$INSTDIR/lib" $MAKEOPTS bitcoin USE_UPNP=1 PATH=$INSTDIR/bin:$PATH make -f makefile.unix CXX="g++ -I$INSTDIR/include -L$INSTDIR/lib" $MAKEOPTS bitcoind USE_UPNP=0 mkdir -p $OUTDIR/bin/$GBUILD_BITS diff --git a/contrib/gitian-descriptors/wxwidgets-win32.yml b/contrib/gitian-descriptors/wxwidgets-win32.yml new file mode 100644 index 0000000000..3d49d7b35e --- /dev/null +++ b/contrib/gitian-descriptors/wxwidgets-win32.yml @@ -0,0 +1,40 @@ +--- +name: "wxwidgets" +suites: +- "lucid" +architectures: +- "i386" +packages: +- "mingw32" +- "faketime" +- "zip" +reference_datetime: "2011-01-30 00:00:00" +remotes: [] +files: +- "wxWidgets-2.9.2.tar.bz2" +script: | + INSTDIR="$HOME/install" + TMPDIR="$HOME/tmpdir" + export LIBRARY_PATH="$INSTDIR/lib" + # + tar xjf wxWidgets-2.9.2.tar.bz2 + cd wxWidgets-2.9.2 + CXXFLAGS=-frandom-seed=wx1 ./configure --host=i586-mingw32msvc --build=i686-linux --prefix=$INSTDIR --disable-shared --enable-monolithic --without-libpng --disable-svg + perl -i -p -e "s/__TIME__/\"$REFERENCE_TIME\"/;s/__DATE__/\"$REFERENCE_DATE\"/" include/wx/chartype.h + make $MAKEOPTS install + mkdir $TMPDIR + cd $TMPDIR + cp -af $INSTDIR/include . + mkdir -p $TMPDIR/bin/$GBUILD_BITS + cd $TMPDIR/bin/$GBUILD_BITS + cp -af $INSTDIR/lib/wx . + for lib in wx_mswu; do + mkdir $lib + (cd $lib ; ar xf $INSTDIR/lib/lib${lib}-2.9-i586-mingw32msvc.a) + done + chmod -R +w $TMPDIR + cd $TMPDIR + export LD_PRELOAD=/usr/lib/faketime/libfaketime.so.1 + export FAKETIME=$REFERENCE_DATETIME + zip -r wxwidgets-win32-2.9.2-gitian.zip * + cp wxwidgets-win32-2.9.2-gitian.zip $OUTDIR diff --git a/contrib/gitian-descriptors/wxwidgets.yml b/contrib/gitian-descriptors/wxwidgets.yml new file mode 100644 index 0000000000..0509615101 --- /dev/null +++ b/contrib/gitian-descriptors/wxwidgets.yml @@ -0,0 +1,42 @@ +--- +name: "wxwidgets" +suites: +- "lucid" +architectures: +- "i386" +- "amd64" +packages: +- "libxxf86vm-dev" +- "libgtk2.0-dev" +- "faketime" +- "zip" +reference_datetime: "2011-01-30 00:00:00" +remotes: [] +files: +- "wxWidgets-2.9.2.tar.bz2" +script: | + INSTDIR="$HOME/install" + TMPDIR="$HOME/tmpdir" + export LIBRARY_PATH="$INSTDIR/lib" + # + tar xjf wxWidgets-2.9.2.tar.bz2 + cd wxWidgets-2.9.2 + ./configure --prefix=$INSTDIR --enable-monolithic --disable-shared + perl -i -p -e "s/__TIME__/\"$REFERENCE_TIME\"/;s/__DATE__/\"$REFERENCE_DATE\"/" include/wx/chartype.h + make $MAKEOPTS install + mkdir $TMPDIR + cd $TMPDIR + cp -af $INSTDIR/include . + mkdir -p $TMPDIR/bin/$GBUILD_BITS + cd $TMPDIR/bin/$GBUILD_BITS + cp -af $INSTDIR/lib/wx . + for lib in wxtiff wxregexu wx_gtk2u; do + mkdir $lib + (cd $lib ; ar xf $INSTDIR/lib/lib${lib}-2.9.a) + done + chmod -R +w $TMPDIR + cd $TMPDIR + export LD_PRELOAD=/usr/lib/faketime/libfaketime.so.1 + export FAKETIME=$REFERENCE_DATETIME + zip -r wxWidgets-2.9.2-x$GBUILD_BITS-gitian.zip * + cp wxWidgets-2.9.2-x$GBUILD_BITS-gitian.zip $OUTDIR diff --git a/contrib/gitian-downloader/bluematt-key.pgp b/contrib/gitian-downloader/bluematt-key.pgp Binary files differnew file mode 100644 index 0000000000..fb6d9eb284 --- /dev/null +++ b/contrib/gitian-downloader/bluematt-key.pgp diff --git a/contrib/gitian-downloader/devrandom-key.pgp b/contrib/gitian-downloader/devrandom-key.pgp Binary files differnew file mode 100644 index 0000000000..71898127ba --- /dev/null +++ b/contrib/gitian-downloader/devrandom-key.pgp diff --git a/contrib/gitian-downloader/gavinandresen-key.pgp b/contrib/gitian-downloader/gavinandresen-key.pgp Binary files differnew file mode 100644 index 0000000000..f81f44e874 --- /dev/null +++ b/contrib/gitian-downloader/gavinandresen-key.pgp diff --git a/contrib/gitian-downloader/linux-download-config b/contrib/gitian-downloader/linux-download-config new file mode 100644 index 0000000000..d21bb07808 --- /dev/null +++ b/contrib/gitian-downloader/linux-download-config @@ -0,0 +1,30 @@ +--- +name: bitcoin +urls: +- http://bitcoin.org/bitcoin-latest-linux-gitian.zip +rss: +- url: http://sourceforge.net/api/file/index/project-id/244765/mtime/desc/limit/100/rss + xpath: //item/link/text() + pattern: bitcoin-\d+.\d+.\d+-linux-gitian.zip +signers: + 0A82509767C7D4A5D14DA2301AE1D35043E08E54: + weight: 40 + name: BlueMatt + key: bluematt + BF6273FAEF7CC0BA1F562E50989F6B3048A116B5: + weight: 40 + name: Devrandom + key: devrandom + D762373D24904A3E42F33B08B9A408E71DAAC974: + weight: 40 + name: Sipa + key: sipa + 77E72E69DA7EE0A148C06B21B34821D4944DE5F7: + weight: 40 + name: tcatm + key: tcatm + 01CDF4627A3B88AAE4A571C87588242FBE38D3A8: + weight: 40 + name: "Gavin Andresen" + key: gavinandresen +minimum_weight: 120 diff --git a/contrib/gitian-downloader/sipa-key.pgp b/contrib/gitian-downloader/sipa-key.pgp Binary files differnew file mode 100644 index 0000000000..086c9eb42e --- /dev/null +++ b/contrib/gitian-downloader/sipa-key.pgp diff --git a/contrib/gitian-downloader/tcatm-key.pgp b/contrib/gitian-downloader/tcatm-key.pgp Binary files differnew file mode 100644 index 0000000000..baaec76b8c --- /dev/null +++ b/contrib/gitian-downloader/tcatm-key.pgp diff --git a/contrib/gitian-downloader/win32-download-config b/contrib/gitian-downloader/win32-download-config new file mode 100644 index 0000000000..c0de21c48f --- /dev/null +++ b/contrib/gitian-downloader/win32-download-config @@ -0,0 +1,30 @@ +--- +name: bitcoin +urls: +- http://bitcoin.org/bitcoin-latest-win32-gitian.zip +rss: +- url: http://sourceforge.net/api/file/index/project-id/244765/mtime/desc/limit/100/rss + xpath: //item/link/text() + pattern: bitcoin-\d+.\d+.\d+-win32-gitian.zip +signers: + 0A82509767C7D4A5D14DA2301AE1D35043E08E54: + weight: 40 + name: BlueMatt + key: bluematt + BF6273FAEF7CC0BA1F562E50989F6B3048A116B5: + weight: 40 + name: Devrandom + key: devrandom + D762373D24904A3E42F33B08B9A408E71DAAC974: + weight: 40 + name: Sipa + key: sipa + 77E72E69DA7EE0A148C06B21B34821D4944DE5F7: + weight: 40 + name: tcatm + key: tcatm + 01CDF4627A3B88AAE4A571C87588242FBE38D3A8: + weight: 40 + name: "Gavin Andresen" + key: gavinandresen +minimum_weight: 120 diff --git a/contrib/gitian-win32.yml b/contrib/gitian-win32.yml deleted file mode 100644 index 07d31c717e..0000000000 --- a/contrib/gitian-win32.yml +++ /dev/null @@ -1,84 +0,0 @@ ---- -name: "bitcoin" -suites: -- "lucid" -architectures: -- "i386" -packages: -- "mingw32" -- "git-core" -- "unzip" -- "nsis" -reference_datetime: "2011-01-30 00:00:00" -remotes: -- "url": "https://github.com/bitcoin/bitcoin.git" - "dir": "bitcoin" -files: -- "wxWidgets-2.9.1.tar.bz2" -- "boost_1_43_0.tar.bz2" -- "openssl-1.0.0d.tar.gz" -- "db-4.7.25.NC.tar.gz" -- "upnpc-exe-win32-20110215.zip" -- "miniupnpc-1.5.20110215.tar.gz" -- "WSPiApi.h" -script: | - # - tar xjf wxWidgets-2.9.1.tar.bz2 - cd wxWidgets-2.9.1 - ./configure --host=i586-mingw32msvc --build=i686-linux --disable-shared --enable-monolithic --without-libpng --disable-svg - perl -i -p -e "s/__TIME__/\"$REFERENCE_TIME\"/;s/__DATE__/\"$REFERENCE_DATE\"/" include/wx/chartype.h - make $MAKEOPTS - cd .. - # - tar xzf openssl-1.0.0d.tar.gz - cd openssl-1.0.0d - ./Configure --cross-compile-prefix=i586-mingw32msvc- mingw - make - cd .. - # - tar xzf db-4.7.25.NC.tar.gz - cd db-4.7.25.NC/build_unix - ../dist/configure --enable-mingw --enable-cxx --host=i586-mingw32msvc CFLAGS="-I/usr/i586-mingw32msvc/include" - make $MAKEOPTS - cd ../.. - # - tar xjf boost_1_43_0.tar.bz2 - cd boost_1_43_0 - echo "using gcc : 4.4 : i586-mingw32msvc-g++ - : - <rc>i586-mingw32msvc-windres - <archiver>i586-mingw32msvc-ar - ;" > user-config.jam - ./bootstrap.sh --without-icu - ./bjam toolset=gcc target-os=windows threadapi=win32 threading=multi --user-config=user-config.jam --without-mpi --without-python -sNO_BZIP2=1 -sNO_ZLIB=1 --layout=tagged --build-type=complete $MAKEOPTS stage - cd .. - # - mkdir upnpc-exe-win32-20110215 - cd upnpc-exe-win32-20110215 - unzip ../upnpc-exe-win32-20110215.zip - mkdir miniupnpc - cd miniupnpc - tar xzf ../../miniupnpc-1.5.20110215.tar.gz - mv ./miniupnpc-1.5.20110215/* ./ - cd ../.. - # - cp WSPiApi.h $HOME/build - # - cd bitcoin - mkdir -p $OUTDIR/src - cp -a . $OUTDIR/src - rm -rf $OUTDIR/src/.git - cp -a $OUTDIR/src/locale $OUTDIR - cp $OUTDIR/src/doc/README_windows.txt $OUTDIR/readme.txt - cp $OUTDIR/src/COPYING $OUTDIR/license.txt - cd src - sed 's/$(DEBUGFLAGS)//' < makefile.linux-mingw > makefile.linux-mingw.2 && mv makefile.linux-mingw.2 makefile.linux-mingw - sed 's|//#include <WSPiApi.h>|#include <WSPiApi.h>|' < net.cpp > net.cpp.2 && mv net.cpp.2 net.cpp - make -f makefile.linux-mingw $MAKEOPTS DEPSDIR=$HOME/build bitcoin.exe USE_UPNP=1 - make -f makefile.linux-mingw $MAKEOPTS DEPSDIR=$HOME/build bitcoind.exe USE_UPNP=0 - i586-mingw32msvc-strip bitcoin.exe - i586-mingw32msvc-strip bitcoind.exe - makensis ../share/setup.nsi - cp bitcoin.exe ../share/bitcoin-*-win32-setup.exe $OUTDIR/ - mkdir $OUTDIR/daemon - cp bitcoind.exe $OUTDIR/daemon diff --git a/contrib/miniupnpc/Portfile b/contrib/miniupnpc/Portfile new file mode 100644 index 0000000000..133aee532c --- /dev/null +++ b/contrib/miniupnpc/Portfile @@ -0,0 +1,43 @@ +# -*- coding: utf-8; mode: tcl; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- vim:fenc=utf-8:filetype=tcl:et:sw=4:ts=4:sts=4 +# $Id$ + +PortSystem 1.0 + +name miniupnpc +epoch 2 +version 1.6 +revision 2 +categories net +platforms darwin +license BSD +maintainers singingwolfboy openmaintainer +description Lightweight client for UPnP protocol +long_description \ + ${description} + +homepage http://miniupnp.free.fr/ +master_sites http://miniupnp.free.fr/files/download.php?file=${distname}${extract.suffix}&dummy= +checksums md5 88055f2d4a061cfd4cfe25a9eae22f67 \ + sha1 ef8f2edb17f2e7c5b8dc67ee80a65c199d823e0a \ + rmd160 d86b75b331a3fb5525c71708548f311977c0598f + +use_configure no + +variant universal {} +if {[variant_isset universal]} { + set archflags ${configure.universal_cflags} +} else { + set archflags ${configure.cc_archflags} +} + +build.args-append CC="${configure.cc} ${archflags}" + +post-patch { + reinplace "s|-Wl,-install_name,|-Wl,-install_name,${prefix}/lib/|" ${worksrcpath}/Makefile +} + +destroot.destdir PREFIX=${prefix} INSTALLPREFIX=${destroot}${prefix} + +livecheck.type regex +livecheck.url http://miniupnp.free.fr/files/ +livecheck.regex ${name}-(\\d+(\\.\\d{1,4})+)${extract.suffix} diff --git a/contrib/pyminer/README b/contrib/pyminer/README new file mode 100644 index 0000000000..d1596575dd --- /dev/null +++ b/contrib/pyminer/README @@ -0,0 +1,6 @@ + +This is a 'getwork' CPU mining client for bitcoin. + +It is pure-python, and therefore very, very slow. The purpose is to +provide a reference implementation of a miner, for study. + diff --git a/contrib/pyminer/example-config.cfg b/contrib/pyminer/example-config.cfg new file mode 100644 index 0000000000..103e7c1372 --- /dev/null +++ b/contrib/pyminer/example-config.cfg @@ -0,0 +1,32 @@ + +# +# RPC login details +# +host=127.0.0.1 +port=8332 + +rpcuser=myusername +rpcpass=mypass + + +# +# mining details +# + +threads=4 + +# periodic rate for requesting new work, if solution not found +scantime=60 + + +# +# misc. +# + +# not really used right now +logdir=/tmp/pyminer + +# set to 1, to enable hashmeter output +hashmeter=0 + + diff --git a/contrib/pyminer/pyminer.py b/contrib/pyminer/pyminer.py new file mode 100755 index 0000000000..2887aba591 --- /dev/null +++ b/contrib/pyminer/pyminer.py @@ -0,0 +1,252 @@ +#!/usr/bin/python +# +# Copyright (c) 2011 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. +# + +import time +import json +import pprint +import hashlib +import struct +import re +import base64 +import httplib +import sys +from multiprocessing import Process + +ERR_SLEEP = 15 +MAX_NONCE = 1000000L + +settings = {} +pp = pprint.PrettyPrinter(indent=4) + +class BitcoinRPC: + OBJID = 1 + + def __init__(self, host, port, username, password): + authpair = "%s:%s" % (username, password) + self.authhdr = "Basic %s" % (base64.b64encode(authpair)) + self.conn = httplib.HTTPConnection(host, port, False, 30) + def rpc(self, method, params=None): + self.OBJID += 1 + obj = { 'version' : '1.1', + 'method' : method, + 'id' : self.OBJID } + if params is None: + obj['params'] = [] + else: + obj['params'] = params + self.conn.request('POST', '/', json.dumps(obj), + { 'Authorization' : self.authhdr, + 'Content-type' : 'application/json' }) + + resp = self.conn.getresponse() + if resp is None: + print "JSON-RPC: no response" + return None + + body = resp.read() + resp_obj = json.loads(body) + if resp_obj is None: + print "JSON-RPC: cannot JSON-decode body" + return None + if 'error' in resp_obj and resp_obj['error'] != None: + return resp_obj['error'] + if 'result' not in resp_obj: + print "JSON-RPC: no result in object" + return None + + return resp_obj['result'] + def getblockcount(self): + return self.rpc('getblockcount') + def getwork(self, data=None): + return self.rpc('getwork', data) + +def uint32(x): + return x & 0xffffffffL + +def bytereverse(x): + return uint32(( ((x) << 24) | (((x) << 8) & 0x00ff0000) | + (((x) >> 8) & 0x0000ff00) | ((x) >> 24) )) + +def bufreverse(in_buf): + out_words = [] + for i in range(0, len(in_buf), 4): + word = struct.unpack('@I', in_buf[i:i+4])[0] + out_words.append(struct.pack('@I', bytereverse(word))) + return ''.join(out_words) + +def wordreverse(in_buf): + out_words = [] + for i in range(0, len(in_buf), 4): + out_words.append(in_buf[i:i+4]) + out_words.reverse() + return ''.join(out_words) + +class Miner: + def __init__(self, id): + self.id = id + self.max_nonce = MAX_NONCE + + def work(self, datastr, targetstr): + # decode work data hex string to binary + static_data = datastr.decode('hex') + static_data = bufreverse(static_data) + + # the first 76b of 80b do not change + blk_hdr = static_data[:76] + + # decode 256-bit target value + targetbin = targetstr.decode('hex') + targetbin = targetbin[::-1] # byte-swap and dword-swap + targetbin_str = targetbin.encode('hex') + target = long(targetbin_str, 16) + + # pre-hash first 76b of block header + static_hash = hashlib.sha256() + static_hash.update(blk_hdr) + + for nonce in xrange(self.max_nonce): + + # encode 32-bit nonce value + nonce_bin = struct.pack("<I", nonce) + + # hash final 4b, the nonce value + hash1_o = static_hash.copy() + hash1_o.update(nonce_bin) + hash1 = hash1_o.digest() + + # sha256 hash of sha256 hash + hash_o = hashlib.sha256() + hash_o.update(hash1) + hash = hash_o.digest() + + # quick test for winning solution: high 32 bits zero? + if hash[-4:] != '\0\0\0\0': + continue + + # convert binary hash to 256-bit Python long + hash = bufreverse(hash) + hash = wordreverse(hash) + + hash_str = hash.encode('hex') + l = long(hash_str, 16) + + # proof-of-work test: hash < target + if l < target: + print time.asctime(), "PROOF-OF-WORK found: %064x" % (l,) + return (nonce + 1, nonce_bin) + else: + print time.asctime(), "PROOF-OF-WORK false positive %064x" % (l,) +# return (nonce + 1, nonce_bin) + + return (nonce + 1, None) + + def submit_work(self, rpc, original_data, nonce_bin): + nonce_bin = bufreverse(nonce_bin) + nonce = nonce_bin.encode('hex') + solution = original_data[:152] + nonce + original_data[160:256] + param_arr = [ solution ] + result = rpc.getwork(param_arr) + print time.asctime(), "--> Upstream RPC result:", result + + def iterate(self, rpc): + work = rpc.getwork() + if work is None: + time.sleep(ERR_SLEEP) + return + if 'data' not in work or 'target' not in work: + time.sleep(ERR_SLEEP) + return + + time_start = time.time() + + (hashes_done, nonce_bin) = self.work(work['data'], + work['target']) + + time_end = time.time() + time_diff = time_end - time_start + + self.max_nonce = long( + (hashes_done * settings['scantime']) / time_diff) + if self.max_nonce > 0xfffffffaL: + self.max_nonce = 0xfffffffaL + + if settings['hashmeter']: + print "HashMeter(%d): %d hashes, %.2f Khash/sec" % ( + self.id, hashes_done, + (hashes_done / 1000.0) / time_diff) + + if nonce_bin is not None: + self.submit_work(rpc, work['data'], nonce_bin) + + def loop(self): + rpc = BitcoinRPC(settings['host'], settings['port'], + settings['rpcuser'], settings['rpcpass']) + if rpc is None: + return + + while True: + self.iterate(rpc) + +def miner_thread(id): + miner = Miner(id) + miner.loop() + +if __name__ == '__main__': + if len(sys.argv) != 2: + print "Usage: pyminer.py CONFIG-FILE" + sys.exit(1) + + f = open(sys.argv[1]) + for line in f: + # skip comment lines + m = re.search('^\s*#', line) + if m: + continue + + # parse key=value lines + m = re.search('^(\w+)\s*=\s*(\S.*)$', line) + if m is None: + continue + settings[m.group(1)] = m.group(2) + f.close() + + if 'host' not in settings: + settings['host'] = '127.0.0.1' + if 'port' not in settings: + settings['port'] = 8332 + if 'threads' not in settings: + settings['threads'] = 1 + if 'hashmeter' not in settings: + settings['hashmeter'] = 0 + if 'scantime' not in settings: + settings['scantime'] = 30L + if 'rpcuser' not in settings or 'rpcpass' not in settings: + print "Missing username and/or password in cfg file" + sys.exit(1) + + settings['port'] = int(settings['port']) + settings['threads'] = int(settings['threads']) + settings['hashmeter'] = int(settings['hashmeter']) + settings['scantime'] = long(settings['scantime']) + + thr_list = [] + for thr_id in range(settings['threads']): + p = Process(target=miner_thread, args=(thr_id,)) + p.start() + thr_list.append(p) + time.sleep(1) # stagger threads + + print settings['threads'], "mining threads started" + + print time.asctime(), "Miner Starts - %s:%s" % (settings['host'], settings['port']) + try: + for thr_proc in thr_list: + thr_proc.join() + except KeyboardInterrupt: + pass + print time.asctime(), "Miner Stops - %s:%s" % (settings['host'], settings['port']) + diff --git a/contrib/wallettools/walletchangepass.py b/contrib/wallettools/walletchangepass.py new file mode 100644 index 0000000000..30f3f5b26a --- /dev/null +++ b/contrib/wallettools/walletchangepass.py @@ -0,0 +1,5 @@ +from jsonrpc import ServiceProxy +access = ServiceProxy("http://127.0.0.1:8332") +pwd = raw_input("Enter old wallet passphrase: ") +pwd2 = raw_input("Enter new wallet passphrase: ") +access.walletpassphrasechange(pwd, pwd2)
\ No newline at end of file diff --git a/contrib/wallettools/walletunlock.py b/contrib/wallettools/walletunlock.py new file mode 100644 index 0000000000..f847c6fe61 --- /dev/null +++ b/contrib/wallettools/walletunlock.py @@ -0,0 +1,4 @@ +from jsonrpc import ServiceProxy +access = ServiceProxy("http://127.0.0.1:8332") +pwd = raw_input("Enter wallet passphrase: ") +access.walletpassphrase(pwd, 60)
\ No newline at end of file diff --git a/contrib/wx-patches/README b/contrib/wx-patches/README deleted file mode 100644 index 2afb4a9e91..0000000000 --- a/contrib/wx-patches/README +++ /dev/null @@ -1,4 +0,0 @@ -This folder contains two patches which are applied to wxWidgets -2.9.1 before building the wxWidgets which is used for release -versions of bitcoin. They make the GUI show up on newer OSs -with new libgtks, such as Ubuntu 11.04. diff --git a/contrib/wx-patches/toplevel.cpp.diff b/contrib/wx-patches/toplevel.cpp.diff deleted file mode 100644 index 359abf28d4..0000000000 --- a/contrib/wx-patches/toplevel.cpp.diff +++ /dev/null @@ -1,86 +0,0 @@ ---- /wxWidgets/trunk/src/gtk/toplevel.cpp (revision 67326)
-+++ /wxWidgets/trunk/src/gtk/toplevel.cpp (revision 67496)
-@@ -72,4 +72,8 @@
- // send any activate events at all
- static int g_sendActivateEvent = -1;
-+
-+// Whether _NET_REQUEST_FRAME_EXTENTS support is working
-+// 0 == not tested yet, 1 == working, 2 == broken
-+static int gs_requestFrameExtentsStatus;
-
- //-----------------------------------------------------------------------------
-@@ -432,4 +436,12 @@
- if (event->state == GDK_PROPERTY_NEW_VALUE && event->atom == property)
- {
-+ if (win->m_netFrameExtentsTimerId)
-+ {
-+ // WM support for _NET_REQUEST_FRAME_EXTENTS is working
-+ gs_requestFrameExtentsStatus = 1;
-+ g_source_remove(win->m_netFrameExtentsTimerId);
-+ win->m_netFrameExtentsTimerId = 0;
-+ }
-+
- wxSize decorSize = win->m_decorSize;
- int left, right, top, bottom;
-@@ -439,4 +451,22 @@
- win->GTKUpdateDecorSize(decorSize);
- }
-+ return false;
-+}
-+}
-+
-+extern "C" {
-+static gboolean request_frame_extents_timeout(void* data)
-+{
-+ // WM support for _NET_REQUEST_FRAME_EXTENTS is broken
-+ gs_requestFrameExtentsStatus = 2;
-+ gdk_threads_enter();
-+ wxTopLevelWindowGTK* win = static_cast<wxTopLevelWindowGTK*>(data);
-+ win->m_netFrameExtentsTimerId = 0;
-+ wxSize decorSize = win->m_decorSize;
-+ int left, right, top, bottom;
-+ if (wxGetFrameExtents(gtk_widget_get_window(win->m_widget), &left, &right, &top, &bottom))
-+ decorSize.Set(left + right, top + bottom);
-+ win->GTKUpdateDecorSize(decorSize);
-+ gdk_threads_leave();
- return false;
- }
-@@ -459,4 +489,5 @@
- m_deferShowAllowed = true;
- m_updateDecorSize = true;
-+ m_netFrameExtentsTimerId = 0;
-
- m_urgency_hint = -2;
-@@ -811,5 +842,6 @@
- if (deferShow)
- {
-- deferShow = m_deferShowAllowed && !GTK_WIDGET_REALIZED(m_widget);
-+ deferShow = gs_requestFrameExtentsStatus != 2 &&
-+ m_deferShowAllowed && !gtk_widget_get_realized(m_widget);
- if (deferShow)
- {
-@@ -829,11 +861,4 @@
- // GetSize()/SetSize() because it makes window bigger between each
- // restore and save.
-- m_updateDecorSize = deferShow;
-- }
-- if (deferShow)
-- {
-- // Fluxbox support for _NET_REQUEST_FRAME_EXTENTS is broken
-- const char* name = gdk_x11_screen_get_window_manager_name(screen);
-- deferShow = strcmp(name, "Fluxbox") != 0;
- m_updateDecorSize = deferShow;
- }
-@@ -875,4 +900,12 @@
- (XEvent*)&xevent);
-
-+ if (gs_requestFrameExtentsStatus == 0)
-+ {
-+ // if WM does not respond to request within 1 second,
-+ // we assume support for _NET_REQUEST_FRAME_EXTENTS is not working
-+ m_netFrameExtentsTimerId =
-+ g_timeout_add(1000, request_frame_extents_timeout, this);
-+ }
-+
- // defer calling gtk_widget_show()
- m_isShown = true;
diff --git a/contrib/wx-patches/toplevel.h.diff b/contrib/wx-patches/toplevel.h.diff deleted file mode 100644 index c2718d4637..0000000000 --- a/contrib/wx-patches/toplevel.h.diff +++ /dev/null @@ -1,9 +0,0 @@ ---- /wxWidgets/trunk/include/wx/gtk/toplevel.h (revision 65373)
-+++ /wxWidgets/trunk/include/wx/gtk/toplevel.h (revision 67496)
-@@ -114,4 +114,6 @@
- // wxUSER_ATTENTION_ERROR difference, -2 for no hint, -1 for ERROR hint, rest for GtkTimeout handle.
- int m_urgency_hint;
-+ // timer for detecting WM with broken _NET_REQUEST_FRAME_EXTENTS handling
-+ unsigned m_netFrameExtentsTimerId;
-
- // return the size of the window without WM decorations
diff --git a/doc/README b/doc/README index a4df4c227b..789cc9fb87 100644 --- a/doc/README +++ b/doc/README @@ -1,4 +1,4 @@ -Bitcoin 0.3.24 BETA +Bitcoin 0.4.1 BETA Copyright (c) 2009-2011 Bitcoin Developers Distributed under the MIT/X11 software license, see the accompanying @@ -24,6 +24,93 @@ Unpack the files into a directory and run: bin/64/bitcoin (GUI, 64-bit) bin/64/bitcoind (headless, 64-bit) + +Wallet Encryption +----------------- +Bitcoin supports native wallet encryption so that people who steal your +wallet file don't automatically get access to all of your Bitcoins. +In order to enable this feature, chose "Encrypt Wallet" from the +Options menu. You will be prompted to enter a passphrase, which +will be used as the key to encrypt your wallet and will be needed +every time you wish to send Bitcoins. If you lose this passphrase, +you will lose access to spend all of the bitcoins in your wallet, +no one, not even the Bitcoin developers can recover your Bitcoins. +This means you are responsible for your own security, store your +passphrase in a secure location and do not forget it. + +Remember that the encryption built into bitcoin only encrypts the +actual keys which are required to send your bitcoins, not the full +wallet. This means that someone who steals your wallet file will +be able to see all the addresses which belong to you, as well as the +relevant transactions, you are only protected from someone spending +your coins. + +It is recommended that you backup your wallet file before you +encrypt your wallet. To do this, close the Bitcoin client and +copy the wallet.dat file from ~/.bitcoin/ on Linux, /Users/(user +name)/Application Support/Bitcoin/ on Mac OSX, and %APPDATA%/Bitcoin/ +on Windows (that is /Users/(user name)/AppData/Roaming/Bitcoin on +Windows Vista and 7 and /Documents and Settings/(user name)/Application +Data/Bitcoin on Windows XP). Once you have copied that file to a +safe location, reopen the Bitcoin client and Encrypt your wallet. +If everything goes fine, delete the backup and enjoy your encrypted +wallet. Note that once you encrypt your wallet, you will never be +able to go back to a version of the Bitcoin client older than 0.4. + +Keep in mind that you are always responsible for your own security. +All it takes is a slightly more advanced wallet-stealing trojan which +installs a keylogger to steal your wallet passphrase as you enter it +in addition to your wallet file and you have lost all your Bitcoins. +Wallet encryption cannot keep you safe if you do not practice +good security, such as running up-to-date antivirus software, only +entering your wallet passphrase in the Bitcoin client and using the +same passphrase only as your wallet passphrase. + + +Technical details of wallet encryption +-------------------------------------- +Wallet encryption uses AES-256-CBC to encrypt only the private keys +that are held in a wallet. The keys are encrypted with a master key +which is entirely random. This master key is then encrypted with +AES-256-CBC with a key derived from the passphrase using SHA512 and +OpenSSL's EVP_BytesToKey and a dynamic number of rounds determined by +the speed of the machine which does the initial encryption (and is +updated based on the speed of a computer which does a subsequent +passphrase change). Although the underlying code supports multiple +encrypted copies of the same master key (and thus multiple passphrases) +the client does not yet have a method to add additional passphrases. + +At runtime, the client loads the wallet as it normally would, however +the keystore stores the keys in encrypted form. When the passphrase +is required (to top up keypool or send coins) it will either be queried +by a GUI prompt, or must first be entered with the walletpassphrase +RPC command. This will change the wallet to "unlocked" state where the +unencrypted master key is stored in memory (in the case of GUI, only for +long enough to complete the requested operation, in RPC, for as long as +is specified by the second parameter to walletpassphrase). The wallet is +then locked (or can be manually locked using the walletlock RPC command) +and the unencrypted master key is removed from memory. + +Implementation details of wallet encryption +------------------------------------------- +When the wallet is locked, calls to sendtoaddress, sendfrom, sendmany, +and keypoolrefill will return Error -13: "Error: Please enter the wallet +passphrase with walletpassphrase first." + +When the wallet is unlocked, calls to walletpassphrase will fail. + +When a wallet is encrypted, the passphrase is required to top up the +keypool, thus, if the passphrase is rarely entered, it is possible that +keypool might run out. In this case, the default key will be used as the +target for payouts for mining, and calls to getnewaddress and getaccount +address will return an error. In order to prevent such cases, the keypool +is automatically refilled when walletpassphrase is called with a correct +passphrase and when topupkeypool is called (while the wallet is unlocked). +Note that the keypool continues to be topped up on various occasions when +a new key from pool is used and the wallet is unlocked (or unencrypted). + + + See the documentation at the bitcoin wiki: https://en.bitcoin.it/wiki/Main_Page diff --git a/doc/README_windows.txt b/doc/README_windows.txt index a19dcc9e92..7ff8834920 100644 --- a/doc/README_windows.txt +++ b/doc/README_windows.txt @@ -1,4 +1,4 @@ -Bitcoin 0.3.24 BETA
+Bitcoin 0.4.1 BETA
Copyright (c) 2009-2011 Bitcoin Developers
Distributed under the MIT/X11 software license, see the accompanying
diff --git a/doc/assets-attribution.txt b/doc/assets-attribution.txt new file mode 100644 index 0000000000..91d2e65804 --- /dev/null +++ b/doc/assets-attribution.txt @@ -0,0 +1,73 @@ +Icon: src/qt/res/icons/clock*.png, src/qt/res/icons/tx*.png, + src/qt/res/src/*.svg +Designer: Wladimir van der Laan +License: Creative Commons Attribution + +Icon: src/qt/res/icons/send.png +Icon Pack: Vista Style Arrow +Designer: Icons Land +License: Freeware Non-commercial +Site: http://findicons.com/icon/231371/right3green + +Icon: src/qt/res/icons/address-book.png +Icon Pack: Farm-Fresh Web +Designer: FatCow Web Hosting +License: Creative Commons Attribution (by) +Site: http://findicons.com/icon/163938/book_open + +Icon: src/qt/res/icons/connect*.png, src/qt/res/icons/synced.png, src/qt/res/icons/lock_*.png +Icon Pack: Human-O2 +Designer: schollidesign +License: GNU/GPL +Site: http://findicons.com/icon/93743/blocks_gnome_netstatus_0 + +Icon: src/qt/res/icons/transaction*.png +Designer: md2k7 +Site: https://forum.bitcoin.org/index.php?topic=15276.0 +License: You are free to do with these icons as you wish, including selling, + copying, modifying etc. + +Icon: src/qt/res/icons/configure.png, src/qt/res/icons/quit.png, + src/qt/res/icons/editcopy.png, src/qt/res/icons/editpaste.png, + src/qt/res/icons/add.png, src/qt/res/icons/edit.png, + src/qt/res/icons/remove.png (edited) +Designer: http://www.everaldo.com +Icon Pack: Crystal SVG +License: LGPL + +Icon: src/qt/res/icons/receive.png, src/qt/res/icons/history.png, + src/qt/res/icons/export.png +Designer: Oxygen team +Icon Pack: Oxygen +License: Creative Common Attribution-ShareAlike 3.0 License or LGPL +Site: http://www.oxygen-icons.org/ + +Icon: src/qt/res/icons/bitcoin.png, src/qt/res/icons/toolbar.png +Designer: Bitboy (optimized for 16x16 by Wladimir van der Laan) +License: Public Domain +Site: http://forum.bitcoin.org/?topic=1756.0 + +Icon: src/qt/res/icons/overview.png +Icon Pack: Primo +Designer: Jack Cai +License: Creative Commons Attribution No Derivatives (by-nd) +Site: http://findicons.com/icon/175944/home?id=176221# + +Icon: scripts/img/reload.xcf (modified),src/qt/res/movies/update_spinner.mng +Icon Pack: Kids +Designer: Everaldo (Everaldo Coelho) +License: GNU/GPL +Site: http://findicons.com/icon/17102/reload?id=17102 + +Image: src/qt/res/images/splash2.jpg (Wallet image) +Designer: Crobbo (forum) +Site: https://bitcointalk.org/index.php?topic=32273.0 +License: Public domain + +Icon: src/qt/res/icons/key.png +Designer: VisualPharm (Ivan Boyko) +Icon Pack: Must Have +Site: http://findicons.com/icon/51009/key?id=51009 +License: Creative Commons Attribution (by) + + diff --git a/doc/build-msw.txt b/doc/build-msw.txt index 1911008d1f..f3150e086e 100644 --- a/doc/build-msw.txt +++ b/doc/build-msw.txt @@ -7,6 +7,9 @@ cryptographic software written by Eric Young (eay@cryptsoft.com) and UPnP software written by Thomas Bernard. +See readme-qt.rst for instructions on building Bitcoin QT, the +graphical user interface. + WINDOWS BUILD NOTES =================== @@ -27,38 +30,23 @@ Dependencies Libraries you need to download separately and build: default path download -wxWidgets \wxwidgets-2.9.1-mgw http://www.wxwidgets.org/downloads/ OpenSSL \openssl-1.0.0d-mgw http://www.openssl.org/source/ -Berkeley DB \db-4.7.25.NC-mgw http://www.oracle.com/technology/software/products/berkeley-db/index.html -Boost \boost-1.43.0-mgw http://www.boost.org/users/download/ -miniupnpc \upnpc-exe-win32-20110215 http://miniupnp.tuxfamily.org/files/ +Berkeley DB \db-4.8.30.NC-mgw http://www.oracle.com/technology/software/products/berkeley-db/index.html +Boost \boost-1.47.0-mgw http://www.boost.org/users/download/ +miniupnpc \miniupnpc-1.6-mgw http://miniupnp.tuxfamily.org/files/ Their licenses: -wxWidgets LGPL 2.1 with very liberal exceptions OpenSSL Old BSD license with the problematic advertising requirement Berkeley DB New BSD license with additional requirement that linked software must be free open source Boost MIT-like license miniupnpc New (3-clause) BSD license Versions used in this release: -wxWidgets 2.9.1 OpenSSL 1.0.0d -Berkeley DB 4.7.25.NC -Boost 1.43.0 -miniupnpc 1.5-20110215 - - -Notes ------ -The UI layout is edited with wxFormBuilder. The project file is -uiproject.fbp. It generates uibase.cpp and uibase.h, which define base -classes that do the rote work of constructing all the UI elements. +Berkeley DB 4.8.30.NC +Boost 1.47.0 +miniupnpc 1.6 -wxWidgets ---------- -DOS shell: -cd \wxWidgets-2.9.1-mgw\build\msw -mingw32-make -f makefile.gcc OpenSSL ------- @@ -73,35 +61,30 @@ make Berkeley DB ----------- MSYS shell: -cd /c/db-4.7.25.NC-mgw/build_unix +cd /c/db-4.8.30.NC-mgw/build_unix sh ../dist/configure --enable-mingw --enable-cxx make - Boost ----- DOS prompt: downloaded boost jam 3.1.18 -cd \boost-1.43.0-mgw +cd \boost-1.47.0-mgw bjam toolset=gcc --build-type=complete stage -Note: -building with boost 1.45.0 failed because of boost ticket 4614, 4258 -builds fine with boost 1.43.0 - MiniUPnPc --------- -Building miniupnpc failed on Windows Server 2003, thus it is expected that a binary copy will be used. -See http://miniupnp.tuxfamily.org/forum/viewtopic.php?t=642 UPnP support is optional, make with USE_UPNP= to disable it. -Get upnpc-exe-win32-20110215.zip and unzip it to \upnpc-exe-win32-20110215 -Get miniupnpc-1.5.20110215.tar.gz and copy *.h to \upnpc-exe-win32-20110215\miniupnpc +MSYS shell: +cd /c/miniupnpc-1.6-mgw +make -f Makefile.mingw +mkdir miniupnpc +cp *.h miniupnpc/ Bitcoin ------- DOS prompt: cd \bitcoin\src -mingw32-make bitcoin.exe bitcoind.exe -f makefile.mingw -strip bitcoin.exe +mingw32-make bitcoind.exe -f makefile.mingw strip bitcoind.exe diff --git a/doc/build-osx.txt b/doc/build-osx.txt index ddf025003b..a13f8d3ada 100644 --- a/doc/build-osx.txt +++ b/doc/build-osx.txt @@ -1,5 +1,4 @@ -Copyright (c) 2010 Laszlo Hanyecz -Portions Copyright (c) 2011 Douglas Huff +Copyright (c) 2011 Bitcoin Developers 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 @@ -8,11 +7,14 @@ software written by Eric Young (eay@cryptsoft.com) and UPnP software written by Thomas Bernard. -Mac OS X build instructions +Mac OS X bitcoind build instructions Laszlo Hanyecz <solar@heliacal.net> Douglas Huff <dhuff@jrbobdobbs.org> +See readme-qt.rst for instructions on building Bitcoin QT, the +graphical user interface. + Tested on 10.5 and 10.6 intel. PPC is not supported because it's big-endian. All of the commands should be executed in Terminal.app.. it's in @@ -23,256 +25,29 @@ everything is available in /usr not just /Developer I think it comes on the DVD but you can get the current version from http://developer.apple.com -1. Pick a directory to work inside.. something like ~/bitcoin works. The -structure I use looks like this: - -(~ is your home directory) - -~/bitcoin -~/bitcoin/bitcoin # Upstream source tree -~/bitcoin/src # source code (symlink to ~/bitcoin/bitcoin/src) -~/bitcoin/deps # dependencies.. like libraries and headers needed to compile -~/bitcoin/Bitcoin.app # the application bundle where you can run the app - -Just execute: mkdir ~/bitcoin -This will create the top dir for you.. - -WARNING: do not use the ~ notation with the configure scripts.. use the full -name of the directory, for example /Users/james/bitcoin/deps for a user named -'james'. In my examples I am using 'macosuser' so make sure you change that. - -2. Check out the bitcoin code from github: - -cd ~/bitcoin -git clone https://github.com/bitcoin/bitcoin.git -ln -s bitcoin/src src - -This will make ~/bitcoin/bitcoin for you with all the files from git. This puts -the actual sources in ~/bitcoin/bitcoin/src and create a symlink src in -~/bitcoin to this location. - -3. Get and build the dependencies - - -Boost ------ - -Download from http://www.boost.org/users/download/ -I'm assuming it ended up in ~/Downloads.. - -mkdir ~/bitcoin/deps -cd ~/bitcoin/deps -tar xvjf ~/Downloads/boost_1_42_0.tar.bz2 -cd boost_1_42_0 -./bootstrap.sh -./bjam architecture=combined address-model=32_64 macosx-version=10.5 macosx-version-min=10.5 link=static runtime-link=static --toolset=darwin --prefix=/Users/macosuser/bitcoin/deps install - -If you're using Snow Leopard, you will need to specify 10.6 as your Mac OS X -version instead of 10.5. - -This part takes a while.. use your judgement and fix it if something doesn't -build for some reason. - -Change the prefix to whatever your directory is (my username in this example -is macosuser). I'm also running on 10.6 so i have macosx-version=10.6 change -to 10.5 if you're using leopard. - -This is what my output looked like at the end: -...failed updating 2 targets... -...skipped 144 targets... -...updated 8074 targets... - - -OpenSSL -------- - -(System or MacPorts openssl will work fine. Optional.) - -Download from http://www.openssl.org/source/ - -We would like to build this as a 32 bit/64 bit library so we actually build it -2 times and join it together here.. If you downloaded with safari it already -uncompressed it so it will just be a tar not a tar.gz - -cd ~/bitcoin/deps -tar xvf ~/Downloads/openssl-1.0.0.tar -mv openssl-1.0.0 openssl-1.0.0-i386 -tar xvf ~/Downloads/openssl-1.0.0.tar -mv openssl-1.0.0 openssl-1.0.0-x86_64 -# build i386 (32 bit intel) binary -cd openssl-1.0.0-i386 -./Configure --prefix=/Users/macosuser/bitcoin/deps --openssldir=/Users/macosuser/bitcoin/deps/openssl darwin-i386-cc && make -make install # only do this on one of the architectures, to install the headers -cd .. -# build x86_64 (64 bit intel) binary -cd openssl-1.0.0-x86_64 -./Configure --prefix=/Users/macosuser/bitcoin/deps --openssldir=/Users/macosuser/bitcoin/deps/openssl darwin64-x86_64-cc && make -cd .. - -# combine the libs -cd ~/bitcoin/deps -lipo -arch i386 openssl-1.0.0-i386/libcrypto.a -arch x86_64 openssl-1.0.0-x86_64/libcrypto.a -o lib/libcrypto.a -create -lipo -arch i386 openssl-1.0.0-i386/libssl.a -arch x86_64 openssl-1.0.0-x86_64/libssl.a -o lib/libssl.a -create - -Verify your binaries - -file lib/libcrypto.a - -output should look like this: - -lib/libcrypto.a: Mach-O universal binary with 2 architectures -lib/libcrypto.a (for architecture i386): current ar archive random library -lib/libcrypto.a (for architecture x86_64): current ar archive random library - - -miniupnpc ---------- - -(MacPorts miniupnpc package works fine. You will need to modify makefile.) - -The process for miniupnpc (optional) is similar to that of OpenSSL. - -Download from http://miniupnp.tuxfamily.org/files/. - -cd ~/bitcoin/deps -tar xvf ~/Downloads/miniupnpc-1.5.tar -mv miniupnpc-1.5 miniupnpc-1.5-x86_64 -tar xvf ~/Downloads/miniupnpc-1.5.tar -mv miniupnpc-1.5 miniupnpc-1.5-i386 -# build x86_64 (64 bit intel) binary -cd miniupnpc-1.5-x86_64 -export CFLAGS="-arch x86_64" -export LDFLAGS="-arch x86_64" -export PREFIX="/Users/macuser/bitcoin/deps" -make && make install -# build i386 (32 bit intel) binary -cd miniupnpc-1.5-i386 -export CFLAGS="-arch i386" -export LDFLAGS="-arch i386" -export PREFIX="/Users/macuser/bitcoin/deps" -make - -# combine the libs -cd ~/bitcoin/deps -lipo -arch i386 miniupnpc-1.5-i386/libminiupnpc.a -arch x86_64 miniupnpc-1.5-x86_64/libminiupnpc.a -o lib/libminiupnpc.a -create - -Verify your binaries - -file lib/libminiupnpc.a - -output should look like this: - -lib/libminiupnpc.a: Mach-O universal binary with 2 architectures -lib/libminiupnpc.a (for architecture i386): current ar archive random library -lib/libminiupnpc.a (for architecture x86_64): current ar archive random library - - -Berkeley DB ------------ - -(System or MacPorts version work fine.) - -Download from http://freshmeat.net/projects/berkeleydb/ - -cd ~/bitcoin/deps -tar xvf ~/Downloads/db-4.8.26.tar -cd db-4.8.26/build_unix -../dist/configure --prefix=/Users/macosuser/bitcoin/deps --enable-cxx && make && make install - - -wxWidgets ---------- - -(The wxWidgets-devel MacPorts package will work but will throw annoying assertion dialogs.) - -This is the big one.. - -Check it out from svn - -cd ~/bitcoin/deps -svn checkout http://svn.wxwidgets.org/svn/wx/wxWidgets/trunk wxWidgets-trunk - -This will make a wxWidgets-trunk directory in deps. - -Use this script snippet, change your prefix to whatever your dir is: - -PREFIX=~/bitcoin/deps -SRCDIR="$PREFIX/wxWidgets-trunk" -BUILDDIR="$SRCDIR/macbuild" - -cd "$PREFIX" && -#svn checkout http://svn.wxwidgets.org/svn/wx/wxWidgets/trunk wxWidgets-trunk && -cd "$SRCDIR" && - -[ -f include/wx/hashmap.h.orig ] || cp include/wx/hashmap.h include/wx/hashmap.h.orig && -sed 's/if wxUSE_STL/if 0 \&\& wxUSE_STL/g' < include/wx/hashmap.h.orig > include/wx/hashmap.h && - -[ -f include/wx/hashset.h.orig ] || cp include/wx/hashset.h include/wx/hashset.h.orig && -sed 's/if wxUSE_STL/if 0 \&\& wxUSE_STL/g' < include/wx/hashset.h.orig > include/wx/hashset.h && - - - -rm -vrf "$BUILDDIR" && -mkdir "$BUILDDIR" && -cd "$BUILDDIR" && - -../configure --prefix="$PREFIX" \ ---with-osx_cocoa \ ---disable-shared \ ---disable-debug_flag \ ---with-macosx-version-min=10.5 \ ---enable-stl \ ---enable-utf8 \ ---enable-universal_binary \ ---with-libjpeg=builtin \ ---with-libpng=builtin \ ---with-regex=builtin \ ---with-libtiff=builtin \ ---with-zlib=builtin \ ---with-expat=builtin \ ---with-macosx-sdk=/Developer/SDKs/MacOSX10.5.sdk && - - -find . -name Makefile | -while read i; do - echo $i; - sed 's/-arch i386/-arch i386 -arch x86_64/g' < "$i" > "$i".new && - mv "$i" "$i".old && - mv "$i".new "$i"; -done - - - -make && -make install - - - -Now you should be able to build bitcoin - -cd ~/bitcoin/src -make -f makefile.osx bitcoin - -Before you can run it, you need to create an application bundle for Mac OS. - -A bundle is provided in contrib/Bitcoin.app. +1. Clone the github tree to get the source code: -Copy the bitcoin binary in to it like this: - cp -pR ~/bitcoin/bitcoin/contrib/Bitcoin.app ~/bitcoin/ - cp ~/bitcoin/src/bitcoin ~/bitcoin/Bitcoin.app/Contents/MacOS/ +git clone git@github.com:bitcoin/bitcoin.git bitcoin -To run it you can just click the Bitcoin.app in Finder, or just do: -open ~/bitcoin/Bitcoin.app +2. Download and install MacPorts from http://www.macports.org/ -If you want to run it with arguments you can just run it without backgrounding -by specifying the full name in terminal: +3. Install dependencies from MacPorts -~/bitcoin/Bitcoin.app/Contents/MacOS/bitcoin -addnode=192.75.207.66 +sudo port install boost db48 openssl -You can also run it with arguments in the background with output going to the -normal places for apps (Console) like this: +Install the right version of miniupnpc: +pushd bitcoin/contrib/minipupnpc; sudo port install; popd +(this will be unnecessary soon, you will just port install miniupnpc +along with the rest of the dependencies). -open ~/bitcoin/Bitcoin.app --args -connect=192.75.207.66 +4. Now you should be able to build bitcoind: -It is advisable to relocate Bitcoin.app to /Applications or $HOME/Applications. +cd bitcoin/src +make -f makefile.osx +Run: + ./bitcoind --help # for a list of command-line options. +Run + ./bitcoind -daemon # to start the bitcoin daemon. +Run + ./bitcoind help # When the daemon is running, to get a list of RPC commands diff --git a/doc/build-unix.txt b/doc/build-unix.txt index 0c4e88e523..b7aa7112b4 100644 --- a/doc/build-unix.txt +++ b/doc/build-unix.txt @@ -1,4 +1,5 @@ Copyright (c) 2009-2010 Satoshi Nakamoto +Copyright (c) 2011 Bitcoin Developers 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 @@ -14,31 +15,22 @@ To Build -------- cd src/ +make -f makefile.unix # Headless bitcoin -make -f makefile.unix # Bitcoin with wxWidgets GUI - or -make -f makefile.unix bitcoind # Headless bitcoin - +See readme-qt.rst for instructions on building Bitcoin QT, +the graphical bitcoin. Dependencies ------------ sudo apt-get install build-essential -sudo apt-get install libgtk2.0-dev sudo apt-get install libssl-dev -sudo apt-get install libdb4.7-dev -sudo apt-get install libdb4.7++-dev +sudo apt-get install libdb4.8-dev +sudo apt-get install libdb4.8++-dev Boost 1.40+: sudo apt-get install libboost-all-dev or Boost 1.37: sudo apt-get install libboost1.37-dev If using Boost 1.37, append -mt to the boost libraries in the makefile. -Requires wxWidgets 2.9.0 or greater, which uses UTF-8. Don't try 2.8, it -won't work. - -You need to download wxWidgets from http://www.wxwidgets.org/downloads/ -and build it yourself. See the build instructions and configure parameters -below. - Requires miniupnpc for UPnP port mapping. It can be downloaded from http://miniupnp.tuxfamily.org/files/. UPnP support is compiled in and turned off by default. Set USE_UPNP to a different value to control this: @@ -47,7 +39,6 @@ USE_UPNP=0 (the default) UPnP support turned off by default at runtime; USE_UPNP=1 UPnP support turned on by default at runtime. Licenses of statically linked libraries: -wxWidgets LGPL 2.1 with very liberal exceptions Berkeley DB New BSD license with additional requirement that linked software must be free open source Boost MIT-like license miniupnpc New (3-clause) BSD license @@ -55,40 +46,21 @@ miniupnpc New (3-clause) BSD license Versions used in this release: GCC 4.3.3 OpenSSL 0.9.8g -wxWidgets 2.9.0 -Berkeley DB 4.7.25.NC +Berkeley DB 4.8.30.NC Boost 1.37 -miniupnpc 1.5 +miniupnpc 1.6 Notes ----- -The UI layout is edited with wxFormBuilder. The project file is -uiproject.fbp. It generates uibase.cpp and uibase.h, which define base -classes that do the rote work of constructing all the UI elements. - The release is built with GCC and then "strip bitcoin" to strip the debug symbols, which reduces the executable size by about 90%. -wxWidgets ---------- -cd /usr/local -tar -xzvf wxWidgets-2.9.0.tar.gz -cd wxWidgets-2.9.0 -mkdir buildgtk -cd buildgtk -../configure --with-gtk --enable-debug --disable-shared --enable-monolithic --without-libpng --disable-svg -make -sudo su -make install -ldconfig - - miniupnpc --------- -tar -xzvf miniupnpc-1.5.tar.gz -cd miniupnpc-1.5 +tar -xzvf miniupnpc-1.6.tar.gz +cd miniupnpc-1.6 make sudo su make install @@ -96,8 +68,7 @@ make install Berkeley DB ----------- -You need Berkeley DB 4.7. Don't use 4.8, the database/log0000* files -are incompatible. If you have to build Berkeley DB yourself: +You need Berkeley DB 4.8. If you have to build Berkeley DB yourself: ../dist/configure --enable-cxx make @@ -108,3 +79,45 @@ If you need to build Boost yourself: sudo su ./bootstrap.sh ./bjam install + + +Security +-------- +To help make your bitcoin installation more secure by making certain attacks impossible to +exploit even if a vulnerability is found, you can take the following measures: + +* Position Independent Executable + Build position independent code to take advantage of Address Space Layout Randomization + offered by some kernels. An attacker who is able to cause execution of code at an arbitrary + memory location is thwarted if he doesn't know where anything useful is located. + The stack and heap are randomly located by default but this allows the code section to be + randomly located as well. + + On an Amd64 processor where a library was not compiled with -fPIC, this will cause an error + such as: "relocation R_X86_64_32 against `......' can not be used when making a shared object;" + + To build with PIE, use: + make -f makefile.unix ... -e PIE=1 + + To test that you have built PIE executable, install scanelf, part of paxutils, and use: + scanelf -e ./bitcoin + + The output should contain: + TYPE + ET_DYN + +* Non-executable Stack + If the stack is executable then trivial stack based buffer overflow exploits are possible if + vulnerable buffers are found. By default, bitcoin should be built with a non-executable stack + but if one of the libraries it uses asks for an executable stack or someone makes a mistake + and uses a compiler extension which requires an executable stack, it will silently build an + executable without the non-executable stack protection. + + To verify that the stack is non-executable after compiling use: + scanelf -e ./bitcoin + + the output should contain: + STK/REL/PTL + RW- R-- RW- + + The STK RW- means that the stack is readable and writeable but not executable. diff --git a/doc/coding.txt b/doc/coding.txt index 4707476697..b3c812a486 100644 --- a/doc/coding.txt +++ b/doc/coding.txt @@ -39,3 +39,61 @@ v vector or similar list objects map map or multimap
set set or multiset
bn CBigNum
+
+-------------------------
+Locking/mutex usage notes
+
+The code is multi-threaded, and uses mutexes and the
+CRITICAL_BLOCK/TRY_CRITICAL_BLOCK macros to protect data structures.
+
+Deadlocks due to inconsistent lock ordering (thread 1 locks cs_main
+and then cs_wallet, while thread 2 locks them in the opposite order:
+result, deadlock as each waits for the other to release its lock) are
+a problem. Compile with -DDEBUG_LOCKORDER to get lock order
+inconsistencies reported in the debug.log file.
+
+Re-architecting the core code so there are better-defined interfaces
+between the various components is a goal, with any necessary locking
+done by the components (e.g. see the self-contained CKeyStore class
+and its cs_KeyStore lock for example).
+
+-------
+Threads
+
+StartNode : Starts other threads.
+
+ThreadGetMyExternalIP : Determines outside-the-firewall IP address,
+sends addr message to connected peers when it determines it.
+
+ThreadIRCSeed : Joins IRC bootstrapping channel, watching for new
+peers and advertising this node's IP address.
+
+ThreadSocketHandler : Sends/Receives data from peers on port 8333.
+
+ThreadMessageHandler : Higher-level message handling (sending and
+receiving).
+
+ThreadOpenConnections : Initiates new connections to peers.
+
+ThreadTopUpKeyPool : replenishes the keystore's keypool.
+
+ThreadCleanWalletPassphrase : re-locks an encrypted wallet after user
+has unlocked it for a period of time.
+
+SendingDialogStartTransfer : used by pay-via-ip-address code (obsolete)
+
+ThreadDelayedRepaint : repaint the gui
+
+ThreadFlushWalletDB : Close the wallet.dat file if it hasn't been used
+in 500ms.
+
+ThreadRPCServer : Remote procedure call handler, listens on port 8332
+for connections and services them.
+
+ThreadBitcoinMiner : Generates bitcoins
+
+ThreadMapPort : Universal plug-and-play startup/shutdown
+
+Shutdown : Does an orderly shutdown of everything
+
+ExitTimeout : Windows-only, sleeps 5 seconds then exits application
diff --git a/doc/readme-qt.rst b/doc/readme-qt.rst new file mode 100644 index 0000000000..b12aa30904 --- /dev/null +++ b/doc/readme-qt.rst @@ -0,0 +1,162 @@ +Bitcoin-qt: Qt4 based GUI replacement for Bitcoin +================================================= + +Features +======== + +- All functionality of the Wx GUI, including wallet encryption + +- Compatibility with Linux (both GNOME and KDE), MacOSX and Windows + +- Notification on incoming / outgoing transactions (compatible with FreeDesktop and other desktop notification schemes) + +- General interface improvements: Splash screen, tabbed interface + +- Overview page with current balance, unconfirmed balance, and such + +- Better transaction list with status icons, real-time filtering and a context menu + +- Asks for confirmation before sending coins, for your own safety + +- CSV export of transactions and address book (for Excel bookkeeping) + +- Shows alternative icon when connected to testnet, so you never accidentally send real coins during testing + +- Shows a progress bar on initial block download, so that you don't have to wonder how many blocks it needs to download to be up to date + +- Sendmany support, send to multiple recipients at the same time + +- Multiple unit support, can show subdivided bitcoins (uBTC, mBTC) for users that like large numbers + +- Support for English, German, Russian and Dutch languages + +- Address books and transaction table can be sorted by any column + +- Accepts "bitcoin:" URLs from browsers and other sources through drag and drop + +Build instructions +=================== + +Debian +------- + +First, make sure that the required packages for Qt4 development of your +distribution are installed, for Debian and Ubuntu these are: + +:: + + apt-get install qt4-qmake libqt4-dev build-essential libboost-dev libboost-system-dev \ + libboost-filesystem-dev libboost-program-options-dev libboost-thread-dev \ + libssl-dev libdb4.8++-dev + +then execute the following: + +:: + + qmake + make + +Alternatively, install Qt Creator and open the `bitcoin-qt.pro` file. + +An executable named `bitcoin-qt` will be built. + + +Windows +-------- + +Windows build instructions: + +- Download the `QT Windows SDK`_ and install it. You don't need the Symbian stuff, just the desktop Qt. + +- Download and extract the `dependencies archive`_ [#]_, or compile openssl, boost and dbcxx yourself. + +- Copy the contents of the folder "deps" to "X:\\QtSDK\\mingw", replace X:\\ with the location where you installed the Qt SDK. Make sure that the contents of "deps\\include" end up in the current "include" directory. + +- Open the .pro file in QT creator and build as normal (ctrl-B) + +.. _`QT Windows SDK`: http://qt.nokia.com/downloads/sdk-windows-cpp +.. _`dependencies archive`: https://download.visucore.com/bitcoin/qtgui_deps_1.zip +.. [#] PGP signature: https://download.visucore.com/bitcoin/qtgui_deps_1.zip.sig (signed with RSA key ID `610945D0`_) +.. _`610945D0`: http://pgp.mit.edu:11371/pks/lookup?op=get&search=0x610945D0 + + +Mac OS X +-------- + +- Download and install the `Qt Mac OS X SDK`_. It is recommended to also install Apple's Xcode with UNIX tools. + +- Download and install `MacPorts`_. + +- Execute the following commands in a terminal to get the dependencies: + +:: + + sudo port selfupdate + sudo port install boost db48 + +- Open the .pro file in Qt Creator and build as normal (cmd-B) + +.. _`Qt Mac OS X SDK`: http://qt.nokia.com/downloads/sdk-mac-os-cpp +.. _`MacPorts`: http://www.macports.org/install.php + + +Build configuration options +============================ + +UPNnP port forwarding +--------------------- + +To use UPnP for port forwarding behind a NAT router (recommended, as more connections overall allow for a faster and more stable bitcoin experience), pass the following argument to qmake: + +:: + + qmake "USE_UPNP=1" + +(in **Qt Creator**, you can find the setting for additional qmake arguments under "Projects" -> "Build Settings" -> "Build Steps", then click "Details" next to **qmake**) + +This requires miniupnpc for UPnP port mapping. It can be downloaded from +http://miniupnp.tuxfamily.org/files/. UPnP support is not compiled in by default. + +Set USE_UPNP to a different value to control this: + ++------------+--------------------------------------------------------------+ +| USE_UPNP= | (the default) no UPnP support, miniupnpc not required; | ++------------+--------------------------------------------------------------+ +| USE_UPNP=0 | UPnP support turned off by default at runtime; | ++------------+--------------------------------------------------------------+ +| USE_UPNP=1 | UPnP support turned on by default at runtime. | ++------------+--------------------------------------------------------------+ + +Mac OS X users: miniupnpc is currently outdated on MacPorts. An updated Portfile is provided in contrib/miniupnpc within this project. +You can execute the following commands in a terminal to install it: + +:: + + cd <location of bitcoin-qt>/contrib/miniupnpc + sudo port install + +Notification support for recent (k)ubuntu versions +--------------------------------------------------- + +To see desktop notifications on (k)ubuntu versions starting from 10.04, enable usage of the +FreeDesktop notification interface through DBUS using the following qmake option: + +:: + + qmake "USE_DBUS=1" + +Berkely DB version warning +========================== + +A warning for people using the *static binary* version of Bitcoin on a Linux/UNIX-ish system (tl;dr: **Berkely DB databases are not forward compatible**). + +The static binary version of Bitcoin is linked against libdb4.7 or libdb4.8 (see also `this Debian issue`_). + +Now the nasty thing is that databases from 5.X are not compatible with 4.X. + +If the globally installed development package of Berkely DB installed on your system is 5.X, any source you +build yourself will be linked against that. The first time you run with a 5.X version the database will be upgraded, +and 4.X cannot open the new format. This means that you cannot go back to the old statically linked version without +significant hassle! + +.. _`this Debian issue`: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=621425 diff --git a/doc/release-process.txt b/doc/release-process.txt index 4940afefa5..4d06627006 100644 --- a/doc/release-process.txt +++ b/doc/release-process.txt @@ -1,6 +1,9 @@ * update (commit) version in sources + src/serialize.h + share/setup.nsi * update (commit) version in OSX app bundle + contrib/Bitcoin.app/Contents/Info.plist * CFBundleShortVersionString should have value like 0.3.23 * CFBundleVersion should have value like 323 @@ -20,15 +23,45 @@ * perform gitian builds - * From the bitcoin source dir - $ cd ../gitian-builder - $ ./bin/gbuild --commit bitcoin=v0.3.23 ../bitcoin/contrib/gitian.yml - $ ./bin/gbuild --commit bitcoin=v0.3.23 ../bitcoin/contrib/gitian-win32.yml + * From a directory containing the bitcoin source, gitian-builder and gitian.sigs + $ export VERSION=0.3.23 + $ cd ./gitian-builder + $ ./bin/gbuild --commit bitcoin=v$VERSION ../bitcoin/contrib/gitian-descriptors/gitian.yml + $ ./bin/gsign --signer (your gitian key, ie bluematt, sipa, etc) --release $VERSION --destination ../gitian.sigs/ ../bitcoin/contrib/gitian-descriptors/gitian.yml + $ cd build/out + $ zip bitcoin-$VERSION-linux-gitian.zip * + $ mv bitcoin-$VERSION-linux-gitian.zip ../../ + $ ./bin/gbuild --commit bitcoin=v$VERSION ../bitcoin/contrib/gitian-descriptors/gitian-win32.yml + $ ./bin/gsign --signer (your gitian key, ie bluematt, sipa, etc) --release $VERSION-win32 --destination ../gitian.sigs/ ../bitcoin/contrib/gitian-descriptors/gitian-win32.yml + $ cd build/out + $ zip bitcoin-$VERSION-win32-gitian.zip * + $ mv bitcoin-$VERSION-win32-gitian.zip ../../ Build output expected: - 1. linux 32-bit and 64-bit binaries + source - 2. windows 32-bit binary + source - 3. windows installer + 1. linux 32-bit and 64-bit binaries + source (bitcoin-$VERSION-linux-gitian.zip) + 2. windows 32-bit binary, installer + source (bitcoin-$VERSION-win32-gitian.zip) + 3. Gitian signatures (in gitian.sigs/$VERSION[-win32]/(your gitian key)/ + +* repackage gitian builds for release as stand-alone zip/tar/installer exe + + * Windows .zip and setup.exe: + $ mkdir bitcoin-$VERSION-win32 + $ cd bitcoin-$VERSION-win32 + $ unzip bitcoin-$VERSION-win32-gitian.zip + $ mv bitcoin-$VERSION-win32-setup.exe .. + $ cd ..; zip bitcoin-$VERSION-win32.zip bitcoin-$VERSION-win32 + + * Linux .tar.gz: + $ mkdir bitcoin-$VERSION-linux + $ cd bitcoin-$VERSION-linux + $ unzip bitcoin-$VERSION-linux-gitian.zip + $ cd ..; tar czvf bitcoin-$VERSION-linux.tar.gz bitcoin-$VERSION-linux + +* perform Mac build + * From the bitcoin source dir + $ cd contrib + $ ./create_osx_dmg.sh + $ mv Bitcoin.dmg bitcoin-$VERSION-macosx.dmg * upload source and builds to SF @@ -42,4 +75,34 @@ * update wiki download links +* release gitian-signed gitian archives + + * Collect enough gitian signatures to meet minimum_weight (see contrib/gitian-downloader/*-download-config) + + * From a directory containing bitcoin source, gitian.sigs and gitian zips + $ export VERSION=0.3.23 + $ mkdir bitcoin-$VERSION-win32-gitian; cd bitcoin-$VERSION-win32-gitian + $ unzip ../bitcoin-$VERSION-win32-gitian.zip + $ mkdir gitian + $ cp ../bitcoin/contrib/gitian-downloader/*.pgp ./gitian/ + $ for file in `ls ../gitian.sigs/$VERSION-win32/`; do + $ cp ../gitian.sigs/$VERSION-win32/$file/bitcoin-build.assert ./gitian/$file-build.assert + $ cp ../gitian.sigs/$VERSION-win32/$file/bitcoin-build.assert.sig ./gitian/$file-build.assert.sig + $ done + $ zip bitcoin-$VERSION-win32-gitian.zip * + $ cp bitcoin-$VERSION-win32-gitian.zip ../ + $ cd .. + $ mkdir bitcoin-$VERSION-linux-gitian; cd bitcoin-$VERSION-linux-gitian + $ unzip ../bitcoin-$VERSION-linux-gitian.zip + $ mkdir gitian + $ cp ../bitcoin/contrib/gitian-downloader/*.pgp ./gitian/ + $ for file in `ls ../gitian.sigs/$VERSION/`; do + $ cp ../gitian.sigs/$VERSION/$file/bitcoin-build.assert ./gitian/$file-build.assert + $ cp ../gitian.sigs/$VERSION/$file/bitcoin-build.assert.sig ./gitian/$file-build.assert.sig + $ done + $ zip bitcoin-$VERSION-linux-gitian.zip * + $ cp bitcoin-$VERSION-linux-gitian.zip ../ + + * Upload gitian zips to SF + diff --git a/locale/cs/LC_MESSAGES/bitcoin.mo b/locale/cs/LC_MESSAGES/bitcoin.mo Binary files differindex 80354cf764..8b6e444b66 100644 --- a/locale/cs/LC_MESSAGES/bitcoin.mo +++ b/locale/cs/LC_MESSAGES/bitcoin.mo diff --git a/locale/cs/LC_MESSAGES/bitcoin.po b/locale/cs/LC_MESSAGES/bitcoin.po index 51fe18297c..2275d901bf 100644 --- a/locale/cs/LC_MESSAGES/bitcoin.po +++ b/locale/cs/LC_MESSAGES/bitcoin.po @@ -5,8 +5,8 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2011-05-26 21:44+0200\n" -"PO-Revision-Date: 2011-05-26 22:31+0100\n" +"POT-Creation-Date: 2011-08-16 15:51+0100\n" +"PO-Revision-Date: 2011-08-16 16:03+0100\n" "Last-Translator: xHire <xhire@mujmalysvet.cz>\n" "Language-Team: \n" "Language: cs\n" @@ -17,114 +17,541 @@ msgstr "" "X-Poedit-Basepath: .\n" "X-Poedit-SearchPath-0: ../../..\n" -#: ../../../src/net.cpp:1503 +#: ../../../src/uibase.cpp:25 +#: ../../../src/ui.cpp:2985 +msgid "E&xit" +msgstr "&Konec" + +#: ../../../src/uibase.cpp:28 +msgid "&File" +msgstr "&Soubor" + +#: ../../../src/uibase.cpp:32 +msgid "&Your Receiving Addresses..." +msgstr "Tvá Bitcoinová &adresa..." + +#: ../../../src/uibase.cpp:35 +msgid "&Encrypt Wallet..." +msgstr "&Zašifruj peněženku..." + +#: ../../../src/uibase.cpp:38 +msgid "&Change Wallet Encryption Passphrase..." +msgstr "Změň &heslo pro šifrování peněženky..." + +#: ../../../src/uibase.cpp:42 +msgid "&Options..." +msgstr "M&ožnosti" + +#: ../../../src/uibase.cpp:45 +msgid "&Settings" +msgstr "Nas&tavení" + +#: ../../../src/uibase.cpp:49 +msgid "&About..." +msgstr "&O programu" + +#: ../../../src/uibase.cpp:52 +msgid "&Help" +msgstr "&Nápověda" + +#: ../../../src/uibase.cpp:61 +#: ../../../src/ui.cpp:2143 +#: ../../../src/ui.cpp:2148 +#: ../../../src/ui.cpp:2153 +#: ../../../src/ui.cpp:2202 +msgid "Send Coins" +msgstr "Pošli mince" + +#: ../../../src/uibase.cpp:62 +msgid "Address Book" +msgstr "Adresář" + +#: ../../../src/uibase.cpp:75 +msgid "Your Bitcoin Address:" +msgstr "Tvá Bitcoinová adresa:" + +#: ../../../src/uibase.cpp:82 +msgid " &New... " +msgstr " &Nová..." + +#: ../../../src/uibase.cpp:85 +#: ../../../src/uibase.cpp:790 +#: ../../../src/uibase.cpp:893 +msgid " &Copy to Clipboard " +msgstr " &Kopírovat do schránky" + +#: ../../../src/uibase.cpp:99 +msgid "Balance:" +msgstr "Stav účtu:" + +#: ../../../src/uibase.cpp:115 +msgid " All" +msgstr " Vše" + +#: ../../../src/uibase.cpp:115 +msgid " Sent" +msgstr " Odeslané" + +#: ../../../src/uibase.cpp:115 +msgid " Received" +msgstr " Přijaté" + +#: ../../../src/uibase.cpp:115 +msgid " In Progress" +msgstr " Pracuje se na tom" + +#: ../../../src/uibase.cpp:136 +msgid "All Transactions" +msgstr "Všechny transakce" + +#: ../../../src/uibase.cpp:147 +msgid "Sent/Received" +msgstr "Odeslané/Přijaté" + +#: ../../../src/uibase.cpp:158 +msgid "Sent" +msgstr "Odeslané" + +#: ../../../src/uibase.cpp:169 +msgid "Received" +msgstr "Přijaté" + +#: ../../../src/uibase.cpp:312 +#: ../../../src/uibase.cpp:453 +#: ../../../src/uibase.cpp:552 +#: ../../../src/uibase.cpp:732 +#: ../../../src/uibase.cpp:793 +#: ../../../src/uibase.cpp:902 +#: ../../../src/uibase.cpp:991 +msgid "OK" +msgstr "&Budiž" + +#: ../../../src/uibase.cpp:355 +msgid "&Start Bitcoin on system startup" +msgstr "&Spustit Bitcoin při startu systému" + +#: ../../../src/uibase.cpp:358 +msgid "&Minimize to the tray instead of the taskbar" +msgstr "&Minimalizovávat do ikony v panelu" + +#: ../../../src/uibase.cpp:361 +msgid "Map port using &UPnP" +msgstr "Namapovat port přes &UPnP" + +#: ../../../src/uibase.cpp:364 +msgid "M&inimize to the tray on close" +msgstr "Zavřením &minimalizovat do ikony" + +#: ../../../src/uibase.cpp:370 +msgid "&Connect through socks4 proxy (requires restart to apply): " +msgstr "&Připojit přes socks4 proxy (vyžaduje restart aplikace):" + +#: ../../../src/uibase.cpp:381 +msgid "Proxy &IP:" +msgstr "&IP adresa proxy:" + +#: ../../../src/uibase.cpp:389 +msgid " &Port:" +msgstr " &Port:" + +#: ../../../src/uibase.cpp:402 +msgid "Optional transaction fee per KB that helps make sure your transactions are processed quickly. Most transactions are 1KB. Fee 0.01 recommended." +msgstr "Dobrovolný transakční poplatek za každý započatý KB napomáhá tomu, aby tvé transakce byly rychle zpracovány. Většina transakcí má do 1 KB. Doporučená výše poplatku je 0.01." + +#: ../../../src/uibase.cpp:409 +msgid "Pay transaction fee:" +msgstr "Výše transakčního poplatku:" + +#: ../../../src/uibase.cpp:430 +msgid "// [don't translate] Test panel 2 for future expansion" +msgstr "" + +#: ../../../src/uibase.cpp:434 +msgid "// [don't translate] Let's not start multiple pages until the first page is filled up" +msgstr "" + +#: ../../../src/uibase.cpp:456 +#: ../../../src/uibase.cpp:678 +#: ../../../src/uibase.cpp:737 +#: ../../../src/uibase.cpp:796 +#: ../../../src/uibase.cpp:905 +#: ../../../src/uibase.cpp:994 +msgid "Cancel" +msgstr "&Zrušit" + +#: ../../../src/uibase.cpp:459 +msgid "&Apply" +msgstr "&Použít" + +#: ../../../src/uibase.cpp:518 +msgid "Bitcoin " +msgstr "Bitcoin" + +#: ../../../src/uibase.cpp:524 +msgid "version" +msgstr "verze" + +#: ../../../src/uibase.cpp:535 +msgid "" +"Copyright (c) 2009-2011 Bitcoin Developers\n" +"\n" +"This is experimental software.\n" +"\n" +"Distributed under the MIT/X11 software license, see the accompanying file \n" +"license.txt or http://www.opensource.org/licenses/mit-license.php.\n" +"\n" +"This product includes software developed by the OpenSSL Project for use in the \n" +"OpenSSL Toolkit (http://www.openssl.org/) and cryptographic software written by \n" +"Eric Young (eay@cryptsoft.com) and UPnP software written by Thomas Bernard." +msgstr "" +"Copyright (c) 2009-2011 Vývojáři Bitcoinu\n" +"\n" +"Tohle je experimentální program.\n" +"\n" +"Šířen pod licencí MIT/X11, viz přiložený soubor license.txt nebo \n" +"http://www.opensource.org/licenses/mit-license.php.\n" +"\n" +"Tento produkt zahrnuje programy vyvinuté OpenSSL Projektem pro použití \n" +"v OpenSSL Toolkitu (http://www.openssl.org/) a kryptografický program od \n" +"Erika Younga (eay@cryptsoft.com) a program UPnP od Thomase Bernarda." + +#: ../../../src/uibase.cpp:591 +msgid "Enter a Bitcoin address (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L)" +msgstr "Vlož Bitcoinovou adresu (např. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L)" + +#: ../../../src/uibase.cpp:605 +msgid "Pay &To:" +msgstr "&Komu:" + +#: ../../../src/uibase.cpp:620 +msgid "&Paste" +msgstr "&Vložit" + +#: ../../../src/uibase.cpp:623 +msgid " Address &Book..." +msgstr " &Adresář..." + +#: ../../../src/uibase.cpp:630 +msgid "&Amount:" +msgstr "&Částka" + +#: ../../../src/uibase.cpp:640 +msgid "T&ransfer:" +msgstr "&Převod:" + +#: ../../../src/uibase.cpp:646 +msgid " Standard" +msgstr " Standard" + +#: ../../../src/uibase.cpp:673 +msgid "&Send" +msgstr "&Poslat" + +#: ../../../src/uibase.cpp:721 +msgid "" +"\n" +"\n" +"Connecting..." +msgstr "" +"\n" +"\n" +"Připojuji..." + +#: ../../../src/uibase.cpp:771 +msgid "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. The highlighted address is displayed in the main window." +msgstr "Tohle jsou tvé Bitcoinové adresy na příjem plateb. Asi budeš chtít dát jinou adresu každému odesílateli, abys věděl, kdo ti kolik platil. Označená adresa bude zobrazena v hlavním okně." + +#: ../../../src/uibase.cpp:784 +#: ../../../src/uibase.cpp:896 +msgid "&Edit..." +msgstr "&Upravit..." + +#: ../../../src/uibase.cpp:787 +#: ../../../src/uibase.cpp:899 +msgid " &New Address... " +msgstr " &Nová adresa..." + +#: ../../../src/uibase.cpp:847 +#: ../../../src/ui.cpp:2620 +msgid "Bitcoin Address" +msgstr "Bitcoinová adresa" + +#: ../../../src/uibase.cpp:859 +msgid "Sending" +msgstr "Cizí adresy (pro odesílání)" + +#: ../../../src/uibase.cpp:867 +msgid "These are your Bitcoin addresses for receiving payments. You can give a different one to each sender to keep track of who is paying you. The highlighted address will be displayed in the main window." +msgstr "Tohle jsou tvé Bitcoinové adresy na příjem plateb. Můžeš dát jinou adresu každému odesílateli, abys věděl, kdo ti kolik platil. Označená adresa bude zobrazena v hlavním okně." + +#: ../../../src/uibase.cpp:880 +msgid "Receiving" +msgstr "Tvoje adresy (pro příjem)" + +#: ../../../src/uibase.cpp:890 +msgid "&Delete" +msgstr "&Smazat" + +#: ../../../src/rpc.cpp:2088 +#: ../../../src/rpc.cpp:2090 #, c-format -msgid "Unable to bind to port %d on this computer. Bitcoin is probably already running." -msgstr "Nedaří se mi připojit na port %d na tomhle počítači. Bitcoin už pravděpodobně jednou běží." +msgid "To use the %s option" +msgstr "Pro použití volby %s" + +#: ../../../src/rpc.cpp:2092 +#, c-format +msgid "" +"Warning: %s, you must set rpcpassword=<password>\n" +"in the configuration file: %s\n" +"If the file does not exist, create it with owner-readable-only file permissions.\n" +msgstr "" +"Varování: %s, musíš nastavit rpcpassword=<heslo>\n" +"v konfiguračním souboru: %s\n" +"Pokud tenhle soubor neexistuje, vytvoř ho s oprávněním pro čtení pouze pro vlastníka.\n" -#: ../../../src/ui.cpp:204 +#: ../../../src/rpc.cpp:2265 +#, c-format +msgid "" +"You must set rpcpassword=<password> in the configuration file:\n" +"%s\n" +"If the file does not exist, create it with owner-readable-only file permissions." +msgstr "" +"Musíš nastavit rpcpassword=<heslo> v konfiguračním souboru:\n" +"%s\n" +"Pokud tenhle soubor neexistuje, vytvoř ho s oprávněním pro čtení pouze pro vlastníka." + +#: ../../../src/util.cpp:870 +msgid "Warning: Please check that your computer's date and time are correct. If your clock is wrong Bitcoin will not work properly." +msgstr "Varování: Prosím zkontroluj, že datum a čas jsou na tvém počítači správně nastaveny. Pokud jsou nastaveny špatně, Bitcoin nebude fungovat správně." + +#: ../../../src/util.cpp:904 +msgid "beta" +msgstr "beta" + +#: ../../../src/wallet.cpp:1084 +msgid "Error: Wallet locked, unable to create transaction " +msgstr "Chyba: Peněženka je zamčená, takže není možné vytvořit transakci" + +#: ../../../src/wallet.cpp:1092 +#, c-format +msgid "Error: This transaction requires a transaction fee of at least %s because of its amount, complexity, or use of recently received funds " +msgstr "Chyba: Tato transakce vyžaduje transakční poplatek nejméně %s kvůli svému objemu, komplexnosti nebo utrácení nedávno přijaté hotovosti" + +#: ../../../src/wallet.cpp:1094 +msgid "Error: Transaction creation failed " +msgstr "Chyba: Vytvoření transakce selhalo" + +#: ../../../src/wallet.cpp:1100 +#: ../../../src/ui.cpp:2176 +#: ../../../src/ui.cpp:2185 +#: ../../../src/ui.cpp:2336 +#: ../../../src/ui.cpp:2500 +msgid "Sending..." +msgstr "Posílám..." + +#: ../../../src/wallet.cpp:1104 +msgid "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." +msgstr "Chyba: Transakce byla odmítnuta. Tohle může nastat, pokud nějaké mince z tvé peněženky už jednou byly utraceny, například pokud používáš kopii souboru wallet.dat a mince byly utraceny v druhé kopii, ale nebyly označeny jako utracené v této." + +#: ../../../src/wallet.cpp:1117 +msgid "Invalid amount" +msgstr "Neplatná částka" + +#: ../../../src/wallet.cpp:1119 +#: ../../../src/ui.cpp:2403 +#: ../../../src/ui.cpp:2474 +msgid "Insufficient funds" +msgstr "Nedostatek peněz" + +#: ../../../src/ui.cpp:217 #, c-format msgid "This transaction is over the size limit. You can still send it for a fee of %s, which goes to the nodes that process your transaction and helps to support the network. Do you want to pay the fee?" msgstr "Tahle transakce přesahuje velikostní limit. Pořád ji ale můžeš poslat, pokud za ni zaplatíš poplatek %s, který půjde uzlům, které tvou transakci zpracují, a navíc tak podpoříš síť. Chceš zaplatit poplatek?" -#: ../../../src/ui.cpp:303 +#: ../../../src/ui.cpp:261 +#: ../../../src/ui.cpp:1247 +msgid "Enter the current passphrase to the wallet." +msgstr "Zadej platné heslo pro peněženku." + +#: ../../../src/ui.cpp:262 +#: ../../../src/ui.cpp:1183 +#: ../../../src/ui.cpp:1200 +#: ../../../src/ui.cpp:1248 +#: ../../../src/ui.cpp:1274 +#: ../../../src/ui.cpp:1294 +msgid "Passphrase" +msgstr "Heslo" + +#: ../../../src/ui.cpp:268 +msgid "Please supply the current wallet decryption passphrase." +msgstr "Zadej platné heslo pro dešifrování peněženky." + +#: ../../../src/ui.cpp:276 +#: ../../../src/ui.cpp:1259 +#: ../../../src/ui.cpp:1316 +msgid "The passphrase entered for the wallet decryption was incorrect." +msgstr "Nezadal jsi správné heslo pro dešifrování peněženky." + +#: ../../../src/ui.cpp:353 msgid "Status" msgstr "Stav" -#: ../../../src/ui.cpp:304 +#: ../../../src/ui.cpp:354 msgid "Date" msgstr "Datum" -#: ../../../src/ui.cpp:305 +#: ../../../src/ui.cpp:355 msgid "Description" msgstr "Popis" -#: ../../../src/ui.cpp:306 +#: ../../../src/ui.cpp:356 msgid "Debit" msgstr "Výdaje" -#: ../../../src/ui.cpp:307 +#: ../../../src/ui.cpp:357 msgid "Credit" msgstr "Příjmy" -#: ../../../src/ui.cpp:513 +#: ../../../src/ui.cpp:568 #, c-format msgid "Open for %d blocks" msgstr "Otevřeno pro %d bloků" -#: ../../../src/ui.cpp:515 +#: ../../../src/ui.cpp:570 #, c-format msgid "Open until %s" msgstr "Otřevřeno dokud %s" -#: ../../../src/ui.cpp:521 +#: ../../../src/ui.cpp:576 #, c-format msgid "%d/offline?" msgstr "%d/offline?" -#: ../../../src/ui.cpp:523 +#: ../../../src/ui.cpp:578 #, c-format msgid "%d/unconfirmed" msgstr "%d/nepotvrzeno" -#: ../../../src/ui.cpp:525 +#: ../../../src/ui.cpp:580 #, c-format msgid "%d confirmations" msgstr "%d potvrzení" -#: ../../../src/ui.cpp:610 +#: ../../../src/ui.cpp:665 msgid "Generated" msgstr "Vygenerováno" -#: ../../../src/ui.cpp:618 +#: ../../../src/ui.cpp:673 #, c-format msgid "Generated (%s matures in %d more blocks)" msgstr "Vygenerováno (%s dozraje po %d blocích)" -#: ../../../src/ui.cpp:622 +#: ../../../src/ui.cpp:677 msgid "Generated - Warning: This block was not received by any other nodes and will probably not be accepted!" msgstr "Vygenerovaný - Varování: Tehnle blok nebyl obdržen žádným jiným uzlem a pravděpodobně nebude akceptován!" -#: ../../../src/ui.cpp:626 +#: ../../../src/ui.cpp:681 msgid "Generated (not accepted)" msgstr "Vygenerováno (neakceptováno)" -#: ../../../src/ui.cpp:636 +#: ../../../src/ui.cpp:691 msgid "From: " msgstr "Od: " -#: ../../../src/ui.cpp:660 +#: ../../../src/ui.cpp:715 msgid "Received with: " msgstr "Přijato adresou: " -#: ../../../src/ui.cpp:706 +#: ../../../src/ui.cpp:760 msgid "Payment to yourself" msgstr "Platba pro sebe sama" -#: ../../../src/ui.cpp:740 +#: ../../../src/ui.cpp:794 msgid "To: " msgstr "Pro: " -#: ../../../src/ui.cpp:1055 +#: ../../../src/ui.cpp:1109 msgid " Generating" msgstr " Generuji" -#: ../../../src/ui.cpp:1057 +#: ../../../src/ui.cpp:1111 msgid "(not connected)" msgstr "(nepřipojen)" -#: ../../../src/ui.cpp:1060 +#: ../../../src/ui.cpp:1114 #, c-format msgid " %d connections %d blocks %d transactions" msgstr " %d spojení %d bloků %d transakcí" -#: ../../../src/ui.cpp:1165 -#: ../../../src/ui.cpp:2529 +#: ../../../src/ui.cpp:1171 +msgid "Wallet already encrypted." +msgstr "Peněženka je už zašifrovaná." + +#: ../../../src/ui.cpp:1182 +msgid "" +"Enter the new passphrase to the wallet.\n" +"Please use a passphrase of 10 or more random characters, or eight or more words." +msgstr "" +"Zadej nové heslo pro peněženku.\n" +"Použij alespoň 10 náhodných znaků nebo alespoň 8 slov." + +#: ../../../src/ui.cpp:1189 +#: ../../../src/ui.cpp:1282 +msgid "Error: The supplied passphrase was too short." +msgstr "Chyba: Zadané heslo je příliš krátké." + +#: ../../../src/ui.cpp:1193 +msgid "" +"WARNING: If you encrypt your wallet and lose your passphrase, you will LOSE ALL OF YOUR BITCOINS!\n" +"Are you sure you wish to encrypt your wallet?" +msgstr "" +"VAROVÁNÍ: Pokud zašifruješ peněženku a ztratíš či zapomeneš heslo, PŘIJDEŠ O VŠECHNY BITCOINY!\n" +"Jsi si jistý, že chceš peněženku zašifrovat?" + +#: ../../../src/ui.cpp:1199 +msgid "Please re-enter your new wallet passphrase." +msgstr "Zadej ještě jednou nové heslo pro peněženku." + +#: ../../../src/ui.cpp:1208 +#: ../../../src/ui.cpp:1304 +msgid "Error: the supplied passphrases didn't match." +msgstr "Chyba: zadaná hesla nejsou shodná." + +#: ../../../src/ui.cpp:1218 +msgid "Wallet encryption failed." +msgstr "Zašifrování peněženky selhalo." + +#: ../../../src/ui.cpp:1225 +msgid "" +"Wallet Encrypted.\n" +"Remember that encrypting your wallet cannot fully protect your bitcoins from being stolen by malware infecting your computer." +msgstr "" +"Peněženka je zašifrována.\n" +"Pamatuj, že pouhé šifrování peněženky nemůže plně ochránit tvé bitcoiny před krádeží malwarem, kterým se může počítač nakazit." + +#: ../../../src/ui.cpp:1236 +msgid "Wallet is unencrypted, please encrypt it first." +msgstr "Peněženka není zašifrovaná, musíš ji prvně zašifrovat." + +#: ../../../src/ui.cpp:1273 +msgid "Enter the new passphrase for the wallet." +msgstr "Zadej nové heslo pro peněženku." + +#: ../../../src/ui.cpp:1293 +msgid "Re-enter the new passphrase for the wallet." +msgstr "Zadej ještě jednou nové heslo pro peněženku." + +#: ../../../src/ui.cpp:1325 +msgid "Wallet Passphrase Changed." +msgstr "Heslo peněženky bylo změněno." + +#: ../../../src/ui.cpp:1382 +#: ../../../src/ui.cpp:2815 msgid "New Receiving Address" msgstr "Nová Bitcoinová adresa" -#: ../../../src/ui.cpp:1166 -#: ../../../src/ui.cpp:2530 +#: ../../../src/ui.cpp:1383 +#: ../../../src/ui.cpp:2816 msgid "" "You should use a new address for each payment you receive.\n" "\n" @@ -134,248 +561,226 @@ msgstr "" "\n" "Označení" -#: ../../../src/ui.cpp:1235 +#: ../../../src/ui.cpp:1467 msgid "<b>Status:</b> " msgstr "<b>Stav:</b> " -#: ../../../src/ui.cpp:1240 +#: ../../../src/ui.cpp:1472 msgid ", has not been successfully broadcast yet" msgstr ", ještě nebylo rozesláno" -#: ../../../src/ui.cpp:1242 +#: ../../../src/ui.cpp:1474 #, c-format msgid ", broadcast through %d node" msgstr ", rozesláno přes %d uzel" -#: ../../../src/ui.cpp:1244 +#: ../../../src/ui.cpp:1476 #, c-format msgid ", broadcast through %d nodes" msgstr ", rozesláno přes %d uzlů" -#: ../../../src/ui.cpp:1248 +#: ../../../src/ui.cpp:1480 msgid "<b>Date:</b> " msgstr "<b>Datum:</b> " -#: ../../../src/ui.cpp:1256 +#: ../../../src/ui.cpp:1488 msgid "<b>Source:</b> Generated<br>" msgstr "<b>Zdroj:</b> Vygenerováno<br>" -#: ../../../src/ui.cpp:1262 -#: ../../../src/ui.cpp:1280 +#: ../../../src/ui.cpp:1494 +#: ../../../src/ui.cpp:1511 msgid "<b>From:</b> " msgstr "<b>Od:</b> " -#: ../../../src/ui.cpp:1280 +#: ../../../src/ui.cpp:1511 msgid "unknown" msgstr "neznámo" -#: ../../../src/ui.cpp:1281 -#: ../../../src/ui.cpp:1305 -#: ../../../src/ui.cpp:1364 +#: ../../../src/ui.cpp:1512 +#: ../../../src/ui.cpp:1536 +#: ../../../src/ui.cpp:1595 msgid "<b>To:</b> " msgstr "<b>Pro:</b> " -#: ../../../src/ui.cpp:1284 +#: ../../../src/ui.cpp:1515 msgid " (yours, label: " msgstr " (tvoje, označení: " -#: ../../../src/ui.cpp:1286 +#: ../../../src/ui.cpp:1517 msgid " (yours)" msgstr " (tvoje)" -#: ../../../src/ui.cpp:1323 -#: ../../../src/ui.cpp:1335 -#: ../../../src/ui.cpp:1381 -#: ../../../src/ui.cpp:1398 +#: ../../../src/ui.cpp:1554 +#: ../../../src/ui.cpp:1566 +#: ../../../src/ui.cpp:1612 +#: ../../../src/ui.cpp:1629 msgid "<b>Credit:</b> " msgstr "<b>Příjem:</b> " -#: ../../../src/ui.cpp:1325 +#: ../../../src/ui.cpp:1556 #, c-format msgid "(%s matures in %d more blocks)" msgstr "(%s dozraje po %d blocích)" -#: ../../../src/ui.cpp:1327 +#: ../../../src/ui.cpp:1558 msgid "(not accepted)" msgstr "(neakceptováno)" -#: ../../../src/ui.cpp:1372 -#: ../../../src/ui.cpp:1380 -#: ../../../src/ui.cpp:1395 +#: ../../../src/ui.cpp:1603 +#: ../../../src/ui.cpp:1611 +#: ../../../src/ui.cpp:1626 msgid "<b>Debit:</b> " msgstr "<b>Výdaj:</b> " -#: ../../../src/ui.cpp:1386 +#: ../../../src/ui.cpp:1617 msgid "<b>Transaction fee:</b> " msgstr "<b>Transakční poplatek:</b> " -#: ../../../src/ui.cpp:1402 +#: ../../../src/ui.cpp:1633 msgid "<b>Net amount:</b> " msgstr "<b>Čistá částka:</b> " -#: ../../../src/ui.cpp:1409 +#: ../../../src/ui.cpp:1640 msgid "Message:" msgstr "Zpráva:" -#: ../../../src/ui.cpp:1411 +#: ../../../src/ui.cpp:1642 msgid "Comment:" msgstr "Komentář:" -#: ../../../src/ui.cpp:1414 +#: ../../../src/ui.cpp:1645 msgid "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 \"not accepted\" and not be spendable. This may occasionally happen if another node generates a block within a few seconds of yours." msgstr "Vygenerované mince musí čekat 120 bloků, než mohou být utraceny. Když jsi vygeneroval tenhle blok, tak byl rozposlán do sítě, aby byl přidán do řetězce bloků. Pokud se mu nepodaří dostat se do řetězce, změní se na \"neakceptovaný\" a nebude utratitelný. To se občas může přihodit, pokud jiný uzel vygeneruje blok zhruba ve stejném okamžiku jako ty." -#: ../../../src/ui.cpp:1594 +#: ../../../src/ui.cpp:1825 msgid "Cannot write autostart/bitcoin.desktop file" msgstr "Nemohu zapisovat do souboru autostart/bitcoin.desktop" -#: ../../../src/ui.cpp:1630 +#: ../../../src/ui.cpp:1861 msgid "Main" msgstr "Hlavní" -#: ../../../src/ui.cpp:1638 +#: ../../../src/ui.cpp:1871 msgid "&Start Bitcoin on window system startup" msgstr "&Spustit Bitcoin při startu okenního systému" -#: ../../../src/ui.cpp:1645 +#: ../../../src/ui.cpp:1878 msgid "&Minimize on close" msgstr "&Zavřením pouze skrýt" -#: ../../../src/ui.cpp:1787 +#: ../../../src/ui.cpp:2020 #, c-format msgid "version %s" msgstr "verze %s" -#: ../../../src/ui.cpp:1899 +#: ../../../src/ui.cpp:2143 msgid "Error in amount " msgstr "Chyba v částce" -#: ../../../src/ui.cpp:1899 -#: ../../../src/ui.cpp:1904 -#: ../../../src/ui.cpp:1909 -#: ../../../src/ui.cpp:1944 -#: ../../../src/uibase.cpp:55 -msgid "Send Coins" -msgstr "Pošli mince" - -#: ../../../src/ui.cpp:1904 +#: ../../../src/ui.cpp:2148 msgid "Amount exceeds your balance " msgstr "Částka překračuje stav účtu" -#: ../../../src/ui.cpp:1909 +#: ../../../src/ui.cpp:2153 msgid "Total exceeds your balance when the " msgstr "Celková částka přesahuje stav tvého účtu, když " -#: ../../../src/ui.cpp:1909 +#: ../../../src/ui.cpp:2153 msgid " transaction fee is included " msgstr " transakční poplatek je zahrnut" -#: ../../../src/ui.cpp:1927 +#: ../../../src/ui.cpp:2176 msgid "Payment sent " msgstr "Platba odeslána" -#: ../../../src/ui.cpp:1927 -#: ../../../src/ui.cpp:1932 -#: ../../../src/ui.cpp:2076 -#: ../../../src/ui.cpp:2229 -#: ../../../src/main.cpp:3997 -msgid "Sending..." -msgstr "Posílám..." - -#: ../../../src/ui.cpp:1944 +#: ../../../src/ui.cpp:2202 msgid "Invalid address " msgstr "Neplatná adresa" -#: ../../../src/ui.cpp:1997 +#: ../../../src/ui.cpp:2257 #, c-format msgid "Sending %s to %s" msgstr "Posílám %s %s" -#: ../../../src/ui.cpp:2070 -#: ../../../src/ui.cpp:2103 +#: ../../../src/ui.cpp:2330 +#: ../../../src/ui.cpp:2363 msgid "CANCELLED" msgstr "ZRUŠENO" -#: ../../../src/ui.cpp:2074 +#: ../../../src/ui.cpp:2334 msgid "Cancelled" msgstr "Zrušeno" -#: ../../../src/ui.cpp:2076 +#: ../../../src/ui.cpp:2336 msgid "Transfer cancelled " msgstr "Převod zrušen" -#: ../../../src/ui.cpp:2129 +#: ../../../src/ui.cpp:2389 msgid "Error: " msgstr "Chyba: " -#: ../../../src/ui.cpp:2143 -#: ../../../src/ui.cpp:2214 -#: ../../../src/main.cpp:4016 -msgid "Insufficient funds" -msgstr "Nedostatek peněz" - -#: ../../../src/ui.cpp:2148 +#: ../../../src/ui.cpp:2408 msgid "Connecting..." msgstr "Připojuji..." -#: ../../../src/ui.cpp:2153 +#: ../../../src/ui.cpp:2413 msgid "Unable to connect" msgstr "Nemohu se připojit" -#: ../../../src/ui.cpp:2158 +#: ../../../src/ui.cpp:2418 msgid "Requesting public key..." msgstr "Požaduji veřejný klíč..." -#: ../../../src/ui.cpp:2170 +#: ../../../src/ui.cpp:2430 msgid "Received public key..." msgstr "Přijat veřejný klíč..." -#: ../../../src/ui.cpp:2184 +#: ../../../src/ui.cpp:2444 msgid "Recipient is not accepting transactions sent by IP address" msgstr "Příjemce neakceptuje transakce poslané IP adresou" -#: ../../../src/ui.cpp:2186 +#: ../../../src/ui.cpp:2446 msgid "Transfer was not accepted" msgstr "Převod nebyl akceptován" -#: ../../../src/ui.cpp:2195 +#: ../../../src/ui.cpp:2455 msgid "Invalid response received" msgstr "Přišla neplatná odpověď" -#: ../../../src/ui.cpp:2210 +#: ../../../src/ui.cpp:2470 msgid "Creating transaction..." msgstr "Vytvářím transakci..." -#: ../../../src/ui.cpp:2222 +#: ../../../src/ui.cpp:2489 #, c-format msgid "This transaction requires a transaction fee of at least %s because of its amount, complexity, or use of recently received funds" msgstr "Tato transakce vyžaduje transakční poplatek nejméně %s kvůli svému objemu, komplexnosti nebo utrácení nedávno přijaté hotovosti" -#: ../../../src/ui.cpp:2224 +#: ../../../src/ui.cpp:2491 msgid "Transaction creation failed" msgstr "Vytvoření transakce selhalo" -#: ../../../src/ui.cpp:2231 +#: ../../../src/ui.cpp:2502 msgid "Transaction aborted" msgstr "Transakce zrušena" -#: ../../../src/ui.cpp:2239 +#: ../../../src/ui.cpp:2510 msgid "Lost connection, transaction cancelled" msgstr "Spojení se ztratilo, takže transakce byla zrušena" -#: ../../../src/ui.cpp:2255 +#: ../../../src/ui.cpp:2526 msgid "Sending payment..." msgstr "Posílám platbu..." -#: ../../../src/ui.cpp:2261 +#: ../../../src/ui.cpp:2532 msgid "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." msgstr "Transakce byla odmítnuta. Tohle může nastat, pokud nějaké mince z tvé peněženky už jednou byly utraceny, například pokud používáš kopii souboru wallet.dat a mince byly utraceny v druhé kopii, ale nebyly označeny jako utracené v této." -#: ../../../src/ui.cpp:2270 +#: ../../../src/ui.cpp:2541 msgid "Waiting for confirmation..." msgstr "Čekám na potvrzení..." -#: ../../../src/ui.cpp:2288 +#: ../../../src/ui.cpp:2559 msgid "" "The payment was sent, but the recipient was unable to verify it.\n" "The transaction is recorded and will credit to the recipient,\n" @@ -385,518 +790,202 @@ msgstr "" "Transakce je zaznamenána a bude připsána příjemci,\n" "ale poznámka u platby bude prázdná." -#: ../../../src/ui.cpp:2297 +#: ../../../src/ui.cpp:2568 msgid "Payment was sent, but an invalid response was received" msgstr "Platba byla odeslána, ale přišla neplatná odpověď" -#: ../../../src/ui.cpp:2303 +#: ../../../src/ui.cpp:2574 msgid "Payment completed" msgstr "Platba je kompletní" -#: ../../../src/ui.cpp:2334 -#: ../../../src/ui.cpp:2480 -#: ../../../src/ui.cpp:2517 +#: ../../../src/ui.cpp:2616 +#: ../../../src/ui.cpp:2763 +#: ../../../src/ui.cpp:2803 msgid "Name" msgstr "Jméno" -#: ../../../src/ui.cpp:2335 -#: ../../../src/ui.cpp:2480 -#: ../../../src/ui.cpp:2517 +#: ../../../src/ui.cpp:2617 +#: ../../../src/ui.cpp:2763 +#: ../../../src/ui.cpp:2803 msgid "Address" msgstr "Adresa" -#: ../../../src/ui.cpp:2337 -#: ../../../src/ui.cpp:2492 +#: ../../../src/ui.cpp:2619 +#: ../../../src/ui.cpp:2775 msgid "Label" msgstr "Označení" -#: ../../../src/ui.cpp:2338 -#: ../../../src/uibase.cpp:837 -msgid "Bitcoin Address" -msgstr "Bitcoinová adresa" - -#: ../../../src/ui.cpp:2462 +#: ../../../src/ui.cpp:2745 msgid "This is one of your own addresses for receiving payments and cannot be entered in the address book. " msgstr "Tohle je jedna z tvých vlastních adres pro příjem plateb a nemůže být zadána do adresáře." -#: ../../../src/ui.cpp:2480 -#: ../../../src/ui.cpp:2486 +#: ../../../src/ui.cpp:2763 +#: ../../../src/ui.cpp:2769 msgid "Edit Address" msgstr "Upravit adresu" -#: ../../../src/ui.cpp:2492 +#: ../../../src/ui.cpp:2775 msgid "Edit Address Label" msgstr "Upravit označení adresy" -#: ../../../src/ui.cpp:2517 -#: ../../../src/ui.cpp:2523 +#: ../../../src/ui.cpp:2803 +#: ../../../src/ui.cpp:2809 msgid "Add Address" msgstr "Přidat adresu" -#: ../../../src/ui.cpp:2600 +#: ../../../src/ui.cpp:2897 msgid "Bitcoin" msgstr "Bitcoin" -#: ../../../src/ui.cpp:2602 +#: ../../../src/ui.cpp:2899 msgid "Bitcoin - Generating" msgstr "Bitcoin - Generování" -#: ../../../src/ui.cpp:2604 +#: ../../../src/ui.cpp:2901 msgid "Bitcoin - (not connected)" msgstr "Bitcoin - (nepřipojen)" -#: ../../../src/ui.cpp:2683 +#: ../../../src/ui.cpp:2980 msgid "&Open Bitcoin" msgstr "&Otevřít Bitcoin" -#: ../../../src/ui.cpp:2684 +#: ../../../src/ui.cpp:2981 msgid "&Send Bitcoins" msgstr "&Poslat Bitcoiny" -#: ../../../src/ui.cpp:2685 +#: ../../../src/ui.cpp:2982 msgid "O&ptions..." msgstr "&Možnosti..." -#: ../../../src/ui.cpp:2688 -#: ../../../src/uibase.cpp:25 -msgid "E&xit" -msgstr "&Konec" - -#: ../../../src/ui.cpp:2904 +#: ../../../src/ui.cpp:3211 msgid "Program has crashed and will terminate. " msgstr "Program havaroval a bude ukončen." -#: ../../../src/main.cpp:1866 -msgid "Warning: Disk space is low " -msgstr "Upozornění: Na disku je málo místa" - -#: ../../../src/main.cpp:3990 -#, c-format -msgid "Error: This transaction requires a transaction fee of at least %s because of its amount, complexity, or use of recently received funds " -msgstr "Chyba: Tato transakce vyžaduje transakční poplatek nejméně %s kvůli svému objemu, komplexnosti nebo utrácení nedávno přijaté hotovosti" - -#: ../../../src/main.cpp:3992 -msgid "Error: Transaction creation failed " -msgstr "Chyba: Vytvoření transakce selhalo" - -#: ../../../src/main.cpp:4001 -msgid "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." -msgstr "Chyba: Transakce byla odmítnuta. Tohle může nastat, pokud nějaké mince z tvé peněženky už jednou byly utraceny, například pokud používáš kopii souboru wallet.dat a mince byly utraceny v druhé kopii, ale nebyly označeny jako utracené v této." - -#: ../../../src/main.cpp:4014 -msgid "Invalid amount" -msgstr "Neplatná částka" - -#: ../../../src/main.cpp:4021 -msgid "Invalid bitcoin address" -msgstr "Neplatná Bitcoinová adresa" - -#: ../../../src/rpc.cpp:1802 -#: ../../../src/rpc.cpp:1804 -#, c-format -msgid "To use the %s option" -msgstr "Pro použití volby %s" - -#: ../../../src/rpc.cpp:1806 -#, c-format -msgid "" -"Warning: %s, you must set rpcpassword=<password>\n" -"in the configuration file: %s\n" -"If the file does not exist, create it with owner-readable-only file permissions.\n" -msgstr "" -"Varování: %s, musíš nastavit rpcpassword=<heslo>\n" -"v konfiguračním souboru: %s\n" -"Pokud tenhle soubor neexistuje, vytvoř ho s oprávněním pro čtení pouze pro vlastníka.\n" - -#: ../../../src/rpc.cpp:1974 -#, c-format -msgid "" -"You must set rpcpassword=<password> in the configuration file:\n" -"%s\n" -"If the file does not exist, create it with owner-readable-only file permissions." -msgstr "" -"Musíš nastavit rpcpassword=<heslo> v konfiguračním souboru:\n" -"%s\n" -"Pokud tenhle soubor neexistuje, vytvoř ho s oprávněním pro čtení pouze pro vlastníka." - -#: ../../../src/util.cpp:866 -msgid "Warning: Please check that your computer's date and time are correct. If your clock is wrong Bitcoin will not work properly." -msgstr "Varování: Prosím zkontroluj, že datum a čas jsou na tvém počítači správně nastaveny. Pokud jsou nastaveny špatně, Bitcoin nebude fungovat správně." - -#: ../../../src/util.cpp:899 -msgid "beta" -msgstr "beta" - -#: ../../../src/uibase.cpp:28 -msgid "&File" -msgstr "&Soubor" - -#: ../../../src/uibase.cpp:32 -msgid "&Your Receiving Addresses..." -msgstr "Tvá Bitcoinová &adresa..." - -#: ../../../src/uibase.cpp:36 -msgid "&Options..." -msgstr "M&ožnosti" - -#: ../../../src/uibase.cpp:39 -msgid "&Settings" -msgstr "Nas&tavení" - -#: ../../../src/uibase.cpp:43 -msgid "&About..." -msgstr "&O programu" - -#: ../../../src/uibase.cpp:46 -msgid "&Help" -msgstr "&Nápověda" - -#: ../../../src/uibase.cpp:56 -msgid "Address Book" -msgstr "Adresář" - -#: ../../../src/uibase.cpp:69 -msgid "Your Bitcoin Address:" -msgstr "Tvá Bitcoinová adresa:" - -#: ../../../src/uibase.cpp:76 -msgid " &New... " -msgstr " &Nová..." - -#: ../../../src/uibase.cpp:79 -#: ../../../src/uibase.cpp:780 -#: ../../../src/uibase.cpp:883 -msgid " &Copy to Clipboard " -msgstr " &Kopírovat do schránky" - -#: ../../../src/uibase.cpp:93 -msgid "Balance:" -msgstr "Stav účtu:" - -#: ../../../src/uibase.cpp:109 -msgid " All" -msgstr " Vše" - -#: ../../../src/uibase.cpp:109 -msgid " Sent" -msgstr " Odeslané" - -#: ../../../src/uibase.cpp:109 -msgid " Received" -msgstr " Přijaté" - -#: ../../../src/uibase.cpp:109 -msgid " In Progress" -msgstr " Pracuje se na tom" - -#: ../../../src/uibase.cpp:130 -msgid "All Transactions" -msgstr "Všechny transakce" - -#: ../../../src/uibase.cpp:141 -msgid "Sent/Received" -msgstr "Odeslané/Přijaté" - -#: ../../../src/uibase.cpp:152 -msgid "Sent" -msgstr "Odeslané" - -#: ../../../src/uibase.cpp:163 -msgid "Received" -msgstr "Přijaté" - -#: ../../../src/uibase.cpp:302 -#: ../../../src/uibase.cpp:443 -#: ../../../src/uibase.cpp:542 -#: ../../../src/uibase.cpp:722 -#: ../../../src/uibase.cpp:783 -#: ../../../src/uibase.cpp:892 -#: ../../../src/uibase.cpp:981 -msgid "OK" -msgstr "&Budiž" - -#: ../../../src/uibase.cpp:345 -msgid "&Start Bitcoin on system startup" -msgstr "&Spustit Bitcoin při startu systému" - -#: ../../../src/uibase.cpp:348 -msgid "&Minimize to the tray instead of the taskbar" -msgstr "&Minimalizovávat do ikony v panelu" - -#: ../../../src/uibase.cpp:351 -msgid "Map port using &UPnP" -msgstr "Namapovat port přes &UPnP" - -#: ../../../src/uibase.cpp:354 -msgid "M&inimize to the tray on close" -msgstr "Zavřením &minimalizovat do ikony" - -#: ../../../src/uibase.cpp:360 -msgid "&Connect through socks4 proxy: " -msgstr "&Připojit přes socks4 proxy:" - -#: ../../../src/uibase.cpp:371 -msgid "Proxy &IP:" -msgstr "&IP adresa proxy:" - -#: ../../../src/uibase.cpp:379 -msgid " &Port:" -msgstr " &Port:" - -#: ../../../src/uibase.cpp:392 -msgid "Optional transaction fee per KB that helps make sure your transactions are processed quickly. Most transactions are 1KB. Fee 0.01 recommended." -msgstr "Dobrovolný transakční poplatek za každý započatý KB napomáhá tomu, aby tvé transakce byly rychle zpracovány. Většina transakcí má do 1 KB. Doporučená výše poplatku je 0.01." - -#: ../../../src/uibase.cpp:399 -msgid "Pay transaction fee:" -msgstr "Výše transakčního poplatku:" - -#: ../../../src/uibase.cpp:420 -msgid "// [don't translate] Test panel 2 for future expansion" -msgstr "" - -#: ../../../src/uibase.cpp:424 -msgid "// [don't translate] Let's not start multiple pages until the first page is filled up" -msgstr "" - -#: ../../../src/uibase.cpp:446 -#: ../../../src/uibase.cpp:668 -#: ../../../src/uibase.cpp:727 -#: ../../../src/uibase.cpp:786 -#: ../../../src/uibase.cpp:895 -#: ../../../src/uibase.cpp:984 -msgid "Cancel" -msgstr "&Zrušit" - -#: ../../../src/uibase.cpp:449 -msgid "&Apply" -msgstr "&Použít" - -#: ../../../src/uibase.cpp:508 -msgid "Bitcoin " -msgstr "Bitcoin" - -#: ../../../src/uibase.cpp:514 -msgid "version" -msgstr "verze" - -#: ../../../src/uibase.cpp:525 -msgid "" -"Copyright (c) 2009-2011 Bitcoin Developers\n" -"\n" -"This is experimental software.\n" -"\n" -"Distributed under the MIT/X11 software license, see the accompanying file \n" -"license.txt or http://www.opensource.org/licenses/mit-license.php.\n" -"\n" -"This product includes software developed by the OpenSSL Project for use in the \n" -"OpenSSL Toolkit (http://www.openssl.org/) and cryptographic software written by \n" -"Eric Young (eay@cryptsoft.com) and UPnP software written by Thomas Bernard." -msgstr "" -"Copyright (c) 2009-2011 Vývojáři Bitcoinu\n" -"\n" -"Tohle je experimentální program.\n" -"\n" -"Šířen pod licencí MIT/X11, viz přiložený soubor license.txt nebo \n" -"http://www.opensource.org/licenses/mit-license.php.\n" -"\n" -"Tento produkt zahrnuje programy vyvinuté OpenSSL Projektem pro použití \n" -"v OpenSSL Toolkitu (http://www.openssl.org/) a kryptografický program od \n" -"Erika Younga (eay@cryptsoft.com) a program UPnP od Thomase Bernarda." - -#: ../../../src/uibase.cpp:581 -msgid "Enter a Bitcoin address (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L)" -msgstr "Vlož Bitcoinovou adresu (např. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L)" - -#: ../../../src/uibase.cpp:595 -msgid "Pay &To:" -msgstr "&Komu:" - -#: ../../../src/uibase.cpp:610 -msgid "&Paste" -msgstr "&Vložit" - -#: ../../../src/uibase.cpp:613 -msgid " Address &Book..." -msgstr " &Adresář..." - -#: ../../../src/uibase.cpp:620 -msgid "&Amount:" -msgstr "&Částka" - -#: ../../../src/uibase.cpp:630 -msgid "T&ransfer:" -msgstr "&Převod:" - -#: ../../../src/uibase.cpp:636 -msgid " Standard" -msgstr " Standard" - -#: ../../../src/uibase.cpp:663 -msgid "&Send" -msgstr "&Poslat" - -#: ../../../src/uibase.cpp:711 -msgid "" -"\n" -"\n" -"Connecting..." -msgstr "" -"\n" -"\n" -"Připojuji..." - -#: ../../../src/uibase.cpp:761 -msgid "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. The highlighted address is displayed in the main window." -msgstr "Tohle jsou tvé Bitcoinové adresy na příjem plateb. Asi budeš chtít dát jinou adresu každému odesílateli, abys věděl, kdo ti kolik platil. Označená adresa bude zobrazena v hlavním okně." - -#: ../../../src/uibase.cpp:774 -#: ../../../src/uibase.cpp:886 -msgid "&Edit..." -msgstr "&Upravit..." - -#: ../../../src/uibase.cpp:777 -#: ../../../src/uibase.cpp:889 -msgid " &New Address... " -msgstr " &Nová adresa..." - -#: ../../../src/uibase.cpp:849 -msgid "Sending" -msgstr "Cizí adresy (pro odesílání)" - -#: ../../../src/uibase.cpp:857 -msgid "These are your Bitcoin addresses for receiving payments. You can give a different one to each sender to keep track of who is paying you. The highlighted address will be displayed in the main window." -msgstr "Tohle jsou tvé Bitcoinové adresy na příjem plateb. Můžeš dát jinou adresu každému odesílateli, abys věděl, kdo ti kolik platil. Označená adresa bude zobrazena v hlavním okně." - -#: ../../../src/uibase.cpp:870 -msgid "Receiving" -msgstr "Tvoje adresy (pro příjem)" - -#: ../../../src/uibase.cpp:880 -msgid "&Delete" -msgstr "&Smazat" - -#: ../../../src/init.cpp:142 +#: ../../../src/init.cpp:163 msgid "Bitcoin version" msgstr "Bitcoin verze" -#: ../../../src/init.cpp:143 +#: ../../../src/init.cpp:164 msgid "Usage:" msgstr "Užití:" -#: ../../../src/init.cpp:145 +#: ../../../src/init.cpp:166 msgid "Send command to -server or bitcoind\n" msgstr "Poslat příkaz pro -server nebo bitcoind\n" -#: ../../../src/init.cpp:146 +#: ../../../src/init.cpp:167 msgid "List commands\n" msgstr "Výpis příkazů\n" -#: ../../../src/init.cpp:147 +#: ../../../src/init.cpp:168 msgid "Get help for a command\n" msgstr "Získat nápovědu pro příkaz\n" -#: ../../../src/init.cpp:148 +#: ../../../src/init.cpp:169 msgid "Options:\n" msgstr "Možnosti:\n" -#: ../../../src/init.cpp:149 +#: ../../../src/init.cpp:170 msgid "Specify configuration file (default: bitcoin.conf)\n" msgstr "Konfigurační soubor (výchozí: bitcoin.conf)\n" -#: ../../../src/init.cpp:150 +#: ../../../src/init.cpp:171 msgid "Specify pid file (default: bitcoind.pid)\n" msgstr "PID soubor (výchozí: bitcoind.pid)\n" -#: ../../../src/init.cpp:151 +#: ../../../src/init.cpp:172 msgid "Generate coins\n" msgstr "Generovat mince\n" -#: ../../../src/init.cpp:152 +#: ../../../src/init.cpp:173 msgid "Don't generate coins\n" msgstr "Negenerovat mince\n" -#: ../../../src/init.cpp:153 +#: ../../../src/init.cpp:174 msgid "Start minimized\n" msgstr "Startovat minimalizovaně\n" -#: ../../../src/init.cpp:154 +#: ../../../src/init.cpp:175 msgid "Specify data directory\n" msgstr "Adresář pro data\n" -#: ../../../src/init.cpp:155 +#: ../../../src/init.cpp:176 +msgid "Specify connection timeout (in milliseconds)\n" +msgstr "Zadej časový limit spojení (v milisekundách)\n" + +#: ../../../src/init.cpp:177 msgid "Connect through socks4 proxy\n" msgstr "Připojovat se skrz socks4 proxy\n" -#: ../../../src/init.cpp:156 +#: ../../../src/init.cpp:178 msgid "Allow DNS lookups for addnode and connect\n" msgstr "Povolit DNS dotazy pro addnode (přidání uzlu) a connect (připojení)\n" -#: ../../../src/init.cpp:157 +#: ../../../src/init.cpp:179 msgid "Add a node to connect to\n" msgstr "Přidat uzel, ke kterému se připojit\n" -#: ../../../src/init.cpp:158 +#: ../../../src/init.cpp:180 msgid "Connect only to the specified node\n" msgstr "Připojovat se pouze k udanému uzlu\n" -#: ../../../src/init.cpp:159 +#: ../../../src/init.cpp:181 msgid "Don't accept connections from outside\n" msgstr "Nepřijímat připojení zvenčí\n" -#: ../../../src/init.cpp:162 +#: ../../../src/init.cpp:184 msgid "Don't attempt to use UPnP to map the listening port\n" msgstr "Nesnažit se použít UPnP k namapování naslouchacího portu\n" -#: ../../../src/init.cpp:164 +#: ../../../src/init.cpp:186 msgid "Attempt to use UPnP to map the listening port\n" msgstr "Snažit se použít UPnP k namapování naslouchacího portu\n" -#: ../../../src/init.cpp:167 +#: ../../../src/init.cpp:189 msgid "Fee per KB to add to transactions you send\n" msgstr "Poplatek za KB, který se přidá ke každé odeslané transakci\n" -#: ../../../src/init.cpp:169 +#: ../../../src/init.cpp:191 msgid "Accept command line and JSON-RPC commands\n" msgstr "Akceptovat příkazy z příkazové řádky a přes JSON-RPC\n" -#: ../../../src/init.cpp:172 +#: ../../../src/init.cpp:194 msgid "Run in the background as a daemon and accept commands\n" msgstr "Běžet na pozadí jako démon a akceptovat příkazy\n" -#: ../../../src/init.cpp:174 +#: ../../../src/init.cpp:196 msgid "Use the test network\n" msgstr "Použít testovací síť\n" -#: ../../../src/init.cpp:175 +#: ../../../src/init.cpp:197 msgid "Username for JSON-RPC connections\n" msgstr "Uživatelské jméno pro JSON-RPC spojení\n" -#: ../../../src/init.cpp:176 +#: ../../../src/init.cpp:198 msgid "Password for JSON-RPC connections\n" msgstr "Heslo pro JSON-RPC spojení\n" -#: ../../../src/init.cpp:177 +#: ../../../src/init.cpp:199 msgid "Listen for JSON-RPC connections on <port> (default: 8332)\n" msgstr "Čekat na JSON-RPC spojení na <portu> (výchozí: 8332)\n" -#: ../../../src/init.cpp:178 +#: ../../../src/init.cpp:200 msgid "Allow JSON-RPC connections from specified IP address\n" msgstr "Povolit JSON-RPC spojení ze specifikované IP adresy\n" -#: ../../../src/init.cpp:179 +#: ../../../src/init.cpp:201 msgid "Send commands to node running on <ip> (default: 127.0.0.1)\n" msgstr "Posílat příkazy uzlu běžícím na <ip> (výchozí: 127.0.0.1)\n" -#: ../../../src/init.cpp:180 +#: ../../../src/init.cpp:202 msgid "Set key pool size to <n> (default: 100)\n" msgstr "Nastavit zásobník klíčů na velikost <n> (výchozí: 100)\n" -#: ../../../src/init.cpp:181 +#: ../../../src/init.cpp:203 msgid "Rescan the block chain for missing wallet transactions\n" msgstr "Přeskenovat řetězec bloků na chybějící transakce peněženky\n" -#: ../../../src/init.cpp:185 +#: ../../../src/init.cpp:207 msgid "" "\n" "SSL options: (see the Bitcoin Wiki for SSL setup instructions)\n" @@ -904,68 +993,87 @@ msgstr "" "\n" "Možnosti SSL: (viz instrukce nastavení SSL v Bitcoin Wiki)\n" -#: ../../../src/init.cpp:186 +#: ../../../src/init.cpp:208 msgid "Use OpenSSL (https) for JSON-RPC connections\n" msgstr "Použít OpenSSL (https) pro JSON-RPC spojení\n" -#: ../../../src/init.cpp:187 +#: ../../../src/init.cpp:209 msgid "Server certificate file (default: server.cert)\n" msgstr "Soubor se serverovým certifikátem (výchozí: server.cert)\n" -#: ../../../src/init.cpp:188 +#: ../../../src/init.cpp:210 msgid "Server private key (default: server.pem)\n" msgstr "Soubor se serverovým soukromým klíčem (výchozí: server.pem)\n" -#: ../../../src/init.cpp:189 +#: ../../../src/init.cpp:211 msgid "Acceptable ciphers (default: TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!AH:!3DES:@STRENGTH)\n" msgstr "Akceptovatelné šifry (výchozí: TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!AH:!3DES:@STRENGTH)\n" -#: ../../../src/init.cpp:193 +#: ../../../src/init.cpp:215 msgid "This help message\n" msgstr "Tato nápověda\n" -#: ../../../src/init.cpp:330 +#: ../../../src/init.cpp:353 #, c-format msgid "Cannot obtain a lock on data directory %s. Bitcoin is probably already running." msgstr "Nedaří se mi získat zámek na datový adresář %s. Bitcoin pravděpodobně už jednou běží." -#: ../../../src/init.cpp:356 +#: ../../../src/init.cpp:379 msgid "Error loading addr.dat \n" msgstr "Chyba při načítání addr.dat \n" -#: ../../../src/init.cpp:362 +#: ../../../src/init.cpp:385 msgid "Error loading blkindex.dat \n" msgstr "Chyba při načítání blkindex.dat \n" -#: ../../../src/init.cpp:369 +#: ../../../src/init.cpp:396 +msgid "Error loading wallet.dat: Wallet corrupted \n" +msgstr "Chyba při načítání wallet.dat: peněženka je poškozená \n" + +#: ../../../src/init.cpp:398 +msgid "Error loading wallet.dat: Wallet requires newer version of Bitcoin \n" +msgstr "Chyba při načítání wallet.dat: peněženka vyžaduje novější verzi Bitcoinu \n" + +#: ../../../src/init.cpp:400 msgid "Error loading wallet.dat \n" msgstr "Chyba při načítání wallet.dat \n" -#: ../../../src/init.cpp:449 +#: ../../../src/init.cpp:489 msgid "Invalid -proxy address" msgstr "Neplatná -proxy adresa" -#: ../../../src/init.cpp:472 +#: ../../../src/init.cpp:514 msgid "Invalid amount for -paytxfee=<amount>" msgstr "Neplatná částka pro -paytxfee=<částka>" -#: ../../../src/init.cpp:476 +#: ../../../src/init.cpp:518 msgid "Warning: -paytxfee is set very high. This is the transaction fee you will pay if you send a transaction." msgstr "Varování: -paytxfee je nastaveno velmi vysoko. Toto je transakční poplatek, který zaplatíš za každou poslanou transakci." -#: ../../../src/uibase.h:147 +#: ../../../src/net.cpp:1622 +#, c-format +msgid "Unable to bind to port %d on this computer. Bitcoin is probably already running." +msgstr "Nedaří se mi připojit na port %d na tomhle počítači. Bitcoin už pravděpodobně jednou běží." + +#: ../../../src/main.cpp:1437 +msgid "Warning: Disk space is low " +msgstr "Upozornění: Na disku je málo místa" + +#: ../../../src/uibase.h:151 msgid "Transaction Details" msgstr "Detaily transakce" -#: ../../../src/uibase.h:199 +#: ../../../src/uibase.h:203 msgid "Options" msgstr "Možnosti" -#: ../../../src/uibase.h:228 +#: ../../../src/uibase.h:232 msgid "About Bitcoin" msgstr "O Bitcoinu" -#: ../../../src/uibase.h:337 +#: ../../../src/uibase.h:341 msgid "Your Bitcoin Addresses" msgstr "Tvá Bitcoinová adresa" +#~ msgid "Invalid bitcoin address" +#~ msgstr "Neplatná Bitcoinová adresa" diff --git a/locale/de/LC_MESSAGES/bitcoin.mo b/locale/de/LC_MESSAGES/bitcoin.mo Binary files differindex bcea1d3662..bd03fd27c3 100644 --- a/locale/de/LC_MESSAGES/bitcoin.mo +++ b/locale/de/LC_MESSAGES/bitcoin.mo diff --git a/locale/de/LC_MESSAGES/bitcoin.po b/locale/de/LC_MESSAGES/bitcoin.po index a0519f0a2f..59381c11e6 100644 --- a/locale/de/LC_MESSAGES/bitcoin.po +++ b/locale/de/LC_MESSAGES/bitcoin.po @@ -3,128 +3,436 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2011-05-15 18:18+0100\n" -"PO-Revision-Date: 2011-05-26 22:34+0100\n" -"Last-Translator: Jakob Kramer <censored@gmail.com>\n" +"POT-Creation-Date: 2011-08-07 01:46+0100\n" +"PO-Revision-Date: 2011-08-07 01:47+0100\n" +"Last-Translator: Michael Bemmerl <mail@mx-server.de>\n" "Language-Team: German <translation-team-de@lists.sourceforge.net>\n" -"Language: de\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" +"Language: de\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" "X-Generator: Virtaal 0.6.1\n" "X-Poedit-KeywordsList: _;gettext;gettext_noop\n" "X-Poedit-Basepath: .\n" "X-Poedit-SearchPath-0: ../../..\n" -#: ../../../src/net.cpp:1499 +#: ../../../src/init.cpp:162 +msgid "Bitcoin version" +msgstr "Bitcoin Version" + +#: ../../../src/init.cpp:163 +msgid "Usage:" +msgstr "Verwendung:" + +#: ../../../src/init.cpp:165 +msgid "Send command to -server or bitcoind\n" +msgstr "Sende Befehl zu -server oder bitcoind\n" + +#: ../../../src/init.cpp:166 +msgid "List commands\n" +msgstr "Liste Befehle auf\n" + +#: ../../../src/init.cpp:167 +msgid "Get help for a command\n" +msgstr "Hilfe für einen Befehl erhalten\n" + +#: ../../../src/init.cpp:168 +msgid "Options:\n" +msgstr "Optionen:\n" + +#: ../../../src/init.cpp:169 +msgid "Specify configuration file (default: bitcoin.conf)\n" +msgstr "Konfigurationsdatei bestimmen (Standard: bitcoin.conf)\n" + +#: ../../../src/init.cpp:170 +msgid "Specify pid file (default: bitcoind.pid)\n" +msgstr "pid-Datei bestimmen (Standard: bitcoind.pid)\n" + +#: ../../../src/init.cpp:171 +msgid "Generate coins\n" +msgstr "Münzen erzeugen\n" + +#: ../../../src/init.cpp:172 +msgid "Don't generate coins\n" +msgstr "Keine Münzen erzeugen\n" + +#: ../../../src/init.cpp:173 +msgid "Start minimized\n" +msgstr "Minimiert starten\n" + +#: ../../../src/init.cpp:174 +msgid "Specify data directory\n" +msgstr "Datenverzeichnis festlegen\n" + +#: ../../../src/init.cpp:175 +msgid "Specify connection timeout (in milliseconds)\n" +msgstr "Verbindungs-Timeout in Milisekunden\n" + +#: ../../../src/init.cpp:176 +msgid "Connect through socks4 proxy\n" +msgstr "Socks4-Proxy verwenden\n" + +#: ../../../src/init.cpp:177 +msgid "Allow DNS lookups for addnode and connect\n" +msgstr "DNS-Auflösung für addnode und connect erlauben\n" + +#: ../../../src/init.cpp:178 +msgid "Add a node to connect to\n" +msgstr "Einen Teilnehmer hinzufügen, zu dem verbunden werden soll\n" + +#: ../../../src/init.cpp:179 +msgid "Connect only to the specified node\n" +msgstr "Nur zu dem angegebenen Teilnehmer verbinden\n" + +#: ../../../src/init.cpp:180 +msgid "Don't accept connections from outside\n" +msgstr "Akzeptiere keine externen Verbindungen\n" + +#: ../../../src/init.cpp:183 +msgid "Don't attempt to use UPnP to map the listening port\n" +msgstr "Versuche nicht, UPnP zur Portweiterleitung zu nutzen\n" + +#: ../../../src/init.cpp:185 +msgid "Attempt to use UPnP to map the listening port\n" +msgstr "Versuche, UPnP zur Portweiterleitung zu nutzen\n" + +#: ../../../src/init.cpp:188 +msgid "Fee per KB to add to transactions you send\n" +msgstr "Gebühr pro KB für Überweisungen, die Sie tätigen\n" + +#: ../../../src/init.cpp:190 +msgid "Accept command line and JSON-RPC commands\n" +msgstr "Akzeptiere Kommandozeile und JSON-RPC-Befehle\n" + +#: ../../../src/init.cpp:193 +msgid "Run in the background as a daemon and accept commands\n" +msgstr "Laufe im Hintergrund als Daemon und akzeptiere Befehle\n" + +#: ../../../src/init.cpp:195 +msgid "Use the test network\n" +msgstr "Nutze das Testnetzwerk\n" + +#: ../../../src/init.cpp:196 +msgid "Username for JSON-RPC connections\n" +msgstr "Benutzername für JSON-RPC-Verbindungen\n" + +#: ../../../src/init.cpp:197 +msgid "Password for JSON-RPC connections\n" +msgstr "Passwort für JSON-RPC-Verbindungen\n" + +#: ../../../src/init.cpp:198 +msgid "Listen for JSON-RPC connections on <port> (default: 8332)\n" +msgstr "Horche für JSON-RPC-Verbindungen auf <port> (Standard: 8332)\n" + +#: ../../../src/init.cpp:199 +msgid "Allow JSON-RPC connections from specified IP address\n" +msgstr "Erlaube JSON-RPC-Verbindungen von bestimmter IP-Adresse\n" + +#: ../../../src/init.cpp:200 +msgid "Send commands to node running on <ip> (default: 127.0.0.1)\n" +msgstr "Sende Befehle zum Knoten mit <ip> (Standard: 127.0.0.1)\n" + +#: ../../../src/init.cpp:201 +msgid "Set key pool size to <n> (default: 100)\n" +msgstr "Setze Key-Pool-Größe auf <n> (Standard: 100)\n" + +#: ../../../src/init.cpp:202 +msgid "Rescan the block chain for missing wallet transactions\n" +msgstr "Frage die Block-Kette nach fehlenden Brieftaschen-Überweisungen ab\n" + +#: ../../../src/init.cpp:206 +msgid "" +"\n" +"SSL options: (see the Bitcoin Wiki for SSL setup instructions)\n" +msgstr "" +"\n" +"SSL-Optionen: (siehe das Bitcoin-Wiki für SSL-Installationsanleitungen)\n" + +#: ../../../src/init.cpp:207 +msgid "Use OpenSSL (https) for JSON-RPC connections\n" +msgstr "Nutze OpenSSL (https) für JSON-RPC-Verbindungen\n" + +#: ../../../src/init.cpp:208 +msgid "Server certificate file (default: server.cert)\n" +msgstr "Server-Zertifikatsdatei (Standard: server.cert)\n" + +#: ../../../src/init.cpp:209 +msgid "Server private key (default: server.pem)\n" +msgstr "Server-Geheimschlüssel (Standard: server.pem)\n" + +#: ../../../src/init.cpp:210 +msgid "Acceptable ciphers (default: TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!AH:!3DES:@STRENGTH)\n" +msgstr "Anzunehmende Verschlüsselungen (Standard: TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!AH:!3DES:@STRENGTH)\n" + +#: ../../../src/init.cpp:214 +msgid "This help message\n" +msgstr "Diese Anleitung\n" + +#: ../../../src/init.cpp:352 +#, c-format +msgid "Cannot obtain a lock on data directory %s. Bitcoin is probably already running." +msgstr "Erhalte keine Datensperre für das Datenverzeichnis %s. Bitcoin läuft wahrscheinlich bereits." + +#: ../../../src/init.cpp:378 +msgid "Error loading addr.dat \n" +msgstr "Fehler beim Laden von addr.dat \n" + +#: ../../../src/init.cpp:384 +msgid "Error loading blkindex.dat \n" +msgstr "Fehler beim Laden von blkindex.dat \n" + +#: ../../../src/init.cpp:395 +msgid "Error loading wallet.dat: Wallet corrupted \n" +msgstr "Fehler beim Laden von wallet.dat: Brieftasche beschädigt \n" + +#: ../../../src/init.cpp:397 +msgid "Error loading wallet.dat: Wallet requires newer version of Bitcoin \n" +msgstr "Fehler beim Laden von wallet.dat: Die Brieftasche benötigt eine neuere Version von Bitcoin \n" + +#: ../../../src/init.cpp:399 +msgid "Error loading wallet.dat \n" +msgstr "Fehler beim Laden von wallet.dat \n" + +#: ../../../src/init.cpp:488 +msgid "Invalid -proxy address" +msgstr "Ungültige -Proxy Adresse" + +#: ../../../src/init.cpp:513 +msgid "Invalid amount for -paytxfee=<amount>" +msgstr "Ungültiger Betrag für -paytxfee=<amount>" + +#: ../../../src/init.cpp:517 +msgid "Warning: -paytxfee is set very high. This is the transaction fee you will pay if you send a transaction." +msgstr "Warnung: -paytxfee ist sehr hoch gesetzt. Das ist die Überweisungsgebühr, die Sie für das Senden einer Überweisung zahlen." + +#: ../../../src/main.cpp:1427 +msgid "Warning: Disk space is low " +msgstr "Warnung: Festplatte fast voll " + +#: ../../../src/net.cpp:1616 #, c-format msgid "Unable to bind to port %d on this computer. Bitcoin is probably already running." msgstr "Kann nicht zu Port %d auf diesem Computer verbinden. Bitcoin läuft wahrscheinlich bereits." -#: ../../../src/ui.cpp:202 +#: ../../../src/rpc.cpp:2086 +#: ../../../src/rpc.cpp:2088 +#, c-format +msgid "To use the %s option" +msgstr "Um die %s-Option zu nutzen" + +#: ../../../src/rpc.cpp:2090 +#, c-format +msgid "" +"Warning: %s, you must set rpcpassword=<password>\n" +"in the configuration file: %s\n" +"If the file does not exist, create it with owner-readable-only file permissions.\n" +msgstr "" +"Warnung: %s, müssen Sie rpcpassword=<password>\n" +"in der Konfigurationsdatei %s einstellen.\n" +"Wenn die Datei nicht existiert, erstellen Sie sie mit ausschließlich Besitzer-Leserechten.\n" + +#: ../../../src/rpc.cpp:2263 +#, c-format +msgid "" +"You must set rpcpassword=<password> in the configuration file:\n" +"%s\n" +"If the file does not exist, create it with owner-readable-only file permissions." +msgstr "" +"Sie müssen rpcpassword=<password> in der Konfigurationsdatei\n" +"\"%s\" einstellen.\n" +"Wenn die Datei nicht existiert, erstellen Sie sie mit ausschließlich Besitzer-Leserechten." + +#: ../../../src/ui.cpp:216 #, c-format msgid "This transaction is over the size limit. You can still send it for a fee of %s, which goes to the nodes that process your transaction and helps to support the network. Do you want to pay the fee?" msgstr "Diese Überweisung übersteigt das Betragslimit. Sie können sie trotzdem tätigen, aber es wird eine Gebühr von %s erhoben, die an den Teilnehmer ausgeschüttet wird, der Ihre Überweisung bearbeitet und dadurch hilft, das Netzwerk am laufen zu halten. Möchten Sie die Gebühr entrichten?" -#: ../../../src/ui.cpp:301 +#: ../../../src/ui.cpp:260 +#: ../../../src/ui.cpp:1246 +msgid "Enter the current passphrase to the wallet." +msgstr "Geben Sie die derzeitige Passphrase der Brieftasche ein." + +# See http://dict.leo.org/forum/viewUnsolvedquery.php?idThread=465865&idForum=2&lp=ende&lang=de +#: ../../../src/ui.cpp:261 +#: ../../../src/ui.cpp:1182 +#: ../../../src/ui.cpp:1199 +#: ../../../src/ui.cpp:1247 +#: ../../../src/ui.cpp:1273 +#: ../../../src/ui.cpp:1293 +msgid "Passphrase" +msgstr "Passphrase" + +#: ../../../src/ui.cpp:267 +msgid "Please supply the current wallet decryption passphrase." +msgstr "Bitte geben Sie die derzeitige Passphrase zur Entschlüsselung der Brieftasche an." + +#: ../../../src/ui.cpp:275 +#: ../../../src/ui.cpp:1258 +#: ../../../src/ui.cpp:1315 +msgid "The passphrase entered for the wallet decryption was incorrect." +msgstr "Die eingegebene Passphrase zur Entschlüsselung der Brieftasche war inkorrekt." + +#: ../../../src/ui.cpp:352 msgid "Status" msgstr "Status" -#: ../../../src/ui.cpp:302 +#: ../../../src/ui.cpp:353 msgid "Date" msgstr "Datum" -#: ../../../src/ui.cpp:303 +#: ../../../src/ui.cpp:354 msgid "Description" msgstr "Beschreibung" -#: ../../../src/ui.cpp:304 +#: ../../../src/ui.cpp:355 msgid "Debit" msgstr "Belastungen" -#: ../../../src/ui.cpp:305 +#: ../../../src/ui.cpp:356 msgid "Credit" msgstr "Gutschriften" -#: ../../../src/ui.cpp:511 +#: ../../../src/ui.cpp:567 #, c-format msgid "Open for %d blocks" msgstr "Offen für %d Blöcke" -#: ../../../src/ui.cpp:513 +#: ../../../src/ui.cpp:569 #, c-format msgid "Open until %s" msgstr "Offen bis %s" -#: ../../../src/ui.cpp:519 +#: ../../../src/ui.cpp:575 #, c-format msgid "%d/offline?" msgstr "%d/Offline?" -#: ../../../src/ui.cpp:521 +#: ../../../src/ui.cpp:577 #, c-format msgid "%d/unconfirmed" msgstr "%d/nicht bestätigt" -#: ../../../src/ui.cpp:523 +#: ../../../src/ui.cpp:579 #, c-format msgid "%d confirmations" msgstr "%d Bestätigungen" -#: ../../../src/ui.cpp:608 +#: ../../../src/ui.cpp:664 msgid "Generated" msgstr "Erzeugt" -#: ../../../src/ui.cpp:616 +#: ../../../src/ui.cpp:672 #, c-format msgid "Generated (%s matures in %d more blocks)" msgstr "Erzeugt (%s reifen nach %d weiteren Blöcken)" -#: ../../../src/ui.cpp:620 +#: ../../../src/ui.cpp:676 msgid "Generated - Warning: This block was not received by any other nodes and will probably not be accepted!" msgstr "Erzeugt - Warnung: Dieser Block wurde von keinem anderen Teilnehmer empfangen und wird wahrscheinlich nicht akzeptiert werden!" -#: ../../../src/ui.cpp:624 +#: ../../../src/ui.cpp:680 msgid "Generated (not accepted)" msgstr "Erzeugt (nicht akzeptiert)" -#: ../../../src/ui.cpp:634 +#: ../../../src/ui.cpp:690 msgid "From: " msgstr "Von: " -#: ../../../src/ui.cpp:658 +#: ../../../src/ui.cpp:714 msgid "Received with: " msgstr "Empfangen durch: " -#: ../../../src/ui.cpp:704 +#: ../../../src/ui.cpp:759 msgid "Payment to yourself" msgstr "Überweisung an Sie selbst" -#: ../../../src/ui.cpp:738 +#: ../../../src/ui.cpp:793 msgid "To: " msgstr "An: " -#: ../../../src/ui.cpp:1053 +#: ../../../src/ui.cpp:1108 msgid " Generating" msgstr " Erzeugen" -#: ../../../src/ui.cpp:1055 +#: ../../../src/ui.cpp:1110 msgid "(not connected)" msgstr "(nicht verbunden)" -#: ../../../src/ui.cpp:1058 +#: ../../../src/ui.cpp:1113 #, c-format msgid " %d connections %d blocks %d transactions" msgstr " %d Verbindungen %d Blöcke %d Überweisungen" -#: ../../../src/ui.cpp:1163 -#: ../../../src/ui.cpp:2527 +#: ../../../src/ui.cpp:1170 +msgid "Wallet already encrypted." +msgstr "Brieftasche bereits verschlüsselt." + +#: ../../../src/ui.cpp:1181 +msgid "" +"Enter the new passphrase to the wallet.\n" +"Please use a passphrase of 10 or more random characters, or eight or more words." +msgstr "" +"Geben Sie die neue Passphrase der Brieftasche ein.\n" +"Bitte benutzen Sie eine Passphrase mit zehn oder mehr zufällig gewählten Zeichen, oder acht oder mehr Wörter." + +#: ../../../src/ui.cpp:1188 +#: ../../../src/ui.cpp:1281 +msgid "Error: The supplied passphrase was too short." +msgstr "Fehler: Die angegebene Passphrase war zu kurz. " + +#: ../../../src/ui.cpp:1192 +msgid "" +"WARNING: If you encrypt your wallet and lose your passphrase, you will LOSE ALL OF YOUR BITCOINS!\n" +"Are you sure you wish to encrypt your wallet?" +msgstr "" +"WARNUNG: Wenn Sie Ihre Brieftasche verschlüsseln und die Passphrase verlieren, werden Sie ALLE IHRE BITCOINS VERLIEREN!\n" +"Sind Sie sicher, dass Sie Ihre Brieftasche verschlüsseln wollen?" + +#: ../../../src/ui.cpp:1198 +msgid "Please re-enter your new wallet passphrase." +msgstr "Bitte geben Sie erneut Ihre neue Passphrase der Brieftasche ein." + +#: ../../../src/ui.cpp:1207 +#: ../../../src/ui.cpp:1303 +msgid "Error: the supplied passphrases didn't match." +msgstr "Fehler: Die angegebenen Passphrasen stimmten nicht überein." + +#: ../../../src/ui.cpp:1217 +msgid "Wallet encryption failed." +msgstr "Verschlüsselung der Brieftasche fehlgeschlagen." + +#: ../../../src/ui.cpp:1224 +msgid "" +"Wallet Encrypted.\n" +"Remember that encrypting your wallet cannot fully protect your bitcoins from being stolen by malware infecting your computer." +msgstr "" +"Brieftasche verschlüsselt.\n" +"Beachten Sie, dass das Verschlüsseln der Brieftasche Ihre Bitcoins nicht völlig vor Diebstahl durch Schadprogramme auf Ihrem Computer schützt." + +#: ../../../src/ui.cpp:1235 +msgid "Wallet is unencrypted, please encrypt it first." +msgstr "Die Brieftasche ist nicht verschlüsselt, bitte verschlüsselen Sie sie erst." + +#: ../../../src/ui.cpp:1272 +msgid "Enter the new passphrase for the wallet." +msgstr "Geben Sie die neue Passphrase der Brieftasche ein." + +#: ../../../src/ui.cpp:1292 +msgid "Re-enter the new passphrase for the wallet." +msgstr "Geben Sie erneut die neue Passphrase der Brieftasche ein." + +#: ../../../src/ui.cpp:1324 +msgid "Wallet Passphrase Changed." +msgstr "Die Passphrase der Brieftasche wurde geändert." + +#: ../../../src/ui.cpp:1381 +#: ../../../src/ui.cpp:2814 msgid "New Receiving Address" msgstr "&Neue Empfangs-Adresse" -#: ../../../src/ui.cpp:1164 -#: ../../../src/ui.cpp:2528 +#: ../../../src/ui.cpp:1382 +#: ../../../src/ui.cpp:2815 msgid "" "You should use a new address for each payment you receive.\n" "\n" @@ -134,248 +442,248 @@ msgstr "" "\n" "Beschreibung" -#: ../../../src/ui.cpp:1233 +#: ../../../src/ui.cpp:1466 msgid "<b>Status:</b> " msgstr "<b>Status:</b> " -#: ../../../src/ui.cpp:1238 +#: ../../../src/ui.cpp:1471 msgid ", has not been successfully broadcast yet" msgstr ", wurde noch nicht erfolgreich übertragen" -#: ../../../src/ui.cpp:1240 +#: ../../../src/ui.cpp:1473 #, c-format msgid ", broadcast through %d node" msgstr ", durch %d Teilnehmer übertragen" -#: ../../../src/ui.cpp:1242 +#: ../../../src/ui.cpp:1475 #, c-format msgid ", broadcast through %d nodes" msgstr ", durch %d Teilnehmer übertragen" -#: ../../../src/ui.cpp:1246 +#: ../../../src/ui.cpp:1479 msgid "<b>Date:</b> " msgstr "<b>Datum</b> " -#: ../../../src/ui.cpp:1254 +#: ../../../src/ui.cpp:1487 msgid "<b>Source:</b> Generated<br>" msgstr "<b>Quelle:</b> Erzeugt<br>" -#: ../../../src/ui.cpp:1260 -#: ../../../src/ui.cpp:1278 +#: ../../../src/ui.cpp:1493 +#: ../../../src/ui.cpp:1510 msgid "<b>From:</b> " msgstr "<b>Von:</b> " -#: ../../../src/ui.cpp:1278 +#: ../../../src/ui.cpp:1510 msgid "unknown" msgstr "Unbekannt" -#: ../../../src/ui.cpp:1279 -#: ../../../src/ui.cpp:1303 -#: ../../../src/ui.cpp:1362 +#: ../../../src/ui.cpp:1511 +#: ../../../src/ui.cpp:1535 +#: ../../../src/ui.cpp:1594 msgid "<b>To:</b> " msgstr "<b>An:</b> " -#: ../../../src/ui.cpp:1282 +#: ../../../src/ui.cpp:1514 msgid " (yours, label: " msgstr " (Eigene, Beschreibung: " -#: ../../../src/ui.cpp:1284 +#: ../../../src/ui.cpp:1516 msgid " (yours)" msgstr " (Eigene)" -#: ../../../src/ui.cpp:1321 -#: ../../../src/ui.cpp:1333 -#: ../../../src/ui.cpp:1379 -#: ../../../src/ui.cpp:1396 +#: ../../../src/ui.cpp:1553 +#: ../../../src/ui.cpp:1565 +#: ../../../src/ui.cpp:1611 +#: ../../../src/ui.cpp:1628 msgid "<b>Credit:</b> " msgstr "<b>Gutschrift:</b> " -#: ../../../src/ui.cpp:1323 +#: ../../../src/ui.cpp:1555 #, c-format msgid "(%s matures in %d more blocks)" msgstr "(%s reifen nach %d weiteren Blöcken)" -#: ../../../src/ui.cpp:1325 +#: ../../../src/ui.cpp:1557 msgid "(not accepted)" msgstr "(nicht akzeptiert)" -#: ../../../src/ui.cpp:1370 -#: ../../../src/ui.cpp:1378 -#: ../../../src/ui.cpp:1393 +#: ../../../src/ui.cpp:1602 +#: ../../../src/ui.cpp:1610 +#: ../../../src/ui.cpp:1625 msgid "<b>Debit:</b> " msgstr "<b>Belastung:</b> " -#: ../../../src/ui.cpp:1384 +#: ../../../src/ui.cpp:1616 msgid "<b>Transaction fee:</b> " msgstr "<b>Überweisungsgebühr:</b> " -#: ../../../src/ui.cpp:1400 +#: ../../../src/ui.cpp:1632 msgid "<b>Net amount:</b> " msgstr "<b>Nettobetrag:</b> " -#: ../../../src/ui.cpp:1407 +#: ../../../src/ui.cpp:1639 msgid "Message:" msgstr "Nachricht:" -#: ../../../src/ui.cpp:1409 +#: ../../../src/ui.cpp:1641 msgid "Comment:" msgstr "Kommentar:" -#: ../../../src/ui.cpp:1412 +#: ../../../src/ui.cpp:1644 msgid "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 \"not accepted\" and not be spendable. This may occasionally happen if another node generates a block within a few seconds of yours." msgstr "Erzeugte Münzen müssen 120 Blöcke lang reifen. Als Sie diesen Block erzeugt haben, wurde er an alle Teilnehmer übertragen, damit er zur Block-Kette hinzugefügt werden kann. Falls der Block es nicht in die Block-Kette schafft, wird die Beschreibung zu \"nicht akzeptiert\" geändert, und Sie können die Münzen nicht ausgeben. Dies kann manchmal passieren, wenn Sie und ein anderer Teilnehmer annähernd zeitgleich einen Block erzeugen." -#: ../../../src/ui.cpp:1592 +#: ../../../src/ui.cpp:1824 msgid "Cannot write autostart/bitcoin.desktop file" msgstr "Kann Datei autostart/bitcoin.desktop nicht schreiben" -#: ../../../src/ui.cpp:1628 +#: ../../../src/ui.cpp:1860 msgid "Main" msgstr "Haupt" -#: ../../../src/ui.cpp:1636 +#: ../../../src/ui.cpp:1870 msgid "&Start Bitcoin on window system startup" msgstr "Bitcoin beim &Systemstart ausführen" -#: ../../../src/ui.cpp:1643 +#: ../../../src/ui.cpp:1877 msgid "&Minimize on close" -msgstr "Beim schließen &Minimieren" +msgstr "Beim Schließen &minimieren" -#: ../../../src/ui.cpp:1785 +#: ../../../src/ui.cpp:2019 #, c-format msgid "version %s" -msgstr "version %s" +msgstr "Version %s" -#: ../../../src/ui.cpp:1897 +#: ../../../src/ui.cpp:2142 msgid "Error in amount " msgstr "Fehler in Betrag " -#: ../../../src/ui.cpp:1897 -#: ../../../src/ui.cpp:1902 -#: ../../../src/ui.cpp:1907 -#: ../../../src/ui.cpp:1942 -#: ../../../src/uibase.cpp:55 +#: ../../../src/ui.cpp:2142 +#: ../../../src/ui.cpp:2147 +#: ../../../src/ui.cpp:2152 +#: ../../../src/ui.cpp:2201 +#: ../../../src/uibase.cpp:61 msgid "Send Coins" msgstr "Überweisen" -#: ../../../src/ui.cpp:1902 +#: ../../../src/ui.cpp:2147 msgid "Amount exceeds your balance " msgstr "Der Betrag übersteigt Ihr Guthaben " -#: ../../../src/ui.cpp:1907 +#: ../../../src/ui.cpp:2152 msgid "Total exceeds your balance when the " msgstr "Der Betrag übersteigt Ihr Guthaben, wenn man die " -#: ../../../src/ui.cpp:1907 +#: ../../../src/ui.cpp:2152 msgid " transaction fee is included " msgstr " Überweisungsgebühr berücksichtigt " -#: ../../../src/ui.cpp:1925 +#: ../../../src/ui.cpp:2175 msgid "Payment sent " msgstr "Zahlung überwiesen " -#: ../../../src/ui.cpp:1925 -#: ../../../src/ui.cpp:1930 -#: ../../../src/ui.cpp:2074 -#: ../../../src/ui.cpp:2227 -#: ../../../src/main.cpp:3999 +#: ../../../src/ui.cpp:2175 +#: ../../../src/ui.cpp:2184 +#: ../../../src/ui.cpp:2335 +#: ../../../src/ui.cpp:2499 +#: ../../../src/wallet.cpp:1099 msgid "Sending..." msgstr "Überweise ..." -#: ../../../src/ui.cpp:1942 +#: ../../../src/ui.cpp:2201 msgid "Invalid address " msgstr "Ungültige Adresse " -#: ../../../src/ui.cpp:1995 +#: ../../../src/ui.cpp:2256 #, c-format msgid "Sending %s to %s" msgstr "Überweise %s an %s" -#: ../../../src/ui.cpp:2068 -#: ../../../src/ui.cpp:2101 +#: ../../../src/ui.cpp:2329 +#: ../../../src/ui.cpp:2362 msgid "CANCELLED" msgstr "ANNULLIERT" -#: ../../../src/ui.cpp:2072 +#: ../../../src/ui.cpp:2333 msgid "Cancelled" msgstr "Annulliert" -#: ../../../src/ui.cpp:2074 +#: ../../../src/ui.cpp:2335 msgid "Transfer cancelled " msgstr "Überweisung annulliert " -#: ../../../src/ui.cpp:2127 +#: ../../../src/ui.cpp:2388 msgid "Error: " msgstr "Fehler: " -#: ../../../src/ui.cpp:2141 -#: ../../../src/ui.cpp:2212 -#: ../../../src/main.cpp:4018 +#: ../../../src/ui.cpp:2402 +#: ../../../src/ui.cpp:2473 +#: ../../../src/wallet.cpp:1118 msgid "Insufficient funds" msgstr "Unzureichende Geldmittel" -#: ../../../src/ui.cpp:2146 +#: ../../../src/ui.cpp:2407 msgid "Connecting..." msgstr "Verbinde ..." -#: ../../../src/ui.cpp:2151 +#: ../../../src/ui.cpp:2412 msgid "Unable to connect" msgstr "Kann nicht verbinden" -#: ../../../src/ui.cpp:2156 +#: ../../../src/ui.cpp:2417 msgid "Requesting public key..." msgstr "Fordere öffentlichen Schlüssel an ..." -#: ../../../src/ui.cpp:2168 +#: ../../../src/ui.cpp:2429 msgid "Received public key..." msgstr "Öffentlicher Schlüssel empfangen ..." -#: ../../../src/ui.cpp:2182 +#: ../../../src/ui.cpp:2443 msgid "Recipient is not accepting transactions sent by IP address" msgstr "Empfänger akzeptiert keine Überweisungen von IP-Adressen" -#: ../../../src/ui.cpp:2184 +#: ../../../src/ui.cpp:2445 msgid "Transfer was not accepted" msgstr "Überweisung wurde nicht akzeptiert" -#: ../../../src/ui.cpp:2193 +#: ../../../src/ui.cpp:2454 msgid "Invalid response received" msgstr "Ungültige Antwort erhalten" -#: ../../../src/ui.cpp:2208 +#: ../../../src/ui.cpp:2469 msgid "Creating transaction..." msgstr "Erstelle Überweisung ..." -#: ../../../src/ui.cpp:2220 +#: ../../../src/ui.cpp:2488 #, c-format msgid "This transaction requires a transaction fee of at least %s because of its amount, complexity, or use of recently received funds" msgstr "Diese Überweisung benötigt eine Überweisungsgebühr von mindestens %s wegen ihres Betrags, Komplexität oder der Benutzung kürzlich erhaltener Geldmittel" -#: ../../../src/ui.cpp:2222 +#: ../../../src/ui.cpp:2490 msgid "Transaction creation failed" msgstr "Überweisung konnte nicht erzeugt werden." -#: ../../../src/ui.cpp:2229 +#: ../../../src/ui.cpp:2501 msgid "Transaction aborted" msgstr "Überweisung abgebrochen" -#: ../../../src/ui.cpp:2237 +#: ../../../src/ui.cpp:2509 msgid "Lost connection, transaction cancelled" msgstr "Verbindung verloren, Überweisungsvorgang abgebrochen" -#: ../../../src/ui.cpp:2253 +#: ../../../src/ui.cpp:2525 msgid "Sending payment..." msgstr "Überweise Zahlung ..." -#: ../../../src/ui.cpp:2259 +#: ../../../src/ui.cpp:2531 msgid "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." msgstr "Die Überweisung wurde abgelehnt. Das kann passieren, wenn einige der Münzen in Ihrer Brieftasche bereits ausgegeben wurden, z.B. weil Sie eine Kopie der Brieftasche (wallet.dat) gemacht haben. Bitcoins, die mithilfe der Kopie ausgegeben wurden, sind in dieser Brieftasche noch nicht als ausgegeben markiert worden." -#: ../../../src/ui.cpp:2268 +#: ../../../src/ui.cpp:2540 msgid "Waiting for confirmation..." msgstr "Warte auf Bestätigung ..." -#: ../../../src/ui.cpp:2286 +#: ../../../src/ui.cpp:2558 msgid "" "The payment was sent, but the recipient was unable to verify it.\n" "The transaction is recorded and will credit to the recipient,\n" @@ -383,304 +691,251 @@ msgid "" msgstr "" "Die Zahlung wurde überwiesen, aber der Empfänger konnte sie nicht bestätigen.\n" "Die Überweisung wurde gespeichert und wird dem Empfänger gutgeschrieben,\n" -"aber die begleitende Nachricht wird nicht ankommen." +"aber die begleitende Nachricht wird leer sein." -#: ../../../src/ui.cpp:2295 +#: ../../../src/ui.cpp:2567 msgid "Payment was sent, but an invalid response was received" msgstr "Die Zahlung wurde überwiesen, aber die Antwort war fehlerhaft" -#: ../../../src/ui.cpp:2301 +#: ../../../src/ui.cpp:2573 msgid "Payment completed" msgstr "Zahlung ausgeführt" -#: ../../../src/ui.cpp:2332 -#: ../../../src/ui.cpp:2478 -#: ../../../src/ui.cpp:2515 +#: ../../../src/ui.cpp:2615 +#: ../../../src/ui.cpp:2762 +#: ../../../src/ui.cpp:2802 msgid "Name" msgstr "Name" -#: ../../../src/ui.cpp:2333 -#: ../../../src/ui.cpp:2478 -#: ../../../src/ui.cpp:2515 +#: ../../../src/ui.cpp:2616 +#: ../../../src/ui.cpp:2762 +#: ../../../src/ui.cpp:2802 msgid "Address" msgstr "Adresse" -#: ../../../src/ui.cpp:2335 -#: ../../../src/ui.cpp:2490 +#: ../../../src/ui.cpp:2618 +#: ../../../src/ui.cpp:2774 msgid "Label" msgstr "Beschreibung" -#: ../../../src/ui.cpp:2336 -#: ../../../src/uibase.cpp:837 +#: ../../../src/ui.cpp:2619 +#: ../../../src/uibase.cpp:847 msgid "Bitcoin Address" msgstr "Bitcoin-Adresse" -#: ../../../src/ui.cpp:2460 +#: ../../../src/ui.cpp:2744 msgid "This is one of your own addresses for receiving payments and cannot be entered in the address book. " msgstr "Dies ist eine Ihrer eigenen Adressen für den Zahlungseingang und kann deshalb nicht in das Adressbuch übernommen werden. " -#: ../../../src/ui.cpp:2478 -#: ../../../src/ui.cpp:2484 +#: ../../../src/ui.cpp:2762 +#: ../../../src/ui.cpp:2768 msgid "Edit Address" msgstr "Adresse bearbeiten" -#: ../../../src/ui.cpp:2490 +#: ../../../src/ui.cpp:2774 msgid "Edit Address Label" msgstr "Beschreibung der Adresse bearbeiten" -#: ../../../src/ui.cpp:2515 -#: ../../../src/ui.cpp:2521 +#: ../../../src/ui.cpp:2802 +#: ../../../src/ui.cpp:2808 msgid "Add Address" msgstr "Adresse hinzufügen" -#: ../../../src/ui.cpp:2598 +#: ../../../src/ui.cpp:2896 msgid "Bitcoin" msgstr "Bitcoin" -#: ../../../src/ui.cpp:2600 +#: ../../../src/ui.cpp:2898 msgid "Bitcoin - Generating" msgstr "Bitcoin - Erzeuge" -#: ../../../src/ui.cpp:2602 +#: ../../../src/ui.cpp:2900 msgid "Bitcoin - (not connected)" msgstr "Bitcoin - (nicht verbunden)" -#: ../../../src/ui.cpp:2681 +#: ../../../src/ui.cpp:2979 msgid "&Open Bitcoin" -msgstr "Bitcoin Ö&ffnen" +msgstr "Bitcoin ö&ffnen" -#: ../../../src/ui.cpp:2682 +#: ../../../src/ui.cpp:2980 msgid "&Send Bitcoins" msgstr "Bitcoins &senden" -#: ../../../src/ui.cpp:2683 +#: ../../../src/ui.cpp:2981 msgid "O&ptions..." msgstr "O&ptionen ..." -#: ../../../src/ui.cpp:2686 +#: ../../../src/ui.cpp:2984 #: ../../../src/uibase.cpp:25 msgid "E&xit" msgstr "B&eenden" -#: ../../../src/ui.cpp:2902 +#: ../../../src/ui.cpp:3210 msgid "Program has crashed and will terminate. " msgstr "Das Programm ist abgestürzt und wird beendet. " -#: ../../../src/main.cpp:1868 -msgid "Warning: Disk space is low " -msgstr "Warnung: Festplatte fast voll " - -#: ../../../src/main.cpp:3992 -#, c-format -msgid "Error: This transaction requires a transaction fee of at least %s because of its amount, complexity, or use of recently received funds " -msgstr "Fehler: Diese Überweisung benötigt eine Überweisungsgebühr von mindestens %s wegen ihrer Größe, Komplexität oder der Benutzung erst kürzlich erhaltener Geldmittel " - -#: ../../../src/main.cpp:3994 -msgid "Error: Transaction creation failed " -msgstr "Fehler: Überweisung konnte nicht erzeugt werden. " - -#: ../../../src/main.cpp:4003 -msgid "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." -msgstr "Fehler: Die Überweisung wurde abgelehnt. Das kann passieren, wenn einige der Münzen in Ihrer Brieftasche bereits ausgegeben wurden, z.B. weil Sie eine Kopie der Brieftasche (wallet.dat) gemacht haben. Bitcoins, die mithilfe der Kopie ausgegeben wurden, sind in dieser Brieftasche noch nicht als ausgegeben markiert worden." - -#: ../../../src/main.cpp:4016 -msgid "Invalid amount" -msgstr "Ungültiger Betrag" - -#: ../../../src/main.cpp:4023 -msgid "Invalid bitcoin address" -msgstr "Ungültige Bitcoin-Adresse" - -#: ../../../src/rpc.cpp:1800 -#: ../../../src/rpc.cpp:1802 -#, c-format -msgid "To use the %s option" -msgstr "Um die %s Option zu nutzen" - -#: ../../../src/rpc.cpp:1804 -#, c-format -msgid "" -"Warning: %s, you must set rpcpassword=<password>\n" -"in the configuration file: %s\n" -"If the file does not exist, create it with owner-readable-only file permissions.\n" -msgstr "" -"Warnung: %s, Sie müssen rpcpassword=<password> einstellen\n" -"in der Konfigurationsdatei: %s\n" -"Wenn die Datei nicht existiert, erstellen Sie sie mit ausschließlich Besitzer-Leserechten.\n" - -#: ../../../src/rpc.cpp:1972 -#, c-format -msgid "" -"You must set rpcpassword=<password> in the configuration file:\n" -"%s\n" -"If the file does not exist, create it with owner-readable-only file permissions." -msgstr "" -"Sie müssen rpcpassword=<password> in der Konfigurationsdatei einstellen:\n" -"%s\n" -"Wenn die Datei nicht existiert, erstellen Sie sie mit ausschließlich Besitzer-Leserechten." - -#: ../../../src/util.cpp:865 -msgid "Warning: Please check that your computer's date and time are correct. If your clock is wrong Bitcoin will not work properly." -msgstr "Warnung: Bitte überprüfen Sie die Richtigkeit des Datums und der Uhrzeit Ihres Computers. Falls Ihre Uhr falsch läuft, wird Bitcoin nicht richtig funktionieren." - -#: ../../../src/util.cpp:898 -msgid "beta" -msgstr "Beta" - #: ../../../src/uibase.cpp:28 msgid "&File" msgstr "&Datei" #: ../../../src/uibase.cpp:32 msgid "&Your Receiving Addresses..." -msgstr "&Ihre Empfangs-Adressen ..." +msgstr "&Ihre Empfangs-Adressen..." + +#: ../../../src/uibase.cpp:35 +msgid "&Encrypt Wallet..." +msgstr "Bri&eftasche verschlüsseln..." + +#: ../../../src/uibase.cpp:38 +msgid "&Change Wallet Encryption Passphrase..." +msgstr "Passphrase der Vers&chlüsselung der Brieftasche ändern..." -#: ../../../src/uibase.cpp:36 +#: ../../../src/uibase.cpp:42 msgid "&Options..." -msgstr "&Optionen ..." +msgstr "&Optionen..." -#: ../../../src/uibase.cpp:39 +#: ../../../src/uibase.cpp:45 msgid "&Settings" msgstr "&Einstellungen" -#: ../../../src/uibase.cpp:43 +#: ../../../src/uibase.cpp:49 msgid "&About..." msgstr "Ü&ber..." -#: ../../../src/uibase.cpp:46 +#: ../../../src/uibase.cpp:52 msgid "&Help" msgstr "&Hilfe" -#: ../../../src/uibase.cpp:56 +#: ../../../src/uibase.cpp:62 msgid "Address Book" msgstr "Adressbuch" -#: ../../../src/uibase.cpp:69 +#: ../../../src/uibase.cpp:75 msgid "Your Bitcoin Address:" msgstr "Ihre Bitcoin-Adresse:" -#: ../../../src/uibase.cpp:76 +#: ../../../src/uibase.cpp:82 msgid " &New... " -msgstr " &Neu ... " +msgstr " &Neu... " -#: ../../../src/uibase.cpp:79 -#: ../../../src/uibase.cpp:780 -#: ../../../src/uibase.cpp:883 +#: ../../../src/uibase.cpp:85 +#: ../../../src/uibase.cpp:790 +#: ../../../src/uibase.cpp:893 msgid " &Copy to Clipboard " msgstr " In die Zwischenablage &kopieren " -#: ../../../src/uibase.cpp:93 +#: ../../../src/uibase.cpp:99 msgid "Balance:" msgstr "Kontostand:" -#: ../../../src/uibase.cpp:109 +#: ../../../src/uibase.cpp:115 msgid " All" msgstr " Alle" -#: ../../../src/uibase.cpp:109 +#: ../../../src/uibase.cpp:115 msgid " Sent" msgstr " Überwiesen" -#: ../../../src/uibase.cpp:109 +#: ../../../src/uibase.cpp:115 msgid " Received" msgstr " Erhalten" -#: ../../../src/uibase.cpp:109 +#: ../../../src/uibase.cpp:115 msgid " In Progress" msgstr " In Bearbeitung" -#: ../../../src/uibase.cpp:130 +#: ../../../src/uibase.cpp:136 msgid "All Transactions" msgstr "Alle Überweisungen" -#: ../../../src/uibase.cpp:141 +#: ../../../src/uibase.cpp:147 msgid "Sent/Received" msgstr "Überwiesen/Erhalten" -#: ../../../src/uibase.cpp:152 +#: ../../../src/uibase.cpp:158 msgid "Sent" msgstr "Überwiesen" -#: ../../../src/uibase.cpp:163 +#: ../../../src/uibase.cpp:169 msgid "Received" msgstr "Erhalten" -#: ../../../src/uibase.cpp:302 -#: ../../../src/uibase.cpp:443 -#: ../../../src/uibase.cpp:542 -#: ../../../src/uibase.cpp:722 -#: ../../../src/uibase.cpp:783 -#: ../../../src/uibase.cpp:892 -#: ../../../src/uibase.cpp:981 +#: ../../../src/uibase.cpp:312 +#: ../../../src/uibase.cpp:453 +#: ../../../src/uibase.cpp:552 +#: ../../../src/uibase.cpp:732 +#: ../../../src/uibase.cpp:793 +#: ../../../src/uibase.cpp:902 +#: ../../../src/uibase.cpp:991 msgid "OK" msgstr "OK" -#: ../../../src/uibase.cpp:345 +#: ../../../src/uibase.cpp:355 msgid "&Start Bitcoin on system startup" msgstr "Bitcoin beim &Systemstart ausführen" -#: ../../../src/uibase.cpp:348 +#: ../../../src/uibase.cpp:358 msgid "&Minimize to the tray instead of the taskbar" msgstr "In den Infobereich statt in die Taskleiste &minimieren" -#: ../../../src/uibase.cpp:351 +#: ../../../src/uibase.cpp:361 msgid "Map port using &UPnP" msgstr "Portweiterleitung via &UPnP" -#: ../../../src/uibase.cpp:354 +#: ../../../src/uibase.cpp:364 msgid "M&inimize to the tray on close" msgstr "Beim Schließen in den Infobereich m&inimieren" -#: ../../../src/uibase.cpp:360 -msgid "&Connect through socks4 proxy: " -msgstr "&Per Socks4-Proxy verbinden: " +#: ../../../src/uibase.cpp:370 +msgid "&Connect through socks4 proxy (requires restart to apply): " +msgstr "&Per Socks4-Proxy verbinden (erfordert einen Neustart): " -#: ../../../src/uibase.cpp:371 +#: ../../../src/uibase.cpp:381 msgid "Proxy &IP:" -msgstr "Proxy &IP:" +msgstr "Proxy-&IP:" -#: ../../../src/uibase.cpp:379 +#: ../../../src/uibase.cpp:389 msgid " &Port:" msgstr " &Port:" -#: ../../../src/uibase.cpp:392 +#: ../../../src/uibase.cpp:402 msgid "Optional transaction fee per KB that helps make sure your transactions are processed quickly. Most transactions are 1KB. Fee 0.01 recommended." msgstr "Eine freiwillige Überweisungsgebühr pro KB, die dabei hilft, dass Ihre Überweisungen schnell durchgeführt werden. Die meisten Überweisungen sind 1 KB groß. Eine Gebühr von 0,01 ist empfohlen." -#: ../../../src/uibase.cpp:399 +#: ../../../src/uibase.cpp:409 msgid "Pay transaction fee:" msgstr "Überweisungsgebühr:" -#: ../../../src/uibase.cpp:420 +#: ../../../src/uibase.cpp:430 msgid "// [don't translate] Test panel 2 for future expansion" msgstr "" -#: ../../../src/uibase.cpp:424 +#: ../../../src/uibase.cpp:434 msgid "// [don't translate] Let's not start multiple pages until the first page is filled up" msgstr "" -#: ../../../src/uibase.cpp:446 -#: ../../../src/uibase.cpp:668 -#: ../../../src/uibase.cpp:727 -#: ../../../src/uibase.cpp:786 -#: ../../../src/uibase.cpp:895 -#: ../../../src/uibase.cpp:984 +#: ../../../src/uibase.cpp:456 +#: ../../../src/uibase.cpp:678 +#: ../../../src/uibase.cpp:737 +#: ../../../src/uibase.cpp:796 +#: ../../../src/uibase.cpp:905 +#: ../../../src/uibase.cpp:994 msgid "Cancel" msgstr "Abbrechen" -#: ../../../src/uibase.cpp:449 +#: ../../../src/uibase.cpp:459 msgid "&Apply" msgstr "&Anwenden" -#: ../../../src/uibase.cpp:508 +#: ../../../src/uibase.cpp:518 msgid "Bitcoin " msgstr "Bitcoin " -#: ../../../src/uibase.cpp:514 +#: ../../../src/uibase.cpp:524 msgid "version" msgstr "Version" -#: ../../../src/uibase.cpp:525 +#: ../../../src/uibase.cpp:535 msgid "" "Copyright (c) 2009-2011 Bitcoin Developers\n" "\n" @@ -705,39 +960,39 @@ msgstr "" "kryptographische Software von Eric Young (eay@cryptsoft.com)\n" "und UPnP-Software, entwickelt von Thomas Bernard." -#: ../../../src/uibase.cpp:581 +#: ../../../src/uibase.cpp:591 msgid "Enter a Bitcoin address (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L)" msgstr "Geben Sie eine Bitcoin-Adresse ein (z.B. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L)" -#: ../../../src/uibase.cpp:595 +#: ../../../src/uibase.cpp:605 msgid "Pay &To:" msgstr "Überweisen &An:" -#: ../../../src/uibase.cpp:610 +#: ../../../src/uibase.cpp:620 msgid "&Paste" msgstr "&Einfügen" -#: ../../../src/uibase.cpp:613 +#: ../../../src/uibase.cpp:623 msgid " Address &Book..." msgstr " Address&buch..." -#: ../../../src/uibase.cpp:620 +#: ../../../src/uibase.cpp:630 msgid "&Amount:" msgstr "&Betrag:" -#: ../../../src/uibase.cpp:630 +#: ../../../src/uibase.cpp:640 msgid "T&ransfer:" msgstr "Ü&berweisung:" -#: ../../../src/uibase.cpp:636 +#: ../../../src/uibase.cpp:646 msgid " Standard" msgstr " Standard" -#: ../../../src/uibase.cpp:663 +#: ../../../src/uibase.cpp:673 msgid "&Send" msgstr "Ü&berweisen" -#: ../../../src/uibase.cpp:711 +#: ../../../src/uibase.cpp:721 msgid "" "\n" "\n" @@ -747,229 +1002,80 @@ msgstr "" "\n" "Verbinde ..." -#: ../../../src/uibase.cpp:761 +#: ../../../src/uibase.cpp:771 msgid "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. The highlighted address is displayed in the main window." msgstr "Dies sind Ihre Bitcoin-Adressen zum Empfang von Zahlungen. Sie sollten vielleicht jedem Überweisenden eine andere Adresse geben um nachvollziehen zu können von wem eine Zahlung stammt. Die markierte Adresse wird im Hauptfenster angezeigt." -#: ../../../src/uibase.cpp:774 -#: ../../../src/uibase.cpp:886 +#: ../../../src/uibase.cpp:784 +#: ../../../src/uibase.cpp:896 msgid "&Edit..." -msgstr "&Bearbeiten ..." +msgstr "&Bearbeiten..." -#: ../../../src/uibase.cpp:777 -#: ../../../src/uibase.cpp:889 +#: ../../../src/uibase.cpp:787 +#: ../../../src/uibase.cpp:899 msgid " &New Address... " -msgstr " &Neue Adresse ... " +msgstr " &Neue Adresse... " -#: ../../../src/uibase.cpp:849 +#: ../../../src/uibase.cpp:859 msgid "Sending" msgstr "Überweise" -#: ../../../src/uibase.cpp:857 +#: ../../../src/uibase.cpp:867 msgid "These are your Bitcoin addresses for receiving payments. You can give a different one to each sender to keep track of who is paying you. The highlighted address will be displayed in the main window." msgstr "Dies sind Ihre Bitcoin-Adressen zum Empfang von Zahlungen. Sie können jedem Überweisenden eine andere Adresse geben um nachvollziehen zu können von wem eine Zahlung stammt. Die markierte Adresse wird im Hauptfenster angezeigt." -#: ../../../src/uibase.cpp:870 +#: ../../../src/uibase.cpp:880 msgid "Receiving" msgstr "Empfange" -#: ../../../src/uibase.cpp:880 +#: ../../../src/uibase.cpp:890 msgid "&Delete" msgstr "&Löschen" -#: ../../../src/init.cpp:147 -msgid "Bitcoin version" -msgstr "Bitcoin " - -#: ../../../src/init.cpp:148 -msgid "Usage:" -msgstr "Benutz:" - -#: ../../../src/init.cpp:150 -msgid "Send command to -server or bitcoind\n" -msgstr "Sende Befehl zu -server oder bitcoind\n" - -#: ../../../src/init.cpp:151 -msgid "List commands\n" -msgstr "Liste Befehle auf\n" - -#: ../../../src/init.cpp:152 -msgid "Get help for a command\n" -msgstr "Hilfe für einen Befehl erhalten\n" - -#: ../../../src/init.cpp:153 -msgid "Options:\n" -msgstr "Optionen:\n" - -#: ../../../src/init.cpp:154 -msgid "Specify configuration file (default: bitcoin.conf)\n" -msgstr "Konfigurationsdatei bestimmen (Standard: bitcoin.conf)\n" - -#: ../../../src/init.cpp:155 -msgid "Specify pid file (default: bitcoind.pid)\n" -msgstr "pid-Datei bestimmen (Standard: bitcoind.pid)\n" - -#: ../../../src/init.cpp:156 -msgid "Generate coins\n" -msgstr "Münzen erzeugen\n" - -#: ../../../src/init.cpp:157 -msgid "Don't generate coins\n" -msgstr "Keine Münzen erzeugen\n" - -#: ../../../src/init.cpp:158 -msgid "Start minimized\n" -msgstr "Minimiert starten\n" - -#: ../../../src/init.cpp:159 -msgid "Specify data directory\n" -msgstr "Datenverzeichnis festlegen\n" - -#: ../../../src/init.cpp:160 -msgid "Connect through socks4 proxy\n" -msgstr "Socks4-Proxy verwenden\n" - -#: ../../../src/init.cpp:161 -msgid "Specify connection timeout (in milliseconds)\n" -msgstr "Verbindungs-Timeout in Milisekunden\n" - -#: ../../../src/init.cpp:161 -msgid "Allow DNS lookups for addnode and connect\n" -msgstr "DNS-Auflösung für addnode und connect erlauben\n" - -#: ../../../src/init.cpp:162 -msgid "Add a node to connect to\n" -msgstr "Einen Teilnehmer hinzufügen, zu dem verbunden werden soll\n" - -#: ../../../src/init.cpp:163 -msgid "Connect only to the specified node\n" -msgstr "Nur zu dem angegebenen Teilnehmer verbinden\n" - -#: ../../../src/init.cpp:164 -msgid "Don't accept connections from outside\n" -msgstr "Akzeptiere keine externen Verbindungen\n" - -#: ../../../src/init.cpp:167 -msgid "Don't attempt to use UPnP to map the listening port\n" -msgstr "Versuche nicht, UPnP zur Portweiterleitung zu nutzen\n" - -#: ../../../src/init.cpp:169 -msgid "Attempt to use UPnP to map the listening port\n" -msgstr "Versuche, UPnP zur Portweiterleitung zu nutzen\n" - -#: ../../../src/init.cpp:172 -msgid "Fee per KB to add to transactions you send\n" -msgstr "Gebühr pro KB für Überweisungen, die Sie tätigen\n" - -#: ../../../src/init.cpp:174 -msgid "Accept command line and JSON-RPC commands\n" -msgstr "Akzeptiere Kommandozeile und JSON-RPC-Befehle\n" - -#: ../../../src/init.cpp:177 -msgid "Run in the background as a daemon and accept commands\n" -msgstr "Laufe im Hintergrund als Daemon und akzeptiere Befehle\n" - -#: ../../../src/init.cpp:179 -msgid "Use the test network\n" -msgstr "Nutze das Testnetzwerk\n" - -#: ../../../src/init.cpp:180 -msgid "Username for JSON-RPC connections\n" -msgstr "Benutzername für JSON-RPC-Verbindungen\n" - -#: ../../../src/init.cpp:181 -msgid "Password for JSON-RPC connections\n" -msgstr "Passwort für JSON-RPC-Verbindungen\n" - -#: ../../../src/init.cpp:182 -msgid "Listen for JSON-RPC connections on <port> (default: 8332)\n" -msgstr "Horche für JSON-RPC-Verbindungen auf <port> (Standard: 8332)\n" - -#: ../../../src/init.cpp:183 -msgid "Allow JSON-RPC connections from specified IP address\n" -msgstr "Erlaube JSON-RPC-Verbindungen von bestimmter IP-Adresse\n" - -#: ../../../src/init.cpp:184 -msgid "Send commands to node running on <ip> (default: 127.0.0.1)\n" -msgstr "Sende Befehle zum Knoten mit <ip> (Standard: 127.0.0.1)\n" - -#: ../../../src/init.cpp:185 -msgid "Set key pool size to <n> (default: 100)\n" -msgstr "Setze Key-Pool-Größe auf <n> (Standard: 100)\n" - -#: ../../../src/init.cpp:186 -msgid "Rescan the block chain for missing wallet transactions\n" -msgstr "Frage die Block-Kette nach fehlenden Brieftaschen-Überweisungen ab\n" - -#: ../../../src/init.cpp:190 -msgid "" -"\n" -"SSL options: (see the Bitcoin Wiki for SSL setup instructions)\n" -msgstr "" -"\n" -"SSL-Optionen: (siehe das Bitcoin-Wiki für SSL-Installationsanleitungen)\n" - -#: ../../../src/init.cpp:191 -msgid "Use OpenSSL (https) for JSON-RPC connections\n" -msgstr "Nutze OpenSSL (https) für JSON-RPC-Verbindungen\n" - -#: ../../../src/init.cpp:192 -msgid "Server certificate file (default: server.cert)\n" -msgstr "Server-Zertifikatsdatei (Standard: server.cert)\n" +#: ../../../src/util.cpp:869 +msgid "Warning: Please check that your computer's date and time are correct. If your clock is wrong Bitcoin will not work properly." +msgstr "Warnung: Bitte überprüfen Sie die Richtigkeit des Datums und der Uhrzeit Ihres Computers. Falls Ihre Uhr falsch läuft, wird Bitcoin nicht richtig funktionieren." -#: ../../../src/init.cpp:193 -msgid "Server private key (default: server.pem)\n" -msgstr "Server-Geheimschlüssel (Standard: server.pem)\n" +#: ../../../src/util.cpp:903 +msgid "beta" +msgstr "Beta" -#: ../../../src/init.cpp:194 -msgid "Acceptable ciphers (default: TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!AH:!3DES:@STRENGTH)\n" -msgstr "Anzunehmende Verschlüsselungen (Standard: TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!AH:!3DES:@STRENGTH)\n" +#: ../../../src/wallet.cpp:1083 +msgid "Error: Wallet locked, unable to create transaction " +msgstr "Fehler: Brieftasche ist verschlossen; Überweisung konnte nicht erstellt werden " -#: ../../../src/init.cpp:198 -msgid "This help message\n" -msgstr "Diese Anleitung\n" - -#: ../../../src/init.cpp:335 +#: ../../../src/wallet.cpp:1091 #, c-format -msgid "Cannot obtain a lock on data directory %s. Bitcoin is probably already running." -msgstr "Erhalte keinen Lock für Datenverzeichnis %s. Bitcoin läuft wahrscheinlich bereits." - -#: ../../../src/init.cpp:361 -msgid "Error loading addr.dat \n" -msgstr "Fehler beim Laden von addr.dat \n" - -#: ../../../src/init.cpp:367 -msgid "Error loading blkindex.dat \n" -msgstr "Fehler beim Laden von blkindex.dat \n" - -#: ../../../src/init.cpp:374 -msgid "Error loading wallet.dat \n" -msgstr "Fehler beim Laden von wallet.dat \n" +msgid "Error: This transaction requires a transaction fee of at least %s because of its amount, complexity, or use of recently received funds " +msgstr "Fehler: Diese Überweisung benötigt eine Überweisungsgebühr von mindestens %s wegen ihrer Größe, Komplexität oder der Benutzung erst kürzlich erhaltener Geldmittel " -#: ../../../src/init.cpp:454 -msgid "Invalid -proxy address" -msgstr "Ungültige -Proxy Adresse" +#: ../../../src/wallet.cpp:1093 +msgid "Error: Transaction creation failed " +msgstr "Fehler: Überweisung konnte nicht erzeugt werden. " -#: ../../../src/init.cpp:477 -msgid "Invalid amount for -paytxfee=<amount>" -msgstr "Ungültiger Betrag für -paytxfee=<amount>" +#: ../../../src/wallet.cpp:1103 +msgid "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." +msgstr "Fehler: Die Überweisung wurde abgelehnt. Das kann passieren, wenn einige der Münzen in Ihrer Brieftasche bereits ausgegeben wurden, z.B. weil Sie eine Kopie der Brieftasche (wallet.dat) gemacht haben. Bitcoins, die mithilfe der Kopie ausgegeben wurden, sind in dieser Brieftasche noch nicht als ausgegeben markiert worden." -#: ../../../src/init.cpp:481 -msgid "Warning: -paytxfee is set very high. This is the transaction fee you will pay if you send a transaction." -msgstr "Warnung: -paytxfee ist sehr hoch gesetzt. Das ist die Überweisungsgebühr, die Sie fürs Senden einer Überweisung zahlen." +#: ../../../src/wallet.cpp:1116 +msgid "Invalid amount" +msgstr "Ungültiger Betrag" -#: ../../../src/uibase.h:147 +#: ../../../src/uibase.h:151 msgid "Transaction Details" msgstr "Überweisungsdetails" -#: ../../../src/uibase.h:199 +#: ../../../src/uibase.h:203 msgid "Options" msgstr "Optionen" -#: ../../../src/uibase.h:228 +#: ../../../src/uibase.h:232 msgid "About Bitcoin" msgstr "Über Bitcoin" -#: ../../../src/uibase.h:337 +#: ../../../src/uibase.h:341 msgid "Your Bitcoin Addresses" msgstr "Ihre Bitcoin-Adressen" + +#~ msgid "Invalid bitcoin address" +#~ msgstr "Ungültige Bitcoin-Adresse" diff --git a/locale/es/LC_MESSAGES/bitcoin.po b/locale/es/LC_MESSAGES/bitcoin.po index c67886e676..1787c4891b 100644 --- a/locale/es/LC_MESSAGES/bitcoin.po +++ b/locale/es/LC_MESSAGES/bitcoin.po @@ -2,126 +2,433 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2011-05-24 20:21-0500\n" -"PO-Revision-Date: 2011-05-24 20:23-0500\n" -"Last-Translator: Ariel Patiño <ariel@ficticio.com>\n" +"POT-Creation-Date: 2011-09-06 21:58+0100\n" +"PO-Revision-Date: 2011-09-06 22:19+0100\n" +"Last-Translator: Alex B <paraipanakos@gmail.com>\n" "Language-Team: \n" -"Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" +"Language: \n" "X-Poedit-KeywordsList: _;gettext;gettext_noop\n" "X-Poedit-Basepath: .\n" "X-Poedit-SearchPath-0: ../../..\n" -#: ../../../src/net.cpp:1503 +#: ../../../src/init.cpp:163 +msgid "Bitcoin version" +msgstr "versión Bitcoin" + +#: ../../../src/init.cpp:164 +msgid "Usage:" +msgstr "Uso:" + +#: ../../../src/init.cpp:166 +msgid "Send command to -server or bitcoind\n" +msgstr "Envia comando a bitcoin lanzado con -server u bitcoind\n" + +#: ../../../src/init.cpp:167 +msgid "List commands\n" +msgstr "Muestra comandos\n" + +#: ../../../src/init.cpp:168 +msgid "Get help for a command\n" +msgstr "Recibir ayuda para un comando\n" + +#: ../../../src/init.cpp:169 +msgid "Options:\n" +msgstr "Opciones:\n" + +#: ../../../src/init.cpp:170 +msgid "Specify configuration file (default: bitcoin.conf)\n" +msgstr "Especifica archivo de configuración (predeterminado: bitcoin.conf)\n" + +#: ../../../src/init.cpp:171 +msgid "Specify pid file (default: bitcoind.pid)\n" +msgstr "Especifica archivo pid (predeterminado: bitcoin.pid)\n" + +#: ../../../src/init.cpp:172 +msgid "Generate coins\n" +msgstr "Genera monedas\n" + +#: ../../../src/init.cpp:173 +msgid "Don't generate coins\n" +msgstr "No generar monedas\n" + +#: ../../../src/init.cpp:174 +msgid "Start minimized\n" +msgstr "Arranca minimizado\n" + +#: ../../../src/init.cpp:175 +msgid "Specify data directory\n" +msgstr "Especifica directorio para los datos\n" + +#: ../../../src/init.cpp:176 +msgid "Specify connection timeout (in milliseconds)\n" +msgstr "Especifica tiempo de espera para conexion (en milisegundos)\n" + +#: ../../../src/init.cpp:177 +msgid "Connect through socks4 proxy\n" +msgstr "Conecta mediante proxy socks4\n" + +#: ../../../src/init.cpp:178 +msgid "Allow DNS lookups for addnode and connect\n" +msgstr "Permite búsqueda DNS para addnode y connect\n" + +#: ../../../src/init.cpp:179 +msgid "Add a node to connect to\n" +msgstr "Agrega un nodo para conectarse\n" + +#: ../../../src/init.cpp:180 +msgid "Connect only to the specified node\n" +msgstr "Conecta solo al nodo especificado\n" + +#: ../../../src/init.cpp:181 +msgid "Don't accept connections from outside\n" +msgstr "No aceptar conexiones desde el exterior\n" + +#: ../../../src/init.cpp:184 +msgid "Don't attempt to use UPnP to map the listening port\n" +msgstr "No intentar usar UPnP para mapear el puerto de entrada\n" + +#: ../../../src/init.cpp:186 +msgid "Attempt to use UPnP to map the listening port\n" +msgstr "Intenta usar UPnP para mapear el puerto de escucha.\n" + +#: ../../../src/init.cpp:189 +msgid "Fee per KB to add to transactions you send\n" +msgstr "Comisión por KB para agregar a las transacciones que envias\n" + +#: ../../../src/init.cpp:191 +msgid "Accept command line and JSON-RPC commands\n" +msgstr "Aceptar comandos consola y JSON-RPC\n" + +#: ../../../src/init.cpp:194 +msgid "Run in the background as a daemon and accept commands\n" +msgstr "Correr como demonio y acepta comandos\n" + +#: ../../../src/init.cpp:196 +msgid "Use the test network\n" +msgstr "Usa la red de pruebas\n" + +#: ../../../src/init.cpp:197 +msgid "Username for JSON-RPC connections\n" +msgstr "Usuario para las conexiones JSON-RPC\n" + +#: ../../../src/init.cpp:198 +msgid "Password for JSON-RPC connections\n" +msgstr "Contraseña para las conexiones JSON-RPC\n" + +#: ../../../src/init.cpp:199 +msgid "Listen for JSON-RPC connections on <port> (default: 8332)\n" +msgstr "Escucha conexiones JSON-RPC en el puerto <port> (predeterminado: 8332)\n" + +#: ../../../src/init.cpp:200 +msgid "Allow JSON-RPC connections from specified IP address\n" +msgstr "Permite conexiones JSON-RPC desde la dirección IP especificada\n" + +#: ../../../src/init.cpp:201 +msgid "Send commands to node running on <ip> (default: 127.0.0.1)\n" +msgstr "Envia comando al nodo situado en <ip> (predeterminado: 127.0.0.1)\n" + +#: ../../../src/init.cpp:202 +msgid "Set key pool size to <n> (default: 100)\n" +msgstr "Ajusta el numero de claves en reserva <n> (predeterminado: 100)\n" + +#: ../../../src/init.cpp:203 +msgid "Rescan the block chain for missing wallet transactions\n" +msgstr "Rescanea la cadena de bloques para transacciones perdidas de la cartera\n" + +#: ../../../src/init.cpp:207 +msgid "" +"\n" +"SSL options: (see the Bitcoin Wiki for SSL setup instructions)\n" +msgstr "" +"\n" +"Opciones SSL: (ver la Bitcoin Wiki para instrucciones de configuración SSL)\n" + +#: ../../../src/init.cpp:208 +msgid "Use OpenSSL (https) for JSON-RPC connections\n" +msgstr "Usa OpenSSL (https) para las conexiones JSON-RPC\n" + +#: ../../../src/init.cpp:209 +msgid "Server certificate file (default: server.cert)\n" +msgstr "Archivo de certificado del servidor (Predeterminado: server.cert)\n" + +#: ../../../src/init.cpp:210 +msgid "Server private key (default: server.pem)\n" +msgstr "Clave privada del servidor (Predeterminado: server.pem)\n" + +#: ../../../src/init.cpp:211 +msgid "Acceptable ciphers (default: TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!AH:!3DES:@STRENGTH)\n" +msgstr "Cifrados aceptados (Predeterminado: TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!AH:!3DES:@STRENGTH)\n" + +#: ../../../src/init.cpp:215 +msgid "This help message\n" +msgstr "Este mensaje de ayuda\n" + +#: ../../../src/init.cpp:353 +#, c-format +msgid "Cannot obtain a lock on data directory %s. Bitcoin is probably already running." +msgstr "No se puede obtener permiso de trabajo en la carpeta de datos %s. Probablemente Bitcoin ya se está ejecutando." + +#: ../../../src/init.cpp:379 +msgid "Error loading addr.dat \n" +msgstr "Error cargando addr.dat \n" + +#: ../../../src/init.cpp:385 +msgid "Error loading blkindex.dat \n" +msgstr "Error cargando blkindex.dat \n" + +#: ../../../src/init.cpp:396 +msgid "Error loading wallet.dat: Wallet corrupted \n" +msgstr "Error cargando wallet.dat: Cartera dañada \n" + +#: ../../../src/init.cpp:398 +msgid "Error loading wallet.dat: Wallet requires newer version of Bitcoin \n" +msgstr "Error cargando el archivo wallet.dat: Se necesita una versión mas nueva de Bitcoin \n" + +#: ../../../src/init.cpp:400 +msgid "Error loading wallet.dat \n" +msgstr "Error cargando wallet.dat \n" + +#: ../../../src/init.cpp:489 +msgid "Invalid -proxy address" +msgstr "Dirección -proxy no valida" + +#: ../../../src/init.cpp:514 +msgid "Invalid amount for -paytxfee=<amount>" +msgstr "Cantidad inválida para -paytxfee=<amount>" + +#: ../../../src/init.cpp:518 +msgid "Warning: -paytxfee is set very high. This is the transaction fee you will pay if you send a transaction." +msgstr "Precaución: -paytxfee es muy alta. Esta es la comisión que pagarás si envias una transacción." + +#: ../../../src/main.cpp:1398 +msgid "Warning: Disk space is low " +msgstr "Cuidado: Poco espacio en el disco duro" + +#: ../../../src/net.cpp:1610 #, c-format msgid "Unable to bind to port %d on this computer. Bitcoin is probably already running." -msgstr "No es posible escuchar en el puerto %d en este computador. Probablemente el cliente Bitcoin ya se está ejecutando." +msgstr "No es posible escuchar en el puerto %d en este ordenador. Probablemente Bitcoin ya se está ejecutando." -#: ../../../src/ui.cpp:204 +#: ../../../src/rpc.cpp:2005 +#: ../../../src/rpc.cpp:2007 +#, c-format +msgid "To use the %s option" +msgstr "Para usar la opción %s" + +#: ../../../src/rpc.cpp:2009 +#, c-format +msgid "" +"Warning: %s, you must set rpcpassword=<password>\n" +"in the configuration file: %s\n" +"If the file does not exist, create it with owner-readable-only file permissions.\n" +msgstr "" +"Precaución: %s, debes especificar rpcpassword=<password>\n" +"en el archivo de configuración: %s\n" +"Si el archivo no existe, debes crearlo con permisos de lectura al autor solamente.\n" + +#: ../../../src/rpc.cpp:2185 +#, c-format +msgid "" +"You must set rpcpassword=<password> in the configuration file:\n" +"%s\n" +"If the file does not exist, create it with owner-readable-only file permissions." +msgstr "" +"Debes especificar rpcpassword=<password> en el archivo de configuración:\n" +"%s\n" +"Si el archivo no existe, debes crearlo con permisos de lectura al autor solamente." + +#: ../../../src/ui.cpp:217 #, c-format msgid "This transaction is over the size limit. You can still send it for a fee of %s, which goes to the nodes that process your transaction and helps to support the network. Do you want to pay the fee?" -msgstr "Esta transacción supera el límite. Puede seguir enviandola con una comisión de %s, que va a los nodos que procesan su transacción y ayuda a mantener la red. ¿Quiere pagar la comisión?" +msgstr "Esta transacción supera el límite. Puedes seguir enviandola incluyendo una comisión de %s que se va a repartir entre los nodos que procesan su transacción y ayudan a mantener la red. ¿Quieres seguir con la transacción?" + +#: ../../../src/ui.cpp:261 +#: ../../../src/ui.cpp:1247 +msgid "Enter the current passphrase to the wallet." +msgstr "Introduce la contraseña actual de la cartera." -#: ../../../src/ui.cpp:303 +#: ../../../src/ui.cpp:262 +#: ../../../src/ui.cpp:1183 +#: ../../../src/ui.cpp:1200 +#: ../../../src/ui.cpp:1248 +#: ../../../src/ui.cpp:1272 +#: ../../../src/ui.cpp:1292 +msgid "Passphrase" +msgstr "Contraseña" + +#: ../../../src/ui.cpp:268 +msgid "Please supply the current wallet decryption passphrase." +msgstr "Por favor introduce la contraseña actual de la cartera." + +#: ../../../src/ui.cpp:276 +#: ../../../src/ui.cpp:1257 +#: ../../../src/ui.cpp:1314 +msgid "The passphrase entered for the wallet decryption was incorrect." +msgstr "La contraseña introducida para decriptar la cartera es incorrecta." + +#: ../../../src/ui.cpp:353 msgid "Status" msgstr "Estado" -#: ../../../src/ui.cpp:304 +#: ../../../src/ui.cpp:354 msgid "Date" msgstr "Fecha" -#: ../../../src/ui.cpp:305 +#: ../../../src/ui.cpp:355 msgid "Description" msgstr "Descripción" -#: ../../../src/ui.cpp:306 +#: ../../../src/ui.cpp:356 msgid "Debit" msgstr "Débito" -#: ../../../src/ui.cpp:307 +#: ../../../src/ui.cpp:357 msgid "Credit" msgstr "Crédito" -#: ../../../src/ui.cpp:513 +#: ../../../src/ui.cpp:568 #, c-format msgid "Open for %d blocks" msgstr "Abrir para %d bloques" -#: ../../../src/ui.cpp:515 +#: ../../../src/ui.cpp:570 #, c-format msgid "Open until %s" msgstr "Abrir hasta %s" -#: ../../../src/ui.cpp:521 +#: ../../../src/ui.cpp:576 #, c-format msgid "%d/offline?" msgstr "%d/desconectado?" -#: ../../../src/ui.cpp:523 +#: ../../../src/ui.cpp:578 #, c-format msgid "%d/unconfirmed" msgstr "%d/no confirmado" -#: ../../../src/ui.cpp:525 +#: ../../../src/ui.cpp:580 #, c-format msgid "%d confirmations" msgstr "%d confirmaciones" -#: ../../../src/ui.cpp:610 +#: ../../../src/ui.cpp:665 msgid "Generated" msgstr "Generado" -#: ../../../src/ui.cpp:618 +#: ../../../src/ui.cpp:673 #, c-format msgid "Generated (%s matures in %d more blocks)" msgstr "Generado (%s madura en %d bloques)" -#: ../../../src/ui.cpp:622 +#: ../../../src/ui.cpp:677 msgid "Generated - Warning: This block was not received by any other nodes and will probably not be accepted!" msgstr "Generado - Cuidado: Este bloque no se recibió de otros nodos y probablemente no sea aceptado!" -#: ../../../src/ui.cpp:626 +#: ../../../src/ui.cpp:681 msgid "Generated (not accepted)" msgstr "Generado (no aceptado)" -#: ../../../src/ui.cpp:636 +#: ../../../src/ui.cpp:691 msgid "From: " msgstr "De: " -#: ../../../src/ui.cpp:660 +#: ../../../src/ui.cpp:715 msgid "Received with: " msgstr "Recibido con: " -#: ../../../src/ui.cpp:706 +#: ../../../src/ui.cpp:760 msgid "Payment to yourself" -msgstr "Pago para usted mismo" +msgstr "Pago a ti mismo" -#: ../../../src/ui.cpp:740 +#: ../../../src/ui.cpp:794 msgid "To: " msgstr "Para: " -#: ../../../src/ui.cpp:1055 +#: ../../../src/ui.cpp:1109 msgid " Generating" msgstr " Generando" -#: ../../../src/ui.cpp:1057 +#: ../../../src/ui.cpp:1111 msgid "(not connected)" msgstr "(no conectado)" -#: ../../../src/ui.cpp:1060 +#: ../../../src/ui.cpp:1114 #, c-format msgid " %d connections %d blocks %d transactions" msgstr " %d conexiones %d bloques %d transacciones" -#: ../../../src/ui.cpp:1165 -#: ../../../src/ui.cpp:2529 +#: ../../../src/ui.cpp:1171 +msgid "Wallet already encrypted." +msgstr "La cartera ya esta encriptada." + +#: ../../../src/ui.cpp:1182 +msgid "" +"Enter the new passphrase to the wallet.\n" +"Please use a passphrase of 10 or more random characters, or eight or more words." +msgstr "" +"Introduce la nueva contraseña de cartera.\n" +"Por favor utiliza un contraseña de 10 o mas caracteres aleatorios, u ocho o mas palabras." + +#: ../../../src/ui.cpp:1189 +#: ../../../src/ui.cpp:1280 +msgid "Error: The supplied passphrase was too short." +msgstr "Error: La contraseña introducida es demasiado corta." + +#: ../../../src/ui.cpp:1193 +msgid "" +"WARNING: If you encrypt your wallet and lose your passphrase, you will LOSE ALL OF YOUR BITCOINS!\n" +"Are you sure you wish to encrypt your wallet?" +msgstr "" +"ATENCION: ¡Si encriptas tu cartera y pierdes la contraseña perderas TODOS TUS BITCOINS!\n" +"¿Seguro que quieres seguir encriptando la cartera?" + +#: ../../../src/ui.cpp:1199 +msgid "Please re-enter your new wallet passphrase." +msgstr "Por favor vuelve introducir la nueva contraseña." + +#: ../../../src/ui.cpp:1208 +#: ../../../src/ui.cpp:1302 +msgid "Error: the supplied passphrases didn't match." +msgstr "Error: las contraseñas no son identicas." + +#: ../../../src/ui.cpp:1218 +msgid "Wallet encryption failed." +msgstr "Encriptacion de cartera fallida." + +#: ../../../src/ui.cpp:1225 +msgid "" +"Wallet Encrypted.\n" +"Remember that encrypting your wallet cannot fully protect your bitcoins from being stolen by malware infecting your computer." +msgstr "" +"Cartera Encriptada.\n" +"Recuerda que encriptando tu cartera no garantiza mantener a salvo tus bitcoins en caso de tener viruses en el ordenador." + +#: ../../../src/ui.cpp:1236 +msgid "Wallet is unencrypted, please encrypt it first." +msgstr "Cartera no encriptada, intenta encriptar primero." + +#: ../../../src/ui.cpp:1271 +msgid "Enter the new passphrase for the wallet." +msgstr "Introduce la nueva contraseña para la cartera." + +#: ../../../src/ui.cpp:1291 +msgid "Re-enter the new passphrase for the wallet." +msgstr "Reintroduce la nueva contraseña para la cartera." + +#: ../../../src/ui.cpp:1323 +msgid "Wallet Passphrase Changed." +msgstr "Contraseña de cartera cambiada." + +#: ../../../src/ui.cpp:1379 +#: ../../../src/ui.cpp:2825 msgid "New Receiving Address" msgstr "Nueva dirección de recepción" -#: ../../../src/ui.cpp:1166 -#: ../../../src/ui.cpp:2530 +#: ../../../src/ui.cpp:1380 +#: ../../../src/ui.cpp:2826 msgid "" "You should use a new address for each payment you receive.\n" "\n" @@ -131,399 +438,338 @@ msgstr "" "\n" "Etiqueta" -#: ../../../src/ui.cpp:1235 +#: ../../../src/ui.cpp:1464 msgid "<b>Status:</b> " msgstr "<b>Estado:</b> " -#: ../../../src/ui.cpp:1240 +#: ../../../src/ui.cpp:1469 msgid ", has not been successfully broadcast yet" msgstr ", no ha sido emitido satisfactoriamente todavía" -#: ../../../src/ui.cpp:1242 +#: ../../../src/ui.cpp:1471 #, c-format msgid ", broadcast through %d node" msgstr ", emitido mediante %d nodo" -#: ../../../src/ui.cpp:1244 +#: ../../../src/ui.cpp:1473 #, c-format msgid ", broadcast through %d nodes" msgstr ", emitido mediante %d nodos" -#: ../../../src/ui.cpp:1248 +#: ../../../src/ui.cpp:1477 msgid "<b>Date:</b> " msgstr "<b>Fecha:</b> " -#: ../../../src/ui.cpp:1256 +#: ../../../src/ui.cpp:1485 msgid "<b>Source:</b> Generated<br>" msgstr "<b>Fuente:</b> Generado<br>" -#: ../../../src/ui.cpp:1262 -#: ../../../src/ui.cpp:1280 +#: ../../../src/ui.cpp:1491 +#: ../../../src/ui.cpp:1508 msgid "<b>From:</b> " msgstr "<b>De:</b> " -#: ../../../src/ui.cpp:1280 +#: ../../../src/ui.cpp:1508 msgid "unknown" msgstr "desconocido" -#: ../../../src/ui.cpp:1281 -#: ../../../src/ui.cpp:1305 -#: ../../../src/ui.cpp:1364 +#: ../../../src/ui.cpp:1509 +#: ../../../src/ui.cpp:1533 +#: ../../../src/ui.cpp:1592 msgid "<b>To:</b> " msgstr "<b>Para:</b> " -#: ../../../src/ui.cpp:1284 +#: ../../../src/ui.cpp:1512 msgid " (yours, label: " -msgstr "(suya, etiqueta: " +msgstr "(tuya, etiqueta: " -#: ../../../src/ui.cpp:1286 +#: ../../../src/ui.cpp:1514 msgid " (yours)" -msgstr "(suya)" +msgstr "(tuya)" -#: ../../../src/ui.cpp:1323 -#: ../../../src/ui.cpp:1335 -#: ../../../src/ui.cpp:1381 -#: ../../../src/ui.cpp:1398 +#: ../../../src/ui.cpp:1551 +#: ../../../src/ui.cpp:1563 +#: ../../../src/ui.cpp:1609 +#: ../../../src/ui.cpp:1626 msgid "<b>Credit:</b> " msgstr "<b>Crédito:</b> " -#: ../../../src/ui.cpp:1325 +#: ../../../src/ui.cpp:1553 #, c-format msgid "(%s matures in %d more blocks)" msgstr "(%s madura en %d bloques)" -#: ../../../src/ui.cpp:1327 +#: ../../../src/ui.cpp:1555 msgid "(not accepted)" msgstr "(no aceptada)" -#: ../../../src/ui.cpp:1372 -#: ../../../src/ui.cpp:1380 -#: ../../../src/ui.cpp:1395 +#: ../../../src/ui.cpp:1600 +#: ../../../src/ui.cpp:1608 +#: ../../../src/ui.cpp:1623 msgid "<b>Debit:</b> " msgstr "<b>Débito:</b> " -#: ../../../src/ui.cpp:1386 +#: ../../../src/ui.cpp:1614 msgid "<b>Transaction fee:</b> " msgstr "<b>Comisión transacción:</b> " -#: ../../../src/ui.cpp:1402 +#: ../../../src/ui.cpp:1630 msgid "<b>Net amount:</b> " -msgstr "<b>Cantidad de la red:</b> " +msgstr "<b>Cantidad total:</b> " -#: ../../../src/ui.cpp:1409 +#: ../../../src/ui.cpp:1637 msgid "Message:" msgstr "Mensaje:" -#: ../../../src/ui.cpp:1411 +#: ../../../src/ui.cpp:1639 msgid "Comment:" msgstr "Comentario:" -#: ../../../src/ui.cpp:1414 +#: ../../../src/ui.cpp:1642 msgid "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 \"not accepted\" and not be spendable. This may occasionally happen if another node generates a block within a few seconds of yours." -msgstr "Las monedas generadas deben esperar 120 bloques antes de ser gastadas. Cuando usted generó este bloque, fue emitido a la red para ser agregado a la cadena de bloques. Si falla al incluirse en la cadena, cambiará a \"no aceptado\" y no se podrá gastar. Esto puede ocurrir ocasionalmente si otro nodo genera un bloque apenas a unos segundos del suyo." +msgstr "Las monedas generadas deben esperar 120 bloques antes de ser gastadas. Cuando has generado este bloque se emitió a la red para ser agregado en la cadena de bloques. Si falla al incluirse en la cadena, cambiará a \"no aceptado\" y no se podrá gastar. Esto puede ocurrir ocasionalmente si otro nodo genera un bloque casi al mismo tiempo que el tuyo." -#: ../../../src/ui.cpp:1594 +#: ../../../src/ui.cpp:1826 msgid "Cannot write autostart/bitcoin.desktop file" msgstr "No se puede escribir el fichero autostart/bitcoin.desktop" -#: ../../../src/ui.cpp:1630 +#: ../../../src/ui.cpp:1862 msgid "Main" msgstr "Principal" -#: ../../../src/ui.cpp:1638 +#: ../../../src/ui.cpp:1872 msgid "&Start Bitcoin on window system startup" -msgstr "&Arrancar Bitcoin al iniciar el sistema" +msgstr "&Arranca Bitcoin al iniciar el sistema" -#: ../../../src/ui.cpp:1645 +#: ../../../src/ui.cpp:1879 msgid "&Minimize on close" -msgstr "&Minimizar al cerrar" +msgstr "&Minimiza al cerrar" -#: ../../../src/ui.cpp:1787 +#: ../../../src/ui.cpp:2021 #, c-format msgid "version %s" msgstr "versión %s" -#: ../../../src/ui.cpp:1899 +#: ../../../src/ui.cpp:2144 msgid "Error in amount " msgstr "Error en la cantidad " -#: ../../../src/ui.cpp:1899 -#: ../../../src/ui.cpp:1904 -#: ../../../src/ui.cpp:1909 -#: ../../../src/ui.cpp:1944 -#: ../../../src/uibase.cpp:55 +#: ../../../src/ui.cpp:2144 +#: ../../../src/ui.cpp:2149 +#: ../../../src/ui.cpp:2154 +#: ../../../src/ui.cpp:2207 +#: ../../../src/uibase.cpp:61 msgid "Send Coins" -msgstr "Enviar monedas" +msgstr "Envia monedas" -#: ../../../src/ui.cpp:1904 +#: ../../../src/ui.cpp:2149 msgid "Amount exceeds your balance " msgstr "La cantidad excede su balance " -#: ../../../src/ui.cpp:1909 +#: ../../../src/ui.cpp:2154 msgid "Total exceeds your balance when the " msgstr "El total excede su balance cuando el " -#: ../../../src/ui.cpp:1909 +#: ../../../src/ui.cpp:2154 msgid " transaction fee is included " -msgstr " la comisión de la transaccion está incluida " +msgstr " la comisión de la transacción está incluida " -#: ../../../src/ui.cpp:1927 +#: ../../../src/ui.cpp:2181 msgid "Payment sent " msgstr "Pago enviado " -#: ../../../src/ui.cpp:1927 -#: ../../../src/ui.cpp:1932 -#: ../../../src/ui.cpp:2076 -#: ../../../src/ui.cpp:2229 -#: ../../../src/main.cpp:3997 +#: ../../../src/ui.cpp:2181 +#: ../../../src/ui.cpp:2191 +#: ../../../src/ui.cpp:2341 +#: ../../../src/ui.cpp:2506 +#: ../../../src/wallet.cpp:1088 msgid "Sending..." msgstr "Enviando..." -#: ../../../src/ui.cpp:1944 +#: ../../../src/ui.cpp:2207 msgid "Invalid address " msgstr "Dirección inválida " -#: ../../../src/ui.cpp:1997 +#: ../../../src/ui.cpp:2262 #, c-format msgid "Sending %s to %s" msgstr "Enviando %s a %s" -#: ../../../src/ui.cpp:2070 -#: ../../../src/ui.cpp:2103 +#: ../../../src/ui.cpp:2335 +#: ../../../src/ui.cpp:2368 msgid "CANCELLED" msgstr "CANCELADO" -#: ../../../src/ui.cpp:2074 +#: ../../../src/ui.cpp:2339 msgid "Cancelled" msgstr "Cancelado" -#: ../../../src/ui.cpp:2076 +#: ../../../src/ui.cpp:2341 msgid "Transfer cancelled " msgstr "Transferencia cancelada " -#: ../../../src/ui.cpp:2129 +#: ../../../src/ui.cpp:2394 msgid "Error: " msgstr "Error: " -#: ../../../src/ui.cpp:2143 -#: ../../../src/ui.cpp:2214 -#: ../../../src/main.cpp:4016 +#: ../../../src/ui.cpp:2408 +#: ../../../src/ui.cpp:2477 +#: ../../../src/wallet.cpp:1106 msgid "Insufficient funds" msgstr "Fondos insuficientes" -#: ../../../src/ui.cpp:2148 +#: ../../../src/ui.cpp:2413 msgid "Connecting..." msgstr "Conectando..." -#: ../../../src/ui.cpp:2153 +#: ../../../src/ui.cpp:2418 msgid "Unable to connect" msgstr "No es posible conectar" -#: ../../../src/ui.cpp:2158 +#: ../../../src/ui.cpp:2423 msgid "Requesting public key..." msgstr "Pidiendo clave pública..." -#: ../../../src/ui.cpp:2170 +#: ../../../src/ui.cpp:2435 msgid "Received public key..." msgstr "Clave pública recibida..." -#: ../../../src/ui.cpp:2184 +#: ../../../src/ui.cpp:2449 msgid "Recipient is not accepting transactions sent by IP address" -msgstr "El destinatario no está aceptando transacciones enviadas por direcciones IP" +msgstr "El destinatario no accepta transacciones enviadas a direcciones IP" -#: ../../../src/ui.cpp:2186 +#: ../../../src/ui.cpp:2451 msgid "Transfer was not accepted" msgstr "La transferencia no fue aceptada" -#: ../../../src/ui.cpp:2195 +#: ../../../src/ui.cpp:2460 msgid "Invalid response received" msgstr "Respuesta inválida recibida" -#: ../../../src/ui.cpp:2210 +#: ../../../src/ui.cpp:2473 msgid "Creating transaction..." msgstr "Creando transacción..." -#: ../../../src/ui.cpp:2222 +#: ../../../src/ui.cpp:2496 #, c-format msgid "This transaction requires a transaction fee of at least %s because of its amount, complexity, or use of recently received funds" -msgstr "Esta transacción requiere de una comisión de al menos %s por su cantidad, complejidad o uso de fondos recibidos recientemente" +msgstr "Esta transacción requiere una comisión de al menos %s por su cantidad, complejidad o uso de fondos recibidos recientemente" -#: ../../../src/ui.cpp:2224 +#: ../../../src/ui.cpp:2498 msgid "Transaction creation failed" msgstr "Fallo al crear la transacción." -#: ../../../src/ui.cpp:2231 +#: ../../../src/ui.cpp:2508 msgid "Transaction aborted" msgstr "Transacción abortada" -#: ../../../src/ui.cpp:2239 +#: ../../../src/ui.cpp:2516 msgid "Lost connection, transaction cancelled" msgstr "Conexión perdida, transacción cancelada" -#: ../../../src/ui.cpp:2255 +#: ../../../src/ui.cpp:2532 msgid "Sending payment..." msgstr "Enviando pago..." -#: ../../../src/ui.cpp:2261 +#: ../../../src/ui.cpp:2544 msgid "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." -msgstr "La transacción fue rechazada. Esto puede haber ocurrido si alguna de las monedas fue gastada, o si ha usado una copia de wallet.dat y las monedas fueron gastadas en la copia pero no fueron marcadas como gastadas aqui." +msgstr "La transacción fue rechazada. Esto puede haber ocurrido si alguna de las monedas ya estaba gastada o si ha usado una copia de wallet.dat y las monedas se gastaron en la copia pero no se han marcado como gastadas aqui." -#: ../../../src/ui.cpp:2270 +#: ../../../src/ui.cpp:2553 msgid "Waiting for confirmation..." msgstr "Esperando confirmación..." -#: ../../../src/ui.cpp:2288 +#: ../../../src/ui.cpp:2570 msgid "" "The payment was sent, but the recipient was unable to verify it.\n" "The transaction is recorded and will credit to the recipient,\n" "but the comment information will be blank." msgstr "" -"El pago fue enviado, pero el receptor no pudo verificarlo.\n" -"La transacción se grabó y dará el crédito al receptor,\n" -"pero la información en los comentarios quedará en blanco." +"El pago se ha enviado, pero el receptor no pudo verificarlo.\n" +"La transacción se grabó y el saldo fue transferido\n" +"pero la información de los comentarios quedará en blanco." -#: ../../../src/ui.cpp:2297 +#: ../../../src/ui.cpp:2579 msgid "Payment was sent, but an invalid response was received" msgstr "El pago fue enviado, pero se recibió una respuesta inválida" -#: ../../../src/ui.cpp:2303 +#: ../../../src/ui.cpp:2585 msgid "Payment completed" msgstr "Pago completado" -#: ../../../src/ui.cpp:2334 -#: ../../../src/ui.cpp:2480 -#: ../../../src/ui.cpp:2517 +#: ../../../src/ui.cpp:2627 +#: ../../../src/ui.cpp:2773 +#: ../../../src/ui.cpp:2813 msgid "Name" msgstr "Nombre" -#: ../../../src/ui.cpp:2335 -#: ../../../src/ui.cpp:2480 -#: ../../../src/ui.cpp:2517 +#: ../../../src/ui.cpp:2628 +#: ../../../src/ui.cpp:2773 +#: ../../../src/ui.cpp:2813 msgid "Address" msgstr "Dirección" -#: ../../../src/ui.cpp:2337 -#: ../../../src/ui.cpp:2492 +#: ../../../src/ui.cpp:2630 +#: ../../../src/ui.cpp:2785 msgid "Label" msgstr "Etiqueta" -#: ../../../src/ui.cpp:2338 -#: ../../../src/uibase.cpp:837 +#: ../../../src/ui.cpp:2631 +#: ../../../src/uibase.cpp:847 msgid "Bitcoin Address" msgstr "Dirección Bitcoin" -#: ../../../src/ui.cpp:2462 +#: ../../../src/ui.cpp:2755 msgid "This is one of your own addresses for receiving payments and cannot be entered in the address book. " msgstr "Esta es una de sus direcciones para recibir pagos y no puede incluirse en la libreta de direcciones. " -#: ../../../src/ui.cpp:2480 -#: ../../../src/ui.cpp:2486 +#: ../../../src/ui.cpp:2773 +#: ../../../src/ui.cpp:2779 msgid "Edit Address" msgstr "Editar dirección" -#: ../../../src/ui.cpp:2492 +#: ../../../src/ui.cpp:2785 msgid "Edit Address Label" msgstr "Editar etiqueta dirección" -#: ../../../src/ui.cpp:2517 -#: ../../../src/ui.cpp:2523 +#: ../../../src/ui.cpp:2813 +#: ../../../src/ui.cpp:2819 msgid "Add Address" msgstr "Agregar dirección" -#: ../../../src/ui.cpp:2600 +#: ../../../src/ui.cpp:2906 msgid "Bitcoin" msgstr "Bitcoin" -#: ../../../src/ui.cpp:2602 +#: ../../../src/ui.cpp:2908 msgid "Bitcoin - Generating" msgstr "Bitcoin - Generando" -#: ../../../src/ui.cpp:2604 +#: ../../../src/ui.cpp:2910 msgid "Bitcoin - (not connected)" msgstr "Bitcoin - (no conectado)" -#: ../../../src/ui.cpp:2683 +#: ../../../src/ui.cpp:2989 msgid "&Open Bitcoin" msgstr "&Abrir Bitcoin" -#: ../../../src/ui.cpp:2684 +#: ../../../src/ui.cpp:2990 msgid "&Send Bitcoins" msgstr "&Enviar Bitcoin" -#: ../../../src/ui.cpp:2685 +#: ../../../src/ui.cpp:2991 msgid "O&ptions..." msgstr "O&pciones" -#: ../../../src/ui.cpp:2688 +#: ../../../src/ui.cpp:2994 #: ../../../src/uibase.cpp:25 msgid "E&xit" msgstr "S&alir" -#: ../../../src/ui.cpp:2904 +#: ../../../src/ui.cpp:3220 msgid "Program has crashed and will terminate. " msgstr "El programa ha detectado un error y va a cerrarse. " -#: ../../../src/main.cpp:1866 -msgid "Warning: Disk space is low " -msgstr "Cuidado: Poco espacio en disco " - -#: ../../../src/main.cpp:3990 -#, c-format -msgid "Error: This transaction requires a transaction fee of at least %s because of its amount, complexity, or use of recently received funds " -msgstr "Error: Esta transacción requiere de una comisión de al menos %s por su cantidad, complejidad o uso de fondos recibidos recientemente " - -#: ../../../src/main.cpp:3992 -msgid "Error: Transaction creation failed " -msgstr "Error: La creación de la transacción falló " - -#: ../../../src/main.cpp:4001 -msgid "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." -msgstr "Error: La transacción fue rechazada. Esto puede haber ocurrido si alguna de las monedas ya fue gastada, o si ha usado un copia de wallet.dat y las monedas fueron gastadas en la copia pero no han sido marcadas como gastadas aqui." - -#: ../../../src/main.cpp:4014 -msgid "Invalid amount" -msgstr "Cantidad erronea" - -#: ../../../src/main.cpp:4021 -msgid "Invalid bitcoin address" -msgstr "Dirección Bitcoin inválida" - -#: ../../../src/rpc.cpp:1802 -#: ../../../src/rpc.cpp:1804 -#, c-format -msgid "To use the %s option" -msgstr "Para usar la opción %s" - -#: ../../../src/rpc.cpp:1806 -#, c-format -msgid "" -"Warning: %s, you must set rpcpassword=<password>\n" -"in the configuration file: %s\n" -"If the file does not exist, create it with owner-readable-only file permissions.\n" -msgstr "" -"Precaución: %s, debes especificar rpcpassword=<password>\n" -"en el archivo de configuración: %s\n" -"Si el archivo no existe, debes crearlo con permisos de lectura al autor solamente.\n" - -#: ../../../src/rpc.cpp:1974 -#, c-format -msgid "" -"You must set rpcpassword=<password> in the configuration file:\n" -"%s\n" -"If the file does not exist, create it with owner-readable-only file permissions." -msgstr "" -"Debes especificar rpcpassword=<password> en el archivo de configuración:\n" -"%s\n" -"Si el archivo no existe, debes crearlo con permisos de lectura al autor solamente." - -#: ../../../src/util.cpp:866 -msgid "Warning: Please check that your computer's date and time are correct. If your clock is wrong Bitcoin will not work properly." -msgstr "Precaución: Por favor revisa que la fecha y hora de tu computador son correctas. Si tu reloj está mal, Bitcoin no funcionará correctamente." - -#: ../../../src/util.cpp:899 -msgid "beta" -msgstr "beta" - #: ../../../src/uibase.cpp:28 msgid "&File" msgstr "&Archivo" @@ -532,152 +778,160 @@ msgstr "&Archivo" msgid "&Your Receiving Addresses..." msgstr "&Tus direcciones de recepción..." -#: ../../../src/uibase.cpp:36 +#: ../../../src/uibase.cpp:35 +msgid "&Encrypt Wallet..." +msgstr "&Encriptar cartera..." + +#: ../../../src/uibase.cpp:38 +msgid "&Change Wallet Encryption Passphrase..." +msgstr "&Cambiar contraseña de cartera..." + +#: ../../../src/uibase.cpp:42 msgid "&Options..." msgstr "&Opciones..." -#: ../../../src/uibase.cpp:39 +#: ../../../src/uibase.cpp:45 msgid "&Settings" msgstr "&Configuración" -#: ../../../src/uibase.cpp:43 +#: ../../../src/uibase.cpp:49 msgid "&About..." msgstr "&Acerca de..." -#: ../../../src/uibase.cpp:46 +#: ../../../src/uibase.cpp:52 msgid "&Help" msgstr "&Ayuda" -#: ../../../src/uibase.cpp:56 +#: ../../../src/uibase.cpp:62 msgid "Address Book" msgstr "Libreta de direcciones" -#: ../../../src/uibase.cpp:69 +#: ../../../src/uibase.cpp:75 msgid "Your Bitcoin Address:" msgstr "Su dirección Bitcoin:" -#: ../../../src/uibase.cpp:76 +#: ../../../src/uibase.cpp:82 msgid " &New... " msgstr " &Nuevo... " -#: ../../../src/uibase.cpp:79 -#: ../../../src/uibase.cpp:780 -#: ../../../src/uibase.cpp:883 +#: ../../../src/uibase.cpp:85 +#: ../../../src/uibase.cpp:790 +#: ../../../src/uibase.cpp:893 msgid " &Copy to Clipboard " msgstr " &Copiar al portapapeles " -#: ../../../src/uibase.cpp:93 +#: ../../../src/uibase.cpp:99 msgid "Balance:" msgstr "Balance:" -#: ../../../src/uibase.cpp:109 +#: ../../../src/uibase.cpp:115 msgid " All" msgstr " Todo" -#: ../../../src/uibase.cpp:109 +#: ../../../src/uibase.cpp:115 msgid " Sent" msgstr " Enviado" -#: ../../../src/uibase.cpp:109 +#: ../../../src/uibase.cpp:115 msgid " Received" msgstr " Recibido" -#: ../../../src/uibase.cpp:109 +#: ../../../src/uibase.cpp:115 msgid " In Progress" msgstr " En progreso" -#: ../../../src/uibase.cpp:130 +#: ../../../src/uibase.cpp:136 msgid "All Transactions" msgstr "Todas las transacciones" -#: ../../../src/uibase.cpp:141 +#: ../../../src/uibase.cpp:147 msgid "Sent/Received" msgstr "Enviado/Recibido" -#: ../../../src/uibase.cpp:152 +#: ../../../src/uibase.cpp:158 msgid "Sent" msgstr "Enviado" -#: ../../../src/uibase.cpp:163 +#: ../../../src/uibase.cpp:169 msgid "Received" msgstr "Recibido" -#: ../../../src/uibase.cpp:302 -#: ../../../src/uibase.cpp:443 -#: ../../../src/uibase.cpp:542 -#: ../../../src/uibase.cpp:722 -#: ../../../src/uibase.cpp:783 -#: ../../../src/uibase.cpp:892 -#: ../../../src/uibase.cpp:981 +#: ../../../src/uibase.cpp:312 +#: ../../../src/uibase.cpp:453 +#: ../../../src/uibase.cpp:552 +#: ../../../src/uibase.cpp:732 +#: ../../../src/uibase.cpp:793 +#: ../../../src/uibase.cpp:902 +#: ../../../src/uibase.cpp:991 msgid "OK" msgstr "OK" -#: ../../../src/uibase.cpp:345 +#: ../../../src/uibase.cpp:355 msgid "&Start Bitcoin on system startup" -msgstr "&Arrancar Bitcoin al iniciar el sistema" +msgstr "&Arranca Bitcoin al iniciar el sistema" -#: ../../../src/uibase.cpp:348 +#: ../../../src/uibase.cpp:358 msgid "&Minimize to the tray instead of the taskbar" -msgstr "&Minimizar a la bandeja en vez de a la barra de tareas" +msgstr "&Minimiza a la bandeja en vez de a la barra de tareas" -#: ../../../src/uibase.cpp:351 +#: ../../../src/uibase.cpp:361 msgid "Map port using &UPnP" -msgstr "Mapear el puerto usando &UPnP" +msgstr "Mapea el puerto usando &UPnP" -#: ../../../src/uibase.cpp:354 +#: ../../../src/uibase.cpp:364 msgid "M&inimize to the tray on close" -msgstr "M&inimizar a la bandeja al cerrar" +msgstr "M&inimiza a la bandeja al cerrar" -#: ../../../src/uibase.cpp:360 -msgid "&Connect through socks4 proxy: " -msgstr "&Conectar usando un proxy socks4: " +#: ../../../src/uibase.cpp:370 +msgid "&Connect through socks4 proxy (requires restart to apply): " +msgstr "&Conecta usando un proxy socks4 (necesita reinicio): " -#: ../../../src/uibase.cpp:371 +#: ../../../src/uibase.cpp:381 msgid "Proxy &IP:" -msgstr "Proxy &IP:" +msgstr "&IP proxy:" -#: ../../../src/uibase.cpp:379 +#: ../../../src/uibase.cpp:389 msgid " &Port:" msgstr " &Puerto:" -#: ../../../src/uibase.cpp:392 +#: ../../../src/uibase.cpp:402 msgid "Optional transaction fee per KB that helps make sure your transactions are processed quickly. Most transactions are 1KB. Fee 0.01 recommended." msgstr "Comisión opcional a las transacciones por KB que ayuda a asegurar que tus transacciones son procesadas rápidamente. La mayoría de las transacciones son de 1KB. Se recomienda una comisión de 0.01." -#: ../../../src/uibase.cpp:399 +#: ../../../src/uibase.cpp:409 msgid "Pay transaction fee:" msgstr "Comisión de la transacción:" -#: ../../../src/uibase.cpp:420 +#: ../../../src/uibase.cpp:430 msgid "// [don't translate] Test panel 2 for future expansion" msgstr "" -#: ../../../src/uibase.cpp:424 +#: ../../../src/uibase.cpp:434 msgid "// [don't translate] Let's not start multiple pages until the first page is filled up" msgstr "" -#: ../../../src/uibase.cpp:446 -#: ../../../src/uibase.cpp:668 -#: ../../../src/uibase.cpp:727 -#: ../../../src/uibase.cpp:786 -#: ../../../src/uibase.cpp:895 -#: ../../../src/uibase.cpp:984 +#: ../../../src/uibase.cpp:456 +#: ../../../src/uibase.cpp:678 +#: ../../../src/uibase.cpp:737 +#: ../../../src/uibase.cpp:796 +#: ../../../src/uibase.cpp:905 +#: ../../../src/uibase.cpp:994 msgid "Cancel" msgstr "Cancelar" -#: ../../../src/uibase.cpp:449 +#: ../../../src/uibase.cpp:459 msgid "&Apply" msgstr "&Aplicar" -#: ../../../src/uibase.cpp:508 +#: ../../../src/uibase.cpp:518 msgid "Bitcoin " msgstr "Bitcoin " -#: ../../../src/uibase.cpp:514 +#: ../../../src/uibase.cpp:524 msgid "version" msgstr "versión" -#: ../../../src/uibase.cpp:525 +#: ../../../src/uibase.cpp:535 msgid "" "Copyright (c) 2009-2011 Bitcoin Developers\n" "\n" @@ -701,39 +955,39 @@ msgstr "" "OpenSSL Toolkit (http://www.openssl.org/) y software criptográfico escrito por \n" "Eric Young (eay@cryptsoft.com) y UPnP software escrito por Thomas Bernard." -#: ../../../src/uibase.cpp:581 +#: ../../../src/uibase.cpp:591 msgid "Enter a Bitcoin address (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L)" -msgstr "Ponga una dirección Bitcoin (ejemplo: 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L)" +msgstr "Introduce una dirección Bitcoin (ejemplo: 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L)" -#: ../../../src/uibase.cpp:595 +#: ../../../src/uibase.cpp:605 msgid "Pay &To:" msgstr "Pagar &A:" -#: ../../../src/uibase.cpp:610 +#: ../../../src/uibase.cpp:620 msgid "&Paste" msgstr "&Pegar" -#: ../../../src/uibase.cpp:613 +#: ../../../src/uibase.cpp:623 msgid " Address &Book..." msgstr " Libreta &Direcciones..." -#: ../../../src/uibase.cpp:620 +#: ../../../src/uibase.cpp:630 msgid "&Amount:" msgstr "&Cantidad:" -#: ../../../src/uibase.cpp:630 +#: ../../../src/uibase.cpp:640 msgid "T&ransfer:" msgstr "T&ransferir:" -#: ../../../src/uibase.cpp:636 +#: ../../../src/uibase.cpp:646 msgid " Standard" msgstr " Estándar" -#: ../../../src/uibase.cpp:663 +#: ../../../src/uibase.cpp:673 msgid "&Send" -msgstr "&Enviar" +msgstr "&Envia" -#: ../../../src/uibase.cpp:711 +#: ../../../src/uibase.cpp:721 msgid "" "\n" "\n" @@ -743,225 +997,80 @@ msgstr "" "\n" "Conenctando..." -#: ../../../src/uibase.cpp:761 +#: ../../../src/uibase.cpp:771 msgid "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. The highlighted address is displayed in the main window." msgstr "Estas son tus direcciones Bitcoin para recibir pagos. Puedes darle una diferente a cada emisor para saber quien te está pagando. La dirección resaltada se muestra en la ventana principal." -#: ../../../src/uibase.cpp:774 -#: ../../../src/uibase.cpp:886 +#: ../../../src/uibase.cpp:784 +#: ../../../src/uibase.cpp:896 msgid "&Edit..." -msgstr "&Editar..." +msgstr "&Edita..." -#: ../../../src/uibase.cpp:777 -#: ../../../src/uibase.cpp:889 +#: ../../../src/uibase.cpp:787 +#: ../../../src/uibase.cpp:899 msgid " &New Address... " msgstr " &Nueva dirección... " -#: ../../../src/uibase.cpp:849 +#: ../../../src/uibase.cpp:859 msgid "Sending" msgstr "Enviando" -#: ../../../src/uibase.cpp:857 +#: ../../../src/uibase.cpp:867 msgid "These are your Bitcoin addresses for receiving payments. You can give a different one to each sender to keep track of who is paying you. The highlighted address will be displayed in the main window." msgstr "Estas son tus direcciones Bitcoin para recibir pagos. Puedes darle una diferente a cada emisor para saber quien te está pagando. La dirección resaltada se muestra en la ventana principal." -#: ../../../src/uibase.cpp:870 +#: ../../../src/uibase.cpp:880 msgid "Receiving" msgstr "Recibiendo" -#: ../../../src/uibase.cpp:880 +#: ../../../src/uibase.cpp:890 msgid "&Delete" -msgstr "&Borrar" - -#: ../../../src/init.cpp:142 -msgid "Bitcoin version" -msgstr "versión Bitcoin" - -#: ../../../src/init.cpp:143 -msgid "Usage:" -msgstr "Uso:" - -#: ../../../src/init.cpp:145 -msgid "Send command to -server or bitcoind\n" -msgstr "Enviar comando a bitcoin corriendo con -server o a bitcoind\n" - -#: ../../../src/init.cpp:146 -msgid "List commands\n" -msgstr "Lista de comandos\n" - -#: ../../../src/init.cpp:147 -msgid "Get help for a command\n" -msgstr "Recibir ayuda para un comando\n" - -#: ../../../src/init.cpp:148 -msgid "Options:\n" -msgstr "Opciones:\n" - -#: ../../../src/init.cpp:149 -msgid "Specify configuration file (default: bitcoin.conf)\n" -msgstr "Especificar archivo de configuración (predeterminado: bitcoin.conf)\n" - -#: ../../../src/init.cpp:150 -msgid "Specify pid file (default: bitcoind.pid)\n" -msgstr "Especificar archivo pid (predeterminado: bitcoin.pid)\n" - -#: ../../../src/init.cpp:151 -msgid "Generate coins\n" -msgstr "Generar monedas\n" - -#: ../../../src/init.cpp:152 -msgid "Don't generate coins\n" -msgstr "No generar monedas\n" - -#: ../../../src/init.cpp:153 -msgid "Start minimized\n" -msgstr "Arrancar minimizado\n" - -#: ../../../src/init.cpp:154 -msgid "Specify data directory\n" -msgstr "Especificar directorio para los datos\n" - -#: ../../../src/init.cpp:155 -msgid "Connect through socks4 proxy\n" -msgstr "Conectar mediante proxy socks4\n" - -#: ../../../src/init.cpp:156 -msgid "Allow DNS lookups for addnode and connect\n" -msgstr "Permitir búsqueda DNS para addnode y connect\n" - -#: ../../../src/init.cpp:157 -msgid "Add a node to connect to\n" -msgstr "Agregar un nodo para conectarse\n" +msgstr "&Borra" -#: ../../../src/init.cpp:158 -msgid "Connect only to the specified node\n" -msgstr "Conectar solo al nodo especificado\n" - -#: ../../../src/init.cpp:159 -msgid "Don't accept connections from outside\n" -msgstr "No aceptar conexiones desde el exterior\n" - -#: ../../../src/init.cpp:162 -msgid "Don't attempt to use UPnP to map the listening port\n" -msgstr "No intentar usar UPnP para mapear el puerto de entrada\n" - -#: ../../../src/init.cpp:164 -msgid "Attempt to use UPnP to map the listening port\n" -msgstr "Intentar usar UPnP para mapear el puerto de escucha.\n" - -#: ../../../src/init.cpp:167 -msgid "Fee per KB to add to transactions you send\n" -msgstr "Comisión por KB para agregar a las transacciones que envias\n" - -#: ../../../src/init.cpp:169 -msgid "Accept command line and JSON-RPC commands\n" -msgstr "Aceptar comandos por línea de comandos y JSON-RPC\n" - -#: ../../../src/init.cpp:172 -msgid "Run in the background as a daemon and accept commands\n" -msgstr "Correr en el fondo como demonio y aceptar comandos\n" - -#: ../../../src/init.cpp:174 -msgid "Use the test network\n" -msgstr "Usar la red de pruebas\n" - -#: ../../../src/init.cpp:175 -msgid "Username for JSON-RPC connections\n" -msgstr "Usuario para las conexiones JSON-RPC\n" - -#: ../../../src/init.cpp:176 -msgid "Password for JSON-RPC connections\n" -msgstr "Contraseña para las conexiones JSON-RPC\n" - -#: ../../../src/init.cpp:177 -msgid "Listen for JSON-RPC connections on <port> (default: 8332)\n" -msgstr "Escuchar conexiones JSON-RPC en el puerto <puerto> (predeterminado: 8332)\n" - -#: ../../../src/init.cpp:178 -msgid "Allow JSON-RPC connections from specified IP address\n" -msgstr "Permitir conexiones JSON-RPC desde la dirección IP especificada\n" - -#: ../../../src/init.cpp:179 -msgid "Send commands to node running on <ip> (default: 127.0.0.1)\n" -msgstr "Enviar comando al nodo ejecutándose en <ip> (predeterminado: 127.0.0.1)\n" - -#: ../../../src/init.cpp:180 -msgid "Set key pool size to <n> (default: 100)\n" -msgstr "Ajustar el tamaño de la llave (key) de la piscina (pool) a <n> (predeterminado: 100)\n" - -#: ../../../src/init.cpp:181 -msgid "Rescan the block chain for missing wallet transactions\n" -msgstr "Re-escanear la cadena de bloques para transacciones perdidas de la billetera\n" - -#: ../../../src/init.cpp:185 -msgid "" -"\n" -"SSL options: (see the Bitcoin Wiki for SSL setup instructions)\n" -msgstr "" -"\n" -"Opciones SSL: (ver la Bitcoin Wiki para instrucciones de configuración SSL)\n" - -#: ../../../src/init.cpp:186 -msgid "Use OpenSSL (https) for JSON-RPC connections\n" -msgstr "Usar OpenSSL (https) para las conexiones JSON-RPC\n" - -#: ../../../src/init.cpp:187 -msgid "Server certificate file (default: server.cert)\n" -msgstr "Archivo de certificado del servidor (Predeterminado: server.cert)\n" +#: ../../../src/util.cpp:870 +msgid "Warning: Please check that your computer's date and time are correct. If your clock is wrong Bitcoin will not work properly." +msgstr "Precaución: Por favor revisa que la fecha y hora de tu ordenador son correctas. Si tu reloj está mal Bitcoin no funcionará correctamente." -#: ../../../src/init.cpp:188 -msgid "Server private key (default: server.pem)\n" -msgstr "Clave privada del servidor (Predeterminado: server.pem)\n" +#: ../../../src/util.cpp:904 +msgid "beta" +msgstr "beta" -#: ../../../src/init.cpp:189 -msgid "Acceptable ciphers (default: TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!AH:!3DES:@STRENGTH)\n" -msgstr "Cifrados aceptados (Predeterminado: TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!AH:!3DES:@STRENGTH)\n" +#: ../../../src/wallet.cpp:1073 +msgid "Error: Wallet locked, unable to create transaction " +msgstr "Error: Cartera bloqueada, no se puede crear la transacción" -#: ../../../src/init.cpp:193 -msgid "This help message\n" -msgstr "Este mensaje de ayuda\n" - -#: ../../../src/init.cpp:330 +#: ../../../src/wallet.cpp:1081 #, c-format -msgid "Cannot obtain a lock on data directory %s. Bitcoin is probably already running." -msgstr "No se puede obtener el bloqueo en el directorio de datos %s. Probablemente el cliente de Bitcoin ya se está ejecutando." - -#: ../../../src/init.cpp:356 -msgid "Error loading addr.dat \n" -msgstr "Error cargando addr.dat \n" - -#: ../../../src/init.cpp:362 -msgid "Error loading blkindex.dat \n" -msgstr "Error cargando blkindex.dat \n" - -#: ../../../src/init.cpp:369 -msgid "Error loading wallet.dat \n" -msgstr "Error cargando wallet.dat \n" +msgid "Error: This transaction requires a transaction fee of at least %s because of its amount, complexity, or use of recently received funds " +msgstr "Error: Esta transacción requiere de una comisión de al menos %s por su cantidad, complejidad o uso de fondos recibidos recientemente " -#: ../../../src/init.cpp:449 -msgid "Invalid -proxy address" -msgstr "Dirección proxy - inválida" +#: ../../../src/wallet.cpp:1083 +msgid "Error: Transaction creation failed " +msgstr "Error: La creación de la transacción falló " -#: ../../../src/init.cpp:472 -msgid "Invalid amount for -paytxfee=<amount>" -msgstr "Cantidad inválida para -paytxfee=<cantidad>" +#: ../../../src/wallet.cpp:1092 +msgid "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." +msgstr "Error: La transacción fue rechazada. Esto puede haber ocurrido si alguna de las monedas ya estaba gastada o si ha usado una copia de wallet.dat y las monedas se gastaron en la copia pero no se han marcado como gastadas aqui." -#: ../../../src/init.cpp:476 -msgid "Warning: -paytxfee is set very high. This is the transaction fee you will pay if you send a transaction." -msgstr "Precaución: -paytxfee está configurado muy alto. Esta es la comisión que pagarás si envias una transacción." +#: ../../../src/wallet.cpp:1104 +msgid "Invalid amount" +msgstr "Cantidad erronea" -#: ../../../src/uibase.h:147 +#: ../../../src/uibase.h:151 msgid "Transaction Details" msgstr "Detalles de la transacción" -#: ../../../src/uibase.h:199 +#: ../../../src/uibase.h:203 msgid "Options" msgstr "Opciones" -#: ../../../src/uibase.h:228 +#: ../../../src/uibase.h:232 msgid "About Bitcoin" msgstr "Acerca de Bitcoin" -#: ../../../src/uibase.h:337 +#: ../../../src/uibase.h:341 msgid "Your Bitcoin Addresses" msgstr "Sus direcciones Bitcoin" + +#~ msgid "Invalid bitcoin address" +#~ msgstr "Dirección Bitcoin inválida" diff --git a/locale/fr/LC_MESSAGES/bitcoin.mo b/locale/fr/LC_MESSAGES/bitcoin.mo Binary files differindex f4d669b4c0..f60e15bd62 100644 --- a/locale/fr/LC_MESSAGES/bitcoin.mo +++ b/locale/fr/LC_MESSAGES/bitcoin.mo diff --git a/locale/nl/LC_MESSAGES/bitcoin.mo b/locale/nl/LC_MESSAGES/bitcoin.mo Binary files differindex c5ae8489fb..13467f225b 100644 --- a/locale/nl/LC_MESSAGES/bitcoin.mo +++ b/locale/nl/LC_MESSAGES/bitcoin.mo diff --git a/locale/nl/LC_MESSAGES/bitcoin.po b/locale/nl/LC_MESSAGES/bitcoin.po index 97216add99..5074f21828 100644 --- a/locale/nl/LC_MESSAGES/bitcoin.po +++ b/locale/nl/LC_MESSAGES/bitcoin.po @@ -2,9 +2,9 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2011-05-15 18:23+0100\n" -"PO-Revision-Date: 2011-05-15 18:23+0100\n" -"Last-Translator: Pieter Wuille <sipa@ulyssis.org>\n" +"POT-Creation-Date: 2011-09-22 19:03+0100\n" +"PO-Revision-Date: 2011-09-22 19:19+0100\n" +"Last-Translator: Pieter Wuille <pieter.wuille@gmail.com>\n" "Language-Team: \n" "Language: \n" "MIME-Version: 1.0\n" @@ -12,116 +12,488 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "X-Poedit-KeywordsList: _;gettext;gettext_noop\n" "X-Poedit-Basepath: .\n" +"X-Poedit-Language: Dutch\n" "X-Poedit-SearchPath-0: ../../..\n" -#: ../../../src/net.cpp:1499 +#: ../../../src/init.cpp:163 +msgid "Bitcoin version" +msgstr "Bitcoin versie" + +#: ../../../src/init.cpp:164 +msgid "Usage:" +msgstr "Mededeling:" + +#: ../../../src/init.cpp:166 +msgid "Send command to -server or bitcoind\n" +msgstr "Zend commando naar -server of bitcoind\n" + +#: ../../../src/init.cpp:167 +msgid "List commands\n" +msgstr "List van commando's\n" + +#: ../../../src/init.cpp:168 +msgid "Get help for a command\n" +msgstr "Toon hulp voor een commando\n" + +#: ../../../src/init.cpp:169 +msgid "Options:\n" +msgstr "Opties:\n" + +#: ../../../src/init.cpp:170 +msgid "Specify configuration file (default: bitcoin.conf)\n" +msgstr "Specifieer configuratiebestand (standaard: bitcoin.conf)\n" + +#: ../../../src/init.cpp:171 +msgid "Specify pid file (default: bitcoind.pid)\n" +msgstr "Specifieer pid-bestand (standaard: bitcoind.pid)\n" + +#: ../../../src/init.cpp:172 +msgid "Generate coins\n" +msgstr "Genereer coins\n" + +#: ../../../src/init.cpp:173 +msgid "Don't generate coins\n" +msgstr "Genereer geen coins\n" + +#: ../../../src/init.cpp:174 +msgid "Start minimized\n" +msgstr "Geminimaliseerd starten\n" + +#: ../../../src/init.cpp:175 +msgid "Specify data directory\n" +msgstr "Stel datamap in\n" + +#: ../../../src/init.cpp:176 +msgid "Specify connection timeout (in milliseconds)\n" +msgstr "Gelieve de time-out tijd te specifieren (in milliseconden)\n" + +#: ../../../src/init.cpp:177 +msgid "Connect through socks4 proxy\n" +msgstr "Verbind via socks4 proxy\n" + +#: ../../../src/init.cpp:178 +msgid "Allow DNS lookups for addnode and connect\n" +msgstr "Sta DNS-opzoeking toe voor addnode en connect\n" + +#: ../../../src/init.cpp:179 +msgid "Add a node to connect to\n" +msgstr "Voeg een node toe om mee te verbinden\n" + +#: ../../../src/init.cpp:180 +msgid "Connect only to the specified node\n" +msgstr "Verbind alleen met deze node\n" + +#: ../../../src/init.cpp:181 +msgid "Don't accept connections from outside\n" +msgstr "Sta geen verbindingen van buitenaf toe\n" + +#: ../../../src/init.cpp:184 +msgid "Don't attempt to use UPnP to map the listening port\n" +msgstr "Probeer geen UPnP te gebruiken om de poort waarop geluisterd wordt te mappen\n" + +#: ../../../src/init.cpp:186 +msgid "Attempt to use UPnP to map the listening port\n" +msgstr "Probeer UPnP te gebruiken om de poort waarop geluisterd wordt te mappen\n" + +#: ../../../src/init.cpp:189 +msgid "Fee per KB to add to transactions you send\n" +msgstr "Fooi per KB om aan transacties die gezonden worden toe te voegen\n" + +#: ../../../src/init.cpp:191 +msgid "Accept command line and JSON-RPC commands\n" +msgstr "Aanvaard commandolijn en JSON-RPC commando's\n" + +#: ../../../src/init.cpp:194 +msgid "Run in the background as a daemon and accept commands\n" +msgstr "Draai in de achtergrond als daemon en aanvaard commando's\n" + +#: ../../../src/init.cpp:196 +msgid "Use the test network\n" +msgstr "Gebruik het test-netwerk\n" + +#: ../../../src/init.cpp:197 +msgid "Username for JSON-RPC connections\n" +msgstr "Gebruikersnaam voor JSON-RPC verbindingen\n" + +#: ../../../src/init.cpp:198 +msgid "Password for JSON-RPC connections\n" +msgstr "Wachtwoord voor JSON-RPC verbindingen\n" + +#: ../../../src/init.cpp:199 +msgid "Listen for JSON-RPC connections on <port> (default: 8332)\n" +msgstr "Luister voor JSON-RPC verbindingen op <poort> (standaard: 8332)\n" + +#: ../../../src/init.cpp:200 +msgid "Allow JSON-RPC connections from specified IP address\n" +msgstr "Enkel JSON-RPC verbindingen van opgegeven IP adres toestaan\n" + +#: ../../../src/init.cpp:201 +msgid "Send commands to node running on <ip> (default: 127.0.0.1)\n" +msgstr "Zend commando's naar proces dat op <ip> draait (standaard: 127.0.0.1)\n" + +#: ../../../src/init.cpp:202 +msgid "Set key pool size to <n> (default: 100)\n" +msgstr "Stel sleutelpoelgrootte in op <n> (standaard: 100)\n" + +#: ../../../src/init.cpp:203 +msgid "Rescan the block chain for missing wallet transactions\n" +msgstr "Doorzoek de blokken database voor ontbrekende portefeuille-transacties\n" + +#: ../../../src/init.cpp:207 +msgid "" +"\n" +"SSL options: (see the Bitcoin Wiki for SSL setup instructions)\n" +msgstr "" +"\n" +"SSL opties: (zie de Bitcoin wiki voor SSL instructies)\n" + +#: ../../../src/init.cpp:208 +msgid "Use OpenSSL (https) for JSON-RPC connections\n" +msgstr "Gebruik OpenSSL (https) voor JSON-RPC verbindingen\n" + +#: ../../../src/init.cpp:209 +msgid "Server certificate file (default: server.cert)\n" +msgstr "Certificaat-bestand voor server (standaard: server.cert)\n" + +#: ../../../src/init.cpp:210 +msgid "Server private key (default: server.pem)\n" +msgstr "Geheime sleutel voor server (standaard: server.pem)\n" + +#: ../../../src/init.cpp:211 +msgid "Acceptable ciphers (default: TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!AH:!3DES:@STRENGTH)\n" +msgstr "Aanvaardbare ciphers (standaard: TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!AH:!3DES:@STRENGTH)\n" + +#: ../../../src/init.cpp:215 +msgid "This help message\n" +msgstr "Dit helpbericht\n" + +#: ../../../src/init.cpp:353 +#, c-format +msgid "Cannot obtain a lock on data directory %s. Bitcoin is probably already running." +msgstr "Kan geen lock op de gegevensdirectory %s verkrijgen. Bitcoin draait vermoedelijk reeds." + +#: ../../../src/init.cpp:379 +msgid "Error loading addr.dat \n" +msgstr "Fout bij laden van bestand addr.dat \n" + +#: ../../../src/init.cpp:385 +msgid "Error loading blkindex.dat \n" +msgstr "Fout bij laden van bestand blkindex.dat \n" + +#: ../../../src/init.cpp:396 +msgid "Error loading wallet.dat: Wallet corrupted \n" +msgstr "Fout bij laden van bestand wallet.dat: portefeuille beschadigd \n" + +#: ../../../src/init.cpp:398 +msgid "Error loading wallet.dat: Wallet requires newer version of Bitcoin \n" +msgstr "Fout bij laden van bestand wallet.dat: portefeuille vereist nieuwere versie van Bitcoin\n" + +#: ../../../src/init.cpp:400 +msgid "Error loading wallet.dat \n" +msgstr "Fout bij laden van bestand wallet.dat \n" + +#: ../../../src/init.cpp:489 +msgid "Invalid -proxy address" +msgstr "Foutief -proxy adres" + +#: ../../../src/init.cpp:514 +msgid "Invalid amount for -paytxfee=<amount>" +msgstr "Ongeldig bedrag voor -paytxfee=<bedrag>" + +#: ../../../src/init.cpp:518 +msgid "Warning: -paytxfee is set very high. This is the transaction fee you will pay if you send a transaction." +msgstr "Waarschuwing: -paytxfee is zeer hoog ingesteld. Dit is de fooi die betaald wordt bij het zenden van een transactie." + +#: ../../../src/rpc.cpp:2035 +#: ../../../src/rpc.cpp:2037 +#, c-format +msgid "To use the %s option" +msgstr "Om de %s optie te gebruiken" + +#: ../../../src/rpc.cpp:2039 +#, c-format +msgid "" +"Warning: %s, you must set rpcpassword=<password>\n" +"in the configuration file: %s\n" +"If the file does not exist, create it with owner-readable-only file permissions.\n" +msgstr "" +"Waarschuwing: %s, rpcpassword=<password> moet ingesteld zijn\n" +"in het configuratie bestand: %s\n" +"Als het bestand nog niet bestaat, maak het dan aan met enkel-leesbaar-door-eigenaar rechten.\n" + +#: ../../../src/rpc.cpp:2215 +#, c-format +msgid "" +"You must set rpcpassword=<password> in the configuration file:\n" +"%s\n" +"If the file does not exist, create it with owner-readable-only file permissions." +msgstr "" +"rpcpassword=<password> moet ingesteld in het configuratie bestand:\n" +"%s\n" +"Als het bestand nog niet bestaat, maak het dan aan met enkel-leesbaar-door-eigenaar rechten." + +#: ../../../src/net.cpp:1616 #, c-format msgid "Unable to bind to port %d on this computer. Bitcoin is probably already running." msgstr "Kan niet binden met poort %d op deze computer. Bitcoin draait vermoedelijk reeds." -#: ../../../src/ui.cpp:202 +#: ../../../src/util.cpp:1008 +msgid "Warning: Please check that your computer's date and time are correct. If your clock is wrong Bitcoin will not work properly." +msgstr "Waarschuwing: Controleer of uw computers datum en tijd correct ingesteld zijn. Als uw klok fout staat zal Bitcoin niet correct werken." + +#: ../../../src/util.cpp:1042 +msgid "beta" +msgstr "beta" + +#: ../../../src/wallet.cpp:1073 +msgid "Error: Wallet locked, unable to create transaction " +msgstr "Fout: portefeuille is op slot, kan geen transactie aanmaken" + +#: ../../../src/wallet.cpp:1081 +#, c-format +msgid "Error: This transaction requires a transaction fee of at least %s because of its amount, complexity, or use of recently received funds " +msgstr "Fout: Deze transactie vergt een fooi van ten minste %s omwille van zijn bedrag, complexiteit, of gebruik van recent ontvangen fonden " + +#: ../../../src/wallet.cpp:1083 +msgid "Error: Transaction creation failed " +msgstr "Fout: Aanmaken van transactie mislukt " + +#: ../../../src/wallet.cpp:1088 +msgid "Sending..." +msgstr "Versturen..." + +#: ../../../src/wallet.cpp:1092 +msgid "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." +msgstr "Fout: De transactie is afgekeurd. Dit kan gebeuren als bepaalde coins in je Portefeuille al zijn uitgegeven. Dit kan veroorzaakt worden doordat je een kopie van wallet.dat gebruikt hebt en enkel daar je uitgave geregistreerd is." + +#: ../../../src/wallet.cpp:1104 +msgid "Invalid amount" +msgstr "Foutieve hoeveelheid" + +#: ../../../src/wallet.cpp:1106 +msgid "Insufficient funds" +msgstr "Onvoldoende saldo" + +#: ../../../src/main.cpp:1398 +#: ../../../src/bak/main.cpp:1414 +msgid "Warning: Disk space is low " +msgstr "Waarschuwing: Weinig schijfruimte over " + +#: ../../../src/ui.cpp:217 +#: ../../../src/bak/ui.cpp:216 #, c-format msgid "This transaction is over the size limit. You can still send it for a fee of %s, which goes to the nodes that process your transaction and helps to support the network. Do you want to pay the fee?" msgstr "Deze transactie overschrijdt de limiet. Om de transactie alsnog te verwerken kun je een fooi betalen van %s. Deze zal betaald worden aan de node die uw transactie verwerkt. Wil je doorgaan en deze fooi betalen?" -#: ../../../src/ui.cpp:301 +#: ../../../src/ui.cpp:261 +#: ../../../src/ui.cpp:1247 +msgid "Enter the current passphrase to the wallet." +msgstr "Geef het huidige wachtwoord voor de portefeuille." + +#: ../../../src/ui.cpp:262 +#: ../../../src/ui.cpp:1183 +#: ../../../src/ui.cpp:1200 +#: ../../../src/ui.cpp:1248 +#: ../../../src/ui.cpp:1272 +#: ../../../src/ui.cpp:1292 +msgid "Passphrase" +msgstr "Wachtwoord" + +#: ../../../src/ui.cpp:268 +msgid "Please supply the current wallet decryption passphrase." +msgstr "Geef het huidige wachtwoord voor de portefeille" + +#: ../../../src/ui.cpp:276 +#: ../../../src/ui.cpp:1257 +#: ../../../src/ui.cpp:1314 +msgid "The passphrase entered for the wallet decryption was incorrect." +msgstr "Het wachtwoord voor het openen van de portefeulle is foutief." + +#: ../../../src/ui.cpp:353 +#: ../../../src/bak/ui.cpp:316 msgid "Status" msgstr "Status" -#: ../../../src/ui.cpp:302 +#: ../../../src/ui.cpp:354 +#: ../../../src/bak/ui.cpp:317 msgid "Date" msgstr "Datum" -#: ../../../src/ui.cpp:303 +#: ../../../src/ui.cpp:355 +#: ../../../src/bak/ui.cpp:318 msgid "Description" msgstr "Beschrijving" -#: ../../../src/ui.cpp:304 +#: ../../../src/ui.cpp:356 +#: ../../../src/bak/ui.cpp:319 msgid "Debit" msgstr "Debet" -#: ../../../src/ui.cpp:305 +#: ../../../src/ui.cpp:357 +#: ../../../src/bak/ui.cpp:320 msgid "Credit" msgstr "Credit" -#: ../../../src/ui.cpp:511 +#: ../../../src/ui.cpp:568 +#: ../../../src/bak/ui.cpp:526 #, c-format msgid "Open for %d blocks" msgstr "Open gedurende %d blokken" -#: ../../../src/ui.cpp:513 +#: ../../../src/ui.cpp:570 +#: ../../../src/bak/ui.cpp:528 #, c-format msgid "Open until %s" msgstr "Open tot %s" -#: ../../../src/ui.cpp:519 +#: ../../../src/ui.cpp:576 +#: ../../../src/bak/ui.cpp:534 #, c-format msgid "%d/offline?" msgstr "%d/offline?" -#: ../../../src/ui.cpp:521 +#: ../../../src/ui.cpp:578 +#: ../../../src/bak/ui.cpp:536 #, c-format msgid "%d/unconfirmed" msgstr "%d/niet bevestigd" -#: ../../../src/ui.cpp:523 +#: ../../../src/ui.cpp:580 +#: ../../../src/bak/ui.cpp:538 #, c-format msgid "%d confirmations" msgstr "%d bevestigingen" -#: ../../../src/ui.cpp:608 +#: ../../../src/ui.cpp:665 +#: ../../../src/bak/ui.cpp:623 msgid "Generated" msgstr "Gegenereerd" -#: ../../../src/ui.cpp:616 +#: ../../../src/ui.cpp:673 +#: ../../../src/bak/ui.cpp:631 #, c-format msgid "Generated (%s matures in %d more blocks)" msgstr "Gegenereerd (%s wordt volwassen over %d blokken)" -#: ../../../src/ui.cpp:620 +#: ../../../src/ui.cpp:677 +#: ../../../src/bak/ui.cpp:635 msgid "Generated - Warning: This block was not received by any other nodes and will probably not be accepted!" msgstr "Gegenereerd - Waarschuwing: Dit blok is niet ontvangen door andere nodes en zal waarschijnlijk niet geaccepteerd worden!" -#: ../../../src/ui.cpp:624 +#: ../../../src/ui.cpp:681 +#: ../../../src/bak/ui.cpp:639 msgid "Generated (not accepted)" msgstr "Gegenereerd (niet geaccepteerd)" -#: ../../../src/ui.cpp:634 +#: ../../../src/ui.cpp:691 +#: ../../../src/bak/ui.cpp:649 msgid "From: " msgstr "Van: " -#: ../../../src/ui.cpp:658 +#: ../../../src/ui.cpp:715 +#: ../../../src/bak/ui.cpp:673 msgid "Received with: " -msgstr "Ontvangen op: " +msgstr "Ontvangen met: " -#: ../../../src/ui.cpp:704 +#: ../../../src/ui.cpp:760 +#: ../../../src/bak/ui.cpp:719 msgid "Payment to yourself" msgstr "Betaling aan uzelf" -#: ../../../src/ui.cpp:738 +#: ../../../src/ui.cpp:794 +#: ../../../src/bak/ui.cpp:753 msgid "To: " msgstr "Naar: " -#: ../../../src/ui.cpp:1053 +#: ../../../src/ui.cpp:1109 +#: ../../../src/bak/ui.cpp:1068 msgid " Generating" msgstr " Genereren..." -#: ../../../src/ui.cpp:1055 +#: ../../../src/ui.cpp:1111 +#: ../../../src/bak/ui.cpp:1070 msgid "(not connected)" msgstr "(niet verbonden)" -#: ../../../src/ui.cpp:1058 +#: ../../../src/ui.cpp:1114 +#: ../../../src/bak/ui.cpp:1073 #, c-format msgid " %d connections %d blocks %d transactions" msgstr " %d verbindingen %d blokken %d transacties" -#: ../../../src/ui.cpp:1163 -#: ../../../src/ui.cpp:2527 +#: ../../../src/ui.cpp:1171 +msgid "Wallet already encrypted." +msgstr "Portefeuille reeds versleuteld." + +#: ../../../src/ui.cpp:1182 +msgid "" +"Enter the new passphrase to the wallet.\n" +"Please use a passphrase of 10 or more random characters, or eight or more words." +msgstr "" +"Geef het nieuwe wachtwoord voor de portefeuille.\n" +"Gebruik een wachtwoord van 10 of meer willekeurige characters, of 8 of meer woorden." + +#: ../../../src/ui.cpp:1189 +#: ../../../src/ui.cpp:1280 +msgid "Error: The supplied passphrase was too short." +msgstr "Fout: het wachtwoord is kort." + +#: ../../../src/ui.cpp:1193 +msgid "" +"WARNING: If you encrypt your wallet and lose your passphrase, you will LOSE ALL OF YOUR BITCOINS!\n" +"Are you sure you wish to encrypt your wallet?" +msgstr "" +"WAARSCHUWING: Indien u uw portefeuille versleutelt en het wachtwoord verliest, zal u AL UW BITCOINS VERLIEZEN!\n" +"Bent u zeker dat u de portfeuille wenst te versleutelen?" + +#: ../../../src/ui.cpp:1199 +msgid "Please re-enter your new wallet passphrase." +msgstr "Voer uw portefeuille-wachtwoord opnieuw in." + +#: ../../../src/ui.cpp:1208 +#: ../../../src/ui.cpp:1302 +msgid "Error: the supplied passphrases didn't match." +msgstr "Fout: de ingevoerde wachtwoorden komen niet overeen." + +#: ../../../src/ui.cpp:1218 +msgid "Wallet encryption failed." +msgstr "Versleutelen van de portefeuille mislukt." + +#: ../../../src/ui.cpp:1225 +msgid "" +"Wallet Encrypted.\n" +"Remember that encrypting your wallet cannot fully protect your bitcoins from being stolen by malware infecting your computer." +msgstr "" +"Portefeuille versleuteld.\n" +"Denk eraan dat uw portefeuille versleutelen geen volledige bescherming biedt tegen malware die uw computer zou geinfecteerd hebben." + +#: ../../../src/ui.cpp:1236 +msgid "Wallet is unencrypted, please encrypt it first." +msgstr "Portefeuille is onversleuteld. Versleutel ze eerst." + +#: ../../../src/ui.cpp:1271 +msgid "Enter the new passphrase for the wallet." +msgstr "Voer nieuw wachtwoord voor de portefeuille in." + +#: ../../../src/ui.cpp:1291 +msgid "Re-enter the new passphrase for the wallet." +msgstr "Voer nieuw wachtwoord voor de portefeuille opnieuw in." + +#: ../../../src/ui.cpp:1323 +msgid "Wallet Passphrase Changed." +msgstr "Portefeuille-wachtwoord gewijzigd." + +#: ../../../src/ui.cpp:1379 +#: ../../../src/ui.cpp:2825 +#: ../../../src/bak/ui.cpp:1178 +#: ../../../src/bak/ui.cpp:2571 msgid "New Receiving Address" msgstr "Nieuw Ontvangstadres" -#: ../../../src/ui.cpp:1164 -#: ../../../src/ui.cpp:2528 +#: ../../../src/ui.cpp:1380 +#: ../../../src/ui.cpp:2826 +#: ../../../src/bak/ui.cpp:1179 +#: ../../../src/bak/ui.cpp:2572 msgid "" "You should use a new address for each payment you receive.\n" "\n" @@ -131,248 +503,299 @@ msgstr "" "\n" "Label" -#: ../../../src/ui.cpp:1233 +#: ../../../src/ui.cpp:1464 +#: ../../../src/bak/ui.cpp:1251 msgid "<b>Status:</b> " msgstr "<b>Status:</b> " -#: ../../../src/ui.cpp:1238 +#: ../../../src/ui.cpp:1469 +#: ../../../src/bak/ui.cpp:1256 msgid ", has not been successfully broadcast yet" msgstr ", is nog niet succesvol verstuurd naar het netwerk" -#: ../../../src/ui.cpp:1240 +#: ../../../src/ui.cpp:1471 +#: ../../../src/bak/ui.cpp:1258 #, c-format msgid ", broadcast through %d node" msgstr ", verstuurd via %d node" -#: ../../../src/ui.cpp:1242 +#: ../../../src/ui.cpp:1473 +#: ../../../src/bak/ui.cpp:1260 #, c-format msgid ", broadcast through %d nodes" msgstr ", verstuurd via %d nodes" -#: ../../../src/ui.cpp:1246 +#: ../../../src/ui.cpp:1477 +#: ../../../src/bak/ui.cpp:1264 msgid "<b>Date:</b> " msgstr "<b>Datum:</b> " -#: ../../../src/ui.cpp:1254 +#: ../../../src/ui.cpp:1485 +#: ../../../src/bak/ui.cpp:1272 msgid "<b>Source:</b> Generated<br>" msgstr "<b>Bron:</b> Gegenereerd<br>" -#: ../../../src/ui.cpp:1260 -#: ../../../src/ui.cpp:1278 +#: ../../../src/ui.cpp:1491 +#: ../../../src/ui.cpp:1508 +#: ../../../src/bak/ui.cpp:1278 +#: ../../../src/bak/ui.cpp:1296 msgid "<b>From:</b> " msgstr "<b>Van:</b> " -#: ../../../src/ui.cpp:1278 +#: ../../../src/ui.cpp:1508 +#: ../../../src/bak/ui.cpp:1296 msgid "unknown" msgstr "onbekend" -#: ../../../src/ui.cpp:1279 -#: ../../../src/ui.cpp:1303 -#: ../../../src/ui.cpp:1362 +#: ../../../src/ui.cpp:1509 +#: ../../../src/ui.cpp:1533 +#: ../../../src/ui.cpp:1592 +#: ../../../src/bak/ui.cpp:1297 +#: ../../../src/bak/ui.cpp:1321 +#: ../../../src/bak/ui.cpp:1380 msgid "<b>To:</b> " msgstr "<b>Naar:</b> " -#: ../../../src/ui.cpp:1282 +#: ../../../src/ui.cpp:1512 +#: ../../../src/bak/ui.cpp:1300 msgid " (yours, label: " msgstr " (van jou, label: " -#: ../../../src/ui.cpp:1284 +#: ../../../src/ui.cpp:1514 +#: ../../../src/bak/ui.cpp:1302 msgid " (yours)" msgstr " (van jou)" -#: ../../../src/ui.cpp:1321 -#: ../../../src/ui.cpp:1333 -#: ../../../src/ui.cpp:1379 -#: ../../../src/ui.cpp:1396 +#: ../../../src/ui.cpp:1551 +#: ../../../src/ui.cpp:1563 +#: ../../../src/ui.cpp:1609 +#: ../../../src/ui.cpp:1626 +#: ../../../src/bak/ui.cpp:1339 +#: ../../../src/bak/ui.cpp:1351 +#: ../../../src/bak/ui.cpp:1397 +#: ../../../src/bak/ui.cpp:1414 msgid "<b>Credit:</b> " msgstr "<b>Credit:</b>" -#: ../../../src/ui.cpp:1323 +#: ../../../src/ui.cpp:1553 +#: ../../../src/bak/ui.cpp:1341 #, c-format msgid "(%s matures in %d more blocks)" msgstr "(%s wordt volwassen over %d blokken)" -#: ../../../src/ui.cpp:1325 +#: ../../../src/ui.cpp:1555 +#: ../../../src/bak/ui.cpp:1343 msgid "(not accepted)" msgstr "(niet geaccepteerd)" -#: ../../../src/ui.cpp:1370 -#: ../../../src/ui.cpp:1378 -#: ../../../src/ui.cpp:1393 +#: ../../../src/ui.cpp:1600 +#: ../../../src/ui.cpp:1608 +#: ../../../src/ui.cpp:1623 +#: ../../../src/bak/ui.cpp:1388 +#: ../../../src/bak/ui.cpp:1396 +#: ../../../src/bak/ui.cpp:1411 msgid "<b>Debit:</b> " msgstr "<b>Debet:</b>" -#: ../../../src/ui.cpp:1384 +#: ../../../src/ui.cpp:1614 +#: ../../../src/bak/ui.cpp:1402 msgid "<b>Transaction fee:</b> " msgstr "<b>Transactiefooi:</b> " -#: ../../../src/ui.cpp:1400 +#: ../../../src/ui.cpp:1630 +#: ../../../src/bak/ui.cpp:1418 msgid "<b>Net amount:</b> " msgstr "<b>Nettobedrag:</b> " -#: ../../../src/ui.cpp:1407 +#: ../../../src/ui.cpp:1637 +#: ../../../src/bak/ui.cpp:1425 msgid "Message:" msgstr "Mededeling:" -#: ../../../src/ui.cpp:1409 +#: ../../../src/ui.cpp:1639 +#: ../../../src/bak/ui.cpp:1427 msgid "Comment:" msgstr "Commentaar:" -#: ../../../src/ui.cpp:1412 +#: ../../../src/ui.cpp:1642 +#: ../../../src/bak/ui.cpp:1430 msgid "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 \"not accepted\" and not be spendable. This may occasionally happen if another node generates a block within a few seconds of yours." msgstr "Gegenereerde coins mogen pas na een wachttijd van 120 blokken uitgegeven worden. Op het moment dat dit blok gegenereerd werd, is het naar het netwerk verzonden om aan de blokkenreeks toegevoegd te worden. Als het niet succesvol in de blokkenreeks opgenomen kan worden verandert de status in \"niet geaccepteerd\" en kan het niet uitegegeven worden. Dit kan soms gebeuren als een andere node op ongeveer hetzelfde moment een blok genereert." -#: ../../../src/ui.cpp:1592 +#: ../../../src/ui.cpp:1826 +#: ../../../src/bak/ui.cpp:1610 msgid "Cannot write autostart/bitcoin.desktop file" msgstr "Kan niet schrijven naar het bestand autostart/bitcoin.desktop" -#: ../../../src/ui.cpp:1628 +#: ../../../src/ui.cpp:1862 +#: ../../../src/bak/ui.cpp:1646 msgid "Main" msgstr "Algemeen" -#: ../../../src/ui.cpp:1636 +#: ../../../src/ui.cpp:1872 +#: ../../../src/bak/ui.cpp:1656 msgid "&Start Bitcoin on window system startup" msgstr "&Start Bitcoin wanneer het systeem opstart" -#: ../../../src/ui.cpp:1643 +#: ../../../src/ui.cpp:1879 +#: ../../../src/bak/ui.cpp:1663 msgid "&Minimize on close" msgstr "&Minimaliseer bij sluiten van het venster" -#: ../../../src/ui.cpp:1785 +#: ../../../src/ui.cpp:2021 +#: ../../../src/bak/ui.cpp:1805 #, c-format msgid "version %s" msgstr "versie %s" -#: ../../../src/ui.cpp:1897 +#: ../../../src/ui.cpp:2144 +#: ../../../src/bak/ui.cpp:1928 msgid "Error in amount " msgstr "Fout in hoeveelheid " -#: ../../../src/ui.cpp:1897 -#: ../../../src/ui.cpp:1902 -#: ../../../src/ui.cpp:1907 -#: ../../../src/ui.cpp:1942 -#: ../../../src/uibase.cpp:55 +#: ../../../src/ui.cpp:2144 +#: ../../../src/ui.cpp:2149 +#: ../../../src/ui.cpp:2154 +#: ../../../src/ui.cpp:2207 +#: ../../../src/uibase.cpp:61 +#: ../../../src/bak/ui.cpp:1928 +#: ../../../src/bak/ui.cpp:1933 +#: ../../../src/bak/ui.cpp:1938 +#: ../../../src/bak/ui.cpp:1973 msgid "Send Coins" msgstr "Verstuur coins" -#: ../../../src/ui.cpp:1902 +#: ../../../src/ui.cpp:2149 +#: ../../../src/bak/ui.cpp:1933 msgid "Amount exceeds your balance " msgstr "Hoeveelheid overschrijdt uw huidige balans " -#: ../../../src/ui.cpp:1907 +#: ../../../src/ui.cpp:2154 +#: ../../../src/bak/ui.cpp:1938 msgid "Total exceeds your balance when the " msgstr "Totaal overschrijdt uw huidige balans wanneer de " -#: ../../../src/ui.cpp:1907 +#: ../../../src/ui.cpp:2154 +#: ../../../src/bak/ui.cpp:1938 msgid " transaction fee is included " msgstr " transactiefooi is meegerekend " -#: ../../../src/ui.cpp:1925 +#: ../../../src/ui.cpp:2181 +#: ../../../src/bak/ui.cpp:1956 msgid "Payment sent " msgstr "Betaling verzonden " -#: ../../../src/ui.cpp:1925 -#: ../../../src/ui.cpp:1930 -#: ../../../src/ui.cpp:2074 -#: ../../../src/ui.cpp:2227 -#: ../../../src/main.cpp:3999 -msgid "Sending..." -msgstr "Versturen..." - -#: ../../../src/ui.cpp:1942 +#: ../../../src/ui.cpp:2207 +#: ../../../src/bak/ui.cpp:1973 msgid "Invalid address " msgstr "Foutief adres " -#: ../../../src/ui.cpp:1995 +#: ../../../src/ui.cpp:2262 +#: ../../../src/bak/ui.cpp:2028 #, c-format msgid "Sending %s to %s" msgstr "%s versturen naar %s" -#: ../../../src/ui.cpp:2068 -#: ../../../src/ui.cpp:2101 +#: ../../../src/ui.cpp:2335 +#: ../../../src/ui.cpp:2368 +#: ../../../src/bak/ui.cpp:2101 +#: ../../../src/bak/ui.cpp:2134 msgid "CANCELLED" msgstr "GEANNULEERD" -#: ../../../src/ui.cpp:2072 +#: ../../../src/ui.cpp:2339 +#: ../../../src/bak/ui.cpp:2105 msgid "Cancelled" msgstr "Geannuleerd" -#: ../../../src/ui.cpp:2074 +#: ../../../src/ui.cpp:2341 +#: ../../../src/bak/ui.cpp:2107 msgid "Transfer cancelled " msgstr "Transactie geannuleerd " -#: ../../../src/ui.cpp:2127 +#: ../../../src/ui.cpp:2394 +#: ../../../src/bak/ui.cpp:2160 msgid "Error: " msgstr "Fout: " -#: ../../../src/ui.cpp:2141 -#: ../../../src/ui.cpp:2212 -#: ../../../src/main.cpp:4018 -msgid "Insufficient funds" -msgstr "Onvoldoende saldo" - -#: ../../../src/ui.cpp:2146 +#: ../../../src/ui.cpp:2413 +#: ../../../src/bak/ui.cpp:2179 msgid "Connecting..." msgstr "Verbinden..." -#: ../../../src/ui.cpp:2151 +#: ../../../src/ui.cpp:2418 +#: ../../../src/bak/ui.cpp:2184 msgid "Unable to connect" msgstr "Kan niet verbinden" -#: ../../../src/ui.cpp:2156 +#: ../../../src/ui.cpp:2423 +#: ../../../src/bak/ui.cpp:2189 msgid "Requesting public key..." msgstr "Aanvragen van publieke sleutel..." -#: ../../../src/ui.cpp:2168 +#: ../../../src/ui.cpp:2435 +#: ../../../src/bak/ui.cpp:2201 msgid "Received public key..." msgstr "Publieke sleutel ontvangen..." -#: ../../../src/ui.cpp:2182 +#: ../../../src/ui.cpp:2449 +#: ../../../src/bak/ui.cpp:2215 msgid "Recipient is not accepting transactions sent by IP address" msgstr "Ontvanger aanvaardt geen transacties via IP adres" -#: ../../../src/ui.cpp:2184 +#: ../../../src/ui.cpp:2451 +#: ../../../src/bak/ui.cpp:2217 msgid "Transfer was not accepted" msgstr "Transactie niet geaccepteerd" -#: ../../../src/ui.cpp:2193 +#: ../../../src/ui.cpp:2460 +#: ../../../src/bak/ui.cpp:2226 msgid "Invalid response received" msgstr "Foutief antwoord ontvangen" -#: ../../../src/ui.cpp:2208 +#: ../../../src/ui.cpp:2473 +#: ../../../src/bak/ui.cpp:2241 msgid "Creating transaction..." msgstr "Transactie aanmaken..." -#: ../../../src/ui.cpp:2220 +#: ../../../src/ui.cpp:2496 +#: ../../../src/bak/ui.cpp:2253 #, c-format msgid "This transaction requires a transaction fee of at least %s because of its amount, complexity, or use of recently received funds" msgstr "Deze transactie vergt een fooi van ten minste %s omwille van zijn bedrag, complexiteit, of gebruik van recent ontvangen fonden" -#: ../../../src/ui.cpp:2222 +#: ../../../src/ui.cpp:2498 +#: ../../../src/bak/ui.cpp:2255 msgid "Transaction creation failed" msgstr "Aanmaken van transactie mislukt" -#: ../../../src/ui.cpp:2229 +#: ../../../src/ui.cpp:2508 +#: ../../../src/bak/ui.cpp:2262 msgid "Transaction aborted" msgstr "Transactie geannuleerd" -#: ../../../src/ui.cpp:2237 +#: ../../../src/ui.cpp:2516 +#: ../../../src/bak/ui.cpp:2270 msgid "Lost connection, transaction cancelled" msgstr "Verbinding verloren, transactie geannuleerd" -#: ../../../src/ui.cpp:2253 +#: ../../../src/ui.cpp:2532 +#: ../../../src/bak/ui.cpp:2286 msgid "Sending payment..." msgstr "Betaling versturen..." -#: ../../../src/ui.cpp:2259 +#: ../../../src/ui.cpp:2544 +#: ../../../src/bak/ui.cpp:2292 msgid "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." msgstr "Fout: De transactie is afgekeurd. Dit kan gebeuren als bepaalde coins in je Portefeuille al zijn uitgegeven. Dit kan veroorzaakt worden doordat je een kopie van wallet.dat gebruikt hebt en enkel daar je uitgave geregistreerd is." -#: ../../../src/ui.cpp:2268 +#: ../../../src/ui.cpp:2553 +#: ../../../src/bak/ui.cpp:2301 msgid "Waiting for confirmation..." msgstr "Wachten op bevestiging..." -#: ../../../src/ui.cpp:2286 +#: ../../../src/ui.cpp:2570 +#: ../../../src/bak/ui.cpp:2319 msgid "" "The payment was sent, but the recipient was unable to verify it.\n" "The transaction is recorded and will credit to the recipient,\n" @@ -382,149 +805,112 @@ msgstr "" "De transactie is opgenomen en wordt uitbetaald aan de ontvanger,\n" "maar het mededelings-veld blijft blanco." -#: ../../../src/ui.cpp:2295 +#: ../../../src/ui.cpp:2579 +#: ../../../src/bak/ui.cpp:2328 msgid "Payment was sent, but an invalid response was received" msgstr "Betaling is verstuurd, maar een foutief antword is ontvangen." -#: ../../../src/ui.cpp:2301 +#: ../../../src/ui.cpp:2585 +#: ../../../src/bak/ui.cpp:2334 msgid "Payment completed" msgstr "Betaling voltooid" -#: ../../../src/ui.cpp:2332 -#: ../../../src/ui.cpp:2478 -#: ../../../src/ui.cpp:2515 +#: ../../../src/ui.cpp:2627 +#: ../../../src/ui.cpp:2773 +#: ../../../src/ui.cpp:2813 +#: ../../../src/bak/ui.cpp:2376 +#: ../../../src/bak/ui.cpp:2522 +#: ../../../src/bak/ui.cpp:2559 msgid "Name" msgstr "Naam" -#: ../../../src/ui.cpp:2333 -#: ../../../src/ui.cpp:2478 -#: ../../../src/ui.cpp:2515 +#: ../../../src/ui.cpp:2628 +#: ../../../src/ui.cpp:2773 +#: ../../../src/ui.cpp:2813 +#: ../../../src/bak/ui.cpp:2377 +#: ../../../src/bak/ui.cpp:2522 +#: ../../../src/bak/ui.cpp:2559 msgid "Address" msgstr "Adres" -#: ../../../src/ui.cpp:2335 -#: ../../../src/ui.cpp:2490 +#: ../../../src/ui.cpp:2630 +#: ../../../src/ui.cpp:2785 +#: ../../../src/bak/ui.cpp:2379 +#: ../../../src/bak/ui.cpp:2534 msgid "Label" msgstr "Label" -#: ../../../src/ui.cpp:2336 -#: ../../../src/uibase.cpp:837 +#: ../../../src/ui.cpp:2631 +#: ../../../src/uibase.cpp:847 +#: ../../../src/bak/ui.cpp:2380 msgid "Bitcoin Address" msgstr "Bitcoin-adres" -#: ../../../src/ui.cpp:2460 +#: ../../../src/ui.cpp:2755 +#: ../../../src/bak/ui.cpp:2504 msgid "This is one of your own addresses for receiving payments and cannot be entered in the address book. " msgstr "Dit is een van uw eigen adressen voor het ontvangen van betalingen, en kan niet worden toegevoegd aan uw adresboek. " -#: ../../../src/ui.cpp:2478 -#: ../../../src/ui.cpp:2484 +#: ../../../src/ui.cpp:2773 +#: ../../../src/ui.cpp:2779 +#: ../../../src/bak/ui.cpp:2522 +#: ../../../src/bak/ui.cpp:2528 msgid "Edit Address" msgstr "Bewerk adres" -#: ../../../src/ui.cpp:2490 +#: ../../../src/ui.cpp:2785 +#: ../../../src/bak/ui.cpp:2534 msgid "Edit Address Label" msgstr "Bewerk adreslabel" -#: ../../../src/ui.cpp:2515 -#: ../../../src/ui.cpp:2521 +#: ../../../src/ui.cpp:2813 +#: ../../../src/ui.cpp:2819 +#: ../../../src/bak/ui.cpp:2559 +#: ../../../src/bak/ui.cpp:2565 msgid "Add Address" msgstr "Adres toevoegen" -#: ../../../src/ui.cpp:2598 +#: ../../../src/ui.cpp:2906 +#: ../../../src/bak/ui.cpp:2642 msgid "Bitcoin" msgstr "Bitcoin" -#: ../../../src/ui.cpp:2600 +#: ../../../src/ui.cpp:2908 +#: ../../../src/bak/ui.cpp:2644 msgid "Bitcoin - Generating" msgstr "Bitcoin - Genereren..." -#: ../../../src/ui.cpp:2602 +#: ../../../src/ui.cpp:2910 +#: ../../../src/bak/ui.cpp:2646 msgid "Bitcoin - (not connected)" msgstr "Bitcoin - (niet verbonden)" -#: ../../../src/ui.cpp:2681 +#: ../../../src/ui.cpp:2989 +#: ../../../src/bak/ui.cpp:2725 msgid "&Open Bitcoin" msgstr "&Open Bitcoin" -#: ../../../src/ui.cpp:2682 +#: ../../../src/ui.cpp:2990 +#: ../../../src/bak/ui.cpp:2726 msgid "&Send Bitcoins" -msgstr "&Open Bitcoin" +msgstr "&Verstuur Bitcoins" -#: ../../../src/ui.cpp:2683 +#: ../../../src/ui.cpp:2991 +#: ../../../src/bak/ui.cpp:2727 msgid "O&ptions..." msgstr "O&pties" -#: ../../../src/ui.cpp:2686 +#: ../../../src/ui.cpp:2994 #: ../../../src/uibase.cpp:25 +#: ../../../src/bak/ui.cpp:2730 msgid "E&xit" msgstr "A&fsluiten" -#: ../../../src/ui.cpp:2902 +#: ../../../src/ui.cpp:3220 +#: ../../../src/bak/ui.cpp:2956 msgid "Program has crashed and will terminate. " msgstr "Het programma is gecrasht en wordt afgesloten. " -#: ../../../src/main.cpp:1868 -msgid "Warning: Disk space is low " -msgstr "Waarschuwing: Weinig schijfruimte over " - -#: ../../../src/main.cpp:3992 -#, c-format -msgid "Error: This transaction requires a transaction fee of at least %s because of its amount, complexity, or use of recently received funds " -msgstr "Fout: Deze transactie vergt een fooi van ten minste %s omwille van zijn bedrag, complexiteit, of gebruik van recent ontvangen fonden " - -#: ../../../src/main.cpp:3994 -msgid "Error: Transaction creation failed " -msgstr "Fout: Aanmaken van transactie mislukt " - -#: ../../../src/main.cpp:4003 -msgid "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." -msgstr "Fout: De transactie is afgekeurd. Dit kan gebeuren als bepaalde coins in je Portefeuille al zijn uitgegeven. Dit kan veroorzaakt worden doordat je een kopie van wallet.dat gebruikt hebt en enkel daar je uitgave geregistreerd is." - -#: ../../../src/main.cpp:4016 -msgid "Invalid amount" -msgstr "Foutieve hoeveelheid" - -#: ../../../src/main.cpp:4023 -msgid "Invalid bitcoin address" -msgstr "Foutief bitcoin-adres" - -#: ../../../src/rpc.cpp:1800 -#: ../../../src/rpc.cpp:1802 -#, c-format -msgid "To use the %s option" -msgstr "Om de %s optie te gebruiken" - -#: ../../../src/rpc.cpp:1804 -#, c-format -msgid "" -"Warning: %s, you must set rpcpassword=<password>\n" -"in the configuration file: %s\n" -"If the file does not exist, create it with owner-readable-only file permissions.\n" -msgstr "" -"Waarschuwing: %s, rpcpassword=<password> moet ingesteld zijn\n" -"in het configuratie bestand: %s\n" -"Als het bestand nog niet bestaat, maak het dan aan met enkel-leesbaar-door-eigenaar rechten.\n" - - -#: ../../../src/rpc.cpp:1972 -#, c-format -msgid "" -"You must set rpcpassword=<password> in the configuration file:\n" -"%s\n" -"If the file does not exist, create it with owner-readable-only file permissions." -msgstr "" -"rpcpassword=<password> moet ingesteld in het configuratie bestand:\n" -"%s\n" -"Als het bestand nog niet bestaat, maak het dan aan met enkel-leesbaar-door-eigenaar rechten." - -#: ../../../src/util.cpp:865 -msgid "Warning: Please check that your computer's date and time are correct. If your clock is wrong Bitcoin will not work properly." -msgstr "Waarschuwing: Controleer of uw computers datum en tijd correct ingesteld zijn. Als uw klok fout staat zal Bitcoin niet correct werken." - -#: ../../../src/util.cpp:898 -msgid "beta" -msgstr "beta" - #: ../../../src/uibase.cpp:28 msgid "&File" msgstr "&Bestand" @@ -533,152 +919,160 @@ msgstr "&Bestand" msgid "&Your Receiving Addresses..." msgstr "&Uw ontvangstadressen..." -#: ../../../src/uibase.cpp:36 +#: ../../../src/uibase.cpp:35 +msgid "&Encrypt Wallet..." +msgstr "&Versleutel portefeuille..." + +#: ../../../src/uibase.cpp:38 +msgid "&Change Wallet Encryption Passphrase..." +msgstr "&Wijzig portefeuille-wachtwoord..." + +#: ../../../src/uibase.cpp:42 msgid "&Options..." msgstr "&Opties..." -#: ../../../src/uibase.cpp:39 +#: ../../../src/uibase.cpp:45 msgid "&Settings" msgstr "&Eigenschappen" -#: ../../../src/uibase.cpp:43 +#: ../../../src/uibase.cpp:49 msgid "&About..." msgstr "&Over..." -#: ../../../src/uibase.cpp:46 +#: ../../../src/uibase.cpp:52 msgid "&Help" msgstr "&Help" -#: ../../../src/uibase.cpp:56 +#: ../../../src/uibase.cpp:62 msgid "Address Book" msgstr "Adresboek" -#: ../../../src/uibase.cpp:69 +#: ../../../src/uibase.cpp:75 msgid "Your Bitcoin Address:" msgstr "Uw bitcoin-adres:" -#: ../../../src/uibase.cpp:76 +#: ../../../src/uibase.cpp:82 msgid " &New... " msgstr " &Nieuw... " -#: ../../../src/uibase.cpp:79 -#: ../../../src/uibase.cpp:780 -#: ../../../src/uibase.cpp:883 +#: ../../../src/uibase.cpp:85 +#: ../../../src/uibase.cpp:790 +#: ../../../src/uibase.cpp:893 msgid " &Copy to Clipboard " msgstr " &Kopieer naar plakbord " -#: ../../../src/uibase.cpp:93 +#: ../../../src/uibase.cpp:99 msgid "Balance:" msgstr "Balans:" -#: ../../../src/uibase.cpp:109 +#: ../../../src/uibase.cpp:115 msgid " All" msgstr " Alles" -#: ../../../src/uibase.cpp:109 +#: ../../../src/uibase.cpp:115 msgid " Sent" msgstr " Verstuurd" -#: ../../../src/uibase.cpp:109 +#: ../../../src/uibase.cpp:115 msgid " Received" msgstr " Ontvangen" -#: ../../../src/uibase.cpp:109 +#: ../../../src/uibase.cpp:115 msgid " In Progress" msgstr " Wordt verwerkt" -#: ../../../src/uibase.cpp:130 +#: ../../../src/uibase.cpp:136 msgid "All Transactions" msgstr "Alle transacties" -#: ../../../src/uibase.cpp:141 +#: ../../../src/uibase.cpp:147 msgid "Sent/Received" msgstr "Verstuurd/Ontvangen" -#: ../../../src/uibase.cpp:152 +#: ../../../src/uibase.cpp:158 msgid "Sent" msgstr "Verstuurd" -#: ../../../src/uibase.cpp:163 +#: ../../../src/uibase.cpp:169 msgid "Received" msgstr "Ontvangen" -#: ../../../src/uibase.cpp:302 -#: ../../../src/uibase.cpp:443 -#: ../../../src/uibase.cpp:542 -#: ../../../src/uibase.cpp:722 -#: ../../../src/uibase.cpp:783 -#: ../../../src/uibase.cpp:892 -#: ../../../src/uibase.cpp:981 +#: ../../../src/uibase.cpp:312 +#: ../../../src/uibase.cpp:453 +#: ../../../src/uibase.cpp:552 +#: ../../../src/uibase.cpp:732 +#: ../../../src/uibase.cpp:793 +#: ../../../src/uibase.cpp:902 +#: ../../../src/uibase.cpp:991 msgid "OK" msgstr "OK" -#: ../../../src/uibase.cpp:345 +#: ../../../src/uibase.cpp:355 msgid "&Start Bitcoin on system startup" msgstr "&Start Bitcoin wanneer het systeem opstart" -#: ../../../src/uibase.cpp:348 +#: ../../../src/uibase.cpp:358 msgid "&Minimize to the tray instead of the taskbar" msgstr "&Minimaliseer tot systeemvak in plaats van de taakbalk" -#: ../../../src/uibase.cpp:351 +#: ../../../src/uibase.cpp:361 msgid "Map port using &UPnP" msgstr "Portmapping via &UPnP" -#: ../../../src/uibase.cpp:354 +#: ../../../src/uibase.cpp:364 msgid "M&inimize to the tray on close" msgstr "M&inimaliseer tot taakbalk bij sluiten" -#: ../../../src/uibase.cpp:360 -msgid "&Connect through socks4 proxy: " -msgstr "&Verbind via socks4 proxy: " +#: ../../../src/uibase.cpp:370 +msgid "&Connect through socks4 proxy (requires restart to apply): " +msgstr "&Verbind via socks4 proxy (vereist herstart):" -#: ../../../src/uibase.cpp:371 +#: ../../../src/uibase.cpp:381 msgid "Proxy &IP:" msgstr "Proxy &IP:" -#: ../../../src/uibase.cpp:379 +#: ../../../src/uibase.cpp:389 msgid " &Port:" msgstr " &Poort:" -#: ../../../src/uibase.cpp:392 +#: ../../../src/uibase.cpp:402 msgid "Optional transaction fee per KB that helps make sure your transactions are processed quickly. Most transactions are 1KB. Fee 0.01 recommended." msgstr "Optionele transactiefooi per KB die helpt ervoor zorgen dat uw transacties snel verwerkt worden. De meeste transacties zijn 1KB. Fooi 0.01 is aangeraden." -#: ../../../src/uibase.cpp:399 +#: ../../../src/uibase.cpp:409 msgid "Pay transaction fee:" msgstr "Transactiefooi:" -#: ../../../src/uibase.cpp:420 +#: ../../../src/uibase.cpp:430 msgid "// [don't translate] Test panel 2 for future expansion" msgstr "" -#: ../../../src/uibase.cpp:424 +#: ../../../src/uibase.cpp:434 msgid "// [don't translate] Let's not start multiple pages until the first page is filled up" msgstr "" -#: ../../../src/uibase.cpp:446 -#: ../../../src/uibase.cpp:668 -#: ../../../src/uibase.cpp:727 -#: ../../../src/uibase.cpp:786 -#: ../../../src/uibase.cpp:895 -#: ../../../src/uibase.cpp:984 +#: ../../../src/uibase.cpp:456 +#: ../../../src/uibase.cpp:678 +#: ../../../src/uibase.cpp:737 +#: ../../../src/uibase.cpp:796 +#: ../../../src/uibase.cpp:905 +#: ../../../src/uibase.cpp:994 msgid "Cancel" msgstr "Annuleren" -#: ../../../src/uibase.cpp:449 +#: ../../../src/uibase.cpp:459 msgid "&Apply" msgstr "&Toepassen" -#: ../../../src/uibase.cpp:508 +#: ../../../src/uibase.cpp:518 msgid "Bitcoin " msgstr "Bitcoin " -#: ../../../src/uibase.cpp:514 +#: ../../../src/uibase.cpp:524 msgid "version" msgstr "versie" -#: ../../../src/uibase.cpp:525 +#: ../../../src/uibase.cpp:535 msgid "" "Copyright (c) 2009-2011 Bitcoin Developers\n" "\n" @@ -703,39 +1097,39 @@ msgstr "" "software geschreven door Eric Young (eay@cryptsoft.com)) en UPnP software geschreven\n" "door Thomas Bernard." -#: ../../../src/uibase.cpp:581 +#: ../../../src/uibase.cpp:591 msgid "Enter a Bitcoin address (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L)" msgstr "Voer een bitcoin-adres (bijvoorbeeld: 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L)" -#: ../../../src/uibase.cpp:595 +#: ../../../src/uibase.cpp:605 msgid "Pay &To:" msgstr "Betaal &aan:" -#: ../../../src/uibase.cpp:610 +#: ../../../src/uibase.cpp:620 msgid "&Paste" msgstr "&Plakken" -#: ../../../src/uibase.cpp:613 +#: ../../../src/uibase.cpp:623 msgid " Address &Book..." msgstr " Adres&boek..." -#: ../../../src/uibase.cpp:620 +#: ../../../src/uibase.cpp:630 msgid "&Amount:" msgstr "&Hoeveelheid:" -#: ../../../src/uibase.cpp:630 +#: ../../../src/uibase.cpp:640 msgid "T&ransfer:" msgstr "O&verdracht:" -#: ../../../src/uibase.cpp:636 +#: ../../../src/uibase.cpp:646 msgid " Standard" msgstr " Standaard" -#: ../../../src/uibase.cpp:663 +#: ../../../src/uibase.cpp:673 msgid "&Send" msgstr "&Versturen" -#: ../../../src/uibase.cpp:711 +#: ../../../src/uibase.cpp:721 msgid "" "\n" "\n" @@ -745,229 +1139,57 @@ msgstr "" "\n" "Verbinden..." -#: ../../../src/uibase.cpp:761 +#: ../../../src/uibase.cpp:771 msgid "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. The highlighted address is displayed in the main window." msgstr "Dit zijn je bitcoin-adressen voor het ontvangen van betalingen. Het is een goed idee iedere afzender een ander adres te geven zodat je bij kunt houden wie je een betaling stuurt. Het geselecteerde adres is zichtbaar in het hoofdscherm." -#: ../../../src/uibase.cpp:774 -#: ../../../src/uibase.cpp:886 +#: ../../../src/uibase.cpp:784 +#: ../../../src/uibase.cpp:896 msgid "&Edit..." msgstr "&Bewerken..." -#: ../../../src/uibase.cpp:777 -#: ../../../src/uibase.cpp:889 +#: ../../../src/uibase.cpp:787 +#: ../../../src/uibase.cpp:899 msgid " &New Address... " msgstr " &Nieuw adres... " -#: ../../../src/uibase.cpp:849 +#: ../../../src/uibase.cpp:859 msgid "Sending" msgstr "Versturen..." -#: ../../../src/uibase.cpp:857 +#: ../../../src/uibase.cpp:867 msgid "These are your Bitcoin addresses for receiving payments. You can give a different one to each sender to keep track of who is paying you. The highlighted address will be displayed in the main window." msgstr "Dit zijn je bitcoin-adressen voor het ontvangen van betalingen. Het is een goed idee iedere afzender een ander adres te geven zodat je bij kunt houden wie je een betaling stuurt. Het geselecteerde adres is zichtbaar in het hoofdscherm." -#: ../../../src/uibase.cpp:870 +#: ../../../src/uibase.cpp:880 msgid "Receiving" msgstr "Ontvangen..." -#: ../../../src/uibase.cpp:880 +#: ../../../src/uibase.cpp:890 msgid "&Delete" msgstr "&Verwijderen" -#: ../../../src/init.cpp:147 -msgid "Bitcoin version" -msgstr "Bitcoin " - -#: ../../../src/init.cpp:148 -msgid "Usage:" -msgstr "Mededeling:" - -#: ../../../src/init.cpp:150 -msgid "Send command to -server or bitcoind\n" -msgstr "Zend commando naar -server of bitcoind\n" - -#: ../../../src/init.cpp:151 -msgid "List commands\n" -msgstr "List van commando's\n" - -#: ../../../src/init.cpp:152 -msgid "Get help for a command\n" -msgstr "Toon hulp voor een commando\n" - -#: ../../../src/init.cpp:153 -msgid "Options:\n" -msgstr "Opties:\n" - -#: ../../../src/init.cpp:154 -msgid "Specify configuration file (default: bitcoin.conf)\n" -msgstr "Specifieer configuratiebestand (standaard: bitcoin.conf)\n" - -#: ../../../src/init.cpp:155 -msgid "Specify pid file (default: bitcoind.pid)\n" -msgstr "Specifieer pid-bestand (standaard: bitcoind.pid)\n" - -#: ../../../src/init.cpp:156 -msgid "Generate coins\n" -msgstr "Genereer coins\n" - -#: ../../../src/init.cpp:157 -msgid "Don't generate coins\n" -msgstr "Genereer geen coins\n" - -#: ../../../src/init.cpp:158 -msgid "Start minimized\n" -msgstr "Geminimaliseerd starten\n" - -#: ../../../src/init.cpp:159 -msgid "Specify data directory\n" -msgstr "Stel datamap in\n" - -#: ../../../src/init.cpp:161 -msgid "Specify connection timeout (in milliseconds)\n" -msgstr "Gelieve de time-out tijd te specifieren (in milliseconden)\n" - -#: ../../../src/init.cpp:160 -msgid "Connect through socks4 proxy\n" -msgstr "Verbind via socks4 proxy\n" - -#: ../../../src/init.cpp:161 -msgid "Allow DNS lookups for addnode and connect\n" -msgstr "Sta DNS-opzoeking toe voor addnode en connect\n" - -#: ../../../src/init.cpp:162 -msgid "Add a node to connect to\n" -msgstr "Voeg een node toe om mee te verbinden\n" - -#: ../../../src/init.cpp:163 -msgid "Connect only to the specified node\n" -msgstr "Verbind alleen met deze node\n" - -#: ../../../src/init.cpp:164 -msgid "Don't accept connections from outside\n" -msgstr "Sta geen verbindingen van buitenaf toe\n" - -#: ../../../src/init.cpp:167 -msgid "Don't attempt to use UPnP to map the listening port\n" -msgstr "Probeer geen UPnP te gebruiken om de poort waarop geluisterd wordt te mappen\n" - -#: ../../../src/init.cpp:169 -msgid "Attempt to use UPnP to map the listening port\n" -msgstr "Probeer UPnP te gebruiken om de poort waarop geluisterd wordt te mappen\n" - -#: ../../../src/init.cpp:172 -msgid "Fee per KB to add to transactions you send\n" -msgstr "Fooi per KB om aan transacties die gezonden worden toe te voegen\n" - -#: ../../../src/init.cpp:174 -msgid "Accept command line and JSON-RPC commands\n" -msgstr "Aanvaard commandolijn en JSON-RPC commando's\n" - -#: ../../../src/init.cpp:177 -msgid "Run in the background as a daemon and accept commands\n" -msgstr "Draai in de achtergrond als daemon en aanvaard commando's\n" - -#: ../../../src/init.cpp:179 -msgid "Use the test network\n" -msgstr "Gebruik het test-netwerk\n" - -#: ../../../src/init.cpp:180 -msgid "Username for JSON-RPC connections\n" -msgstr "Gebruikersnaam voor JSON-RPC verbindingen\n" - -#: ../../../src/init.cpp:181 -msgid "Password for JSON-RPC connections\n" -msgstr "Wachtwoord voor JSON-RPC verbindingen\n" - -#: ../../../src/init.cpp:182 -msgid "Listen for JSON-RPC connections on <port> (default: 8332)\n" -msgstr "Luister voor JSON-RPC verbindingen op <poort> (standaard: 8332)\n" - -#: ../../../src/init.cpp:183 -msgid "Allow JSON-RPC connections from specified IP address\n" -msgstr "Enkel JSON-RPC verbindingen van opgegeven IP adres toestaan\n" - -#: ../../../src/init.cpp:184 -msgid "Send commands to node running on <ip> (default: 127.0.0.1)\n" -msgstr "Zend commando's naar proces dat op <ip> draait (standaard: 127.0.0.1)\n" - -#: ../../../src/init.cpp:185 -msgid "Set key pool size to <n> (default: 100)\n" -msgstr "Stel sleutelpoelgrootte in op <n> (standaard: 100)\n" - -#: ../../../src/init.cpp:186 -msgid "Rescan the block chain for missing wallet transactions\n" -msgstr "Doorzoek de blokken database voor ontbrekende portefeuille-transacties\n" - -#: ../../../src/init.cpp:190 -msgid "" -"\n" -"SSL options: (see the Bitcoin Wiki for SSL setup instructions)\n" -msgstr "" -"\n" -"SSL opties: (zie de Bitcoin wiki voor SSL instructies)\n" - -#: ../../../src/init.cpp:191 -msgid "Use OpenSSL (https) for JSON-RPC connections\n" -msgstr "Gebruik OpenSSL (https) voor JSON-RPC verbindingen\n" - -#: ../../../src/init.cpp:192 -msgid "Server certificate file (default: server.cert)\n" -msgstr "Certificaat-bestand voor server (standaard: server.cert)\n" - -#: ../../../src/init.cpp:193 -msgid "Server private key (default: server.pem)\n" -msgstr "Geheime sleutel voor server (standaard: server.pem)\n" - -#: ../../../src/init.cpp:194 -msgid "Acceptable ciphers (default: TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!AH:!3DES:@STRENGTH)\n" -msgstr "Aanvaardbare ciphers (standaard: TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!AH:!3DES:@STRENGTH)\n" - -#: ../../../src/init.cpp:198 -msgid "This help message\n" -msgstr "Dit helpbericht\n" - -#: ../../../src/init.cpp:335 -#, c-format -msgid "Cannot obtain a lock on data directory %s. Bitcoin is probably already running." -msgstr "Kan geen lock op de gegevensdirectory %s verkrijgen. Bitcoin draait vermoedelijk reeds." - -#: ../../../src/init.cpp:361 -msgid "Error loading addr.dat \n" -msgstr "Fout bij laden van bestand addr.dat \n" - -#: ../../../src/init.cpp:367 -msgid "Error loading blkindex.dat \n" -msgstr "Fout bij laden van bestand blkindex.dat \n" - -#: ../../../src/init.cpp:374 -msgid "Error loading wallet.dat \n" -msgstr "Fout bij laden van bestand wallet.dat \n" - -#: ../../../src/init.cpp:454 -msgid "Invalid -proxy address" -msgstr "Foutief -proxy adres" - -#: ../../../src/init.cpp:477 -msgid "Invalid amount for -paytxfee=<amount>" -msgstr "Ongeldig bedrag voor -paytxfee=<bedrag>" +#: ../../../src/bak/wallet.cpp:957 +msgid "Invalid bitcoin address" +msgstr "Foutief bitcoin-adres" -#: ../../../src/init.cpp:481 -msgid "Warning: -paytxfee is set very high. This is the transaction fee you will pay if you send a transaction." -msgstr "Waarschuwing: -paytxfee is zeer hoog ingesteld. Dit is de fooi die betaald wordt bij het zenden van een transactie." +#: ../../../src/bak/uibase.cpp:360 +msgid "&Connect through socks4 proxy: " +msgstr "&Verbind via socks4 proxy: " -#: ../../../src/uibase.h:147 +#: ../../../src/uibase.h:151 msgid "Transaction Details" msgstr "Transactiedetails" -#: ../../../src/uibase.h:199 +#: ../../../src/uibase.h:203 msgid "Options" msgstr "Opties" -#: ../../../src/uibase.h:228 +#: ../../../src/uibase.h:232 msgid "About Bitcoin" msgstr "Over Bitcoin" -#: ../../../src/uibase.h:337 +#: ../../../src/uibase.h:341 msgid "Your Bitcoin Addresses" msgstr "Uw bitcoin-adressen" + diff --git a/locale/pl/LC_MESSAGES/bitcoin.po b/locale/pl/LC_MESSAGES/bitcoin.po index ef6be0d9da..17b5f10468 100644 --- a/locale/pl/LC_MESSAGES/bitcoin.po +++ b/locale/pl/LC_MESSAGES/bitcoin.po @@ -4,8 +4,8 @@ msgstr "" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2011-06-28 20:11+0100\n" "PO-Revision-Date: \n" -"Last-Translator: Dawid Spiechowicz <spiechu@gmail.com>\n" -"Language-Team: Spiechu <spiechu@gmail.com>\n" +"Last-Translator: Krystian Maksymowicz <krystian.maksymowicz@gmail.com>\n" +"Language-Team: Spiechu <spiechu@gmail.com>, Krystian Maksymowicz <krystian.maksymowicz@gmail.com>\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" @@ -21,7 +21,7 @@ msgstr "" #: ../../../src/net.cpp:1590 #, c-format msgid "Unable to bind to port %d on this computer. Bitcoin is probably already running." -msgstr "Nie można powiązać z portem %d tego komputera. Prawdopodobnie program Bitcoin jest już uruchomiony." +msgstr "Powiązanie z portem %d nie powiodło się. Prawdopodobnie Bitcoin jest już uruchomiony." #: ../../../src/init.cpp:162 msgid "Bitcoin version" @@ -29,7 +29,7 @@ msgstr "Wersja Bitcoin" #: ../../../src/init.cpp:163 msgid "Usage:" -msgstr "Użycie:" +msgstr "Zastosowanie:" #: ../../../src/init.cpp:165 msgid "Send command to -server or bitcoind\n" @@ -37,7 +37,7 @@ msgstr "Wyślij polecenie do -server lub bitcoind\n" #: ../../../src/init.cpp:166 msgid "List commands\n" -msgstr "Wyświetl komendy\n" +msgstr "Lista komend\n" #: ../../../src/init.cpp:167 msgid "Get help for a command\n" @@ -53,7 +53,7 @@ msgstr "Określ plik konfiguracyjny (domyślnie: bitcoin.conf)\n" #: ../../../src/init.cpp:170 msgid "Specify pid file (default: bitcoind.pid)\n" -msgstr "Wybierz plik pid (domyślnie: bitcoind.pid)\n" +msgstr "Określ plik pid (domyślnie: bitcoind.pid)\n" #: ../../../src/init.cpp:171 msgid "Generate coins\n" @@ -69,20 +69,22 @@ msgstr "Uruchom zminimalizowany\n" #: ../../../src/init.cpp:174 msgid "Specify data directory\n" -msgstr "Wybierz katalog z danymi\n" +msgstr "Określ katalog danych\n" #: ../../../src/init.cpp:175 msgid "Specify connection timeout (in milliseconds)\n" -msgstr "Ustaw czas upływu połączenia (w milisekundach)\n" +msgstr "Ustaw limit czasu połączenia (w milisekundach)\n" #: ../../../src/init.cpp:176 msgid "Connect through socks4 proxy\n" -msgstr "Połącz przez socks4 proxy\n" +msgstr "Połącz przez proxy socks4\n" +# 2do #: ../../../src/init.cpp:177 msgid "Allow DNS lookups for addnode and connect\n" -msgstr "Umożliwiaj wyszukiwanie DNS dla dodania węzła i połączenia\n" +msgstr "Umożliwiaj wyszukiwanie DNS przy dodawaniu węzła i połączenia\n" +# 2do #: ../../../src/init.cpp:178 msgid "Add a node to connect to\n" msgstr "Dodaj węzeł do którego połączyć\n" @@ -234,7 +236,7 @@ msgstr "" #: ../../../src/util.cpp:874 msgid "Warning: Please check that your computer's date and time are correct. If your clock is wrong Bitcoin will not work properly." -msgstr "Ostrzeżenie: Sprawdź czy ustawienia daty i czasu komputera są prawidłowe. Jeżeli zegar jest źle ustawiony, Bitcoin nie będzie poprawnie działał." +msgstr "Ostrzeżenie: Sprawdź czy ustawienia daty i czasu komputera są prawidłowe. Jeżeli zegar jest źle ustawiony, Bitcoin nie będzie działał poprawnie." #: ../../../src/util.cpp:908 msgid "beta" @@ -243,11 +245,11 @@ msgstr "beta" #: ../../../src/ui.cpp:216 #, c-format msgid "This transaction is over the size limit. You can still send it for a fee of %s, which goes to the nodes that process your transaction and helps to support the network. Do you want to pay the fee?" -msgstr "Ta transakcja jest poza limitem wielkości. W dalszym ciągu możesz wysłać ją z prowizją %s, która dotrze do węzłów przetwarzających twoją transakcję i pomoże utrzymać sieć. Chcesz zapłacić prowizję?" +msgstr "Ta transakcja przekracza limit wielkości. W dalszym ciągu możesz ją wysłać z prowizją %s, która dotrze do węzłów przetwarzających twoją transakcję i pomoże utrzymać całą sieć. Chcesz zapłacić prowizję?" #: ../../../src/ui.cpp:316 msgid "Status" -msgstr "Status" +msgstr "Stan" #: ../../../src/ui.cpp:317 msgid "Date" @@ -259,11 +261,11 @@ msgstr "Opis" #: ../../../src/ui.cpp:319 msgid "Debit" -msgstr "Obciążenie" +msgstr "Debet" #: ../../../src/ui.cpp:320 msgid "Credit" -msgstr "Suma" +msgstr "Kredyt" #: ../../../src/ui.cpp:526 #, c-format @@ -283,7 +285,7 @@ msgstr "%d/offline?" #: ../../../src/ui.cpp:536 #, c-format msgid "%d/unconfirmed" -msgstr "%d/niepotwierdzono" +msgstr "%d/niepotwierdzona" #: ../../../src/ui.cpp:538 #, c-format @@ -339,7 +341,7 @@ msgstr " %d połączeń %d bloków %d transakcji" #: ../../../src/ui.cpp:1178 #: ../../../src/ui.cpp:2571 msgid "New Receiving Address" -msgstr "Nowy Adres Odbiorczy" +msgstr "Nowy adres odbiorczy" #: ../../../src/ui.cpp:1179 #: ../../../src/ui.cpp:2572 @@ -348,7 +350,7 @@ msgid "" "\n" "Label" msgstr "" -"Powinieneś użyć nowego adresu dla każdej płatności, którą otrzymasz.\n" +"Powinieneś używać nowych adresów dla każdej otrzymywanej płatności.\n" "\n" "Etykieta" @@ -406,7 +408,7 @@ msgstr " (twoja)" #: ../../../src/ui.cpp:1397 #: ../../../src/ui.cpp:1414 msgid "<b>Credit:</b> " -msgstr "<b>Suma:</b>" +msgstr "<b>Kredyt:</b>" #: ../../../src/ui.cpp:1341 #, c-format @@ -421,7 +423,7 @@ msgstr "(nie zaakceptowano)" #: ../../../src/ui.cpp:1396 #: ../../../src/ui.cpp:1411 msgid "<b>Debit:</b> " -msgstr "<b>Obciążenie:</b>" +msgstr "<b>Debet:</b>" #: ../../../src/ui.cpp:1402 msgid "<b>Transaction fee:</b> " @@ -441,7 +443,7 @@ msgstr "Komentarz:" #: ../../../src/ui.cpp:1430 msgid "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 \"not accepted\" and not be spendable. This may occasionally happen if another node generates a block within a few seconds of yours." -msgstr "Wygenerowane monety muszą poczekać 120 bloków zanim mogą zostać wydane. Gdy wygenerowałeś ten blok, został rozgłoszony do sieci z przeznaczeniem do dodania do łańcucha bloków. Jeżeli nie uda się dodać bloku do łańcucha, zostanie oznaczony jako \"nie zaakceptowany\" i nie będzie mógł zostać wydany. Sporadycznie dzieje się tak jeżeli inny węzeł wygeneruje blok nie dalej niż kilka sekund od ciebie." +msgstr "Wygenerowane monety muszą poczekać 120 bloków zanim będą mogły być wydane. Wygenerowany blok został został rozgłoszony w sieci z przeznaczeniem dodawania nowych bloków do łańcucha. Jeżeli nie uda się go dodać do łańcucha, zostanie oznaczony jako \"nie zaakceptowany\" i nie będzie mógł być wydany. Sporadycznie dzieje się tak jeżeli inny węzeł wygeneruje blok nie dalej niż kilka sekund od ciebie." #: ../../../src/ui.cpp:1610 msgid "Cannot write autostart/bitcoin.desktop file" @@ -520,7 +522,7 @@ msgstr "Anulowano" #: ../../../src/ui.cpp:2107 msgid "Transfer cancelled " -msgstr "Transfer anulowano" +msgstr "Transfer anulowany" #: ../../../src/ui.cpp:2160 msgid "Error: " @@ -567,7 +569,7 @@ msgstr "Tworzenie transakcji..." #: ../../../src/ui.cpp:2253 #, c-format msgid "This transaction requires a transaction fee of at least %s because of its amount, complexity, or use of recently received funds" -msgstr "Ta transakcja wymaga prowizji co najmniej %s z uwagi na kwotę, złożoność lub użycie niedawno otrzymanych funduszy" +msgstr "Ta transakcja wymaga prowizji co najmniej %s z uwagi na jej kwotę, złożoność lub wykorzystanie niedawno otrzymanych funduszy" #: ../../../src/ui.cpp:2255 msgid "Transaction creation failed" @@ -575,7 +577,7 @@ msgstr "Błąd tworzenia transakcji " #: ../../../src/ui.cpp:2262 msgid "Transaction aborted" -msgstr "Transakcję przerwano" +msgstr "Przerwano transakcję" #: ../../../src/ui.cpp:2270 msgid "Lost connection, transaction cancelled" @@ -635,21 +637,21 @@ msgstr "Adres Bitcoin" #: ../../../src/ui.cpp:2504 msgid "This is one of your own addresses for receiving payments and cannot be entered in the address book. " -msgstr "To jest jeden z twoich adresów na otrzymywane płatności i nie może zostać wpisany do księgi adresowej." +msgstr "To jest jeden z twoich adresów na otrzymywane płatności i nie może zostać wpisany do książki adresowej." #: ../../../src/ui.cpp:2522 #: ../../../src/ui.cpp:2528 msgid "Edit Address" -msgstr "Edytuj Adres" +msgstr "Edytuj adres" #: ../../../src/ui.cpp:2534 msgid "Edit Address Label" -msgstr "Edytuj Etykietę Adresu" +msgstr "Edytuj etykietę adresu" #: ../../../src/ui.cpp:2559 #: ../../../src/ui.cpp:2565 msgid "Add Address" -msgstr "Dodaj Adres" +msgstr "Dodaj adres" #: ../../../src/ui.cpp:2642 msgid "Bitcoin" @@ -682,7 +684,7 @@ msgstr "W&yjście" #: ../../../src/ui.cpp:2956 msgid "Program has crashed and will terminate. " -msgstr "Program uległ awarii i zostanie przerwany." +msgstr "Program uległ awarii i zostanie zamknięty." #: ../../../src/main.cpp:1430 msgid "Warning: Disk space is low " @@ -694,7 +696,7 @@ msgstr "&Plik" #: ../../../src/uibase.cpp:32 msgid "&Your Receiving Addresses..." -msgstr "&Twój Adres Odbiorczy..." +msgstr "&Twój adres odbiorczy..." #: ../../../src/uibase.cpp:36 msgid "&Options..." @@ -714,11 +716,11 @@ msgstr "&Pomoc" #: ../../../src/uibase.cpp:56 msgid "Address Book" -msgstr "Księga Adresowa" +msgstr "Książka adresowa" #: ../../../src/uibase.cpp:69 msgid "Your Bitcoin Address:" -msgstr "Twój Adres Bitcoin:" +msgstr "Twój adres Bitcoin:" #: ../../../src/uibase.cpp:76 msgid " &New... " @@ -740,31 +742,31 @@ msgstr " Wszystko" #: ../../../src/uibase.cpp:109 msgid " Sent" -msgstr "Wysłano" +msgstr " Wysłano" #: ../../../src/uibase.cpp:109 msgid " Received" -msgstr "Otrzymano" +msgstr " Otrzymano" #: ../../../src/uibase.cpp:109 msgid " In Progress" -msgstr "W Trakcie" +msgstr "W realizacji" #: ../../../src/uibase.cpp:130 msgid "All Transactions" -msgstr "Wszystkie Transakcje" +msgstr "Wszystkie transakcje" #: ../../../src/uibase.cpp:141 msgid "Sent/Received" -msgstr "Wysłano/Otrzymano" +msgstr "Wysłane/Otrzymane" #: ../../../src/uibase.cpp:152 msgid "Sent" -msgstr "Wysłano" +msgstr "Wysłane" #: ../../../src/uibase.cpp:163 msgid "Received" -msgstr "Otrzymano" +msgstr "Otrzymane" #: ../../../src/uibase.cpp:302 #: ../../../src/uibase.cpp:443 @@ -782,7 +784,7 @@ msgstr "&Uruchom Bitcoin wraz ze startem systemu" #: ../../../src/uibase.cpp:348 msgid "&Minimize to the tray instead of the taskbar" -msgstr "&Zminimalizuj do traya zamiast do paska zadań" +msgstr "&Minimalizuj do obszaru powiadomień zamiast paska zadań" #: ../../../src/uibase.cpp:351 msgid "Map port using &UPnP" @@ -790,11 +792,11 @@ msgstr "Mapuj port używając &UPnP" #: ../../../src/uibase.cpp:354 msgid "M&inimize to the tray on close" -msgstr "Zm&inimalizuj do traya przy zamknięciu" +msgstr "M&inimalizuj do obszaru powiadomień przy zamknięciu" #: ../../../src/uibase.cpp:360 msgid "&Connect through socks4 proxy: " -msgstr "&Połącz przez socks4 proxy:" +msgstr "&Połącz przez proxy socks4:" #: ../../../src/uibase.cpp:371 msgid "Proxy &IP:" @@ -806,11 +808,11 @@ msgstr " &Port:" #: ../../../src/uibase.cpp:392 msgid "Optional transaction fee per KB that helps make sure your transactions are processed quickly. Most transactions are 1KB. Fee 0.01 recommended." -msgstr "Opcjonalna prowizja określona dla KB transakcji, która zapewni, że twoje transakcje będą szybko przetworzone. Większość transakcji to 1KB. Rekomendowana prowizja to 0.01." +msgstr "Opcjonalna prowizja określona na każdy KB transakcji, zapewniająca szybkie przetworzenie. Większość transakcji to 1KB. Rekomendowana prowizja to 0.01." #: ../../../src/uibase.cpp:399 msgid "Pay transaction fee:" -msgstr "Płać prowizję transakcji:" +msgstr "Płać prowizję od transakcji:" #: ../../../src/uibase.cpp:420 msgid "// [don't translate] Test panel 2 for future expansion" @@ -835,7 +837,7 @@ msgstr "&Zastosuj" #: ../../../src/uibase.cpp:508 msgid "Bitcoin " -msgstr "Bitcoin" +msgstr "Bitcoin " #: ../../../src/uibase.cpp:514 msgid "version" @@ -871,7 +873,7 @@ msgstr "Wprowadź adres Bitcoin (np. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L)" #: ../../../src/uibase.cpp:595 msgid "Pay &To:" -msgstr "Wpłać &Dla:" +msgstr "Wpłać &dla:" #: ../../../src/uibase.cpp:610 msgid "&Paste" @@ -879,11 +881,11 @@ msgstr "&Wklej" #: ../../../src/uibase.cpp:613 msgid " Address &Book..." -msgstr " Księga &Adresowa..." +msgstr " Książka &adresowa..." #: ../../../src/uibase.cpp:620 msgid "&Amount:" -msgstr "&Kwota:" +msgstr "&Saldo:" #: ../../../src/uibase.cpp:630 msgid "T&ransfer:" @@ -909,7 +911,7 @@ msgstr "" #: ../../../src/uibase.cpp:761 msgid "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. The highlighted address is displayed in the main window." -msgstr "To są twoje adresy Bitcoin dla otrzymywania płatności. Możesz chcieć podać różne dla każdego płacącego aby kontrolować kto ci płaci. Wyróżniony adres będzie wyświetlany w oknie głównym." +msgstr "To są twoje adresy Bitcoin dla otrzymywania płatności. Możesz chcieć podawać inny dla każdego płacącego aby kontrolować kto ci płaci. Wyróżniony adres będzie wyświetlany w oknie głównym." #: ../../../src/uibase.cpp:774 #: ../../../src/uibase.cpp:886 @@ -919,7 +921,7 @@ msgstr "&Edytuj..." #: ../../../src/uibase.cpp:777 #: ../../../src/uibase.cpp:889 msgid " &New Address... " -msgstr " &Nowy Adres..." +msgstr " &Nowy adres..." #: ../../../src/uibase.cpp:849 msgid "Sending" @@ -960,7 +962,7 @@ msgstr "Niewłaściwy adres bitcoin" #: ../../../src/uibase.h:147 msgid "Transaction Details" -msgstr "Szczegóły Transakcji" +msgstr "Szczegóły transakcji" #: ../../../src/uibase.h:199 msgid "Options" @@ -972,5 +974,5 @@ msgstr "O Bitcoin" #: ../../../src/uibase.h:337 msgid "Your Bitcoin Addresses" -msgstr "Twoje Adresy Bitcoin" +msgstr "Twoje adresy bitcoin" diff --git a/locale/pt/LC_MESSAGES/bitcoin.mo b/locale/pt/LC_MESSAGES/bitcoin.mo Binary files differindex 20e100f578..35a3fd7bc9 100644 --- a/locale/pt/LC_MESSAGES/bitcoin.mo +++ b/locale/pt/LC_MESSAGES/bitcoin.mo diff --git a/locale/readme.txt b/locale/readme.txt index 9fca3ce657..4019bf43c9 100644 --- a/locale/readme.txt +++ b/locale/readme.txt @@ -3,3 +3,5 @@ locale/<langcode>/LC_MESSAGES/bitcoin.mo and .po .po is the sourcefile
.mo is the compiled translation
+
+Note: pull requests should only include the .po file. Do not include .mo file
\ No newline at end of file diff --git a/locale/ro/LC_MESSAGES/bitcoin.mo b/locale/ro/LC_MESSAGES/bitcoin.mo Binary files differnew file mode 100644 index 0000000000..0eb994bcbe --- /dev/null +++ b/locale/ro/LC_MESSAGES/bitcoin.mo diff --git a/locale/ro/LC_MESSAGES/bitcoin.po b/locale/ro/LC_MESSAGES/bitcoin.po new file mode 100644 index 0000000000..e906e97566 --- /dev/null +++ b/locale/ro/LC_MESSAGES/bitcoin.po @@ -0,0 +1,1078 @@ +msgid "" +msgstr "" +"Project-Id-Version: \n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2011-09-06 03:47+0100\n" +"PO-Revision-Date: 2011-09-06 06:36+0100\n" +"Last-Translator: Alex B <paraipanakos@gmail.com>\n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: \n" +"X-Poedit-KeywordsList: _;gettext;gettext_noop\n" +"X-Poedit-Basepath: .\n" +"X-Poedit-Language: Romanian\n" +"X-Poedit-SourceCharset: iso-8859-2\n" +"X-Poedit-SearchPath-0: ../../..\n" + +#: ../../../src/init.cpp:163 +msgid "Bitcoin version" +msgstr "versiune Bitcoin" + +#: ../../../src/init.cpp:164 +msgid "Usage:" +msgstr "Uz:" + +#: ../../../src/init.cpp:166 +msgid "Send command to -server or bitcoind\n" +msgstr "Trimite comanda la bitcoin lansat cu -server sau bitcoind\n" + +#: ../../../src/init.cpp:167 +msgid "List commands\n" +msgstr "Listeaza comenzi\n" + +#: ../../../src/init.cpp:168 +msgid "Get help for a command\n" +msgstr "Ajutor pentru o comanda\n" + +#: ../../../src/init.cpp:169 +msgid "Options:\n" +msgstr "Optiuni:\n" + +#: ../../../src/init.cpp:170 +msgid "Specify configuration file (default: bitcoin.conf)\n" +msgstr "Specifica fisier de configuratie (predeterminat: bitcoin.conf)\n" + +#: ../../../src/init.cpp:171 +msgid "Specify pid file (default: bitcoind.pid)\n" +msgstr "Specifica fisier pid (predeterminat: bitcoin.pid)\n" + +#: ../../../src/init.cpp:172 +msgid "Generate coins\n" +msgstr "Genereaza monede\n" + +#: ../../../src/init.cpp:173 +msgid "Don't generate coins\n" +msgstr "Nu genera monede\n" + +#: ../../../src/init.cpp:174 +msgid "Start minimized\n" +msgstr "Porneste minimizat\n" + +#: ../../../src/init.cpp:175 +msgid "Specify data directory\n" +msgstr "Specifica directorul de date\n" + +#: ../../../src/init.cpp:176 +msgid "Specify connection timeout (in milliseconds)\n" +msgstr "Specifica timpul maxim de conexiune (in milisecunde)\n" + +#: ../../../src/init.cpp:177 +msgid "Connect through socks4 proxy\n" +msgstr "Conecteaza prin proxy socks4\n" + +#: ../../../src/init.cpp:178 +msgid "Allow DNS lookups for addnode and connect\n" +msgstr "Permite cautare DNS pentru addnode si connect\n" + +#: ../../../src/init.cpp:179 +msgid "Add a node to connect to\n" +msgstr "Adauga un nod de conectare\n" + +#: ../../../src/init.cpp:180 +msgid "Connect only to the specified node\n" +msgstr "Conecteaza numai la nodul specificat\n" + +#: ../../../src/init.cpp:181 +msgid "Don't accept connections from outside\n" +msgstr "Nu accepta conexiuni din exterior\n" + +#: ../../../src/init.cpp:184 +msgid "Don't attempt to use UPnP to map the listening port\n" +msgstr "Nu utiliza UPnP pentru deschiderea portul de ascultare\n" + +#: ../../../src/init.cpp:186 +msgid "Attempt to use UPnP to map the listening port\n" +msgstr "Incearca sa utilizezi UPnP pentru deschiderea portului de ascultare.\n" + +#: ../../../src/init.cpp:189 +msgid "Fee per KB to add to transactions you send\n" +msgstr "Comision per KB ce se adauga la tranzactiile transmise\n" + +#: ../../../src/init.cpp:191 +msgid "Accept command line and JSON-RPC commands\n" +msgstr "Accepta comenzi de consola si JSON-RPC\n" + +#: ../../../src/init.cpp:194 +msgid "Run in the background as a daemon and accept commands\n" +msgstr "Executa ca daemon si accepta comenzi\n" + +#: ../../../src/init.cpp:196 +msgid "Use the test network\n" +msgstr "Utilizeaza reteaua de probe\n" + +#: ../../../src/init.cpp:197 +msgid "Username for JSON-RPC connections\n" +msgstr "Utilizator pentru conexiuni JSON-RPC\n" + +#: ../../../src/init.cpp:198 +msgid "Password for JSON-RPC connections\n" +msgstr "Parola pentru conexiuni JSON-RPC\n" + +#: ../../../src/init.cpp:199 +msgid "Listen for JSON-RPC connections on <port> (default: 8332)\n" +msgstr "Asculta conexiuni JSON-RPC pe portul <puerto> (predeterminat: 8332)\n" + +#: ../../../src/init.cpp:200 +msgid "Allow JSON-RPC connections from specified IP address\n" +msgstr "Permite conexiuni JSON-RPC de la adresa IP specifica\n" + +#: ../../../src/init.cpp:201 +msgid "Send commands to node running on <ip> (default: 127.0.0.1)\n" +msgstr "Trimite comanda la nod existent la <ip> (predeterminat: 127.0.0.1)\n" + +#: ../../../src/init.cpp:202 +msgid "Set key pool size to <n> (default: 100)\n" +msgstr "Ajusteaza numarul de chei in rezerva (predeterminat: 100)\n" + +#: ../../../src/init.cpp:203 +msgid "Rescan the block chain for missing wallet transactions\n" +msgstr "Rescaneza lantul de blocuri in cautare de tranzacti lipsa din portofel\n" + +#: ../../../src/init.cpp:207 +msgid "" +"\n" +"SSL options: (see the Bitcoin Wiki for SSL setup instructions)\n" +msgstr "" +"\n" +"Optiuni SSL: (vezi la Wiki Bitcoin pentru instructiuni detaliate)\n" + +#: ../../../src/init.cpp:208 +msgid "Use OpenSSL (https) for JSON-RPC connections\n" +msgstr "Utilizeaza OpenSSL (https) pentru conexiunile JSON-RPC\n" + +#: ../../../src/init.cpp:209 +msgid "Server certificate file (default: server.cert)\n" +msgstr "Arhiva certificat de server (predeterminat: server.cert)\n" + +#: ../../../src/init.cpp:210 +msgid "Server private key (default: server.pem)\n" +msgstr "Cheie privata de server (predeterminat: server.pem)\n" + +#: ../../../src/init.cpp:211 +msgid "Acceptable ciphers (default: TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!AH:!3DES:@STRENGTH)\n" +msgstr "Tipuri de cifrare acceptate (predeterminat: TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!AH:!3DES:@STRENGTH)\n" + +#: ../../../src/init.cpp:215 +msgid "This help message\n" +msgstr "Acest mesaj de ajutor\n" + +#: ../../../src/init.cpp:353 +#, c-format +msgid "Cannot obtain a lock on data directory %s. Bitcoin is probably already running." +msgstr "Nu se poate obtine permis de lucru in directorul de date %s. E posibil ca Bitcoin sa fie deja in executie." + +#: ../../../src/init.cpp:379 +msgid "Error loading addr.dat \n" +msgstr "Eroare la incarcare addr.dat \n" + +#: ../../../src/init.cpp:385 +msgid "Error loading blkindex.dat \n" +msgstr "Eroare la incarcare blkindex.dat \n" + +#: ../../../src/init.cpp:396 +msgid "Error loading wallet.dat: Wallet corrupted \n" +msgstr "Eroare la incarcare wallet.dat \n" + +#: ../../../src/init.cpp:398 +msgid "Error loading wallet.dat: Wallet requires newer version of Bitcoin \n" +msgstr "Eroare la incarcare wallet.dat: E necesare o versiune mai noua de Bitcoin \n" + +#: ../../../src/init.cpp:400 +msgid "Error loading wallet.dat \n" +msgstr "Eroare la incarcare wallet.dat \n" + +#: ../../../src/init.cpp:489 +msgid "Invalid -proxy address" +msgstr "Adresa -proxy invalida" + +#: ../../../src/init.cpp:514 +msgid "Invalid amount for -paytxfee=<amount>" +msgstr "Cantitate invalida pentru -paytxfee=<amount>" + +#: ../../../src/init.cpp:518 +msgid "Warning: -paytxfee is set very high. This is the transaction fee you will pay if you send a transaction." +msgstr "Atentie: -paytxfee este prea mare. Acesta este comisionul platit la fiecare tranzactie." + +#: ../../../src/main.cpp:1398 +msgid "Warning: Disk space is low " +msgstr "Atentie: Spatiul pe hard disk este redus" + +#: ../../../src/net.cpp:1610 +#, c-format +msgid "Unable to bind to port %d on this computer. Bitcoin is probably already running." +msgstr "Nu e posibila ascultarea pe portul %d in acest calculator. Probabil clientul Bitcoin este deja in executie." + +#: ../../../src/rpc.cpp:2005 +#: ../../../src/rpc.cpp:2007 +#, c-format +msgid "To use the %s option" +msgstr "Pentru a utiliza optiunea %s" + +#: ../../../src/rpc.cpp:2009 +#, c-format +msgid "" +"Warning: %s, you must set rpcpassword=<password>\n" +"in the configuration file: %s\n" +"If the file does not exist, create it with owner-readable-only file permissions.\n" +msgstr "" +"Atentie: %s, trebuie sa specifici rpcpassword=<password>\n" +"in fisierul de configuratie: %s\n" +"Daca fisierul nu exista trebuie creat cu permisiuni de citire numai pentru autor.\n" + +#: ../../../src/rpc.cpp:2185 +#, c-format +msgid "" +"You must set rpcpassword=<password> in the configuration file:\n" +"%s\n" +"If the file does not exist, create it with owner-readable-only file permissions." +msgstr "" +"Trebuie sa specifici rpcpassword=<password> in fisierul de configuratie:\n" +"%s\n" +"Daca fisierul nu exista trebuie creat cu permisiuni de citire numai pentru autor." + +#: ../../../src/ui.cpp:217 +#, c-format +msgid "This transaction is over the size limit. You can still send it for a fee of %s, which goes to the nodes that process your transaction and helps to support the network. Do you want to pay the fee?" +msgstr "Aceasta tranzactie trece peste limita de dimensiune. O poti trimite in continuare pentru %s, care taxa se imparte intre nodurile ce receptioneaza tranzactia si ajuta la mentinerea retelei. Continui tranzactia?" + +#: ../../../src/ui.cpp:261 +#: ../../../src/ui.cpp:1247 +msgid "Enter the current passphrase to the wallet." +msgstr "Introduce parola actuala de portofel" + +#: ../../../src/ui.cpp:262 +#: ../../../src/ui.cpp:1183 +#: ../../../src/ui.cpp:1200 +#: ../../../src/ui.cpp:1248 +#: ../../../src/ui.cpp:1272 +#: ../../../src/ui.cpp:1292 +msgid "Passphrase" +msgstr "Parola" + +#: ../../../src/ui.cpp:268 +msgid "Please supply the current wallet decryption passphrase." +msgstr "Introduce parola actuala para decriptarea portofelului." + +#: ../../../src/ui.cpp:276 +#: ../../../src/ui.cpp:1257 +#: ../../../src/ui.cpp:1314 +msgid "The passphrase entered for the wallet decryption was incorrect." +msgstr "Parola introdusa pentru decriptarea portofelului nu este corecta." + +#: ../../../src/ui.cpp:353 +msgid "Status" +msgstr "Stare" + +#: ../../../src/ui.cpp:354 +msgid "Date" +msgstr "Data" + +#: ../../../src/ui.cpp:355 +msgid "Description" +msgstr "Descriere" + +#: ../../../src/ui.cpp:356 +msgid "Debit" +msgstr "Debit" + +#: ../../../src/ui.cpp:357 +msgid "Credit" +msgstr "Credit" + +#: ../../../src/ui.cpp:568 +#, c-format +msgid "Open for %d blocks" +msgstr "Deschis pentru %d blocuri" + +#: ../../../src/ui.cpp:570 +#, c-format +msgid "Open until %s" +msgstr "Deschis pana la %s" + +#: ../../../src/ui.cpp:576 +#, c-format +msgid "%d/offline?" +msgstr "%d/desconectat?" + +#: ../../../src/ui.cpp:578 +#, c-format +msgid "%d/unconfirmed" +msgstr "%d/neconfirmat" + +#: ../../../src/ui.cpp:580 +#, c-format +msgid "%d confirmations" +msgstr "%d confirmari" + +#: ../../../src/ui.cpp:665 +msgid "Generated" +msgstr "Generat" + +#: ../../../src/ui.cpp:673 +#, c-format +msgid "Generated (%s matures in %d more blocks)" +msgstr "Generat (%s matureaza in %d blocuri)" + +#: ../../../src/ui.cpp:677 +msgid "Generated - Warning: This block was not received by any other nodes and will probably not be accepted!" +msgstr "Generat - Atentie: Acest block nu se a receptionat de la alte noduri si probabil nu va fi acceptat!" + +#: ../../../src/ui.cpp:681 +msgid "Generated (not accepted)" +msgstr "Generat (neaceptat)" + +#: ../../../src/ui.cpp:691 +msgid "From: " +msgstr "De: " + +#: ../../../src/ui.cpp:715 +msgid "Received with: " +msgstr "Receptionat cu: " + +#: ../../../src/ui.cpp:760 +msgid "Payment to yourself" +msgstr "Plata proprie" + +#: ../../../src/ui.cpp:794 +msgid "To: " +msgstr "Pentru: " + +#: ../../../src/ui.cpp:1109 +msgid " Generating" +msgstr " Genereaza" + +#: ../../../src/ui.cpp:1111 +msgid "(not connected)" +msgstr "(neconectat)" + +#: ../../../src/ui.cpp:1114 +#, c-format +msgid " %d connections %d blocks %d transactions" +msgstr " %d conexiuni %d blocuri %d tranzactii" + +#: ../../../src/ui.cpp:1171 +msgid "Wallet already encrypted." +msgstr "Portofel deja encriptat." + +#: ../../../src/ui.cpp:1182 +msgid "" +"Enter the new passphrase to the wallet.\n" +"Please use a passphrase of 10 or more random characters, or eight or more words." +msgstr "" +"Introduce noua parola de portofel.\n" +"Te rugam sa utilizezi o parola de 10 sau mai multe caracter aleatoare sau minimum opt cuvinte." + +#: ../../../src/ui.cpp:1189 +#: ../../../src/ui.cpp:1280 +msgid "Error: The supplied passphrase was too short." +msgstr "Eroare: Parola introdusa este prea scurta." + +#: ../../../src/ui.cpp:1193 +msgid "" +"WARNING: If you encrypt your wallet and lose your passphrase, you will LOSE ALL OF YOUR BITCOINS!\n" +"Are you sure you wish to encrypt your wallet?" +msgstr "" +"ATENTIE: Daca encriptezi portofelul si uiti parola vei pierde TOATE MONEDELE!\n" +"Esti sigur ca vrei sa encriptezi portofelul?" + +#: ../../../src/ui.cpp:1199 +msgid "Please re-enter your new wallet passphrase." +msgstr "Reintroduce noua parola de portofel." + +#: ../../../src/ui.cpp:1208 +#: ../../../src/ui.cpp:1302 +msgid "Error: the supplied passphrases didn't match." +msgstr "Eroare: parolele introduse nu sunt identice." + +#: ../../../src/ui.cpp:1218 +msgid "Wallet encryption failed." +msgstr "Encriptare portofel esuata." + +#: ../../../src/ui.cpp:1225 +msgid "" +"Wallet Encrypted.\n" +"Remember that encrypting your wallet cannot fully protect your bitcoins from being stolen by malware infecting your computer." +msgstr "" +"Portofel encriptat.\n" +"Retine ca encriptarea portofelului nu iti poate proteja complet monedele daca pc-ul este infectat de malware." + +#: ../../../src/ui.cpp:1236 +msgid "Wallet is unencrypted, please encrypt it first." +msgstr "Portofelul nu este encriptat, incearca sa-l encriptezi inainte." + +#: ../../../src/ui.cpp:1271 +msgid "Enter the new passphrase for the wallet." +msgstr "Introduce noua parola de portofel." + +#: ../../../src/ui.cpp:1291 +msgid "Re-enter the new passphrase for the wallet." +msgstr "Reintroduce noua parola de portofel." + +#: ../../../src/ui.cpp:1323 +msgid "Wallet Passphrase Changed." +msgstr "Parola de portofel schimbata." + +#: ../../../src/ui.cpp:1379 +#: ../../../src/ui.cpp:2821 +msgid "New Receiving Address" +msgstr "Adresa Noua de Primire" + +#: ../../../src/ui.cpp:1380 +#: ../../../src/ui.cpp:2822 +msgid "" +"You should use a new address for each payment you receive.\n" +"\n" +"Label" +msgstr "" +"Cel mai indicat e sa utilizezi a adresa noua pentru fiecare plata primita.\n" +"\n" +"Eticheta" + +#: ../../../src/ui.cpp:1464 +msgid "<b>Status:</b> " +msgstr "<b>Stare:</b> " + +#: ../../../src/ui.cpp:1469 +msgid ", has not been successfully broadcast yet" +msgstr ", inca nu a fost trimisa cu succes" + +#: ../../../src/ui.cpp:1471 +#, c-format +msgid ", broadcast through %d node" +msgstr ", emis prin nod %d" + +#: ../../../src/ui.cpp:1473 +#, c-format +msgid ", broadcast through %d nodes" +msgstr ", emis prin noduri %d" + +#: ../../../src/ui.cpp:1477 +msgid "<b>Date:</b> " +msgstr "<b>Data:</b> " + +#: ../../../src/ui.cpp:1485 +msgid "<b>Source:</b> Generated<br>" +msgstr "<b>Sursa:</b> Generat<br>" + +#: ../../../src/ui.cpp:1491 +#: ../../../src/ui.cpp:1508 +msgid "<b>From:</b> " +msgstr "<b>De:</b> " + +#: ../../../src/ui.cpp:1508 +msgid "unknown" +msgstr "necunoscut" + +#: ../../../src/ui.cpp:1509 +#: ../../../src/ui.cpp:1533 +#: ../../../src/ui.cpp:1592 +msgid "<b>To:</b> " +msgstr "<b>Pentru:</b> " + +#: ../../../src/ui.cpp:1512 +msgid " (yours, label: " +msgstr "(tau, eticheta: " + +#: ../../../src/ui.cpp:1514 +msgid " (yours)" +msgstr "(tau)" + +#: ../../../src/ui.cpp:1551 +#: ../../../src/ui.cpp:1563 +#: ../../../src/ui.cpp:1609 +#: ../../../src/ui.cpp:1626 +msgid "<b>Credit:</b> " +msgstr "<b>Credit:</b> " + +#: ../../../src/ui.cpp:1553 +#, c-format +msgid "(%s matures in %d more blocks)" +msgstr "(%s matureaza in %d blocuri)" + +#: ../../../src/ui.cpp:1555 +msgid "(not accepted)" +msgstr "(neaceptat)" + +#: ../../../src/ui.cpp:1600 +#: ../../../src/ui.cpp:1608 +#: ../../../src/ui.cpp:1623 +msgid "<b>Debit:</b> " +msgstr "<b>Debit:</b> " + +#: ../../../src/ui.cpp:1614 +msgid "<b>Transaction fee:</b> " +msgstr "<b>Comision tranzactie:</b> " + +#: ../../../src/ui.cpp:1630 +msgid "<b>Net amount:</b> " +msgstr "<b>Cantitate neta:</b> " + +#: ../../../src/ui.cpp:1637 +msgid "Message:" +msgstr "Mesaj:" + +#: ../../../src/ui.cpp:1639 +msgid "Comment:" +msgstr "Comentariu:" + +#: ../../../src/ui.cpp:1642 +msgid "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 \"not accepted\" and not be spendable. This may occasionally happen if another node generates a block within a few seconds of yours." +msgstr "Monedele generate trebuie sa astepte 120 de blocuri inainte sa poata fi cheltuite. Cand ai generat acest block, s-a transmis in retea pentru a fi incul in lantul de blocuri. Daca nu este acceptat in lant, se va schimba in \"neaceptat\" si nu se va putea cheltui. Acest lucru se poate intampla rareori cand alt nod genereaza un bloc in acelasi moment cu al tau ." + +#: ../../../src/ui.cpp:1822 +msgid "Cannot write autostart/bitcoin.desktop file" +msgstr "Nu se poate scrie in fisierul autostart/bitcoin.desktop" + +#: ../../../src/ui.cpp:1858 +msgid "Main" +msgstr "Principal" + +#: ../../../src/ui.cpp:1868 +msgid "&Start Bitcoin on window system startup" +msgstr "&Porneste Bitcoin odata cu sistemul" + +#: ../../../src/ui.cpp:1875 +msgid "&Minimize on close" +msgstr "&Minimizeaza la inchidere" + +#: ../../../src/ui.cpp:2017 +#, c-format +msgid "version %s" +msgstr "versiune %s" + +#: ../../../src/ui.cpp:2140 +msgid "Error in amount " +msgstr "Eroare in cantitate " + +#: ../../../src/ui.cpp:2140 +#: ../../../src/ui.cpp:2145 +#: ../../../src/ui.cpp:2150 +#: ../../../src/ui.cpp:2203 +#: ../../../src/uibase.cpp:61 +msgid "Send Coins" +msgstr "Trimite Monede" + +#: ../../../src/ui.cpp:2145 +msgid "Amount exceeds your balance " +msgstr "Cantitatea trece peste limita disponibila" + +#: ../../../src/ui.cpp:2150 +msgid "Total exceeds your balance when the " +msgstr "Totalul trece peste limita cand" + +#: ../../../src/ui.cpp:2150 +msgid " transaction fee is included " +msgstr "comisionul de tranzactie este inclus" + +#: ../../../src/ui.cpp:2177 +msgid "Payment sent " +msgstr "Plata trimisa" + +#: ../../../src/ui.cpp:2177 +#: ../../../src/ui.cpp:2187 +#: ../../../src/ui.cpp:2337 +#: ../../../src/ui.cpp:2502 +#: ../../../src/wallet.cpp:1088 +msgid "Sending..." +msgstr "Se trimite..." + +#: ../../../src/ui.cpp:2203 +msgid "Invalid address " +msgstr "Adresa incorecta" + +#: ../../../src/ui.cpp:2258 +#, c-format +msgid "Sending %s to %s" +msgstr "Se trimite %s la %s" + +#: ../../../src/ui.cpp:2331 +#: ../../../src/ui.cpp:2364 +msgid "CANCELLED" +msgstr "ANULAT" + +#: ../../../src/ui.cpp:2335 +msgid "Cancelled" +msgstr "Anulat" + +#: ../../../src/ui.cpp:2337 +msgid "Transfer cancelled " +msgstr "Transfer anulat" + +#: ../../../src/ui.cpp:2390 +msgid "Error: " +msgstr "Eroare: " + +#: ../../../src/ui.cpp:2404 +#: ../../../src/ui.cpp:2473 +#: ../../../src/wallet.cpp:1106 +msgid "Insufficient funds" +msgstr "Fonduri insuficiente" + +#: ../../../src/ui.cpp:2409 +msgid "Connecting..." +msgstr "Se conecteaza..." + +#: ../../../src/ui.cpp:2414 +msgid "Unable to connect" +msgstr "Conectare imposibila" + +#: ../../../src/ui.cpp:2419 +msgid "Requesting public key..." +msgstr "Se cere cheia publica..." + +#: ../../../src/ui.cpp:2431 +msgid "Received public key..." +msgstr "Cheia publica primita..." + +#: ../../../src/ui.cpp:2445 +msgid "Recipient is not accepting transactions sent by IP address" +msgstr "Destinatarul nu accepta tranzacti trimise la adresa IP" + +#: ../../../src/ui.cpp:2447 +msgid "Transfer was not accepted" +msgstr "Transferul nu a fost acceptat" + +#: ../../../src/ui.cpp:2456 +msgid "Invalid response received" +msgstr "Raspuns invalid receptionat" + +#: ../../../src/ui.cpp:2469 +msgid "Creating transaction..." +msgstr "Se creeaza tranzactia..." + +#: ../../../src/ui.cpp:2492 +#, c-format +msgid "This transaction requires a transaction fee of at least %s because of its amount, complexity, or use of recently received funds" +msgstr "Aceasta tranzactie necesita un comision de cel putin %s datorita cantitatii, complexitatii sau uzului de fonduri primite recent" + +#: ../../../src/ui.cpp:2494 +msgid "Transaction creation failed" +msgstr "Crearea tranzactiei a esuat." + +#: ../../../src/ui.cpp:2504 +msgid "Transaction aborted" +msgstr "Tranzactie anulata" + +#: ../../../src/ui.cpp:2512 +msgid "Lost connection, transaction cancelled" +msgstr "Conexiune pierduta, tranzactie anulata" + +#: ../../../src/ui.cpp:2528 +msgid "Sending payment..." +msgstr "Se trimite plata..." + +#: ../../../src/ui.cpp:2540 +msgid "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." +msgstr "Tranzactia a fost respinsa. Acest lucru se poate intampla daca vreuna din monede a fost cheltuita sau s-a folosit o copie de portofel (wallet.dat) si monedele a fost cheltuite in copie dar nu s-au marcat cheltuite aici." + +#: ../../../src/ui.cpp:2549 +msgid "Waiting for confirmation..." +msgstr "Se asteapta confirmare..." + +#: ../../../src/ui.cpp:2566 +msgid "" +"The payment was sent, but the recipient was unable to verify it.\n" +"The transaction is recorded and will credit to the recipient,\n" +"but the comment information will be blank." +msgstr "" +"Plata a fost trimisa dar destinatarul nu a putut sa o verifice.\n" +"Tranzactia a fost inregistrata si creditul trimis la desinatar,\n" +"dar informatia de comentarii va ramane in alb." + +#: ../../../src/ui.cpp:2575 +msgid "Payment was sent, but an invalid response was received" +msgstr "Plata a fost trimisa dar s-a receptionat un raspuns incorect" + +#: ../../../src/ui.cpp:2581 +msgid "Payment completed" +msgstr "Plata completa" + +#: ../../../src/ui.cpp:2623 +#: ../../../src/ui.cpp:2769 +#: ../../../src/ui.cpp:2809 +msgid "Name" +msgstr "Nume" + +#: ../../../src/ui.cpp:2624 +#: ../../../src/ui.cpp:2769 +#: ../../../src/ui.cpp:2809 +msgid "Address" +msgstr "Adresa" + +#: ../../../src/ui.cpp:2626 +#: ../../../src/ui.cpp:2781 +msgid "Label" +msgstr "Eticheta" + +#: ../../../src/ui.cpp:2627 +#: ../../../src/uibase.cpp:847 +msgid "Bitcoin Address" +msgstr "Adresa Bitcoin" + +#: ../../../src/ui.cpp:2751 +msgid "This is one of your own addresses for receiving payments and cannot be entered in the address book. " +msgstr "Aceasta este o adresa pentru primire de plati de aceea nu se poate introduce manual in agenda" + +#: ../../../src/ui.cpp:2769 +#: ../../../src/ui.cpp:2775 +msgid "Edit Address" +msgstr "Editeaza adresa" + +#: ../../../src/ui.cpp:2781 +msgid "Edit Address Label" +msgstr "Editeaza eticheta de adresa" + +#: ../../../src/ui.cpp:2809 +#: ../../../src/ui.cpp:2815 +msgid "Add Address" +msgstr "Adauga adresa" + +#: ../../../src/ui.cpp:2902 +msgid "Bitcoin" +msgstr "Bitcoin" + +#: ../../../src/ui.cpp:2904 +msgid "Bitcoin - Generating" +msgstr "Bitcoin - Se genereaza" + +#: ../../../src/ui.cpp:2906 +msgid "Bitcoin - (not connected)" +msgstr "Bitcoin - (neconectat)" + +#: ../../../src/ui.cpp:2985 +msgid "&Open Bitcoin" +msgstr "&Deschide Bitcoin" + +#: ../../../src/ui.cpp:2986 +msgid "&Send Bitcoins" +msgstr "&Trimite Bitcoin" + +#: ../../../src/ui.cpp:2987 +msgid "O&ptions..." +msgstr "O&ptiuni" + +#: ../../../src/ui.cpp:2990 +#: ../../../src/uibase.cpp:25 +msgid "E&xit" +msgstr "I&esire" + +#: ../../../src/ui.cpp:3216 +msgid "Program has crashed and will terminate. " +msgstr "Programul a detectat o eroare si se va inchide." + +#: ../../../src/uibase.cpp:28 +msgid "&File" +msgstr "&Arhiva" + +#: ../../../src/uibase.cpp:32 +msgid "&Your Receiving Addresses..." +msgstr "&Adresele de primire..." + +#: ../../../src/uibase.cpp:35 +msgid "&Encrypt Wallet..." +msgstr "&Encripteaza portofel..." + +#: ../../../src/uibase.cpp:38 +msgid "&Change Wallet Encryption Passphrase..." +msgstr "&Schimba parola de encriptare portofel..." + +#: ../../../src/uibase.cpp:42 +msgid "&Options..." +msgstr "&Optiuni..." + +#: ../../../src/uibase.cpp:45 +msgid "&Settings" +msgstr "&Cnfiguratie" + +#: ../../../src/uibase.cpp:49 +msgid "&About..." +msgstr "&Despre..." + +#: ../../../src/uibase.cpp:52 +msgid "&Help" +msgstr "&Ajutor" + +#: ../../../src/uibase.cpp:62 +msgid "Address Book" +msgstr "Agenda cu adrese" + +#: ../../../src/uibase.cpp:75 +msgid "Your Bitcoin Address:" +msgstr "Adresa Ta Bitcoin:" + +#: ../../../src/uibase.cpp:82 +msgid " &New... " +msgstr " &Nou... " + +#: ../../../src/uibase.cpp:85 +#: ../../../src/uibase.cpp:790 +#: ../../../src/uibase.cpp:893 +msgid " &Copy to Clipboard " +msgstr " &Copiaza in Clipboard" + +#: ../../../src/uibase.cpp:99 +msgid "Balance:" +msgstr "Balant:" + +#: ../../../src/uibase.cpp:115 +msgid " All" +msgstr "Tot" + +#: ../../../src/uibase.cpp:115 +msgid " Sent" +msgstr "Trimis" + +#: ../../../src/uibase.cpp:115 +msgid " Received" +msgstr "Primit" + +#: ../../../src/uibase.cpp:115 +msgid " In Progress" +msgstr "In Curs" + +#: ../../../src/uibase.cpp:136 +msgid "All Transactions" +msgstr "Toate Tranzactiile" + +#: ../../../src/uibase.cpp:147 +msgid "Sent/Received" +msgstr "Trimis/Primit" + +#: ../../../src/uibase.cpp:158 +msgid "Sent" +msgstr "Trimis" + +#: ../../../src/uibase.cpp:169 +msgid "Received" +msgstr "Primit" + +#: ../../../src/uibase.cpp:312 +#: ../../../src/uibase.cpp:453 +#: ../../../src/uibase.cpp:552 +#: ../../../src/uibase.cpp:732 +#: ../../../src/uibase.cpp:793 +#: ../../../src/uibase.cpp:902 +#: ../../../src/uibase.cpp:991 +msgid "OK" +msgstr "OK" + +#: ../../../src/uibase.cpp:355 +msgid "&Start Bitcoin on system startup" +msgstr "&Porneste Bitcoin odata cu sistemul" + +#: ../../../src/uibase.cpp:358 +msgid "&Minimize to the tray instead of the taskbar" +msgstr "&Minimizeaza in tray nu in bara de aplicatii" + +#: ../../../src/uibase.cpp:361 +msgid "Map port using &UPnP" +msgstr "Reserva portul utilizand &UPnP" + +#: ../../../src/uibase.cpp:364 +msgid "M&inimize to the tray on close" +msgstr "M&inimizeaza in tray la inchidere" + +#: ../../../src/uibase.cpp:370 +msgid "&Connect through socks4 proxy (requires restart to apply): " +msgstr "&Conecteaza prin proxy socks4 (repornire apl. necesara): " + +#: ../../../src/uibase.cpp:381 +msgid "Proxy &IP:" +msgstr "&IP de proxy:" + +#: ../../../src/uibase.cpp:389 +msgid " &Port:" +msgstr " &Port:" + +#: ../../../src/uibase.cpp:402 +msgid "Optional transaction fee per KB that helps make sure your transactions are processed quickly. Most transactions are 1KB. Fee 0.01 recommended." +msgstr "Comision optional per KB ce asigura ca tranzactiile tale sunt procesate rapid. Majoritatea tranzactiilor sunt de 1KB. Se recomanda un comision de 0.01." + +#: ../../../src/uibase.cpp:409 +msgid "Pay transaction fee:" +msgstr "Comision de tranzactie:" + +#: ../../../src/uibase.cpp:430 +msgid "// [don't translate] Test panel 2 for future expansion" +msgstr "" + +#: ../../../src/uibase.cpp:434 +msgid "// [don't translate] Let's not start multiple pages until the first page is filled up" +msgstr "" + +#: ../../../src/uibase.cpp:456 +#: ../../../src/uibase.cpp:678 +#: ../../../src/uibase.cpp:737 +#: ../../../src/uibase.cpp:796 +#: ../../../src/uibase.cpp:905 +#: ../../../src/uibase.cpp:994 +msgid "Cancel" +msgstr "Anuleaza" + +#: ../../../src/uibase.cpp:459 +msgid "&Apply" +msgstr "&Aplica" + +#: ../../../src/uibase.cpp:518 +msgid "Bitcoin " +msgstr "Bitcoin " + +#: ../../../src/uibase.cpp:524 +msgid "version" +msgstr "versiune" + +#: ../../../src/uibase.cpp:535 +msgid "" +"Copyright (c) 2009-2011 Bitcoin Developers\n" +"\n" +"This is experimental software.\n" +"\n" +"Distributed under the MIT/X11 software license, see the accompanying file \n" +"license.txt or http://www.opensource.org/licenses/mit-license.php.\n" +"\n" +"This product includes software developed by the OpenSSL Project for use in the \n" +"OpenSSL Toolkit (http://www.openssl.org/) and cryptographic software written by \n" +"Eric Young (eay@cryptsoft.com) and UPnP software written by Thomas Bernard." +msgstr "" +"Copyright (c) 2009-2011 Bitcoin Developers\n" +"\n" +"Acesta este un program experimental.\n" +"\n" +"Distribuit sub licenta MIT/X11, cauta fisierul adaugat de licenta \n" +"license.txt sau http://www.opensource.org/licenses/mit-license.php.\n" +"\n" +"Acest produs contine software creat deOpenSSL Project pentru uz in \n" +"OpenSSL Toolkit (http://www.openssl.org/), software cryptografic scris de \n" +"Eric Young (eay@cryptsoft.com) si software UPnP scris de Thomas Bernard." + +#: ../../../src/uibase.cpp:591 +msgid "Enter a Bitcoin address (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L)" +msgstr "Introduce o a adresa Bitcoin (exemplu: 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L)" + +#: ../../../src/uibase.cpp:605 +msgid "Pay &To:" +msgstr "Plateste &la:" + +#: ../../../src/uibase.cpp:620 +msgid "&Paste" +msgstr "&Lipeste (paste)" + +#: ../../../src/uibase.cpp:623 +msgid " Address &Book..." +msgstr "Agenda de &adrese..." + +#: ../../../src/uibase.cpp:630 +msgid "&Amount:" +msgstr "&Cantitate:" + +#: ../../../src/uibase.cpp:640 +msgid "T&ransfer:" +msgstr "T&ransfera:" + +#: ../../../src/uibase.cpp:646 +msgid " Standard" +msgstr "Standard" + +#: ../../../src/uibase.cpp:673 +msgid "&Send" +msgstr "&Trimite" + +#: ../../../src/uibase.cpp:721 +msgid "" +"\n" +"\n" +"Connecting..." +msgstr "" +"\n" +"\n" +"Se conecteaza..." + +#: ../../../src/uibase.cpp:771 +msgid "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. The highlighted address is displayed in the main window." +msgstr "Acestea sunt adresele tale pentru primit plati. Poti sa folosesti o adresa diferita pentru fiecare persoana care iti trimite pentru a putea tine cont de unde vin platile. Adresa selectionata este afisata in fereastra principala." + +#: ../../../src/uibase.cpp:784 +#: ../../../src/uibase.cpp:896 +msgid "&Edit..." +msgstr "&Editeaza..." + +#: ../../../src/uibase.cpp:787 +#: ../../../src/uibase.cpp:899 +msgid " &New Address... " +msgstr " &Adresa noua... " + +#: ../../../src/uibase.cpp:859 +msgid "Sending" +msgstr "Se trimite" + +#: ../../../src/uibase.cpp:867 +msgid "These are your Bitcoin addresses for receiving payments. You can give a different one to each sender to keep track of who is paying you. The highlighted address will be displayed in the main window." +msgstr "Acestea sunt adresele tale pentru primit plati. Poti sa folosesti o adresa diferita pentru fiecare persoana care iti trimite pentru a putea tine cont de unde vin platile. Adresa selectionata este afisata in fereastra principala." + +#: ../../../src/uibase.cpp:880 +msgid "Receiving" +msgstr "Se receptioneaza" + +#: ../../../src/uibase.cpp:890 +msgid "&Delete" +msgstr "&Sterge" + +#: ../../../src/util.cpp:870 +msgid "Warning: Please check that your computer's date and time are correct. If your clock is wrong Bitcoin will not work properly." +msgstr "Atentie: Regleaza corect hora si data calculatorului pentru ca Bitcoin sa functioneze corect." + +#: ../../../src/util.cpp:904 +msgid "beta" +msgstr "beta" + +#: ../../../src/wallet.cpp:1073 +msgid "Error: Wallet locked, unable to create transaction " +msgstr "Eroare: Portofel blocat, nu se poate crea tranzactia" + +#: ../../../src/wallet.cpp:1081 +#, c-format +msgid "Error: This transaction requires a transaction fee of at least %s because of its amount, complexity, or use of recently received funds " +msgstr "Eroare: Aceasta tranzactie necesita un comision de cel putin %s datorita cantitatii, complexitatii sau uzului de fonduri primite recent" + +#: ../../../src/wallet.cpp:1083 +msgid "Error: Transaction creation failed " +msgstr "Eroare: Crearea tranzactiei a esuat" + +#: ../../../src/wallet.cpp:1092 +msgid "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." +msgstr "Error: Tranzactia a fost respinsa. Acest lucru se poate intampla daca vreuna din monede a fost cheltuita sau s-a folosit o copie de portofel (wallet.dat) si monedele a fost cheltuite in copie dar nu s-au marcat cheltuite aici." + +#: ../../../src/wallet.cpp:1104 +msgid "Invalid amount" +msgstr "Cantitate incorecta" + +#: ../../../src/uibase.h:151 +msgid "Transaction Details" +msgstr "Detalii de Tranzactie" + +#: ../../../src/uibase.h:203 +msgid "Options" +msgstr "Optiuni" + +#: ../../../src/uibase.h:232 +msgid "About Bitcoin" +msgstr "Despre Bitcoin" + +#: ../../../src/uibase.h:341 +msgid "Your Bitcoin Addresses" +msgstr "Adresele Tale Bitcoin" + +#~ msgid "Invalid bitcoin address" +#~ msgstr "Dirección Bitcoin inválida" diff --git a/locale/ru/LC_MESSAGES/bitcoin.mo b/locale/ru/LC_MESSAGES/bitcoin.mo Binary files differindex 92bb888fe9..4175fc47d1 100644 --- a/locale/ru/LC_MESSAGES/bitcoin.mo +++ b/locale/ru/LC_MESSAGES/bitcoin.mo diff --git a/locale/ru/LC_MESSAGES/bitcoin.po b/locale/ru/LC_MESSAGES/bitcoin.po index d53b08d46c..266e76825a 100644 --- a/locale/ru/LC_MESSAGES/bitcoin.po +++ b/locale/ru/LC_MESSAGES/bitcoin.po @@ -3,8 +3,8 @@ msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: m0Ray <m0ray@nm.ru>\n" "POT-Creation-Date: 2011-05-15 18:24+0100\n" -"PO-Revision-Date: 2011-05-23 07:06+0500\n" -"Last-Translator: m0Ray <m0ray@nm.ru>\n" +"PO-Revision-Date: 2011-07-17 04:18+0100\n" +"Last-Translator: Michael Bemmerl <mail@mx-server.de>\n" "Language-Team: \n" "Language: \n" "MIME-Version: 1.0\n" @@ -448,7 +448,7 @@ msgstr "&Открыть Bitcoin" #: ../../../src/ui.cpp:2682 msgid "&Send Bitcoins" -msgstr "&Открыть Bitcoin" +msgstr "&Отправить Bitcoins" #: ../../../src/ui.cpp:2683 msgid "O&ptions..." diff --git a/locale/zh_cn/LC_MESSAGES/bitcoin.po b/locale/zh_cn/LC_MESSAGES/bitcoin.po index e870a16400..f53367e34c 100644 --- a/locale/zh_cn/LC_MESSAGES/bitcoin.po +++ b/locale/zh_cn/LC_MESSAGES/bitcoin.po @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2011-05-21 14:19+0800\n" -"PO-Revision-Date: 2011-05-28 17:08+0800\n" +"POT-Creation-Date: 2011-09-06 21:58+0100\n" +"PO-Revision-Date: 2011-09-17 19:08+0800\n" "Last-Translator: Dean Lee <xslidian@gmail.com>\n" "Language-Team: \n" "MIME-Version: 1.0\n" @@ -17,127 +17,131 @@ msgstr "" "X-Poedit-Bookmarks: 77,-1,-1,-1,-1,-1,-1,-1,-1,-1\n" "X-Poedit-SearchPath-0: ../../..\n" -#: ../../../src/init.cpp:142 +#: ../../../src/init.cpp:163 msgid "Bitcoin version" msgstr "Bitcoin 版本" -#: ../../../src/init.cpp:143 +#: ../../../src/init.cpp:164 msgid "Usage:" msgstr "用法:" -#: ../../../src/init.cpp:145 +#: ../../../src/init.cpp:166 msgid "Send command to -server or bitcoind\n" msgstr "发送命令给 -server 或 bitcoin\n" -#: ../../../src/init.cpp:146 +#: ../../../src/init.cpp:167 msgid "List commands\n" msgstr "列出命令\n" -#: ../../../src/init.cpp:147 +#: ../../../src/init.cpp:168 msgid "Get help for a command\n" msgstr "获取命令的帮助\n" -#: ../../../src/init.cpp:148 +#: ../../../src/init.cpp:169 msgid "Options:\n" msgstr "选项:\n" -#: ../../../src/init.cpp:149 +#: ../../../src/init.cpp:170 msgid "Specify configuration file (default: bitcoin.conf)\n" msgstr "指定配置文件 (默认: bitcoin.conf)\n" -#: ../../../src/init.cpp:150 +#: ../../../src/init.cpp:171 msgid "Specify pid file (default: bitcoind.pid)\n" msgstr "指定 pid 文件 (默认: bitcoin.pid)\n" -#: ../../../src/init.cpp:151 +#: ../../../src/init.cpp:172 msgid "Generate coins\n" msgstr "生成货币\n" -#: ../../../src/init.cpp:152 +#: ../../../src/init.cpp:173 msgid "Don't generate coins\n" msgstr "不要生成货币\n" -#: ../../../src/init.cpp:153 +#: ../../../src/init.cpp:174 msgid "Start minimized\n" msgstr "启动时最小化\n" -#: ../../../src/init.cpp:154 +#: ../../../src/init.cpp:175 msgid "Specify data directory\n" msgstr "指定数据目录\n" -#: ../../../src/init.cpp:155 +#: ../../../src/init.cpp:176 +msgid "Specify connection timeout (in milliseconds)\n" +msgstr "指定连接超时时间 (毫秒)\n" + +#: ../../../src/init.cpp:177 msgid "Connect through socks4 proxy\n" msgstr "通过 socks4 代理连接\n" -#: ../../../src/init.cpp:156 +#: ../../../src/init.cpp:178 msgid "Allow DNS lookups for addnode and connect\n" msgstr "允许 DNS 查找新增结点和连接\n" -#: ../../../src/init.cpp:157 +#: ../../../src/init.cpp:179 msgid "Add a node to connect to\n" msgstr "添加一个连接结点\n" -#: ../../../src/init.cpp:158 +#: ../../../src/init.cpp:180 msgid "Connect only to the specified node\n" msgstr "只连接特定结点\n" -#: ../../../src/init.cpp:159 +#: ../../../src/init.cpp:181 msgid "Don't accept connections from outside\n" msgstr "不要接受外部传来的连接\n" -#: ../../../src/init.cpp:162 +#: ../../../src/init.cpp:184 msgid "Don't attempt to use UPnP to map the listening port\n" msgstr "不要尝试使用 UPnP 映射监听端口\n" -#: ../../../src/init.cpp:164 +#: ../../../src/init.cpp:186 msgid "Attempt to use UPnP to map the listening port\n" msgstr "尝试使用 UPnP 映射监听端口\n" -#: ../../../src/init.cpp:167 +#: ../../../src/init.cpp:189 msgid "Fee per KB to add to transactions you send\n" msgstr "您为每 KB 支付所增加的交易佣金\n" -#: ../../../src/init.cpp:169 +#: ../../../src/init.cpp:191 msgid "Accept command line and JSON-RPC commands\n" msgstr "允许命令行和 JSON-RPC 控制\n" -#: ../../../src/init.cpp:172 +#: ../../../src/init.cpp:194 msgid "Run in the background as a daemon and accept commands\n" msgstr "在后台运行并接收命令\n" -#: ../../../src/init.cpp:174 +#: ../../../src/init.cpp:196 msgid "Use the test network\n" msgstr "使用测试网络\n" -#: ../../../src/init.cpp:175 +#: ../../../src/init.cpp:197 msgid "Username for JSON-RPC connections\n" msgstr "JSON-RPC 连接的用户名\n" -#: ../../../src/init.cpp:176 +#: ../../../src/init.cpp:198 msgid "Password for JSON-RPC connections\n" msgstr "JSON-RPC 连接的密码\n" -#: ../../../src/init.cpp:177 +#: ../../../src/init.cpp:199 msgid "Listen for JSON-RPC connections on <port> (default: 8332)\n" msgstr "在端口 <port> 监听 JSON-RPC 连接 (默认: 8332)\n" -#: ../../../src/init.cpp:178 +#: ../../../src/init.cpp:200 msgid "Allow JSON-RPC connections from specified IP address\n" msgstr "允许来自特定 IP 地址的 JSON-RPC 连接\n" -#: ../../../src/init.cpp:179 +#: ../../../src/init.cpp:201 msgid "Send commands to node running on <ip> (default: 127.0.0.1)\n" msgstr "发送命令给运行的结点,IP 地址 <ip> (默认: 127.0.0.1)\n" -#: ../../../src/init.cpp:180 +#: ../../../src/init.cpp:202 msgid "Set key pool size to <n> (default: 100)\n" msgstr "设置密钥池大小为 <n> (默认: 100)\n" -#: ../../../src/init.cpp:181 +#: ../../../src/init.cpp:203 msgid "Rescan the block chain for missing wallet transactions\n" -msgstr "重新扫描货币包链来检测丢失的货币交易\n" +msgstr "重新扫描货币包链来检测丢失的钱包交易\n" -#: ../../../src/init.cpp:185 +#: ../../../src/init.cpp:207 msgid "" "\n" "SSL options: (see the Bitcoin Wiki for SSL setup instructions)\n" @@ -145,106 +149,79 @@ msgstr "" "\n" "SSL 选项: (SSL 设置步骤请参见 Bitcoin Wiki)\n" -#: ../../../src/init.cpp:186 +#: ../../../src/init.cpp:208 msgid "Use OpenSSL (https) for JSON-RPC connections\n" msgstr "使用 OpenSSL (https) 进行 JSON-RPC 连接\n" -#: ../../../src/init.cpp:187 +#: ../../../src/init.cpp:209 msgid "Server certificate file (default: server.cert)\n" msgstr "服务器证书 (默认: server.cert)\n" -#: ../../../src/init.cpp:188 +#: ../../../src/init.cpp:210 msgid "Server private key (default: server.pem)\n" msgstr "服务器私有密钥 (默认: server.pem)\n" -#: ../../../src/init.cpp:189 +#: ../../../src/init.cpp:211 msgid "Acceptable ciphers (default: TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!AH:!3DES:@STRENGTH)\n" msgstr "许可密码 (默认: TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!AH:!3DES:@STRENGTH)\n" -#: ../../../src/init.cpp:193 +#: ../../../src/init.cpp:215 msgid "This help message\n" msgstr "本帮助信息\n" -#: ../../../src/init.cpp:330 +#: ../../../src/init.cpp:353 #, c-format msgid "Cannot obtain a lock on data directory %s. Bitcoin is probably already running." msgstr "无法获取数据目录 %s 的锁。 Bitcoin 可能已经启动。" -#: ../../../src/init.cpp:356 +#: ../../../src/init.cpp:379 msgid "Error loading addr.dat \n" msgstr "加载 addr.dat 出错 \n" -#: ../../../src/init.cpp:362 +#: ../../../src/init.cpp:385 msgid "Error loading blkindex.dat \n" msgstr "加载 blkindex.dat 出错 \n" -#: ../../../src/init.cpp:369 +#: ../../../src/init.cpp:396 +msgid "Error loading wallet.dat: Wallet corrupted \n" +msgstr "加载 wallet.dat 出错: 钱包已损坏 \n" + +#: ../../../src/init.cpp:398 +msgid "Error loading wallet.dat: Wallet requires newer version of Bitcoin \n" +msgstr "加载 wallet.dat 出错: 钱包要求更高版本的 Bitcoin \n" + +#: ../../../src/init.cpp:400 msgid "Error loading wallet.dat \n" msgstr "加载 wallet.dat 出错 \n" -#: ../../../src/init.cpp:449 +#: ../../../src/init.cpp:489 msgid "Invalid -proxy address" msgstr "无效 -proxy 地址" -#: ../../../src/init.cpp:472 +#: ../../../src/init.cpp:514 msgid "Invalid amount for -paytxfee=<amount>" msgstr "无效的金额 -paytxfee=<amount>" -#: ../../../src/init.cpp:476 +#: ../../../src/init.cpp:518 msgid "Warning: -paytxfee is set very high. This is the transaction fee you will pay if you send a transaction." msgstr "警告: -paytxfee 设置得过高。 这个参数是您发送一笔交易要支付的佣金。" -#: ../../../src/main.cpp:1866 +#: ../../../src/main.cpp:1398 msgid "Warning: Disk space is low " msgstr "警告: 磁盘空间不足" -#: ../../../src/main.cpp:3990 -#, c-format -msgid "Error: This transaction requires a transaction fee of at least %s because of its amount, complexity, or use of recently received funds " -msgstr "错误: 这个交易因为近期收到支付的数量,难度或者使用而需要支付至少 %s 交易佣金 " - -#: ../../../src/main.cpp:3992 -msgid "Error: Transaction creation failed " -msgstr "错误: 交易创建失败" - -#: ../../../src/main.cpp:3997 -#: ../../../src/ui.cpp:1927 -#: ../../../src/ui.cpp:1932 -#: ../../../src/ui.cpp:2076 -#: ../../../src/ui.cpp:2229 -msgid "Sending..." -msgstr "正在发送..." - -#: ../../../src/main.cpp:4001 -msgid "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." -msgstr "错误: 交易被拒绝。 这可能是因为您账户里的一些货币应经被使用,比如您使用了一个复制的 wallet.dat 文件,一些货币在另一个复件里支付了但是没有在这里更新。" - -#: ../../../src/main.cpp:4014 -msgid "Invalid amount" -msgstr "无效金额" - -#: ../../../src/main.cpp:4016 -#: ../../../src/ui.cpp:2143 -#: ../../../src/ui.cpp:2214 -msgid "Insufficient funds" -msgstr "余额不足" - -#: ../../../src/main.cpp:4021 -msgid "Invalid bitcoin address" -msgstr "无效 bitcoin 地址" - -#: ../../../src/net.cpp:1503 +#: ../../../src/net.cpp:1610 #, c-format msgid "Unable to bind to port %d on this computer. Bitcoin is probably already running." msgstr "无法在这台电脑上绑定 %d 端口。 Bitcoin 可能已经在运行。" -#: ../../../src/rpc.cpp:1802 -#: ../../../src/rpc.cpp:1804 +#: ../../../src/rpc.cpp:2005 +#: ../../../src/rpc.cpp:2007 #, c-format msgid "To use the %s option" msgstr "使用 %s 选项" -#: ../../../src/rpc.cpp:1806 +#: ../../../src/rpc.cpp:2009 #, c-format msgid "" "Warning: %s, you must set rpcpassword=<password>\n" @@ -255,7 +232,7 @@ msgstr "" "配置文件为: %s\n" "如果文件不存在,请创建文件并只给创建者提供只读访问权限。\n" -#: ../../../src/rpc.cpp:1974 +#: ../../../src/rpc.cpp:2185 #, c-format msgid "" "You must set rpcpassword=<password> in the configuration file:\n" @@ -266,109 +243,195 @@ msgstr "" "%s\n" "如果文件不存在,请创建文件并只给创建者提供只读访问权限。" -#: ../../../src/ui.cpp:204 +#: ../../../src/ui.cpp:217 #, c-format msgid "This transaction is over the size limit. You can still send it for a fee of %s, which goes to the nodes that process your transaction and helps to support the network. Do you want to pay the fee?" msgstr "这笔交易超过了大小限制。 您依然可以通过支付 %s 的佣金来进行,佣金用来支付为您的交易计算的结点来帮助支撑网络。 您是否要支付佣金?" -#: ../../../src/ui.cpp:303 +#: ../../../src/ui.cpp:261 +#: ../../../src/ui.cpp:1247 +msgid "Enter the current passphrase to the wallet." +msgstr "输入钱包当前的口令。" + +#: ../../../src/ui.cpp:262 +#: ../../../src/ui.cpp:1183 +#: ../../../src/ui.cpp:1200 +#: ../../../src/ui.cpp:1248 +#: ../../../src/ui.cpp:1272 +#: ../../../src/ui.cpp:1292 +msgid "Passphrase" +msgstr "口令" + +#: ../../../src/ui.cpp:268 +msgid "Please supply the current wallet decryption passphrase." +msgstr "请输入钱包当前的解密口令。" + +#: ../../../src/ui.cpp:276 +#: ../../../src/ui.cpp:1257 +#: ../../../src/ui.cpp:1314 +msgid "The passphrase entered for the wallet decryption was incorrect." +msgstr "钱包解密口令不正确。" + +#: ../../../src/ui.cpp:353 msgid "Status" msgstr "状态" -#: ../../../src/ui.cpp:304 +#: ../../../src/ui.cpp:354 msgid "Date" msgstr "日期" -#: ../../../src/ui.cpp:305 +#: ../../../src/ui.cpp:355 msgid "Description" msgstr "描述" -#: ../../../src/ui.cpp:306 +#: ../../../src/ui.cpp:356 msgid "Debit" msgstr "付款人" -#: ../../../src/ui.cpp:307 +#: ../../../src/ui.cpp:357 msgid "Credit" msgstr "信用" -#: ../../../src/ui.cpp:513 +#: ../../../src/ui.cpp:568 #, c-format msgid "Open for %d blocks" msgstr "%d 个货币包开放" -#: ../../../src/ui.cpp:515 +#: ../../../src/ui.cpp:570 #, c-format msgid "Open until %s" msgstr "开放直到 %s" -#: ../../../src/ui.cpp:521 +#: ../../../src/ui.cpp:576 #, c-format msgid "%d/offline?" msgstr "%d/离线?" -#: ../../../src/ui.cpp:523 +#: ../../../src/ui.cpp:578 #, c-format msgid "%d/unconfirmed" msgstr "%d/未确认" -#: ../../../src/ui.cpp:525 +#: ../../../src/ui.cpp:580 #, c-format msgid "%d confirmations" msgstr "%d 确认" -#: ../../../src/ui.cpp:610 +#: ../../../src/ui.cpp:665 msgid "Generated" msgstr "已生成" -#: ../../../src/ui.cpp:618 +#: ../../../src/ui.cpp:673 #, c-format msgid "Generated (%s matures in %d more blocks)" msgstr "已生成 (%s 成熟 %d 新增货币包)" -#: ../../../src/ui.cpp:622 +#: ../../../src/ui.cpp:677 msgid "Generated - Warning: This block was not received by any other nodes and will probably not be accepted!" msgstr "已生成 - 警告: 这个货币包没有被任何其他结点收到,因此很可能不会被接受!" -#: ../../../src/ui.cpp:626 +#: ../../../src/ui.cpp:681 msgid "Generated (not accepted)" msgstr "已生成 (未被接受)" -#: ../../../src/ui.cpp:636 +#: ../../../src/ui.cpp:691 msgid "From: " msgstr "来自: " -#: ../../../src/ui.cpp:660 +#: ../../../src/ui.cpp:715 msgid "Received with: " msgstr "伴随接收: " -#: ../../../src/ui.cpp:706 +#: ../../../src/ui.cpp:760 msgid "Payment to yourself" msgstr "支付给您自己" -#: ../../../src/ui.cpp:740 +#: ../../../src/ui.cpp:794 msgid "To: " msgstr "到: " -#: ../../../src/ui.cpp:1055 +#: ../../../src/ui.cpp:1109 msgid " Generating" msgstr " 生成中" -#: ../../../src/ui.cpp:1057 +#: ../../../src/ui.cpp:1111 msgid "(not connected)" msgstr "(未连接)" -#: ../../../src/ui.cpp:1060 +#: ../../../src/ui.cpp:1114 #, c-format msgid " %d connections %d blocks %d transactions" msgstr " %d 个连接 %d 个货币包 %d 个交易 " -#: ../../../src/ui.cpp:1165 -#: ../../../src/ui.cpp:2529 +#: ../../../src/ui.cpp:1171 +msgid "Wallet already encrypted." +msgstr "钱包已加密。" + +#: ../../../src/ui.cpp:1182 +msgid "" +"Enter the new passphrase to the wallet.\n" +"Please use a passphrase of 10 or more random characters, or eight or more words." +msgstr "" +"输入钱包的新口令。\n" +"请使用 10 个或更多字符,或 8 个或更多单词的口令。" + +#: ../../../src/ui.cpp:1189 +#: ../../../src/ui.cpp:1280 +msgid "Error: The supplied passphrase was too short." +msgstr "错误: 所输口令太短。" + +#: ../../../src/ui.cpp:1193 +msgid "" +"WARNING: If you encrypt your wallet and lose your passphrase, you will LOSE ALL OF YOUR BITCOINS!\n" +"Are you sure you wish to encrypt your wallet?" +msgstr "" +"警告: 如果您加密钱包又丢失口令,将失去全部 BITCOINS!\n" +"是否确实想加密钱包?" + +#: ../../../src/ui.cpp:1199 +msgid "Please re-enter your new wallet passphrase." +msgstr "请重新输入新的钱包口令。" + +#: ../../../src/ui.cpp:1208 +#: ../../../src/ui.cpp:1302 +msgid "Error: the supplied passphrases didn't match." +msgstr "错误: 所输口令不匹配。" + +#: ../../../src/ui.cpp:1218 +msgid "Wallet encryption failed." +msgstr "钱包加密失败。" + +#: ../../../src/ui.cpp:1225 +msgid "" +"Wallet Encrypted.\n" +"Remember that encrypting your wallet cannot fully protect your bitcoins from being stolen by malware infecting your computer." +msgstr "" +"钱包已加密。\n" +"请记住,加密钱包无法完全保护您的 bitcoins 不被计算机感染的恶意软件窃取。" + +#: ../../../src/ui.cpp:1236 +msgid "Wallet is unencrypted, please encrypt it first." +msgstr "钱包未加密,请先加密。" + +#: ../../../src/ui.cpp:1271 +msgid "Enter the new passphrase for the wallet." +msgstr "输入钱包的新口令。" + +#: ../../../src/ui.cpp:1291 +msgid "Re-enter the new passphrase for the wallet." +msgstr "重新输入钱包的新口令。" + +#: ../../../src/ui.cpp:1323 +msgid "Wallet Passphrase Changed." +msgstr "钱包口令已更改。" + +#: ../../../src/ui.cpp:1379 +#: ../../../src/ui.cpp:2825 msgid "New Receiving Address" msgstr "新建接收地址" -#: ../../../src/ui.cpp:1166 -#: ../../../src/ui.cpp:2530 +#: ../../../src/ui.cpp:1380 +#: ../../../src/ui.cpp:2826 msgid "" "You should use a new address for each payment you receive.\n" "\n" @@ -378,234 +441,248 @@ msgstr "" "\n" "标签" -#: ../../../src/ui.cpp:1235 +#: ../../../src/ui.cpp:1464 msgid "<b>Status:</b> " msgstr "<b>状态:</b> " -#: ../../../src/ui.cpp:1240 +#: ../../../src/ui.cpp:1469 msgid ", has not been successfully broadcast yet" msgstr ",尚未被成功广播" -#: ../../../src/ui.cpp:1242 +#: ../../../src/ui.cpp:1471 #, c-format msgid ", broadcast through %d node" msgstr ",通过 %d 个结点广播" -#: ../../../src/ui.cpp:1244 +#: ../../../src/ui.cpp:1473 #, c-format msgid ", broadcast through %d nodes" msgstr ",通过 %d 个结点广播" -#: ../../../src/ui.cpp:1248 +#: ../../../src/ui.cpp:1477 msgid "<b>Date:</b> " msgstr "<b>日期:</b>" -#: ../../../src/ui.cpp:1256 +#: ../../../src/ui.cpp:1485 msgid "<b>Source:</b> Generated<br>" msgstr "<b>来源:</b> 生成<br>" -#: ../../../src/ui.cpp:1262 -#: ../../../src/ui.cpp:1280 +#: ../../../src/ui.cpp:1491 +#: ../../../src/ui.cpp:1508 msgid "<b>From:</b> " msgstr "<b>从:</b> " -#: ../../../src/ui.cpp:1280 +#: ../../../src/ui.cpp:1508 msgid "unknown" msgstr "未知" -#: ../../../src/ui.cpp:1281 -#: ../../../src/ui.cpp:1305 -#: ../../../src/ui.cpp:1364 +#: ../../../src/ui.cpp:1509 +#: ../../../src/ui.cpp:1533 +#: ../../../src/ui.cpp:1592 msgid "<b>To:</b> " msgstr "<b>到:</b> " -#: ../../../src/ui.cpp:1284 +#: ../../../src/ui.cpp:1512 msgid " (yours, label: " msgstr " (您的标签: " -#: ../../../src/ui.cpp:1286 +#: ../../../src/ui.cpp:1514 msgid " (yours)" msgstr " (您的)" -#: ../../../src/ui.cpp:1323 -#: ../../../src/ui.cpp:1335 -#: ../../../src/ui.cpp:1381 -#: ../../../src/ui.cpp:1398 +#: ../../../src/ui.cpp:1551 +#: ../../../src/ui.cpp:1563 +#: ../../../src/ui.cpp:1609 +#: ../../../src/ui.cpp:1626 msgid "<b>Credit:</b> " msgstr "<b>信用:</b> " -#: ../../../src/ui.cpp:1325 +#: ../../../src/ui.cpp:1553 #, c-format msgid "(%s matures in %d more blocks)" msgstr "(%s 收获在 %d 更多的货币包)" -#: ../../../src/ui.cpp:1327 +#: ../../../src/ui.cpp:1555 msgid "(not accepted)" msgstr "(未被接受)" -#: ../../../src/ui.cpp:1372 -#: ../../../src/ui.cpp:1380 -#: ../../../src/ui.cpp:1395 +#: ../../../src/ui.cpp:1600 +#: ../../../src/ui.cpp:1608 +#: ../../../src/ui.cpp:1623 msgid "<b>Debit:</b> " msgstr "<b>付款人:</b> " -#: ../../../src/ui.cpp:1386 +#: ../../../src/ui.cpp:1614 msgid "<b>Transaction fee:</b> " msgstr "<b>交易佣金:</b> " -#: ../../../src/ui.cpp:1402 +#: ../../../src/ui.cpp:1630 msgid "<b>Net amount:</b> " msgstr "<b>网络金额:</b> " -#: ../../../src/ui.cpp:1409 +#: ../../../src/ui.cpp:1637 msgid "Message:" msgstr "消息:" -#: ../../../src/ui.cpp:1411 +#: ../../../src/ui.cpp:1639 msgid "Comment:" msgstr "评论" -#: ../../../src/ui.cpp:1414 +#: ../../../src/ui.cpp:1642 msgid "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 \"not accepted\" and not be spendable. This may occasionally happen if another node generates a block within a few seconds of yours." msgstr "生成的货币必须等待 120 个货币包之后才能够使用。 当您生成了一个货币包后,它被广播给网络来加入货币包链中。 如果它无法加入货币包链中,他将会标记为\"不被接受\"且不能被支付。 这种情况可能因为在您生成这个货币包之后的几秒钟内有别人也生成了货币包而发生。" -#: ../../../src/ui.cpp:1594 +#: ../../../src/ui.cpp:1826 msgid "Cannot write autostart/bitcoin.desktop file" msgstr "无法写入 autostart/bitcoin.desktop 文件" -#: ../../../src/ui.cpp:1630 +#: ../../../src/ui.cpp:1862 msgid "Main" msgstr "主要" -#: ../../../src/ui.cpp:1638 +#: ../../../src/ui.cpp:1872 msgid "&Start Bitcoin on window system startup" msgstr "开机自动启动 Bitcoin(&S)" -#: ../../../src/ui.cpp:1645 +#: ../../../src/ui.cpp:1879 msgid "&Minimize on close" msgstr "关闭时最小化(&M)" -#: ../../../src/ui.cpp:1787 +#: ../../../src/ui.cpp:2021 #, c-format msgid "version %s" msgstr "版本 %s" -#: ../../../src/ui.cpp:1899 +#: ../../../src/ui.cpp:2144 msgid "Error in amount " msgstr "金额有误 " -#: ../../../src/ui.cpp:1899 -#: ../../../src/ui.cpp:1904 -#: ../../../src/ui.cpp:1909 -#: ../../../src/ui.cpp:1944 -#: ../../../src/uibase.cpp:55 +#: ../../../src/ui.cpp:2144 +#: ../../../src/ui.cpp:2149 +#: ../../../src/ui.cpp:2154 +#: ../../../src/ui.cpp:2207 +#: ../../../src/uibase.cpp:61 msgid "Send Coins" msgstr "发送货币" -#: ../../../src/ui.cpp:1904 +#: ../../../src/ui.cpp:2149 msgid "Amount exceeds your balance " msgstr "金额超出您的账户余额" -#: ../../../src/ui.cpp:1909 +#: ../../../src/ui.cpp:2154 msgid "Total exceeds your balance when the " msgstr "总费用超出您的账户余额当 " -#: ../../../src/ui.cpp:1909 +#: ../../../src/ui.cpp:2154 msgid " transaction fee is included " msgstr " 交易佣金已包括" -#: ../../../src/ui.cpp:1927 +#: ../../../src/ui.cpp:2181 msgid "Payment sent " msgstr "付款已发送" -#: ../../../src/ui.cpp:1944 +#: ../../../src/ui.cpp:2181 +#: ../../../src/ui.cpp:2191 +#: ../../../src/ui.cpp:2341 +#: ../../../src/ui.cpp:2506 +#: ../../../src/wallet.cpp:1088 +msgid "Sending..." +msgstr "正在发送..." + +#: ../../../src/ui.cpp:2207 msgid "Invalid address " msgstr "无效地址 " -#: ../../../src/ui.cpp:1997 +#: ../../../src/ui.cpp:2262 #, c-format msgid "Sending %s to %s" msgstr "发送 %s 给 %s" -#: ../../../src/ui.cpp:2070 -#: ../../../src/ui.cpp:2103 +#: ../../../src/ui.cpp:2335 +#: ../../../src/ui.cpp:2368 msgid "CANCELLED" msgstr "已取消" -#: ../../../src/ui.cpp:2074 +#: ../../../src/ui.cpp:2339 msgid "Cancelled" msgstr "已取消" -#: ../../../src/ui.cpp:2076 +#: ../../../src/ui.cpp:2341 msgid "Transfer cancelled " msgstr "传输已取消 " -#: ../../../src/ui.cpp:2129 +#: ../../../src/ui.cpp:2394 msgid "Error: " msgstr "错误: " -#: ../../../src/ui.cpp:2148 +#: ../../../src/ui.cpp:2408 +#: ../../../src/ui.cpp:2477 +#: ../../../src/wallet.cpp:1106 +msgid "Insufficient funds" +msgstr "余额不足" + +#: ../../../src/ui.cpp:2413 msgid "Connecting..." msgstr "正在连接..." -#: ../../../src/ui.cpp:2153 +#: ../../../src/ui.cpp:2418 msgid "Unable to connect" msgstr "无法连接" -#: ../../../src/ui.cpp:2158 +#: ../../../src/ui.cpp:2423 msgid "Requesting public key..." msgstr "正在请求公共密钥..." -#: ../../../src/ui.cpp:2170 +#: ../../../src/ui.cpp:2435 msgid "Received public key..." msgstr "收到公共密钥..." -#: ../../../src/ui.cpp:2184 +#: ../../../src/ui.cpp:2449 msgid "Recipient is not accepting transactions sent by IP address" msgstr "收款人不接受来自 IP 地址的交易" -#: ../../../src/ui.cpp:2186 +#: ../../../src/ui.cpp:2451 msgid "Transfer was not accepted" msgstr "传输没有被接受" -#: ../../../src/ui.cpp:2195 +#: ../../../src/ui.cpp:2460 msgid "Invalid response received" msgstr "接收到无效回复" -#: ../../../src/ui.cpp:2210 +#: ../../../src/ui.cpp:2473 msgid "Creating transaction..." msgstr "正在创建交易..." -#: ../../../src/ui.cpp:2222 +#: ../../../src/ui.cpp:2496 #, c-format msgid "This transaction requires a transaction fee of at least %s because of its amount, complexity, or use of recently received funds" msgstr "这笔交易因为它最近收到的付款的数量,交易难度或者使用情况,需要至少 %s 交易佣金" -#: ../../../src/ui.cpp:2224 +#: ../../../src/ui.cpp:2498 msgid "Transaction creation failed" msgstr "交易创建失败" -#: ../../../src/ui.cpp:2231 +#: ../../../src/ui.cpp:2508 msgid "Transaction aborted" msgstr "交易中止" -#: ../../../src/ui.cpp:2239 +#: ../../../src/ui.cpp:2516 msgid "Lost connection, transaction cancelled" msgstr "失去连接,交易已取消" -#: ../../../src/ui.cpp:2255 +#: ../../../src/ui.cpp:2532 msgid "Sending payment..." msgstr "正在发送付款..." -#: ../../../src/ui.cpp:2261 +#: ../../../src/ui.cpp:2544 msgid "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." -msgstr "交易被拒绝。 这可能是因为您账户中的一部分货币已经被使用,比如您使用了一个复制的 wallet.dat 文件,而且货币在另一个副本里使用但没有在这里标记。" +msgstr "交易被拒绝。 这可能是因为您账户中的一部分货币已经被使用,比如您使用了一个复制的 wallet.dat 文件,而且货币在另一个副本里支付但没有在这里标记。" -#: ../../../src/ui.cpp:2270 +#: ../../../src/ui.cpp:2553 msgid "Waiting for confirmation..." msgstr "正在等待确认..." -#: ../../../src/ui.cpp:2288 +#: ../../../src/ui.cpp:2570 msgid "" "The payment was sent, but the recipient was unable to verify it.\n" "The transaction is recorded and will credit to the recipient,\n" @@ -615,84 +692,84 @@ msgstr "" "交易已经被记录,并且支付给收款人,\n" "但是评论信息可能是空的。" -#: ../../../src/ui.cpp:2297 +#: ../../../src/ui.cpp:2579 msgid "Payment was sent, but an invalid response was received" msgstr "支付已发送,但是收到无效回复" -#: ../../../src/ui.cpp:2303 +#: ../../../src/ui.cpp:2585 msgid "Payment completed" msgstr "付款完成" -#: ../../../src/ui.cpp:2334 -#: ../../../src/ui.cpp:2480 -#: ../../../src/ui.cpp:2517 +#: ../../../src/ui.cpp:2627 +#: ../../../src/ui.cpp:2773 +#: ../../../src/ui.cpp:2813 msgid "Name" msgstr "姓名" -#: ../../../src/ui.cpp:2335 -#: ../../../src/ui.cpp:2480 -#: ../../../src/ui.cpp:2517 +#: ../../../src/ui.cpp:2628 +#: ../../../src/ui.cpp:2773 +#: ../../../src/ui.cpp:2813 msgid "Address" msgstr "地址" -#: ../../../src/ui.cpp:2337 -#: ../../../src/ui.cpp:2492 +#: ../../../src/ui.cpp:2630 +#: ../../../src/ui.cpp:2785 msgid "Label" msgstr "标签" -#: ../../../src/ui.cpp:2338 -#: ../../../src/uibase.cpp:837 +#: ../../../src/ui.cpp:2631 +#: ../../../src/uibase.cpp:847 msgid "Bitcoin Address" msgstr "Bitcoin 地址" -#: ../../../src/ui.cpp:2462 +#: ../../../src/ui.cpp:2755 msgid "This is one of your own addresses for receiving payments and cannot be entered in the address book. " msgstr "这是您拥有的接收付款的地址之一,它不能够进入这个地址簿。 " -#: ../../../src/ui.cpp:2480 -#: ../../../src/ui.cpp:2486 +#: ../../../src/ui.cpp:2773 +#: ../../../src/ui.cpp:2779 msgid "Edit Address" msgstr "编辑地址" -#: ../../../src/ui.cpp:2492 +#: ../../../src/ui.cpp:2785 msgid "Edit Address Label" msgstr "编辑地址标签" -#: ../../../src/ui.cpp:2517 -#: ../../../src/ui.cpp:2523 +#: ../../../src/ui.cpp:2813 +#: ../../../src/ui.cpp:2819 msgid "Add Address" msgstr "添加地址" -#: ../../../src/ui.cpp:2600 +#: ../../../src/ui.cpp:2906 msgid "Bitcoin" msgstr "Bitcoin" -#: ../../../src/ui.cpp:2602 +#: ../../../src/ui.cpp:2908 msgid "Bitcoin - Generating" msgstr "Bitcoin - 生成中" -#: ../../../src/ui.cpp:2604 +#: ../../../src/ui.cpp:2910 msgid "Bitcoin - (not connected)" msgstr "Bitcoin - (未连接)" -#: ../../../src/ui.cpp:2683 +#: ../../../src/ui.cpp:2989 msgid "&Open Bitcoin" msgstr "打开 Bitcoin(&O)" -#: ../../../src/ui.cpp:2684 +#: ../../../src/ui.cpp:2990 msgid "&Send Bitcoins" msgstr "发送 Bitcoins(&S)" -#: ../../../src/ui.cpp:2685 +#: ../../../src/ui.cpp:2991 msgid "O&ptions..." msgstr "选项(&P)..." -#: ../../../src/ui.cpp:2688 +#: ../../../src/ui.cpp:2994 #: ../../../src/uibase.cpp:25 msgid "E&xit" msgstr "退出(&X)" -#: ../../../src/ui.cpp:2904 +#: ../../../src/ui.cpp:3220 msgid "Program has crashed and will terminate. " msgstr "程序崩溃,即将关闭。 " @@ -704,152 +781,160 @@ msgstr "文件(&F)" msgid "&Your Receiving Addresses..." msgstr "您的接收地址(&Y)..." -#: ../../../src/uibase.cpp:36 +#: ../../../src/uibase.cpp:35 +msgid "&Encrypt Wallet..." +msgstr "加密钱包(&E)..." + +#: ../../../src/uibase.cpp:38 +msgid "&Change Wallet Encryption Passphrase..." +msgstr "更改钱包加密口令(&C)..." + +#: ../../../src/uibase.cpp:42 msgid "&Options..." msgstr "选项(&O)..." -#: ../../../src/uibase.cpp:39 +#: ../../../src/uibase.cpp:45 msgid "&Settings" msgstr "设置(&S)" -#: ../../../src/uibase.cpp:43 +#: ../../../src/uibase.cpp:49 msgid "&About..." msgstr "关于(&A)..." -#: ../../../src/uibase.cpp:46 +#: ../../../src/uibase.cpp:52 msgid "&Help" msgstr "帮助(&H)" -#: ../../../src/uibase.cpp:56 +#: ../../../src/uibase.cpp:62 msgid "Address Book" msgstr "地址簿" -#: ../../../src/uibase.cpp:69 +#: ../../../src/uibase.cpp:75 msgid "Your Bitcoin Address:" msgstr "您的 Bitcoin 地址:" -#: ../../../src/uibase.cpp:76 +#: ../../../src/uibase.cpp:82 msgid " &New... " msgstr " 新建(&N)... " -#: ../../../src/uibase.cpp:79 -#: ../../../src/uibase.cpp:780 -#: ../../../src/uibase.cpp:883 +#: ../../../src/uibase.cpp:85 +#: ../../../src/uibase.cpp:790 +#: ../../../src/uibase.cpp:893 msgid " &Copy to Clipboard " msgstr " 复制到剪贴板(&C)" -#: ../../../src/uibase.cpp:93 +#: ../../../src/uibase.cpp:99 msgid "Balance:" msgstr "账户余额:" -#: ../../../src/uibase.cpp:109 +#: ../../../src/uibase.cpp:115 msgid " All" msgstr "全部" -#: ../../../src/uibase.cpp:109 +#: ../../../src/uibase.cpp:115 msgid " Sent" msgstr " 已发送" -#: ../../../src/uibase.cpp:109 +#: ../../../src/uibase.cpp:115 msgid " Received" msgstr " 已接收" -#: ../../../src/uibase.cpp:109 +#: ../../../src/uibase.cpp:115 msgid " In Progress" msgstr "处理中" -#: ../../../src/uibase.cpp:130 +#: ../../../src/uibase.cpp:136 msgid "All Transactions" msgstr "所有交易" -#: ../../../src/uibase.cpp:141 +#: ../../../src/uibase.cpp:147 msgid "Sent/Received" msgstr "已发送/已接收" -#: ../../../src/uibase.cpp:152 +#: ../../../src/uibase.cpp:158 msgid "Sent" msgstr "已发送" -#: ../../../src/uibase.cpp:163 +#: ../../../src/uibase.cpp:169 msgid "Received" msgstr "已接收" -#: ../../../src/uibase.cpp:302 -#: ../../../src/uibase.cpp:443 -#: ../../../src/uibase.cpp:542 -#: ../../../src/uibase.cpp:722 -#: ../../../src/uibase.cpp:783 -#: ../../../src/uibase.cpp:892 -#: ../../../src/uibase.cpp:981 +#: ../../../src/uibase.cpp:312 +#: ../../../src/uibase.cpp:453 +#: ../../../src/uibase.cpp:552 +#: ../../../src/uibase.cpp:732 +#: ../../../src/uibase.cpp:793 +#: ../../../src/uibase.cpp:902 +#: ../../../src/uibase.cpp:991 msgid "OK" msgstr "确定" -#: ../../../src/uibase.cpp:345 +#: ../../../src/uibase.cpp:355 msgid "&Start Bitcoin on system startup" msgstr "开机自动启动(&S)" -#: ../../../src/uibase.cpp:348 +#: ../../../src/uibase.cpp:358 msgid "&Minimize to the tray instead of the taskbar" msgstr "最小化到系统托盘(&M)" -#: ../../../src/uibase.cpp:351 +#: ../../../src/uibase.cpp:361 msgid "Map port using &UPnP" msgstr "使用 &UPnP 映射端口" -#: ../../../src/uibase.cpp:354 +#: ../../../src/uibase.cpp:364 msgid "M&inimize to the tray on close" msgstr "关闭时最小化到托盘(&I)" -#: ../../../src/uibase.cpp:360 -msgid "&Connect through socks4 proxy: " -msgstr "通过 socks4 代理连接(&C): " +#: ../../../src/uibase.cpp:370 +msgid "&Connect through socks4 proxy (requires restart to apply): " +msgstr "通过 socks4 代理连接 (重启生效) (&C): " -#: ../../../src/uibase.cpp:371 +#: ../../../src/uibase.cpp:381 msgid "Proxy &IP:" msgstr "代理服务器(&I):" -#: ../../../src/uibase.cpp:379 +#: ../../../src/uibase.cpp:389 msgid " &Port:" msgstr " 端口(&P):" -#: ../../../src/uibase.cpp:392 +#: ../../../src/uibase.cpp:402 msgid "Optional transaction fee per KB that helps make sure your transactions are processed quickly. Most transactions are 1KB. Fee 0.01 recommended." msgstr "可以选择按照KB支付交易佣金来确保您的交易得到迅速处理。 大多数交易需要 1KB。 建议支付 0.01。" -#: ../../../src/uibase.cpp:399 +#: ../../../src/uibase.cpp:409 msgid "Pay transaction fee:" msgstr "支付交易佣金:" -#: ../../../src/uibase.cpp:420 +#: ../../../src/uibase.cpp:430 msgid "// [don't translate] Test panel 2 for future expansion" msgstr "" -#: ../../../src/uibase.cpp:424 +#: ../../../src/uibase.cpp:434 msgid "// [don't translate] Let's not start multiple pages until the first page is filled up" msgstr "" -#: ../../../src/uibase.cpp:446 -#: ../../../src/uibase.cpp:668 -#: ../../../src/uibase.cpp:727 -#: ../../../src/uibase.cpp:786 -#: ../../../src/uibase.cpp:895 -#: ../../../src/uibase.cpp:984 +#: ../../../src/uibase.cpp:456 +#: ../../../src/uibase.cpp:678 +#: ../../../src/uibase.cpp:737 +#: ../../../src/uibase.cpp:796 +#: ../../../src/uibase.cpp:905 +#: ../../../src/uibase.cpp:994 msgid "Cancel" msgstr "取消" -#: ../../../src/uibase.cpp:449 +#: ../../../src/uibase.cpp:459 msgid "&Apply" msgstr "应用(&A)" -#: ../../../src/uibase.cpp:508 +#: ../../../src/uibase.cpp:518 msgid "Bitcoin " msgstr "Bitcoin " -#: ../../../src/uibase.cpp:514 +#: ../../../src/uibase.cpp:524 msgid "version" msgstr "版本" -#: ../../../src/uibase.cpp:525 +#: ../../../src/uibase.cpp:535 msgid "" "Copyright (c) 2009-2011 Bitcoin Developers\n" "\n" @@ -870,39 +955,39 @@ msgstr "" "(http://www.openssl.org/),以及 Eric Young(eay@cryptsoft.com)\n" "编写的加密软件和 Thomas Bernard 编写的 UPnP 软件。" -#: ../../../src/uibase.cpp:581 +#: ../../../src/uibase.cpp:591 msgid "Enter a Bitcoin address (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L)" msgstr "输入 Bitcoin 地址 (比如 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L)" -#: ../../../src/uibase.cpp:595 +#: ../../../src/uibase.cpp:605 msgid "Pay &To:" msgstr "付款给(&T):" -#: ../../../src/uibase.cpp:610 +#: ../../../src/uibase.cpp:620 msgid "&Paste" msgstr "粘贴(&P)" -#: ../../../src/uibase.cpp:613 +#: ../../../src/uibase.cpp:623 msgid " Address &Book..." msgstr " 地址簿(&B)..." -#: ../../../src/uibase.cpp:620 +#: ../../../src/uibase.cpp:630 msgid "&Amount:" msgstr "数量(&A):" -#: ../../../src/uibase.cpp:630 +#: ../../../src/uibase.cpp:640 msgid "T&ransfer:" msgstr "传输(&R):" -#: ../../../src/uibase.cpp:636 +#: ../../../src/uibase.cpp:646 msgid " Standard" msgstr "标准" -#: ../../../src/uibase.cpp:663 +#: ../../../src/uibase.cpp:673 msgid "&Send" msgstr "发送(&S)" -#: ../../../src/uibase.cpp:711 +#: ../../../src/uibase.cpp:721 msgid "" "\n" "\n" @@ -912,56 +997,80 @@ msgstr "" "\n" "正在连接..." -#: ../../../src/uibase.cpp:761 +#: ../../../src/uibase.cpp:771 msgid "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. The highlighted address is displayed in the main window." msgstr "这些是您用来接收付款的 Bitcoin 地址。 您可能需要给每一个付款人一个不同的地址从而可以最终每一笔交易是谁支付的。 下面高亮的地址是您的主窗口正在使用的地址。" -#: ../../../src/uibase.cpp:774 -#: ../../../src/uibase.cpp:886 +#: ../../../src/uibase.cpp:784 +#: ../../../src/uibase.cpp:896 msgid "&Edit..." msgstr "编辑(&E)..." -#: ../../../src/uibase.cpp:777 -#: ../../../src/uibase.cpp:889 +#: ../../../src/uibase.cpp:787 +#: ../../../src/uibase.cpp:899 msgid " &New Address... " msgstr " 新建地址(&N)..." -#: ../../../src/uibase.cpp:849 +#: ../../../src/uibase.cpp:859 msgid "Sending" msgstr "发送人地址" -#: ../../../src/uibase.cpp:857 +#: ../../../src/uibase.cpp:867 msgid "These are your Bitcoin addresses for receiving payments. You can give a different one to each sender to keep track of who is paying you. The highlighted address will be displayed in the main window." msgstr "这些是您用来接收付款的 Bitcoin 地址。 您可以给每一个付款人一个不同的地址从而可以最终每一笔交易是谁支付的。 下面高亮的地址是您的主窗口正在使用的地址。" -#: ../../../src/uibase.cpp:870 +#: ../../../src/uibase.cpp:880 msgid "Receiving" msgstr "我的接收地址" -#: ../../../src/uibase.cpp:880 +#: ../../../src/uibase.cpp:890 msgid "&Delete" msgstr "删除(&D)" -#: ../../../src/util.cpp:866 +#: ../../../src/util.cpp:870 msgid "Warning: Please check that your computer's date and time are correct. If your clock is wrong Bitcoin will not work properly." msgstr "警告: 请检查您的电脑日期和时间是否正确。 如果您的时钟不正确 Bitcoin 将无法正常工作。" -#: ../../../src/util.cpp:899 +#: ../../../src/util.cpp:904 msgid "beta" msgstr "测试版" -#: ../../../src/uibase.h:147 +#: ../../../src/wallet.cpp:1073 +msgid "Error: Wallet locked, unable to create transaction " +msgstr "错误: 钱包已锁定,无法创建交易 " + +#: ../../../src/wallet.cpp:1081 +#, c-format +msgid "Error: This transaction requires a transaction fee of at least %s because of its amount, complexity, or use of recently received funds " +msgstr "错误: 这个交易因为近期收到支付的数量,难度或者使用而需要支付至少 %s 交易佣金 " + +#: ../../../src/wallet.cpp:1083 +msgid "Error: Transaction creation failed " +msgstr "错误: 交易创建失败" + +#: ../../../src/wallet.cpp:1092 +msgid "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." +msgstr "错误: 交易被拒绝。 这可能是因为您账户里的一些货币应经被使用,比如您使用了一个复制的 wallet.dat 文件,一些货币在另一个副本里支付了但是没有在这里更新。" + +#: ../../../src/wallet.cpp:1104 +msgid "Invalid amount" +msgstr "无效金额" + +#: ../../../src/uibase.h:151 msgid "Transaction Details" msgstr "交易详情" -#: ../../../src/uibase.h:199 +#: ../../../src/uibase.h:203 msgid "Options" msgstr "选项" -#: ../../../src/uibase.h:228 +#: ../../../src/uibase.h:232 msgid "About Bitcoin" msgstr "关于 Bitcoin" -#: ../../../src/uibase.h:337 +#: ../../../src/uibase.h:341 msgid "Your Bitcoin Addresses" msgstr "您的 Bitcoin 地址" + +#~ msgid "Invalid bitcoin address" +#~ msgstr "无效 bitcoin 地址" diff --git a/scripts/qt/extract_strings_qt.py b/scripts/qt/extract_strings_qt.py new file mode 100755 index 0000000000..6627de4abf --- /dev/null +++ b/scripts/qt/extract_strings_qt.py @@ -0,0 +1,63 @@ +#!/usr/bin/python +''' +Extract _("...") strings for translation and convert to Qt4 stringdefs so that +they can be picked up by Qt linguist. +''' +from subprocess import Popen, PIPE + +OUT_CPP="src/qt/bitcoinstrings.cpp" +EMPTY=['""'] + +def parse_po(text): + """ + Parse 'po' format produced by xgettext. + Return a list of (msgid,msgstr) tuples. + """ + messages = [] + msgid = [] + msgstr = [] + in_msgid = False + in_msgstr = False + + for line in text.split('\n'): + line = line.rstrip('\r') + if line.startswith('msgid '): + if in_msgstr: + messages.append((msgid, msgstr)) + in_msgstr = False + # message start + in_msgid = True + + msgid = [line[6:]] + elif line.startswith('msgstr '): + in_msgid = False + in_msgstr = True + msgstr = [line[7:]] + elif line.startswith('"'): + if in_msgid: + msgid.append(line) + if in_msgstr: + msgstr.append(line) + + if in_msgstr: + messages.append((msgid, msgstr)) + + return messages + +files = ['src/base58.h', 'src/bignum.h', 'src/db.cpp', 'src/db.h', 'src/headers.h', 'src/init.cpp', 'src/init.h', 'src/irc.cpp', 'src/irc.h', 'src/key.h', 'src/main.cpp', 'src/main.h', 'src/net.cpp', 'src/net.h', 'src/noui.h', 'src/script.cpp', 'src/script.h', 'src/serialize.h', 'src/strlcpy.h', 'src/uint256.h', 'src/util.cpp', 'src/util.h'] + +# xgettext -n --keyword=_ $FILES +child = Popen(['xgettext','--output=-','-n','--keyword=_'] + files, stdout=PIPE) +(out, err) = child.communicate() + +messages = parse_po(out) + +f = open(OUT_CPP, 'w') +f.write('#include <QtGlobal>\n') +f.write('// Automatically generated by extract_strings.py\n') +f.write('static const char *bitcoin_strings[] = {') +for (msgid, msgstr) in messages: + if msgid != EMPTY: + f.write('QT_TRANSLATE_NOOP("bitcoin-core", %s),\n' % ('\n'.join(msgid))) +f.write('};') +f.close() diff --git a/scripts/qt/img/reload.xcf b/scripts/qt/img/reload.xcf Binary files differnew file mode 100644 index 0000000000..dc8be62831 --- /dev/null +++ b/scripts/qt/img/reload.xcf diff --git a/scripts/qt/make_spinner.py b/scripts/qt/make_spinner.py new file mode 100755 index 0000000000..136aff3cb7 --- /dev/null +++ b/scripts/qt/make_spinner.py @@ -0,0 +1,43 @@ +#!/usr/bin/env python +# W.J. van der Laan, 2011 +# Make spinning .mng animation from a .png +# Requires imagemagick 6.7+ +from __future__ import division +from os import path +from PIL import Image +from subprocess import Popen + +SRC='img/reload_scaled.png' +DST='../../src/qt/res/movies/update_spinner.mng' +TMPDIR='/tmp' +TMPNAME='tmp-%03i.png' +NUMFRAMES=35 +FRAMERATE=10.0 +CONVERT='convert' +CLOCKWISE=True +DSIZE=(16,16) + +im_src = Image.open(SRC) + +if CLOCKWISE: + im_src = im_src.transpose(Image.FLIP_LEFT_RIGHT) + +def frame_to_filename(frame): + return path.join(TMPDIR, TMPNAME % frame) + +frame_files = [] +for frame in xrange(NUMFRAMES): + rotation = (frame + 0.5) / NUMFRAMES * 360.0 + if CLOCKWISE: + rotation = -rotation + im_new = im_src.rotate(rotation, Image.BICUBIC) + im_new.thumbnail(DSIZE, Image.ANTIALIAS) + outfile = frame_to_filename(frame) + im_new.save(outfile, 'png') + frame_files.append(outfile) + +p = Popen([CONVERT, "-delay", str(FRAMERATE), "-dispose", "2"] + frame_files + [DST]) +p.communicate() + + + diff --git a/scripts/qt/make_windows_icon.py b/scripts/qt/make_windows_icon.py new file mode 100755 index 0000000000..bf607b1c62 --- /dev/null +++ b/scripts/qt/make_windows_icon.py @@ -0,0 +1,9 @@ +#!/bin/bash +# create multiresolution windows icon +ICON_SRC=../../src/qt/res/icons/bitcoin.png +ICON_DST=../../src/qt/res/icons/bitcoin.ico +convert ${ICON_SRC} -resize 16x16 bitcoin-16.png +convert ${ICON_SRC} -resize 32x32 bitcoin-32.png +convert ${ICON_SRC} -resize 48x48 bitcoin-48.png +convert bitcoin-16.png bitcoin-32.png bitcoin-48.png ${ICON_DST} + diff --git a/share/pixmaps/bitcoin.ico b/share/pixmaps/bitcoin.ico Binary files differindex cdec9a037b..61926807cc 100644 --- a/share/pixmaps/bitcoin.ico +++ b/share/pixmaps/bitcoin.ico diff --git a/share/pixmaps/nsis-header.bmp b/share/pixmaps/nsis-header.bmp Binary files differnew file mode 100644 index 0000000000..9ab0ce2591 --- /dev/null +++ b/share/pixmaps/nsis-header.bmp diff --git a/share/pixmaps/nsis-wizard.bmp b/share/pixmaps/nsis-wizard.bmp Binary files differnew file mode 100644 index 0000000000..71255c6850 --- /dev/null +++ b/share/pixmaps/nsis-wizard.bmp diff --git a/share/setup.nsi b/share/setup.nsi index 8677d334e2..4c837c974b 100644 --- a/share/setup.nsi +++ b/share/setup.nsi @@ -1,15 +1,20 @@ Name Bitcoin
RequestExecutionLevel highest
+SetCompressor /SOLID lzma
# General Symbol Definitions
!define REGKEY "SOFTWARE\$(^Name)"
-!define VERSION 0.3.24
+!define VERSION 0.4.1
!define COMPANY "Bitcoin project"
!define URL http://www.bitcoin.org/
# MUI Symbol Definitions
!define MUI_ICON "../share/pixmaps/bitcoin.ico"
+!define MUI_WELCOMEFINISHPAGE_BITMAP "../share/pixmaps/nsis-wizard.bmp"
+!define MUI_HEADERIMAGE
+!define MUI_HEADERIMAGE_RIGHT
+!define MUI_HEADERIMAGE_BITMAP "../share/pixmaps/nsis-header.bmp"
!define MUI_FINISHPAGE_NOAUTOCLOSE
!define MUI_STARTMENUPAGE_REGISTRY_ROOT HKLM
!define MUI_STARTMENUPAGE_REGISTRY_KEY ${REGKEY}
@@ -17,6 +22,7 @@ RequestExecutionLevel highest !define MUI_STARTMENUPAGE_DEFAULTFOLDER Bitcoin
!define MUI_FINISHPAGE_RUN $INSTDIR\bitcoin.exe
!define MUI_UNICON "${NSISDIR}\Contrib\Graphics\Icons\modern-uninstall.ico"
+!define MUI_UNWELCOMEFINISHPAGE_BITMAP "../share/pixmaps/nsis-wizard.bmp"
!define MUI_UNFINISHPAGE_NOAUTOCLOSE
# Included files
@@ -39,12 +45,13 @@ Var StartMenuGroup !insertmacro MUI_LANGUAGE English
# Installer attributes
-OutFile bitcoin-0.3.24-win32-setup.exe
+OutFile bitcoin-0.4.1-win32-setup.exe
InstallDir $PROGRAMFILES\Bitcoin
CRCCheck on
XPStyle on
+BrandingText " "
ShowInstDetails show
-VIProductVersion 0.3.24.0
+VIProductVersion 0.4.1.0
VIAddVersionKey ProductName Bitcoin
VIAddVersionKey ProductVersion "${VERSION}"
VIAddVersionKey CompanyName "${COMPANY}"
diff --git a/share/uiproject.fbp b/share/uiproject.fbp deleted file mode 100644 index d9d46382d3..0000000000 --- a/share/uiproject.fbp +++ /dev/null @@ -1,6358 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
-<wxFormBuilder_Project>
- <FileVersion major="1" minor="9" />
- <object class="Project" expanded="1">
- <property name="class_decoration"></property>
- <property name="code_generation">C++</property>
- <property name="disconnect_events">1</property>
- <property name="encoding">UTF-8</property>
- <property name="event_generation">connect</property>
- <property name="event_handler">impl_virtual</property>
- <property name="file">uibase</property>
- <property name="first_id">1000</property>
- <property name="help_provider">none</property>
- <property name="internationalize">1</property>
- <property name="name"></property>
- <property name="namespace"></property>
- <property name="path">.</property>
- <property name="precompiled_header"></property>
- <property name="relative_path">1</property>
- <property name="use_enum">0</property>
- <property name="use_microsoft_bom">0</property>
- <object class="Frame" expanded="0">
- <property name="bg">wxSYS_COLOUR_BTNFACE</property>
- <property name="center"></property>
- <property name="context_help"></property>
- <property name="enabled">1</property>
- <property name="extra_style"></property>
- <property name="fg"></property>
- <property name="font"></property>
- <property name="hidden">0</property>
- <property name="id">wxID_MAINFRAME</property>
- <property name="maximum_size"></property>
- <property name="minimum_size"></property>
- <property name="name">CMainFrameBase</property>
- <property name="pos"></property>
- <property name="size">723,484</property>
- <property name="style">wxDEFAULT_FRAME_STYLE|wxRESIZE_BORDER</property>
- <property name="subclass"></property>
- <property name="title">Bitcoin</property>
- <property name="tooltip"></property>
- <property name="validator_data_type"></property>
- <property name="validator_style">wxFILTER_NONE</property>
- <property name="validator_type">wxDefaultValidator</property>
- <property name="validator_variable"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style">wxTAB_TRAVERSAL</property>
- <property name="xrc_skip_sizer">1</property>
- <event name="OnActivate"></event>
- <event name="OnActivateApp"></event>
- <event name="OnChar"></event>
- <event name="OnClose">OnClose</event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnHibernate"></event>
- <event name="OnIconize">OnIconize</event>
- <event name="OnIdle">OnIdle</event>
- <event name="OnKeyDown"></event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents">OnMouseEvents</event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint">OnPaint</event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnUpdateUI"></event>
- <object class="wxMenuBar" expanded="1">
- <property name="bg"></property>
- <property name="context_help"></property>
- <property name="enabled">1</property>
- <property name="fg"></property>
- <property name="font"></property>
- <property name="hidden">0</property>
- <property name="id">wxID_ANY</property>
- <property name="label">MyMenuBar</property>
- <property name="maximum_size"></property>
- <property name="minimum_size"></property>
- <property name="name">m_menubar</property>
- <property name="permission">protected</property>
- <property name="pos"></property>
- <property name="size"></property>
- <property name="style"></property>
- <property name="subclass"></property>
- <property name="tooltip"></property>
- <property name="validator_data_type"></property>
- <property name="validator_style">wxFILTER_NONE</property>
- <property name="validator_type">wxDefaultValidator</property>
- <property name="validator_variable"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style"></property>
- <event name="OnChar"></event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnKeyDown"></event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint"></event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnUpdateUI"></event>
- <object class="wxMenu" expanded="1">
- <property name="label">&File</property>
- <property name="name">m_menuFile</property>
- <property name="permission">protected</property>
- <object class="wxMenuItem" expanded="1">
- <property name="bitmap"></property>
- <property name="checked">0</property>
- <property name="enabled">1</property>
- <property name="help"></property>
- <property name="id">wxID_EXIT</property>
- <property name="kind">wxITEM_NORMAL</property>
- <property name="label">E&xit</property>
- <property name="name">m_menuFileExit</property>
- <property name="permission">none</property>
- <property name="shortcut"></property>
- <property name="unchecked_bitmap"></property>
- <event name="OnMenuSelection">OnMenuFileExit</event>
- <event name="OnUpdateUI"></event>
- </object>
- </object>
- <object class="wxMenu" expanded="1">
- <property name="label">&Settings</property>
- <property name="name">m_menuOptions</property>
- <property name="permission">public</property>
- <object class="wxMenuItem" expanded="1">
- <property name="bitmap"></property>
- <property name="checked">0</property>
- <property name="enabled">1</property>
- <property name="help"></property>
- <property name="id">wxID_ANY</property>
- <property name="kind">wxITEM_NORMAL</property>
- <property name="label">&Your Receiving Addresses...</property>
- <property name="name">m_menuOptionsChangeYourAddress</property>
- <property name="permission">none</property>
- <property name="shortcut"></property>
- <property name="unchecked_bitmap"></property>
- <event name="OnMenuSelection">OnMenuOptionsChangeYourAddress</event>
- <event name="OnUpdateUI"></event>
- </object>
- <object class="wxMenuItem" expanded="1">
- <property name="bitmap"></property>
- <property name="checked">0</property>
- <property name="enabled">1</property>
- <property name="help"></property>
- <property name="id">wxID_PREFERENCES</property>
- <property name="kind">wxITEM_NORMAL</property>
- <property name="label">&Options...</property>
- <property name="name">m_menuOptionsOptions</property>
- <property name="permission">none</property>
- <property name="shortcut"></property>
- <property name="unchecked_bitmap"></property>
- <event name="OnMenuSelection">OnMenuOptionsOptions</event>
- <event name="OnUpdateUI"></event>
- </object>
- </object>
- <object class="wxMenu" expanded="1">
- <property name="label">&Help</property>
- <property name="name">m_menuHelp</property>
- <property name="permission">protected</property>
- <object class="wxMenuItem" expanded="1">
- <property name="bitmap"></property>
- <property name="checked">0</property>
- <property name="enabled">1</property>
- <property name="help"></property>
- <property name="id">wxID_ABOUT</property>
- <property name="kind">wxITEM_NORMAL</property>
- <property name="label">&About...</property>
- <property name="name">m_menuHelpAbout</property>
- <property name="permission">none</property>
- <property name="shortcut"></property>
- <property name="unchecked_bitmap"></property>
- <event name="OnMenuSelection">OnMenuHelpAbout</event>
- <event name="OnUpdateUI"></event>
- </object>
- </object>
- </object>
- <object class="wxToolBar" expanded="1">
- <property name="bg"></property>
- <property name="bitmapsize">20,20</property>
- <property name="context_help"></property>
- <property name="enabled">1</property>
- <property name="fg"></property>
- <property name="font">,90,90,-1,70,0</property>
- <property name="hidden">0</property>
- <property name="id">wxID_ANY</property>
- <property name="margins"></property>
- <property name="maximum_size"></property>
- <property name="minimum_size"></property>
- <property name="name">m_toolBar</property>
- <property name="packing">1</property>
- <property name="permission">protected</property>
- <property name="pos"></property>
- <property name="separation">1</property>
- <property name="size">-1,-1</property>
- <property name="style">wxTB_FLAT|wxTB_HORZ_TEXT</property>
- <property name="subclass"></property>
- <property name="tooltip"></property>
- <property name="validator_data_type"></property>
- <property name="validator_style">wxFILTER_NONE</property>
- <property name="validator_type">wxDefaultValidator</property>
- <property name="validator_variable"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style"></property>
- <event name="OnChar"></event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnKeyDown"></event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint"></event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnUpdateUI"></event>
- <object class="tool" expanded="1">
- <property name="bitmap">xpm/send20.xpm; Load From File</property>
- <property name="id">wxID_BUTTONSEND</property>
- <property name="kind">wxITEM_NORMAL</property>
- <property name="label">Send Coins</property>
- <property name="name">m_tool1</property>
- <property name="statusbar"></property>
- <property name="tooltip"></property>
- <event name="OnMenuSelection"></event>
- <event name="OnToolClicked">OnButtonSend</event>
- <event name="OnToolEnter"></event>
- <event name="OnToolRClicked"></event>
- <event name="OnUpdateUI"></event>
- </object>
- <object class="tool" expanded="1">
- <property name="bitmap">xpm/addressbook20.xpm; Load From File</property>
- <property name="id">wxID_BUTTONRECEIVE</property>
- <property name="kind">wxITEM_NORMAL</property>
- <property name="label">Address Book</property>
- <property name="name">m_tool2</property>
- <property name="statusbar"></property>
- <property name="tooltip"></property>
- <event name="OnMenuSelection"></event>
- <event name="OnToolClicked">OnButtonAddressBook</event>
- <event name="OnToolEnter"></event>
- <event name="OnToolRClicked"></event>
- <event name="OnUpdateUI"></event>
- </object>
- </object>
- <object class="wxStatusBar" expanded="1">
- <property name="bg"></property>
- <property name="context_help"></property>
- <property name="enabled">1</property>
- <property name="fg"></property>
- <property name="fields">1</property>
- <property name="font"></property>
- <property name="hidden">0</property>
- <property name="id">wxID_ANY</property>
- <property name="maximum_size"></property>
- <property name="minimum_size"></property>
- <property name="name">m_statusBar</property>
- <property name="permission">public</property>
- <property name="pos"></property>
- <property name="size"></property>
- <property name="style">wxST_SIZEGRIP</property>
- <property name="subclass"></property>
- <property name="tooltip"></property>
- <property name="validator_data_type"></property>
- <property name="validator_style">wxFILTER_NONE</property>
- <property name="validator_type">wxDefaultValidator</property>
- <property name="validator_variable"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style"></property>
- <event name="OnChar"></event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnKeyDown"></event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint"></event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnUpdateUI"></event>
- </object>
- <object class="wxBoxSizer" expanded="1">
- <property name="minimum_size"></property>
- <property name="name">bSizer2</property>
- <property name="orient">wxVERTICAL</property>
- <property name="permission">none</property>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxEXPAND</property>
- <property name="proportion">0</property>
- <object class="spacer" expanded="1">
- <property name="height">2</property>
- <property name="permission">protected</property>
- <property name="width">0</property>
- </object>
- </object>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxEXPAND|wxRIGHT|wxLEFT</property>
- <property name="proportion">0</property>
- <object class="wxBoxSizer" expanded="1">
- <property name="minimum_size"></property>
- <property name="name">bSizer85</property>
- <property name="orient">wxHORIZONTAL</property>
- <property name="permission">none</property>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxALIGN_CENTER_VERTICAL|wxLEFT</property>
- <property name="proportion">0</property>
- <object class="wxStaticText" expanded="1">
- <property name="bg"></property>
- <property name="context_help"></property>
- <property name="enabled">1</property>
- <property name="fg"></property>
- <property name="font"></property>
- <property name="hidden">0</property>
- <property name="id">wxID_ANY</property>
- <property name="label">Your Bitcoin Address:</property>
- <property name="maximum_size"></property>
- <property name="minimum_size"></property>
- <property name="name">m_staticText32</property>
- <property name="permission">protected</property>
- <property name="pos"></property>
- <property name="size"></property>
- <property name="style"></property>
- <property name="subclass"></property>
- <property name="tooltip"></property>
- <property name="validator_data_type"></property>
- <property name="validator_style">wxFILTER_NONE</property>
- <property name="validator_type">wxDefaultValidator</property>
- <property name="validator_variable"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style"></property>
- <property name="wrap">-1</property>
- <event name="OnChar"></event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnKeyDown"></event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint"></event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnUpdateUI"></event>
- </object>
- </object>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT</property>
- <property name="proportion">0</property>
- <object class="wxTextCtrl" expanded="1">
- <property name="bg"></property>
- <property name="context_help"></property>
- <property name="enabled">1</property>
- <property name="fg"></property>
- <property name="font"></property>
- <property name="hidden">0</property>
- <property name="id">wxID_TEXTCTRLADDRESS</property>
- <property name="maximum_size">-1,-1</property>
- <property name="maxlength">0</property>
- <property name="minimum_size">-1,-1</property>
- <property name="name">m_textCtrlAddress</property>
- <property name="permission">public</property>
- <property name="pos"></property>
- <property name="size">340,-1</property>
- <property name="style">wxTE_READONLY</property>
- <property name="subclass"></property>
- <property name="tooltip"></property>
- <property name="validator_data_type"></property>
- <property name="validator_style">wxFILTER_NONE</property>
- <property name="validator_type">wxDefaultValidator</property>
- <property name="validator_variable"></property>
- <property name="value"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style"></property>
- <event name="OnChar"></event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnKeyDown">OnKeyDown</event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents">OnMouseEventsAddress</event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint"></event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus">OnSetFocusAddress</event>
- <event name="OnSize"></event>
- <event name="OnText"></event>
- <event name="OnTextEnter"></event>
- <event name="OnTextMaxLen"></event>
- <event name="OnTextURL"></event>
- <event name="OnUpdateUI"></event>
- </object>
- </object>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxRIGHT|wxALIGN_CENTER_VERTICAL</property>
- <property name="proportion">0</property>
- <object class="wxButton" expanded="1">
- <property name="bg"></property>
- <property name="context_help"></property>
- <property name="default">0</property>
- <property name="enabled">1</property>
- <property name="fg"></property>
- <property name="font"></property>
- <property name="hidden">0</property>
- <property name="id">wxID_BUTTONNEW</property>
- <property name="label"> &New... </property>
- <property name="maximum_size"></property>
- <property name="minimum_size"></property>
- <property name="name">m_buttonNew</property>
- <property name="permission">protected</property>
- <property name="pos"></property>
- <property name="size">-1,-1</property>
- <property name="style">wxBU_EXACTFIT</property>
- <property name="subclass"></property>
- <property name="tooltip"></property>
- <property name="validator_data_type"></property>
- <property name="validator_style">wxFILTER_NONE</property>
- <property name="validator_type">wxDefaultValidator</property>
- <property name="validator_variable"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style"></property>
- <event name="OnButtonClick">OnButtonNew</event>
- <event name="OnChar"></event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnKeyDown"></event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint"></event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnUpdateUI"></event>
- </object>
- </object>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxALIGN_CENTER_VERTICAL|wxRIGHT</property>
- <property name="proportion">0</property>
- <object class="wxButton" expanded="1">
- <property name="bg"></property>
- <property name="context_help"></property>
- <property name="default">0</property>
- <property name="enabled">1</property>
- <property name="fg"></property>
- <property name="font"></property>
- <property name="hidden">0</property>
- <property name="id">wxID_BUTTONCOPY</property>
- <property name="label"> &Copy to Clipboard </property>
- <property name="maximum_size"></property>
- <property name="minimum_size"></property>
- <property name="name">m_buttonCopy</property>
- <property name="permission">protected</property>
- <property name="pos"></property>
- <property name="size"></property>
- <property name="style">wxBU_EXACTFIT</property>
- <property name="subclass"></property>
- <property name="tooltip"></property>
- <property name="validator_data_type"></property>
- <property name="validator_style">wxFILTER_NONE</property>
- <property name="validator_type">wxDefaultValidator</property>
- <property name="validator_variable"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style"></property>
- <event name="OnButtonClick">OnButtonCopy</event>
- <event name="OnChar"></event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnKeyDown"></event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint"></event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnUpdateUI"></event>
- </object>
- </object>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxEXPAND</property>
- <property name="proportion">0</property>
- <object class="spacer" expanded="1">
- <property name="height">0</property>
- <property name="permission">protected</property>
- <property name="width">0</property>
- </object>
- </object>
- </object>
- </object>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxEXPAND</property>
- <property name="proportion">0</property>
- <object class="wxBoxSizer" expanded="1">
- <property name="minimum_size"></property>
- <property name="name">bSizer3</property>
- <property name="orient">wxHORIZONTAL</property>
- <property name="permission">none</property>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxEXPAND|wxALL</property>
- <property name="proportion">1</property>
- <object class="wxBoxSizer" expanded="1">
- <property name="minimum_size"></property>
- <property name="name">bSizer66</property>
- <property name="orient">wxHORIZONTAL</property>
- <property name="permission">none</property>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxLEFT</property>
- <property name="proportion">0</property>
- <object class="wxStaticText" expanded="1">
- <property name="bg"></property>
- <property name="context_help"></property>
- <property name="enabled">1</property>
- <property name="fg"></property>
- <property name="font"></property>
- <property name="hidden">0</property>
- <property name="id">wxID_ANY</property>
- <property name="label">Balance:</property>
- <property name="maximum_size"></property>
- <property name="minimum_size"></property>
- <property name="name">m_staticText41</property>
- <property name="permission">protected</property>
- <property name="pos"></property>
- <property name="size">-1,15</property>
- <property name="style"></property>
- <property name="subclass"></property>
- <property name="tooltip"></property>
- <property name="validator_data_type"></property>
- <property name="validator_style">wxFILTER_NONE</property>
- <property name="validator_type">wxDefaultValidator</property>
- <property name="validator_variable"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style"></property>
- <property name="wrap">-1</property>
- <event name="OnChar"></event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnKeyDown"></event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint"></event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnUpdateUI"></event>
- </object>
- </object>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxALIGN_CENTER_VERTICAL|wxALL</property>
- <property name="proportion">0</property>
- <object class="wxStaticText" expanded="1">
- <property name="bg">255,255,255</property>
- <property name="context_help"></property>
- <property name="enabled">1</property>
- <property name="fg"></property>
- <property name="font">,90,90,8,70,0</property>
- <property name="hidden">0</property>
- <property name="id">wxID_ANY</property>
- <property name="label"></property>
- <property name="maximum_size"></property>
- <property name="minimum_size"></property>
- <property name="name">m_staticTextBalance</property>
- <property name="permission">protected</property>
- <property name="pos"></property>
- <property name="size">120,15</property>
- <property name="style">wxALIGN_RIGHT|wxST_NO_AUTORESIZE</property>
- <property name="subclass"></property>
- <property name="tooltip"></property>
- <property name="validator_data_type"></property>
- <property name="validator_style">wxFILTER_NONE</property>
- <property name="validator_type">wxDefaultValidator</property>
- <property name="validator_variable"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style"></property>
- <property name="wrap">-1</property>
- <event name="OnChar"></event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnKeyDown"></event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint"></event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnUpdateUI"></event>
- </object>
- </object>
- </object>
- </object>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxEXPAND</property>
- <property name="proportion">0</property>
- <object class="spacer" expanded="1">
- <property name="height">0</property>
- <property name="permission">protected</property>
- <property name="width">0</property>
- </object>
- </object>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxALIGN_BOTTOM|wxTOP|wxRIGHT|wxLEFT</property>
- <property name="proportion">0</property>
- <object class="wxChoice" expanded="1">
- <property name="bg"></property>
- <property name="choices">" All" " Sent" " Received" " In Progress"</property>
- <property name="context_help"></property>
- <property name="enabled">1</property>
- <property name="fg"></property>
- <property name="font"></property>
- <property name="hidden">1</property>
- <property name="id">wxID_ANY</property>
- <property name="maximum_size"></property>
- <property name="minimum_size"></property>
- <property name="name">m_choiceFilter</property>
- <property name="permission">protected</property>
- <property name="pos"></property>
- <property name="selection">0</property>
- <property name="size">110,-1</property>
- <property name="subclass"></property>
- <property name="tooltip"></property>
- <property name="validator_data_type"></property>
- <property name="validator_style">wxFILTER_NONE</property>
- <property name="validator_type">wxDefaultValidator</property>
- <property name="validator_variable"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style"></property>
- <event name="OnChar"></event>
- <event name="OnChoice"></event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnKeyDown"></event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint"></event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnUpdateUI"></event>
- </object>
- </object>
- </object>
- </object>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxEXPAND</property>
- <property name="proportion">1</property>
- <object class="wxNotebook" expanded="1">
- <property name="bg"></property>
- <property name="bitmapsize"></property>
- <property name="context_help"></property>
- <property name="enabled">1</property>
- <property name="fg"></property>
- <property name="font"></property>
- <property name="hidden">0</property>
- <property name="id">wxID_ANY</property>
- <property name="maximum_size"></property>
- <property name="minimum_size"></property>
- <property name="name">m_notebook</property>
- <property name="permission">protected</property>
- <property name="pos"></property>
- <property name="size"></property>
- <property name="style"></property>
- <property name="subclass"></property>
- <property name="tooltip"></property>
- <property name="validator_data_type"></property>
- <property name="validator_style">wxFILTER_NONE</property>
- <property name="validator_type">wxDefaultValidator</property>
- <property name="validator_variable"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style"></property>
- <event name="OnChar"></event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnKeyDown"></event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnNotebookPageChanged">OnNotebookPageChanged</event>
- <event name="OnNotebookPageChanging"></event>
- <event name="OnPaint"></event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnUpdateUI"></event>
- <object class="notebookpage" expanded="1">
- <property name="bitmap"></property>
- <property name="label">All Transactions</property>
- <property name="select">1</property>
- <object class="wxPanel" expanded="1">
- <property name="bg"></property>
- <property name="context_help"></property>
- <property name="enabled">1</property>
- <property name="fg"></property>
- <property name="font"></property>
- <property name="hidden">0</property>
- <property name="id">wxID_ANY</property>
- <property name="maximum_size"></property>
- <property name="minimum_size"></property>
- <property name="name">m_panel9</property>
- <property name="permission">protected</property>
- <property name="pos"></property>
- <property name="size"></property>
- <property name="subclass"></property>
- <property name="tooltip"></property>
- <property name="validator_data_type"></property>
- <property name="validator_style">wxFILTER_NONE</property>
- <property name="validator_type">wxDefaultValidator</property>
- <property name="validator_variable"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style">wxTAB_TRAVERSAL</property>
- <event name="OnChar"></event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnKeyDown"></event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint"></event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnUpdateUI"></event>
- <object class="wxBoxSizer" expanded="1">
- <property name="minimum_size"></property>
- <property name="name">bSizer11</property>
- <property name="orient">wxVERTICAL</property>
- <property name="permission">none</property>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxEXPAND</property>
- <property name="proportion">1</property>
- <object class="wxListCtrl" expanded="1">
- <property name="bg"></property>
- <property name="context_help"></property>
- <property name="enabled">1</property>
- <property name="fg"></property>
- <property name="font"></property>
- <property name="hidden">0</property>
- <property name="id">wxID_ANY</property>
- <property name="maximum_size"></property>
- <property name="minimum_size"></property>
- <property name="name">m_listCtrlAll</property>
- <property name="permission">public</property>
- <property name="pos"></property>
- <property name="size"></property>
- <property name="style">wxLC_NO_SORT_HEADER|wxLC_REPORT|wxLC_SORT_DESCENDING</property>
- <property name="subclass"></property>
- <property name="tooltip"></property>
- <property name="validator_data_type"></property>
- <property name="validator_style">wxFILTER_NONE</property>
- <property name="validator_type">wxDefaultValidator</property>
- <property name="validator_variable"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style"></property>
- <event name="OnChar"></event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnKeyDown"></event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnListBeginDrag"></event>
- <event name="OnListBeginLabelEdit"></event>
- <event name="OnListBeginRDrag"></event>
- <event name="OnListCacheHint"></event>
- <event name="OnListColBeginDrag">OnListColBeginDrag</event>
- <event name="OnListColClick"></event>
- <event name="OnListColDragging"></event>
- <event name="OnListColEndDrag"></event>
- <event name="OnListColRightClick"></event>
- <event name="OnListDeleteAllItems"></event>
- <event name="OnListDeleteItem"></event>
- <event name="OnListEndLabelEdit"></event>
- <event name="OnListInsertItem"></event>
- <event name="OnListItemActivated">OnListItemActivated</event>
- <event name="OnListItemDeselected"></event>
- <event name="OnListItemFocused"></event>
- <event name="OnListItemMiddleClick"></event>
- <event name="OnListItemRightClick"></event>
- <event name="OnListItemSelected"></event>
- <event name="OnListKeyDown"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint">OnPaintListCtrl</event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnUpdateUI"></event>
- </object>
- </object>
- </object>
- </object>
- </object>
- <object class="notebookpage" expanded="1">
- <property name="bitmap"></property>
- <property name="label">Sent/Received</property>
- <property name="select">0</property>
- <object class="wxPanel" expanded="1">
- <property name="bg"></property>
- <property name="context_help"></property>
- <property name="enabled">1</property>
- <property name="fg"></property>
- <property name="font"></property>
- <property name="hidden">0</property>
- <property name="id">wxID_ANY</property>
- <property name="maximum_size"></property>
- <property name="minimum_size"></property>
- <property name="name">m_panel91</property>
- <property name="permission">protected</property>
- <property name="pos"></property>
- <property name="size"></property>
- <property name="subclass"></property>
- <property name="tooltip"></property>
- <property name="validator_data_type"></property>
- <property name="validator_style">wxFILTER_NONE</property>
- <property name="validator_type">wxDefaultValidator</property>
- <property name="validator_variable"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style">wxTAB_TRAVERSAL</property>
- <event name="OnChar"></event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnKeyDown"></event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint"></event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnUpdateUI"></event>
- <object class="wxBoxSizer" expanded="1">
- <property name="minimum_size"></property>
- <property name="name">bSizer111</property>
- <property name="orient">wxVERTICAL</property>
- <property name="permission">none</property>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxEXPAND</property>
- <property name="proportion">1</property>
- <object class="wxListCtrl" expanded="1">
- <property name="bg"></property>
- <property name="context_help"></property>
- <property name="enabled">1</property>
- <property name="fg"></property>
- <property name="font"></property>
- <property name="hidden">0</property>
- <property name="id">wxID_ANY</property>
- <property name="maximum_size"></property>
- <property name="minimum_size"></property>
- <property name="name">m_listCtrlSentReceived</property>
- <property name="permission">public</property>
- <property name="pos"></property>
- <property name="size"></property>
- <property name="style">wxLC_NO_SORT_HEADER|wxLC_REPORT|wxLC_SORT_DESCENDING</property>
- <property name="subclass"></property>
- <property name="tooltip"></property>
- <property name="validator_data_type"></property>
- <property name="validator_style">wxFILTER_NONE</property>
- <property name="validator_type">wxDefaultValidator</property>
- <property name="validator_variable"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style"></property>
- <event name="OnChar"></event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnKeyDown"></event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnListBeginDrag"></event>
- <event name="OnListBeginLabelEdit"></event>
- <event name="OnListBeginRDrag"></event>
- <event name="OnListCacheHint"></event>
- <event name="OnListColBeginDrag">OnListColBeginDrag</event>
- <event name="OnListColClick"></event>
- <event name="OnListColDragging"></event>
- <event name="OnListColEndDrag"></event>
- <event name="OnListColRightClick"></event>
- <event name="OnListDeleteAllItems"></event>
- <event name="OnListDeleteItem"></event>
- <event name="OnListEndLabelEdit"></event>
- <event name="OnListInsertItem"></event>
- <event name="OnListItemActivated">OnListItemActivated</event>
- <event name="OnListItemDeselected"></event>
- <event name="OnListItemFocused"></event>
- <event name="OnListItemMiddleClick"></event>
- <event name="OnListItemRightClick"></event>
- <event name="OnListItemSelected"></event>
- <event name="OnListKeyDown"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint">OnPaintListCtrl</event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnUpdateUI"></event>
- </object>
- </object>
- </object>
- </object>
- </object>
- <object class="notebookpage" expanded="1">
- <property name="bitmap"></property>
- <property name="label">Sent</property>
- <property name="select">0</property>
- <object class="wxPanel" expanded="1">
- <property name="bg"></property>
- <property name="context_help"></property>
- <property name="enabled">1</property>
- <property name="fg"></property>
- <property name="font"></property>
- <property name="hidden">0</property>
- <property name="id">wxID_ANY</property>
- <property name="maximum_size"></property>
- <property name="minimum_size"></property>
- <property name="name">m_panel92</property>
- <property name="permission">protected</property>
- <property name="pos"></property>
- <property name="size"></property>
- <property name="subclass"></property>
- <property name="tooltip"></property>
- <property name="validator_data_type"></property>
- <property name="validator_style">wxFILTER_NONE</property>
- <property name="validator_type">wxDefaultValidator</property>
- <property name="validator_variable"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style">wxTAB_TRAVERSAL</property>
- <event name="OnChar"></event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnKeyDown"></event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint"></event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnUpdateUI"></event>
- <object class="wxBoxSizer" expanded="1">
- <property name="minimum_size"></property>
- <property name="name">bSizer112</property>
- <property name="orient">wxVERTICAL</property>
- <property name="permission">none</property>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxEXPAND</property>
- <property name="proportion">1</property>
- <object class="wxListCtrl" expanded="1">
- <property name="bg"></property>
- <property name="context_help"></property>
- <property name="enabled">1</property>
- <property name="fg"></property>
- <property name="font"></property>
- <property name="hidden">0</property>
- <property name="id">wxID_ANY</property>
- <property name="maximum_size"></property>
- <property name="minimum_size"></property>
- <property name="name">m_listCtrlSent</property>
- <property name="permission">public</property>
- <property name="pos"></property>
- <property name="size"></property>
- <property name="style">wxLC_NO_SORT_HEADER|wxLC_REPORT|wxLC_SORT_DESCENDING</property>
- <property name="subclass"></property>
- <property name="tooltip"></property>
- <property name="validator_data_type"></property>
- <property name="validator_style">wxFILTER_NONE</property>
- <property name="validator_type">wxDefaultValidator</property>
- <property name="validator_variable"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style"></property>
- <event name="OnChar"></event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnKeyDown"></event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnListBeginDrag"></event>
- <event name="OnListBeginLabelEdit"></event>
- <event name="OnListBeginRDrag"></event>
- <event name="OnListCacheHint"></event>
- <event name="OnListColBeginDrag">OnListColBeginDrag</event>
- <event name="OnListColClick"></event>
- <event name="OnListColDragging"></event>
- <event name="OnListColEndDrag"></event>
- <event name="OnListColRightClick"></event>
- <event name="OnListDeleteAllItems"></event>
- <event name="OnListDeleteItem"></event>
- <event name="OnListEndLabelEdit"></event>
- <event name="OnListInsertItem"></event>
- <event name="OnListItemActivated">OnListItemActivated</event>
- <event name="OnListItemDeselected"></event>
- <event name="OnListItemFocused"></event>
- <event name="OnListItemMiddleClick"></event>
- <event name="OnListItemRightClick"></event>
- <event name="OnListItemSelected"></event>
- <event name="OnListKeyDown"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint">OnPaintListCtrl</event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnUpdateUI"></event>
- </object>
- </object>
- </object>
- </object>
- </object>
- <object class="notebookpage" expanded="1">
- <property name="bitmap"></property>
- <property name="label">Received</property>
- <property name="select">0</property>
- <object class="wxPanel" expanded="1">
- <property name="bg"></property>
- <property name="context_help"></property>
- <property name="enabled">1</property>
- <property name="fg"></property>
- <property name="font"></property>
- <property name="hidden">0</property>
- <property name="id">wxID_ANY</property>
- <property name="maximum_size"></property>
- <property name="minimum_size"></property>
- <property name="name">m_panel93</property>
- <property name="permission">protected</property>
- <property name="pos"></property>
- <property name="size"></property>
- <property name="subclass"></property>
- <property name="tooltip"></property>
- <property name="validator_data_type"></property>
- <property name="validator_style">wxFILTER_NONE</property>
- <property name="validator_type">wxDefaultValidator</property>
- <property name="validator_variable"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style">wxTAB_TRAVERSAL</property>
- <event name="OnChar"></event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnKeyDown"></event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint"></event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnUpdateUI"></event>
- <object class="wxBoxSizer" expanded="1">
- <property name="minimum_size"></property>
- <property name="name">bSizer113</property>
- <property name="orient">wxVERTICAL</property>
- <property name="permission">none</property>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxEXPAND</property>
- <property name="proportion">1</property>
- <object class="wxListCtrl" expanded="1">
- <property name="bg"></property>
- <property name="context_help"></property>
- <property name="enabled">1</property>
- <property name="fg"></property>
- <property name="font"></property>
- <property name="hidden">0</property>
- <property name="id">wxID_ANY</property>
- <property name="maximum_size"></property>
- <property name="minimum_size"></property>
- <property name="name">m_listCtrlReceived</property>
- <property name="permission">public</property>
- <property name="pos"></property>
- <property name="size"></property>
- <property name="style">wxLC_NO_SORT_HEADER|wxLC_REPORT|wxLC_SORT_DESCENDING</property>
- <property name="subclass"></property>
- <property name="tooltip"></property>
- <property name="validator_data_type"></property>
- <property name="validator_style">wxFILTER_NONE</property>
- <property name="validator_type">wxDefaultValidator</property>
- <property name="validator_variable"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style"></property>
- <event name="OnChar"></event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnKeyDown"></event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnListBeginDrag"></event>
- <event name="OnListBeginLabelEdit"></event>
- <event name="OnListBeginRDrag"></event>
- <event name="OnListCacheHint"></event>
- <event name="OnListColBeginDrag">OnListColBeginDrag</event>
- <event name="OnListColClick"></event>
- <event name="OnListColDragging"></event>
- <event name="OnListColEndDrag"></event>
- <event name="OnListColRightClick"></event>
- <event name="OnListDeleteAllItems"></event>
- <event name="OnListDeleteItem"></event>
- <event name="OnListEndLabelEdit"></event>
- <event name="OnListInsertItem"></event>
- <event name="OnListItemActivated">OnListItemActivated</event>
- <event name="OnListItemDeselected"></event>
- <event name="OnListItemFocused"></event>
- <event name="OnListItemMiddleClick"></event>
- <event name="OnListItemRightClick"></event>
- <event name="OnListItemSelected"></event>
- <event name="OnListKeyDown"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint">OnPaintListCtrl</event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnUpdateUI"></event>
- </object>
- </object>
- </object>
- </object>
- </object>
- </object>
- </object>
- </object>
- </object>
- <object class="Dialog" expanded="0">
- <property name="bg"></property>
- <property name="center"></property>
- <property name="context_help"></property>
- <property name="enabled">1</property>
- <property name="extra_style"></property>
- <property name="fg"></property>
- <property name="font"></property>
- <property name="hidden">0</property>
- <property name="id">wxID_ANY</property>
- <property name="maximum_size"></property>
- <property name="minimum_size"></property>
- <property name="name">CTxDetailsDialogBase</property>
- <property name="pos"></property>
- <property name="size">620,450</property>
- <property name="style">wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER</property>
- <property name="subclass"></property>
- <property name="title">Transaction Details</property>
- <property name="tooltip"></property>
- <property name="validator_data_type"></property>
- <property name="validator_style">wxFILTER_NONE</property>
- <property name="validator_type">wxDefaultValidator</property>
- <property name="validator_variable"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style"></property>
- <event name="OnActivate"></event>
- <event name="OnActivateApp"></event>
- <event name="OnChar"></event>
- <event name="OnClose"></event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnHibernate"></event>
- <event name="OnIconize"></event>
- <event name="OnIdle"></event>
- <event name="OnInitDialog"></event>
- <event name="OnKeyDown"></event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint"></event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnUpdateUI"></event>
- <object class="wxBoxSizer" expanded="1">
- <property name="minimum_size"></property>
- <property name="name">bSizer64</property>
- <property name="orient">wxVERTICAL</property>
- <property name="permission">none</property>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxEXPAND</property>
- <property name="proportion">1</property>
- <object class="wxBoxSizer" expanded="1">
- <property name="minimum_size"></property>
- <property name="name">bSizer66</property>
- <property name="orient">wxVERTICAL</property>
- <property name="permission">none</property>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxALL|wxEXPAND</property>
- <property name="proportion">1</property>
- <object class="wxHtmlWindow" expanded="1">
- <property name="bg"></property>
- <property name="context_help"></property>
- <property name="enabled">1</property>
- <property name="fg"></property>
- <property name="font"></property>
- <property name="hidden">0</property>
- <property name="id">wxID_ANY</property>
- <property name="maximum_size"></property>
- <property name="minimum_size"></property>
- <property name="name">m_htmlWin</property>
- <property name="permission">protected</property>
- <property name="pos"></property>
- <property name="size"></property>
- <property name="style">wxHW_SCROLLBAR_AUTO</property>
- <property name="subclass"></property>
- <property name="tooltip"></property>
- <property name="validator_data_type"></property>
- <property name="validator_style">wxFILTER_NONE</property>
- <property name="validator_type">wxDefaultValidator</property>
- <property name="validator_variable"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style"></property>
- <event name="OnChar"></event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnHtmlCellClicked"></event>
- <event name="OnHtmlCellHover"></event>
- <event name="OnHtmlLinkClicked"></event>
- <event name="OnKeyDown"></event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint"></event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnUpdateUI"></event>
- </object>
- </object>
- </object>
- </object>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxALIGN_RIGHT</property>
- <property name="proportion">0</property>
- <object class="wxBoxSizer" expanded="1">
- <property name="minimum_size"></property>
- <property name="name">bSizer65</property>
- <property name="orient">wxHORIZONTAL</property>
- <property name="permission">none</property>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND</property>
- <property name="proportion">0</property>
- <object class="wxButton" expanded="1">
- <property name="bg"></property>
- <property name="context_help"></property>
- <property name="default">0</property>
- <property name="enabled">1</property>
- <property name="fg"></property>
- <property name="font"></property>
- <property name="hidden">0</property>
- <property name="id">wxID_OK</property>
- <property name="label">OK</property>
- <property name="maximum_size"></property>
- <property name="minimum_size"></property>
- <property name="name">m_buttonOK</property>
- <property name="permission">protected</property>
- <property name="pos"></property>
- <property name="size">-1,-1</property>
- <property name="style"></property>
- <property name="subclass"></property>
- <property name="tooltip"></property>
- <property name="validator_data_type"></property>
- <property name="validator_style">wxFILTER_NONE</property>
- <property name="validator_type">wxDefaultValidator</property>
- <property name="validator_variable"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style"></property>
- <event name="OnButtonClick">OnButtonOK</event>
- <event name="OnChar"></event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnKeyDown"></event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint"></event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnUpdateUI"></event>
- </object>
- </object>
- </object>
- </object>
- </object>
- </object>
- <object class="Dialog" expanded="0">
- <property name="bg"></property>
- <property name="center"></property>
- <property name="context_help"></property>
- <property name="enabled">1</property>
- <property name="extra_style"></property>
- <property name="fg"></property>
- <property name="font"></property>
- <property name="hidden">0</property>
- <property name="id">wxID_ANY</property>
- <property name="maximum_size"></property>
- <property name="minimum_size"></property>
- <property name="name">COptionsDialogBase</property>
- <property name="pos"></property>
- <property name="size">540,360</property>
- <property name="style">wxDEFAULT_DIALOG_STYLE</property>
- <property name="subclass"></property>
- <property name="title">Options</property>
- <property name="tooltip"></property>
- <property name="validator_data_type"></property>
- <property name="validator_style">wxFILTER_NONE</property>
- <property name="validator_type">wxDefaultValidator</property>
- <property name="validator_variable"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style"></property>
- <event name="OnActivate"></event>
- <event name="OnActivateApp"></event>
- <event name="OnChar"></event>
- <event name="OnClose"></event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnHibernate"></event>
- <event name="OnIconize"></event>
- <event name="OnIdle"></event>
- <event name="OnInitDialog"></event>
- <event name="OnKeyDown"></event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint"></event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnUpdateUI"></event>
- <object class="wxBoxSizer" expanded="1">
- <property name="minimum_size"></property>
- <property name="name">bSizer55</property>
- <property name="orient">wxVERTICAL</property>
- <property name="permission">none</property>
- <object class="sizeritem" expanded="1">
- <property name="border">9</property>
- <property name="flag">wxEXPAND|wxALL</property>
- <property name="proportion">1</property>
- <object class="wxBoxSizer" expanded="1">
- <property name="minimum_size"></property>
- <property name="name">bSizer66</property>
- <property name="orient">wxHORIZONTAL</property>
- <property name="permission">none</property>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxEXPAND|wxRIGHT</property>
- <property name="proportion">0</property>
- <object class="wxListBox" expanded="1">
- <property name="bg"></property>
- <property name="choices"></property>
- <property name="context_help"></property>
- <property name="enabled">1</property>
- <property name="fg"></property>
- <property name="font"></property>
- <property name="hidden">0</property>
- <property name="id">wxID_ANY</property>
- <property name="maximum_size"></property>
- <property name="minimum_size"></property>
- <property name="name">m_listBox</property>
- <property name="permission">protected</property>
- <property name="pos"></property>
- <property name="size">110,-1</property>
- <property name="style">wxLB_NEEDED_SB|wxLB_SINGLE</property>
- <property name="subclass"></property>
- <property name="tooltip"></property>
- <property name="validator_data_type"></property>
- <property name="validator_style">wxFILTER_NONE</property>
- <property name="validator_type">wxDefaultValidator</property>
- <property name="validator_variable"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style"></property>
- <event name="OnChar"></event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnKeyDown"></event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnListBox">OnListBox</event>
- <event name="OnListBoxDClick"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint"></event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnUpdateUI"></event>
- </object>
- </object>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxEXPAND|wxLEFT</property>
- <property name="proportion">1</property>
- <object class="wxScrolledWindow" expanded="1">
- <property name="bg"></property>
- <property name="context_help"></property>
- <property name="enabled">1</property>
- <property name="fg"></property>
- <property name="font"></property>
- <property name="hidden">0</property>
- <property name="id">wxID_ANY</property>
- <property name="maximum_size"></property>
- <property name="minimum_size"></property>
- <property name="name">m_scrolledWindow</property>
- <property name="permission">protected</property>
- <property name="pos"></property>
- <property name="scroll_rate_x">5</property>
- <property name="scroll_rate_y">5</property>
- <property name="size"></property>
- <property name="subclass"></property>
- <property name="tooltip"></property>
- <property name="validator_data_type"></property>
- <property name="validator_style">wxFILTER_NONE</property>
- <property name="validator_type">wxDefaultValidator</property>
- <property name="validator_variable"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style"></property>
- <event name="OnChar"></event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnKeyDown"></event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint"></event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnUpdateUI"></event>
- <object class="wxBoxSizer" expanded="1">
- <property name="minimum_size"></property>
- <property name="name">bSizer63</property>
- <property name="orient">wxVERTICAL</property>
- <property name="permission">none</property>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxEXPAND</property>
- <property name="proportion">0</property>
- <object class="wxPanel" expanded="1">
- <property name="bg"></property>
- <property name="context_help"></property>
- <property name="enabled">1</property>
- <property name="fg"></property>
- <property name="font"></property>
- <property name="hidden">0</property>
- <property name="id">wxID_ANY</property>
- <property name="maximum_size"></property>
- <property name="minimum_size"></property>
- <property name="name">m_panelMain</property>
- <property name="permission">protected</property>
- <property name="pos"></property>
- <property name="size"></property>
- <property name="subclass"></property>
- <property name="tooltip"></property>
- <property name="validator_data_type"></property>
- <property name="validator_style">wxFILTER_NONE</property>
- <property name="validator_type">wxDefaultValidator</property>
- <property name="validator_variable"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style">wxTAB_TRAVERSAL</property>
- <event name="OnChar"></event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnKeyDown"></event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint"></event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnUpdateUI"></event>
- <object class="wxBoxSizer" expanded="1">
- <property name="minimum_size"></property>
- <property name="name">bSizer69</property>
- <property name="orient">wxVERTICAL</property>
- <property name="permission">none</property>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxEXPAND</property>
- <property name="proportion">0</property>
- <object class="spacer" expanded="1">
- <property name="height">16</property>
- <property name="permission">protected</property>
- <property name="width">0</property>
- </object>
- </object>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxALL</property>
- <property name="proportion">0</property>
- <object class="wxCheckBox" expanded="1">
- <property name="bg"></property>
- <property name="checked">0</property>
- <property name="context_help"></property>
- <property name="enabled">1</property>
- <property name="fg"></property>
- <property name="font"></property>
- <property name="hidden">0</property>
- <property name="id">wxID_ANY</property>
- <property name="label">&Start Bitcoin on system startup</property>
- <property name="maximum_size"></property>
- <property name="minimum_size"></property>
- <property name="name">m_checkBoxStartOnSystemStartup</property>
- <property name="permission">protected</property>
- <property name="pos"></property>
- <property name="size"></property>
- <property name="style"></property>
- <property name="subclass"></property>
- <property name="tooltip"></property>
- <property name="validator_data_type"></property>
- <property name="validator_style">wxFILTER_NONE</property>
- <property name="validator_type">wxDefaultValidator</property>
- <property name="validator_variable"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style"></property>
- <event name="OnChar"></event>
- <event name="OnCheckBox"></event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnKeyDown"></event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint"></event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnUpdateUI"></event>
- </object>
- </object>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxALL</property>
- <property name="proportion">0</property>
- <object class="wxCheckBox" expanded="1">
- <property name="bg"></property>
- <property name="checked">0</property>
- <property name="context_help"></property>
- <property name="enabled">1</property>
- <property name="fg"></property>
- <property name="font"></property>
- <property name="hidden">0</property>
- <property name="id">wxID_ANY</property>
- <property name="label">&Minimize to the tray instead of the taskbar</property>
- <property name="maximum_size"></property>
- <property name="minimum_size"></property>
- <property name="name">m_checkBoxMinimizeToTray</property>
- <property name="permission">protected</property>
- <property name="pos"></property>
- <property name="size"></property>
- <property name="style"></property>
- <property name="subclass"></property>
- <property name="tooltip"></property>
- <property name="validator_data_type"></property>
- <property name="validator_style">wxFILTER_NONE</property>
- <property name="validator_type">wxDefaultValidator</property>
- <property name="validator_variable"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style"></property>
- <event name="OnChar"></event>
- <event name="OnCheckBox">OnCheckBoxMinimizeToTray</event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnKeyDown"></event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint"></event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnUpdateUI"></event>
- </object>
- </object>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxALL</property>
- <property name="proportion">0</property>
- <object class="wxCheckBox" expanded="1">
- <property name="bg"></property>
- <property name="checked">0</property>
- <property name="context_help"></property>
- <property name="enabled">1</property>
- <property name="fg"></property>
- <property name="font"></property>
- <property name="hidden">0</property>
- <property name="id">wxID_ANY</property>
- <property name="label">Map port using &UPnP</property>
- <property name="maximum_size"></property>
- <property name="minimum_size"></property>
- <property name="name">m_checkBoxUseUPnP</property>
- <property name="permission">protected</property>
- <property name="pos"></property>
- <property name="size"></property>
- <property name="style"></property>
- <property name="subclass"></property>
- <property name="tooltip"></property>
- <property name="validator_data_type"></property>
- <property name="validator_style">wxFILTER_NONE</property>
- <property name="validator_type">wxDefaultValidator</property>
- <property name="validator_variable"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style"></property>
- <event name="OnChar"></event>
- <event name="OnCheckBox"></event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnKeyDown"></event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint"></event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnUpdateUI"></event>
- </object>
- </object>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxALL|wxALIGN_CENTER_VERTICAL</property>
- <property name="proportion">0</property>
- <object class="wxCheckBox" expanded="1">
- <property name="bg"></property>
- <property name="checked">0</property>
- <property name="context_help"></property>
- <property name="enabled">1</property>
- <property name="fg"></property>
- <property name="font"></property>
- <property name="hidden">0</property>
- <property name="id">wxID_ANY</property>
- <property name="label">M&inimize to the tray on close</property>
- <property name="maximum_size"></property>
- <property name="minimum_size"></property>
- <property name="name">m_checkBoxMinimizeOnClose</property>
- <property name="permission">protected</property>
- <property name="pos"></property>
- <property name="size"></property>
- <property name="style"></property>
- <property name="subclass"></property>
- <property name="tooltip"></property>
- <property name="validator_data_type"></property>
- <property name="validator_style">wxFILTER_NONE</property>
- <property name="validator_type">wxDefaultValidator</property>
- <property name="validator_variable"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style"></property>
- <event name="OnChar"></event>
- <event name="OnCheckBox"></event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnKeyDown"></event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint"></event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnUpdateUI"></event>
- </object>
- </object>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxEXPAND</property>
- <property name="proportion">1</property>
- <object class="wxBoxSizer" expanded="1">
- <property name="minimum_size"></property>
- <property name="name">bSizer102</property>
- <property name="orient">wxHORIZONTAL</property>
- <property name="permission">none</property>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxALL|wxALIGN_CENTER_VERTICAL</property>
- <property name="proportion">0</property>
- <object class="wxCheckBox" expanded="1">
- <property name="bg"></property>
- <property name="checked">0</property>
- <property name="context_help"></property>
- <property name="enabled">1</property>
- <property name="fg"></property>
- <property name="font"></property>
- <property name="hidden">0</property>
- <property name="id">wxID_ANY</property>
- <property name="label">&Connect through socks4 proxy: </property>
- <property name="maximum_size"></property>
- <property name="minimum_size"></property>
- <property name="name">m_checkBoxUseProxy</property>
- <property name="permission">protected</property>
- <property name="pos"></property>
- <property name="size"></property>
- <property name="style"></property>
- <property name="subclass"></property>
- <property name="tooltip"></property>
- <property name="validator_data_type"></property>
- <property name="validator_style">wxFILTER_NONE</property>
- <property name="validator_type">wxDefaultValidator</property>
- <property name="validator_variable"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style"></property>
- <event name="OnChar"></event>
- <event name="OnCheckBox">OnCheckBoxUseProxy</event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnKeyDown"></event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint"></event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnUpdateUI"></event>
- </object>
- </object>
- </object>
- </object>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxEXPAND</property>
- <property name="proportion">1</property>
- <object class="wxBoxSizer" expanded="1">
- <property name="minimum_size"></property>
- <property name="name">bSizer103</property>
- <property name="orient">wxHORIZONTAL</property>
- <property name="permission">none</property>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag"></property>
- <property name="proportion">0</property>
- <object class="spacer" expanded="1">
- <property name="height">0</property>
- <property name="permission">protected</property>
- <property name="width">18</property>
- </object>
- </object>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxALL|wxALIGN_CENTER_VERTICAL</property>
- <property name="proportion">0</property>
- <object class="wxStaticText" expanded="1">
- <property name="bg"></property>
- <property name="context_help"></property>
- <property name="enabled">1</property>
- <property name="fg"></property>
- <property name="font"></property>
- <property name="hidden">0</property>
- <property name="id">wxID_ANY</property>
- <property name="label">Proxy &IP:</property>
- <property name="maximum_size"></property>
- <property name="minimum_size"></property>
- <property name="name">m_staticTextProxyIP</property>
- <property name="permission">protected</property>
- <property name="pos"></property>
- <property name="size"></property>
- <property name="style"></property>
- <property name="subclass"></property>
- <property name="tooltip"></property>
- <property name="validator_data_type"></property>
- <property name="validator_style">wxFILTER_NONE</property>
- <property name="validator_type">wxDefaultValidator</property>
- <property name="validator_variable"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style"></property>
- <property name="wrap">-1</property>
- <event name="OnChar"></event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnKeyDown"></event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint"></event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnUpdateUI"></event>
- </object>
- </object>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxALIGN_CENTER_VERTICAL</property>
- <property name="proportion">0</property>
- <object class="wxTextCtrl" expanded="1">
- <property name="bg"></property>
- <property name="context_help"></property>
- <property name="enabled">1</property>
- <property name="fg"></property>
- <property name="font"></property>
- <property name="hidden">0</property>
- <property name="id">wxID_PROXYIP</property>
- <property name="maximum_size"></property>
- <property name="maxlength">15</property>
- <property name="minimum_size"></property>
- <property name="name">m_textCtrlProxyIP</property>
- <property name="permission">protected</property>
- <property name="pos"></property>
- <property name="size">140,-1</property>
- <property name="style"></property>
- <property name="subclass"></property>
- <property name="tooltip"></property>
- <property name="validator_data_type"></property>
- <property name="validator_style">wxFILTER_NONE</property>
- <property name="validator_type">wxDefaultValidator</property>
- <property name="validator_variable"></property>
- <property name="value"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style"></property>
- <event name="OnChar"></event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnKeyDown"></event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus">OnKillFocusProxy</event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint"></event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnText"></event>
- <event name="OnTextEnter"></event>
- <event name="OnTextMaxLen"></event>
- <event name="OnTextURL"></event>
- <event name="OnUpdateUI"></event>
- </object>
- </object>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxALL|wxALIGN_CENTER_VERTICAL</property>
- <property name="proportion">0</property>
- <object class="wxStaticText" expanded="1">
- <property name="bg"></property>
- <property name="context_help"></property>
- <property name="enabled">1</property>
- <property name="fg"></property>
- <property name="font"></property>
- <property name="hidden">0</property>
- <property name="id">wxID_ANY</property>
- <property name="label"> &Port:</property>
- <property name="maximum_size"></property>
- <property name="minimum_size"></property>
- <property name="name">m_staticTextProxyPort</property>
- <property name="permission">protected</property>
- <property name="pos"></property>
- <property name="size"></property>
- <property name="style"></property>
- <property name="subclass"></property>
- <property name="tooltip"></property>
- <property name="validator_data_type"></property>
- <property name="validator_style">wxFILTER_NONE</property>
- <property name="validator_type">wxDefaultValidator</property>
- <property name="validator_variable"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style"></property>
- <property name="wrap">-1</property>
- <event name="OnChar"></event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnKeyDown"></event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint"></event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnUpdateUI"></event>
- </object>
- </object>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxALIGN_CENTER_VERTICAL</property>
- <property name="proportion">0</property>
- <object class="wxTextCtrl" expanded="1">
- <property name="bg"></property>
- <property name="context_help"></property>
- <property name="enabled">1</property>
- <property name="fg"></property>
- <property name="font"></property>
- <property name="hidden">0</property>
- <property name="id">wxID_PROXYPORT</property>
- <property name="maximum_size"></property>
- <property name="maxlength">5</property>
- <property name="minimum_size"></property>
- <property name="name">m_textCtrlProxyPort</property>
- <property name="permission">protected</property>
- <property name="pos"></property>
- <property name="size">55,-1</property>
- <property name="style"></property>
- <property name="subclass"></property>
- <property name="tooltip"></property>
- <property name="validator_data_type"></property>
- <property name="validator_style">wxFILTER_NONE</property>
- <property name="validator_type">wxDefaultValidator</property>
- <property name="validator_variable"></property>
- <property name="value"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style"></property>
- <event name="OnChar"></event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnKeyDown"></event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus">OnKillFocusProxy</event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint"></event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnText"></event>
- <event name="OnTextEnter"></event>
- <event name="OnTextMaxLen"></event>
- <event name="OnTextURL"></event>
- <event name="OnUpdateUI"></event>
- </object>
- </object>
- </object>
- </object>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag"></property>
- <property name="proportion">0</property>
- <object class="spacer" expanded="1">
- <property name="height">1</property>
- <property name="permission">protected</property>
- <property name="width">0</property>
- </object>
- </object>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxALIGN_CENTER_VERTICAL|wxTOP|wxRIGHT|wxLEFT</property>
- <property name="proportion">0</property>
- <object class="wxStaticText" expanded="1">
- <property name="bg"></property>
- <property name="context_help"></property>
- <property name="enabled">1</property>
- <property name="fg"></property>
- <property name="font"></property>
- <property name="hidden">0</property>
- <property name="id">wxID_ANY</property>
- <property name="label">Optional transaction fee per KB that helps make sure your transactions are processed quickly. Most transactions are 1KB. Fee 0.01 recommended.</property>
- <property name="maximum_size"></property>
- <property name="minimum_size"></property>
- <property name="name">m_staticText32</property>
- <property name="permission">protected</property>
- <property name="pos"></property>
- <property name="size"></property>
- <property name="style"></property>
- <property name="subclass"></property>
- <property name="tooltip"></property>
- <property name="validator_data_type"></property>
- <property name="validator_style">wxFILTER_NONE</property>
- <property name="validator_type">wxDefaultValidator</property>
- <property name="validator_variable"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style"></property>
- <property name="wrap">365</property>
- <event name="OnChar"></event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnKeyDown"></event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint"></event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnUpdateUI"></event>
- </object>
- </object>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxEXPAND</property>
- <property name="proportion">0</property>
- <object class="wxBoxSizer" expanded="1">
- <property name="minimum_size"></property>
- <property name="name">bSizer56</property>
- <property name="orient">wxHORIZONTAL</property>
- <property name="permission">none</property>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxLEFT</property>
- <property name="proportion">0</property>
- <object class="wxStaticText" expanded="1">
- <property name="bg"></property>
- <property name="context_help"></property>
- <property name="enabled">1</property>
- <property name="fg"></property>
- <property name="font"></property>
- <property name="hidden">0</property>
- <property name="id">wxID_ANY</property>
- <property name="label">Pay transaction fee:</property>
- <property name="maximum_size"></property>
- <property name="minimum_size"></property>
- <property name="name">m_staticText31</property>
- <property name="permission">protected</property>
- <property name="pos"></property>
- <property name="size"></property>
- <property name="style"></property>
- <property name="subclass"></property>
- <property name="tooltip"></property>
- <property name="validator_data_type"></property>
- <property name="validator_style">wxFILTER_NONE</property>
- <property name="validator_type">wxDefaultValidator</property>
- <property name="validator_variable"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style"></property>
- <property name="wrap">-1</property>
- <event name="OnChar"></event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnKeyDown"></event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint"></event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnUpdateUI"></event>
- </object>
- </object>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxALIGN_CENTER_VERTICAL|wxALL</property>
- <property name="proportion">0</property>
- <object class="wxTextCtrl" expanded="1">
- <property name="bg"></property>
- <property name="context_help"></property>
- <property name="enabled">1</property>
- <property name="fg"></property>
- <property name="font"></property>
- <property name="hidden">0</property>
- <property name="id">wxID_TRANSACTIONFEE</property>
- <property name="maximum_size"></property>
- <property name="maxlength">0</property>
- <property name="minimum_size"></property>
- <property name="name">m_textCtrlTransactionFee</property>
- <property name="permission">protected</property>
- <property name="pos"></property>
- <property name="size">70,-1</property>
- <property name="style"></property>
- <property name="subclass"></property>
- <property name="tooltip"></property>
- <property name="validator_data_type"></property>
- <property name="validator_style">wxFILTER_NONE</property>
- <property name="validator_type">wxDefaultValidator</property>
- <property name="validator_variable"></property>
- <property name="value"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style"></property>
- <event name="OnChar"></event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnKeyDown"></event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus">OnKillFocusTransactionFee</event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint"></event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnText"></event>
- <event name="OnTextEnter"></event>
- <event name="OnTextMaxLen"></event>
- <event name="OnTextURL"></event>
- <event name="OnUpdateUI"></event>
- </object>
- </object>
- </object>
- </object>
- </object>
- </object>
- </object>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxEXPAND</property>
- <property name="proportion">0</property>
- <object class="wxPanel" expanded="1">
- <property name="bg"></property>
- <property name="context_help"></property>
- <property name="enabled">1</property>
- <property name="fg"></property>
- <property name="font"></property>
- <property name="hidden">0</property>
- <property name="id">wxID_ANY</property>
- <property name="maximum_size"></property>
- <property name="minimum_size"></property>
- <property name="name">m_panelTest2</property>
- <property name="permission">protected</property>
- <property name="pos"></property>
- <property name="size"></property>
- <property name="subclass"></property>
- <property name="tooltip"></property>
- <property name="validator_data_type"></property>
- <property name="validator_style">wxFILTER_NONE</property>
- <property name="validator_type">wxDefaultValidator</property>
- <property name="validator_variable"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style">wxTAB_TRAVERSAL</property>
- <event name="OnChar"></event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnKeyDown"></event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint"></event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnUpdateUI"></event>
- <object class="wxBoxSizer" expanded="1">
- <property name="minimum_size"></property>
- <property name="name">bSizer64</property>
- <property name="orient">wxVERTICAL</property>
- <property name="permission">none</property>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxEXPAND</property>
- <property name="proportion">0</property>
- <object class="spacer" expanded="1">
- <property name="height">16</property>
- <property name="permission">protected</property>
- <property name="width">0</property>
- </object>
- </object>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxALIGN_CENTER_VERTICAL|wxALL</property>
- <property name="proportion">0</property>
- <object class="wxStaticText" expanded="1">
- <property name="bg"></property>
- <property name="context_help"></property>
- <property name="enabled">1</property>
- <property name="fg"></property>
- <property name="font"></property>
- <property name="hidden">0</property>
- <property name="id">wxID_ANY</property>
- <property name="label">// [don't translate] Test panel 2 for future expansion</property>
- <property name="maximum_size"></property>
- <property name="minimum_size"></property>
- <property name="name">m_staticText321</property>
- <property name="permission">protected</property>
- <property name="pos"></property>
- <property name="size"></property>
- <property name="style"></property>
- <property name="subclass"></property>
- <property name="tooltip"></property>
- <property name="validator_data_type"></property>
- <property name="validator_style">wxFILTER_NONE</property>
- <property name="validator_type">wxDefaultValidator</property>
- <property name="validator_variable"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style"></property>
- <property name="wrap">-1</property>
- <event name="OnChar"></event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnKeyDown"></event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint"></event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnUpdateUI"></event>
- </object>
- </object>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxALL</property>
- <property name="proportion">0</property>
- <object class="wxStaticText" expanded="1">
- <property name="bg"></property>
- <property name="context_help"></property>
- <property name="enabled">1</property>
- <property name="fg"></property>
- <property name="font"></property>
- <property name="hidden">0</property>
- <property name="id">wxID_ANY</property>
- <property name="label">// [don't translate] Let's not start multiple pages until the first page is filled up</property>
- <property name="maximum_size"></property>
- <property name="minimum_size"></property>
- <property name="name">m_staticText69</property>
- <property name="permission">protected</property>
- <property name="pos"></property>
- <property name="size"></property>
- <property name="style"></property>
- <property name="subclass"></property>
- <property name="tooltip"></property>
- <property name="validator_data_type"></property>
- <property name="validator_style">wxFILTER_NONE</property>
- <property name="validator_type">wxDefaultValidator</property>
- <property name="validator_variable"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style"></property>
- <property name="wrap">-1</property>
- <event name="OnChar"></event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnKeyDown"></event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint"></event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnUpdateUI"></event>
- </object>
- </object>
- </object>
- </object>
- </object>
- </object>
- </object>
- </object>
- </object>
- </object>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxALIGN_RIGHT</property>
- <property name="proportion">0</property>
- <object class="wxBoxSizer" expanded="1">
- <property name="minimum_size"></property>
- <property name="name">bSizer58</property>
- <property name="orient">wxHORIZONTAL</property>
- <property name="permission">none</property>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND</property>
- <property name="proportion">0</property>
- <object class="wxButton" expanded="1">
- <property name="bg"></property>
- <property name="context_help"></property>
- <property name="default">0</property>
- <property name="enabled">1</property>
- <property name="fg"></property>
- <property name="font"></property>
- <property name="hidden">0</property>
- <property name="id">wxID_OK</property>
- <property name="label">OK</property>
- <property name="maximum_size"></property>
- <property name="minimum_size"></property>
- <property name="name">m_buttonOK</property>
- <property name="permission">protected</property>
- <property name="pos"></property>
- <property name="size">-1,-1</property>
- <property name="style"></property>
- <property name="subclass"></property>
- <property name="tooltip"></property>
- <property name="validator_data_type"></property>
- <property name="validator_style">wxFILTER_NONE</property>
- <property name="validator_type">wxDefaultValidator</property>
- <property name="validator_variable"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style"></property>
- <event name="OnButtonClick">OnButtonOK</event>
- <event name="OnChar"></event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnKeyDown"></event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint"></event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnUpdateUI"></event>
- </object>
- </object>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND</property>
- <property name="proportion">0</property>
- <object class="wxButton" expanded="1">
- <property name="bg"></property>
- <property name="context_help"></property>
- <property name="default">0</property>
- <property name="enabled">1</property>
- <property name="fg"></property>
- <property name="font"></property>
- <property name="hidden">0</property>
- <property name="id">wxID_CANCEL</property>
- <property name="label">Cancel</property>
- <property name="maximum_size"></property>
- <property name="minimum_size">-1,-1</property>
- <property name="name">m_buttonCancel</property>
- <property name="permission">protected</property>
- <property name="pos"></property>
- <property name="size">-1,-1</property>
- <property name="style"></property>
- <property name="subclass"></property>
- <property name="tooltip"></property>
- <property name="validator_data_type"></property>
- <property name="validator_style">wxFILTER_NONE</property>
- <property name="validator_type">wxDefaultValidator</property>
- <property name="validator_variable"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style"></property>
- <event name="OnButtonClick">OnButtonCancel</event>
- <event name="OnChar"></event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnKeyDown"></event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint"></event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnUpdateUI"></event>
- </object>
- </object>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND</property>
- <property name="proportion">0</property>
- <object class="wxButton" expanded="1">
- <property name="bg"></property>
- <property name="context_help"></property>
- <property name="default">0</property>
- <property name="enabled">1</property>
- <property name="fg"></property>
- <property name="font"></property>
- <property name="hidden">0</property>
- <property name="id">wxID_APPLY</property>
- <property name="label">&Apply</property>
- <property name="maximum_size"></property>
- <property name="minimum_size">-1,-1</property>
- <property name="name">m_buttonApply</property>
- <property name="permission">protected</property>
- <property name="pos"></property>
- <property name="size">-1,-1</property>
- <property name="style"></property>
- <property name="subclass"></property>
- <property name="tooltip"></property>
- <property name="validator_data_type"></property>
- <property name="validator_style">wxFILTER_NONE</property>
- <property name="validator_type">wxDefaultValidator</property>
- <property name="validator_variable"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style"></property>
- <event name="OnButtonClick">OnButtonApply</event>
- <event name="OnChar"></event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnKeyDown"></event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint"></event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnUpdateUI"></event>
- </object>
- </object>
- </object>
- </object>
- </object>
- </object>
- <object class="Dialog" expanded="0">
- <property name="bg"></property>
- <property name="center"></property>
- <property name="context_help"></property>
- <property name="enabled">1</property>
- <property name="extra_style"></property>
- <property name="fg"></property>
- <property name="font"></property>
- <property name="hidden">0</property>
- <property name="id">wxID_ANY</property>
- <property name="maximum_size"></property>
- <property name="minimum_size"></property>
- <property name="name">CAboutDialogBase</property>
- <property name="pos"></property>
- <property name="size">532,333</property>
- <property name="style">wxDEFAULT_DIALOG_STYLE</property>
- <property name="subclass"></property>
- <property name="title">About Bitcoin</property>
- <property name="tooltip"></property>
- <property name="validator_data_type"></property>
- <property name="validator_style">wxFILTER_NONE</property>
- <property name="validator_type">wxDefaultValidator</property>
- <property name="validator_variable"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style"></property>
- <event name="OnActivate"></event>
- <event name="OnActivateApp"></event>
- <event name="OnChar"></event>
- <event name="OnClose"></event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnHibernate"></event>
- <event name="OnIconize"></event>
- <event name="OnIdle"></event>
- <event name="OnInitDialog"></event>
- <event name="OnKeyDown"></event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint"></event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnUpdateUI"></event>
- <object class="wxBoxSizer" expanded="1">
- <property name="minimum_size"></property>
- <property name="name">bSizer63</property>
- <property name="orient">wxHORIZONTAL</property>
- <property name="permission">none</property>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag"></property>
- <property name="proportion">0</property>
- <object class="wxStaticBitmap" expanded="1">
- <property name="bg"></property>
- <property name="bitmap">xpm/about.xpm; Load From File</property>
- <property name="context_help"></property>
- <property name="enabled">1</property>
- <property name="fg"></property>
- <property name="font"></property>
- <property name="hidden">0</property>
- <property name="id">wxID_ANY</property>
- <property name="maximum_size"></property>
- <property name="minimum_size"></property>
- <property name="name">m_bitmap</property>
- <property name="permission">protected</property>
- <property name="pos"></property>
- <property name="size"></property>
- <property name="subclass"></property>
- <property name="tooltip"></property>
- <property name="validator_data_type"></property>
- <property name="validator_style">wxFILTER_NONE</property>
- <property name="validator_type">wxDefaultValidator</property>
- <property name="validator_variable"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style"></property>
- <event name="OnChar"></event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnKeyDown"></event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint"></event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnUpdateUI"></event>
- </object>
- </object>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxEXPAND|wxLEFT</property>
- <property name="proportion">1</property>
- <object class="wxBoxSizer" expanded="1">
- <property name="minimum_size"></property>
- <property name="name">bSizer60</property>
- <property name="orient">wxVERTICAL</property>
- <property name="permission">none</property>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxEXPAND</property>
- <property name="proportion">1</property>
- <object class="wxBoxSizer" expanded="1">
- <property name="minimum_size"></property>
- <property name="name">bSizer62</property>
- <property name="orient">wxHORIZONTAL</property>
- <property name="permission">none</property>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxEXPAND</property>
- <property name="proportion">1</property>
- <object class="wxBoxSizer" expanded="1">
- <property name="minimum_size"></property>
- <property name="name">bSizer631</property>
- <property name="orient">wxVERTICAL</property>
- <property name="permission">none</property>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxEXPAND</property>
- <property name="proportion">0</property>
- <object class="spacer" expanded="1">
- <property name="height">65</property>
- <property name="permission">protected</property>
- <property name="width">0</property>
- </object>
- </object>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxEXPAND</property>
- <property name="proportion">0</property>
- <object class="wxBoxSizer" expanded="1">
- <property name="minimum_size"></property>
- <property name="name">bSizer64</property>
- <property name="orient">wxHORIZONTAL</property>
- <property name="permission">none</property>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxALIGN_BOTTOM|wxTOP|wxBOTTOM|wxLEFT</property>
- <property name="proportion">0</property>
- <object class="wxStaticText" expanded="1">
- <property name="bg"></property>
- <property name="context_help"></property>
- <property name="enabled">1</property>
- <property name="fg"></property>
- <property name="font">Tahoma,90,92,10,74,0</property>
- <property name="hidden">0</property>
- <property name="id">wxID_ANY</property>
- <property name="label">Bitcoin </property>
- <property name="maximum_size"></property>
- <property name="minimum_size"></property>
- <property name="name">m_staticText40</property>
- <property name="permission">protected</property>
- <property name="pos"></property>
- <property name="size"></property>
- <property name="style"></property>
- <property name="subclass"></property>
- <property name="tooltip"></property>
- <property name="validator_data_type"></property>
- <property name="validator_style">wxFILTER_NONE</property>
- <property name="validator_type">wxDefaultValidator</property>
- <property name="validator_variable"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style"></property>
- <property name="wrap">-1</property>
- <event name="OnChar"></event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnKeyDown"></event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint"></event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnUpdateUI"></event>
- </object>
- </object>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxALIGN_BOTTOM|wxTOP|wxBOTTOM|wxRIGHT</property>
- <property name="proportion">0</property>
- <object class="wxStaticText" expanded="1">
- <property name="bg"></property>
- <property name="context_help"></property>
- <property name="enabled">1</property>
- <property name="fg"></property>
- <property name="font">Tahoma,90,90,10,74,0</property>
- <property name="hidden">0</property>
- <property name="id">wxID_ANY</property>
- <property name="label">version</property>
- <property name="maximum_size"></property>
- <property name="minimum_size"></property>
- <property name="name">m_staticTextVersion</property>
- <property name="permission">public</property>
- <property name="pos"></property>
- <property name="size"></property>
- <property name="style"></property>
- <property name="subclass"></property>
- <property name="tooltip"></property>
- <property name="validator_data_type"></property>
- <property name="validator_style">wxFILTER_NONE</property>
- <property name="validator_type">wxDefaultValidator</property>
- <property name="validator_variable"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style"></property>
- <property name="wrap">-1</property>
- <event name="OnChar"></event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnKeyDown"></event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint"></event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnUpdateUI"></event>
- </object>
- </object>
- </object>
- </object>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxEXPAND</property>
- <property name="proportion">0</property>
- <object class="spacer" expanded="1">
- <property name="height">4</property>
- <property name="permission">protected</property>
- <property name="width">0</property>
- </object>
- </object>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxALL</property>
- <property name="proportion">0</property>
- <object class="wxStaticText" expanded="1">
- <property name="bg"></property>
- <property name="context_help"></property>
- <property name="enabled">1</property>
- <property name="fg"></property>
- <property name="font"></property>
- <property name="hidden">0</property>
- <property name="id">wxID_ANY</property>
- <property name="label">Copyright (c) 2009-2011 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.</property>
- <property name="maximum_size"></property>
- <property name="minimum_size"></property>
- <property name="name">m_staticTextMain</property>
- <property name="permission">protected</property>
- <property name="pos"></property>
- <property name="size"></property>
- <property name="style"></property>
- <property name="subclass"></property>
- <property name="tooltip"></property>
- <property name="validator_data_type"></property>
- <property name="validator_style">wxFILTER_NONE</property>
- <property name="validator_type">wxDefaultValidator</property>
- <property name="validator_variable"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style"></property>
- <property name="wrap">-1</property>
- <event name="OnChar"></event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnKeyDown"></event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint"></event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnUpdateUI"></event>
- </object>
- </object>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxEXPAND</property>
- <property name="proportion">0</property>
- <object class="spacer" expanded="1">
- <property name="height">0</property>
- <property name="permission">protected</property>
- <property name="width">0</property>
- </object>
- </object>
- </object>
- </object>
- </object>
- </object>
- <object class="sizeritem" expanded="1">
- <property name="border">2</property>
- <property name="flag">wxALIGN_RIGHT|wxEXPAND|wxRIGHT</property>
- <property name="proportion">0</property>
- <object class="wxBoxSizer" expanded="1">
- <property name="minimum_size"></property>
- <property name="name">bSizer61</property>
- <property name="orient">wxHORIZONTAL</property>
- <property name="permission">none</property>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxEXPAND</property>
- <property name="proportion">1</property>
- <object class="spacer" expanded="1">
- <property name="height">0</property>
- <property name="permission">protected</property>
- <property name="width">0</property>
- </object>
- </object>
- <object class="sizeritem" expanded="1">
- <property name="border">6</property>
- <property name="flag">wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND</property>
- <property name="proportion">0</property>
- <object class="wxButton" expanded="1">
- <property name="bg"></property>
- <property name="context_help"></property>
- <property name="default">0</property>
- <property name="enabled">1</property>
- <property name="fg"></property>
- <property name="font"></property>
- <property name="hidden">0</property>
- <property name="id">wxID_OK</property>
- <property name="label">OK</property>
- <property name="maximum_size"></property>
- <property name="minimum_size"></property>
- <property name="name">m_buttonOK</property>
- <property name="permission">protected</property>
- <property name="pos"></property>
- <property name="size">-1,-1</property>
- <property name="style"></property>
- <property name="subclass"></property>
- <property name="tooltip"></property>
- <property name="validator_data_type"></property>
- <property name="validator_style">wxFILTER_NONE</property>
- <property name="validator_type">wxDefaultValidator</property>
- <property name="validator_variable"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style"></property>
- <event name="OnButtonClick">OnButtonOK</event>
- <event name="OnChar"></event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnKeyDown"></event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint"></event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnUpdateUI"></event>
- </object>
- </object>
- </object>
- </object>
- </object>
- </object>
- </object>
- </object>
- <object class="Dialog" expanded="1">
- <property name="bg"></property>
- <property name="center"></property>
- <property name="context_help"></property>
- <property name="enabled">1</property>
- <property name="extra_style"></property>
- <property name="fg"></property>
- <property name="font"></property>
- <property name="hidden">0</property>
- <property name="id">wxID_ANY</property>
- <property name="maximum_size"></property>
- <property name="minimum_size"></property>
- <property name="name">CSendDialogBase</property>
- <property name="pos"></property>
- <property name="size">498,157</property>
- <property name="style">wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER</property>
- <property name="subclass"></property>
- <property name="title">Send Coins</property>
- <property name="tooltip"></property>
- <property name="validator_data_type"></property>
- <property name="validator_style">wxFILTER_NONE</property>
- <property name="validator_type">wxDefaultValidator</property>
- <property name="validator_variable"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style"></property>
- <event name="OnActivate"></event>
- <event name="OnActivateApp"></event>
- <event name="OnChar"></event>
- <event name="OnClose"></event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnHibernate"></event>
- <event name="OnIconize"></event>
- <event name="OnIdle"></event>
- <event name="OnInitDialog"></event>
- <event name="OnKeyDown"></event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint"></event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnUpdateUI"></event>
- <object class="wxBoxSizer" expanded="1">
- <property name="minimum_size"></property>
- <property name="name">bSizer21</property>
- <property name="orient">wxVERTICAL</property>
- <property name="permission">none</property>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxEXPAND</property>
- <property name="proportion">0</property>
- <object class="spacer" expanded="1">
- <property name="height">5</property>
- <property name="permission">protected</property>
- <property name="width">0</property>
- </object>
- </object>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxEXPAND|wxLEFT</property>
- <property name="proportion">0</property>
- <object class="wxFlexGridSizer" expanded="1">
- <property name="cols">2</property>
- <property name="flexible_direction">wxBOTH</property>
- <property name="growablecols">1</property>
- <property name="growablerows"></property>
- <property name="hgap">0</property>
- <property name="minimum_size"></property>
- <property name="name">fgSizer1</property>
- <property name="non_flexible_grow_mode">wxFLEX_GROWMODE_SPECIFIED</property>
- <property name="permission">none</property>
- <property name="rows">0</property>
- <property name="vgap">0</property>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxEXPAND</property>
- <property name="proportion">0</property>
- <object class="spacer" expanded="1">
- <property name="height">0</property>
- <property name="permission">protected</property>
- <property name="width">0</property>
- </object>
- </object>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxTOP|wxRIGHT|wxLEFT</property>
- <property name="proportion">0</property>
- <object class="wxStaticText" expanded="1">
- <property name="bg"></property>
- <property name="context_help"></property>
- <property name="enabled">1</property>
- <property name="fg"></property>
- <property name="font"></property>
- <property name="hidden">0</property>
- <property name="id">wxID_ANY</property>
- <property name="label">Enter a Bitcoin address (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L)</property>
- <property name="maximum_size"></property>
- <property name="minimum_size"></property>
- <property name="name">m_staticTextInstructions</property>
- <property name="permission">protected</property>
- <property name="pos"></property>
- <property name="size"></property>
- <property name="style"></property>
- <property name="subclass"></property>
- <property name="tooltip"></property>
- <property name="validator_data_type"></property>
- <property name="validator_style">wxFILTER_NONE</property>
- <property name="validator_type">wxDefaultValidator</property>
- <property name="validator_variable"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style"></property>
- <property name="wrap">-1</property>
- <event name="OnChar"></event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnKeyDown"></event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint"></event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnUpdateUI"></event>
- </object>
- </object>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxEXPAND|wxLEFT</property>
- <property name="proportion">1</property>
- <object class="wxBoxSizer" expanded="1">
- <property name="minimum_size">70,-1</property>
- <property name="name">bSizer47</property>
- <property name="orient">wxHORIZONTAL</property>
- <property name="permission">none</property>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxEXPAND</property>
- <property name="proportion">1</property>
- <object class="spacer" expanded="1">
- <property name="height">0</property>
- <property name="permission">protected</property>
- <property name="width">0</property>
- </object>
- </object>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxALL|wxALIGN_CENTER_VERTICAL</property>
- <property name="proportion">0</property>
- <object class="wxStaticBitmap" expanded="1">
- <property name="bg"></property>
- <property name="bitmap">xpm/check.xpm; Load From File</property>
- <property name="context_help"></property>
- <property name="enabled">1</property>
- <property name="fg"></property>
- <property name="font"></property>
- <property name="hidden">0</property>
- <property name="id">wxID_ANY</property>
- <property name="maximum_size"></property>
- <property name="minimum_size"></property>
- <property name="name">m_bitmapCheckMark</property>
- <property name="permission">protected</property>
- <property name="pos"></property>
- <property name="size">16,16</property>
- <property name="subclass"></property>
- <property name="tooltip"></property>
- <property name="validator_data_type"></property>
- <property name="validator_style">wxFILTER_NONE</property>
- <property name="validator_type">wxDefaultValidator</property>
- <property name="validator_variable"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style"></property>
- <event name="OnChar"></event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnKeyDown"></event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint"></event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnUpdateUI"></event>
- </object>
- </object>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxLEFT</property>
- <property name="proportion">0</property>
- <object class="wxStaticText" expanded="1">
- <property name="bg"></property>
- <property name="context_help"></property>
- <property name="enabled">1</property>
- <property name="fg"></property>
- <property name="font"></property>
- <property name="hidden">0</property>
- <property name="id">wxID_ANY</property>
- <property name="label">Pay &To:</property>
- <property name="maximum_size"></property>
- <property name="minimum_size"></property>
- <property name="name">m_staticText36</property>
- <property name="permission">protected</property>
- <property name="pos"></property>
- <property name="size">-1,-1</property>
- <property name="style">wxALIGN_RIGHT</property>
- <property name="subclass"></property>
- <property name="tooltip"></property>
- <property name="validator_data_type"></property>
- <property name="validator_style">wxFILTER_NONE</property>
- <property name="validator_type">wxDefaultValidator</property>
- <property name="validator_variable"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style"></property>
- <property name="wrap">-1</property>
- <event name="OnChar"></event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnKeyDown"></event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint"></event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnUpdateUI"></event>
- </object>
- </object>
- </object>
- </object>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxEXPAND|wxRIGHT</property>
- <property name="proportion">1</property>
- <object class="wxBoxSizer" expanded="1">
- <property name="minimum_size"></property>
- <property name="name">bSizer19</property>
- <property name="orient">wxHORIZONTAL</property>
- <property name="permission">none</property>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxALIGN_CENTER_VERTICAL|wxALL</property>
- <property name="proportion">1</property>
- <object class="wxTextCtrl" expanded="1">
- <property name="bg"></property>
- <property name="context_help"></property>
- <property name="enabled">1</property>
- <property name="fg"></property>
- <property name="font"></property>
- <property name="hidden">0</property>
- <property name="id">wxID_TEXTCTRLPAYTO</property>
- <property name="maximum_size"></property>
- <property name="maxlength">0</property>
- <property name="minimum_size"></property>
- <property name="name">m_textCtrlAddress</property>
- <property name="permission">protected</property>
- <property name="pos"></property>
- <property name="size"></property>
- <property name="style"></property>
- <property name="subclass"></property>
- <property name="tooltip"></property>
- <property name="validator_data_type"></property>
- <property name="validator_style">wxFILTER_NONE</property>
- <property name="validator_type">wxDefaultValidator</property>
- <property name="validator_variable"></property>
- <property name="value"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style"></property>
- <event name="OnChar"></event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnKeyDown">OnKeyDown</event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint"></event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnText">OnTextAddress</event>
- <event name="OnTextEnter"></event>
- <event name="OnTextMaxLen"></event>
- <event name="OnTextURL"></event>
- <event name="OnUpdateUI"></event>
- </object>
- </object>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxALIGN_CENTER_VERTICAL</property>
- <property name="proportion">0</property>
- <object class="wxBoxSizer" expanded="1">
- <property name="minimum_size"></property>
- <property name="name">bSizer66</property>
- <property name="orient">wxHORIZONTAL</property>
- <property name="permission">none</property>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxALIGN_CENTER_VERTICAL|wxRIGHT|wxEXPAND</property>
- <property name="proportion">0</property>
- <object class="wxButton" expanded="1">
- <property name="bg"></property>
- <property name="context_help"></property>
- <property name="default">0</property>
- <property name="enabled">1</property>
- <property name="fg"></property>
- <property name="font"></property>
- <property name="hidden">0</property>
- <property name="id">wxID_BUTTONPASTE</property>
- <property name="label">&Paste</property>
- <property name="maximum_size"></property>
- <property name="minimum_size"></property>
- <property name="name">m_buttonPaste</property>
- <property name="permission">protected</property>
- <property name="pos"></property>
- <property name="size">-1,-1</property>
- <property name="style">wxBU_EXACTFIT</property>
- <property name="subclass"></property>
- <property name="tooltip"></property>
- <property name="validator_data_type"></property>
- <property name="validator_style">wxFILTER_NONE</property>
- <property name="validator_type">wxDefaultValidator</property>
- <property name="validator_variable"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style"></property>
- <event name="OnButtonClick">OnButtonPaste</event>
- <event name="OnChar"></event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnKeyDown"></event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint"></event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnUpdateUI"></event>
- </object>
- </object>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxALIGN_CENTER_VERTICAL|wxRIGHT|wxEXPAND</property>
- <property name="proportion">0</property>
- <object class="wxButton" expanded="1">
- <property name="bg"></property>
- <property name="context_help"></property>
- <property name="default">0</property>
- <property name="enabled">1</property>
- <property name="fg"></property>
- <property name="font"></property>
- <property name="hidden">0</property>
- <property name="id">wxID_BUTTONADDRESSBOOK</property>
- <property name="label"> Address &Book...</property>
- <property name="maximum_size"></property>
- <property name="minimum_size"></property>
- <property name="name">m_buttonAddress</property>
- <property name="permission">protected</property>
- <property name="pos"></property>
- <property name="size"></property>
- <property name="style"></property>
- <property name="subclass"></property>
- <property name="tooltip"></property>
- <property name="validator_data_type"></property>
- <property name="validator_style">wxFILTER_NONE</property>
- <property name="validator_type">wxDefaultValidator</property>
- <property name="validator_variable"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style"></property>
- <event name="OnButtonClick">OnButtonAddressBook</event>
- <event name="OnChar"></event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnKeyDown"></event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint"></event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnUpdateUI"></event>
- </object>
- </object>
- </object>
- </object>
- </object>
- </object>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxLEFT|wxALIGN_RIGHT</property>
- <property name="proportion">0</property>
- <object class="wxStaticText" expanded="1">
- <property name="bg"></property>
- <property name="context_help"></property>
- <property name="enabled">1</property>
- <property name="fg"></property>
- <property name="font"></property>
- <property name="hidden">0</property>
- <property name="id">wxID_ANY</property>
- <property name="label">&Amount:</property>
- <property name="maximum_size"></property>
- <property name="minimum_size"></property>
- <property name="name">m_staticText19</property>
- <property name="permission">protected</property>
- <property name="pos"></property>
- <property name="size">-1,-1</property>
- <property name="style">wxALIGN_RIGHT</property>
- <property name="subclass"></property>
- <property name="tooltip"></property>
- <property name="validator_data_type"></property>
- <property name="validator_style">wxFILTER_NONE</property>
- <property name="validator_type">wxDefaultValidator</property>
- <property name="validator_variable"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style"></property>
- <property name="wrap">-1</property>
- <event name="OnChar"></event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnKeyDown"></event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint"></event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnUpdateUI"></event>
- </object>
- </object>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxALIGN_CENTER_VERTICAL|wxALL</property>
- <property name="proportion">0</property>
- <object class="wxTextCtrl" expanded="1">
- <property name="bg"></property>
- <property name="context_help"></property>
- <property name="enabled">1</property>
- <property name="fg"></property>
- <property name="font">,90,90,-1,70,0</property>
- <property name="hidden">0</property>
- <property name="id">wxID_TEXTCTRLAMOUNT</property>
- <property name="maximum_size"></property>
- <property name="maxlength">20</property>
- <property name="minimum_size"></property>
- <property name="name">m_textCtrlAmount</property>
- <property name="permission">protected</property>
- <property name="pos"></property>
- <property name="size">145,-1</property>
- <property name="style"></property>
- <property name="subclass"></property>
- <property name="tooltip"></property>
- <property name="validator_data_type"></property>
- <property name="validator_style">wxFILTER_NONE</property>
- <property name="validator_type">wxDefaultValidator</property>
- <property name="validator_variable"></property>
- <property name="value"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style"></property>
- <event name="OnChar"></event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnKeyDown">OnKeyDown</event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus">OnKillFocusAmount</event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint"></event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnText"></event>
- <event name="OnTextEnter"></event>
- <event name="OnTextMaxLen"></event>
- <event name="OnTextURL"></event>
- <event name="OnUpdateUI"></event>
- </object>
- </object>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxTOP|wxBOTTOM|wxLEFT</property>
- <property name="proportion">0</property>
- <object class="wxStaticText" expanded="1">
- <property name="bg"></property>
- <property name="context_help"></property>
- <property name="enabled">1</property>
- <property name="fg"></property>
- <property name="font"></property>
- <property name="hidden">1</property>
- <property name="id">wxID_ANY</property>
- <property name="label">T&ransfer:</property>
- <property name="maximum_size"></property>
- <property name="minimum_size"></property>
- <property name="name">m_staticText20</property>
- <property name="permission">protected</property>
- <property name="pos"></property>
- <property name="size">-1,-1</property>
- <property name="style">wxALIGN_RIGHT</property>
- <property name="subclass"></property>
- <property name="tooltip"></property>
- <property name="validator_data_type"></property>
- <property name="validator_style">wxFILTER_NONE</property>
- <property name="validator_type">wxDefaultValidator</property>
- <property name="validator_variable"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style"></property>
- <property name="wrap">-1</property>
- <event name="OnChar"></event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnKeyDown"></event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint"></event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnUpdateUI"></event>
- </object>
- </object>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxALIGN_CENTER_VERTICAL|wxALL</property>
- <property name="proportion">0</property>
- <object class="wxChoice" expanded="1">
- <property name="bg"></property>
- <property name="choices">" Standard"</property>
- <property name="context_help"></property>
- <property name="enabled">1</property>
- <property name="fg"></property>
- <property name="font"></property>
- <property name="hidden">1</property>
- <property name="id">wxID_CHOICETRANSFERTYPE</property>
- <property name="maximum_size"></property>
- <property name="minimum_size"></property>
- <property name="name">m_choiceTransferType</property>
- <property name="permission">protected</property>
- <property name="pos"></property>
- <property name="selection">0</property>
- <property name="size"></property>
- <property name="subclass"></property>
- <property name="tooltip"></property>
- <property name="validator_data_type"></property>
- <property name="validator_style">wxFILTER_NONE</property>
- <property name="validator_type">wxDefaultValidator</property>
- <property name="validator_variable"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style"></property>
- <event name="OnChar"></event>
- <event name="OnChoice"></event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnKeyDown"></event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint"></event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnUpdateUI"></event>
- </object>
- </object>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxEXPAND</property>
- <property name="proportion">0</property>
- <object class="spacer" expanded="1">
- <property name="height">3</property>
- <property name="permission">protected</property>
- <property name="width">0</property>
- </object>
- </object>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxEXPAND</property>
- <property name="proportion">0</property>
- <object class="spacer" expanded="1">
- <property name="height">0</property>
- <property name="permission">protected</property>
- <property name="width">0</property>
- </object>
- </object>
- </object>
- </object>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxEXPAND</property>
- <property name="proportion">0</property>
- <object class="wxBoxSizer" expanded="0">
- <property name="minimum_size"></property>
- <property name="name">bSizer672</property>
- <property name="orient">wxHORIZONTAL</property>
- <property name="permission">none</property>
- </object>
- </object>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxEXPAND</property>
- <property name="proportion">0</property>
- <object class="wxBoxSizer" expanded="0">
- <property name="minimum_size"></property>
- <property name="name">bSizer23</property>
- <property name="orient">wxHORIZONTAL</property>
- <property name="permission">none</property>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxEXPAND</property>
- <property name="proportion">1</property>
- <object class="spacer" expanded="1">
- <property name="height">0</property>
- <property name="permission">protected</property>
- <property name="width">0</property>
- </object>
- </object>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND</property>
- <property name="proportion">0</property>
- <object class="wxButton" expanded="1">
- <property name="bg"></property>
- <property name="context_help"></property>
- <property name="default">0</property>
- <property name="enabled">1</property>
- <property name="fg"></property>
- <property name="font">,90,90,-1,70,0</property>
- <property name="hidden">0</property>
- <property name="id">wxID_BUTTONSEND</property>
- <property name="label">&Send</property>
- <property name="maximum_size"></property>
- <property name="minimum_size">-1,-1</property>
- <property name="name">m_buttonSend</property>
- <property name="permission">protected</property>
- <property name="pos"></property>
- <property name="size">-1,-1</property>
- <property name="style"></property>
- <property name="subclass"></property>
- <property name="tooltip"></property>
- <property name="validator_data_type"></property>
- <property name="validator_style">wxFILTER_NONE</property>
- <property name="validator_type">wxDefaultValidator</property>
- <property name="validator_variable"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style"></property>
- <event name="OnButtonClick">OnButtonSend</event>
- <event name="OnChar"></event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnKeyDown"></event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint"></event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnUpdateUI"></event>
- </object>
- </object>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND</property>
- <property name="proportion">0</property>
- <object class="wxButton" expanded="1">
- <property name="bg"></property>
- <property name="context_help"></property>
- <property name="default">0</property>
- <property name="enabled">1</property>
- <property name="fg"></property>
- <property name="font"></property>
- <property name="hidden">0</property>
- <property name="id">wxID_CANCEL</property>
- <property name="label">Cancel</property>
- <property name="maximum_size"></property>
- <property name="minimum_size">-1,-1</property>
- <property name="name">m_buttonCancel</property>
- <property name="permission">protected</property>
- <property name="pos"></property>
- <property name="size">-1,-1</property>
- <property name="style"></property>
- <property name="subclass"></property>
- <property name="tooltip"></property>
- <property name="validator_data_type"></property>
- <property name="validator_style">wxFILTER_NONE</property>
- <property name="validator_type">wxDefaultValidator</property>
- <property name="validator_variable"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style"></property>
- <event name="OnButtonClick">OnButtonCancel</event>
- <event name="OnChar"></event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnKeyDown"></event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint"></event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnUpdateUI"></event>
- </object>
- </object>
- </object>
- </object>
- </object>
- </object>
- <object class="Dialog" expanded="0">
- <property name="bg"></property>
- <property name="center"></property>
- <property name="context_help"></property>
- <property name="enabled">1</property>
- <property name="extra_style"></property>
- <property name="fg"></property>
- <property name="font"></property>
- <property name="hidden">0</property>
- <property name="id">wxID_ANY</property>
- <property name="maximum_size"></property>
- <property name="minimum_size"></property>
- <property name="name">CSendingDialogBase</property>
- <property name="pos"></property>
- <property name="size">442,151</property>
- <property name="style">wxDEFAULT_DIALOG_STYLE</property>
- <property name="subclass"></property>
- <property name="title">Sending...</property>
- <property name="tooltip"></property>
- <property name="validator_data_type"></property>
- <property name="validator_style">wxFILTER_NONE</property>
- <property name="validator_type">wxDefaultValidator</property>
- <property name="validator_variable"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style"></property>
- <event name="OnActivate"></event>
- <event name="OnActivateApp"></event>
- <event name="OnChar"></event>
- <event name="OnClose">OnClose</event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnHibernate"></event>
- <event name="OnIconize"></event>
- <event name="OnIdle"></event>
- <event name="OnInitDialog"></event>
- <event name="OnKeyDown"></event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint">OnPaint</event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnUpdateUI"></event>
- <object class="wxBoxSizer" expanded="1">
- <property name="minimum_size"></property>
- <property name="name">bSizer68</property>
- <property name="orient">wxVERTICAL</property>
- <property name="permission">none</property>
- <object class="sizeritem" expanded="1">
- <property name="border">8</property>
- <property name="flag">wxALIGN_CENTER_VERTICAL|wxEXPAND|wxTOP|wxRIGHT|wxLEFT</property>
- <property name="proportion">0</property>
- <object class="wxStaticText" expanded="1">
- <property name="bg"></property>
- <property name="context_help"></property>
- <property name="enabled">1</property>
- <property name="fg"></property>
- <property name="font"></property>
- <property name="hidden">0</property>
- <property name="id">wxID_ANY</property>
- <property name="label"></property>
- <property name="maximum_size"></property>
- <property name="minimum_size"></property>
- <property name="name">m_staticTextSending</property>
- <property name="permission">protected</property>
- <property name="pos"></property>
- <property name="size">-1,14</property>
- <property name="style"></property>
- <property name="subclass"></property>
- <property name="tooltip"></property>
- <property name="validator_data_type"></property>
- <property name="validator_style">wxFILTER_NONE</property>
- <property name="validator_type">wxDefaultValidator</property>
- <property name="validator_variable"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style"></property>
- <property name="wrap">-1</property>
- <event name="OnChar"></event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnKeyDown"></event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint"></event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnUpdateUI"></event>
- </object>
- </object>
- <object class="sizeritem" expanded="1">
- <property name="border">10</property>
- <property name="flag">wxEXPAND|wxRIGHT|wxLEFT</property>
- <property name="proportion">1</property>
- <object class="wxTextCtrl" expanded="1">
- <property name="bg">wxSYS_COLOUR_BTNFACE</property>
- <property name="context_help"></property>
- <property name="enabled">1</property>
- <property name="fg"></property>
- <property name="font"></property>
- <property name="hidden">0</property>
- <property name="id">wxID_ANY</property>
- <property name="maximum_size"></property>
- <property name="maxlength">0</property>
- <property name="minimum_size"></property>
- <property name="name">m_textCtrlStatus</property>
- <property name="permission">protected</property>
- <property name="pos"></property>
- <property name="size"></property>
- <property name="style">wxTE_CENTRE|wxTE_MULTILINE|wxTE_NO_VSCROLL|wxTE_READONLY</property>
- <property name="subclass"></property>
- <property name="tooltip"></property>
- <property name="validator_data_type"></property>
- <property name="validator_style">wxFILTER_NONE</property>
- <property name="validator_type">wxDefaultValidator</property>
- <property name="validator_variable"></property>
- <property name="value">

Connecting...</property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style">wxNO_BORDER</property>
- <event name="OnChar"></event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnKeyDown"></event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint"></event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnText"></event>
- <event name="OnTextEnter"></event>
- <event name="OnTextMaxLen"></event>
- <event name="OnTextURL"></event>
- <event name="OnUpdateUI"></event>
- </object>
- </object>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxEXPAND</property>
- <property name="proportion">0</property>
- <object class="wxBoxSizer" expanded="1">
- <property name="minimum_size"></property>
- <property name="name">bSizer69</property>
- <property name="orient">wxHORIZONTAL</property>
- <property name="permission">none</property>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxEXPAND</property>
- <property name="proportion">1</property>
- <object class="spacer" expanded="1">
- <property name="height">0</property>
- <property name="permission">protected</property>
- <property name="width">0</property>
- </object>
- </object>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND</property>
- <property name="proportion">0</property>
- <object class="wxButton" expanded="1">
- <property name="bg"></property>
- <property name="context_help"></property>
- <property name="default">0</property>
- <property name="enabled">0</property>
- <property name="fg"></property>
- <property name="font"></property>
- <property name="hidden">0</property>
- <property name="id">wxID_ANY</property>
- <property name="label">OK</property>
- <property name="maximum_size"></property>
- <property name="minimum_size">-1,-1</property>
- <property name="name">m_buttonOK</property>
- <property name="permission">protected</property>
- <property name="pos"></property>
- <property name="size"></property>
- <property name="style"></property>
- <property name="subclass"></property>
- <property name="tooltip"></property>
- <property name="validator_data_type"></property>
- <property name="validator_style">wxFILTER_NONE</property>
- <property name="validator_type">wxDefaultValidator</property>
- <property name="validator_variable"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style"></property>
- <event name="OnButtonClick">OnButtonOK</event>
- <event name="OnChar"></event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnKeyDown"></event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint"></event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnUpdateUI"></event>
- </object>
- </object>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND</property>
- <property name="proportion">0</property>
- <object class="wxButton" expanded="1">
- <property name="bg"></property>
- <property name="context_help"></property>
- <property name="default">0</property>
- <property name="enabled">1</property>
- <property name="fg"></property>
- <property name="font"></property>
- <property name="hidden">0</property>
- <property name="id">wxID_CANCEL</property>
- <property name="label">Cancel</property>
- <property name="maximum_size"></property>
- <property name="minimum_size">-1,-1</property>
- <property name="name">m_buttonCancel</property>
- <property name="permission">protected</property>
- <property name="pos"></property>
- <property name="size">-1,-1</property>
- <property name="style"></property>
- <property name="subclass"></property>
- <property name="tooltip"></property>
- <property name="validator_data_type"></property>
- <property name="validator_style">wxFILTER_NONE</property>
- <property name="validator_type">wxDefaultValidator</property>
- <property name="validator_variable"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style"></property>
- <event name="OnButtonClick">OnButtonCancel</event>
- <event name="OnChar"></event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnKeyDown"></event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint"></event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnUpdateUI"></event>
- </object>
- </object>
- </object>
- </object>
- </object>
- </object>
- <object class="Dialog" expanded="0">
- <property name="bg"></property>
- <property name="center"></property>
- <property name="context_help"></property>
- <property name="enabled">1</property>
- <property name="extra_style"></property>
- <property name="fg"></property>
- <property name="font"></property>
- <property name="hidden">0</property>
- <property name="id">wxID_ANY</property>
- <property name="maximum_size"></property>
- <property name="minimum_size"></property>
- <property name="name">CYourAddressDialogBase</property>
- <property name="pos"></property>
- <property name="size">610,390</property>
- <property name="style">wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER</property>
- <property name="subclass"></property>
- <property name="title">Your Bitcoin Addresses</property>
- <property name="tooltip"></property>
- <property name="validator_data_type"></property>
- <property name="validator_style">wxFILTER_NONE</property>
- <property name="validator_type">wxDefaultValidator</property>
- <property name="validator_variable"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style"></property>
- <event name="OnActivate"></event>
- <event name="OnActivateApp"></event>
- <event name="OnChar"></event>
- <event name="OnClose">OnClose</event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnHibernate"></event>
- <event name="OnIconize"></event>
- <event name="OnIdle"></event>
- <event name="OnInitDialog"></event>
- <event name="OnKeyDown"></event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint"></event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnUpdateUI"></event>
- <object class="wxBoxSizer" expanded="1">
- <property name="minimum_size"></property>
- <property name="name">bSizer68</property>
- <property name="orient">wxVERTICAL</property>
- <property name="permission">none</property>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxEXPAND</property>
- <property name="proportion">0</property>
- <object class="spacer" expanded="1">
- <property name="height">5</property>
- <property name="permission">protected</property>
- <property name="width">0</property>
- </object>
- </object>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxALL</property>
- <property name="proportion">0</property>
- <object class="wxStaticText" expanded="1">
- <property name="bg"></property>
- <property name="context_help"></property>
- <property name="enabled">1</property>
- <property name="fg"></property>
- <property name="font"></property>
- <property name="hidden">0</property>
- <property name="id">wxID_ANY</property>
- <property name="label">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. The highlighted address is displayed in the main window.</property>
- <property name="maximum_size"></property>
- <property name="minimum_size"></property>
- <property name="name">m_staticText45</property>
- <property name="permission">protected</property>
- <property name="pos"></property>
- <property name="size"></property>
- <property name="style"></property>
- <property name="subclass"></property>
- <property name="tooltip"></property>
- <property name="validator_data_type"></property>
- <property name="validator_style">wxFILTER_NONE</property>
- <property name="validator_type">wxDefaultValidator</property>
- <property name="validator_variable"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style"></property>
- <property name="wrap">590</property>
- <event name="OnChar"></event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnKeyDown"></event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint"></event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnUpdateUI"></event>
- </object>
- </object>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxALL|wxEXPAND</property>
- <property name="proportion">1</property>
- <object class="wxListCtrl" expanded="1">
- <property name="bg"></property>
- <property name="context_help"></property>
- <property name="enabled">1</property>
- <property name="fg"></property>
- <property name="font"></property>
- <property name="hidden">0</property>
- <property name="id">wxID_LISTCTRL</property>
- <property name="maximum_size"></property>
- <property name="minimum_size"></property>
- <property name="name">m_listCtrl</property>
- <property name="permission">protected</property>
- <property name="pos"></property>
- <property name="size"></property>
- <property name="style">wxLC_NO_SORT_HEADER|wxLC_REPORT|wxLC_SORT_ASCENDING</property>
- <property name="subclass"></property>
- <property name="tooltip"></property>
- <property name="validator_data_type"></property>
- <property name="validator_style">wxFILTER_NONE</property>
- <property name="validator_type">wxDefaultValidator</property>
- <property name="validator_variable"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style"></property>
- <event name="OnChar"></event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnKeyDown"></event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnListBeginDrag"></event>
- <event name="OnListBeginLabelEdit"></event>
- <event name="OnListBeginRDrag"></event>
- <event name="OnListCacheHint"></event>
- <event name="OnListColBeginDrag"></event>
- <event name="OnListColClick"></event>
- <event name="OnListColDragging"></event>
- <event name="OnListColEndDrag"></event>
- <event name="OnListColRightClick"></event>
- <event name="OnListDeleteAllItems"></event>
- <event name="OnListDeleteItem"></event>
- <event name="OnListEndLabelEdit">OnListEndLabelEdit</event>
- <event name="OnListInsertItem"></event>
- <event name="OnListItemActivated">OnListItemActivated</event>
- <event name="OnListItemDeselected"></event>
- <event name="OnListItemFocused"></event>
- <event name="OnListItemMiddleClick"></event>
- <event name="OnListItemRightClick"></event>
- <event name="OnListItemSelected">OnListItemSelected</event>
- <event name="OnListKeyDown"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint"></event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnUpdateUI"></event>
- </object>
- </object>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxEXPAND</property>
- <property name="proportion">0</property>
- <object class="wxBoxSizer" expanded="1">
- <property name="minimum_size"></property>
- <property name="name">bSizer69</property>
- <property name="orient">wxHORIZONTAL</property>
- <property name="permission">none</property>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxEXPAND</property>
- <property name="proportion">1</property>
- <object class="spacer" expanded="1">
- <property name="height">0</property>
- <property name="permission">protected</property>
- <property name="width">0</property>
- </object>
- </object>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND</property>
- <property name="proportion">0</property>
- <object class="wxButton" expanded="1">
- <property name="bg"></property>
- <property name="context_help"></property>
- <property name="default">0</property>
- <property name="enabled">1</property>
- <property name="fg"></property>
- <property name="font"></property>
- <property name="hidden">0</property>
- <property name="id">wxID_BUTTONRENAME</property>
- <property name="label">&Edit...</property>
- <property name="maximum_size"></property>
- <property name="minimum_size">-1,-1</property>
- <property name="name">m_buttonRename</property>
- <property name="permission">protected</property>
- <property name="pos"></property>
- <property name="size"></property>
- <property name="style"></property>
- <property name="subclass"></property>
- <property name="tooltip"></property>
- <property name="validator_data_type"></property>
- <property name="validator_style">wxFILTER_NONE</property>
- <property name="validator_type">wxDefaultValidator</property>
- <property name="validator_variable"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style"></property>
- <event name="OnButtonClick">OnButtonRename</event>
- <event name="OnChar"></event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnKeyDown"></event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint"></event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnUpdateUI"></event>
- </object>
- </object>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND</property>
- <property name="proportion">0</property>
- <object class="wxButton" expanded="1">
- <property name="bg"></property>
- <property name="context_help"></property>
- <property name="default">0</property>
- <property name="enabled">1</property>
- <property name="fg"></property>
- <property name="font"></property>
- <property name="hidden">0</property>
- <property name="id">wxID_BUTTONNEW</property>
- <property name="label"> &New Address... </property>
- <property name="maximum_size"></property>
- <property name="minimum_size">-1,-1</property>
- <property name="name">m_buttonNew</property>
- <property name="permission">protected</property>
- <property name="pos"></property>
- <property name="size">-1,-1</property>
- <property name="style"></property>
- <property name="subclass"></property>
- <property name="tooltip"></property>
- <property name="validator_data_type"></property>
- <property name="validator_style">wxFILTER_NONE</property>
- <property name="validator_type">wxDefaultValidator</property>
- <property name="validator_variable"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style"></property>
- <event name="OnButtonClick">OnButtonNew</event>
- <event name="OnChar"></event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnKeyDown"></event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint"></event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnUpdateUI"></event>
- </object>
- </object>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND</property>
- <property name="proportion">0</property>
- <object class="wxButton" expanded="1">
- <property name="bg"></property>
- <property name="context_help"></property>
- <property name="default">0</property>
- <property name="enabled">1</property>
- <property name="fg"></property>
- <property name="font"></property>
- <property name="hidden">0</property>
- <property name="id">wxID_BUTTONCOPY</property>
- <property name="label"> &Copy to Clipboard </property>
- <property name="maximum_size"></property>
- <property name="minimum_size">-1,-1</property>
- <property name="name">m_buttonCopy</property>
- <property name="permission">protected</property>
- <property name="pos"></property>
- <property name="size">-1,-1</property>
- <property name="style"></property>
- <property name="subclass"></property>
- <property name="tooltip"></property>
- <property name="validator_data_type"></property>
- <property name="validator_style">wxFILTER_NONE</property>
- <property name="validator_type">wxDefaultValidator</property>
- <property name="validator_variable"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style"></property>
- <event name="OnButtonClick">OnButtonCopy</event>
- <event name="OnChar"></event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnKeyDown"></event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint"></event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnUpdateUI"></event>
- </object>
- </object>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND</property>
- <property name="proportion">0</property>
- <object class="wxButton" expanded="1">
- <property name="bg"></property>
- <property name="context_help"></property>
- <property name="default">0</property>
- <property name="enabled">1</property>
- <property name="fg"></property>
- <property name="font"></property>
- <property name="hidden">0</property>
- <property name="id">wxID_OK</property>
- <property name="label">OK</property>
- <property name="maximum_size"></property>
- <property name="minimum_size">-1,-1</property>
- <property name="name">m_buttonOK</property>
- <property name="permission">protected</property>
- <property name="pos"></property>
- <property name="size"></property>
- <property name="style"></property>
- <property name="subclass"></property>
- <property name="tooltip"></property>
- <property name="validator_data_type"></property>
- <property name="validator_style">wxFILTER_NONE</property>
- <property name="validator_type">wxDefaultValidator</property>
- <property name="validator_variable"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style"></property>
- <event name="OnButtonClick">OnButtonOK</event>
- <event name="OnChar"></event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnKeyDown"></event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint"></event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnUpdateUI"></event>
- </object>
- </object>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND</property>
- <property name="proportion">0</property>
- <object class="wxButton" expanded="1">
- <property name="bg"></property>
- <property name="context_help"></property>
- <property name="default">0</property>
- <property name="enabled">1</property>
- <property name="fg"></property>
- <property name="font"></property>
- <property name="hidden">1</property>
- <property name="id">wxID_CANCEL</property>
- <property name="label">Cancel</property>
- <property name="maximum_size"></property>
- <property name="minimum_size">-1,-1</property>
- <property name="name">m_buttonCancel</property>
- <property name="permission">protected</property>
- <property name="pos"></property>
- <property name="size">-1,-1</property>
- <property name="style"></property>
- <property name="subclass"></property>
- <property name="tooltip"></property>
- <property name="validator_data_type"></property>
- <property name="validator_style">wxFILTER_NONE</property>
- <property name="validator_type">wxDefaultValidator</property>
- <property name="validator_variable"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style"></property>
- <event name="OnButtonClick">OnButtonCancel</event>
- <event name="OnChar"></event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnKeyDown"></event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint"></event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnUpdateUI"></event>
- </object>
- </object>
- </object>
- </object>
- </object>
- </object>
- <object class="Dialog" expanded="0">
- <property name="bg"></property>
- <property name="center"></property>
- <property name="context_help"></property>
- <property name="enabled">1</property>
- <property name="extra_style"></property>
- <property name="fg"></property>
- <property name="font"></property>
- <property name="hidden">0</property>
- <property name="id">wxID_ANY</property>
- <property name="maximum_size"></property>
- <property name="minimum_size"></property>
- <property name="name">CAddressBookDialogBase</property>
- <property name="pos"></property>
- <property name="size">610,390</property>
- <property name="style">wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER</property>
- <property name="subclass"></property>
- <property name="title">Address Book</property>
- <property name="tooltip"></property>
- <property name="validator_data_type"></property>
- <property name="validator_style">wxFILTER_NONE</property>
- <property name="validator_type">wxDefaultValidator</property>
- <property name="validator_variable"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style"></property>
- <event name="OnActivate"></event>
- <event name="OnActivateApp"></event>
- <event name="OnChar"></event>
- <event name="OnClose">OnClose</event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnHibernate"></event>
- <event name="OnIconize"></event>
- <event name="OnIdle"></event>
- <event name="OnInitDialog"></event>
- <event name="OnKeyDown"></event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint"></event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnUpdateUI"></event>
- <object class="wxBoxSizer" expanded="1">
- <property name="minimum_size"></property>
- <property name="name">bSizer58</property>
- <property name="orient">wxVERTICAL</property>
- <property name="permission">none</property>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxEXPAND|wxTOP|wxRIGHT|wxLEFT</property>
- <property name="proportion">1</property>
- <object class="wxNotebook" expanded="1">
- <property name="bg"></property>
- <property name="bitmapsize"></property>
- <property name="context_help"></property>
- <property name="enabled">1</property>
- <property name="fg"></property>
- <property name="font"></property>
- <property name="hidden">0</property>
- <property name="id">wxID_ANY</property>
- <property name="maximum_size"></property>
- <property name="minimum_size"></property>
- <property name="name">m_notebook</property>
- <property name="permission">protected</property>
- <property name="pos"></property>
- <property name="size"></property>
- <property name="style"></property>
- <property name="subclass"></property>
- <property name="tooltip"></property>
- <property name="validator_data_type"></property>
- <property name="validator_style">wxFILTER_NONE</property>
- <property name="validator_type">wxDefaultValidator</property>
- <property name="validator_variable"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style"></property>
- <event name="OnChar"></event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnKeyDown"></event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnNotebookPageChanged">OnNotebookPageChanged</event>
- <event name="OnNotebookPageChanging"></event>
- <event name="OnPaint"></event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnUpdateUI"></event>
- <object class="notebookpage" expanded="1">
- <property name="bitmap"></property>
- <property name="label">Sending</property>
- <property name="select">0</property>
- <object class="wxPanel" expanded="1">
- <property name="bg"></property>
- <property name="context_help"></property>
- <property name="enabled">1</property>
- <property name="fg"></property>
- <property name="font"></property>
- <property name="hidden">0</property>
- <property name="id">wxID_PANELSENDING</property>
- <property name="maximum_size"></property>
- <property name="minimum_size"></property>
- <property name="name">m_panelSending</property>
- <property name="permission">protected</property>
- <property name="pos"></property>
- <property name="size"></property>
- <property name="subclass"></property>
- <property name="tooltip"></property>
- <property name="validator_data_type"></property>
- <property name="validator_style">wxFILTER_NONE</property>
- <property name="validator_type">wxDefaultValidator</property>
- <property name="validator_variable"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style">wxTAB_TRAVERSAL</property>
- <event name="OnChar"></event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnKeyDown"></event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint"></event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnUpdateUI"></event>
- <object class="wxBoxSizer" expanded="1">
- <property name="minimum_size"></property>
- <property name="name">bSizer68</property>
- <property name="orient">wxVERTICAL</property>
- <property name="permission">none</property>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxEXPAND</property>
- <property name="proportion">0</property>
- <object class="spacer" expanded="1">
- <property name="height">0</property>
- <property name="permission">protected</property>
- <property name="width">0</property>
- </object>
- </object>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxTOP|wxRIGHT|wxLEFT</property>
- <property name="proportion">0</property>
- <object class="wxStaticText" expanded="1">
- <property name="bg"></property>
- <property name="context_help"></property>
- <property name="enabled">1</property>
- <property name="fg"></property>
- <property name="font"></property>
- <property name="hidden">1</property>
- <property name="id">wxID_ANY</property>
- <property name="label">Bitcoin Address</property>
- <property name="maximum_size"></property>
- <property name="minimum_size"></property>
- <property name="name">m_staticText55</property>
- <property name="permission">protected</property>
- <property name="pos"></property>
- <property name="size"></property>
- <property name="style"></property>
- <property name="subclass"></property>
- <property name="tooltip"></property>
- <property name="validator_data_type"></property>
- <property name="validator_style">wxFILTER_NONE</property>
- <property name="validator_type">wxDefaultValidator</property>
- <property name="validator_variable"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style"></property>
- <property name="wrap">-1</property>
- <event name="OnChar"></event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnKeyDown"></event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint"></event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnUpdateUI"></event>
- </object>
- </object>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxALL|wxEXPAND</property>
- <property name="proportion">1</property>
- <object class="wxListCtrl" expanded="1">
- <property name="bg"></property>
- <property name="context_help"></property>
- <property name="enabled">1</property>
- <property name="fg"></property>
- <property name="font"></property>
- <property name="hidden">0</property>
- <property name="id">wxID_LISTCTRLSENDING</property>
- <property name="maximum_size"></property>
- <property name="minimum_size"></property>
- <property name="name">m_listCtrlSending</property>
- <property name="permission">protected</property>
- <property name="pos"></property>
- <property name="size"></property>
- <property name="style">wxLC_NO_SORT_HEADER|wxLC_REPORT|wxLC_SORT_ASCENDING</property>
- <property name="subclass"></property>
- <property name="tooltip"></property>
- <property name="validator_data_type"></property>
- <property name="validator_style">wxFILTER_NONE</property>
- <property name="validator_type">wxDefaultValidator</property>
- <property name="validator_variable"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style"></property>
- <event name="OnChar"></event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnKeyDown"></event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnListBeginDrag"></event>
- <event name="OnListBeginLabelEdit"></event>
- <event name="OnListBeginRDrag"></event>
- <event name="OnListCacheHint"></event>
- <event name="OnListColBeginDrag"></event>
- <event name="OnListColClick"></event>
- <event name="OnListColDragging"></event>
- <event name="OnListColEndDrag"></event>
- <event name="OnListColRightClick"></event>
- <event name="OnListDeleteAllItems"></event>
- <event name="OnListDeleteItem"></event>
- <event name="OnListEndLabelEdit">OnListEndLabelEdit</event>
- <event name="OnListInsertItem"></event>
- <event name="OnListItemActivated">OnListItemActivated</event>
- <event name="OnListItemDeselected"></event>
- <event name="OnListItemFocused"></event>
- <event name="OnListItemMiddleClick"></event>
- <event name="OnListItemRightClick"></event>
- <event name="OnListItemSelected">OnListItemSelected</event>
- <event name="OnListKeyDown"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint"></event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnUpdateUI"></event>
- </object>
- </object>
- </object>
- </object>
- </object>
- <object class="notebookpage" expanded="1">
- <property name="bitmap"></property>
- <property name="label">Receiving</property>
- <property name="select">1</property>
- <object class="wxPanel" expanded="1">
- <property name="bg"></property>
- <property name="context_help"></property>
- <property name="enabled">1</property>
- <property name="fg"></property>
- <property name="font"></property>
- <property name="hidden">0</property>
- <property name="id">wxID_PANELRECEIVING</property>
- <property name="maximum_size"></property>
- <property name="minimum_size"></property>
- <property name="name">m_panelReceiving</property>
- <property name="permission">protected</property>
- <property name="pos"></property>
- <property name="size"></property>
- <property name="subclass"></property>
- <property name="tooltip"></property>
- <property name="validator_data_type"></property>
- <property name="validator_style">wxFILTER_NONE</property>
- <property name="validator_type">wxDefaultValidator</property>
- <property name="validator_variable"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style">wxTAB_TRAVERSAL</property>
- <event name="OnChar"></event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnKeyDown"></event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint"></event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnUpdateUI"></event>
- <object class="wxBoxSizer" expanded="1">
- <property name="minimum_size"></property>
- <property name="name">bSizer681</property>
- <property name="orient">wxVERTICAL</property>
- <property name="permission">none</property>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxEXPAND</property>
- <property name="proportion">0</property>
- <object class="spacer" expanded="1">
- <property name="height">0</property>
- <property name="permission">protected</property>
- <property name="width">0</property>
- </object>
- </object>
- <object class="sizeritem" expanded="1">
- <property name="border">6</property>
- <property name="flag">wxTOP|wxRIGHT|wxLEFT</property>
- <property name="proportion">0</property>
- <object class="wxStaticText" expanded="1">
- <property name="bg"></property>
- <property name="context_help"></property>
- <property name="enabled">1</property>
- <property name="fg"></property>
- <property name="font"></property>
- <property name="hidden">0</property>
- <property name="id">wxID_ANY</property>
- <property name="label">These are your Bitcoin addresses for receiving payments. You can give a different one to each sender to keep track of who is paying you. The highlighted address will be displayed in the main window.</property>
- <property name="maximum_size"></property>
- <property name="minimum_size"></property>
- <property name="name">m_staticText45</property>
- <property name="permission">protected</property>
- <property name="pos"></property>
- <property name="size"></property>
- <property name="style"></property>
- <property name="subclass"></property>
- <property name="tooltip"></property>
- <property name="validator_data_type"></property>
- <property name="validator_style">wxFILTER_NONE</property>
- <property name="validator_type">wxDefaultValidator</property>
- <property name="validator_variable"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style"></property>
- <property name="wrap">570</property>
- <event name="OnChar"></event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnKeyDown"></event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint"></event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnUpdateUI"></event>
- </object>
- </object>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxEXPAND</property>
- <property name="proportion">0</property>
- <object class="spacer" expanded="1">
- <property name="height">2</property>
- <property name="permission">protected</property>
- <property name="width">0</property>
- </object>
- </object>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxALL|wxEXPAND</property>
- <property name="proportion">1</property>
- <object class="wxListCtrl" expanded="1">
- <property name="bg"></property>
- <property name="context_help"></property>
- <property name="enabled">1</property>
- <property name="fg"></property>
- <property name="font"></property>
- <property name="hidden">0</property>
- <property name="id">wxID_LISTCTRLRECEIVING</property>
- <property name="maximum_size"></property>
- <property name="minimum_size"></property>
- <property name="name">m_listCtrlReceiving</property>
- <property name="permission">protected</property>
- <property name="pos"></property>
- <property name="size"></property>
- <property name="style">wxLC_NO_SORT_HEADER|wxLC_REPORT|wxLC_SORT_ASCENDING</property>
- <property name="subclass"></property>
- <property name="tooltip"></property>
- <property name="validator_data_type"></property>
- <property name="validator_style">wxFILTER_NONE</property>
- <property name="validator_type">wxDefaultValidator</property>
- <property name="validator_variable"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style"></property>
- <event name="OnChar"></event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnKeyDown"></event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnListBeginDrag"></event>
- <event name="OnListBeginLabelEdit"></event>
- <event name="OnListBeginRDrag"></event>
- <event name="OnListCacheHint"></event>
- <event name="OnListColBeginDrag"></event>
- <event name="OnListColClick"></event>
- <event name="OnListColDragging"></event>
- <event name="OnListColEndDrag"></event>
- <event name="OnListColRightClick"></event>
- <event name="OnListDeleteAllItems"></event>
- <event name="OnListDeleteItem"></event>
- <event name="OnListEndLabelEdit">OnListEndLabelEdit</event>
- <event name="OnListInsertItem"></event>
- <event name="OnListItemActivated">OnListItemActivated</event>
- <event name="OnListItemDeselected"></event>
- <event name="OnListItemFocused"></event>
- <event name="OnListItemMiddleClick"></event>
- <event name="OnListItemRightClick"></event>
- <event name="OnListItemSelected">OnListItemSelected</event>
- <event name="OnListKeyDown"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint"></event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnUpdateUI"></event>
- </object>
- </object>
- </object>
- </object>
- </object>
- </object>
- </object>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxEXPAND</property>
- <property name="proportion">0</property>
- <object class="wxBoxSizer" expanded="1">
- <property name="minimum_size"></property>
- <property name="name">bSizer69</property>
- <property name="orient">wxHORIZONTAL</property>
- <property name="permission">none</property>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxEXPAND</property>
- <property name="proportion">1</property>
- <object class="spacer" expanded="1">
- <property name="height">0</property>
- <property name="permission">protected</property>
- <property name="width">0</property>
- </object>
- </object>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND</property>
- <property name="proportion">0</property>
- <object class="wxButton" expanded="1">
- <property name="bg"></property>
- <property name="context_help"></property>
- <property name="default">0</property>
- <property name="enabled">1</property>
- <property name="fg"></property>
- <property name="font"></property>
- <property name="hidden">0</property>
- <property name="id">wxID_BUTTONDELETE</property>
- <property name="label">&Delete</property>
- <property name="maximum_size"></property>
- <property name="minimum_size">-1,-1</property>
- <property name="name">m_buttonDelete</property>
- <property name="permission">protected</property>
- <property name="pos"></property>
- <property name="size"></property>
- <property name="style"></property>
- <property name="subclass"></property>
- <property name="tooltip"></property>
- <property name="validator_data_type"></property>
- <property name="validator_style">wxFILTER_NONE</property>
- <property name="validator_type">wxDefaultValidator</property>
- <property name="validator_variable"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style"></property>
- <event name="OnButtonClick">OnButtonDelete</event>
- <event name="OnChar"></event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnKeyDown"></event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint"></event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnUpdateUI"></event>
- </object>
- </object>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND</property>
- <property name="proportion">0</property>
- <object class="wxButton" expanded="1">
- <property name="bg"></property>
- <property name="context_help"></property>
- <property name="default">0</property>
- <property name="enabled">1</property>
- <property name="fg"></property>
- <property name="font"></property>
- <property name="hidden">0</property>
- <property name="id">wxID_BUTTONCOPY</property>
- <property name="label"> &Copy to Clipboard </property>
- <property name="maximum_size"></property>
- <property name="minimum_size">-1,-1</property>
- <property name="name">m_buttonCopy</property>
- <property name="permission">protected</property>
- <property name="pos"></property>
- <property name="size">-1,-1</property>
- <property name="style"></property>
- <property name="subclass"></property>
- <property name="tooltip"></property>
- <property name="validator_data_type"></property>
- <property name="validator_style">wxFILTER_NONE</property>
- <property name="validator_type">wxDefaultValidator</property>
- <property name="validator_variable"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style"></property>
- <event name="OnButtonClick">OnButtonCopy</event>
- <event name="OnChar"></event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnKeyDown"></event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint"></event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnUpdateUI"></event>
- </object>
- </object>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND</property>
- <property name="proportion">0</property>
- <object class="wxButton" expanded="1">
- <property name="bg"></property>
- <property name="context_help"></property>
- <property name="default">0</property>
- <property name="enabled">1</property>
- <property name="fg"></property>
- <property name="font"></property>
- <property name="hidden">0</property>
- <property name="id">wxID_BUTTONEDIT</property>
- <property name="label">&Edit...</property>
- <property name="maximum_size"></property>
- <property name="minimum_size">-1,-1</property>
- <property name="name">m_buttonEdit</property>
- <property name="permission">protected</property>
- <property name="pos"></property>
- <property name="size"></property>
- <property name="style"></property>
- <property name="subclass"></property>
- <property name="tooltip"></property>
- <property name="validator_data_type"></property>
- <property name="validator_style">wxFILTER_NONE</property>
- <property name="validator_type">wxDefaultValidator</property>
- <property name="validator_variable"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style"></property>
- <event name="OnButtonClick">OnButtonEdit</event>
- <event name="OnChar"></event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnKeyDown"></event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint"></event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnUpdateUI"></event>
- </object>
- </object>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND</property>
- <property name="proportion">0</property>
- <object class="wxButton" expanded="1">
- <property name="bg"></property>
- <property name="context_help"></property>
- <property name="default">0</property>
- <property name="enabled">1</property>
- <property name="fg"></property>
- <property name="font"></property>
- <property name="hidden">0</property>
- <property name="id">wxID_BUTTONNEW</property>
- <property name="label"> &New Address... </property>
- <property name="maximum_size"></property>
- <property name="minimum_size">-1,-1</property>
- <property name="name">m_buttonNew</property>
- <property name="permission">protected</property>
- <property name="pos"></property>
- <property name="size"></property>
- <property name="style"></property>
- <property name="subclass"></property>
- <property name="tooltip"></property>
- <property name="validator_data_type"></property>
- <property name="validator_style">wxFILTER_NONE</property>
- <property name="validator_type">wxDefaultValidator</property>
- <property name="validator_variable"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style"></property>
- <event name="OnButtonClick">OnButtonNew</event>
- <event name="OnChar"></event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnKeyDown"></event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint"></event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnUpdateUI"></event>
- </object>
- </object>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND</property>
- <property name="proportion">0</property>
- <object class="wxButton" expanded="1">
- <property name="bg"></property>
- <property name="context_help"></property>
- <property name="default">0</property>
- <property name="enabled">1</property>
- <property name="fg"></property>
- <property name="font"></property>
- <property name="hidden">0</property>
- <property name="id">wxID_OK</property>
- <property name="label">OK</property>
- <property name="maximum_size"></property>
- <property name="minimum_size">-1,-1</property>
- <property name="name">m_buttonOK</property>
- <property name="permission">protected</property>
- <property name="pos"></property>
- <property name="size">-1,-1</property>
- <property name="style"></property>
- <property name="subclass"></property>
- <property name="tooltip"></property>
- <property name="validator_data_type"></property>
- <property name="validator_style">wxFILTER_NONE</property>
- <property name="validator_type">wxDefaultValidator</property>
- <property name="validator_variable"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style"></property>
- <event name="OnButtonClick">OnButtonOK</event>
- <event name="OnChar"></event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnKeyDown"></event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint"></event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnUpdateUI"></event>
- </object>
- </object>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND</property>
- <property name="proportion">0</property>
- <object class="wxButton" expanded="1">
- <property name="bg"></property>
- <property name="context_help"></property>
- <property name="default">0</property>
- <property name="enabled">1</property>
- <property name="fg"></property>
- <property name="font"></property>
- <property name="hidden">0</property>
- <property name="id">wxID_CANCEL</property>
- <property name="label">Cancel</property>
- <property name="maximum_size"></property>
- <property name="minimum_size">-1,-1</property>
- <property name="name">m_buttonCancel</property>
- <property name="permission">public</property>
- <property name="pos"></property>
- <property name="size">-1,-1</property>
- <property name="style"></property>
- <property name="subclass"></property>
- <property name="tooltip"></property>
- <property name="validator_data_type"></property>
- <property name="validator_style">wxFILTER_NONE</property>
- <property name="validator_type">wxDefaultValidator</property>
- <property name="validator_variable"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style"></property>
- <event name="OnButtonClick">OnButtonCancel</event>
- <event name="OnChar"></event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnKeyDown"></event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint"></event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnUpdateUI"></event>
- </object>
- </object>
- </object>
- </object>
- </object>
- </object>
- <object class="Dialog" expanded="0">
- <property name="bg"></property>
- <property name="center"></property>
- <property name="context_help"></property>
- <property name="enabled">1</property>
- <property name="extra_style"></property>
- <property name="fg"></property>
- <property name="font"></property>
- <property name="hidden">0</property>
- <property name="id">wxID_ANY</property>
- <property name="maximum_size"></property>
- <property name="minimum_size"></property>
- <property name="name">CGetTextFromUserDialogBase</property>
- <property name="pos"></property>
- <property name="size">440,138</property>
- <property name="style">wxDEFAULT_DIALOG_STYLE</property>
- <property name="subclass"></property>
- <property name="title"></property>
- <property name="tooltip"></property>
- <property name="validator_data_type"></property>
- <property name="validator_style">wxFILTER_NONE</property>
- <property name="validator_type">wxDefaultValidator</property>
- <property name="validator_variable"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style"></property>
- <event name="OnActivate"></event>
- <event name="OnActivateApp"></event>
- <event name="OnChar"></event>
- <event name="OnClose">OnClose</event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnHibernate"></event>
- <event name="OnIconize"></event>
- <event name="OnIdle"></event>
- <event name="OnInitDialog"></event>
- <event name="OnKeyDown"></event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint"></event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnUpdateUI"></event>
- <object class="wxBoxSizer" expanded="1">
- <property name="minimum_size"></property>
- <property name="name">bSizer79</property>
- <property name="orient">wxVERTICAL</property>
- <property name="permission">none</property>
- <object class="sizeritem" expanded="1">
- <property name="border">10</property>
- <property name="flag">wxEXPAND|wxALL</property>
- <property name="proportion">1</property>
- <object class="wxBoxSizer" expanded="1">
- <property name="minimum_size"></property>
- <property name="name">bSizer81</property>
- <property name="orient">wxVERTICAL</property>
- <property name="permission">none</property>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxEXPAND</property>
- <property name="proportion">1</property>
- <object class="spacer" expanded="1">
- <property name="height">0</property>
- <property name="permission">protected</property>
- <property name="width">0</property>
- </object>
- </object>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxTOP|wxRIGHT|wxLEFT</property>
- <property name="proportion">0</property>
- <object class="wxStaticText" expanded="1">
- <property name="bg"></property>
- <property name="context_help"></property>
- <property name="enabled">1</property>
- <property name="fg"></property>
- <property name="font"></property>
- <property name="hidden">0</property>
- <property name="id">wxID_ANY</property>
- <property name="label"></property>
- <property name="maximum_size"></property>
- <property name="minimum_size"></property>
- <property name="name">m_staticTextMessage1</property>
- <property name="permission">protected</property>
- <property name="pos"></property>
- <property name="size"></property>
- <property name="style"></property>
- <property name="subclass"></property>
- <property name="tooltip"></property>
- <property name="validator_data_type"></property>
- <property name="validator_style">wxFILTER_NONE</property>
- <property name="validator_type">wxDefaultValidator</property>
- <property name="validator_variable"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style"></property>
- <property name="wrap">-1</property>
- <event name="OnChar"></event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnKeyDown"></event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint"></event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnUpdateUI"></event>
- </object>
- </object>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxALL|wxEXPAND|wxALIGN_CENTER_HORIZONTAL</property>
- <property name="proportion">0</property>
- <object class="wxTextCtrl" expanded="1">
- <property name="bg"></property>
- <property name="context_help"></property>
- <property name="enabled">1</property>
- <property name="fg"></property>
- <property name="font"></property>
- <property name="hidden">0</property>
- <property name="id">wxID_TEXTCTRL</property>
- <property name="maximum_size"></property>
- <property name="maxlength">0</property>
- <property name="minimum_size"></property>
- <property name="name">m_textCtrl1</property>
- <property name="permission">protected</property>
- <property name="pos"></property>
- <property name="size"></property>
- <property name="style">wxTE_PROCESS_ENTER</property>
- <property name="subclass"></property>
- <property name="tooltip"></property>
- <property name="validator_data_type"></property>
- <property name="validator_style">wxFILTER_NONE</property>
- <property name="validator_type">wxDefaultValidator</property>
- <property name="validator_variable"></property>
- <property name="value"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style"></property>
- <event name="OnChar"></event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnKeyDown">OnKeyDown</event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint"></event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnText"></event>
- <event name="OnTextEnter"></event>
- <event name="OnTextMaxLen"></event>
- <event name="OnTextURL"></event>
- <event name="OnUpdateUI"></event>
- </object>
- </object>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxTOP|wxRIGHT|wxLEFT</property>
- <property name="proportion">0</property>
- <object class="wxStaticText" expanded="1">
- <property name="bg"></property>
- <property name="context_help"></property>
- <property name="enabled">1</property>
- <property name="fg"></property>
- <property name="font"></property>
- <property name="hidden">1</property>
- <property name="id">wxID_ANY</property>
- <property name="label"></property>
- <property name="maximum_size"></property>
- <property name="minimum_size"></property>
- <property name="name">m_staticTextMessage2</property>
- <property name="permission">protected</property>
- <property name="pos"></property>
- <property name="size"></property>
- <property name="style"></property>
- <property name="subclass"></property>
- <property name="tooltip"></property>
- <property name="validator_data_type"></property>
- <property name="validator_style">wxFILTER_NONE</property>
- <property name="validator_type">wxDefaultValidator</property>
- <property name="validator_variable"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style"></property>
- <property name="wrap">-1</property>
- <event name="OnChar"></event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnKeyDown"></event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint"></event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnUpdateUI"></event>
- </object>
- </object>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxALL|wxEXPAND|wxALIGN_CENTER_HORIZONTAL</property>
- <property name="proportion">0</property>
- <object class="wxTextCtrl" expanded="1">
- <property name="bg"></property>
- <property name="context_help"></property>
- <property name="enabled">1</property>
- <property name="fg"></property>
- <property name="font"></property>
- <property name="hidden">1</property>
- <property name="id">wxID_TEXTCTRL</property>
- <property name="maximum_size"></property>
- <property name="maxlength">0</property>
- <property name="minimum_size"></property>
- <property name="name">m_textCtrl2</property>
- <property name="permission">protected</property>
- <property name="pos"></property>
- <property name="size"></property>
- <property name="style">wxTE_PROCESS_ENTER</property>
- <property name="subclass"></property>
- <property name="tooltip"></property>
- <property name="validator_data_type"></property>
- <property name="validator_style">wxFILTER_NONE</property>
- <property name="validator_type">wxDefaultValidator</property>
- <property name="validator_variable"></property>
- <property name="value"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style"></property>
- <event name="OnChar"></event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnKeyDown">OnKeyDown</event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint"></event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnText"></event>
- <event name="OnTextEnter"></event>
- <event name="OnTextMaxLen"></event>
- <event name="OnTextURL"></event>
- <event name="OnUpdateUI"></event>
- </object>
- </object>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxEXPAND</property>
- <property name="proportion">1</property>
- <object class="spacer" expanded="1">
- <property name="height">0</property>
- <property name="permission">protected</property>
- <property name="width">0</property>
- </object>
- </object>
- </object>
- </object>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxEXPAND</property>
- <property name="proportion">0</property>
- <object class="wxBoxSizer" expanded="1">
- <property name="minimum_size"></property>
- <property name="name">bSizer80</property>
- <property name="orient">wxHORIZONTAL</property>
- <property name="permission">none</property>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxEXPAND</property>
- <property name="proportion">1</property>
- <object class="spacer" expanded="1">
- <property name="height">0</property>
- <property name="permission">protected</property>
- <property name="width">0</property>
- </object>
- </object>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND</property>
- <property name="proportion">0</property>
- <object class="wxButton" expanded="1">
- <property name="bg"></property>
- <property name="context_help"></property>
- <property name="default">0</property>
- <property name="enabled">1</property>
- <property name="fg"></property>
- <property name="font"></property>
- <property name="hidden">0</property>
- <property name="id">wxID_OK</property>
- <property name="label">OK</property>
- <property name="maximum_size"></property>
- <property name="minimum_size">-1,-1</property>
- <property name="name">m_buttonOK</property>
- <property name="permission">protected</property>
- <property name="pos"></property>
- <property name="size">-1,-1</property>
- <property name="style"></property>
- <property name="subclass"></property>
- <property name="tooltip"></property>
- <property name="validator_data_type"></property>
- <property name="validator_style">wxFILTER_NONE</property>
- <property name="validator_type">wxDefaultValidator</property>
- <property name="validator_variable"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style"></property>
- <event name="OnButtonClick">OnButtonOK</event>
- <event name="OnChar"></event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnKeyDown"></event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint"></event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnUpdateUI"></event>
- </object>
- </object>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND</property>
- <property name="proportion">0</property>
- <object class="wxButton" expanded="1">
- <property name="bg"></property>
- <property name="context_help"></property>
- <property name="default">0</property>
- <property name="enabled">1</property>
- <property name="fg"></property>
- <property name="font"></property>
- <property name="hidden">0</property>
- <property name="id">wxID_CANCEL</property>
- <property name="label">Cancel</property>
- <property name="maximum_size"></property>
- <property name="minimum_size">-1,-1</property>
- <property name="name">m_buttonCancel</property>
- <property name="permission">protected</property>
- <property name="pos"></property>
- <property name="size"></property>
- <property name="style"></property>
- <property name="subclass"></property>
- <property name="tooltip"></property>
- <property name="validator_data_type"></property>
- <property name="validator_style">wxFILTER_NONE</property>
- <property name="validator_type">wxDefaultValidator</property>
- <property name="validator_variable"></property>
- <property name="window_extra_style"></property>
- <property name="window_name"></property>
- <property name="window_style"></property>
- <event name="OnButtonClick">OnButtonCancel</event>
- <event name="OnChar"></event>
- <event name="OnEnterWindow"></event>
- <event name="OnEraseBackground"></event>
- <event name="OnKeyDown"></event>
- <event name="OnKeyUp"></event>
- <event name="OnKillFocus"></event>
- <event name="OnLeaveWindow"></event>
- <event name="OnLeftDClick"></event>
- <event name="OnLeftDown"></event>
- <event name="OnLeftUp"></event>
- <event name="OnMiddleDClick"></event>
- <event name="OnMiddleDown"></event>
- <event name="OnMiddleUp"></event>
- <event name="OnMotion"></event>
- <event name="OnMouseEvents"></event>
- <event name="OnMouseWheel"></event>
- <event name="OnPaint"></event>
- <event name="OnRightDClick"></event>
- <event name="OnRightDown"></event>
- <event name="OnRightUp"></event>
- <event name="OnSetFocus"></event>
- <event name="OnSize"></event>
- <event name="OnUpdateUI"></event>
- </object>
- </object>
- </object>
- </object>
- </object>
- </object>
- </object>
-</wxFormBuilder_Project>
diff --git a/src/base58.h b/src/base58.h index c2729d4770..592756ff74 100644 --- a/src/base58.h +++ b/src/base58.h @@ -1,4 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto +// Copyright (c) 2011 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. @@ -159,52 +160,149 @@ inline bool DecodeBase58Check(const std::string& str, std::vector<unsigned char> -#define ADDRESSVERSION ((unsigned char)(fTestNet ? 111 : 0)) - -inline std::string Hash160ToAddress(uint160 hash160) +class CBase58Data { - // add 1-byte version number to the front - std::vector<unsigned char> vch(1, ADDRESSVERSION); - vch.insert(vch.end(), UBEGIN(hash160), UEND(hash160)); - return EncodeBase58Check(vch); -} +protected: + unsigned char nVersion; + std::vector<unsigned char> vchData; -inline bool AddressToHash160(const char* psz, uint160& hash160Ret) -{ - std::vector<unsigned char> vch; - if (!DecodeBase58Check(psz, vch)) - return false; - if (vch.empty()) - return false; - unsigned char nVersion = vch[0]; - if (vch.size() != sizeof(hash160Ret) + 1) - return false; - memcpy(&hash160Ret, &vch[1], sizeof(hash160Ret)); - return (nVersion <= ADDRESSVERSION); -} + CBase58Data() + { + nVersion = 0; + vchData.clear(); + } -inline bool AddressToHash160(const std::string& str, uint160& hash160Ret) -{ - return AddressToHash160(str.c_str(), hash160Ret); -} + ~CBase58Data() + { + if (!vchData.empty()) + memset(&vchData[0], 0, vchData.size()); + } -inline bool IsValidBitcoinAddress(const char* psz) -{ - uint160 hash160; - return AddressToHash160(psz, hash160); -} + void SetData(int nVersionIn, const void* pdata, size_t nSize) + { + nVersion = nVersionIn; + vchData.resize(nSize); + if (!vchData.empty()) + memcpy(&vchData[0], pdata, nSize); + } -inline bool IsValidBitcoinAddress(const std::string& str) -{ - return IsValidBitcoinAddress(str.c_str()); -} + void SetData(int nVersionIn, const unsigned char *pbegin, const unsigned char *pend) + { + SetData(nVersionIn, (void*)pbegin, pend - pbegin); + } + +public: + bool SetString(const char* psz) + { + std::vector<unsigned char> vchTemp; + DecodeBase58Check(psz, vchTemp); + if (vchTemp.empty()) + { + vchData.clear(); + nVersion = 0; + return false; + } + nVersion = vchTemp[0]; + vchData.resize(vchTemp.size() - 1); + if (!vchData.empty()) + memcpy(&vchData[0], &vchTemp[1], vchData.size()); + memset(&vchTemp[0], 0, vchTemp.size()); + return true; + } + + bool SetString(const std::string& str) + { + return SetString(str.c_str()); + } + std::string ToString() const + { + std::vector<unsigned char> vch(1, nVersion); + vch.insert(vch.end(), vchData.begin(), vchData.end()); + return EncodeBase58Check(vch); + } + + int CompareTo(const CBase58Data& b58) const + { + if (nVersion < b58.nVersion) return -1; + if (nVersion > b58.nVersion) return 1; + if (vchData < b58.vchData) return -1; + if (vchData > b58.vchData) return 1; + return 0; + } + bool operator==(const CBase58Data& b58) const { return CompareTo(b58) == 0; } + bool operator<=(const CBase58Data& b58) const { return CompareTo(b58) <= 0; } + bool operator>=(const CBase58Data& b58) const { return CompareTo(b58) >= 0; } + bool operator< (const CBase58Data& b58) const { return CompareTo(b58) < 0; } + bool operator> (const CBase58Data& b58) const { return CompareTo(b58) > 0; } +}; -inline std::string PubKeyToAddress(const std::vector<unsigned char>& vchPubKey) +class CBitcoinAddress : public CBase58Data { - return Hash160ToAddress(Hash160(vchPubKey)); -} +public: + bool SetHash160(const uint160& hash160) + { + SetData(fTestNet ? 111 : 0, &hash160, 20); + return true; + } + + bool SetPubKey(const std::vector<unsigned char>& vchPubKey) + { + return SetHash160(Hash160(vchPubKey)); + } + + bool IsValid() const + { + int nExpectedSize = 20; + bool fExpectTestNet = false; + switch(nVersion) + { + case 0: + break; + + case 111: + fExpectTestNet = true; + break; + + default: + return false; + } + return fExpectTestNet == fTestNet && vchData.size() == nExpectedSize; + } + + CBitcoinAddress() + { + } + + CBitcoinAddress(uint160 hash160In) + { + SetHash160(hash160In); + } + + CBitcoinAddress(const std::vector<unsigned char>& vchPubKey) + { + SetPubKey(vchPubKey); + } + + CBitcoinAddress(const std::string& strAddress) + { + SetString(strAddress); + } + + CBitcoinAddress(const char* pszAddress) + { + SetString(pszAddress); + } + + uint160 GetHash160() const + { + assert(vchData.size() == 20); + uint160 hash160; + memcpy(&hash160, &vchData[0], 20); + return hash160; + } +}; #endif diff --git a/src/bignum.h b/src/bignum.h index 5eaa4028b7..1a2406b935 100644 --- a/src/bignum.h +++ b/src/bignum.h @@ -1,4 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto +// Copyright (c) 2011 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. #ifndef BITCOIN_BIGNUM_H diff --git a/src/rpc.cpp b/src/bitcoinrpc.cpp index 09be63203a..d3d92c8e7e 100644 --- a/src/rpc.cpp +++ b/src/bitcoinrpc.cpp @@ -1,9 +1,9 @@ // Copyright (c) 2010 Satoshi Nakamoto +// Copyright (c) 2011 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. #include "headers.h" -#include "cryptopp/sha.h" #include "db.h" #include "net.h" #include "init.h" @@ -36,6 +36,9 @@ void ThreadRPCServer2(void* parg); typedef Value(*rpcfn_type)(const Array& params, bool fHelp); extern map<string, rpcfn_type> mapCallTable; +static int64 nWalletUnlockTime; +static CCriticalSection cs_nWalletUnlockTime; + Object JSONRPCError(int code, const string& message) { @@ -46,13 +49,13 @@ Object JSONRPCError(int code, const string& message) } -void PrintConsole(const char* format, ...) +void PrintConsole(const std::string &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); + int ret = _vsnprintf(buffer, limit, format.c_str(), arg_ptr); va_end(arg_ptr); if (ret < 0 || ret >= limit) { @@ -60,11 +63,7 @@ void PrintConsole(const char* format, ...) buffer[limit-1] = 0; } printf("%s", buffer); -#if defined(__WXMSW__) && defined(GUI) - MyMessageBox(buffer, "Bitcoin", wxOK | wxICON_EXCLAMATION); -#else fprintf(stdout, "%s", buffer); -#endif } @@ -309,7 +308,10 @@ Value getinfo(const Array& params, bool fHelp) obj.push_back(Pair("hashespersec", gethashespersec(params, false))); obj.push_back(Pair("testnet", fTestNet)); obj.push_back(Pair("keypoololdest", (boost::int64_t)pwalletMain->GetOldestKeyPoolTime())); + obj.push_back(Pair("keypoolsize", pwalletMain->GetKeyPoolSize())); obj.push_back(Pair("paytxfee", ValueFromAmount(nTransactionFee))); + if (pwalletMain->IsCrypted()) + obj.push_back(Pair("unlocked_until", (boost::int64_t)nWalletUnlockTime)); obj.push_back(Pair("errors", GetWarnings("statusbar"))); return obj; } @@ -329,28 +331,30 @@ Value getnewaddress(const Array& params, bool fHelp) if (params.size() > 0) strAccount = AccountFromValue(params[0]); + if (!pwalletMain->IsLocked()) + pwalletMain->TopUpKeyPool(); + // Generate a new key that is added to wallet - string strAddress = PubKeyToAddress(pwalletMain->GetKeyFromKeyPool()); + std::vector<unsigned char> newKey; + if (!pwalletMain->GetKeyFromPool(newKey, false)) + throw JSONRPCError(-12, "Error: Keypool ran out, please call keypoolrefill first"); + CBitcoinAddress address(newKey); - // This could be done in the same main CS as GetKeyFromKeyPool. - CRITICAL_BLOCK(pwalletMain->cs_mapAddressBook) - pwalletMain->SetAddressBookName(strAddress, strAccount); + pwalletMain->SetAddressBookName(address, strAccount); - return strAddress; + return address.ToString(); } -// requires cs_main, cs_mapWallet, cs_mapAddressBook locks -string GetAccountAddress(string strAccount, bool bForceNew=false) +CBitcoinAddress GetAccountAddress(string strAccount, bool bForceNew=false) { - string strAddress; - CWalletDB walletdb(pwalletMain->strWalletFile); - walletdb.TxnBegin(); CAccount account; walletdb.ReadAccount(strAccount, account); + bool bKeyUsed = false; + // Check if the current key has been used if (!account.vchPubKey.empty()) { @@ -363,23 +367,21 @@ string GetAccountAddress(string strAccount, bool bForceNew=false) const CWalletTx& wtx = (*it).second; BOOST_FOREACH(const CTxOut& txout, wtx.vout) if (txout.scriptPubKey == scriptPubKey) - account.vchPubKey.clear(); + bKeyUsed = true; } } // Generate a new key - if (account.vchPubKey.empty() || bForceNew) + if (account.vchPubKey.empty() || bForceNew || bKeyUsed) { - account.vchPubKey = pwalletMain->GetKeyFromKeyPool(); - string strAddress = PubKeyToAddress(account.vchPubKey); - pwalletMain->SetAddressBookName(strAddress, strAccount); + if (!pwalletMain->GetKeyFromPool(account.vchPubKey, false)) + throw JSONRPCError(-12, "Error: Keypool ran out, please call keypoolrefill first"); + + pwalletMain->SetAddressBookName(CBitcoinAddress(account.vchPubKey), strAccount); walletdb.WriteAccount(strAccount, account); } - walletdb.TxnCommit(); - strAddress = PubKeyToAddress(account.vchPubKey); - - return strAddress; + return CBitcoinAddress(account.vchPubKey); } Value getaccountaddress(const Array& params, bool fHelp) @@ -394,12 +396,7 @@ Value getaccountaddress(const Array& params, bool fHelp) Value ret; - CRITICAL_BLOCK(cs_main) - CRITICAL_BLOCK(pwalletMain->cs_mapWallet) - CRITICAL_BLOCK(pwalletMain->cs_mapAddressBook) - { - ret = GetAccountAddress(strAccount); - } + ret = GetAccountAddress(strAccount).ToString(); return ret; } @@ -413,10 +410,8 @@ Value setaccount(const Array& params, bool fHelp) "setaccount <bitcoinaddress> <account>\n" "Sets the account associated with the given address."); - string strAddress = params[0].get_str(); - uint160 hash160; - bool isValid = AddressToHash160(strAddress, hash160); - if (!isValid) + CBitcoinAddress address(params[0].get_str()); + if (!address.IsValid()) throw JSONRPCError(-5, "Invalid bitcoin address"); @@ -425,20 +420,15 @@ Value setaccount(const Array& params, bool fHelp) strAccount = AccountFromValue(params[1]); // Detect when changing the account of an address that is the 'unused current key' of another account: - CRITICAL_BLOCK(cs_main) - CRITICAL_BLOCK(pwalletMain->cs_mapWallet) - CRITICAL_BLOCK(pwalletMain->cs_mapAddressBook) + if (pwalletMain->mapAddressBook.count(address)) { - if (pwalletMain->mapAddressBook.count(strAddress)) - { - string strOldAccount = pwalletMain->mapAddressBook[strAddress]; - if (strAddress == GetAccountAddress(strOldAccount)) - GetAccountAddress(strOldAccount, true); - } - - pwalletMain->SetAddressBookName(strAddress, strAccount); + string strOldAccount = pwalletMain->mapAddressBook[address]; + if (address == GetAccountAddress(strOldAccount)) + GetAccountAddress(strOldAccount, true); } + pwalletMain->SetAddressBookName(address, strAccount); + return Value::null; } @@ -450,15 +440,14 @@ Value getaccount(const Array& params, bool fHelp) "getaccount <bitcoinaddress>\n" "Returns the account associated with the given address."); - string strAddress = params[0].get_str(); + CBitcoinAddress address(params[0].get_str()); + if (!address.IsValid()) + throw JSONRPCError(-5, "Invalid bitcoin address"); string strAccount; - CRITICAL_BLOCK(pwalletMain->cs_mapAddressBook) - { - map<string, string>::iterator mi = pwalletMain->mapAddressBook.find(strAddress); - if (mi != pwalletMain->mapAddressBook.end() && !(*mi).second.empty()) - strAccount = (*mi).second; - } + map<CBitcoinAddress, string>::iterator mi = pwalletMain->mapAddressBook.find(address); + if (mi != pwalletMain->mapAddressBook.end() && !(*mi).second.empty()) + strAccount = (*mi).second; return strAccount; } @@ -474,20 +463,12 @@ Value getaddressesbyaccount(const Array& params, bool fHelp) // Find all addresses that have the given account Array ret; - CRITICAL_BLOCK(pwalletMain->cs_mapAddressBook) + BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress, string)& item, pwalletMain->mapAddressBook) { - BOOST_FOREACH(const PAIRTYPE(string, string)& item, pwalletMain->mapAddressBook) - { - const string& strAddress = item.first; - const string& strName = item.second; - if (strName == strAccount) - { - // We're only adding valid bitcoin addresses and not ip addresses - CScript scriptPubKey; - if (scriptPubKey.SetBitcoinAddress(strAddress)) - ret.push_back(strAddress); - } - } + const CBitcoinAddress& address = item.first; + const string& strName = item.second; + if (strName == strAccount) + ret.push_back(address.ToString()); } return ret; } @@ -510,12 +491,19 @@ Value settxfee(const Array& params, bool fHelp) Value sendtoaddress(const Array& params, bool fHelp) { - if (fHelp || params.size() < 2 || params.size() > 4) + 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)) throw runtime_error( "sendtoaddress <bitcoinaddress> <amount> [comment] [comment-to]\n" "<amount> is a real and is rounded to the nearest 0.00000001"); - string strAddress = params[0].get_str(); + CBitcoinAddress address(params[0].get_str()); + if (!address.IsValid()) + throw JSONRPCError(-5, "Invalid bitcoin address"); // Amount int64 nAmount = AmountFromValue(params[1]); @@ -527,16 +515,82 @@ Value sendtoaddress(const Array& params, bool fHelp) if (params.size() > 3 && params[3].type() != null_type && !params[3].get_str().empty()) wtx.mapValue["to"] = params[3].get_str(); - CRITICAL_BLOCK(cs_main) - { - string strError = pwalletMain->SendMoneyToBitcoinAddress(strAddress, nAmount, wtx); - if (strError != "") - throw JSONRPCError(-4, strError); - } + if (pwalletMain->IsLocked()) + throw JSONRPCError(-13, "Error: Please enter the wallet passphrase with walletpassphrase first."); + + string strError = pwalletMain->SendMoneyToBitcoinAddress(address, nAmount, wtx); + if (strError != "") + throw JSONRPCError(-4, strError); return wtx.GetHash().GetHex(); } +static const string strMessageMagic = "Bitcoin Signed Message:\n"; + +Value signmessage(const Array& params, bool fHelp) +{ + if (fHelp || params.size() != 2) + throw runtime_error( + "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."); + + string strAddress = params[0].get_str(); + string strMessage = params[1].get_str(); + + CBitcoinAddress addr(strAddress); + if (!addr.IsValid()) + throw JSONRPCError(-3, "Invalid address"); + + CKey key; + if (!pwalletMain->GetKey(addr, key)) + throw JSONRPCError(-4, "Private key not available"); + + CDataStream ss(SER_GETHASH); + ss << strMessageMagic; + ss << strMessage; + + vector<unsigned char> vchSig; + if (!key.SignCompact(Hash(ss.begin(), ss.end()), vchSig)) + throw JSONRPCError(-5, "Sign failed"); + + return EncodeBase64(&vchSig[0], vchSig.size()); +} + +Value verifymessage(const Array& params, bool fHelp) +{ + if (fHelp || params.size() != 3) + throw runtime_error( + "verifymessage <bitcoinaddress> <signature> <message>\n" + "Verify a signed message"); + + string strAddress = params[0].get_str(); + string strSign = params[1].get_str(); + string strMessage = params[2].get_str(); + + CBitcoinAddress addr(strAddress); + if (!addr.IsValid()) + throw JSONRPCError(-3, "Invalid address"); + + bool fInvalid = false; + vector<unsigned char> vchSig = DecodeBase64(strSign.c_str(), &fInvalid); + + if (fInvalid) + throw JSONRPCError(-5, "Malformed base64 encoding"); + + CDataStream ss(SER_GETHASH); + ss << strMessageMagic; + ss << strMessage; + + CKey key; + if (!key.SetCompactSignature(Hash(ss.begin(), ss.end()), vchSig)) + return false; + + return (key.GetAddress() == addr); +} + Value getreceivedbyaddress(const Array& params, bool fHelp) { @@ -546,10 +600,11 @@ Value getreceivedbyaddress(const Array& params, bool fHelp) "Returns the total amount received by <bitcoinaddress> in transactions with at least [minconf] confirmations."); // Bitcoin address - string strAddress = params[0].get_str(); + CBitcoinAddress address = CBitcoinAddress(params[0].get_str()); CScript scriptPubKey; - if (!scriptPubKey.SetBitcoinAddress(strAddress)) + if (!address.IsValid()) throw JSONRPCError(-5, "Invalid bitcoin address"); + scriptPubKey.SetBitcoinAddress(address); if (!IsMine(*pwalletMain,scriptPubKey)) return (double)0.0; @@ -560,42 +615,30 @@ Value getreceivedbyaddress(const Array& params, bool fHelp) // Tally int64 nAmount = 0; - CRITICAL_BLOCK(pwalletMain->cs_mapWallet) + for (map<uint256, CWalletTx>::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); ++it) { - for (map<uint256, CWalletTx>::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); ++it) - { - const CWalletTx& wtx = (*it).second; - if (wtx.IsCoinBase() || !wtx.IsFinal()) - continue; + const CWalletTx& wtx = (*it).second; + if (wtx.IsCoinBase() || !wtx.IsFinal()) + continue; - BOOST_FOREACH(const CTxOut& txout, wtx.vout) - if (txout.scriptPubKey == scriptPubKey) - if (wtx.GetDepthInMainChain() >= nMinDepth) - nAmount += txout.nValue; - } + BOOST_FOREACH(const CTxOut& txout, wtx.vout) + if (txout.scriptPubKey == scriptPubKey) + if (wtx.GetDepthInMainChain() >= nMinDepth) + nAmount += txout.nValue; } return ValueFromAmount(nAmount); } -void GetAccountPubKeys(string strAccount, set<CScript>& setPubKey) +void GetAccountAddresses(string strAccount, set<CBitcoinAddress>& setAddress) { - CRITICAL_BLOCK(pwalletMain->cs_mapAddressBook) + BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress, string)& item, pwalletMain->mapAddressBook) { - BOOST_FOREACH(const PAIRTYPE(string, string)& item, pwalletMain->mapAddressBook) - { - const string& strAddress = item.first; - const string& strName = item.second; - if (strName == strAccount) - { - // We're only counting our own valid bitcoin addresses and not ip addresses - CScript scriptPubKey; - if (scriptPubKey.SetBitcoinAddress(strAddress)) - if (IsMine(*pwalletMain,scriptPubKey)) - setPubKey.insert(scriptPubKey); - } - } + const CBitcoinAddress& address = item.first; + const string& strName = item.second; + if (strName == strAccount) + setAddress.insert(address); } } @@ -614,23 +657,23 @@ Value getreceivedbyaccount(const Array& params, bool fHelp) // Get the set of pub keys that have the label string strAccount = AccountFromValue(params[0]); - set<CScript> setPubKey; - GetAccountPubKeys(strAccount, setPubKey); + set<CBitcoinAddress> setAddress; + GetAccountAddresses(strAccount, setAddress); // Tally int64 nAmount = 0; - CRITICAL_BLOCK(pwalletMain->cs_mapWallet) + for (map<uint256, CWalletTx>::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); ++it) { - for (map<uint256, CWalletTx>::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); ++it) - { - const CWalletTx& wtx = (*it).second; - if (wtx.IsCoinBase() || !wtx.IsFinal()) - continue; + const CWalletTx& wtx = (*it).second; + if (wtx.IsCoinBase() || !wtx.IsFinal()) + continue; - BOOST_FOREACH(const CTxOut& txout, wtx.vout) - if (setPubKey.count(txout.scriptPubKey)) - if (wtx.GetDepthInMainChain() >= nMinDepth) - nAmount += txout.nValue; + BOOST_FOREACH(const CTxOut& txout, wtx.vout) + { + CBitcoinAddress address; + if (ExtractAddress(txout.scriptPubKey, pwalletMain, address) && setAddress.count(address)) + if (wtx.GetDepthInMainChain() >= nMinDepth) + nAmount += txout.nValue; } } @@ -641,27 +684,25 @@ Value getreceivedbyaccount(const Array& params, bool fHelp) int64 GetAccountBalance(CWalletDB& walletdb, const string& strAccount, int nMinDepth) { int64 nBalance = 0; - CRITICAL_BLOCK(pwalletMain->cs_mapWallet) - { - // Tally wallet transactions - for (map<uint256, CWalletTx>::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); ++it) - { - const CWalletTx& wtx = (*it).second; - if (!wtx.IsFinal()) - continue; - int64 nGenerated, nReceived, nSent, nFee; - wtx.GetAccountAmounts(strAccount, nGenerated, nReceived, nSent, nFee); + // Tally wallet transactions + for (map<uint256, CWalletTx>::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); ++it) + { + const CWalletTx& wtx = (*it).second; + if (!wtx.IsFinal()) + continue; - if (nReceived != 0 && wtx.GetDepthInMainChain() >= nMinDepth) - nBalance += nReceived; - nBalance += nGenerated - nSent - nFee; - } + int64 nGenerated, nReceived, nSent, nFee; + wtx.GetAccountAmounts(strAccount, nGenerated, nReceived, nSent, nFee); - // Tally internal accounting entries - nBalance += walletdb.GetAccountCreditDebit(strAccount); + if (nReceived != 0 && wtx.GetDepthInMainChain() >= nMinDepth) + nBalance += nReceived; + nBalance += nGenerated - nSent - nFee; } + // Tally internal accounting entries + nBalance += walletdb.GetAccountCreditDebit(strAccount); + return nBalance; } @@ -674,7 +715,7 @@ int64 GetAccountBalance(const string& strAccount, int nMinDepth) Value getbalance(const Array& params, bool fHelp) { - if (fHelp || params.size() < 0 || params.size() > 2) + if (fHelp || params.size() > 2) throw runtime_error( "getbalance [account] [minconf=1]\n" "If [account] is not specified, returns the server's total available balance.\n" @@ -701,13 +742,13 @@ Value getbalance(const Array& params, bool fHelp) int64 allGeneratedImmature, allGeneratedMature, allFee; allGeneratedImmature = allGeneratedMature = allFee = 0; string strSentAccount; - list<pair<string, int64> > listReceived; - list<pair<string, int64> > listSent; + list<pair<CBitcoinAddress, int64> > listReceived; + list<pair<CBitcoinAddress, int64> > listSent; wtx.GetAmounts(allGeneratedImmature, allGeneratedMature, listReceived, listSent, allFee, strSentAccount); if (wtx.GetDepthInMainChain() >= nMinDepth) - BOOST_FOREACH(const PAIRTYPE(string,int64)& r, listReceived) + BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress,int64)& r, listReceived) nBalance += r.second; - BOOST_FOREACH(const PAIRTYPE(string,int64)& r, listSent) + BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress,int64)& r, listSent) nBalance -= r.second; nBalance -= allFee; nBalance += allGeneratedMature; @@ -733,53 +774,58 @@ Value movecmd(const Array& params, bool fHelp) string strFrom = AccountFromValue(params[0]); string strTo = AccountFromValue(params[1]); int64 nAmount = AmountFromValue(params[2]); - int nMinDepth = 1; if (params.size() > 3) - nMinDepth = params[3].get_int(); + // unused parameter, used to be nMinDepth, keep type-checking it though + (void)params[3].get_int(); string strComment; if (params.size() > 4) strComment = params[4].get_str(); - CRITICAL_BLOCK(pwalletMain->cs_mapWallet) - { - CWalletDB walletdb(pwalletMain->strWalletFile); - walletdb.TxnBegin(); - - int64 nNow = GetAdjustedTime(); - - // Debit - CAccountingEntry debit; - debit.strAccount = strFrom; - debit.nCreditDebit = -nAmount; - debit.nTime = nNow; - debit.strOtherAccount = strTo; - debit.strComment = strComment; - walletdb.WriteAccountingEntry(debit); - - // Credit - CAccountingEntry credit; - credit.strAccount = strTo; - credit.nCreditDebit = nAmount; - credit.nTime = nNow; - credit.strOtherAccount = strFrom; - credit.strComment = strComment; - walletdb.WriteAccountingEntry(credit); - - walletdb.TxnCommit(); - } + CWalletDB walletdb(pwalletMain->strWalletFile); + walletdb.TxnBegin(); + + int64 nNow = GetAdjustedTime(); + + // Debit + CAccountingEntry debit; + debit.strAccount = strFrom; + debit.nCreditDebit = -nAmount; + debit.nTime = nNow; + debit.strOtherAccount = strTo; + debit.strComment = strComment; + walletdb.WriteAccountingEntry(debit); + + // Credit + CAccountingEntry credit; + credit.strAccount = strTo; + credit.nCreditDebit = nAmount; + credit.nTime = nNow; + credit.strOtherAccount = strFrom; + credit.strComment = strComment; + walletdb.WriteAccountingEntry(credit); + + walletdb.TxnCommit(); + return true; } Value sendfrom(const Array& params, bool fHelp) { - if (fHelp || params.size() < 3 || params.size() > 6) + 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\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"); string strAccount = AccountFromValue(params[0]); - string strAddress = params[1].get_str(); + CBitcoinAddress address(params[1].get_str()); + if (!address.IsValid()) + throw JSONRPCError(-5, "Invalid bitcoin address"); int64 nAmount = AmountFromValue(params[2]); int nMinDepth = 1; if (params.size() > 3) @@ -792,26 +838,31 @@ 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(); - CRITICAL_BLOCK(cs_main) - CRITICAL_BLOCK(pwalletMain->cs_mapWallet) - { - // Check funds - int64 nBalance = GetAccountBalance(strAccount, nMinDepth); - if (nAmount > nBalance) - throw JSONRPCError(-6, "Account has insufficient funds"); + if (pwalletMain->IsLocked()) + throw JSONRPCError(-13, "Error: Please enter the wallet passphrase with walletpassphrase first."); - // Send - string strError = pwalletMain->SendMoneyToBitcoinAddress(strAddress, nAmount, wtx); - if (strError != "") - throw JSONRPCError(-4, strError); - } + // Check funds + int64 nBalance = GetAccountBalance(strAccount, nMinDepth); + if (nAmount > nBalance) + throw JSONRPCError(-6, "Account has insufficient funds"); + + // Send + string strError = pwalletMain->SendMoneyToBitcoinAddress(address, nAmount, wtx); + if (strError != "") + throw JSONRPCError(-4, strError); return wtx.GetHash().GetHex(); } + Value sendmany(const Array& params, bool fHelp) { - if (fHelp || params.size() < 2 || params.size() > 4) + 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\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"); @@ -827,49 +878,48 @@ Value sendmany(const Array& params, bool fHelp) if (params.size() > 3 && params[3].type() != null_type && !params[3].get_str().empty()) wtx.mapValue["comment"] = params[3].get_str(); - set<string> setAddress; + set<CBitcoinAddress> setAddress; vector<pair<CScript, int64> > vecSend; int64 totalAmount = 0; BOOST_FOREACH(const Pair& s, sendTo) { - uint160 hash160; - string strAddress = s.name_; + CBitcoinAddress address(s.name_); + if (!address.IsValid()) + throw JSONRPCError(-5, string("Invalid bitcoin address:")+s.name_); - if (setAddress.count(strAddress)) - throw JSONRPCError(-8, string("Invalid parameter, duplicated address: ")+strAddress); - setAddress.insert(strAddress); + if (setAddress.count(address)) + throw JSONRPCError(-8, string("Invalid parameter, duplicated address: ")+s.name_); + setAddress.insert(address); CScript scriptPubKey; - if (!scriptPubKey.SetBitcoinAddress(strAddress)) - throw JSONRPCError(-5, string("Invalid bitcoin address:")+strAddress); + scriptPubKey.SetBitcoinAddress(address); int64 nAmount = AmountFromValue(s.value_); totalAmount += nAmount; vecSend.push_back(make_pair(scriptPubKey, nAmount)); } - CRITICAL_BLOCK(cs_main) - CRITICAL_BLOCK(pwalletMain->cs_mapWallet) + if (pwalletMain->IsLocked()) + throw JSONRPCError(-13, "Error: Please enter the wallet passphrase with walletpassphrase first."); + + // Check funds + int64 nBalance = GetAccountBalance(strAccount, nMinDepth); + if (totalAmount > nBalance) + throw JSONRPCError(-6, "Account has insufficient funds"); + + // Send + CReserveKey keyChange(pwalletMain); + int64 nFeeRequired = 0; + bool fCreated = pwalletMain->CreateTransaction(vecSend, wtx, keyChange, nFeeRequired); + if (!fCreated) { - // Check funds - int64 nBalance = GetAccountBalance(strAccount, nMinDepth); - if (totalAmount > nBalance) - throw JSONRPCError(-6, "Account has insufficient funds"); - - // Send - CReserveKey keyChange(pwalletMain); - int64 nFeeRequired = 0; - bool fCreated = pwalletMain->CreateTransaction(vecSend, wtx, keyChange, nFeeRequired); - if (!fCreated) - { - if (totalAmount + nFeeRequired > pwalletMain->GetBalance()) - throw JSONRPCError(-6, "Insufficient funds"); - throw JSONRPCError(-4, "Transaction creation failed"); - } - if (!pwalletMain->CommitTransaction(wtx, keyChange)) - throw JSONRPCError(-4, "Transaction commit failed"); + if (totalAmount + nFeeRequired > pwalletMain->GetBalance()) + throw JSONRPCError(-6, "Insufficient funds"); + throw JSONRPCError(-4, "Transaction creation failed"); } + if (!pwalletMain->CommitTransaction(wtx, keyChange)) + throw JSONRPCError(-4, "Transaction commit failed"); return wtx.GetHash().GetHex(); } @@ -899,73 +949,62 @@ Value ListReceived(const Array& params, bool fByAccounts) fIncludeEmpty = params[1].get_bool(); // Tally - map<uint160, tallyitem> mapTally; - CRITICAL_BLOCK(pwalletMain->cs_mapWallet) + map<CBitcoinAddress, tallyitem> mapTally; + for (map<uint256, CWalletTx>::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); ++it) { - for (map<uint256, CWalletTx>::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); ++it) - { - const CWalletTx& wtx = (*it).second; - if (wtx.IsCoinBase() || !wtx.IsFinal()) - continue; + const CWalletTx& wtx = (*it).second; + if (wtx.IsCoinBase() || !wtx.IsFinal()) + continue; + + int nDepth = wtx.GetDepthInMainChain(); + if (nDepth < nMinDepth) + continue; - int nDepth = wtx.GetDepthInMainChain(); - if (nDepth < nMinDepth) + BOOST_FOREACH(const CTxOut& txout, wtx.vout) + { + CBitcoinAddress address; + if (!ExtractAddress(txout.scriptPubKey, pwalletMain, address) || !address.IsValid()) continue; - BOOST_FOREACH(const CTxOut& txout, wtx.vout) - { - // Only counting our own bitcoin addresses and not ip addresses - uint160 hash160 = txout.scriptPubKey.GetBitcoinAddressHash160(); - if (hash160 == 0 || !mapPubKeys.count(hash160)) // IsMine - continue; - - tallyitem& item = mapTally[hash160]; - item.nAmount += txout.nValue; - item.nConf = min(item.nConf, nDepth); - } + tallyitem& item = mapTally[address]; + item.nAmount += txout.nValue; + item.nConf = min(item.nConf, nDepth); } } // Reply Array ret; map<string, tallyitem> mapAccountTally; - CRITICAL_BLOCK(pwalletMain->cs_mapAddressBook) + BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress, string)& item, pwalletMain->mapAddressBook) { - BOOST_FOREACH(const PAIRTYPE(string, string)& item, pwalletMain->mapAddressBook) - { - const string& strAddress = item.first; - const string& strAccount = item.second; - uint160 hash160; - if (!AddressToHash160(strAddress, hash160)) - continue; - map<uint160, tallyitem>::iterator it = mapTally.find(hash160); - if (it == mapTally.end() && !fIncludeEmpty) - continue; + const CBitcoinAddress& address = item.first; + const string& strAccount = item.second; + map<CBitcoinAddress, tallyitem>::iterator it = mapTally.find(address); + if (it == mapTally.end() && !fIncludeEmpty) + continue; - int64 nAmount = 0; - int nConf = INT_MAX; - if (it != mapTally.end()) - { - nAmount = (*it).second.nAmount; - nConf = (*it).second.nConf; - } + int64 nAmount = 0; + int nConf = INT_MAX; + if (it != mapTally.end()) + { + nAmount = (*it).second.nAmount; + nConf = (*it).second.nConf; + } - if (fByAccounts) - { - tallyitem& item = mapAccountTally[strAccount]; - item.nAmount += nAmount; - item.nConf = min(item.nConf, nConf); - } - else - { - Object obj; - obj.push_back(Pair("address", strAddress)); - obj.push_back(Pair("account", strAccount)); - obj.push_back(Pair("label", strAccount)); // deprecated - obj.push_back(Pair("amount", ValueFromAmount(nAmount))); - obj.push_back(Pair("confirmations", (nConf == INT_MAX ? 0 : nConf))); - ret.push_back(obj); - } + if (fByAccounts) + { + tallyitem& item = mapAccountTally[strAccount]; + item.nAmount += nAmount; + item.nConf = min(item.nConf, nConf); + } + else + { + Object obj; + obj.push_back(Pair("address", address.ToString())); + obj.push_back(Pair("account", strAccount)); + obj.push_back(Pair("amount", ValueFromAmount(nAmount))); + obj.push_back(Pair("confirmations", (nConf == INT_MAX ? 0 : nConf))); + ret.push_back(obj); } } @@ -977,7 +1016,6 @@ Value ListReceived(const Array& params, bool fByAccounts) int nConf = (*it).second.nConf; Object obj; obj.push_back(Pair("account", (*it).first)); - obj.push_back(Pair("label", (*it).first)); // deprecated obj.push_back(Pair("amount", ValueFromAmount(nAmount))); obj.push_back(Pair("confirmations", (nConf == INT_MAX ? 0 : nConf))); ret.push_back(obj); @@ -1022,8 +1060,8 @@ void ListTransactions(const CWalletTx& wtx, const string& strAccount, int nMinDe { int64 nGeneratedImmature, nGeneratedMature, nFee; string strSentAccount; - list<pair<string, int64> > listReceived; - list<pair<string, int64> > listSent; + list<pair<CBitcoinAddress, int64> > listReceived; + list<pair<CBitcoinAddress, int64> > listSent; wtx.GetAmounts(nGeneratedImmature, nGeneratedMature, listReceived, listSent, nFee, strSentAccount); bool fAllAccounts = (strAccount == string("*")); @@ -1051,11 +1089,11 @@ void ListTransactions(const CWalletTx& wtx, const string& strAccount, int nMinDe // Sent if ((!listSent.empty() || nFee != 0) && (fAllAccounts || strAccount == strSentAccount)) { - BOOST_FOREACH(const PAIRTYPE(string, int64)& s, listSent) + BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress, int64)& s, listSent) { Object entry; entry.push_back(Pair("account", strSentAccount)); - entry.push_back(Pair("address", s.first)); + entry.push_back(Pair("address", s.first.ToString())); entry.push_back(Pair("category", "send")); entry.push_back(Pair("amount", ValueFromAmount(-s.second))); entry.push_back(Pair("fee", ValueFromAmount(-nFee))); @@ -1067,27 +1105,23 @@ void ListTransactions(const CWalletTx& wtx, const string& strAccount, int nMinDe // Received if (listReceived.size() > 0 && wtx.GetDepthInMainChain() >= nMinDepth) - CRITICAL_BLOCK(pwalletMain->cs_mapAddressBook) + BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress, int64)& r, listReceived) { - BOOST_FOREACH(const PAIRTYPE(string, int64)& r, listReceived) + string account; + if (pwalletMain->mapAddressBook.count(r.first)) + account = pwalletMain->mapAddressBook[r.first]; + if (fAllAccounts || (account == strAccount)) { - string account; - if (pwalletMain->mapAddressBook.count(r.first)) - account = pwalletMain->mapAddressBook[r.first]; - if (fAllAccounts || (account == strAccount)) - { - Object entry; - entry.push_back(Pair("account", account)); - entry.push_back(Pair("address", r.first)); - entry.push_back(Pair("category", "receive")); - entry.push_back(Pair("amount", ValueFromAmount(r.second))); - if (fLong) - WalletTxToJSON(wtx, entry); - ret.push_back(entry); - } + Object entry; + entry.push_back(Pair("account", account)); + entry.push_back(Pair("address", r.first.ToString())); + entry.push_back(Pair("category", "receive")); + entry.push_back(Pair("amount", ValueFromAmount(r.second))); + if (fLong) + WalletTxToJSON(wtx, entry); + ret.push_back(entry); } } - } void AcentryToJSON(const CAccountingEntry& acentry, const string& strAccount, Array& ret) @@ -1127,40 +1161,38 @@ Value listtransactions(const Array& params, bool fHelp) Array ret; CWalletDB walletdb(pwalletMain->strWalletFile); - CRITICAL_BLOCK(pwalletMain->cs_mapWallet) - { - // Firs: get all CWalletTx and CAccountingEntry into a sorted-by-time multimap: - typedef pair<CWalletTx*, CAccountingEntry*> TxPair; - typedef multimap<int64, TxPair > TxItems; - TxItems txByTime; + // Firs: get all CWalletTx and CAccountingEntry into a sorted-by-time multimap: + typedef pair<CWalletTx*, CAccountingEntry*> TxPair; + typedef multimap<int64, TxPair > TxItems; + TxItems txByTime; - for (map<uint256, CWalletTx>::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); ++it) - { - CWalletTx* wtx = &((*it).second); - txByTime.insert(make_pair(wtx->GetTxTime(), TxPair(wtx, (CAccountingEntry*)0))); - } - list<CAccountingEntry> acentries; - walletdb.ListAccountCreditDebit(strAccount, acentries); - BOOST_FOREACH(CAccountingEntry& entry, acentries) - { - txByTime.insert(make_pair(entry.nTime, TxPair((CWalletTx*)0, &entry))); - } + for (map<uint256, CWalletTx>::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); ++it) + { + CWalletTx* wtx = &((*it).second); + txByTime.insert(make_pair(wtx->GetTxTime(), TxPair(wtx, (CAccountingEntry*)0))); + } + list<CAccountingEntry> acentries; + walletdb.ListAccountCreditDebit(strAccount, acentries); + BOOST_FOREACH(CAccountingEntry& entry, acentries) + { + txByTime.insert(make_pair(entry.nTime, TxPair((CWalletTx*)0, &entry))); + } - // Now: iterate backwards until we have nCount items to return: - TxItems::reverse_iterator it = txByTime.rbegin(); - for (std::advance(it, nFrom); it != txByTime.rend(); ++it) - { - CWalletTx *const pwtx = (*it).second.first; - if (pwtx != 0) - ListTransactions(*pwtx, strAccount, 0, true, ret); - CAccountingEntry *const pacentry = (*it).second.second; - if (pacentry != 0) - AcentryToJSON(*pacentry, strAccount, ret); - - if (ret.size() >= nCount) break; - } - // ret is now newest to oldest + // Now: iterate backwards until we have nCount items to return: + TxItems::reverse_iterator it = txByTime.rbegin(); + if (txByTime.size() > nFrom) std::advance(it, nFrom); + for (; it != txByTime.rend(); ++it) + { + CWalletTx *const pwtx = (*it).second.first; + if (pwtx != 0) + ListTransactions(*pwtx, strAccount, 0, true, ret); + CAccountingEntry *const pacentry = (*it).second.second; + if (pacentry != 0) + AcentryToJSON(*pacentry, strAccount, ret); + + if (ret.size() >= nCount) break; } + // ret is now newest to oldest // Make sure we return only last nCount items (sends-to-self might give us an extra): if (ret.size() > nCount) @@ -1186,35 +1218,30 @@ Value listaccounts(const Array& params, bool fHelp) nMinDepth = params[0].get_int(); map<string, int64> mapAccountBalances; - CRITICAL_BLOCK(pwalletMain->cs_mapWallet) - CRITICAL_BLOCK(pwalletMain->cs_mapAddressBook) - { - BOOST_FOREACH(const PAIRTYPE(string, string)& entry, pwalletMain->mapAddressBook) { - uint160 hash160; - if(AddressToHash160(entry.first, hash160) && mapPubKeys.count(hash160)) // This address belongs to me - mapAccountBalances[entry.second] = 0; - } + BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress, string)& entry, pwalletMain->mapAddressBook) { + if (pwalletMain->HaveKey(entry.first)) // This address belongs to me + mapAccountBalances[entry.second] = 0; + } - for (map<uint256, CWalletTx>::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); ++it) + for (map<uint256, CWalletTx>::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); ++it) + { + const CWalletTx& wtx = (*it).second; + int64 nGeneratedImmature, nGeneratedMature, nFee; + string strSentAccount; + list<pair<CBitcoinAddress, int64> > listReceived; + list<pair<CBitcoinAddress, int64> > listSent; + wtx.GetAmounts(nGeneratedImmature, nGeneratedMature, listReceived, listSent, nFee, strSentAccount); + mapAccountBalances[strSentAccount] -= nFee; + BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress, int64)& s, listSent) + mapAccountBalances[strSentAccount] -= s.second; + if (wtx.GetDepthInMainChain() >= nMinDepth) { - const CWalletTx& wtx = (*it).second; - int64 nGeneratedImmature, nGeneratedMature, nFee; - string strSentAccount; - list<pair<string, int64> > listReceived; - list<pair<string, int64> > listSent; - wtx.GetAmounts(nGeneratedImmature, nGeneratedMature, listReceived, listSent, nFee, strSentAccount); - mapAccountBalances[strSentAccount] -= nFee; - BOOST_FOREACH(const PAIRTYPE(string, int64)& s, listSent) - mapAccountBalances[strSentAccount] -= s.second; - if (wtx.GetDepthInMainChain() >= nMinDepth) - { - mapAccountBalances[""] += nGeneratedMature; - BOOST_FOREACH(const PAIRTYPE(string, int64)& r, listReceived) - if (pwalletMain->mapAddressBook.count(r.first)) - mapAccountBalances[pwalletMain->mapAddressBook[r.first]] += r.second; - else - mapAccountBalances[""] += r.second; - } + mapAccountBalances[""] += nGeneratedMature; + BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress, int64)& r, listReceived) + if (pwalletMain->mapAddressBook.count(r.first)) + mapAccountBalances[pwalletMain->mapAddressBook[r.first]] += r.second; + else + mapAccountBalances[""] += r.second; } } @@ -1260,7 +1287,6 @@ Value listsinceblock(const Array& params, bool fHelp) Array transactions; - CRITICAL_BLOCK(pwalletMain->cs_mapWallet) for (map<uint256, CWalletTx>::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); it++) { CWalletTx tx = (*it).second; @@ -1306,27 +1332,25 @@ Value gettransaction(const Array& params, bool fHelp) hash.SetHex(params[0].get_str()); Object entry; - CRITICAL_BLOCK(pwalletMain->cs_mapWallet) - { - 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); + if (!pwalletMain->mapWallet.count(hash)) + throw JSONRPCError(-5, "Invalid or non-wallet transaction id"); + const CWalletTx& wtx = pwalletMain->mapWallet[hash]; - entry.push_back(Pair("amount", ValueFromAmount(nNet - nFee))); - if (wtx.IsFromMe()) - entry.push_back(Pair("fee", ValueFromAmount(nFee))); + int64 nCredit = wtx.GetCredit(); + int64 nDebit = wtx.GetDebit(); + int64 nNet = nCredit - nDebit; + int64 nFee = (wtx.IsFromMe() ? wtx.GetValueOut() - nDebit : 0); - WalletTxToJSON(pwalletMain->mapWallet[hash], entry); + entry.push_back(Pair("amount", ValueFromAmount(nNet - nFee))); + if (wtx.IsFromMe()) + entry.push_back(Pair("fee", ValueFromAmount(nFee))); - Array details; - ListTransactions(pwalletMain->mapWallet[hash], "*", 0, false, details); - entry.push_back(Pair("details", details)); - } + WalletTxToJSON(pwalletMain->mapWallet[hash], entry); + + Array details; + ListTransactions(pwalletMain->mapWallet[hash], "*", 0, false, details); + entry.push_back(Pair("details", details)); return entry; } @@ -1346,6 +1370,213 @@ 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)) + throw runtime_error( + "keypoolrefill\n" + "Fills the keypool."); + + if (pwalletMain->IsLocked()) + throw JSONRPCError(-13, "Error: Please enter the wallet passphrase with walletpassphrase first."); + + pwalletMain->TopUpKeyPool(); + + if (pwalletMain->GetKeyPoolSize() < GetArg("-keypool", 100)) + throw JSONRPCError(-4, "Error refreshing keypool."); + + return Value::null; +} + + +void ThreadTopUpKeyPool(void* parg) +{ + pwalletMain->TopUpKeyPool(); +} + +void ThreadCleanWalletPassphrase(void* parg) +{ + int64 nMyWakeTime = GetTime() + *((int*)parg); + + if (nWalletUnlockTime == 0) + { + CRITICAL_BLOCK(cs_nWalletUnlockTime) + { + nWalletUnlockTime = nMyWakeTime; + } + + while (GetTime() < nWalletUnlockTime) + Sleep(GetTime() - nWalletUnlockTime); + + CRITICAL_BLOCK(cs_nWalletUnlockTime) + { + nWalletUnlockTime = 0; + } + } + else + { + CRITICAL_BLOCK(cs_nWalletUnlockTime) + { + if (nWalletUnlockTime < nMyWakeTime) + nWalletUnlockTime = nMyWakeTime; + } + free(parg); + return; + } + + pwalletMain->Lock(); + + delete (int*)parg; +} + +Value walletpassphrase(const Array& params, bool fHelp) +{ + if (pwalletMain->IsCrypted() && (fHelp || params.size() != 2)) + throw runtime_error( + "walletpassphrase <passphrase> <timeout>\n" + "Stores the wallet decryption key in memory for <timeout> seconds."); + if (fHelp) + return true; + if (!pwalletMain->IsCrypted()) + throw JSONRPCError(-15, "Error: running with an unencrypted wallet, but walletpassphrase was called."); + + if (!pwalletMain->IsLocked()) + throw JSONRPCError(-17, "Error: Wallet is already unlocked."); + + // Note that the walletpassphrase is stored in params[0] which is not mlock()ed + string strWalletPass; + strWalletPass.reserve(100); + mlock(&strWalletPass[0], strWalletPass.capacity()); + strWalletPass = params[0].get_str(); + + if (strWalletPass.length() > 0) + { + if (!pwalletMain->Unlock(strWalletPass)) + { + fill(strWalletPass.begin(), strWalletPass.end(), '\0'); + munlock(&strWalletPass[0], strWalletPass.capacity()); + throw JSONRPCError(-14, "Error: The wallet passphrase entered was incorrect."); + } + fill(strWalletPass.begin(), strWalletPass.end(), '\0'); + munlock(&strWalletPass[0], strWalletPass.capacity()); + } + else + throw runtime_error( + "walletpassphrase <passphrase> <timeout>\n" + "Stores the wallet decryption key in memory for <timeout> seconds."); + + CreateThread(ThreadTopUpKeyPool, NULL); + int* pnSleepTime = new int(params[1].get_int()); + CreateThread(ThreadCleanWalletPassphrase, pnSleepTime); + + return Value::null; +} + + +Value walletpassphrasechange(const Array& params, bool fHelp) +{ + if (pwalletMain->IsCrypted() && (fHelp || params.size() != 2)) + throw runtime_error( + "walletpassphrasechange <oldpassphrase> <newpassphrase>\n" + "Changes the wallet passphrase from <oldpassphrase> to <newpassphrase>."); + if (fHelp) + return true; + if (!pwalletMain->IsCrypted()) + throw JSONRPCError(-15, "Error: running with an unencrypted wallet, but walletpassphrasechange was called."); + + string strOldWalletPass; + strOldWalletPass.reserve(100); + mlock(&strOldWalletPass[0], strOldWalletPass.capacity()); + strOldWalletPass = params[0].get_str(); + + string strNewWalletPass; + strNewWalletPass.reserve(100); + mlock(&strNewWalletPass[0], strNewWalletPass.capacity()); + strNewWalletPass = params[1].get_str(); + + if (strOldWalletPass.length() < 1 || strNewWalletPass.length() < 1) + throw runtime_error( + "walletpassphrasechange <oldpassphrase> <newpassphrase>\n" + "Changes the wallet passphrase from <oldpassphrase> to <newpassphrase>."); + + if (!pwalletMain->ChangeWalletPassphrase(strOldWalletPass, strNewWalletPass)) + { + fill(strOldWalletPass.begin(), strOldWalletPass.end(), '\0'); + fill(strNewWalletPass.begin(), strNewWalletPass.end(), '\0'); + munlock(&strOldWalletPass[0], strOldWalletPass.capacity()); + munlock(&strNewWalletPass[0], strNewWalletPass.capacity()); + throw JSONRPCError(-14, "Error: The wallet passphrase entered was incorrect."); + } + fill(strNewWalletPass.begin(), strNewWalletPass.end(), '\0'); + fill(strOldWalletPass.begin(), strOldWalletPass.end(), '\0'); + munlock(&strOldWalletPass[0], strOldWalletPass.capacity()); + munlock(&strNewWalletPass[0], strNewWalletPass.capacity()); + + return Value::null; +} + + +Value walletlock(const Array& params, bool fHelp) +{ + if (pwalletMain->IsCrypted() && (fHelp || params.size() != 0)) + throw runtime_error( + "walletlock\n" + "Removes the wallet encryption key from memory, locking the wallet.\n" + "After calling this method, you will need to call walletpassphrase again\n" + "before being able to call any methods which require the wallet to be unlocked."); + if (fHelp) + return true; + if (!pwalletMain->IsCrypted()) + throw JSONRPCError(-15, "Error: running with an unencrypted wallet, but walletlock was called."); + + pwalletMain->Lock(); + CRITICAL_BLOCK(cs_nWalletUnlockTime) + { + nWalletUnlockTime = 0; + } + + return Value::null; +} + + +Value encryptwallet(const Array& params, bool fHelp) +{ + if (!pwalletMain->IsCrypted() && (fHelp || params.size() != 1)) + throw runtime_error( + "encryptwallet <passphrase>\n" + "Encrypts the wallet with <passphrase>."); + if (fHelp) + return true; + if (pwalletMain->IsCrypted()) + throw JSONRPCError(-15, "Error: running with an encrypted wallet, but encryptwallet was called."); + + string strWalletPass; + strWalletPass.reserve(100); + mlock(&strWalletPass[0], strWalletPass.capacity()); + strWalletPass = params[0].get_str(); + + if (strWalletPass.length() < 1) + throw runtime_error( + "encryptwallet <passphrase>\n" + "Encrypts the wallet with <passphrase>."); + + if (!pwalletMain->EncryptWallet(strWalletPass)) + { + fill(strWalletPass.begin(), strWalletPass.end(), '\0'); + munlock(&strWalletPass[0], strWalletPass.capacity()); + throw JSONRPCError(-16, "Error: Failed to encrypt the wallet."); + } + fill(strWalletPass.begin(), strWalletPass.end(), '\0'); + munlock(&strWalletPass[0], strWalletPass.capacity()); + + return Value::null; +} + + Value validateaddress(const Array& params, bool fHelp) { if (fHelp || params.size() != 1) @@ -1353,9 +1584,8 @@ Value validateaddress(const Array& params, bool fHelp) "validateaddress <bitcoinaddress>\n" "Return information about <bitcoinaddress>."); - string strAddress = params[0].get_str(); - uint160 hash160; - bool isValid = AddressToHash160(strAddress, hash160); + CBitcoinAddress address(params[0].get_str()); + bool isValid = address.IsValid(); Object ret; ret.push_back(Pair("isvalid", isValid)); @@ -1363,14 +1593,11 @@ Value validateaddress(const Array& params, bool fHelp) { // Call Hash160ToAddress() so we always return current ADDRESSVERSION // version of the address: - string currentAddress = Hash160ToAddress(hash160); + string currentAddress = address.ToString(); ret.push_back(Pair("address", currentAddress)); - ret.push_back(Pair("ismine", (mapPubKeys.count(hash160) > 0))); - CRITICAL_BLOCK(pwalletMain->cs_mapAddressBook) - { - if (pwalletMain->mapAddressBook.count(currentAddress)) - ret.push_back(Pair("account", pwalletMain->mapAddressBook[currentAddress])); - } + ret.push_back(Pair("ismine", (pwalletMain->HaveKey(address) > 0))); + if (pwalletMain->mapAddressBook.count(address)) + ret.push_back(Pair("account", pwalletMain->mapAddressBook[address])); } return ret; } @@ -1382,9 +1609,9 @@ Value getwork(const Array& params, bool fHelp) throw runtime_error( "getwork [data]\n" "If [data] is not specified, returns formatted hash data to work on:\n" - " \"midstate\" : precomputed hash state after hashing the first half of the data\n" + " \"midstate\" : precomputed hash state after hashing the first half of the data (DEPRECATED)\n" // deprecated " \"data\" : block data\n" - " \"hash1\" : formatted hash buffer for second hash\n" + " \"hash1\" : formatted hash buffer for second hash (DEPRECATED)\n" // deprecated " \"target\" : little endian hash target\n" "If [data] is specified, tries to solve the block and returns true if it was successful."); @@ -1394,7 +1621,8 @@ Value getwork(const Array& params, bool fHelp) if (IsInitialBlockDownload()) throw JSONRPCError(-10, "Bitcoin is downloading blocks..."); - static map<uint256, pair<CBlock*, unsigned int> > mapNewBlock; + typedef map<uint256, pair<CBlock*, CScript> > mapNewBlock_t; + static mapNewBlock_t mapNewBlock; static vector<CBlock*> vNewBlock; static CReserveKey reservekey(pwalletMain); @@ -1433,11 +1661,10 @@ Value getwork(const Array& params, bool fHelp) // Update nExtraNonce static unsigned int nExtraNonce = 0; - static int64 nPrevTime = 0; - IncrementExtraNonce(pblock, pindexPrev, nExtraNonce, nPrevTime); + IncrementExtraNonce(pblock, pindexPrev, nExtraNonce); // Save - mapNewBlock[pblock->hashMerkleRoot] = make_pair(pblock, nExtraNonce); + mapNewBlock[pblock->hashMerkleRoot] = make_pair(pblock, pblock->vtx[0].vin[0].scriptSig); // Prebuild hash buffers char pmidstate[32]; @@ -1448,9 +1675,9 @@ Value getwork(const Array& params, bool fHelp) uint256 hashTarget = CBigNum().SetCompact(pblock->nBits).getuint256(); Object result; - result.push_back(Pair("midstate", HexStr(BEGIN(pmidstate), END(pmidstate)))); + result.push_back(Pair("midstate", HexStr(BEGIN(pmidstate), END(pmidstate)))); // deprecated result.push_back(Pair("data", HexStr(BEGIN(pdata), END(pdata)))); - result.push_back(Pair("hash1", HexStr(BEGIN(phash1), END(phash1)))); + result.push_back(Pair("hash1", HexStr(BEGIN(phash1), END(phash1)))); // deprecated result.push_back(Pair("target", HexStr(BEGIN(hashTarget), END(hashTarget)))); return result; } @@ -1464,17 +1691,16 @@ Value getwork(const Array& params, bool fHelp) // Byte reverse for (int i = 0; i < 128/4; i++) - ((unsigned int*)pdata)[i] = CryptoPP::ByteReverse(((unsigned int*)pdata)[i]); + ((unsigned int*)pdata)[i] = ByteReverse(((unsigned int*)pdata)[i]); // Get saved block if (!mapNewBlock.count(pdata->hashMerkleRoot)) return false; CBlock* pblock = mapNewBlock[pdata->hashMerkleRoot].first; - unsigned int nExtraNonce = mapNewBlock[pdata->hashMerkleRoot].second; pblock->nTime = pdata->nTime; pblock->nNonce = pdata->nNonce; - pblock->vtx[0].vin[0].scriptSig = CScript() << pblock->nBits << CBigNum(nExtraNonce); + pblock->vtx[0].vin[0].scriptSig = mapNewBlock[pdata->hashMerkleRoot].second; pblock->hashMerkleRoot = pblock->BuildMerkleTree(); return CheckWork(pblock, *pwalletMain, reservekey); @@ -1482,6 +1708,86 @@ Value getwork(const Array& params, bool fHelp) } +Value getmemorypool(const Array& params, bool fHelp) +{ + if (fHelp || params.size() > 1) + throw runtime_error( + "getmemorypool [data]\n" + "If [data] is not specified, returns data needed to construct a block to work on:\n" + " \"version\" : block version\n" + " \"previousblockhash\" : hash of current highest block\n" + " \"transactions\" : contents of non-coinbase transactions that should be included in the next block\n" + " \"coinbasevalue\" : maximum allowable input to coinbase transaction, including the generation award and transaction fees\n" + " \"time\" : timestamp appropriate for next block\n" + " \"bits\" : compressed target of next block\n" + "If [data] is specified, tries to solve the block and returns true if it was successful."); + + if (params.size() == 0) + { + if (vNodes.empty()) + throw JSONRPCError(-9, "Bitcoin is not connected!"); + + if (IsInitialBlockDownload()) + throw JSONRPCError(-10, "Bitcoin is downloading blocks..."); + + static CReserveKey reservekey(pwalletMain); + + // Update block + static unsigned int nTransactionsUpdatedLast; + static CBlockIndex* pindexPrev; + static int64 nStart; + static CBlock* pblock; + if (pindexPrev != pindexBest || + (nTransactionsUpdated != nTransactionsUpdatedLast && GetTime() - nStart > 5)) + { + nTransactionsUpdatedLast = nTransactionsUpdated; + pindexPrev = pindexBest; + nStart = GetTime(); + + // Create new block + if(pblock) + delete pblock; + pblock = CreateNewBlock(reservekey); + if (!pblock) + throw JSONRPCError(-7, "Out of memory"); + } + + // Update nTime + pblock->nTime = max(pindexPrev->GetMedianTimePast()+1, GetAdjustedTime()); + pblock->nNonce = 0; + + Array transactions; + BOOST_FOREACH(CTransaction tx, pblock->vtx) { + if(tx.IsCoinBase()) + continue; + + CDataStream ssTx; + ssTx << tx; + + transactions.push_back(HexStr(ssTx.begin(), ssTx.end())); + } + + Object result; + result.push_back(Pair("version", pblock->nVersion)); + result.push_back(Pair("previousblockhash", pblock->hashPrevBlock.GetHex())); + result.push_back(Pair("transactions", transactions)); + result.push_back(Pair("coinbasevalue", (int64_t)pblock->vtx[0].vout[0].nValue)); + result.push_back(Pair("time", (int64_t)pblock->nTime)); + result.push_back(Pair("bits", (int64_t)pblock->nBits)); + return result; + } + else + { + // Parse parameters + CDataStream ssBlock(ParseHex(params[0].get_str())); + CBlock pblock; + ssBlock >> pblock; + + return ProcessBlock(NULL, &pblock); + } +} + + @@ -1497,44 +1803,45 @@ Value getwork(const Array& params, bool fHelp) pair<string, rpcfn_type> pCallTable[] = { - make_pair("help", &help), - make_pair("stop", &stop), - make_pair("getblockcount", &getblockcount), - make_pair("getblocknumber", &getblocknumber), - make_pair("getconnectioncount", &getconnectioncount), - make_pair("getdifficulty", &getdifficulty), - make_pair("getgenerate", &getgenerate), - make_pair("setgenerate", &setgenerate), - make_pair("gethashespersec", &gethashespersec), - make_pair("getinfo", &getinfo), - make_pair("getnewaddress", &getnewaddress), - make_pair("getaccountaddress", &getaccountaddress), - make_pair("setaccount", &setaccount), - make_pair("setlabel", &setaccount), // deprecated - make_pair("getaccount", &getaccount), - make_pair("getlabel", &getaccount), // deprecated - make_pair("getaddressesbyaccount", &getaddressesbyaccount), - make_pair("getaddressesbylabel", &getaddressesbyaccount), // deprecated - make_pair("sendtoaddress", &sendtoaddress), - make_pair("getamountreceived", &getreceivedbyaddress), // deprecated, renamed to getreceivedbyaddress - make_pair("getallreceived", &listreceivedbyaddress), // deprecated, renamed to listreceivedbyaddress - make_pair("getreceivedbyaddress", &getreceivedbyaddress), - make_pair("getreceivedbyaccount", &getreceivedbyaccount), - make_pair("getreceivedbylabel", &getreceivedbyaccount), // deprecated - make_pair("listreceivedbyaddress", &listreceivedbyaddress), - make_pair("listreceivedbyaccount", &listreceivedbyaccount), - make_pair("listreceivedbylabel", &listreceivedbyaccount), // deprecated - make_pair("backupwallet", &backupwallet), - make_pair("validateaddress", &validateaddress), - make_pair("getbalance", &getbalance), - make_pair("move", &movecmd), - make_pair("sendfrom", &sendfrom), - make_pair("sendmany", &sendmany), - make_pair("gettransaction", &gettransaction), - make_pair("listtransactions", &listtransactions), - make_pair("getwork", &getwork), - make_pair("listaccounts", &listaccounts), - make_pair("settxfee", &settxfee), + make_pair("help", &help), + make_pair("stop", &stop), + make_pair("getblockcount", &getblockcount), + make_pair("getblocknumber", &getblocknumber), + make_pair("getconnectioncount", &getconnectioncount), + make_pair("getdifficulty", &getdifficulty), + make_pair("getgenerate", &getgenerate), + make_pair("setgenerate", &setgenerate), + make_pair("gethashespersec", &gethashespersec), + make_pair("getinfo", &getinfo), + make_pair("getnewaddress", &getnewaddress), + make_pair("getaccountaddress", &getaccountaddress), + make_pair("setaccount", &setaccount), + make_pair("getaccount", &getaccount), + make_pair("getaddressesbyaccount", &getaddressesbyaccount), + make_pair("sendtoaddress", &sendtoaddress), + make_pair("getreceivedbyaddress", &getreceivedbyaddress), + make_pair("getreceivedbyaccount", &getreceivedbyaccount), + make_pair("listreceivedbyaddress", &listreceivedbyaddress), + make_pair("listreceivedbyaccount", &listreceivedbyaccount), + make_pair("backupwallet", &backupwallet), + make_pair("keypoolrefill", &keypoolrefill), + make_pair("walletpassphrase", &walletpassphrase), + make_pair("walletpassphrasechange", &walletpassphrasechange), + make_pair("walletlock", &walletlock), + make_pair("encryptwallet", &encryptwallet), + make_pair("validateaddress", &validateaddress), + make_pair("getbalance", &getbalance), + make_pair("move", &movecmd), + make_pair("sendfrom", &sendfrom), + make_pair("sendmany", &sendmany), + make_pair("gettransaction", &gettransaction), + make_pair("listtransactions", &listtransactions), + make_pair("signmessage", &signmessage), + make_pair("verifymessage", &verifymessage), + make_pair("getwork", &getwork), + make_pair("listaccounts", &listaccounts), + make_pair("settxfee", &settxfee), + make_pair("getmemorypool", &getmemorypool), make_pair("listsinceblock", &listsinceblock), }; map<string, rpcfn_type> mapCallTable(pCallTable, pCallTable + sizeof(pCallTable)/sizeof(pCallTable[0])); @@ -1553,14 +1860,15 @@ string pAllowInSafeMode[] = "getinfo", "getnewaddress", "getaccountaddress", - "setlabel", "getaccount", - "getlabel", // deprecated "getaddressesbyaccount", - "getaddressesbylabel", // deprecated "backupwallet", + "keypoolrefill", + "walletpassphrase", + "walletlock", "validateaddress", "getwork", + "getmemorypool", }; set<string> setAllowInSafeMode(pAllowInSafeMode, pAllowInSafeMode + sizeof(pAllowInSafeMode)/sizeof(pAllowInSafeMode[0])); @@ -1582,6 +1890,7 @@ string HTTPPost(const string& strMsg, const map<string,string>& mapRequestHeader << "Host: 127.0.0.1\r\n" << "Content-Type: application/json\r\n" << "Content-Length: " << strMsg.size() << "\r\n" + << "Connection: close\r\n" << "Accept: application/json\r\n"; BOOST_FOREACH(const PAIRTYPE(string, string)& item, mapRequestHeaders) s << item.first << ": " << item.second << "\r\n"; @@ -1705,43 +2014,6 @@ int ReadHTTP(std::basic_istream<char>& stream, map<string, string>& mapHeadersRe return nStatus; } -string EncodeBase64(string s) -{ - BIO *b64, *bmem; - BUF_MEM *bptr; - - b64 = BIO_new(BIO_f_base64()); - BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL); - bmem = BIO_new(BIO_s_mem()); - b64 = BIO_push(b64, bmem); - BIO_write(b64, s.c_str(), s.size()); - BIO_flush(b64); - BIO_get_mem_ptr(b64, &bptr); - - string result(bptr->data, bptr->length); - BIO_free_all(b64); - - return result; -} - -string DecodeBase64(string s) -{ - BIO *b64, *bmem; - - char* buffer = static_cast<char*>(calloc(s.size(), sizeof(char))); - - b64 = BIO_new(BIO_f_base64()); - BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL); - bmem = BIO_new_mem_buf(const_cast<char*>(s.c_str()), s.size()); - bmem = BIO_push(b64, bmem); - BIO_read(bmem, buffer, s.size()); - BIO_free_all(bmem); - - string result(buffer); - free(buffer); - return result; -} - bool HTTPAuthorized(map<string, string>& mapHeaders) { string strAuth = mapHeaders["authorization"]; @@ -2013,7 +2285,7 @@ void ThreadRPCServer2(void* parg) if (valMethod.type() != str_type) throw JSONRPCError(-32600, "Method must be a string"); string strMethod = valMethod.get_str(); - if (strMethod != "getwork") + if (strMethod != "getwork" && strMethod != "getmemorypool") printf("ThreadRPCServer method=%s\n", strMethod.c_str()); // Parse params @@ -2039,7 +2311,10 @@ void ThreadRPCServer2(void* parg) try { // Execute - Value result = (*(*mi).second)(params, false); + Value result; + CRITICAL_BLOCK(cs_main) + CRITICAL_BLOCK(pwalletMain->cs_wallet) + result = (*(*mi).second)(params, false); // Send reply string strReply = JSONRPCReply(result, Value::null, id); @@ -2176,18 +2451,12 @@ int CommandLineRPC(int argc, char *argv[]) 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 == "getamountreceived" && n > 1) ConvertTo<boost::int64_t>(params[1]); // deprecated if (strMethod == "getreceivedbyaddress" && n > 1) ConvertTo<boost::int64_t>(params[1]); if (strMethod == "getreceivedbyaccount" && n > 1) ConvertTo<boost::int64_t>(params[1]); - if (strMethod == "getreceivedbylabel" && n > 1) ConvertTo<boost::int64_t>(params[1]); // deprecated - if (strMethod == "getallreceived" && n > 0) ConvertTo<boost::int64_t>(params[0]); // deprecated - if (strMethod == "getallreceived" && n > 1) ConvertTo<bool>(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 == "listreceivedbylabel" && n > 0) ConvertTo<boost::int64_t>(params[0]); // deprecated - if (strMethod == "listreceivedbylabel" && n > 1) ConvertTo<bool>(params[1]); // deprecated if (strMethod == "getbalance" && n > 1) ConvertTo<boost::int64_t>(params[1]); if (strMethod == "move" && n > 2) ConvertTo<double>(params[2]); if (strMethod == "move" && n > 3) ConvertTo<boost::int64_t>(params[3]); @@ -2196,6 +2465,7 @@ int CommandLineRPC(int argc, char *argv[]) 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) { @@ -2213,7 +2483,6 @@ int CommandLineRPC(int argc, char *argv[]) // Parse reply const Value& result = find_value(reply, "result"); const Value& error = find_value(reply, "error"); - const Value& id = find_value(reply, "id"); if (error.type() != null_type) { @@ -2245,13 +2514,7 @@ int CommandLineRPC(int argc, char *argv[]) if (strPrint != "") { -#if defined(__WXMSW__) && defined(GUI) - // Windows GUI apps can't print to command line, - // so settle for a message box yuck - MyMessageBox(strPrint, "Bitcoin", wxOK); -#else fprintf((nRet == 0 ? stdout : stderr), "%s\n", strPrint.c_str()); -#endif } return nRet; } diff --git a/src/rpc.h b/src/bitcoinrpc.h index 48a7b8a8a6..f267400797 100644 --- a/src/rpc.h +++ b/src/bitcoinrpc.h @@ -1,4 +1,5 @@ // Copyright (c) 2010 Satoshi Nakamoto +// Copyright (c) 2011 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. diff --git a/src/crypter.cpp b/src/crypter.cpp new file mode 100644 index 0000000000..9a8e6ca89a --- /dev/null +++ b/src/crypter.cpp @@ -0,0 +1,132 @@ +// Copyright (c) 2011 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 <openssl/aes.h> +#include <openssl/evp.h> +#include <vector> +#include <string> +#include "headers.h" +#ifdef __WXMSW__ +#include <windows.h> +#endif + +#include "crypter.h" +#include "main.h" +#include "util.h" + +bool CCrypter::SetKeyFromPassphrase(const std::string& strKeyData, const std::vector<unsigned char>& chSalt, const unsigned int nRounds, const unsigned int nDerivationMethod) +{ + if (nRounds < 1 || chSalt.size() != WALLET_CRYPTO_SALT_SIZE) + return false; + + // Try to keep the keydata out of swap (and be a bit over-careful to keep the IV that we don't even use out of swap) + // Note that this does nothing about suspend-to-disk (which will put all our key data on disk) + // Note as well that at no point in this program is any attempt made to prevent stealing of keys by reading the memory of the running process. + mlock(&chKey[0], sizeof chKey); + mlock(&chIV[0], sizeof chIV); + + int i = 0; + if (nDerivationMethod == 0) + i = EVP_BytesToKey(EVP_aes_256_cbc(), EVP_sha512(), &chSalt[0], + (unsigned char *)&strKeyData[0], strKeyData.size(), nRounds, chKey, chIV); + + if (i != WALLET_CRYPTO_KEY_SIZE) + { + memset(&chKey, 0, sizeof chKey); + memset(&chIV, 0, sizeof chIV); + return false; + } + + fKeySet = true; + return true; +} + +bool CCrypter::SetKey(const CKeyingMaterial& chNewKey, const std::vector<unsigned char>& chNewIV) +{ + if (chNewKey.size() != WALLET_CRYPTO_KEY_SIZE || chNewIV.size() != WALLET_CRYPTO_KEY_SIZE) + return false; + + // Try to keep the keydata out of swap + // Note that this does nothing about suspend-to-disk (which will put all our key data on disk) + // Note as well that at no point in this program is any attempt made to prevent stealing of keys by reading the memory of the running process. + mlock(&chKey[0], sizeof chKey); + mlock(&chIV[0], sizeof chIV); + + memcpy(&chKey[0], &chNewKey[0], sizeof chKey); + memcpy(&chIV[0], &chNewIV[0], sizeof chIV); + + fKeySet = true; + return true; +} + +bool CCrypter::Encrypt(const CKeyingMaterial& vchPlaintext, std::vector<unsigned char> &vchCiphertext) +{ + if (!fKeySet) + return false; + + // max ciphertext len for a n bytes of plaintext is + // n + AES_BLOCK_SIZE - 1 bytes + int nLen = vchPlaintext.size(); + int nCLen = nLen + AES_BLOCK_SIZE, nFLen = 0; + vchCiphertext = std::vector<unsigned char> (nCLen); + + EVP_CIPHER_CTX ctx; + + EVP_CIPHER_CTX_init(&ctx); + EVP_EncryptInit_ex(&ctx, EVP_aes_256_cbc(), NULL, chKey, chIV); + + EVP_EncryptUpdate(&ctx, &vchCiphertext[0], &nCLen, &vchPlaintext[0], nLen); + EVP_EncryptFinal_ex(&ctx, (&vchCiphertext[0])+nCLen, &nFLen); + + EVP_CIPHER_CTX_cleanup(&ctx); + + vchCiphertext.resize(nCLen + nFLen); + return true; +} + +bool CCrypter::Decrypt(const std::vector<unsigned char>& vchCiphertext, CKeyingMaterial& vchPlaintext) +{ + if (!fKeySet) + return false; + + // plaintext will always be equal to or lesser than length of ciphertext + int nLen = vchCiphertext.size(); + int nPLen = nLen, nFLen = 0; + + vchPlaintext = CKeyingMaterial(nPLen); + + EVP_CIPHER_CTX ctx; + + EVP_CIPHER_CTX_init(&ctx); + EVP_DecryptInit_ex(&ctx, EVP_aes_256_cbc(), NULL, chKey, chIV); + + EVP_DecryptUpdate(&ctx, &vchPlaintext[0], &nPLen, &vchCiphertext[0], nLen); + EVP_DecryptFinal_ex(&ctx, (&vchPlaintext[0])+nPLen, &nFLen); + + EVP_CIPHER_CTX_cleanup(&ctx); + + vchPlaintext.resize(nPLen + nFLen); + return true; +} + + +bool EncryptSecret(CKeyingMaterial& vMasterKey, const CSecret &vchPlaintext, const uint256& nIV, std::vector<unsigned char> &vchCiphertext) +{ + CCrypter cKeyCrypter; + std::vector<unsigned char> chIV(WALLET_CRYPTO_KEY_SIZE); + memcpy(&chIV[0], &nIV, WALLET_CRYPTO_KEY_SIZE); + if(!cKeyCrypter.SetKey(vMasterKey, chIV)) + return false; + return cKeyCrypter.Encrypt((CKeyingMaterial)vchPlaintext, vchCiphertext); +} + +bool DecryptSecret(const CKeyingMaterial& vMasterKey, const std::vector<unsigned char>& vchCiphertext, const uint256& nIV, CSecret& vchPlaintext) +{ + CCrypter cKeyCrypter; + std::vector<unsigned char> chIV(WALLET_CRYPTO_KEY_SIZE); + memcpy(&chIV[0], &nIV, WALLET_CRYPTO_KEY_SIZE); + if(!cKeyCrypter.SetKey(vMasterKey, chIV)) + return false; + return cKeyCrypter.Decrypt(vchCiphertext, *((CKeyingMaterial*)&vchPlaintext)); +} diff --git a/src/crypter.h b/src/crypter.h new file mode 100644 index 0000000000..5b95ea415e --- /dev/null +++ b/src/crypter.h @@ -0,0 +1,96 @@ +// Copyright (c) 2011 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 __CRYPTER_H__ +#define __CRYPTER_H__ + +#include "key.h" + +const unsigned int WALLET_CRYPTO_KEY_SIZE = 32; +const unsigned int WALLET_CRYPTO_SALT_SIZE = 8; + +/* +Private key encryption is done based on a CMasterKey, +which holds a salt and random encryption key. + +CMasterKeys is encrypted using AES-256-CBC using a key +derived using derivation method nDerivationMethod +(0 == EVP_sha512()) and derivation iterations nDeriveIterations. +vchOtherDerivationParameters is provided for alternative algorithms +which may require more parameters (such as scrypt). + +Wallet Private Keys are then encrypted using AES-256-CBC +with the double-sha256 of the private key as the IV, and the +master key's key as the encryption key. +*/ + +class CMasterKey +{ +public: + std::vector<unsigned char> vchCryptedKey; + std::vector<unsigned char> vchSalt; + // 0 = EVP_sha512() + // 1 = scrypt() + unsigned int nDerivationMethod; + unsigned int nDeriveIterations; + // Use this for more parameters to key derivation, + // such as the various parameters to scrypt + std::vector<unsigned char> vchOtherDerivationParameters; + + IMPLEMENT_SERIALIZE + ( + READWRITE(vchCryptedKey); + READWRITE(vchSalt); + READWRITE(nDerivationMethod); + READWRITE(nDeriveIterations); + READWRITE(vchOtherDerivationParameters); + ) + CMasterKey() + { + // 25000 rounds is just under 0.1 seconds on a 1.86 GHz Pentium M + // ie slightly lower than the lowest hardware we need bother supporting + nDeriveIterations = 25000; + nDerivationMethod = 0; + vchOtherDerivationParameters = std::vector<unsigned char>(0); + } +}; + +typedef std::vector<unsigned char, secure_allocator<unsigned char> > CKeyingMaterial; + +class CCrypter +{ +private: + unsigned char chKey[WALLET_CRYPTO_KEY_SIZE]; + unsigned char chIV[WALLET_CRYPTO_KEY_SIZE]; + bool fKeySet; + +public: + bool SetKeyFromPassphrase(const std::string &strKeyData, const std::vector<unsigned char>& chSalt, const unsigned int nRounds, const unsigned int nDerivationMethod); + bool Encrypt(const CKeyingMaterial& vchPlaintext, std::vector<unsigned char> &vchCiphertext); + bool Decrypt(const std::vector<unsigned char>& vchCiphertext, CKeyingMaterial& vchPlaintext); + bool SetKey(const CKeyingMaterial& chNewKey, const std::vector<unsigned char>& chNewIV); + + void CleanKey() + { + memset(&chKey, 0, sizeof chKey); + memset(&chIV, 0, sizeof chIV); + munlock(&chKey, sizeof chKey); + munlock(&chIV, sizeof chIV); + fKeySet = false; + } + + CCrypter() + { + fKeySet = false; + } + + ~CCrypter() + { + CleanKey(); + } +}; + +bool EncryptSecret(CKeyingMaterial& vMasterKey, const CSecret &vchPlaintext, const uint256& nIV, std::vector<unsigned char> &vchCiphertext); +bool DecryptSecret(const CKeyingMaterial& vMasterKey, const std::vector<unsigned char> &vchCiphertext, const uint256& nIV, CSecret &vchPlaintext); + +#endif diff --git a/src/cryptopp/License.txt b/src/cryptopp/License.txt deleted file mode 100644 index fc3f054693..0000000000 --- a/src/cryptopp/License.txt +++ /dev/null @@ -1,67 +0,0 @@ -Compilation Copyright (c) 1995-2009 by Wei Dai. All rights reserved. -This copyright applies only to this software distribution package -as a compilation, and does not imply a copyright on any particular -file in the package. - -The following files are copyrighted by their respective original authors, -and their use is subject to additional licenses included in these files. - -mars.cpp - Copyright 1998 Brian Gladman. - -All other files in this compilation are placed in the public domain by -Wei Dai and other contributors. - -I would like to thank the following authors for placing their works into -the public domain: - -Joan Daemen - 3way.cpp -Leonard Janke - cast.cpp, seal.cpp -Steve Reid - cast.cpp -Phil Karn - des.cpp -Andrew M. Kuchling - md2.cpp, md4.cpp -Colin Plumb - md5.cpp -Seal Woods - rc6.cpp -Chris Morgan - rijndael.cpp -Paulo Baretto - rijndael.cpp, skipjack.cpp, square.cpp -Richard De Moliner - safer.cpp -Matthew Skala - twofish.cpp -Kevin Springle - camellia.cpp, shacal2.cpp, ttmac.cpp, whrlpool.cpp, ripemd.cpp - -Permission to use, copy, modify, and distribute this compilation for -any purpose, including commercial applications, is hereby granted -without fee, subject to the following restrictions: - -1. Any copy or modification of this compilation in any form, except -in object code form as part of an application software, must include -the above copyright notice and this license. - -2. Users of this software agree that any modification or extension -they provide to Wei Dai will be considered public domain and not -copyrighted unless it includes an explicit copyright notice. - -3. Wei Dai makes no warranty or representation that the operation of the -software in this compilation will be error-free, and Wei Dai is under no -obligation to provide any services, by way of maintenance, update, or -otherwise. THE SOFTWARE AND ANY DOCUMENTATION ARE PROVIDED "AS IS" -WITHOUT EXPRESS OR IMPLIED WARRANTY INCLUDING, BUT NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. IN NO EVENT WILL WEI DAI OR ANY OTHER CONTRIBUTOR BE LIABLE FOR -DIRECT, INCIDENTAL OR CONSEQUENTIAL DAMAGES, EVEN IF -ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. - -4. Users will not use Wei Dai or any other contributor's name in any -publicity or advertising, without prior written consent in each case. - -5. Export of this software from the United States may require a -specific license from the United States Government. It is the -responsibility of any person or organization contemplating export -to obtain such a license before exporting. - -6. Certain parts of this software may be protected by patents. It -is the users' responsibility to obtain the appropriate -licenses before using those parts. - -If this compilation is used in object code form in an application -software, acknowledgement of the author is not required but would be -appreciated. The contribution of any useful modifications or extensions -to Wei Dai is not required but would also be appreciated. diff --git a/src/cryptopp/Readme.txt b/src/cryptopp/Readme.txt deleted file mode 100644 index 861c036c68..0000000000 --- a/src/cryptopp/Readme.txt +++ /dev/null @@ -1,429 +0,0 @@ -Crypto++: a C++ Class Library of Cryptographic Schemes -Version 5.6.0 (3/15/2009) - -Crypto++ Library is a free C++ class library of cryptographic schemes. -Currently the library contains the following algorithms: - - algorithm type name - - authenticated encryption schemes GCM, CCM, EAX - - high speed stream ciphers Panama, Sosemanuk, Salsa20, XSalsa20 - - AES and AES candidates AES (Rijndael), RC6, MARS, Twofish, Serpent, - CAST-256 - - IDEA, Triple-DES (DES-EDE2 and DES-EDE3), - other block ciphers Camellia, SEED, RC5, Blowfish, TEA, XTEA, - Skipjack, SHACAL-2 - - block cipher modes of operation ECB, CBC, CBC ciphertext stealing (CTS), - CFB, OFB, counter mode (CTR) - - message authentication codes VMAC, HMAC, CMAC, CBC-MAC, DMAC, - Two-Track-MAC - - SHA-1, SHA-2 (SHA-224, SHA-256, SHA-384, and - hash functions SHA-512), Tiger, WHIRLPOOL, RIPEMD-128, - RIPEMD-256, RIPEMD-160, RIPEMD-320 - - RSA, DSA, ElGamal, Nyberg-Rueppel (NR), - public-key cryptography Rabin, Rabin-Williams (RW), LUC, LUCELG, - DLIES (variants of DHAES), ESIGN - - padding schemes for public-key PKCS#1 v2.0, OAEP, PSS, PSSR, IEEE P1363 - systems EMSA2 and EMSA5 - - Diffie-Hellman (DH), Unified Diffie-Hellman - key agreement schemes (DH2), Menezes-Qu-Vanstone (MQV), LUCDIF, - XTR-DH - - elliptic curve cryptography ECDSA, ECNR, ECIES, ECDH, ECMQV - - insecure or obsolescent MD2, MD4, MD5, Panama Hash, DES, ARC4, SEAL -algorithms retained for backwards 3.0, WAKE, WAKE-OFB, DESX (DES-XEX3), RC2, - compatibility and historical SAFER, 3-WAY, GOST, SHARK, CAST-128, Square - value - -Other features include: - - * pseudo random number generators (PRNG): ANSI X9.17 appendix C, RandomPool - * password based key derivation functions: PBKDF1 and PBKDF2 from PKCS #5, - PBKDF from PKCS #12 appendix B - * Shamir's secret sharing scheme and Rabin's information dispersal algorithm - (IDA) - * fast multi-precision integer (bignum) and polynomial operations - * finite field arithmetics, including GF(p) and GF(2^n) - * prime number generation and verification - * useful non-cryptographic algorithms - + DEFLATE (RFC 1951) compression/decompression with gzip (RFC 1952) and - zlib (RFC 1950) format support - + hex, base-32, and base-64 coding/decoding - + 32-bit CRC and Adler32 checksum - * class wrappers for these operating system features (optional): - + high resolution timers on Windows, Unix, and Mac OS - + Berkeley and Windows style sockets - + Windows named pipes - + /dev/random, /dev/urandom, /dev/srandom - + Microsoft's CryptGenRandom on Windows - * A high level interface for most of the above, using a filter/pipeline - metaphor - * benchmarks and validation testing - * x86, x86-64 (x64), MMX, and SSE2 assembly code for the most commonly used - algorithms, with run-time CPU feature detection and code selection - * some versions are available in FIPS 140-2 validated form - -You are welcome to use it for any purpose without paying me, but see -License.txt for the fine print. - -The following compilers are supported for this release. Please visit -http://www.cryptopp.com the most up to date build instructions and porting notes. - - * MSVC 6.0 - 2008 - * GCC 3.3 - 4.3 - * C++Builder 2009 - * Intel C++ Compiler 9 - 11 - * Sun Studio 12 (CC 5.9) - -*** Important Usage Notes *** - -1. If a constructor for A takes a pointer to an object B (except primitive -types such as int and char), then A owns B and will delete B at A's -destruction. If a constructor for A takes a reference to an object B, -then the caller retains ownership of B and should not destroy it until -A no longer needs it. - -2. Crypto++ is thread safe at the class level. This means you can use -Crypto++ safely in a multithreaded application, but you must provide -synchronization when multiple threads access a common Crypto++ object. - -*** MSVC-Specific Information *** - -On Windows, Crypto++ can be compiled into 3 forms: a static library -including all algorithms, a DLL with only FIPS Approved algorithms, and -a static library with only algorithms not in the DLL. -(FIPS Approved means Approved according to the FIPS 140-2 standard.) -The DLL may be used by itself, or it may be used together with the second -form of the static library. MSVC project files are included to build -all three forms, and sample applications using each of the three forms -are also included. - -To compile Crypto++ with MSVC, open the "cryptest.dsw" (for MSVC 6 and MSVC .NET -2003) or "cryptest.sln" (for MSVC .NET 2005) workspace file and build one or -more of the following projects: - -cryptdll - This builds the DLL. Please note that if you wish to use Crypto++ - as a FIPS validated module, you must use a pre-built DLL that has undergone - the FIPS validation process instead of building your own. -dlltest - This builds a sample application that only uses the DLL. -cryptest Non-DLL-Import Configuration - This builds the full static library - along with a full test driver. -cryptest DLL-Import Configuration - This builds a static library containing - only algorithms not in the DLL, along with a full test driver that uses - both the DLL and the static library. - -To use the Crypto++ DLL in your application, #include "dll.h" before including -any other Crypto++ header files, and place the DLL in the same directory as -your .exe file. dll.h includes the line #pragma comment(lib, "cryptopp") -so you don't have to explicitly list the import library in your project -settings. To use a static library form of Crypto++, specify it as -an additional library to link with in your project settings. -In either case you should check the compiler options to -make sure that the library and your application are using the same C++ -run-time libraries and calling conventions. - -*** DLL Memory Management *** - -Because it's possible for the Crypto++ DLL to delete objects allocated -by the calling application, they must use the same C++ memory heap. Three -methods are provided to achieve this. -1. The calling application can tell Crypto++ what heap to use. This method - is required when the calling application uses a non-standard heap. -2. Crypto++ can tell the calling application what heap to use. This method - is required when the calling application uses a statically linked C++ Run - Time Library. (Method 1 does not work in this case because the Crypto++ DLL - is initialized before the calling application's heap is initialized.) -3. Crypto++ can automatically use the heap provided by the calling application's - dynamically linked C++ Run Time Library. The calling application must - make sure that the dynamically linked C++ Run Time Library is initialized - before Crypto++ is loaded. (At this time it is not clear if it is possible - to control the order in which DLLs are initialized on Windows 9x machines, - so it might be best to avoid using this method.) - -When Crypto++ attaches to a new process, it searches all modules loaded -into the process space for exported functions "GetNewAndDeleteForCryptoPP" -and "SetNewAndDeleteFromCryptoPP". If one of these functions is found, -Crypto++ uses methods 1 or 2, respectively, by calling the function. -Otherwise, method 3 is used. - -*** GCC-Specific Information *** - -A makefile is included for you to compile Crypto++ with GCC. Make sure -you are using GNU Make and GNU ld. The make process will produce two files, -libcryptopp.a and cryptest.exe. Run "cryptest.exe v" for the validation -suite. - -*** Documentation and Support *** - -Crypto++ is documented through inline comments in header files, which are -processed through Doxygen to produce an HTML reference manual. You can find -a link to the manual from http://www.cryptopp.com. Also at that site is -the Crypto++ FAQ, which you should browse through before attempting to -use this library, because it will likely answer many of questions that -may come up. - -If you run into any problems, please try the Crypto++ mailing list. -The subscription information and the list archive are available on -http://www.cryptopp.com. You can also email me directly by visiting -http://www.weidai.com, but you will probably get a faster response through -the mailing list. - -*** History *** - -1.0 - First public release. Withdrawn at the request of RSA DSI. - - included Blowfish, BBS, DES, DH, Diamond, DSA, ElGamal, IDEA, - MD5, RC4, RC5, RSA, SHA, WAKE, secret sharing, DEFLATE compression - - had a serious bug in the RSA key generation code. - -1.1 - Removed RSA, RC4, RC5 - - Disabled calls to RSAREF's non-public functions - - Minor bugs fixed - -2.0 - a completely new, faster multiprecision integer class - - added MD5-MAC, HAVAL, 3-WAY, TEA, SAFER, LUC, Rabin, BlumGoldwasser, - elliptic curve algorithms - - added the Lucas strong probable primality test - - ElGamal encryption and signature schemes modified to avoid weaknesses - - Diamond changed to Diamond2 because of key schedule weakness - - fixed bug in WAKE key setup - - SHS class renamed to SHA - - lots of miscellaneous optimizations - -2.1 - added Tiger, HMAC, GOST, RIPE-MD160, LUCELG, LUCDIF, XOR-MAC, - OAEP, PSSR, SHARK - - added precomputation to DH, ElGamal, DSA, and elliptic curve algorithms - - added back RC5 and a new RSA - - optimizations in elliptic curves over GF(p) - - changed Rabin to use OAEP and PSSR - - changed many classes to allow copy constructors to work correctly - - improved exception generation and handling - -2.2 - added SEAL, CAST-128, Square - - fixed bug in HAVAL (padding problem) - - fixed bug in triple-DES (decryption order was reversed) - - fixed bug in RC5 (couldn't handle key length not a multiple of 4) - - changed HMAC to conform to RFC-2104 (which is not compatible - with the original HMAC) - - changed secret sharing and information dispersal to use GF(2^32) - instead of GF(65521) - - removed zero knowledge prover/verifier for graph isomorphism - - removed several utility classes in favor of the C++ standard library - -2.3 - ported to EGCS - - fixed incomplete workaround of min/max conflict in MSVC - -3.0 - placed all names into the "CryptoPP" namespace - - added MD2, RC2, RC6, MARS, RW, DH2, MQV, ECDHC, CBC-CTS - - added abstract base classes PK_SimpleKeyAgreementDomain and - PK_AuthenticatedKeyAgreementDomain - - changed DH and LUCDIF to implement the PK_SimpleKeyAgreementDomain - interface and to perform domain parameter and key validation - - changed interfaces of PK_Signer and PK_Verifier to sign and verify - messages instead of message digests - - changed OAEP to conform to PKCS#1 v2.0 - - changed benchmark code to produce HTML tables as output - - changed PSSR to track IEEE P1363a - - renamed ElGamalSignature to NR and changed it to track IEEE P1363 - - renamed ECKEP to ECMQVC and changed it to track IEEE P1363 - - renamed several other classes for clarity - - removed support for calling RSAREF - - removed option to compile old SHA (SHA-0) - - removed option not to throw exceptions - -3.1 - added ARC4, Rijndael, Twofish, Serpent, CBC-MAC, DMAC - - added interface for querying supported key lengths of symmetric ciphers - and MACs - - added sample code for RSA signature and verification - - changed CBC-CTS to be compatible with RFC 2040 - - updated SEAL to version 3.0 of the cipher specification - - optimized multiprecision squaring and elliptic curves over GF(p) - - fixed bug in MARS key setup - - fixed bug with attaching objects to Deflator - -3.2 - added DES-XEX3, ECDSA, DefaultEncryptorWithMAC - - renamed DES-EDE to DES-EDE2 and TripleDES to DES-EDE3 - - optimized ARC4 - - generalized DSA to allow keys longer than 1024 bits - - fixed bugs in GF2N and ModularArithmetic that can cause calculation errors - - fixed crashing bug in Inflator when given invalid inputs - - fixed endian bug in Serpent - - fixed padding bug in Tiger - -4.0 - added Skipjack, CAST-256, Panama, SHA-2 (SHA-256, SHA-384, and SHA-512), - and XTR-DH - - added a faster variant of Rabin's Information Dispersal Algorithm (IDA) - - added class wrappers for these operating system features: - - high resolution timers on Windows, Unix, and MacOS - - Berkeley and Windows style sockets - - Windows named pipes - - /dev/random and /dev/urandom on Linux and FreeBSD - - Microsoft's CryptGenRandom on Windows - - added support for SEC 1 elliptic curve key format and compressed points - - added support for X.509 public key format (subjectPublicKeyInfo) for - RSA, DSA, and elliptic curve schemes - - added support for DER and OpenPGP signature format for DSA - - added support for ZLIB compressed data format (RFC 1950) - - changed elliptic curve encryption to use ECIES (as defined in SEC 1) - - changed MARS key schedule to reflect the latest specification - - changed BufferedTransformation interface to support multiple channels - and messages - - changed CAST and SHA-1 implementations to use public domain source code - - fixed bug in StringSource - - optmized multi-precision integer code for better performance - -4.1 - added more support for the recommended elliptic curve parameters in SEC 2 - - added Panama MAC, MARC4 - - added IV stealing feature to CTS mode - - added support for PKCS #8 private key format for RSA, DSA, and elliptic - curve schemes - - changed Deflate, MD5, Rijndael, and Twofish to use public domain code - - fixed a bug with flushing compressed streams - - fixed a bug with decompressing stored blocks - - fixed a bug with EC point decompression using non-trinomial basis - - fixed a bug in NetworkSource::GeneralPump() - - fixed a performance issue with EC over GF(p) decryption - - fixed syntax to allow GCC to compile without -fpermissive - - relaxed some restrictions in the license - -4.2 - added support for longer HMAC keys - - added MD4 (which is not secure so use for compatibility purposes only) - - added compatibility fixes/workarounds for STLport 4.5, GCC 3.0.2, - and MSVC 7.0 - - changed MD2 to use public domain code - - fixed a bug with decompressing multiple messages with the same object - - fixed a bug in CBC-MAC with MACing multiple messages with the same object - - fixed a bug in RC5 and RC6 with zero-length keys - - fixed a bug in Adler32 where incorrect checksum may be generated - -5.0 - added ESIGN, DLIES, WAKE-OFB, PBKDF1 and PBKDF2 from PKCS #5 - - added key validation for encryption and signature public/private keys - - renamed StreamCipher interface to SymmetricCipher, which is now implemented - by both stream ciphers and block cipher modes including ECB and CBC - - added keying interfaces to support resetting of keys and IVs without - having to destroy and recreate objects - - changed filter interface to support non-blocking input/output - - changed SocketSource and SocketSink to use overlapped I/O on Microsoft Windows - - grouped related classes inside structs to help templates, for example - AESEncryption and AESDecryption are now AES::Encryption and AES::Decryption - - where possible, typedefs have been added to improve backwards - compatibility when the CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY macro is defined - - changed Serpent, HAVAL and IDEA to use public domain code - - implemented SSE2 optimizations for Integer operations - - fixed a bug in HMAC::TruncatedFinal() - - fixed SKIPJACK byte ordering following NIST clarification dated 5/9/02 - -5.01 - added known answer test for X9.17 RNG in FIPS 140 power-up self test - - submitted to NIST/CSE, but not publicly released - -5.02 - changed EDC test to MAC integrity check using HMAC/SHA1 - - improved performance of integrity check - - added blinding to defend against RSA timing attack - -5.03 - created DLL version of Crypto++ for FIPS 140-2 validation - - fixed vulnerabilities in GetNextIV for CTR and OFB modes - -5.0.4 - Removed DES, SHA-256, SHA-384, SHA-512 from DLL - -5.1 - added PSS padding and changed PSSR to track IEEE P1363a draft standard - - added blinding for RSA and Rabin to defend against timing attacks - on decryption operations - - changed signing and decryption APIs to support the above - - changed WaitObjectContainer to allow waiting for more than 64 - objects at a time on Win32 platforms - - fixed a bug in CBC and ECB modes with processing non-aligned data - - fixed standard conformance bugs in DLIES (DHAES mode) and RW/EMSA2 - signature scheme (these fixes are not backwards compatible) - - fixed a number of compiler warnings, minor bugs, and portability problems - - removed Sapphire - -5.2 - merged in changes for 5.01 - 5.0.4 - - added support for using encoding parameters and key derivation parameters - with public key encryption (implemented by OAEP and DL/ECIES) - - added Camellia, SHACAL-2, Two-Track-MAC, Whirlpool, RIPEMD-320, - RIPEMD-128, RIPEMD-256, Base-32 coding, FIPS variant of CFB mode - - added ThreadUserTimer for timing thread CPU usage - - added option for password-based key derivation functions - to iterate until a mimimum elapsed thread CPU time is reached - - added option (on by default) for DEFLATE compression to detect - uncompressible files and process them more quickly - - improved compatibility and performance on 64-bit platforms, - including Alpha, IA-64, x86-64, PPC64, Sparc64, and MIPS64 - - fixed ONE_AND_ZEROS_PADDING to use 0x80 instead 0x01 as padding. - - fixed encoding/decoding of PKCS #8 privateKeyInfo to properly - handle optional attributes - -5.2.1 - fixed bug in the "dlltest" DLL testing program - - fixed compiling with STLport using VC .NET - - fixed compiling with -fPIC using GCC - - fixed compiling with -msse2 on systems without memalign() - - fixed inability to instantiate PanamaMAC - - fixed problems with inline documentation - -5.2.2 - added SHA-224 - - put SHA-256, SHA-384, SHA-512, RSASSA-PSS into DLL - -5.2.3 - fixed issues with FIPS algorithm test vectors - - put RSASSA-ISO into DLL - -5.3 - ported to MSVC 2005 with support for x86-64 - - added defense against AES timing attacks, and more AES test vectors - - changed StaticAlgorithmName() of Rijndael to "AES", CTR to "CTR" - -5.4 - added Salsa20 - - updated Whirlpool to version 3.0 - - ported to GCC 4.1, Sun C++ 5.8, and Borland C++Builder 2006 - -5.5 - added VMAC and Sosemanuk (with x86-64 and SSE2 assembly) - - improved speed of integer arithmetic, AES, SHA-512, Tiger, Salsa20, - Whirlpool, and PANAMA cipher using assembly (x86-64, MMX, SSE2) - - optimized Camellia and added defense against timing attacks - - updated benchmarks code to show cycles per byte and to time key/IV setup - - started using OpenMP for increased multi-core speed - - enabled GCC optimization flags by default in GNUmakefile - - added blinding and computational error checking for RW signing - - changed RandomPool, X917RNG, GetNextIV, DSA/NR/ECDSA/ECNR to reduce - the risk of reusing random numbers and IVs after virtual machine state - rollback - - changed default FIPS mode RNG from AutoSeededX917RNG<DES_EDE3> to - AutoSeededX917RNG<AES> - - fixed PANAMA cipher interface to accept 256-bit key and 256-bit IV - - moved MD2, MD4, MD5, PanamaHash, ARC4, WAKE_CFB into the namespace "Weak" - - removed HAVAL, MD5-MAC, XMAC - -5.5.1 - fixed VMAC validation failure on 32-bit big-endian machines - -5.5.2 - ported x64 assembly language code for AES, Salsa20, Sosemanuk, and Panama - to MSVC 2005 (using MASM since MSVC doesn't support inline assembly on x64) - - fixed Salsa20 initialization crash on non-SSE2 machines - - fixed Whirlpool crash on Pentium 2 machines - - fixed possible branch prediction analysis (BPA) vulnerability in - MontgomeryReduce(), which may affect security of RSA, RW, LUC - - fixed link error with MSVC 2003 when using "debug DLL" form of runtime library - - fixed crash in SSE2_Add on P4 machines when compiled with - MSVC 6.0 SP5 with Processor Pack - - ported to MSVC 2008, GCC 4.2, Sun CC 5.9, Intel C++ Compiler 10.0, - and Borland C++Builder 2007 - -5.6 - added AuthenticatedSymmetricCipher interface class and Filter wrappers - - added CCM, GCM (with SSE2 assembly), EAX, CMAC, XSalsa20, and SEED - - added support for variable length IVs - - improved AES and SHA-256 speed on x86 and x64 - - fixed incorrect VMAC computation on message lengths - that are >64 mod 128 (x86 assembly version is not affected) - - fixed compiler error in vmac.cpp on x86 with GCC -fPIC - - fixed run-time validation error on x86-64 with GCC 4.3.2 -O2 - - fixed HashFilter bug when putMessage=true - - removed WORD64_AVAILABLE; compiler support for 64-bit int is now required - - ported to GCC 4.3, C++Builder 2009, Sun CC 5.10, Intel C++ Compiler 11 - -Written by Wei Dai diff --git a/src/cryptopp/config.h b/src/cryptopp/config.h deleted file mode 100644 index 0737027f41..0000000000 --- a/src/cryptopp/config.h +++ /dev/null @@ -1,462 +0,0 @@ -#ifndef CRYPTOPP_CONFIG_H -#define CRYPTOPP_CONFIG_H - -//// Bitcoin: disable SSE2 on 32-bit -#if !defined(_M_X64) && !defined(__x86_64__) -#define CRYPTOPP_DISABLE_SSE2 1 -#endif -//////////// end of Bitcoin changes - - -// ***************** Important Settings ******************** - -// define this if running on a big-endian CPU -#if !defined(IS_LITTLE_ENDIAN) && (defined(__BIG_ENDIAN__) || defined(__sparc) || defined(__sparc__) || defined(__hppa__) || defined(__mips__) || (defined(__MWERKS__) && !defined(__INTEL__))) -# define IS_BIG_ENDIAN -#endif - -// define this if running on a little-endian CPU -// big endian will be assumed if IS_LITTLE_ENDIAN is not defined -#ifndef IS_BIG_ENDIAN -# define IS_LITTLE_ENDIAN -#endif - -// define this if you want to disable all OS-dependent features, -// such as sockets and OS-provided random number generators -// #define NO_OS_DEPENDENCE - -// Define this to use features provided by Microsoft's CryptoAPI. -// Currently the only feature used is random number generation. -// This macro will be ignored if NO_OS_DEPENDENCE is defined. -#define USE_MS_CRYPTOAPI - -// Define this to 1 to enforce the requirement in FIPS 186-2 Change Notice 1 that only 1024 bit moduli be used -#ifndef DSA_1024_BIT_MODULUS_ONLY -# define DSA_1024_BIT_MODULUS_ONLY 1 -#endif - -// ***************** Less Important Settings *************** - -// define this to retain (as much as possible) old deprecated function and class names -// #define CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY - -#define GZIP_OS_CODE 0 - -// Try this if your CPU has 256K internal cache or a slow multiply instruction -// and you want a (possibly) faster IDEA implementation using log tables -// #define IDEA_LARGECACHE - -// Define this if, for the linear congruential RNG, you want to use -// the original constants as specified in S.K. Park and K.W. Miller's -// CACM paper. -// #define LCRNG_ORIGINAL_NUMBERS - -// choose which style of sockets to wrap (mostly useful for cygwin which has both) -#define PREFER_BERKELEY_STYLE_SOCKETS -// #define PREFER_WINDOWS_STYLE_SOCKETS - -// set the name of Rijndael cipher, was "Rijndael" before version 5.3 -#define CRYPTOPP_RIJNDAEL_NAME "AES" - -// ***************** Important Settings Again ******************** -// But the defaults should be ok. - -// namespace support is now required -#ifdef NO_NAMESPACE -# error namespace support is now required -#endif - -// Define this to workaround a Microsoft CryptoAPI bug where -// each call to CryptAcquireContext causes a 100 KB memory leak. -// Defining this will cause Crypto++ to make only one call to CryptAcquireContext. -#define WORKAROUND_MS_BUG_Q258000 - -#ifdef CRYPTOPP_DOXYGEN_PROCESSING -// Avoid putting "CryptoPP::" in front of everything in Doxygen output -# define CryptoPP -# define NAMESPACE_BEGIN(x) -# define NAMESPACE_END -// Get Doxygen to generate better documentation for these typedefs -# define DOCUMENTED_TYPEDEF(x, y) class y : public x {}; -#else -# define NAMESPACE_BEGIN(x) namespace x { -# define NAMESPACE_END } -# define DOCUMENTED_TYPEDEF(x, y) typedef x y; -#endif -#define ANONYMOUS_NAMESPACE_BEGIN namespace { -#define USING_NAMESPACE(x) using namespace x; -#define DOCUMENTED_NAMESPACE_BEGIN(x) namespace x { -#define DOCUMENTED_NAMESPACE_END } - -// What is the type of the third parameter to bind? -// For Unix, the new standard is ::socklen_t (typically unsigned int), and the old standard is int. -// Unfortunately there is no way to tell whether or not socklen_t is defined. -// To work around this, TYPE_OF_SOCKLEN_T is a macro so that you can change it from the makefile. -#ifndef TYPE_OF_SOCKLEN_T -# if defined(_WIN32) || defined(__CYGWIN__) -# define TYPE_OF_SOCKLEN_T int -# else -# define TYPE_OF_SOCKLEN_T ::socklen_t -# endif -#endif - -#if defined(__CYGWIN__) && defined(PREFER_WINDOWS_STYLE_SOCKETS) -# define __USE_W32_SOCKETS -#endif - -typedef unsigned char byte; // put in global namespace to avoid ambiguity with other byte typedefs - -NAMESPACE_BEGIN(CryptoPP) - -typedef unsigned short word16; -typedef unsigned int word32; - -#if defined(_MSC_VER) || defined(__BORLANDC__) - typedef unsigned __int64 word64; - #define W64LIT(x) x##ui64 -#else - typedef unsigned long long word64; - #define W64LIT(x) x##ULL -#endif - -// define large word type, used for file offsets and such -typedef word64 lword; -const lword LWORD_MAX = W64LIT(0xffffffffffffffff); - -#ifdef __GNUC__ - #define CRYPTOPP_GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) -#endif - -// define hword, word, and dword. these are used for multiprecision integer arithmetic -// Intel compiler won't have _umul128 until version 10.0. See http://softwarecommunity.intel.com/isn/Community/en-US/forums/thread/30231625.aspx -#if (defined(_MSC_VER) && (!defined(__INTEL_COMPILER) || __INTEL_COMPILER >= 1000) && (defined(_M_X64) || defined(_M_IA64))) || (defined(__DECCXX) && defined(__alpha__)) || (defined(__INTEL_COMPILER) && defined(__x86_64__)) || (defined(__SUNPRO_CC) && defined(__x86_64__)) - typedef word32 hword; - typedef word64 word; -#else - #define CRYPTOPP_NATIVE_DWORD_AVAILABLE - #if defined(__alpha__) || defined(__ia64__) || defined(_ARCH_PPC64) || defined(__x86_64__) || defined(__mips64) || defined(__sparc64__) - #if defined(__GNUC__) && !defined(__INTEL_COMPILER) && !(CRYPTOPP_GCC_VERSION == 40001 && defined(__APPLE__)) && CRYPTOPP_GCC_VERSION >= 30400 - // GCC 4.0.1 on MacOS X is missing __umodti3 and __udivti3 - // mode(TI) division broken on amd64 with GCC earlier than GCC 3.4 - typedef word32 hword; - typedef word64 word; - typedef __uint128_t dword; - typedef __uint128_t word128; - #define CRYPTOPP_WORD128_AVAILABLE - #else - // if we're here, it means we're on a 64-bit CPU but we don't have a way to obtain 128-bit multiplication results - typedef word16 hword; - typedef word32 word; - typedef word64 dword; - #endif - #else - // being here means the native register size is probably 32 bits or less - #define CRYPTOPP_BOOL_SLOW_WORD64 1 - typedef word16 hword; - typedef word32 word; - typedef word64 dword; - #endif -#endif -#ifndef CRYPTOPP_BOOL_SLOW_WORD64 - #define CRYPTOPP_BOOL_SLOW_WORD64 0 -#endif - -const unsigned int WORD_SIZE = sizeof(word); -const unsigned int WORD_BITS = WORD_SIZE * 8; - -NAMESPACE_END - -#ifndef CRYPTOPP_L1_CACHE_LINE_SIZE - // This should be a lower bound on the L1 cache line size. It's used for defense against timing attacks. - #if defined(_M_X64) || defined(__x86_64__) - #define CRYPTOPP_L1_CACHE_LINE_SIZE 64 - #else - // L1 cache line size is 32 on Pentium III and earlier - #define CRYPTOPP_L1_CACHE_LINE_SIZE 32 - #endif -#endif - -#if defined(_MSC_VER) - #if _MSC_VER == 1200 - #include <malloc.h> - #endif - #if _MSC_VER > 1200 || defined(_mm_free) - #define CRYPTOPP_MSVC6PP_OR_LATER // VC 6 processor pack or later - #else - #define CRYPTOPP_MSVC6_NO_PP // VC 6 without processor pack - #endif -#endif - -#ifndef CRYPTOPP_ALIGN_DATA - #if defined(CRYPTOPP_MSVC6PP_OR_LATER) - #define CRYPTOPP_ALIGN_DATA(x) __declspec(align(x)) - #elif defined(__GNUC__) - #define CRYPTOPP_ALIGN_DATA(x) __attribute__((aligned(x))) - #else - #define CRYPTOPP_ALIGN_DATA(x) - #endif -#endif - -#ifndef CRYPTOPP_SECTION_ALIGN16 - #if defined(__GNUC__) && !defined(__APPLE__) - // the alignment attribute doesn't seem to work without this section attribute when -fdata-sections is turned on - #define CRYPTOPP_SECTION_ALIGN16 __attribute__((section ("CryptoPP_Align16"))) - #else - #define CRYPTOPP_SECTION_ALIGN16 - #endif -#endif - -#if defined(_MSC_VER) || defined(__fastcall) - #define CRYPTOPP_FASTCALL __fastcall -#else - #define CRYPTOPP_FASTCALL -#endif - -// VC60 workaround: it doesn't allow typename in some places -#if defined(_MSC_VER) && (_MSC_VER < 1300) -#define CPP_TYPENAME -#else -#define CPP_TYPENAME typename -#endif - -// VC60 workaround: can't cast unsigned __int64 to float or double -#if defined(_MSC_VER) && !defined(CRYPTOPP_MSVC6PP_OR_LATER) -#define CRYPTOPP_VC6_INT64 (__int64) -#else -#define CRYPTOPP_VC6_INT64 -#endif - -#ifdef _MSC_VER -#define CRYPTOPP_NO_VTABLE __declspec(novtable) -#else -#define CRYPTOPP_NO_VTABLE -#endif - -#ifdef _MSC_VER - // 4231: nonstandard extension used : 'extern' before template explicit instantiation - // 4250: dominance - // 4251: member needs to have dll-interface - // 4275: base needs to have dll-interface - // 4660: explicitly instantiating a class that's already implicitly instantiated - // 4661: no suitable definition provided for explicit template instantiation request - // 4786: identifer was truncated in debug information - // 4355: 'this' : used in base member initializer list - // 4910: '__declspec(dllexport)' and 'extern' are incompatible on an explicit instantiation -# pragma warning(disable: 4231 4250 4251 4275 4660 4661 4786 4355 4910) -#endif - -#ifdef __BORLANDC__ -// 8037: non-const function called for const object. needed to work around BCB2006 bug -# pragma warn -8037 -#endif - -#if (defined(_MSC_VER) && _MSC_VER <= 1300) || defined(__MWERKS__) || defined(_STLPORT_VERSION) -#define CRYPTOPP_DISABLE_UNCAUGHT_EXCEPTION -#endif - -#ifndef CRYPTOPP_DISABLE_UNCAUGHT_EXCEPTION -#define CRYPTOPP_UNCAUGHT_EXCEPTION_AVAILABLE -#endif - -#ifdef CRYPTOPP_DISABLE_X86ASM // for backwards compatibility: this macro had both meanings -#define CRYPTOPP_DISABLE_ASM -#define CRYPTOPP_DISABLE_SSE2 -#endif - -#if !defined(CRYPTOPP_DISABLE_ASM) && ((defined(_MSC_VER) && defined(_M_IX86)) || (defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)))) - #define CRYPTOPP_X86_ASM_AVAILABLE - - #if !defined(CRYPTOPP_DISABLE_SSE2) && (defined(CRYPTOPP_MSVC6PP_OR_LATER) || CRYPTOPP_GCC_VERSION >= 30300) - #define CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE 1 - #else - #define CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE 0 - #endif - - // SSSE3 was actually introduced in GNU as 2.17, which was released 6/23/2006, but we can't tell what version of binutils is installed. - // GCC 4.1.2 was released on 2/13/2007, so we'll use that as a proxy for the binutils version. - #if !defined(CRYPTOPP_DISABLE_SSSE3) && (_MSC_VER >= 1400 || CRYPTOPP_GCC_VERSION >= 40102) - #define CRYPTOPP_BOOL_SSSE3_ASM_AVAILABLE 1 - #else - #define CRYPTOPP_BOOL_SSSE3_ASM_AVAILABLE 0 - #endif -#endif - -#if !defined(CRYPTOPP_DISABLE_ASM) && defined(_MSC_VER) && defined(_M_X64) - #define CRYPTOPP_X64_MASM_AVAILABLE -#endif - -#if !defined(CRYPTOPP_DISABLE_ASM) && defined(__GNUC__) && defined(__x86_64__) - #define CRYPTOPP_X64_ASM_AVAILABLE -#endif - -#if !defined(CRYPTOPP_DISABLE_SSE2) && (defined(CRYPTOPP_MSVC6PP_OR_LATER) || defined(__SSE2__)) - #define CRYPTOPP_BOOL_SSE2_INTRINSICS_AVAILABLE 1 -#else - #define CRYPTOPP_BOOL_SSE2_INTRINSICS_AVAILABLE 0 -#endif - -#if CRYPTOPP_BOOL_SSE2_INTRINSICS_AVAILABLE || CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE || defined(CRYPTOPP_X64_MASM_AVAILABLE) - #define CRYPTOPP_BOOL_ALIGN16_ENABLED 1 -#else - #define CRYPTOPP_BOOL_ALIGN16_ENABLED 0 -#endif - -// how to allocate 16-byte aligned memory (for SSE2) -#if defined(CRYPTOPP_MSVC6PP_OR_LATER) - #define CRYPTOPP_MM_MALLOC_AVAILABLE -#elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) - #define CRYPTOPP_MALLOC_ALIGNMENT_IS_16 -#elif defined(__linux__) || defined(__sun__) || defined(__CYGWIN__) - #define CRYPTOPP_MEMALIGN_AVAILABLE -#else - #define CRYPTOPP_NO_ALIGNED_ALLOC -#endif - -// how to disable inlining -#if defined(_MSC_VER) && _MSC_VER >= 1300 -# define CRYPTOPP_NOINLINE_DOTDOTDOT -# define CRYPTOPP_NOINLINE __declspec(noinline) -#elif defined(__GNUC__) -# define CRYPTOPP_NOINLINE_DOTDOTDOT -# define CRYPTOPP_NOINLINE __attribute__((noinline)) -#else -# define CRYPTOPP_NOINLINE_DOTDOTDOT ... -# define CRYPTOPP_NOINLINE -#endif - -// how to declare class constants -#if (defined(_MSC_VER) && _MSC_VER <= 1300) || defined(__INTEL_COMPILER) -# define CRYPTOPP_CONSTANT(x) enum {x}; -#else -# define CRYPTOPP_CONSTANT(x) static const int x; -#endif - -#if defined(_M_X64) || defined(__x86_64__) - #define CRYPTOPP_BOOL_X64 1 -#else - #define CRYPTOPP_BOOL_X64 0 -#endif - -// see http://predef.sourceforge.net/prearch.html -#if defined(_M_IX86) || defined(__i386__) || defined(__i386) || defined(_X86_) || defined(__I86__) || defined(__INTEL__) - #define CRYPTOPP_BOOL_X86 1 -#else - #define CRYPTOPP_BOOL_X86 0 -#endif - -#if CRYPTOPP_BOOL_X64 || CRYPTOPP_BOOL_X86 || defined(__powerpc__) - #define CRYPTOPP_ALLOW_UNALIGNED_DATA_ACCESS -#endif - -#define CRYPTOPP_VERSION 560 - -// ***************** determine availability of OS features ******************** - -#ifndef NO_OS_DEPENDENCE - -#if defined(_WIN32) || defined(__CYGWIN__) -#define CRYPTOPP_WIN32_AVAILABLE -#endif - -#if defined(__unix__) || defined(__MACH__) || defined(__NetBSD__) || defined(__sun) -#define CRYPTOPP_UNIX_AVAILABLE -#endif - -#if defined(CRYPTOPP_WIN32_AVAILABLE) || defined(CRYPTOPP_UNIX_AVAILABLE) -# define HIGHRES_TIMER_AVAILABLE -#endif - -#ifdef CRYPTOPP_UNIX_AVAILABLE -# define HAS_BERKELEY_STYLE_SOCKETS -#endif - -#ifdef CRYPTOPP_WIN32_AVAILABLE -# define HAS_WINDOWS_STYLE_SOCKETS -#endif - -#if defined(HIGHRES_TIMER_AVAILABLE) && (defined(HAS_BERKELEY_STYLE_SOCKETS) || defined(HAS_WINDOWS_STYLE_SOCKETS)) -# define SOCKETS_AVAILABLE -#endif - -#if defined(HAS_WINDOWS_STYLE_SOCKETS) && (!defined(HAS_BERKELEY_STYLE_SOCKETS) || defined(PREFER_WINDOWS_STYLE_SOCKETS)) -# define USE_WINDOWS_STYLE_SOCKETS -#else -# define USE_BERKELEY_STYLE_SOCKETS -#endif - -#if defined(HIGHRES_TIMER_AVAILABLE) && defined(CRYPTOPP_WIN32_AVAILABLE) && !defined(USE_BERKELEY_STYLE_SOCKETS) -# define WINDOWS_PIPES_AVAILABLE -#endif - -#if defined(CRYPTOPP_WIN32_AVAILABLE) && defined(USE_MS_CRYPTOAPI) -# define NONBLOCKING_RNG_AVAILABLE -# define OS_RNG_AVAILABLE -#endif - -#if defined(CRYPTOPP_UNIX_AVAILABLE) || defined(CRYPTOPP_DOXYGEN_PROCESSING) -# define NONBLOCKING_RNG_AVAILABLE -# define BLOCKING_RNG_AVAILABLE -# define OS_RNG_AVAILABLE -# define HAS_PTHREADS -# define THREADS_AVAILABLE -#endif - -#ifdef CRYPTOPP_WIN32_AVAILABLE -# define HAS_WINTHREADS -# define THREADS_AVAILABLE -#endif - -#endif // NO_OS_DEPENDENCE - -// ***************** DLL related ******************** - -#ifdef CRYPTOPP_WIN32_AVAILABLE - -#ifdef CRYPTOPP_EXPORTS -#define CRYPTOPP_IS_DLL -#define CRYPTOPP_DLL __declspec(dllexport) -#elif defined(CRYPTOPP_IMPORTS) -#define CRYPTOPP_IS_DLL -#define CRYPTOPP_DLL __declspec(dllimport) -#else -#define CRYPTOPP_DLL -#endif - -#define CRYPTOPP_API __cdecl - -#else // CRYPTOPP_WIN32_AVAILABLE - -#define CRYPTOPP_DLL -#define CRYPTOPP_API - -#endif // CRYPTOPP_WIN32_AVAILABLE - -#if defined(__MWERKS__) -#define CRYPTOPP_EXTERN_DLL_TEMPLATE_CLASS extern class CRYPTOPP_DLL -#elif defined(__BORLANDC__) || defined(__SUNPRO_CC) -#define CRYPTOPP_EXTERN_DLL_TEMPLATE_CLASS template class CRYPTOPP_DLL -#else -#define CRYPTOPP_EXTERN_DLL_TEMPLATE_CLASS extern template class CRYPTOPP_DLL -#endif - -#if defined(CRYPTOPP_MANUALLY_INSTANTIATE_TEMPLATES) && !defined(CRYPTOPP_IMPORTS) -#define CRYPTOPP_DLL_TEMPLATE_CLASS template class CRYPTOPP_DLL -#else -#define CRYPTOPP_DLL_TEMPLATE_CLASS CRYPTOPP_EXTERN_DLL_TEMPLATE_CLASS -#endif - -#if defined(__MWERKS__) -#define CRYPTOPP_EXTERN_STATIC_TEMPLATE_CLASS extern class -#elif defined(__BORLANDC__) || defined(__SUNPRO_CC) -#define CRYPTOPP_EXTERN_STATIC_TEMPLATE_CLASS template class -#else -#define CRYPTOPP_EXTERN_STATIC_TEMPLATE_CLASS extern template class -#endif - -#if defined(CRYPTOPP_MANUALLY_INSTANTIATE_TEMPLATES) && !defined(CRYPTOPP_EXPORTS) -#define CRYPTOPP_STATIC_TEMPLATE_CLASS template class -#else -#define CRYPTOPP_STATIC_TEMPLATE_CLASS CRYPTOPP_EXTERN_STATIC_TEMPLATE_CLASS -#endif - -#endif diff --git a/src/cryptopp/cpu.cpp b/src/cryptopp/cpu.cpp deleted file mode 100644 index 3e46804212..0000000000 --- a/src/cryptopp/cpu.cpp +++ /dev/null @@ -1,199 +0,0 @@ -// cpu.cpp - written and placed in the public domain by Wei Dai - -#include "pch.h" - -#ifndef CRYPTOPP_IMPORTS - -#include "cpu.h" -#include "misc.h" -#include <algorithm> - -#ifdef __GNUC__ -#include <signal.h> -#include <setjmp.h> -#endif - -#ifdef CRYPTOPP_MSVC6PP_OR_LATER -#include <emmintrin.h> -#endif - -NAMESPACE_BEGIN(CryptoPP) - -#ifdef CRYPTOPP_X86_ASM_AVAILABLE - -#ifndef _MSC_VER -typedef void (*SigHandler)(int); - -static jmp_buf s_jmpNoCPUID; -static void SigIllHandlerCPUID(int) -{ - longjmp(s_jmpNoCPUID, 1); -} -#endif - -bool CpuId(word32 input, word32 *output) -{ -#ifdef _MSC_VER - __try - { - __asm - { - mov eax, input - cpuid - mov edi, output - mov [edi], eax - mov [edi+4], ebx - mov [edi+8], ecx - mov [edi+12], edx - } - } - __except (1) - { - return false; - } - return true; -#else - SigHandler oldHandler = signal(SIGILL, SigIllHandlerCPUID); - if (oldHandler == SIG_ERR) - return false; - - bool result = true; - if (setjmp(s_jmpNoCPUID)) - result = false; - else - { - __asm__ - ( - // save ebx in case -fPIC is being used -#if CRYPTOPP_BOOL_X86 - "push %%ebx; cpuid; mov %%ebx, %%edi; pop %%ebx" -#else - "pushq %%rbx; cpuid; mov %%ebx, %%edi; popq %%rbx" -#endif - : "=a" (output[0]), "=D" (output[1]), "=c" (output[2]), "=d" (output[3]) - : "a" (input) - ); - } - - signal(SIGILL, oldHandler); - return result; -#endif -} - -#ifndef _MSC_VER -static jmp_buf s_jmpNoSSE2; -static void SigIllHandlerSSE2(int) -{ - longjmp(s_jmpNoSSE2, 1); -} -#endif - -#elif _MSC_VER >= 1400 && CRYPTOPP_BOOL_X64 - -bool CpuId(word32 input, word32 *output) -{ - __cpuid((int *)output, input); - return true; -} - -#endif - -#ifdef CRYPTOPP_CPUID_AVAILABLE - -static bool TrySSE2() -{ -#if CRYPTOPP_BOOL_X64 - return true; -#elif defined(_MSC_VER) - __try - { -#if CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE - AS2(por xmm0, xmm0) // executing SSE2 instruction -#elif CRYPTOPP_BOOL_SSE2_INTRINSICS_AVAILABLE - __mm128i x = _mm_setzero_si128(); - return _mm_cvtsi128_si32(x) == 0; -#endif - } - __except (1) - { - return false; - } - return true; -#elif defined(__GNUC__) - SigHandler oldHandler = signal(SIGILL, SigIllHandlerSSE2); - if (oldHandler == SIG_ERR) - return false; - - bool result = true; - if (setjmp(s_jmpNoSSE2)) - result = false; - else - { -#if CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE - __asm __volatile ("por %xmm0, %xmm0"); -#elif CRYPTOPP_BOOL_SSE2_INTRINSICS_AVAILABLE - __mm128i x = _mm_setzero_si128(); - result = _mm_cvtsi128_si32(x) == 0; -#endif - } - - signal(SIGILL, oldHandler); - return result; -#else - return false; -#endif -} - -bool g_x86DetectionDone = false; -bool g_hasISSE = false, g_hasSSE2 = false, g_hasSSSE3 = false, g_hasMMX = false, g_isP4 = false; -word32 g_cacheLineSize = CRYPTOPP_L1_CACHE_LINE_SIZE; - -void DetectX86Features() -{ - word32 cpuid[4], cpuid1[4]; - if (!CpuId(0, cpuid)) - return; - if (!CpuId(1, cpuid1)) - return; - - g_hasMMX = (cpuid1[3] & (1 << 23)) != 0; - if ((cpuid1[3] & (1 << 26)) != 0) - g_hasSSE2 = TrySSE2(); - g_hasSSSE3 = g_hasSSE2 && (cpuid1[2] & (1<<9)); - - if ((cpuid1[3] & (1 << 25)) != 0) - g_hasISSE = true; - else - { - word32 cpuid2[4]; - CpuId(0x080000000, cpuid2); - if (cpuid2[0] >= 0x080000001) - { - CpuId(0x080000001, cpuid2); - g_hasISSE = (cpuid2[3] & (1 << 22)) != 0; - } - } - - std::swap(cpuid[2], cpuid[3]); - if (memcmp(cpuid+1, "GenuineIntel", 12) == 0) - { - g_isP4 = ((cpuid1[0] >> 8) & 0xf) == 0xf; - g_cacheLineSize = 8 * GETBYTE(cpuid1[1], 1); - } - else if (memcmp(cpuid+1, "AuthenticAMD", 12) == 0) - { - CpuId(0x80000005, cpuid); - g_cacheLineSize = GETBYTE(cpuid[2], 0); - } - - if (!g_cacheLineSize) - g_cacheLineSize = CRYPTOPP_L1_CACHE_LINE_SIZE; - - g_x86DetectionDone = true; -} - -#endif - -NAMESPACE_END - -#endif diff --git a/src/cryptopp/cpu.h b/src/cryptopp/cpu.h deleted file mode 100644 index 7f01dad852..0000000000 --- a/src/cryptopp/cpu.h +++ /dev/null @@ -1,263 +0,0 @@ -#ifndef CRYPTOPP_CPU_H -#define CRYPTOPP_CPU_H - -#ifdef CRYPTOPP_GENERATE_X64_MASM - -#define CRYPTOPP_X86_ASM_AVAILABLE -#define CRYPTOPP_BOOL_X64 1 -#define CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE 1 -#define NAMESPACE_END - -#else - -#include "config.h" - -#ifdef CRYPTOPP_MSVC6PP_OR_LATER - #include <emmintrin.h> -#endif - -NAMESPACE_BEGIN(CryptoPP) - -#if defined(CRYPTOPP_X86_ASM_AVAILABLE) || (_MSC_VER >= 1400 && CRYPTOPP_BOOL_X64) - -#define CRYPTOPP_CPUID_AVAILABLE - -// these should not be used directly -extern CRYPTOPP_DLL bool g_x86DetectionDone; -extern CRYPTOPP_DLL bool g_hasSSE2; -extern CRYPTOPP_DLL bool g_hasISSE; -extern CRYPTOPP_DLL bool g_hasMMX; -extern CRYPTOPP_DLL bool g_hasSSSE3; -extern CRYPTOPP_DLL bool g_isP4; -extern CRYPTOPP_DLL word32 g_cacheLineSize; -CRYPTOPP_DLL void CRYPTOPP_API DetectX86Features(); - -CRYPTOPP_DLL bool CRYPTOPP_API CpuId(word32 input, word32 *output); - -#if CRYPTOPP_BOOL_X64 -inline bool HasSSE2() {return true;} -inline bool HasISSE() {return true;} -inline bool HasMMX() {return true;} -#else - -inline bool HasSSE2() -{ - if (!g_x86DetectionDone) - DetectX86Features(); - return g_hasSSE2; -} - -inline bool HasISSE() -{ - if (!g_x86DetectionDone) - DetectX86Features(); - return g_hasISSE; -} - -inline bool HasMMX() -{ - if (!g_x86DetectionDone) - DetectX86Features(); - return g_hasMMX; -} - -#endif - -inline bool HasSSSE3() -{ - if (!g_x86DetectionDone) - DetectX86Features(); - return g_hasSSSE3; -} - -inline bool IsP4() -{ - if (!g_x86DetectionDone) - DetectX86Features(); - return g_isP4; -} - -inline int GetCacheLineSize() -{ - if (!g_x86DetectionDone) - DetectX86Features(); - return g_cacheLineSize; -} - -#else - -inline int GetCacheLineSize() -{ - return CRYPTOPP_L1_CACHE_LINE_SIZE; -} - -inline bool HasSSSE3() {return false;} -inline bool IsP4() {return false;} - -// assume MMX and SSE2 if intrinsics are enabled -#if CRYPTOPP_BOOL_SSE2_INTRINSICS_AVAILABLE || CRYPTOPP_BOOL_X64 -inline bool HasSSE2() {return true;} -inline bool HasISSE() {return true;} -inline bool HasMMX() {return true;} -#else -inline bool HasSSE2() {return false;} -inline bool HasISSE() {return false;} -inline bool HasMMX() {return false;} -#endif - -#endif // #ifdef CRYPTOPP_X86_ASM_AVAILABLE || _MSC_VER >= 1400 - -#endif - -#ifdef CRYPTOPP_GENERATE_X64_MASM - #define AS1(x) x*newline* - #define AS2(x, y) x, y*newline* - #define AS3(x, y, z) x, y, z*newline* - #define ASS(x, y, a, b, c, d) x, y, a*64+b*16+c*4+d*newline* - #define ASL(x) label##x:*newline* - #define ASJ(x, y, z) x label##y*newline* - #define ASC(x, y) x label##y*newline* - #define AS_HEX(y) 0##y##h -#elif defined(__GNUC__) - // define these in two steps to allow arguments to be expanded - #define GNU_AS1(x) #x ";" - #define GNU_AS2(x, y) #x ", " #y ";" - #define GNU_AS3(x, y, z) #x ", " #y ", " #z ";" - #define GNU_ASL(x) "\n" #x ":" - #define GNU_ASJ(x, y, z) #x " " #y #z ";" - #define AS1(x) GNU_AS1(x) - #define AS2(x, y) GNU_AS2(x, y) - #define AS3(x, y, z) GNU_AS3(x, y, z) - #define ASS(x, y, a, b, c, d) #x ", " #y ", " #a "*64+" #b "*16+" #c "*4+" #d ";" - #define ASL(x) GNU_ASL(x) - #define ASJ(x, y, z) GNU_ASJ(x, y, z) - #define ASC(x, y) #x " " #y ";" - #define CRYPTOPP_NAKED - #define AS_HEX(y) 0x##y -#else - #define AS1(x) __asm {x} - #define AS2(x, y) __asm {x, y} - #define AS3(x, y, z) __asm {x, y, z} - #define ASS(x, y, a, b, c, d) __asm {x, y, _MM_SHUFFLE(a, b, c, d)} - #define ASL(x) __asm {label##x:} - #define ASJ(x, y, z) __asm {x label##y} - #define ASC(x, y) __asm {x label##y} - #define CRYPTOPP_NAKED __declspec(naked) - #define AS_HEX(y) 0x##y -#endif - -#define IF0(y) -#define IF1(y) y - -#ifdef CRYPTOPP_GENERATE_X64_MASM -#define ASM_MOD(x, y) ((x) MOD (y)) -#define XMMWORD_PTR XMMWORD PTR -#else -// GNU assembler doesn't seem to have mod operator -#define ASM_MOD(x, y) ((x)-((x)/(y))*(y)) -// GAS 2.15 doesn't support XMMWORD PTR. it seems necessary only for MASM -#define XMMWORD_PTR -#endif - -#if CRYPTOPP_BOOL_X86 - #define AS_REG_1 ecx - #define AS_REG_2 edx - #define AS_REG_3 esi - #define AS_REG_4 edi - #define AS_REG_5 eax - #define AS_REG_6 ebx - #define AS_REG_7 ebp - #define AS_REG_1d ecx - #define AS_REG_2d edx - #define AS_REG_3d esi - #define AS_REG_4d edi - #define AS_REG_5d eax - #define AS_REG_6d ebx - #define AS_REG_7d ebp - #define WORD_SZ 4 - #define WORD_REG(x) e##x - #define WORD_PTR DWORD PTR - #define AS_PUSH_IF86(x) AS1(push e##x) - #define AS_POP_IF86(x) AS1(pop e##x) - #define AS_JCXZ jecxz -#elif CRYPTOPP_BOOL_X64 - #ifdef CRYPTOPP_GENERATE_X64_MASM - #define AS_REG_1 rcx - #define AS_REG_2 rdx - #define AS_REG_3 r8 - #define AS_REG_4 r9 - #define AS_REG_5 rax - #define AS_REG_6 r10 - #define AS_REG_7 r11 - #define AS_REG_1d ecx - #define AS_REG_2d edx - #define AS_REG_3d r8d - #define AS_REG_4d r9d - #define AS_REG_5d eax - #define AS_REG_6d r10d - #define AS_REG_7d r11d - #else - #define AS_REG_1 rdi - #define AS_REG_2 rsi - #define AS_REG_3 rdx - #define AS_REG_4 rcx - #define AS_REG_5 r8 - #define AS_REG_6 r9 - #define AS_REG_7 r10 - #define AS_REG_1d edi - #define AS_REG_2d esi - #define AS_REG_3d edx - #define AS_REG_4d ecx - #define AS_REG_5d r8d - #define AS_REG_6d r9d - #define AS_REG_7d r10d - #endif - #define WORD_SZ 8 - #define WORD_REG(x) r##x - #define WORD_PTR QWORD PTR - #define AS_PUSH_IF86(x) - #define AS_POP_IF86(x) - #define AS_JCXZ jrcxz -#endif - -// helper macro for stream cipher output -#define AS_XMM_OUTPUT4(labelPrefix, inputPtr, outputPtr, x0, x1, x2, x3, t, p0, p1, p2, p3, increment)\ - AS2( test inputPtr, inputPtr)\ - ASC( jz, labelPrefix##3)\ - AS2( test inputPtr, 15)\ - ASC( jnz, labelPrefix##7)\ - AS2( pxor xmm##x0, [inputPtr+p0*16])\ - AS2( pxor xmm##x1, [inputPtr+p1*16])\ - AS2( pxor xmm##x2, [inputPtr+p2*16])\ - AS2( pxor xmm##x3, [inputPtr+p3*16])\ - AS2( add inputPtr, increment*16)\ - ASC( jmp, labelPrefix##3)\ - ASL(labelPrefix##7)\ - AS2( movdqu xmm##t, [inputPtr+p0*16])\ - AS2( pxor xmm##x0, xmm##t)\ - AS2( movdqu xmm##t, [inputPtr+p1*16])\ - AS2( pxor xmm##x1, xmm##t)\ - AS2( movdqu xmm##t, [inputPtr+p2*16])\ - AS2( pxor xmm##x2, xmm##t)\ - AS2( movdqu xmm##t, [inputPtr+p3*16])\ - AS2( pxor xmm##x3, xmm##t)\ - AS2( add inputPtr, increment*16)\ - ASL(labelPrefix##3)\ - AS2( test outputPtr, 15)\ - ASC( jnz, labelPrefix##8)\ - AS2( movdqa [outputPtr+p0*16], xmm##x0)\ - AS2( movdqa [outputPtr+p1*16], xmm##x1)\ - AS2( movdqa [outputPtr+p2*16], xmm##x2)\ - AS2( movdqa [outputPtr+p3*16], xmm##x3)\ - ASC( jmp, labelPrefix##9)\ - ASL(labelPrefix##8)\ - AS2( movdqu [outputPtr+p0*16], xmm##x0)\ - AS2( movdqu [outputPtr+p1*16], xmm##x1)\ - AS2( movdqu [outputPtr+p2*16], xmm##x2)\ - AS2( movdqu [outputPtr+p3*16], xmm##x3)\ - ASL(labelPrefix##9)\ - AS2( add outputPtr, increment*16) - -NAMESPACE_END - -#endif diff --git a/src/cryptopp/cryptlib.h b/src/cryptopp/cryptlib.h deleted file mode 100644 index 15cd6dad67..0000000000 --- a/src/cryptopp/cryptlib.h +++ /dev/null @@ -1,1668 +0,0 @@ -// cryptlib.h - written and placed in the public domain by Wei Dai -/*! \file - This file contains the declarations for the abstract base - classes that provide a uniform interface to this library. -*/ - -/*! \mainpage Crypto++ Library 5.6.0 API Reference -<dl> -<dt>Abstract Base Classes<dd> - cryptlib.h -<dt>Authenticated Encryption<dd> - AuthenticatedSymmetricCipherDocumentation -<dt>Symmetric Ciphers<dd> - SymmetricCipherDocumentation -<dt>Hash Functions<dd> - SHA1, SHA224, SHA256, SHA384, SHA512, Tiger, Whirlpool, RIPEMD160, RIPEMD320, RIPEMD128, RIPEMD256, Weak1::MD2, Weak1::MD4, Weak1::MD5 -<dt>Non-Cryptographic Checksums<dd> - CRC32, Adler32 -<dt>Message Authentication Codes<dd> - VMAC, HMAC, CBC_MAC, CMAC, DMAC, TTMAC, GCM (GMAC) -<dt>Random Number Generators<dd> - NullRNG(), LC_RNG, RandomPool, BlockingRng, NonblockingRng, AutoSeededRandomPool, AutoSeededX917RNG, DefaultAutoSeededRNG -<dt>Password-based Cryptography<dd> - PasswordBasedKeyDerivationFunction -<dt>Public Key Cryptosystems<dd> - DLIES, ECIES, LUCES, RSAES, RabinES, LUC_IES -<dt>Public Key Signature Schemes<dd> - DSA, GDSA, ECDSA, NR, ECNR, LUCSS, RSASS, RSASS_ISO, RabinSS, RWSS, ESIGN -<dt>Key Agreement<dd> - #DH, DH2, #MQV, ECDH, ECMQV, XTR_DH -<dt>Algebraic Structures<dd> - Integer, PolynomialMod2, PolynomialOver, RingOfPolynomialsOver, - ModularArithmetic, MontgomeryRepresentation, GFP2_ONB, - GF2NP, GF256, GF2_32, EC2N, ECP -<dt>Secret Sharing and Information Dispersal<dd> - SecretSharing, SecretRecovery, InformationDispersal, InformationRecovery -<dt>Compression<dd> - Deflator, Inflator, Gzip, Gunzip, ZlibCompressor, ZlibDecompressor -<dt>Input Source Classes<dd> - StringSource, ArraySource, FileSource, SocketSource, WindowsPipeSource, RandomNumberSource -<dt>Output Sink Classes<dd> - StringSinkTemplate, ArraySink, FileSink, SocketSink, WindowsPipeSink, RandomNumberSink -<dt>Filter Wrappers<dd> - StreamTransformationFilter, HashFilter, HashVerificationFilter, SignerFilter, SignatureVerificationFilter -<dt>Binary to Text Encoders and Decoders<dd> - HexEncoder, HexDecoder, Base64Encoder, Base64Decoder, Base32Encoder, Base32Decoder -<dt>Wrappers for OS features<dd> - Timer, Socket, WindowsHandle, ThreadLocalStorage, ThreadUserTimer -<dt>FIPS 140 related<dd> - fips140.h -</dl> - -In the FIPS 140-2 validated DLL version of Crypto++, only the following implementation class are available. -<dl> -<dt>Block Ciphers<dd> - AES, DES_EDE2, DES_EDE3, SKIPJACK -<dt>Cipher Modes (replace template parameter BC with one of the block ciphers above)<dd> - ECB_Mode\<BC\>, CTR_Mode\<BC\>, CBC_Mode\<BC\>, CFB_FIPS_Mode\<BC\>, OFB_Mode\<BC\> -<dt>Hash Functions<dd> - SHA1, SHA224, SHA256, SHA384, SHA512 -<dt>Public Key Signature Schemes (replace template parameter H with one of the hash functions above)<dd> - RSASS\<PKCS1v15, H\>, RSASS\<PSS, H\>, RSASS_ISO\<H\>, RWSS\<P1363_EMSA2, H\>, DSA, ECDSA\<ECP, H\>, ECDSA\<EC2N, H\> -<dt>Message Authentication Codes (replace template parameter H with one of the hash functions above)<dd> - HMAC\<H\>, CBC_MAC\<DES_EDE2\>, CBC_MAC\<DES_EDE3\> -<dt>Random Number Generators<dd> - DefaultAutoSeededRNG (AutoSeededX917RNG\<AES\>) -<dt>Key Agreement<dd> - #DH -<dt>Public Key Cryptosystems<dd> - RSAES\<OAEP\<SHA1\> \> -</dl> - -<p>This reference manual is a work in progress. Some classes are still lacking detailed descriptions. -<p>Click <a href="CryptoPPRef.zip">here</a> to download a zip archive containing this manual. -<p>Thanks to Ryan Phillips for providing the Doxygen configuration file -and getting me started with this manual. -*/ - -#ifndef CRYPTOPP_CRYPTLIB_H -#define CRYPTOPP_CRYPTLIB_H - -#include "config.h" -#include "stdcpp.h" - -NAMESPACE_BEGIN(CryptoPP) - -// forward declarations -class Integer; -class RandomNumberGenerator; -class BufferedTransformation; - -//! used to specify a direction for a cipher to operate in (encrypt or decrypt) -enum CipherDir {ENCRYPTION, DECRYPTION}; - -//! used to represent infinite time -const unsigned long INFINITE_TIME = ULONG_MAX; - -// VC60 workaround: using enums as template parameters causes problems -template <typename ENUM_TYPE, int VALUE> -struct EnumToType -{ - static ENUM_TYPE ToEnum() {return (ENUM_TYPE)VALUE;} -}; - -enum ByteOrder {LITTLE_ENDIAN_ORDER = 0, BIG_ENDIAN_ORDER = 1}; -typedef EnumToType<ByteOrder, LITTLE_ENDIAN_ORDER> LittleEndian; -typedef EnumToType<ByteOrder, BIG_ENDIAN_ORDER> BigEndian; - -//! base class for all exceptions thrown by Crypto++ -class CRYPTOPP_DLL Exception : public std::exception -{ -public: - //! error types - enum ErrorType { - //! a method is not implemented - NOT_IMPLEMENTED, - //! invalid function argument - INVALID_ARGUMENT, - //! BufferedTransformation received a Flush(true) signal but can't flush buffers - CANNOT_FLUSH, - //! data integerity check (such as CRC or MAC) failed - DATA_INTEGRITY_CHECK_FAILED, - //! received input data that doesn't conform to expected format - INVALID_DATA_FORMAT, - //! error reading from input device or writing to output device - IO_ERROR, - //! some error not belong to any of the above categories - OTHER_ERROR - }; - - explicit Exception(ErrorType errorType, const std::string &s) : m_errorType(errorType), m_what(s) {} - virtual ~Exception() throw() {} - const char *what() const throw() {return (m_what.c_str());} - const std::string &GetWhat() const {return m_what;} - void SetWhat(const std::string &s) {m_what = s;} - ErrorType GetErrorType() const {return m_errorType;} - void SetErrorType(ErrorType errorType) {m_errorType = errorType;} - -private: - ErrorType m_errorType; - std::string m_what; -}; - -//! exception thrown when an invalid argument is detected -class CRYPTOPP_DLL InvalidArgument : public Exception -{ -public: - explicit InvalidArgument(const std::string &s) : Exception(INVALID_ARGUMENT, s) {} -}; - -//! exception thrown when input data is received that doesn't conform to expected format -class CRYPTOPP_DLL InvalidDataFormat : public Exception -{ -public: - explicit InvalidDataFormat(const std::string &s) : Exception(INVALID_DATA_FORMAT, s) {} -}; - -//! exception thrown by decryption filters when trying to decrypt an invalid ciphertext -class CRYPTOPP_DLL InvalidCiphertext : public InvalidDataFormat -{ -public: - explicit InvalidCiphertext(const std::string &s) : InvalidDataFormat(s) {} -}; - -//! exception thrown by a class if a non-implemented method is called -class CRYPTOPP_DLL NotImplemented : public Exception -{ -public: - explicit NotImplemented(const std::string &s) : Exception(NOT_IMPLEMENTED, s) {} -}; - -//! exception thrown by a class when Flush(true) is called but it can't completely flush its buffers -class CRYPTOPP_DLL CannotFlush : public Exception -{ -public: - explicit CannotFlush(const std::string &s) : Exception(CANNOT_FLUSH, s) {} -}; - -//! error reported by the operating system -class CRYPTOPP_DLL OS_Error : public Exception -{ -public: - OS_Error(ErrorType errorType, const std::string &s, const std::string& operation, int errorCode) - : Exception(errorType, s), m_operation(operation), m_errorCode(errorCode) {} - ~OS_Error() throw() {} - - // the operating system API that reported the error - const std::string & GetOperation() const {return m_operation;} - // the error code return by the operating system - int GetErrorCode() const {return m_errorCode;} - -protected: - std::string m_operation; - int m_errorCode; -}; - -//! used to return decoding results -struct CRYPTOPP_DLL DecodingResult -{ - explicit DecodingResult() : isValidCoding(false), messageLength(0) {} - explicit DecodingResult(size_t len) : isValidCoding(true), messageLength(len) {} - - bool operator==(const DecodingResult &rhs) const {return isValidCoding == rhs.isValidCoding && messageLength == rhs.messageLength;} - bool operator!=(const DecodingResult &rhs) const {return !operator==(rhs);} - - bool isValidCoding; - size_t messageLength; - -#ifdef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY - operator size_t() const {return isValidCoding ? messageLength : 0;} -#endif -}; - -//! interface for retrieving values given their names -/*! \note This class is used to safely pass a variable number of arbitrarily typed arguments to functions - and to read values from keys and crypto parameters. - \note To obtain an object that implements NameValuePairs for the purpose of parameter - passing, use the MakeParameters() function. - \note To get a value from NameValuePairs, you need to know the name and the type of the value. - Call GetValueNames() on a NameValuePairs object to obtain a list of value names that it supports. - Then look at the Name namespace documentation to see what the type of each value is, or - alternatively, call GetIntValue() with the value name, and if the type is not int, a - ValueTypeMismatch exception will be thrown and you can get the actual type from the exception object. -*/ -class CRYPTOPP_NO_VTABLE NameValuePairs -{ -public: - virtual ~NameValuePairs() {} - - //! exception thrown when trying to retrieve a value using a different type than expected - class CRYPTOPP_DLL ValueTypeMismatch : public InvalidArgument - { - public: - ValueTypeMismatch(const std::string &name, const std::type_info &stored, const std::type_info &retrieving) - : InvalidArgument("NameValuePairs: type mismatch for '" + name + "', stored '" + stored.name() + "', trying to retrieve '" + retrieving.name() + "'") - , m_stored(stored), m_retrieving(retrieving) {} - - const std::type_info & GetStoredTypeInfo() const {return m_stored;} - const std::type_info & GetRetrievingTypeInfo() const {return m_retrieving;} - - private: - const std::type_info &m_stored; - const std::type_info &m_retrieving; - }; - - //! get a copy of this object or a subobject of it - template <class T> - bool GetThisObject(T &object) const - { - return GetValue((std::string("ThisObject:")+typeid(T).name()).c_str(), object); - } - - //! get a pointer to this object, as a pointer to T - template <class T> - bool GetThisPointer(T *&p) const - { - return GetValue((std::string("ThisPointer:")+typeid(T).name()).c_str(), p); - } - - //! get a named value, returns true if the name exists - template <class T> - bool GetValue(const char *name, T &value) const - { - return GetVoidValue(name, typeid(T), &value); - } - - //! get a named value, returns the default if the name doesn't exist - template <class T> - T GetValueWithDefault(const char *name, T defaultValue) const - { - GetValue(name, defaultValue); - return defaultValue; - } - - //! get a list of value names that can be retrieved - CRYPTOPP_DLL std::string GetValueNames() const - {std::string result; GetValue("ValueNames", result); return result;} - - //! get a named value with type int - /*! used to ensure we don't accidentally try to get an unsigned int - or some other type when we mean int (which is the most common case) */ - CRYPTOPP_DLL bool GetIntValue(const char *name, int &value) const - {return GetValue(name, value);} - - //! get a named value with type int, with default - CRYPTOPP_DLL int GetIntValueWithDefault(const char *name, int defaultValue) const - {return GetValueWithDefault(name, defaultValue);} - - //! used by derived classes to check for type mismatch - CRYPTOPP_DLL static void CRYPTOPP_API ThrowIfTypeMismatch(const char *name, const std::type_info &stored, const std::type_info &retrieving) - {if (stored != retrieving) throw ValueTypeMismatch(name, stored, retrieving);} - - template <class T> - void GetRequiredParameter(const char *className, const char *name, T &value) const - { - if (!GetValue(name, value)) - throw InvalidArgument(std::string(className) + ": missing required parameter '" + name + "'"); - } - - CRYPTOPP_DLL void GetRequiredIntParameter(const char *className, const char *name, int &value) const - { - if (!GetIntValue(name, value)) - throw InvalidArgument(std::string(className) + ": missing required parameter '" + name + "'"); - } - - //! to be implemented by derived classes, users should use one of the above functions instead - CRYPTOPP_DLL virtual bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const =0; -}; - -//! namespace containing value name definitions -/*! value names, types and semantics: - - ThisObject:ClassName (ClassName, copy of this object or a subobject) - ThisPointer:ClassName (const ClassName *, pointer to this object or a subobject) -*/ -DOCUMENTED_NAMESPACE_BEGIN(Name) -// more names defined in argnames.h -DOCUMENTED_NAMESPACE_END - -//! empty set of name-value pairs -class CRYPTOPP_DLL NullNameValuePairs : public NameValuePairs -{ -public: - bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const {return false;} -}; - -//! _ -extern CRYPTOPP_DLL const NullNameValuePairs g_nullNameValuePairs; - -// ******************************************************** - -//! interface for cloning objects, this is not implemented by most classes yet -class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE Clonable -{ -public: - virtual ~Clonable() {} - //! this is not implemented by most classes yet - virtual Clonable* Clone() const {throw NotImplemented("Clone() is not implemented yet.");} // TODO: make this =0 -}; - -//! interface for all crypto algorithms - -class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE Algorithm : public Clonable -{ -public: - /*! When FIPS 140-2 compliance is enabled and checkSelfTestStatus == true, - this constructor throws SelfTestFailure if the self test hasn't been run or fails. */ - Algorithm(bool checkSelfTestStatus = true); - //! returns name of this algorithm, not universally implemented yet - virtual std::string AlgorithmName() const {return "unknown";} -}; - -//! keying interface for crypto algorithms that take byte strings as keys -class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE SimpleKeyingInterface -{ -public: - virtual ~SimpleKeyingInterface() {} - - //! returns smallest valid key length in bytes */ - virtual size_t MinKeyLength() const =0; - //! returns largest valid key length in bytes */ - virtual size_t MaxKeyLength() const =0; - //! returns default (recommended) key length in bytes */ - virtual size_t DefaultKeyLength() const =0; - - //! returns the smallest valid key length in bytes that is >= min(n, GetMaxKeyLength()) - virtual size_t GetValidKeyLength(size_t n) const =0; - - //! returns whether n is a valid key length - virtual bool IsValidKeyLength(size_t n) const - {return n == GetValidKeyLength(n);} - - //! set or reset the key of this object - /*! \param params is used to specify Rounds, BlockSize, etc. */ - virtual void SetKey(const byte *key, size_t length, const NameValuePairs ¶ms = g_nullNameValuePairs); - - //! calls SetKey() with an NameValuePairs object that just specifies "Rounds" - void SetKeyWithRounds(const byte *key, size_t length, int rounds); - - //! calls SetKey() with an NameValuePairs object that just specifies "IV" - void SetKeyWithIV(const byte *key, size_t length, const byte *iv, size_t ivLength); - - //! calls SetKey() with an NameValuePairs object that just specifies "IV" - void SetKeyWithIV(const byte *key, size_t length, const byte *iv) - {SetKeyWithIV(key, length, iv, IVSize());} - - enum IV_Requirement {UNIQUE_IV = 0, RANDOM_IV, UNPREDICTABLE_RANDOM_IV, INTERNALLY_GENERATED_IV, NOT_RESYNCHRONIZABLE}; - //! returns the minimal requirement for secure IVs - virtual IV_Requirement IVRequirement() const =0; - - //! returns whether this object can be resynchronized (i.e. supports initialization vectors) - /*! If this function returns true, and no IV is passed to SetKey() and CanUseStructuredIVs()==true, an IV of all 0's will be assumed. */ - bool IsResynchronizable() const {return IVRequirement() < NOT_RESYNCHRONIZABLE;} - //! returns whether this object can use random IVs (in addition to ones returned by GetNextIV) - bool CanUseRandomIVs() const {return IVRequirement() <= UNPREDICTABLE_RANDOM_IV;} - //! returns whether this object can use random but possibly predictable IVs (in addition to ones returned by GetNextIV) - bool CanUsePredictableIVs() const {return IVRequirement() <= RANDOM_IV;} - //! returns whether this object can use structured IVs, for example a counter (in addition to ones returned by GetNextIV) - bool CanUseStructuredIVs() const {return IVRequirement() <= UNIQUE_IV;} - - virtual unsigned int IVSize() const {throw NotImplemented(GetAlgorithm().AlgorithmName() + ": this object doesn't support resynchronization");} - //! returns default length of IVs accepted by this object - unsigned int DefaultIVLength() const {return IVSize();} - //! returns minimal length of IVs accepted by this object - virtual unsigned int MinIVLength() const {return IVSize();} - //! returns maximal length of IVs accepted by this object - virtual unsigned int MaxIVLength() const {return IVSize();} - //! resynchronize with an IV. ivLength=-1 means use IVSize() - virtual void Resynchronize(const byte *iv, int ivLength=-1) {throw NotImplemented(GetAlgorithm().AlgorithmName() + ": this object doesn't support resynchronization");} - //! get a secure IV for the next message - /*! This method should be called after you finish encrypting one message and are ready to start the next one. - After calling it, you must call SetKey() or Resynchronize() before using this object again. - This method is not implemented on decryption objects. */ - virtual void GetNextIV(RandomNumberGenerator &rng, byte *IV); - -protected: - virtual const Algorithm & GetAlgorithm() const =0; - virtual void UncheckedSetKey(const byte *key, unsigned int length, const NameValuePairs ¶ms) =0; - - void ThrowIfInvalidKeyLength(size_t length); - void ThrowIfResynchronizable(); // to be called when no IV is passed - void ThrowIfInvalidIV(const byte *iv); // check for NULL IV if it can't be used - size_t ThrowIfInvalidIVLength(int size); - const byte * GetIVAndThrowIfInvalid(const NameValuePairs ¶ms, size_t &size); - inline void AssertValidKeyLength(size_t length) const - {assert(IsValidKeyLength(length));} -}; - -//! interface for the data processing part of block ciphers - -/*! Classes derived from BlockTransformation are block ciphers - in ECB mode (for example the DES::Encryption class), which are stateless. - These classes should not be used directly, but only in combination with - a mode class (see CipherModeDocumentation in modes.h). -*/ -class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE BlockTransformation : public Algorithm -{ -public: - //! encrypt or decrypt inBlock, xor with xorBlock, and write to outBlock - virtual void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const =0; - - //! encrypt or decrypt one block - /*! \pre size of inBlock and outBlock == BlockSize() */ - void ProcessBlock(const byte *inBlock, byte *outBlock) const - {ProcessAndXorBlock(inBlock, NULL, outBlock);} - - //! encrypt or decrypt one block in place - void ProcessBlock(byte *inoutBlock) const - {ProcessAndXorBlock(inoutBlock, NULL, inoutBlock);} - - //! block size of the cipher in bytes - virtual unsigned int BlockSize() const =0; - - //! returns how inputs and outputs should be aligned for optimal performance - virtual unsigned int OptimalDataAlignment() const; - - //! returns true if this is a permutation (i.e. there is an inverse transformation) - virtual bool IsPermutation() const {return true;} - - //! returns true if this is an encryption object - virtual bool IsForwardTransformation() const =0; - - //! return number of blocks that can be processed in parallel, for bit-slicing implementations - virtual unsigned int OptimalNumberOfParallelBlocks() const {return 1;} - - enum {BT_InBlockIsCounter=1, BT_DontIncrementInOutPointers=2, BT_XorInput=4, BT_ReverseDirection=8} FlagsForAdvancedProcessBlocks; - - //! encrypt and xor blocks according to flags (see FlagsForAdvancedProcessBlocks) - /*! /note If BT_InBlockIsCounter is set, last byte of inBlocks may be modified. */ - virtual size_t AdvancedProcessBlocks(const byte *inBlocks, const byte *xorBlocks, byte *outBlocks, size_t length, word32 flags) const; - - inline CipherDir GetCipherDirection() const {return IsForwardTransformation() ? ENCRYPTION : DECRYPTION;} -}; - -//! interface for the data processing part of stream ciphers - -class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE StreamTransformation : public Algorithm -{ -public: - //! return a reference to this object, - /*! This function is useful for passing a temporary StreamTransformation object to a - function that takes a non-const reference. */ - StreamTransformation& Ref() {return *this;} - - //! returns block size, if input must be processed in blocks, otherwise 1 - virtual unsigned int MandatoryBlockSize() const {return 1;} - - //! returns the input block size that is most efficient for this cipher - /*! \note optimal input length is n * OptimalBlockSize() - GetOptimalBlockSizeUsed() for any n > 0 */ - virtual unsigned int OptimalBlockSize() const {return MandatoryBlockSize();} - //! returns how much of the current block is used up - virtual unsigned int GetOptimalBlockSizeUsed() const {return 0;} - - //! returns how input should be aligned for optimal performance - virtual unsigned int OptimalDataAlignment() const; - - //! encrypt or decrypt an array of bytes of specified length - /*! \note either inString == outString, or they don't overlap */ - virtual void ProcessData(byte *outString, const byte *inString, size_t length) =0; - - //! for ciphers where the last block of data is special, encrypt or decrypt the last block of data - /*! For now the only use of this function is for CBC-CTS mode. */ - virtual void ProcessLastBlock(byte *outString, const byte *inString, size_t length); - //! returns the minimum size of the last block, 0 indicating the last block is not special - virtual unsigned int MinLastBlockSize() const {return 0;} - - //! same as ProcessData(inoutString, inoutString, length) - inline void ProcessString(byte *inoutString, size_t length) - {ProcessData(inoutString, inoutString, length);} - //! same as ProcessData(outString, inString, length) - inline void ProcessString(byte *outString, const byte *inString, size_t length) - {ProcessData(outString, inString, length);} - //! implemented as {ProcessData(&input, &input, 1); return input;} - inline byte ProcessByte(byte input) - {ProcessData(&input, &input, 1); return input;} - - //! returns whether this cipher supports random access - virtual bool IsRandomAccess() const =0; - //! for random access ciphers, seek to an absolute position - virtual void Seek(lword n) - { - assert(!IsRandomAccess()); - throw NotImplemented("StreamTransformation: this object doesn't support random access"); - } - - //! returns whether this transformation is self-inverting (e.g. xor with a keystream) - virtual bool IsSelfInverting() const =0; - //! returns whether this is an encryption object - virtual bool IsForwardTransformation() const =0; -}; - -//! interface for hash functions and data processing part of MACs - -/*! HashTransformation objects are stateful. They are created in an initial state, - change state as Update() is called, and return to the initial - state when Final() is called. This interface allows a large message to - be hashed in pieces by calling Update() on each piece followed by - calling Final(). -*/ -class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE HashTransformation : public Algorithm -{ -public: - //! return a reference to this object, - /*! This function is useful for passing a temporary HashTransformation object to a - function that takes a non-const reference. */ - HashTransformation& Ref() {return *this;} - - //! process more input - virtual void Update(const byte *input, size_t length) =0; - - //! request space to write input into - virtual byte * CreateUpdateSpace(size_t &size) {size=0; return NULL;} - - //! compute hash for current message, then restart for a new message - /*! \pre size of digest == DigestSize(). */ - virtual void Final(byte *digest) - {TruncatedFinal(digest, DigestSize());} - - //! discard the current state, and restart with a new message - virtual void Restart() - {TruncatedFinal(NULL, 0);} - - //! size of the hash/digest/MAC returned by Final() - virtual unsigned int DigestSize() const =0; - - //! same as DigestSize() - unsigned int TagSize() const {return DigestSize();} - - - //! block size of underlying compression function, or 0 if not block based - virtual unsigned int BlockSize() const {return 0;} - - //! input to Update() should have length a multiple of this for optimal speed - virtual unsigned int OptimalBlockSize() const {return 1;} - - //! returns how input should be aligned for optimal performance - virtual unsigned int OptimalDataAlignment() const; - - //! use this if your input is in one piece and you don't want to call Update() and Final() separately - virtual void CalculateDigest(byte *digest, const byte *input, size_t length) - {Update(input, length); Final(digest);} - - //! verify that digest is a valid digest for the current message, then reinitialize the object - /*! Default implementation is to call Final() and do a bitwise comparison - between its output and digest. */ - virtual bool Verify(const byte *digest) - {return TruncatedVerify(digest, DigestSize());} - - //! use this if your input is in one piece and you don't want to call Update() and Verify() separately - virtual bool VerifyDigest(const byte *digest, const byte *input, size_t length) - {Update(input, length); return Verify(digest);} - - //! truncated version of Final() - virtual void TruncatedFinal(byte *digest, size_t digestSize) =0; - - //! truncated version of CalculateDigest() - virtual void CalculateTruncatedDigest(byte *digest, size_t digestSize, const byte *input, size_t length) - {Update(input, length); TruncatedFinal(digest, digestSize);} - - //! truncated version of Verify() - virtual bool TruncatedVerify(const byte *digest, size_t digestLength); - - //! truncated version of VerifyDigest() - virtual bool VerifyTruncatedDigest(const byte *digest, size_t digestLength, const byte *input, size_t length) - {Update(input, length); return TruncatedVerify(digest, digestLength);} - -protected: - void ThrowIfInvalidTruncatedSize(size_t size) const; -}; - -typedef HashTransformation HashFunction; - -//! interface for one direction (encryption or decryption) of a block cipher -/*! \note These objects usually should not be used directly. See BlockTransformation for more details. */ -class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE BlockCipher : public SimpleKeyingInterface, public BlockTransformation -{ -protected: - const Algorithm & GetAlgorithm() const {return *this;} -}; - -//! interface for one direction (encryption or decryption) of a stream cipher or cipher mode -class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE SymmetricCipher : public SimpleKeyingInterface, public StreamTransformation -{ -protected: - const Algorithm & GetAlgorithm() const {return *this;} -}; - -//! interface for message authentication codes -class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE MessageAuthenticationCode : public SimpleKeyingInterface, public HashTransformation -{ -protected: - const Algorithm & GetAlgorithm() const {return *this;} -}; - -//! interface for for one direction (encryption or decryption) of a stream cipher or block cipher mode with authentication -/*! The StreamTransformation part of this interface is used to encrypt/decrypt the data, and the MessageAuthenticationCode part of this - interface is used to input additional authenticated data (AAD, which is MAC'ed but not encrypted), and to generate/verify the MAC. */ -class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE AuthenticatedSymmetricCipher : public MessageAuthenticationCode, public StreamTransformation -{ -public: - //! this indicates that a member function was called in the wrong state, for example trying to encrypt a message before having set the key or IV - class BadState : public Exception - { - public: - explicit BadState(const std::string &name, const char *message) : Exception(OTHER_ERROR, name + ": " + message) {} - explicit BadState(const std::string &name, const char *function, const char *state) : Exception(OTHER_ERROR, name + ": " + function + " was called before " + state) {} - }; - - //! the maximum length of AAD that can be input before the encrypted data - virtual lword MaxHeaderLength() const =0; - //! the maximum length of encrypted data - virtual lword MaxMessageLength() const =0; - //! the maximum length of AAD that can be input after the encrypted data - virtual lword MaxFooterLength() const {return 0;} - //! if this function returns true, SpecifyDataLengths() must be called before attempting to input data - /*! This is the case for some schemes, such as CCM. */ - virtual bool NeedsPrespecifiedDataLengths() const {return false;} - //! this function only needs to be called if NeedsPrespecifiedDataLengths() returns true - void SpecifyDataLengths(lword headerLength, lword messageLength, lword footerLength=0); - //! encrypt and generate MAC in one call. will truncate MAC if macSize < TagSize() - virtual void EncryptAndAuthenticate(byte *ciphertext, byte *mac, size_t macSize, const byte *iv, int ivLength, const byte *header, size_t headerLength, const byte *message, size_t messageLength); - //! decrypt and verify MAC in one call, returning true iff MAC is valid. will assume MAC is truncated if macLength < TagSize() - virtual bool DecryptAndVerify(byte *message, const byte *mac, size_t macLength, const byte *iv, int ivLength, const byte *header, size_t headerLength, const byte *ciphertext, size_t ciphertextLength); - - // redeclare this to avoid compiler ambiguity errors - virtual std::string AlgorithmName() const =0; - -protected: - const Algorithm & GetAlgorithm() const {return *static_cast<const MessageAuthenticationCode *>(this);} - virtual void UncheckedSpecifyDataLengths(lword headerLength, lword messageLength, lword footerLength) {} -}; - -#ifdef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY -typedef SymmetricCipher StreamCipher; -#endif - -//! interface for random number generators -/*! All return values are uniformly distributed over the range specified. -*/ -class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE RandomNumberGenerator : public Algorithm -{ -public: - //! update RNG state with additional unpredictable values - virtual void IncorporateEntropy(const byte *input, size_t length) {throw NotImplemented("RandomNumberGenerator: IncorporateEntropy not implemented");} - - //! returns true if IncorporateEntropy is implemented - virtual bool CanIncorporateEntropy() const {return false;} - - //! generate new random byte and return it - virtual byte GenerateByte(); - - //! generate new random bit and return it - /*! Default implementation is to call GenerateByte() and return its lowest bit. */ - virtual unsigned int GenerateBit(); - - //! generate a random 32 bit word in the range min to max, inclusive - virtual word32 GenerateWord32(word32 a=0, word32 b=0xffffffffL); - - //! generate random array of bytes - virtual void GenerateBlock(byte *output, size_t size); - - //! generate and discard n bytes - virtual void DiscardBytes(size_t n); - - //! generate random bytes as input to a BufferedTransformation - virtual void GenerateIntoBufferedTransformation(BufferedTransformation &target, const std::string &channel, lword length); - - //! randomly shuffle the specified array, resulting permutation is uniformly distributed - template <class IT> void Shuffle(IT begin, IT end) - { - for (; begin != end; ++begin) - std::iter_swap(begin, begin + GenerateWord32(0, end-begin-1)); - } - -#ifdef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY - byte GetByte() {return GenerateByte();} - unsigned int GetBit() {return GenerateBit();} - word32 GetLong(word32 a=0, word32 b=0xffffffffL) {return GenerateWord32(a, b);} - word16 GetShort(word16 a=0, word16 b=0xffff) {return (word16)GenerateWord32(a, b);} - void GetBlock(byte *output, size_t size) {GenerateBlock(output, size);} -#endif -}; - -//! returns a reference that can be passed to functions that ask for a RNG but doesn't actually use it -CRYPTOPP_DLL RandomNumberGenerator & CRYPTOPP_API NullRNG(); - -class WaitObjectContainer; -class CallStack; - -//! interface for objects that you can wait for - -class CRYPTOPP_NO_VTABLE Waitable -{ -public: - virtual ~Waitable() {} - - //! maximum number of wait objects that this object can return - virtual unsigned int GetMaxWaitObjectCount() const =0; - //! put wait objects into container - /*! \param callStack is used for tracing no wait loops, example: - something.GetWaitObjects(c, CallStack("my func after X", 0)); - - or in an outer GetWaitObjects() method that itself takes a callStack parameter: - innerThing.GetWaitObjects(c, CallStack("MyClass::GetWaitObjects at X", &callStack)); */ - virtual void GetWaitObjects(WaitObjectContainer &container, CallStack const& callStack) =0; - //! wait on this object - /*! same as creating an empty container, calling GetWaitObjects(), and calling Wait() on the container */ - bool Wait(unsigned long milliseconds, CallStack const& callStack); -}; - -//! the default channel for BufferedTransformation, equal to the empty string -extern CRYPTOPP_DLL const std::string DEFAULT_CHANNEL; - -//! channel for additional authenticated data, equal to "AAD" -extern CRYPTOPP_DLL const std::string AAD_CHANNEL; - -//! interface for buffered transformations - -/*! BufferedTransformation is a generalization of BlockTransformation, - StreamTransformation, and HashTransformation. - - A buffered transformation is an object that takes a stream of bytes - as input (this may be done in stages), does some computation on them, and - then places the result into an internal buffer for later retrieval. Any - partial result already in the output buffer is not modified by further - input. - - If a method takes a "blocking" parameter, and you - pass "false" for it, the method will return before all input has been processed if - the input cannot be processed without waiting (for network buffers to become available, for example). - In this case the method will return true - or a non-zero integer value. When this happens you must continue to call the method with the same - parameters until it returns false or zero, before calling any other method on it or - attached BufferedTransformation. The integer return value in this case is approximately - the number of bytes left to be processed, and can be used to implement a progress bar. - - For functions that take a "propagation" parameter, propagation != 0 means pass on the signal to attached - BufferedTransformation objects, with propagation decremented at each step until it reaches 0. - -1 means unlimited propagation. - - \nosubgrouping -*/ -class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE BufferedTransformation : public Algorithm, public Waitable -{ -public: - // placed up here for CW8 - static const std::string &NULL_CHANNEL; // same as DEFAULT_CHANNEL, for backwards compatibility - - BufferedTransformation() : Algorithm(false) {} - - //! return a reference to this object - /*! This function is useful for passing a temporary BufferedTransformation object to a - function that takes a non-const reference. */ - BufferedTransformation& Ref() {return *this;} - - //! \name INPUT - //@{ - //! input a byte for processing - size_t Put(byte inByte, bool blocking=true) - {return Put(&inByte, 1, blocking);} - //! input multiple bytes - size_t Put(const byte *inString, size_t length, bool blocking=true) - {return Put2(inString, length, 0, blocking);} - - //! input a 16-bit word - size_t PutWord16(word16 value, ByteOrder order=BIG_ENDIAN_ORDER, bool blocking=true); - //! input a 32-bit word - size_t PutWord32(word32 value, ByteOrder order=BIG_ENDIAN_ORDER, bool blocking=true); - - //! request space which can be written into by the caller, and then used as input to Put() - /*! \param size is requested size (as a hint) for input, and size of the returned space for output */ - /*! \note The purpose of this method is to help avoid doing extra memory allocations. */ - virtual byte * CreatePutSpace(size_t &size) {size=0; return NULL;} - - virtual bool CanModifyInput() const {return false;} - - //! input multiple bytes that may be modified by callee - size_t PutModifiable(byte *inString, size_t length, bool blocking=true) - {return PutModifiable2(inString, length, 0, blocking);} - - bool MessageEnd(int propagation=-1, bool blocking=true) - {return !!Put2(NULL, 0, propagation < 0 ? -1 : propagation+1, blocking);} - size_t PutMessageEnd(const byte *inString, size_t length, int propagation=-1, bool blocking=true) - {return Put2(inString, length, propagation < 0 ? -1 : propagation+1, blocking);} - - //! input multiple bytes for blocking or non-blocking processing - /*! \param messageEnd means how many filters to signal MessageEnd to, including this one */ - virtual size_t Put2(const byte *inString, size_t length, int messageEnd, bool blocking) =0; - //! input multiple bytes that may be modified by callee for blocking or non-blocking processing - /*! \param messageEnd means how many filters to signal MessageEnd to, including this one */ - virtual size_t PutModifiable2(byte *inString, size_t length, int messageEnd, bool blocking) - {return Put2(inString, length, messageEnd, blocking);} - - //! thrown by objects that have not implemented nonblocking input processing - struct BlockingInputOnly : public NotImplemented - {BlockingInputOnly(const std::string &s) : NotImplemented(s + ": Nonblocking input is not implemented by this object.") {}}; - //@} - - //! \name WAITING - //@{ - unsigned int GetMaxWaitObjectCount() const; - void GetWaitObjects(WaitObjectContainer &container, CallStack const& callStack); - //@} - - //! \name SIGNALS - //@{ - virtual void IsolatedInitialize(const NameValuePairs ¶meters) {throw NotImplemented("BufferedTransformation: this object can't be reinitialized");} - virtual bool IsolatedFlush(bool hardFlush, bool blocking) =0; - virtual bool IsolatedMessageSeriesEnd(bool blocking) {return false;} - - //! initialize or reinitialize this object - virtual void Initialize(const NameValuePairs ¶meters=g_nullNameValuePairs, int propagation=-1); - //! flush buffered input and/or output - /*! \param hardFlush is used to indicate whether all data should be flushed - \note Hard flushes must be used with care. It means try to process and output everything, even if - there may not be enough data to complete the action. For example, hard flushing a HexDecoder would - cause an error if you do it after inputing an odd number of hex encoded characters. - For some types of filters, for example ZlibDecompressor, hard flushes can only - be done at "synchronization points". These synchronization points are positions in the data - stream that are created by hard flushes on the corresponding reverse filters, in this - example ZlibCompressor. This is useful when zlib compressed data is moved across a - network in packets and compression state is preserved across packets, as in the ssh2 protocol. - */ - virtual bool Flush(bool hardFlush, int propagation=-1, bool blocking=true); - //! mark end of a series of messages - /*! There should be a MessageEnd immediately before MessageSeriesEnd. */ - virtual bool MessageSeriesEnd(int propagation=-1, bool blocking=true); - - //! set propagation of automatically generated and transferred signals - /*! propagation == 0 means do not automaticly generate signals */ - virtual void SetAutoSignalPropagation(int propagation) {} - - //! - virtual int GetAutoSignalPropagation() const {return 0;} -public: - -#ifdef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY - void Close() {MessageEnd();} -#endif - //@} - - //! \name RETRIEVAL OF ONE MESSAGE - //@{ - //! returns number of bytes that is currently ready for retrieval - /*! All retrieval functions return the actual number of bytes - retrieved, which is the lesser of the request number and - MaxRetrievable(). */ - virtual lword MaxRetrievable() const; - - //! returns whether any bytes are currently ready for retrieval - virtual bool AnyRetrievable() const; - - //! try to retrieve a single byte - virtual size_t Get(byte &outByte); - //! try to retrieve multiple bytes - virtual size_t Get(byte *outString, size_t getMax); - - //! peek at the next byte without removing it from the output buffer - virtual size_t Peek(byte &outByte) const; - //! peek at multiple bytes without removing them from the output buffer - virtual size_t Peek(byte *outString, size_t peekMax) const; - - //! try to retrieve a 16-bit word - size_t GetWord16(word16 &value, ByteOrder order=BIG_ENDIAN_ORDER); - //! try to retrieve a 32-bit word - size_t GetWord32(word32 &value, ByteOrder order=BIG_ENDIAN_ORDER); - - //! try to peek at a 16-bit word - size_t PeekWord16(word16 &value, ByteOrder order=BIG_ENDIAN_ORDER) const; - //! try to peek at a 32-bit word - size_t PeekWord32(word32 &value, ByteOrder order=BIG_ENDIAN_ORDER) const; - - //! move transferMax bytes of the buffered output to target as input - lword TransferTo(BufferedTransformation &target, lword transferMax=LWORD_MAX, const std::string &channel=DEFAULT_CHANNEL) - {TransferTo2(target, transferMax, channel); return transferMax;} - - //! discard skipMax bytes from the output buffer - virtual lword Skip(lword skipMax=LWORD_MAX); - - //! copy copyMax bytes of the buffered output to target as input - lword CopyTo(BufferedTransformation &target, lword copyMax=LWORD_MAX, const std::string &channel=DEFAULT_CHANNEL) const - {return CopyRangeTo(target, 0, copyMax, channel);} - - //! copy copyMax bytes of the buffered output, starting at position (relative to current position), to target as input - lword CopyRangeTo(BufferedTransformation &target, lword position, lword copyMax=LWORD_MAX, const std::string &channel=DEFAULT_CHANNEL) const - {lword i = position; CopyRangeTo2(target, i, i+copyMax, channel); return i-position;} - -#ifdef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY - unsigned long MaxRetrieveable() const {return MaxRetrievable();} -#endif - //@} - - //! \name RETRIEVAL OF MULTIPLE MESSAGES - //@{ - //! - virtual lword TotalBytesRetrievable() const; - //! number of times MessageEnd() has been received minus messages retrieved or skipped - virtual unsigned int NumberOfMessages() const; - //! returns true if NumberOfMessages() > 0 - virtual bool AnyMessages() const; - //! start retrieving the next message - /*! - Returns false if no more messages exist or this message - is not completely retrieved. - */ - virtual bool GetNextMessage(); - //! skip count number of messages - virtual unsigned int SkipMessages(unsigned int count=UINT_MAX); - //! - unsigned int TransferMessagesTo(BufferedTransformation &target, unsigned int count=UINT_MAX, const std::string &channel=DEFAULT_CHANNEL) - {TransferMessagesTo2(target, count, channel); return count;} - //! - unsigned int CopyMessagesTo(BufferedTransformation &target, unsigned int count=UINT_MAX, const std::string &channel=DEFAULT_CHANNEL) const; - - //! - virtual void SkipAll(); - //! - void TransferAllTo(BufferedTransformation &target, const std::string &channel=DEFAULT_CHANNEL) - {TransferAllTo2(target, channel);} - //! - void CopyAllTo(BufferedTransformation &target, const std::string &channel=DEFAULT_CHANNEL) const; - - virtual bool GetNextMessageSeries() {return false;} - virtual unsigned int NumberOfMessagesInThisSeries() const {return NumberOfMessages();} - virtual unsigned int NumberOfMessageSeries() const {return 0;} - //@} - - //! \name NON-BLOCKING TRANSFER OF OUTPUT - //@{ - //! upon return, byteCount contains number of bytes that have finished being transfered, and returns the number of bytes left in the current transfer block - virtual size_t TransferTo2(BufferedTransformation &target, lword &byteCount, const std::string &channel=DEFAULT_CHANNEL, bool blocking=true) =0; - //! upon return, begin contains the start position of data yet to be finished copying, and returns the number of bytes left in the current transfer block - virtual size_t CopyRangeTo2(BufferedTransformation &target, lword &begin, lword end=LWORD_MAX, const std::string &channel=DEFAULT_CHANNEL, bool blocking=true) const =0; - //! upon return, messageCount contains number of messages that have finished being transfered, and returns the number of bytes left in the current transfer block - size_t TransferMessagesTo2(BufferedTransformation &target, unsigned int &messageCount, const std::string &channel=DEFAULT_CHANNEL, bool blocking=true); - //! returns the number of bytes left in the current transfer block - size_t TransferAllTo2(BufferedTransformation &target, const std::string &channel=DEFAULT_CHANNEL, bool blocking=true); - //@} - - //! \name CHANNELS - //@{ - struct NoChannelSupport : public NotImplemented - {NoChannelSupport(const std::string &name) : NotImplemented(name + ": this object doesn't support multiple channels") {}}; - struct InvalidChannelName : public InvalidArgument - {InvalidChannelName(const std::string &name, const std::string &channel) : InvalidArgument(name + ": unexpected channel name \"" + channel + "\"") {}}; - - size_t ChannelPut(const std::string &channel, byte inByte, bool blocking=true) - {return ChannelPut(channel, &inByte, 1, blocking);} - size_t ChannelPut(const std::string &channel, const byte *inString, size_t length, bool blocking=true) - {return ChannelPut2(channel, inString, length, 0, blocking);} - - size_t ChannelPutModifiable(const std::string &channel, byte *inString, size_t length, bool blocking=true) - {return ChannelPutModifiable2(channel, inString, length, 0, blocking);} - - size_t ChannelPutWord16(const std::string &channel, word16 value, ByteOrder order=BIG_ENDIAN_ORDER, bool blocking=true); - size_t ChannelPutWord32(const std::string &channel, word32 value, ByteOrder order=BIG_ENDIAN_ORDER, bool blocking=true); - - bool ChannelMessageEnd(const std::string &channel, int propagation=-1, bool blocking=true) - {return !!ChannelPut2(channel, NULL, 0, propagation < 0 ? -1 : propagation+1, blocking);} - size_t ChannelPutMessageEnd(const std::string &channel, const byte *inString, size_t length, int propagation=-1, bool blocking=true) - {return ChannelPut2(channel, inString, length, propagation < 0 ? -1 : propagation+1, blocking);} - - virtual byte * ChannelCreatePutSpace(const std::string &channel, size_t &size); - - virtual size_t ChannelPut2(const std::string &channel, const byte *begin, size_t length, int messageEnd, bool blocking); - virtual size_t ChannelPutModifiable2(const std::string &channel, byte *begin, size_t length, int messageEnd, bool blocking); - - virtual bool ChannelFlush(const std::string &channel, bool hardFlush, int propagation=-1, bool blocking=true); - virtual bool ChannelMessageSeriesEnd(const std::string &channel, int propagation=-1, bool blocking=true); - - virtual void SetRetrievalChannel(const std::string &channel); - //@} - - //! \name ATTACHMENT - /*! Some BufferedTransformation objects (e.g. Filter objects) - allow other BufferedTransformation objects to be attached. When - this is done, the first object instead of buffering its output, - sents that output to the attached object as input. The entire - attachment chain is deleted when the anchor object is destructed. - */ - //@{ - //! returns whether this object allows attachment - virtual bool Attachable() {return false;} - //! returns the object immediately attached to this object or NULL for no attachment - virtual BufferedTransformation *AttachedTransformation() {assert(!Attachable()); return 0;} - //! - virtual const BufferedTransformation *AttachedTransformation() const - {return const_cast<BufferedTransformation *>(this)->AttachedTransformation();} - //! delete the current attachment chain and replace it with newAttachment - virtual void Detach(BufferedTransformation *newAttachment = 0) - {assert(!Attachable()); throw NotImplemented("BufferedTransformation: this object is not attachable");} - //! add newAttachment to the end of attachment chain - virtual void Attach(BufferedTransformation *newAttachment); - //@} - -protected: - static int DecrementPropagation(int propagation) - {return propagation != 0 ? propagation - 1 : 0;} - -private: - byte m_buf[4]; // for ChannelPutWord16 and ChannelPutWord32, to ensure buffer isn't deallocated before non-blocking operation completes -}; - -//! returns a reference to a BufferedTransformation object that discards all input -BufferedTransformation & TheBitBucket(); - -//! interface for crypto material, such as public and private keys, and crypto parameters - -class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE CryptoMaterial : public NameValuePairs -{ -public: - //! exception thrown when invalid crypto material is detected - class CRYPTOPP_DLL InvalidMaterial : public InvalidDataFormat - { - public: - explicit InvalidMaterial(const std::string &s) : InvalidDataFormat(s) {} - }; - - //! assign values from source to this object - /*! \note This function can be used to create a public key from a private key. */ - virtual void AssignFrom(const NameValuePairs &source) =0; - - //! check this object for errors - /*! \param level denotes the level of thoroughness: - 0 - using this object won't cause a crash or exception (rng is ignored) - 1 - this object will probably function (encrypt, sign, etc.) correctly (but may not check for weak keys and such) - 2 - make sure this object will function correctly, and do reasonable security checks - 3 - do checks that may take a long time - \return true if the tests pass */ - virtual bool Validate(RandomNumberGenerator &rng, unsigned int level) const =0; - - //! throws InvalidMaterial if this object fails Validate() test - virtual void ThrowIfInvalid(RandomNumberGenerator &rng, unsigned int level) const - {if (!Validate(rng, level)) throw InvalidMaterial("CryptoMaterial: this object contains invalid values");} - -// virtual std::vector<std::string> GetSupportedFormats(bool includeSaveOnly=false, bool includeLoadOnly=false); - - //! save key into a BufferedTransformation - virtual void Save(BufferedTransformation &bt) const - {throw NotImplemented("CryptoMaterial: this object does not support saving");} - - //! load key from a BufferedTransformation - /*! \throws KeyingErr if decode fails - \note Generally does not check that the key is valid. - Call ValidateKey() or ThrowIfInvalidKey() to check that. */ - virtual void Load(BufferedTransformation &bt) - {throw NotImplemented("CryptoMaterial: this object does not support loading");} - - //! \return whether this object supports precomputation - virtual bool SupportsPrecomputation() const {return false;} - //! do precomputation - /*! The exact semantics of Precompute() is varies, but - typically it means calculate a table of n objects - that can be used later to speed up computation. */ - virtual void Precompute(unsigned int n) - {assert(!SupportsPrecomputation()); throw NotImplemented("CryptoMaterial: this object does not support precomputation");} - //! retrieve previously saved precomputation - virtual void LoadPrecomputation(BufferedTransformation &storedPrecomputation) - {assert(!SupportsPrecomputation()); throw NotImplemented("CryptoMaterial: this object does not support precomputation");} - //! save precomputation for later use - virtual void SavePrecomputation(BufferedTransformation &storedPrecomputation) const - {assert(!SupportsPrecomputation()); throw NotImplemented("CryptoMaterial: this object does not support precomputation");} - - // for internal library use - void DoQuickSanityCheck() const {ThrowIfInvalid(NullRNG(), 0);} - -#if (defined(__SUNPRO_CC) && __SUNPRO_CC < 0x590) - // Sun Studio 11/CC 5.8 workaround: it generates incorrect code when casting to an empty virtual base class - char m_sunCCworkaround; -#endif -}; - -//! interface for generatable crypto material, such as private keys and crypto parameters - -class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE GeneratableCryptoMaterial : virtual public CryptoMaterial -{ -public: - //! generate a random key or crypto parameters - /*! \throws KeyingErr if algorithm parameters are invalid, or if a key can't be generated - (e.g., if this is a public key object) */ - virtual void GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs ¶ms = g_nullNameValuePairs) - {throw NotImplemented("GeneratableCryptoMaterial: this object does not support key/parameter generation");} - - //! calls the above function with a NameValuePairs object that just specifies "KeySize" - void GenerateRandomWithKeySize(RandomNumberGenerator &rng, unsigned int keySize); -}; - -//! interface for public keys - -class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE PublicKey : virtual public CryptoMaterial -{ -}; - -//! interface for private keys - -class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE PrivateKey : public GeneratableCryptoMaterial -{ -}; - -//! interface for crypto prameters - -class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE CryptoParameters : public GeneratableCryptoMaterial -{ -}; - -//! interface for asymmetric algorithms - -class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE AsymmetricAlgorithm : public Algorithm -{ -public: - //! returns a reference to the crypto material used by this object - virtual CryptoMaterial & AccessMaterial() =0; - //! returns a const reference to the crypto material used by this object - virtual const CryptoMaterial & GetMaterial() const =0; - - //! for backwards compatibility, calls AccessMaterial().Load(bt) - void BERDecode(BufferedTransformation &bt) - {AccessMaterial().Load(bt);} - //! for backwards compatibility, calls GetMaterial().Save(bt) - void DEREncode(BufferedTransformation &bt) const - {GetMaterial().Save(bt);} -}; - -//! interface for asymmetric algorithms using public keys - -class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE PublicKeyAlgorithm : public AsymmetricAlgorithm -{ -public: - // VC60 workaround: no co-variant return type - CryptoMaterial & AccessMaterial() {return AccessPublicKey();} - const CryptoMaterial & GetMaterial() const {return GetPublicKey();} - - virtual PublicKey & AccessPublicKey() =0; - virtual const PublicKey & GetPublicKey() const {return const_cast<PublicKeyAlgorithm *>(this)->AccessPublicKey();} -}; - -//! interface for asymmetric algorithms using private keys - -class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE PrivateKeyAlgorithm : public AsymmetricAlgorithm -{ -public: - CryptoMaterial & AccessMaterial() {return AccessPrivateKey();} - const CryptoMaterial & GetMaterial() const {return GetPrivateKey();} - - virtual PrivateKey & AccessPrivateKey() =0; - virtual const PrivateKey & GetPrivateKey() const {return const_cast<PrivateKeyAlgorithm *>(this)->AccessPrivateKey();} -}; - -//! interface for key agreement algorithms - -class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE KeyAgreementAlgorithm : public AsymmetricAlgorithm -{ -public: - CryptoMaterial & AccessMaterial() {return AccessCryptoParameters();} - const CryptoMaterial & GetMaterial() const {return GetCryptoParameters();} - - virtual CryptoParameters & AccessCryptoParameters() =0; - virtual const CryptoParameters & GetCryptoParameters() const {return const_cast<KeyAgreementAlgorithm *>(this)->AccessCryptoParameters();} -}; - -//! interface for public-key encryptors and decryptors - -/*! This class provides an interface common to encryptors and decryptors - for querying their plaintext and ciphertext lengths. -*/ -class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE PK_CryptoSystem -{ -public: - virtual ~PK_CryptoSystem() {} - - //! maximum length of plaintext for a given ciphertext length - /*! \note This function returns 0 if ciphertextLength is not valid (too long or too short). */ - virtual size_t MaxPlaintextLength(size_t ciphertextLength) const =0; - - //! calculate length of ciphertext given length of plaintext - /*! \note This function returns 0 if plaintextLength is not valid (too long). */ - virtual size_t CiphertextLength(size_t plaintextLength) const =0; - - //! this object supports the use of the parameter with the given name - /*! some possible parameter names: EncodingParameters, KeyDerivationParameters */ - virtual bool ParameterSupported(const char *name) const =0; - - //! return fixed ciphertext length, if one exists, otherwise return 0 - /*! \note "Fixed" here means length of ciphertext does not depend on length of plaintext. - It usually does depend on the key length. */ - virtual size_t FixedCiphertextLength() const {return 0;} - - //! return maximum plaintext length given the fixed ciphertext length, if one exists, otherwise return 0 - virtual size_t FixedMaxPlaintextLength() const {return 0;} - -#ifdef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY - size_t MaxPlainTextLength(size_t cipherTextLength) const {return MaxPlaintextLength(cipherTextLength);} - size_t CipherTextLength(size_t plainTextLength) const {return CiphertextLength(plainTextLength);} -#endif -}; - -//! interface for public-key encryptors -class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE PK_Encryptor : public PK_CryptoSystem, public PublicKeyAlgorithm -{ -public: - //! exception thrown when trying to encrypt plaintext of invalid length - class CRYPTOPP_DLL InvalidPlaintextLength : public Exception - { - public: - InvalidPlaintextLength() : Exception(OTHER_ERROR, "PK_Encryptor: invalid plaintext length") {} - }; - - //! encrypt a byte string - /*! \pre CiphertextLength(plaintextLength) != 0 (i.e., plaintext isn't too long) - \pre size of ciphertext == CiphertextLength(plaintextLength) - */ - virtual void Encrypt(RandomNumberGenerator &rng, - const byte *plaintext, size_t plaintextLength, - byte *ciphertext, const NameValuePairs ¶meters = g_nullNameValuePairs) const =0; - - //! create a new encryption filter - /*! \note The caller is responsible for deleting the returned pointer. - \note Encoding parameters should be passed in the "EP" channel. - */ - virtual BufferedTransformation * CreateEncryptionFilter(RandomNumberGenerator &rng, - BufferedTransformation *attachment=NULL, const NameValuePairs ¶meters = g_nullNameValuePairs) const; -}; - -//! interface for public-key decryptors - -class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE PK_Decryptor : public PK_CryptoSystem, public PrivateKeyAlgorithm -{ -public: - //! decrypt a byte string, and return the length of plaintext - /*! \pre size of plaintext == MaxPlaintextLength(ciphertextLength) bytes. - \return the actual length of the plaintext, indication that decryption failed. - */ - virtual DecodingResult Decrypt(RandomNumberGenerator &rng, - const byte *ciphertext, size_t ciphertextLength, - byte *plaintext, const NameValuePairs ¶meters = g_nullNameValuePairs) const =0; - - //! create a new decryption filter - /*! \note caller is responsible for deleting the returned pointer - */ - virtual BufferedTransformation * CreateDecryptionFilter(RandomNumberGenerator &rng, - BufferedTransformation *attachment=NULL, const NameValuePairs ¶meters = g_nullNameValuePairs) const; - - //! decrypt a fixed size ciphertext - DecodingResult FixedLengthDecrypt(RandomNumberGenerator &rng, const byte *ciphertext, byte *plaintext, const NameValuePairs ¶meters = g_nullNameValuePairs) const - {return Decrypt(rng, ciphertext, FixedCiphertextLength(), plaintext, parameters);} -}; - -#ifdef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY -typedef PK_CryptoSystem PK_FixedLengthCryptoSystem; -typedef PK_Encryptor PK_FixedLengthEncryptor; -typedef PK_Decryptor PK_FixedLengthDecryptor; -#endif - -//! interface for public-key signers and verifiers - -/*! This class provides an interface common to signers and verifiers - for querying scheme properties. -*/ -class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE PK_SignatureScheme -{ -public: - //! invalid key exception, may be thrown by any function in this class if the private or public key has a length that can't be used - class CRYPTOPP_DLL InvalidKeyLength : public Exception - { - public: - InvalidKeyLength(const std::string &message) : Exception(OTHER_ERROR, message) {} - }; - - //! key too short exception, may be thrown by any function in this class if the private or public key is too short to sign or verify anything - class CRYPTOPP_DLL KeyTooShort : public InvalidKeyLength - { - public: - KeyTooShort() : InvalidKeyLength("PK_Signer: key too short for this signature scheme") {} - }; - - virtual ~PK_SignatureScheme() {} - - //! signature length if it only depends on the key, otherwise 0 - virtual size_t SignatureLength() const =0; - - //! maximum signature length produced for a given length of recoverable message part - virtual size_t MaxSignatureLength(size_t recoverablePartLength = 0) const {return SignatureLength();} - - //! length of longest message that can be recovered, or 0 if this signature scheme does not support message recovery - virtual size_t MaxRecoverableLength() const =0; - - //! length of longest message that can be recovered from a signature of given length, or 0 if this signature scheme does not support message recovery - virtual size_t MaxRecoverableLengthFromSignatureLength(size_t signatureLength) const =0; - - //! requires a random number generator to sign - /*! if this returns false, NullRNG() can be passed to functions that take RandomNumberGenerator & */ - virtual bool IsProbabilistic() const =0; - - //! whether or not a non-recoverable message part can be signed - virtual bool AllowNonrecoverablePart() const =0; - - //! if this function returns true, during verification you must input the signature before the message, otherwise you can input it at anytime */ - virtual bool SignatureUpfront() const {return false;} - - //! whether you must input the recoverable part before the non-recoverable part during signing - virtual bool RecoverablePartFirst() const =0; -}; - -//! interface for accumulating messages to be signed or verified -/*! Only Update() should be called - on this class. No other functions inherited from HashTransformation should be called. -*/ -class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE PK_MessageAccumulator : public HashTransformation -{ -public: - //! should not be called on PK_MessageAccumulator - unsigned int DigestSize() const - {throw NotImplemented("PK_MessageAccumulator: DigestSize() should not be called");} - //! should not be called on PK_MessageAccumulator - void TruncatedFinal(byte *digest, size_t digestSize) - {throw NotImplemented("PK_MessageAccumulator: TruncatedFinal() should not be called");} -}; - -//! interface for public-key signers - -class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE PK_Signer : public PK_SignatureScheme, public PrivateKeyAlgorithm -{ -public: - //! create a new HashTransformation to accumulate the message to be signed - virtual PK_MessageAccumulator * NewSignatureAccumulator(RandomNumberGenerator &rng) const =0; - - virtual void InputRecoverableMessage(PK_MessageAccumulator &messageAccumulator, const byte *recoverableMessage, size_t recoverableMessageLength) const =0; - - //! sign and delete messageAccumulator (even in case of exception thrown) - /*! \pre size of signature == MaxSignatureLength() - \return actual signature length - */ - virtual size_t Sign(RandomNumberGenerator &rng, PK_MessageAccumulator *messageAccumulator, byte *signature) const; - - //! sign and restart messageAccumulator - /*! \pre size of signature == MaxSignatureLength() - \return actual signature length - */ - virtual size_t SignAndRestart(RandomNumberGenerator &rng, PK_MessageAccumulator &messageAccumulator, byte *signature, bool restart=true) const =0; - - //! sign a message - /*! \pre size of signature == MaxSignatureLength() - \return actual signature length - */ - virtual size_t SignMessage(RandomNumberGenerator &rng, const byte *message, size_t messageLen, byte *signature) const; - - //! sign a recoverable message - /*! \pre size of signature == MaxSignatureLength(recoverableMessageLength) - \return actual signature length - */ - virtual size_t SignMessageWithRecovery(RandomNumberGenerator &rng, const byte *recoverableMessage, size_t recoverableMessageLength, - const byte *nonrecoverableMessage, size_t nonrecoverableMessageLength, byte *signature) const; -}; - -//! interface for public-key signature verifiers -/*! The Recover* functions throw NotImplemented if the signature scheme does not support - message recovery. - The Verify* functions throw InvalidDataFormat if the scheme does support message - recovery and the signature contains a non-empty recoverable message part. The - Recovery* functions should be used in that case. -*/ -class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE PK_Verifier : public PK_SignatureScheme, public PublicKeyAlgorithm -{ -public: - //! create a new HashTransformation to accumulate the message to be verified - virtual PK_MessageAccumulator * NewVerificationAccumulator() const =0; - - //! input signature into a message accumulator - virtual void InputSignature(PK_MessageAccumulator &messageAccumulator, const byte *signature, size_t signatureLength) const =0; - - //! check whether messageAccumulator contains a valid signature and message, and delete messageAccumulator (even in case of exception thrown) - virtual bool Verify(PK_MessageAccumulator *messageAccumulator) const; - - //! check whether messageAccumulator contains a valid signature and message, and restart messageAccumulator - virtual bool VerifyAndRestart(PK_MessageAccumulator &messageAccumulator) const =0; - - //! check whether input signature is a valid signature for input message - virtual bool VerifyMessage(const byte *message, size_t messageLen, - const byte *signature, size_t signatureLength) const; - - //! recover a message from its signature - /*! \pre size of recoveredMessage == MaxRecoverableLengthFromSignatureLength(signatureLength) - */ - virtual DecodingResult Recover(byte *recoveredMessage, PK_MessageAccumulator *messageAccumulator) const; - - //! recover a message from its signature - /*! \pre size of recoveredMessage == MaxRecoverableLengthFromSignatureLength(signatureLength) - */ - virtual DecodingResult RecoverAndRestart(byte *recoveredMessage, PK_MessageAccumulator &messageAccumulator) const =0; - - //! recover a message from its signature - /*! \pre size of recoveredMessage == MaxRecoverableLengthFromSignatureLength(signatureLength) - */ - virtual DecodingResult RecoverMessage(byte *recoveredMessage, - const byte *nonrecoverableMessage, size_t nonrecoverableMessageLength, - const byte *signature, size_t signatureLength) const; -}; - -//! interface for domains of simple key agreement protocols - -/*! A key agreement domain is a set of parameters that must be shared - by two parties in a key agreement protocol, along with the algorithms - for generating key pairs and deriving agreed values. -*/ -class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE SimpleKeyAgreementDomain : public KeyAgreementAlgorithm -{ -public: - //! return length of agreed value produced - virtual unsigned int AgreedValueLength() const =0; - //! return length of private keys in this domain - virtual unsigned int PrivateKeyLength() const =0; - //! return length of public keys in this domain - virtual unsigned int PublicKeyLength() const =0; - //! generate private key - /*! \pre size of privateKey == PrivateKeyLength() */ - virtual void GeneratePrivateKey(RandomNumberGenerator &rng, byte *privateKey) const =0; - //! generate public key - /*! \pre size of publicKey == PublicKeyLength() */ - virtual void GeneratePublicKey(RandomNumberGenerator &rng, const byte *privateKey, byte *publicKey) const =0; - //! generate private/public key pair - /*! \note equivalent to calling GeneratePrivateKey() and then GeneratePublicKey() */ - virtual void GenerateKeyPair(RandomNumberGenerator &rng, byte *privateKey, byte *publicKey) const; - //! derive agreed value from your private key and couterparty's public key, return false in case of failure - /*! \note If you have previously validated the public key, use validateOtherPublicKey=false to save time. - \pre size of agreedValue == AgreedValueLength() - \pre length of privateKey == PrivateKeyLength() - \pre length of otherPublicKey == PublicKeyLength() - */ - virtual bool Agree(byte *agreedValue, const byte *privateKey, const byte *otherPublicKey, bool validateOtherPublicKey=true) const =0; - -#ifdef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY - bool ValidateDomainParameters(RandomNumberGenerator &rng) const - {return GetCryptoParameters().Validate(rng, 2);} -#endif -}; - -//! interface for domains of authenticated key agreement protocols - -/*! In an authenticated key agreement protocol, each party has two - key pairs. The long-lived key pair is called the static key pair, - and the short-lived key pair is called the ephemeral key pair. -*/ -class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE AuthenticatedKeyAgreementDomain : public KeyAgreementAlgorithm -{ -public: - //! return length of agreed value produced - virtual unsigned int AgreedValueLength() const =0; - - //! return length of static private keys in this domain - virtual unsigned int StaticPrivateKeyLength() const =0; - //! return length of static public keys in this domain - virtual unsigned int StaticPublicKeyLength() const =0; - //! generate static private key - /*! \pre size of privateKey == PrivateStaticKeyLength() */ - virtual void GenerateStaticPrivateKey(RandomNumberGenerator &rng, byte *privateKey) const =0; - //! generate static public key - /*! \pre size of publicKey == PublicStaticKeyLength() */ - virtual void GenerateStaticPublicKey(RandomNumberGenerator &rng, const byte *privateKey, byte *publicKey) const =0; - //! generate private/public key pair - /*! \note equivalent to calling GenerateStaticPrivateKey() and then GenerateStaticPublicKey() */ - virtual void GenerateStaticKeyPair(RandomNumberGenerator &rng, byte *privateKey, byte *publicKey) const; - - //! return length of ephemeral private keys in this domain - virtual unsigned int EphemeralPrivateKeyLength() const =0; - //! return length of ephemeral public keys in this domain - virtual unsigned int EphemeralPublicKeyLength() const =0; - //! generate ephemeral private key - /*! \pre size of privateKey == PrivateEphemeralKeyLength() */ - virtual void GenerateEphemeralPrivateKey(RandomNumberGenerator &rng, byte *privateKey) const =0; - //! generate ephemeral public key - /*! \pre size of publicKey == PublicEphemeralKeyLength() */ - virtual void GenerateEphemeralPublicKey(RandomNumberGenerator &rng, const byte *privateKey, byte *publicKey) const =0; - //! generate private/public key pair - /*! \note equivalent to calling GenerateEphemeralPrivateKey() and then GenerateEphemeralPublicKey() */ - virtual void GenerateEphemeralKeyPair(RandomNumberGenerator &rng, byte *privateKey, byte *publicKey) const; - - //! derive agreed value from your private keys and couterparty's public keys, return false in case of failure - /*! \note The ephemeral public key will always be validated. - If you have previously validated the static public key, use validateStaticOtherPublicKey=false to save time. - \pre size of agreedValue == AgreedValueLength() - \pre length of staticPrivateKey == StaticPrivateKeyLength() - \pre length of ephemeralPrivateKey == EphemeralPrivateKeyLength() - \pre length of staticOtherPublicKey == StaticPublicKeyLength() - \pre length of ephemeralOtherPublicKey == EphemeralPublicKeyLength() - */ - virtual bool Agree(byte *agreedValue, - const byte *staticPrivateKey, const byte *ephemeralPrivateKey, - const byte *staticOtherPublicKey, const byte *ephemeralOtherPublicKey, - bool validateStaticOtherPublicKey=true) const =0; - -#ifdef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY - bool ValidateDomainParameters(RandomNumberGenerator &rng) const - {return GetCryptoParameters().Validate(rng, 2);} -#endif -}; - -// interface for password authenticated key agreement protocols, not implemented yet -#if 0 -//! interface for protocol sessions -/*! The methods should be called in the following order: - - InitializeSession(rng, parameters); // or call initialize method in derived class - while (true) - { - if (OutgoingMessageAvailable()) - { - length = GetOutgoingMessageLength(); - GetOutgoingMessage(message); - ; // send outgoing message - } - - if (LastMessageProcessed()) - break; - - ; // receive incoming message - ProcessIncomingMessage(message); - } - ; // call methods in derived class to obtain result of protocol session -*/ -class ProtocolSession -{ -public: - //! exception thrown when an invalid protocol message is processed - class ProtocolError : public Exception - { - public: - ProtocolError(ErrorType errorType, const std::string &s) : Exception(errorType, s) {} - }; - - //! exception thrown when a function is called unexpectedly - /*! for example calling ProcessIncomingMessage() when ProcessedLastMessage() == true */ - class UnexpectedMethodCall : public Exception - { - public: - UnexpectedMethodCall(const std::string &s) : Exception(OTHER_ERROR, s) {} - }; - - ProtocolSession() : m_rng(NULL), m_throwOnProtocolError(true), m_validState(false) {} - virtual ~ProtocolSession() {} - - virtual void InitializeSession(RandomNumberGenerator &rng, const NameValuePairs ¶meters) =0; - - bool GetThrowOnProtocolError() const {return m_throwOnProtocolError;} - void SetThrowOnProtocolError(bool throwOnProtocolError) {m_throwOnProtocolError = throwOnProtocolError;} - - bool HasValidState() const {return m_validState;} - - virtual bool OutgoingMessageAvailable() const =0; - virtual unsigned int GetOutgoingMessageLength() const =0; - virtual void GetOutgoingMessage(byte *message) =0; - - virtual bool LastMessageProcessed() const =0; - virtual void ProcessIncomingMessage(const byte *message, unsigned int messageLength) =0; - -protected: - void HandleProtocolError(Exception::ErrorType errorType, const std::string &s) const; - void CheckAndHandleInvalidState() const; - void SetValidState(bool valid) {m_validState = valid;} - - RandomNumberGenerator *m_rng; - -private: - bool m_throwOnProtocolError, m_validState; -}; - -class KeyAgreementSession : public ProtocolSession -{ -public: - virtual unsigned int GetAgreedValueLength() const =0; - virtual void GetAgreedValue(byte *agreedValue) const =0; -}; - -class PasswordAuthenticatedKeyAgreementSession : public KeyAgreementSession -{ -public: - void InitializePasswordAuthenticatedKeyAgreementSession(RandomNumberGenerator &rng, - const byte *myId, unsigned int myIdLength, - const byte *counterPartyId, unsigned int counterPartyIdLength, - const byte *passwordOrVerifier, unsigned int passwordOrVerifierLength); -}; - -class PasswordAuthenticatedKeyAgreementDomain : public KeyAgreementAlgorithm -{ -public: - //! return whether the domain parameters stored in this object are valid - virtual bool ValidateDomainParameters(RandomNumberGenerator &rng) const - {return GetCryptoParameters().Validate(rng, 2);} - - virtual unsigned int GetPasswordVerifierLength(const byte *password, unsigned int passwordLength) const =0; - virtual void GeneratePasswordVerifier(RandomNumberGenerator &rng, const byte *userId, unsigned int userIdLength, const byte *password, unsigned int passwordLength, byte *verifier) const =0; - - enum RoleFlags {CLIENT=1, SERVER=2, INITIATOR=4, RESPONDER=8}; - - virtual bool IsValidRole(unsigned int role) =0; - virtual PasswordAuthenticatedKeyAgreementSession * CreateProtocolSession(unsigned int role) const =0; -}; -#endif - -//! BER Decode Exception Class, may be thrown during an ASN1 BER decode operation -class CRYPTOPP_DLL BERDecodeErr : public InvalidArgument -{ -public: - BERDecodeErr() : InvalidArgument("BER decode error") {} - BERDecodeErr(const std::string &s) : InvalidArgument(s) {} -}; - -//! interface for encoding and decoding ASN1 objects -class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE ASN1Object -{ -public: - virtual ~ASN1Object() {} - //! decode this object from a BufferedTransformation, using BER (Basic Encoding Rules) - virtual void BERDecode(BufferedTransformation &bt) =0; - //! encode this object into a BufferedTransformation, using DER (Distinguished Encoding Rules) - virtual void DEREncode(BufferedTransformation &bt) const =0; - //! encode this object into a BufferedTransformation, using BER - /*! this may be useful if DEREncode() would be too inefficient */ - virtual void BEREncode(BufferedTransformation &bt) const {DEREncode(bt);} -}; - -#ifdef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY -typedef PK_SignatureScheme PK_SignatureSystem; -typedef SimpleKeyAgreementDomain PK_SimpleKeyAgreementDomain; -typedef AuthenticatedKeyAgreementDomain PK_AuthenticatedKeyAgreementDomain; -#endif - -NAMESPACE_END - -#endif diff --git a/src/cryptopp/iterhash.h b/src/cryptopp/iterhash.h deleted file mode 100644 index 2f5895e2d3..0000000000 --- a/src/cryptopp/iterhash.h +++ /dev/null @@ -1,29 +0,0 @@ -#ifndef CRYPTOPP_ITERHASH_H -#define CRYPTOPP_ITERHASH_H - -#include "secblock.h" - -NAMESPACE_BEGIN(CryptoPP) - -// *** trimmed down dependency from iterhash.h *** -template <class T_HashWordType, class T_Endianness, unsigned int T_BlockSize, unsigned int T_StateSize, class T_Transform, unsigned int T_DigestSize = 0, bool T_StateAligned = false> -class CRYPTOPP_NO_VTABLE IteratedHashWithStaticTransform -{ -public: - CRYPTOPP_CONSTANT(DIGESTSIZE = T_DigestSize ? T_DigestSize : T_StateSize) - unsigned int DigestSize() const {return DIGESTSIZE;}; - typedef T_HashWordType HashWordType; - CRYPTOPP_CONSTANT(BLOCKSIZE = T_BlockSize) - -protected: - IteratedHashWithStaticTransform() {this->Init();} - void HashEndianCorrectedBlock(const T_HashWordType *data) {T_Transform::Transform(this->m_state, data);} - void Init() {T_Transform::InitState(this->m_state);} - - T_HashWordType* StateBuf() {return this->m_state;} - FixedSizeAlignedSecBlock<T_HashWordType, T_BlockSize/sizeof(T_HashWordType), T_StateAligned> m_state; -}; - -NAMESPACE_END - -#endif diff --git a/src/cryptopp/misc.h b/src/cryptopp/misc.h deleted file mode 100644 index de8037bf61..0000000000 --- a/src/cryptopp/misc.h +++ /dev/null @@ -1,1134 +0,0 @@ -#ifndef CRYPTOPP_MISC_H -#define CRYPTOPP_MISC_H - -#include "cryptlib.h" -#include "smartptr.h" -#include <string.h> // for memcpy and memmove - -#ifdef _MSC_VER - #include <stdlib.h> - #if _MSC_VER >= 1400 - // VC2005 workaround: disable declarations that conflict with winnt.h - #define _interlockedbittestandset CRYPTOPP_DISABLED_INTRINSIC_1 - #define _interlockedbittestandreset CRYPTOPP_DISABLED_INTRINSIC_2 - #define _interlockedbittestandset64 CRYPTOPP_DISABLED_INTRINSIC_3 - #define _interlockedbittestandreset64 CRYPTOPP_DISABLED_INTRINSIC_4 - #include <intrin.h> - #undef _interlockedbittestandset - #undef _interlockedbittestandreset - #undef _interlockedbittestandset64 - #undef _interlockedbittestandreset64 - #define CRYPTOPP_FAST_ROTATE(x) 1 - #elif _MSC_VER >= 1300 - #define CRYPTOPP_FAST_ROTATE(x) ((x) == 32 | (x) == 64) - #else - #define CRYPTOPP_FAST_ROTATE(x) ((x) == 32) - #endif -#elif (defined(__MWERKS__) && TARGET_CPU_PPC) || \ - (defined(__GNUC__) && (defined(_ARCH_PWR2) || defined(_ARCH_PWR) || defined(_ARCH_PPC) || defined(_ARCH_PPC64) || defined(_ARCH_COM))) - #define CRYPTOPP_FAST_ROTATE(x) ((x) == 32) -#elif defined(__GNUC__) && (CRYPTOPP_BOOL_X64 || CRYPTOPP_BOOL_X86) // depend on GCC's peephole optimization to generate rotate instructions - #define CRYPTOPP_FAST_ROTATE(x) 1 -#else - #define CRYPTOPP_FAST_ROTATE(x) 0 -#endif - -#ifdef __BORLANDC__ -#include <mem.h> -#endif - -#if defined(__GNUC__) && defined(__linux__) -#define CRYPTOPP_BYTESWAP_AVAILABLE -#include <byteswap.h> -#endif - -NAMESPACE_BEGIN(CryptoPP) - -// ************** compile-time assertion *************** - -template <bool b> -struct CompileAssert -{ - static char dummy[2*b-1]; -}; - -#define CRYPTOPP_COMPILE_ASSERT(assertion) CRYPTOPP_COMPILE_ASSERT_INSTANCE(assertion, __LINE__) -#if defined(CRYPTOPP_EXPORTS) || defined(CRYPTOPP_IMPORTS) -#define CRYPTOPP_COMPILE_ASSERT_INSTANCE(assertion, instance) -#else -#define CRYPTOPP_COMPILE_ASSERT_INSTANCE(assertion, instance) static CompileAssert<(assertion)> CRYPTOPP_ASSERT_JOIN(cryptopp_assert_, instance) -#endif -#define CRYPTOPP_ASSERT_JOIN(X, Y) CRYPTOPP_DO_ASSERT_JOIN(X, Y) -#define CRYPTOPP_DO_ASSERT_JOIN(X, Y) X##Y - -// ************** misc classes *************** - -class CRYPTOPP_DLL Empty -{ -}; - -//! _ -template <class BASE1, class BASE2> -class CRYPTOPP_NO_VTABLE TwoBases : public BASE1, public BASE2 -{ -}; - -//! _ -template <class BASE1, class BASE2, class BASE3> -class CRYPTOPP_NO_VTABLE ThreeBases : public BASE1, public BASE2, public BASE3 -{ -}; - -template <class T> -class ObjectHolder -{ -protected: - T m_object; -}; - -class NotCopyable -{ -public: - NotCopyable() {} -private: - NotCopyable(const NotCopyable &); - void operator=(const NotCopyable &); -}; - -template <class T> -struct NewObject -{ - T* operator()() const {return new T;} -}; - -/*! This function safely initializes a static object in a multithreaded environment without using locks. - It may leak memory when two threads try to initialize the static object at the same time - but this should be acceptable since each static object is only initialized once per session. -*/ -template <class T, class F = NewObject<T>, int instance=0> -class Singleton -{ -public: - Singleton(F objectFactory = F()) : m_objectFactory(objectFactory) {} - - // prevent this function from being inlined - CRYPTOPP_NOINLINE const T & Ref(CRYPTOPP_NOINLINE_DOTDOTDOT) const; - -private: - F m_objectFactory; -}; - -template <class T, class F, int instance> -const T & Singleton<T, F, instance>::Ref(CRYPTOPP_NOINLINE_DOTDOTDOT) const -{ - static simple_ptr<T> s_pObject; - static char s_objectState = 0; - -retry: - switch (s_objectState) - { - case 0: - s_objectState = 1; - try - { - s_pObject.m_p = m_objectFactory(); - } - catch(...) - { - s_objectState = 0; - throw; - } - s_objectState = 2; - break; - case 1: - goto retry; - default: - break; - } - return *s_pObject.m_p; -} - -// ************** misc functions *************** - -#if (!__STDC_WANT_SECURE_LIB__) -inline void memcpy_s(void *dest, size_t sizeInBytes, const void *src, size_t count) -{ - if (count > sizeInBytes) - throw InvalidArgument("memcpy_s: buffer overflow"); - memcpy(dest, src, count); -} - -inline void memmove_s(void *dest, size_t sizeInBytes, const void *src, size_t count) -{ - if (count > sizeInBytes) - throw InvalidArgument("memmove_s: buffer overflow"); - memmove(dest, src, count); -} -#endif - -inline void * memset_z(void *ptr, int value, size_t num) -{ -// avoid extranous warning on GCC 4.3.2 Ubuntu 8.10 -#if CRYPTOPP_GCC_VERSION >= 30001 - if (__builtin_constant_p(num) && num==0) - return ptr; -#endif - return memset(ptr, value, num); -} - -// can't use std::min or std::max in MSVC60 or Cygwin 1.1.0 -template <class T> inline const T& STDMIN(const T& a, const T& b) -{ - return b < a ? b : a; -} - -template <class T1, class T2> inline const T1 UnsignedMin(const T1& a, const T2& b) -{ - CRYPTOPP_COMPILE_ASSERT((sizeof(T1)<=sizeof(T2) && T2(-1)>0) || (sizeof(T1)>sizeof(T2) && T1(-1)>0)); - assert(a==0 || a>0); // GCC workaround: get rid of the warning "comparison is always true due to limited range of data type" - assert(b>=0); - - if (sizeof(T1)<=sizeof(T2)) - return b < (T2)a ? (T1)b : a; - else - return (T1)b < a ? (T1)b : a; -} - -template <class T> inline const T& STDMAX(const T& a, const T& b) -{ - return a < b ? b : a; -} - -#define RETURN_IF_NONZERO(x) size_t returnedValue = x; if (returnedValue) return returnedValue - -// this version of the macro is fastest on Pentium 3 and Pentium 4 with MSVC 6 SP5 w/ Processor Pack -#define GETBYTE(x, y) (unsigned int)byte((x)>>(8*(y))) -// these may be faster on other CPUs/compilers -// #define GETBYTE(x, y) (unsigned int)(((x)>>(8*(y)))&255) -// #define GETBYTE(x, y) (((byte *)&(x))[y]) - -#define CRYPTOPP_GET_BYTE_AS_BYTE(x, y) byte((x)>>(8*(y))) - -template <class T> -unsigned int Parity(T value) -{ - for (unsigned int i=8*sizeof(value)/2; i>0; i/=2) - value ^= value >> i; - return (unsigned int)value&1; -} - -template <class T> -unsigned int BytePrecision(const T &value) -{ - if (!value) - return 0; - - unsigned int l=0, h=8*sizeof(value); - - while (h-l > 8) - { - unsigned int t = (l+h)/2; - if (value >> t) - l = t; - else - h = t; - } - - return h/8; -} - -template <class T> -unsigned int BitPrecision(const T &value) -{ - if (!value) - return 0; - - unsigned int l=0, h=8*sizeof(value); - - while (h-l > 1) - { - unsigned int t = (l+h)/2; - if (value >> t) - l = t; - else - h = t; - } - - return h; -} - -template <class T> -inline T Crop(T value, size_t size) -{ - if (size < 8*sizeof(value)) - return T(value & ((T(1) << size) - 1)); - else - return value; -} - -template <class T1, class T2> -inline bool SafeConvert(T1 from, T2 &to) -{ - to = (T2)from; - if (from != to || (from > 0) != (to > 0)) - return false; - return true; -} - -inline size_t BitsToBytes(size_t bitCount) -{ - return ((bitCount+7)/(8)); -} - -inline size_t BytesToWords(size_t byteCount) -{ - return ((byteCount+WORD_SIZE-1)/WORD_SIZE); -} - -inline size_t BitsToWords(size_t bitCount) -{ - return ((bitCount+WORD_BITS-1)/(WORD_BITS)); -} - -inline size_t BitsToDwords(size_t bitCount) -{ - return ((bitCount+2*WORD_BITS-1)/(2*WORD_BITS)); -} - -CRYPTOPP_DLL void CRYPTOPP_API xorbuf(byte *buf, const byte *mask, size_t count); -CRYPTOPP_DLL void CRYPTOPP_API xorbuf(byte *output, const byte *input, const byte *mask, size_t count); - -CRYPTOPP_DLL bool CRYPTOPP_API VerifyBufsEqual(const byte *buf1, const byte *buf2, size_t count); - -template <class T> -inline bool IsPowerOf2(const T &n) -{ - return n > 0 && (n & (n-1)) == 0; -} - -template <class T1, class T2> -inline T2 ModPowerOf2(const T1 &a, const T2 &b) -{ - assert(IsPowerOf2(b)); - return T2(a) & (b-1); -} - -template <class T1, class T2> -inline T1 RoundDownToMultipleOf(const T1 &n, const T2 &m) -{ - if (IsPowerOf2(m)) - return n - ModPowerOf2(n, m); - else - return n - n%m; -} - -template <class T1, class T2> -inline T1 RoundUpToMultipleOf(const T1 &n, const T2 &m) -{ - if (n+m-1 < n) - throw InvalidArgument("RoundUpToMultipleOf: integer overflow"); - return RoundDownToMultipleOf(n+m-1, m); -} - -template <class T> -inline unsigned int GetAlignmentOf(T *dummy=NULL) // VC60 workaround -{ -#ifdef CRYPTOPP_ALLOW_UNALIGNED_DATA_ACCESS - if (sizeof(T) < 16) - return 1; -#endif - -#if (_MSC_VER >= 1300) - return __alignof(T); -#elif defined(__GNUC__) - return __alignof__(T); -#elif CRYPTOPP_BOOL_SLOW_WORD64 - return UnsignedMin(4U, sizeof(T)); -#else - return sizeof(T); -#endif -} - -inline bool IsAlignedOn(const void *p, unsigned int alignment) -{ - return alignment==1 || (IsPowerOf2(alignment) ? ModPowerOf2((size_t)p, alignment) == 0 : (size_t)p % alignment == 0); -} - -template <class T> -inline bool IsAligned(const void *p, T *dummy=NULL) // VC60 workaround -{ - return IsAlignedOn(p, GetAlignmentOf<T>()); -} - -#ifdef IS_LITTLE_ENDIAN - typedef LittleEndian NativeByteOrder; -#else - typedef BigEndian NativeByteOrder; -#endif - -inline ByteOrder GetNativeByteOrder() -{ - return NativeByteOrder::ToEnum(); -} - -inline bool NativeByteOrderIs(ByteOrder order) -{ - return order == GetNativeByteOrder(); -} - -template <class T> -std::string IntToString(T a, unsigned int base = 10) -{ - if (a == 0) - return "0"; - bool negate = false; - if (a < 0) - { - negate = true; - a = 0-a; // VC .NET does not like -a - } - std::string result; - while (a > 0) - { - T digit = a % base; - result = char((digit < 10 ? '0' : ('a' - 10)) + digit) + result; - a /= base; - } - if (negate) - result = "-" + result; - return result; -} - -template <class T1, class T2> -inline T1 SaturatingSubtract(const T1 &a, const T2 &b) -{ - return T1((a > b) ? (a - b) : 0); -} - -template <class T> -inline CipherDir GetCipherDir(const T &obj) -{ - return obj.IsForwardTransformation() ? ENCRYPTION : DECRYPTION; -} - -CRYPTOPP_DLL void CRYPTOPP_API CallNewHandler(); - -inline void IncrementCounterByOne(byte *inout, unsigned int s) -{ - for (int i=s-1, carry=1; i>=0 && carry; i--) - carry = !++inout[i]; -} - -inline void IncrementCounterByOne(byte *output, const byte *input, unsigned int s) -{ - int i, carry; - for (i=s-1, carry=1; i>=0 && carry; i--) - carry = ((output[i] = input[i]+1) == 0); - memcpy_s(output, s, input, i+1); -} - -// ************** rotate functions *************** - -template <class T> inline T rotlFixed(T x, unsigned int y) -{ - assert(y < sizeof(T)*8); - return T((x<<y) | (x>>(sizeof(T)*8-y))); -} - -template <class T> inline T rotrFixed(T x, unsigned int y) -{ - assert(y < sizeof(T)*8); - return T((x>>y) | (x<<(sizeof(T)*8-y))); -} - -template <class T> inline T rotlVariable(T x, unsigned int y) -{ - assert(y < sizeof(T)*8); - return T((x<<y) | (x>>(sizeof(T)*8-y))); -} - -template <class T> inline T rotrVariable(T x, unsigned int y) -{ - assert(y < sizeof(T)*8); - return T((x>>y) | (x<<(sizeof(T)*8-y))); -} - -template <class T> inline T rotlMod(T x, unsigned int y) -{ - y %= sizeof(T)*8; - return T((x<<y) | (x>>(sizeof(T)*8-y))); -} - -template <class T> inline T rotrMod(T x, unsigned int y) -{ - y %= sizeof(T)*8; - return T((x>>y) | (x<<(sizeof(T)*8-y))); -} - -#ifdef _MSC_VER - -template<> inline word32 rotlFixed<word32>(word32 x, unsigned int y) -{ - assert(y < 8*sizeof(x)); - return y ? _lrotl(x, y) : x; -} - -template<> inline word32 rotrFixed<word32>(word32 x, unsigned int y) -{ - assert(y < 8*sizeof(x)); - return y ? _lrotr(x, y) : x; -} - -template<> inline word32 rotlVariable<word32>(word32 x, unsigned int y) -{ - assert(y < 8*sizeof(x)); - return _lrotl(x, y); -} - -template<> inline word32 rotrVariable<word32>(word32 x, unsigned int y) -{ - assert(y < 8*sizeof(x)); - return _lrotr(x, y); -} - -template<> inline word32 rotlMod<word32>(word32 x, unsigned int y) -{ - return _lrotl(x, y); -} - -template<> inline word32 rotrMod<word32>(word32 x, unsigned int y) -{ - return _lrotr(x, y); -} - -#endif // #ifdef _MSC_VER - -#if _MSC_VER >= 1300 && !defined(__INTEL_COMPILER) -// Intel C++ Compiler 10.0 calls a function instead of using the rotate instruction when using these instructions - -template<> inline word64 rotlFixed<word64>(word64 x, unsigned int y) -{ - assert(y < 8*sizeof(x)); - return y ? _rotl64(x, y) : x; -} - -template<> inline word64 rotrFixed<word64>(word64 x, unsigned int y) -{ - assert(y < 8*sizeof(x)); - return y ? _rotr64(x, y) : x; -} - -template<> inline word64 rotlVariable<word64>(word64 x, unsigned int y) -{ - assert(y < 8*sizeof(x)); - return _rotl64(x, y); -} - -template<> inline word64 rotrVariable<word64>(word64 x, unsigned int y) -{ - assert(y < 8*sizeof(x)); - return _rotr64(x, y); -} - -template<> inline word64 rotlMod<word64>(word64 x, unsigned int y) -{ - return _rotl64(x, y); -} - -template<> inline word64 rotrMod<word64>(word64 x, unsigned int y) -{ - return _rotr64(x, y); -} - -#endif // #if _MSC_VER >= 1310 - -#if _MSC_VER >= 1400 && !defined(__INTEL_COMPILER) -// Intel C++ Compiler 10.0 gives undefined externals with these - -template<> inline word16 rotlFixed<word16>(word16 x, unsigned int y) -{ - assert(y < 8*sizeof(x)); - return y ? _rotl16(x, y) : x; -} - -template<> inline word16 rotrFixed<word16>(word16 x, unsigned int y) -{ - assert(y < 8*sizeof(x)); - return y ? _rotr16(x, y) : x; -} - -template<> inline word16 rotlVariable<word16>(word16 x, unsigned int y) -{ - assert(y < 8*sizeof(x)); - return _rotl16(x, y); -} - -template<> inline word16 rotrVariable<word16>(word16 x, unsigned int y) -{ - assert(y < 8*sizeof(x)); - return _rotr16(x, y); -} - -template<> inline word16 rotlMod<word16>(word16 x, unsigned int y) -{ - return _rotl16(x, y); -} - -template<> inline word16 rotrMod<word16>(word16 x, unsigned int y) -{ - return _rotr16(x, y); -} - -template<> inline byte rotlFixed<byte>(byte x, unsigned int y) -{ - assert(y < 8*sizeof(x)); - return y ? _rotl8(x, y) : x; -} - -template<> inline byte rotrFixed<byte>(byte x, unsigned int y) -{ - assert(y < 8*sizeof(x)); - return y ? _rotr8(x, y) : x; -} - -template<> inline byte rotlVariable<byte>(byte x, unsigned int y) -{ - assert(y < 8*sizeof(x)); - return _rotl8(x, y); -} - -template<> inline byte rotrVariable<byte>(byte x, unsigned int y) -{ - assert(y < 8*sizeof(x)); - return _rotr8(x, y); -} - -template<> inline byte rotlMod<byte>(byte x, unsigned int y) -{ - return _rotl8(x, y); -} - -template<> inline byte rotrMod<byte>(byte x, unsigned int y) -{ - return _rotr8(x, y); -} - -#endif // #if _MSC_VER >= 1400 - -#if (defined(__MWERKS__) && TARGET_CPU_PPC) - -template<> inline word32 rotlFixed<word32>(word32 x, unsigned int y) -{ - assert(y < 32); - return y ? __rlwinm(x,y,0,31) : x; -} - -template<> inline word32 rotrFixed<word32>(word32 x, unsigned int y) -{ - assert(y < 32); - return y ? __rlwinm(x,32-y,0,31) : x; -} - -template<> inline word32 rotlVariable<word32>(word32 x, unsigned int y) -{ - assert(y < 32); - return (__rlwnm(x,y,0,31)); -} - -template<> inline word32 rotrVariable<word32>(word32 x, unsigned int y) -{ - assert(y < 32); - return (__rlwnm(x,32-y,0,31)); -} - -template<> inline word32 rotlMod<word32>(word32 x, unsigned int y) -{ - return (__rlwnm(x,y,0,31)); -} - -template<> inline word32 rotrMod<word32>(word32 x, unsigned int y) -{ - return (__rlwnm(x,32-y,0,31)); -} - -#endif // #if (defined(__MWERKS__) && TARGET_CPU_PPC) - -// ************** endian reversal *************** - -template <class T> -inline unsigned int GetByte(ByteOrder order, T value, unsigned int index) -{ - if (order == LITTLE_ENDIAN_ORDER) - return GETBYTE(value, index); - else - return GETBYTE(value, sizeof(T)-index-1); -} - -inline byte ByteReverse(byte value) -{ - return value; -} - -inline word16 ByteReverse(word16 value) -{ -#ifdef CRYPTOPP_BYTESWAP_AVAILABLE - return bswap_16(value); -#elif defined(_MSC_VER) && _MSC_VER >= 1300 - return _byteswap_ushort(value); -#else - return rotlFixed(value, 8U); -#endif -} - -inline word32 ByteReverse(word32 value) -{ -#if defined(__GNUC__) && defined(CRYPTOPP_X86_ASM_AVAILABLE) - __asm__ ("bswap %0" : "=r" (value) : "0" (value)); - return value; -#elif defined(CRYPTOPP_BYTESWAP_AVAILABLE) - return bswap_32(value); -#elif defined(__MWERKS__) && TARGET_CPU_PPC - return (word32)__lwbrx(&value,0); -#elif _MSC_VER >= 1400 || (_MSC_VER >= 1300 && !defined(_DLL)) - return _byteswap_ulong(value); -#elif CRYPTOPP_FAST_ROTATE(32) - // 5 instructions with rotate instruction, 9 without - return (rotrFixed(value, 8U) & 0xff00ff00) | (rotlFixed(value, 8U) & 0x00ff00ff); -#else - // 6 instructions with rotate instruction, 8 without - value = ((value & 0xFF00FF00) >> 8) | ((value & 0x00FF00FF) << 8); - return rotlFixed(value, 16U); -#endif -} - -inline word64 ByteReverse(word64 value) -{ -#if defined(__GNUC__) && defined(CRYPTOPP_X86_ASM_AVAILABLE) && defined(__x86_64__) - __asm__ ("bswap %0" : "=r" (value) : "0" (value)); - return value; -#elif defined(CRYPTOPP_BYTESWAP_AVAILABLE) - return bswap_64(value); -#elif defined(_MSC_VER) && _MSC_VER >= 1300 - return _byteswap_uint64(value); -#elif CRYPTOPP_BOOL_SLOW_WORD64 - return (word64(ByteReverse(word32(value))) << 32) | ByteReverse(word32(value>>32)); -#else - value = ((value & W64LIT(0xFF00FF00FF00FF00)) >> 8) | ((value & W64LIT(0x00FF00FF00FF00FF)) << 8); - value = ((value & W64LIT(0xFFFF0000FFFF0000)) >> 16) | ((value & W64LIT(0x0000FFFF0000FFFF)) << 16); - return rotlFixed(value, 32U); -#endif -} - -inline byte BitReverse(byte value) -{ - value = ((value & 0xAA) >> 1) | ((value & 0x55) << 1); - value = ((value & 0xCC) >> 2) | ((value & 0x33) << 2); - return rotlFixed(value, 4U); -} - -inline word16 BitReverse(word16 value) -{ - value = ((value & 0xAAAA) >> 1) | ((value & 0x5555) << 1); - value = ((value & 0xCCCC) >> 2) | ((value & 0x3333) << 2); - value = ((value & 0xF0F0) >> 4) | ((value & 0x0F0F) << 4); - return ByteReverse(value); -} - -inline word32 BitReverse(word32 value) -{ - value = ((value & 0xAAAAAAAA) >> 1) | ((value & 0x55555555) << 1); - value = ((value & 0xCCCCCCCC) >> 2) | ((value & 0x33333333) << 2); - value = ((value & 0xF0F0F0F0) >> 4) | ((value & 0x0F0F0F0F) << 4); - return ByteReverse(value); -} - -inline word64 BitReverse(word64 value) -{ -#if CRYPTOPP_BOOL_SLOW_WORD64 - return (word64(BitReverse(word32(value))) << 32) | BitReverse(word32(value>>32)); -#else - value = ((value & W64LIT(0xAAAAAAAAAAAAAAAA)) >> 1) | ((value & W64LIT(0x5555555555555555)) << 1); - value = ((value & W64LIT(0xCCCCCCCCCCCCCCCC)) >> 2) | ((value & W64LIT(0x3333333333333333)) << 2); - value = ((value & W64LIT(0xF0F0F0F0F0F0F0F0)) >> 4) | ((value & W64LIT(0x0F0F0F0F0F0F0F0F)) << 4); - return ByteReverse(value); -#endif -} - -template <class T> -inline T BitReverse(T value) -{ - if (sizeof(T) == 1) - return (T)BitReverse((byte)value); - else if (sizeof(T) == 2) - return (T)BitReverse((word16)value); - else if (sizeof(T) == 4) - return (T)BitReverse((word32)value); - else - { - assert(sizeof(T) == 8); - return (T)BitReverse((word64)value); - } -} - -template <class T> -inline T ConditionalByteReverse(ByteOrder order, T value) -{ - return NativeByteOrderIs(order) ? value : ByteReverse(value); -} - -template <class T> -void ByteReverse(T *out, const T *in, size_t byteCount) -{ - assert(byteCount % sizeof(T) == 0); - size_t count = byteCount/sizeof(T); - for (size_t i=0; i<count; i++) - out[i] = ByteReverse(in[i]); -} - -template <class T> -inline void ConditionalByteReverse(ByteOrder order, T *out, const T *in, size_t byteCount) -{ - if (!NativeByteOrderIs(order)) - ByteReverse(out, in, byteCount); - else if (in != out) - memcpy_s(out, byteCount, in, byteCount); -} - -template <class T> -inline void GetUserKey(ByteOrder order, T *out, size_t outlen, const byte *in, size_t inlen) -{ - const size_t U = sizeof(T); - assert(inlen <= outlen*U); - memcpy_s(out, outlen*U, in, inlen); - memset_z((byte *)out+inlen, 0, outlen*U-inlen); - ConditionalByteReverse(order, out, out, RoundUpToMultipleOf(inlen, U)); -} - -#ifndef CRYPTOPP_ALLOW_UNALIGNED_DATA_ACCESS -inline byte UnalignedGetWordNonTemplate(ByteOrder order, const byte *block, const byte *) -{ - return block[0]; -} - -inline word16 UnalignedGetWordNonTemplate(ByteOrder order, const byte *block, const word16 *) -{ - return (order == BIG_ENDIAN_ORDER) - ? block[1] | (block[0] << 8) - : block[0] | (block[1] << 8); -} - -inline word32 UnalignedGetWordNonTemplate(ByteOrder order, const byte *block, const word32 *) -{ - return (order == BIG_ENDIAN_ORDER) - ? word32(block[3]) | (word32(block[2]) << 8) | (word32(block[1]) << 16) | (word32(block[0]) << 24) - : word32(block[0]) | (word32(block[1]) << 8) | (word32(block[2]) << 16) | (word32(block[3]) << 24); -} - -inline word64 UnalignedGetWordNonTemplate(ByteOrder order, const byte *block, const word64 *) -{ - return (order == BIG_ENDIAN_ORDER) - ? - (word64(block[7]) | - (word64(block[6]) << 8) | - (word64(block[5]) << 16) | - (word64(block[4]) << 24) | - (word64(block[3]) << 32) | - (word64(block[2]) << 40) | - (word64(block[1]) << 48) | - (word64(block[0]) << 56)) - : - (word64(block[0]) | - (word64(block[1]) << 8) | - (word64(block[2]) << 16) | - (word64(block[3]) << 24) | - (word64(block[4]) << 32) | - (word64(block[5]) << 40) | - (word64(block[6]) << 48) | - (word64(block[7]) << 56)); -} - -inline void UnalignedPutWordNonTemplate(ByteOrder order, byte *block, byte value, const byte *xorBlock) -{ - block[0] = xorBlock ? (value ^ xorBlock[0]) : value; -} - -inline void UnalignedPutWordNonTemplate(ByteOrder order, byte *block, word16 value, const byte *xorBlock) -{ - if (order == BIG_ENDIAN_ORDER) - { - if (xorBlock) - { - block[0] = xorBlock[0] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 1); - block[1] = xorBlock[1] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 0); - } - else - { - block[0] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 1); - block[1] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 0); - } - } - else - { - if (xorBlock) - { - block[0] = xorBlock[0] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 0); - block[1] = xorBlock[1] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 1); - } - else - { - block[0] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 0); - block[1] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 1); - } - } -} - -inline void UnalignedPutWordNonTemplate(ByteOrder order, byte *block, word32 value, const byte *xorBlock) -{ - if (order == BIG_ENDIAN_ORDER) - { - if (xorBlock) - { - block[0] = xorBlock[0] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 3); - block[1] = xorBlock[1] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 2); - block[2] = xorBlock[2] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 1); - block[3] = xorBlock[3] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 0); - } - else - { - block[0] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 3); - block[1] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 2); - block[2] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 1); - block[3] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 0); - } - } - else - { - if (xorBlock) - { - block[0] = xorBlock[0] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 0); - block[1] = xorBlock[1] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 1); - block[2] = xorBlock[2] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 2); - block[3] = xorBlock[3] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 3); - } - else - { - block[0] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 0); - block[1] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 1); - block[2] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 2); - block[3] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 3); - } - } -} - -inline void UnalignedPutWordNonTemplate(ByteOrder order, byte *block, word64 value, const byte *xorBlock) -{ - if (order == BIG_ENDIAN_ORDER) - { - if (xorBlock) - { - block[0] = xorBlock[0] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 7); - block[1] = xorBlock[1] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 6); - block[2] = xorBlock[2] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 5); - block[3] = xorBlock[3] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 4); - block[4] = xorBlock[4] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 3); - block[5] = xorBlock[5] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 2); - block[6] = xorBlock[6] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 1); - block[7] = xorBlock[7] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 0); - } - else - { - block[0] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 7); - block[1] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 6); - block[2] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 5); - block[3] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 4); - block[4] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 3); - block[5] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 2); - block[6] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 1); - block[7] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 0); - } - } - else - { - if (xorBlock) - { - block[0] = xorBlock[0] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 0); - block[1] = xorBlock[1] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 1); - block[2] = xorBlock[2] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 2); - block[3] = xorBlock[3] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 3); - block[4] = xorBlock[4] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 4); - block[5] = xorBlock[5] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 5); - block[6] = xorBlock[6] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 6); - block[7] = xorBlock[7] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 7); - } - else - { - block[0] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 0); - block[1] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 1); - block[2] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 2); - block[3] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 3); - block[4] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 4); - block[5] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 5); - block[6] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 6); - block[7] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 7); - } - } -} -#endif // #ifndef CRYPTOPP_ALLOW_UNALIGNED_DATA_ACCESS - -template <class T> -inline T GetWord(bool assumeAligned, ByteOrder order, const byte *block) -{ -#ifndef CRYPTOPP_ALLOW_UNALIGNED_DATA_ACCESS - if (!assumeAligned) - return UnalignedGetWordNonTemplate(order, block, (T*)NULL); - assert(IsAligned<T>(block)); -#endif - return ConditionalByteReverse(order, *reinterpret_cast<const T *>(block)); -} - -template <class T> -inline void GetWord(bool assumeAligned, ByteOrder order, T &result, const byte *block) -{ - result = GetWord<T>(assumeAligned, order, block); -} - -template <class T> -inline void PutWord(bool assumeAligned, ByteOrder order, byte *block, T value, const byte *xorBlock = NULL) -{ -#ifndef CRYPTOPP_ALLOW_UNALIGNED_DATA_ACCESS - if (!assumeAligned) - return UnalignedPutWordNonTemplate(order, block, value, xorBlock); - assert(IsAligned<T>(block)); - assert(IsAligned<T>(xorBlock)); -#endif - *reinterpret_cast<T *>(block) = ConditionalByteReverse(order, value) ^ (xorBlock ? *reinterpret_cast<const T *>(xorBlock) : 0); -} - -template <class T, class B, bool A=false> -class GetBlock -{ -public: - GetBlock(const void *block) - : m_block((const byte *)block) {} - - template <class U> - inline GetBlock<T, B, A> & operator()(U &x) - { - CRYPTOPP_COMPILE_ASSERT(sizeof(U) >= sizeof(T)); - x = GetWord<T>(A, B::ToEnum(), m_block); - m_block += sizeof(T); - return *this; - } - -private: - const byte *m_block; -}; - -template <class T, class B, bool A=false> -class PutBlock -{ -public: - PutBlock(const void *xorBlock, void *block) - : m_xorBlock((const byte *)xorBlock), m_block((byte *)block) {} - - template <class U> - inline PutBlock<T, B, A> & operator()(U x) - { - PutWord(A, B::ToEnum(), m_block, (T)x, m_xorBlock); - m_block += sizeof(T); - if (m_xorBlock) - m_xorBlock += sizeof(T); - return *this; - } - -private: - const byte *m_xorBlock; - byte *m_block; -}; - -template <class T, class B, bool GA=false, bool PA=false> -struct BlockGetAndPut -{ - // function needed because of C++ grammatical ambiguity between expression-statements and declarations - static inline GetBlock<T, B, GA> Get(const void *block) {return GetBlock<T, B, GA>(block);} - typedef PutBlock<T, B, PA> Put; -}; - -template <class T> -std::string WordToString(T value, ByteOrder order = BIG_ENDIAN_ORDER) -{ - if (!NativeByteOrderIs(order)) - value = ByteReverse(value); - - return std::string((char *)&value, sizeof(value)); -} - -template <class T> -T StringToWord(const std::string &str, ByteOrder order = BIG_ENDIAN_ORDER) -{ - T value = 0; - memcpy_s(&value, sizeof(value), str.data(), UnsignedMin(str.size(), sizeof(value))); - return NativeByteOrderIs(order) ? value : ByteReverse(value); -} - -// ************** help remove warning on g++ *************** - -template <bool overflow> struct SafeShifter; - -template<> struct SafeShifter<true> -{ - template <class T> - static inline T RightShift(T value, unsigned int bits) - { - return 0; - } - - template <class T> - static inline T LeftShift(T value, unsigned int bits) - { - return 0; - } -}; - -template<> struct SafeShifter<false> -{ - template <class T> - static inline T RightShift(T value, unsigned int bits) - { - return value >> bits; - } - - template <class T> - static inline T LeftShift(T value, unsigned int bits) - { - return value << bits; - } -}; - -template <unsigned int bits, class T> -inline T SafeRightShift(T value) -{ - return SafeShifter<(bits>=(8*sizeof(T)))>::RightShift(value, bits); -} - -template <unsigned int bits, class T> -inline T SafeLeftShift(T value) -{ - return SafeShifter<(bits>=(8*sizeof(T)))>::LeftShift(value, bits); -} - -// ************** use one buffer for multiple data members *************** - -#define CRYPTOPP_BLOCK_1(n, t, s) t* m_##n() {return (t *)(m_aggregate+0);} size_t SS1() {return sizeof(t)*(s);} size_t m_##n##Size() {return (s);} -#define CRYPTOPP_BLOCK_2(n, t, s) t* m_##n() {return (t *)(m_aggregate+SS1());} size_t SS2() {return SS1()+sizeof(t)*(s);} size_t m_##n##Size() {return (s);} -#define CRYPTOPP_BLOCK_3(n, t, s) t* m_##n() {return (t *)(m_aggregate+SS2());} size_t SS3() {return SS2()+sizeof(t)*(s);} size_t m_##n##Size() {return (s);} -#define CRYPTOPP_BLOCK_4(n, t, s) t* m_##n() {return (t *)(m_aggregate+SS3());} size_t SS4() {return SS3()+sizeof(t)*(s);} size_t m_##n##Size() {return (s);} -#define CRYPTOPP_BLOCK_5(n, t, s) t* m_##n() {return (t *)(m_aggregate+SS4());} size_t SS5() {return SS4()+sizeof(t)*(s);} size_t m_##n##Size() {return (s);} -#define CRYPTOPP_BLOCK_6(n, t, s) t* m_##n() {return (t *)(m_aggregate+SS5());} size_t SS6() {return SS5()+sizeof(t)*(s);} size_t m_##n##Size() {return (s);} -#define CRYPTOPP_BLOCK_7(n, t, s) t* m_##n() {return (t *)(m_aggregate+SS6());} size_t SS7() {return SS6()+sizeof(t)*(s);} size_t m_##n##Size() {return (s);} -#define CRYPTOPP_BLOCK_8(n, t, s) t* m_##n() {return (t *)(m_aggregate+SS7());} size_t SS8() {return SS7()+sizeof(t)*(s);} size_t m_##n##Size() {return (s);} -#define CRYPTOPP_BLOCKS_END(i) size_t SST() {return SS##i();} void AllocateBlocks() {m_aggregate.New(SST());} AlignedSecByteBlock m_aggregate; - -NAMESPACE_END - -#endif diff --git a/src/cryptopp/obj/.gitignore b/src/cryptopp/obj/.gitignore deleted file mode 100644 index d6b7ef32c8..0000000000 --- a/src/cryptopp/obj/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -* -!.gitignore diff --git a/src/cryptopp/pch.h b/src/cryptopp/pch.h deleted file mode 100644 index 418c39076d..0000000000 --- a/src/cryptopp/pch.h +++ /dev/null @@ -1,21 +0,0 @@ -#ifndef CRYPTOPP_PCH_H -#define CRYPTOPP_PCH_H - -#ifdef CRYPTOPP_GENERATE_X64_MASM - - #include "cpu.h" - -#else - - #include "config.h" - - #ifdef USE_PRECOMPILED_HEADERS - #include "simple.h" - #include "secblock.h" - #include "misc.h" - #include "smartptr.h" - #endif - -#endif - -#endif diff --git a/src/cryptopp/secblock.h b/src/cryptopp/secblock.h deleted file mode 100644 index 2025757dbb..0000000000 --- a/src/cryptopp/secblock.h +++ /dev/null @@ -1,501 +0,0 @@ -// secblock.h - written and placed in the public domain by Wei Dai - -#ifndef CRYPTOPP_SECBLOCK_H -#define CRYPTOPP_SECBLOCK_H - -#include "config.h" -#include "misc.h" -#include <assert.h> - -#if defined(CRYPTOPP_MEMALIGN_AVAILABLE) || defined(CRYPTOPP_MM_MALLOC_AVAILABLE) || defined(QNX) - #include <malloc.h> -#else - #include <stdlib.h> -#endif - -NAMESPACE_BEGIN(CryptoPP) - -// ************** secure memory allocation *************** - -template<class T> -class AllocatorBase -{ -public: - typedef T value_type; - typedef size_t size_type; -#ifdef CRYPTOPP_MSVCRT6 - typedef ptrdiff_t difference_type; -#else - typedef std::ptrdiff_t difference_type; -#endif - typedef T * pointer; - typedef const T * const_pointer; - typedef T & reference; - typedef const T & const_reference; - - pointer address(reference r) const {return (&r);} - const_pointer address(const_reference r) const {return (&r); } - void construct(pointer p, const T& val) {new (p) T(val);} - void destroy(pointer p) {p->~T();} - size_type max_size() const {return ~size_type(0)/sizeof(T);} // switch to std::numeric_limits<T>::max later - -protected: - static void CheckSize(size_t n) - { - if (n > ~size_t(0) / sizeof(T)) - throw InvalidArgument("AllocatorBase: requested size would cause integer overflow"); - } -}; - -#define CRYPTOPP_INHERIT_ALLOCATOR_TYPES \ -typedef typename AllocatorBase<T>::value_type value_type;\ -typedef typename AllocatorBase<T>::size_type size_type;\ -typedef typename AllocatorBase<T>::difference_type difference_type;\ -typedef typename AllocatorBase<T>::pointer pointer;\ -typedef typename AllocatorBase<T>::const_pointer const_pointer;\ -typedef typename AllocatorBase<T>::reference reference;\ -typedef typename AllocatorBase<T>::const_reference const_reference; - -#if defined(_MSC_VER) && (_MSC_VER < 1300) -// this pragma causes an internal compiler error if placed immediately before std::swap(a, b) -#pragma warning(push) -#pragma warning(disable: 4700) // VC60 workaround: don't know how to get rid of this warning -#endif - -template <class T, class A> -typename A::pointer StandardReallocate(A& a, T *p, typename A::size_type oldSize, typename A::size_type newSize, bool preserve) -{ - if (oldSize == newSize) - return p; - - if (preserve) - { - typename A::pointer newPointer = a.allocate(newSize, NULL); - memcpy_s(newPointer, sizeof(T)*newSize, p, sizeof(T)*STDMIN(oldSize, newSize)); - a.deallocate(p, oldSize); - return newPointer; - } - else - { - a.deallocate(p, oldSize); - return a.allocate(newSize, NULL); - } -} - -#if defined(_MSC_VER) && (_MSC_VER < 1300) -#pragma warning(pop) -#endif - -template <class T, bool T_Align16 = false> -class AllocatorWithCleanup : public AllocatorBase<T> -{ -public: - CRYPTOPP_INHERIT_ALLOCATOR_TYPES - - pointer allocate(size_type n, const void * = NULL) - { - CheckSize(n); - if (n == 0) - return NULL; - - if (CRYPTOPP_BOOL_ALIGN16_ENABLED && T_Align16 && n*sizeof(T) >= 16) - { - byte *p; - #ifdef CRYPTOPP_MM_MALLOC_AVAILABLE - while (!(p = (byte *)_mm_malloc(sizeof(T)*n, 16))) - #elif defined(CRYPTOPP_MEMALIGN_AVAILABLE) - while (!(p = (byte *)memalign(16, sizeof(T)*n))) - #elif defined(CRYPTOPP_MALLOC_ALIGNMENT_IS_16) - while (!(p = (byte *)malloc(sizeof(T)*n))) - #else - while (!(p = (byte *)malloc(sizeof(T)*n + 16))) - #endif - CallNewHandler(); - - #ifdef CRYPTOPP_NO_ALIGNED_ALLOC - size_t adjustment = 16-((size_t)p%16); - p += adjustment; - p[-1] = (byte)adjustment; - #endif - - assert(IsAlignedOn(p, 16)); - return (pointer)p; - } - - pointer p; - while (!(p = (pointer)malloc(sizeof(T)*n))) - CallNewHandler(); - return p; - } - - void deallocate(void *p, size_type n) - { - memset_z(p, 0, n*sizeof(T)); - - if (CRYPTOPP_BOOL_ALIGN16_ENABLED && T_Align16 && n*sizeof(T) >= 16) - { - #ifdef CRYPTOPP_MM_MALLOC_AVAILABLE - _mm_free(p); - #elif defined(CRYPTOPP_NO_ALIGNED_ALLOC) - p = (byte *)p - ((byte *)p)[-1]; - free(p); - #else - free(p); - #endif - return; - } - - free(p); - } - - pointer reallocate(T *p, size_type oldSize, size_type newSize, bool preserve) - { - return StandardReallocate(*this, p, oldSize, newSize, preserve); - } - - // VS.NET STL enforces the policy of "All STL-compliant allocators have to provide a - // template class member called rebind". - template <class U> struct rebind { typedef AllocatorWithCleanup<U, T_Align16> other; }; -#if _MSC_VER >= 1500 - AllocatorWithCleanup() {} - template <class U, bool A> AllocatorWithCleanup(const AllocatorWithCleanup<U, A> &) {} -#endif -}; - -CRYPTOPP_DLL_TEMPLATE_CLASS AllocatorWithCleanup<byte>; -CRYPTOPP_DLL_TEMPLATE_CLASS AllocatorWithCleanup<word16>; -CRYPTOPP_DLL_TEMPLATE_CLASS AllocatorWithCleanup<word32>; -CRYPTOPP_DLL_TEMPLATE_CLASS AllocatorWithCleanup<word64>; -#if CRYPTOPP_BOOL_X86 -CRYPTOPP_DLL_TEMPLATE_CLASS AllocatorWithCleanup<word, true>; // for Integer -#endif - -template <class T> -class NullAllocator : public AllocatorBase<T> -{ -public: - CRYPTOPP_INHERIT_ALLOCATOR_TYPES - - pointer allocate(size_type n, const void * = NULL) - { - assert(false); - return NULL; - } - - void deallocate(void *p, size_type n) - { - //// Bitcoin: don't know why this trips, probably a false alarm, depends on the compiler used. - //assert(false); - } - - size_type max_size() const {return 0;} -}; - -// This allocator can't be used with standard collections because -// they require that all objects of the same allocator type are equivalent. -// So this is for use with SecBlock only. -template <class T, size_t S, class A = NullAllocator<T>, bool T_Align16 = false> -class FixedSizeAllocatorWithCleanup : public AllocatorBase<T> -{ -public: - CRYPTOPP_INHERIT_ALLOCATOR_TYPES - - FixedSizeAllocatorWithCleanup() : m_allocated(false) {} - - pointer allocate(size_type n) - { - assert(IsAlignedOn(m_array, 8)); - - if (n <= S && !m_allocated) - { - m_allocated = true; - return GetAlignedArray(); - } - else - return m_fallbackAllocator.allocate(n); - } - - pointer allocate(size_type n, const void *hint) - { - if (n <= S && !m_allocated) - { - m_allocated = true; - return GetAlignedArray(); - } - else - return m_fallbackAllocator.allocate(n, hint); - } - - void deallocate(void *p, size_type n) - { - if (p == GetAlignedArray()) - { - assert(n <= S); - assert(m_allocated); - m_allocated = false; - memset(p, 0, n*sizeof(T)); - } - else - m_fallbackAllocator.deallocate(p, n); - } - - pointer reallocate(pointer p, size_type oldSize, size_type newSize, bool preserve) - { - if (p == GetAlignedArray() && newSize <= S) - { - assert(oldSize <= S); - if (oldSize > newSize) - memset(p + newSize, 0, (oldSize-newSize)*sizeof(T)); - return p; - } - - pointer newPointer = allocate(newSize, NULL); - if (preserve) - memcpy(newPointer, p, sizeof(T)*STDMIN(oldSize, newSize)); - deallocate(p, oldSize); - return newPointer; - } - - size_type max_size() const {return STDMAX(m_fallbackAllocator.max_size(), S);} - -private: -#ifdef __BORLANDC__ - T* GetAlignedArray() {return m_array;} - T m_array[S]; -#else - T* GetAlignedArray() {return (CRYPTOPP_BOOL_ALIGN16_ENABLED && T_Align16) ? (T*)(((byte *)m_array) + (0-(size_t)m_array)%16) : m_array;} - CRYPTOPP_ALIGN_DATA(8) T m_array[(CRYPTOPP_BOOL_ALIGN16_ENABLED && T_Align16) ? S+8/sizeof(T) : S]; -#endif - A m_fallbackAllocator; - bool m_allocated; -}; - -//! a block of memory allocated using A -template <class T, class A = AllocatorWithCleanup<T> > -class SecBlock -{ -public: - typedef typename A::value_type value_type; - typedef typename A::pointer iterator; - typedef typename A::const_pointer const_iterator; - typedef typename A::size_type size_type; - - explicit SecBlock(size_type size=0) - : m_size(size) {m_ptr = m_alloc.allocate(size, NULL);} - SecBlock(const SecBlock<T, A> &t) - : m_size(t.m_size) {m_ptr = m_alloc.allocate(m_size, NULL); memcpy_s(m_ptr, m_size*sizeof(T), t.m_ptr, m_size*sizeof(T));} - SecBlock(const T *t, size_type len) - : m_size(len) - { - m_ptr = m_alloc.allocate(len, NULL); - if (t == NULL) - memset_z(m_ptr, 0, len*sizeof(T)); - else - memcpy(m_ptr, t, len*sizeof(T)); - } - - ~SecBlock() - {m_alloc.deallocate(m_ptr, m_size);} - -#ifdef __BORLANDC__ - operator T *() const - {return (T*)m_ptr;} -#else - operator const void *() const - {return m_ptr;} - operator void *() - {return m_ptr;} - - operator const T *() const - {return m_ptr;} - operator T *() - {return m_ptr;} -#endif - -// T *operator +(size_type offset) -// {return m_ptr+offset;} - -// const T *operator +(size_type offset) const -// {return m_ptr+offset;} - -// T& operator[](size_type index) -// {assert(index >= 0 && index < m_size); return m_ptr[index];} - -// const T& operator[](size_type index) const -// {assert(index >= 0 && index < m_size); return m_ptr[index];} - - iterator begin() - {return m_ptr;} - const_iterator begin() const - {return m_ptr;} - iterator end() - {return m_ptr+m_size;} - const_iterator end() const - {return m_ptr+m_size;} - - typename A::pointer data() {return m_ptr;} - typename A::const_pointer data() const {return m_ptr;} - - size_type size() const {return m_size;} - bool empty() const {return m_size == 0;} - - byte * BytePtr() {return (byte *)m_ptr;} - const byte * BytePtr() const {return (const byte *)m_ptr;} - size_type SizeInBytes() const {return m_size*sizeof(T);} - - //! set contents and size - void Assign(const T *t, size_type len) - { - New(len); - memcpy_s(m_ptr, m_size*sizeof(T), t, len*sizeof(T)); - } - - //! copy contents and size from another SecBlock - void Assign(const SecBlock<T, A> &t) - { - New(t.m_size); - memcpy_s(m_ptr, m_size*sizeof(T), t.m_ptr, m_size*sizeof(T)); - } - - SecBlock<T, A>& operator=(const SecBlock<T, A> &t) - { - Assign(t); - return *this; - } - - // append to this object - SecBlock<T, A>& operator+=(const SecBlock<T, A> &t) - { - size_type oldSize = m_size; - Grow(m_size+t.m_size); - memcpy_s(m_ptr+oldSize, m_size*sizeof(T), t.m_ptr, t.m_size*sizeof(T)); - return *this; - } - - // append operator - SecBlock<T, A> operator+(const SecBlock<T, A> &t) - { - SecBlock<T, A> result(m_size+t.m_size); - memcpy_s(result.m_ptr, result.m_size*sizeof(T), m_ptr, m_size*sizeof(T)); - memcpy_s(result.m_ptr+m_size, t.m_size*sizeof(T), t.m_ptr, t.m_size*sizeof(T)); - return result; - } - - bool operator==(const SecBlock<T, A> &t) const - { - return m_size == t.m_size && VerifyBufsEqual(m_ptr, t.m_ptr, m_size*sizeof(T)); - } - - bool operator!=(const SecBlock<T, A> &t) const - { - return !operator==(t); - } - - //! change size, without preserving contents - void New(size_type newSize) - { - m_ptr = m_alloc.reallocate(m_ptr, m_size, newSize, false); - m_size = newSize; - } - - //! change size and set contents to 0 - void CleanNew(size_type newSize) - { - New(newSize); - memset_z(m_ptr, 0, m_size*sizeof(T)); - } - - //! change size only if newSize > current size. contents are preserved - void Grow(size_type newSize) - { - if (newSize > m_size) - { - m_ptr = m_alloc.reallocate(m_ptr, m_size, newSize, true); - m_size = newSize; - } - } - - //! change size only if newSize > current size. contents are preserved and additional area is set to 0 - void CleanGrow(size_type newSize) - { - if (newSize > m_size) - { - m_ptr = m_alloc.reallocate(m_ptr, m_size, newSize, true); - memset(m_ptr+m_size, 0, (newSize-m_size)*sizeof(T)); - m_size = newSize; - } - } - - //! change size and preserve contents - void resize(size_type newSize) - { - m_ptr = m_alloc.reallocate(m_ptr, m_size, newSize, true); - m_size = newSize; - } - - //! swap contents and size with another SecBlock - void swap(SecBlock<T, A> &b) - { - std::swap(m_alloc, b.m_alloc); - std::swap(m_size, b.m_size); - std::swap(m_ptr, b.m_ptr); - } - -//private: - A m_alloc; - size_type m_size; - T *m_ptr; -}; - -typedef SecBlock<byte> SecByteBlock; -typedef SecBlock<byte, AllocatorWithCleanup<byte, true> > AlignedSecByteBlock; -typedef SecBlock<word> SecWordBlock; - -//! a SecBlock with fixed size, allocated statically -template <class T, unsigned int S, class A = FixedSizeAllocatorWithCleanup<T, S> > -class FixedSizeSecBlock : public SecBlock<T, A> -{ -public: - explicit FixedSizeSecBlock() : SecBlock<T, A>(S) {} -}; - -template <class T, unsigned int S, bool T_Align16 = true> -class FixedSizeAlignedSecBlock : public FixedSizeSecBlock<T, S, FixedSizeAllocatorWithCleanup<T, S, NullAllocator<T>, T_Align16> > -{ -}; - -//! a SecBlock that preallocates size S statically, and uses the heap when this size is exceeded -template <class T, unsigned int S, class A = FixedSizeAllocatorWithCleanup<T, S, AllocatorWithCleanup<T> > > -class SecBlockWithHint : public SecBlock<T, A> -{ -public: - explicit SecBlockWithHint(size_t size) : SecBlock<T, A>(size) {} -}; - -template<class T, bool A, class U, bool B> -inline bool operator==(const CryptoPP::AllocatorWithCleanup<T, A>&, const CryptoPP::AllocatorWithCleanup<U, B>&) {return (true);} -template<class T, bool A, class U, bool B> -inline bool operator!=(const CryptoPP::AllocatorWithCleanup<T, A>&, const CryptoPP::AllocatorWithCleanup<U, B>&) {return (false);} - -NAMESPACE_END - -NAMESPACE_BEGIN(std) -template <class T, class A> -inline void swap(CryptoPP::SecBlock<T, A> &a, CryptoPP::SecBlock<T, A> &b) -{ - a.swap(b); -} - -#if defined(_STLP_DONT_SUPPORT_REBIND_MEMBER_TEMPLATE) || (defined(_STLPORT_VERSION) && !defined(_STLP_MEMBER_TEMPLATE_CLASSES)) -// working for STLport 5.1.3 and MSVC 6 SP5 -template <class _Tp1, class _Tp2> -inline CryptoPP::AllocatorWithCleanup<_Tp2>& -__stl_alloc_rebind(CryptoPP::AllocatorWithCleanup<_Tp1>& __a, const _Tp2*) -{ - return (CryptoPP::AllocatorWithCleanup<_Tp2>&)(__a); -} -#endif - -NAMESPACE_END - -#endif diff --git a/src/cryptopp/sha.cpp b/src/cryptopp/sha.cpp deleted file mode 100644 index fd0b0a2596..0000000000 --- a/src/cryptopp/sha.cpp +++ /dev/null @@ -1,899 +0,0 @@ -// sha.cpp - modified by Wei Dai from Steve Reid's public domain sha1.c - -// Steve Reid implemented SHA-1. Wei Dai implemented SHA-2. -// Both are in the public domain. - -// use "cl /EP /P /DCRYPTOPP_GENERATE_X64_MASM sha.cpp" to generate MASM code - -#include "pch.h" - -#ifndef CRYPTOPP_IMPORTS -#ifndef CRYPTOPP_GENERATE_X64_MASM - -#include "sha.h" -#include "misc.h" -#include "cpu.h" - -NAMESPACE_BEGIN(CryptoPP) - -// start of Steve Reid's code - -#define blk0(i) (W[i] = data[i]) -#define blk1(i) (W[i&15] = rotlFixed(W[(i+13)&15]^W[(i+8)&15]^W[(i+2)&15]^W[i&15],1)) - -void SHA1::InitState(HashWordType *state) -{ - state[0] = 0x67452301L; - state[1] = 0xEFCDAB89L; - state[2] = 0x98BADCFEL; - state[3] = 0x10325476L; - state[4] = 0xC3D2E1F0L; -} - -#define f1(x,y,z) (z^(x&(y^z))) -#define f2(x,y,z) (x^y^z) -#define f3(x,y,z) ((x&y)|(z&(x|y))) -#define f4(x,y,z) (x^y^z) - -/* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */ -#define R0(v,w,x,y,z,i) z+=f1(w,x,y)+blk0(i)+0x5A827999+rotlFixed(v,5);w=rotlFixed(w,30); -#define R1(v,w,x,y,z,i) z+=f1(w,x,y)+blk1(i)+0x5A827999+rotlFixed(v,5);w=rotlFixed(w,30); -#define R2(v,w,x,y,z,i) z+=f2(w,x,y)+blk1(i)+0x6ED9EBA1+rotlFixed(v,5);w=rotlFixed(w,30); -#define R3(v,w,x,y,z,i) z+=f3(w,x,y)+blk1(i)+0x8F1BBCDC+rotlFixed(v,5);w=rotlFixed(w,30); -#define R4(v,w,x,y,z,i) z+=f4(w,x,y)+blk1(i)+0xCA62C1D6+rotlFixed(v,5);w=rotlFixed(w,30); - -void SHA1::Transform(word32 *state, const word32 *data) -{ - word32 W[16]; - /* Copy context->state[] to working vars */ - word32 a = state[0]; - word32 b = state[1]; - word32 c = state[2]; - word32 d = state[3]; - word32 e = state[4]; - /* 4 rounds of 20 operations each. Loop unrolled. */ - R0(a,b,c,d,e, 0); R0(e,a,b,c,d, 1); R0(d,e,a,b,c, 2); R0(c,d,e,a,b, 3); - R0(b,c,d,e,a, 4); R0(a,b,c,d,e, 5); R0(e,a,b,c,d, 6); R0(d,e,a,b,c, 7); - R0(c,d,e,a,b, 8); R0(b,c,d,e,a, 9); R0(a,b,c,d,e,10); R0(e,a,b,c,d,11); - R0(d,e,a,b,c,12); R0(c,d,e,a,b,13); R0(b,c,d,e,a,14); R0(a,b,c,d,e,15); - R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19); - R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23); - R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27); - R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31); - R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35); - R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39); - R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43); - R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47); - R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51); - R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55); - R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59); - R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63); - R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67); - R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71); - R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75); - R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79); - /* Add the working vars back into context.state[] */ - state[0] += a; - state[1] += b; - state[2] += c; - state[3] += d; - state[4] += e; -} - -// end of Steve Reid's code - -// ************************************************************* - -void SHA224::InitState(HashWordType *state) -{ - static const word32 s[8] = {0xc1059ed8, 0x367cd507, 0x3070dd17, 0xf70e5939, 0xffc00b31, 0x68581511, 0x64f98fa7, 0xbefa4fa4}; - memcpy(state, s, sizeof(s)); -} - -void SHA256::InitState(HashWordType *state) -{ - static const word32 s[8] = {0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19}; - memcpy(state, s, sizeof(s)); -} - -#if CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE -CRYPTOPP_ALIGN_DATA(16) extern const word32 SHA256_K[64] CRYPTOPP_SECTION_ALIGN16 = { -#else -extern const word32 SHA256_K[64] = { -#endif - 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, - 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, - 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, - 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, - 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, - 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, - 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, - 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, - 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, - 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, - 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, - 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, - 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, - 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, - 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, - 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 -}; - -#endif // #ifndef CRYPTOPP_GENERATE_X64_MASM - -#if defined(CRYPTOPP_X86_ASM_AVAILABLE) || defined(CRYPTOPP_GENERATE_X64_MASM) - -#pragma warning(disable: 4731) // frame pointer register 'ebp' modified by inline assembly code - -static void CRYPTOPP_FASTCALL X86_SHA256_HashBlocks(word32 *state, const word32 *data, size_t len -#if defined(_MSC_VER) && (_MSC_VER == 1200) - , ... // VC60 workaround: prevent VC 6 from inlining this function -#endif - ) -{ -#if defined(_MSC_VER) && (_MSC_VER == 1200) - AS2(mov ecx, [state]) - AS2(mov edx, [data]) -#endif - - #define LOCALS_SIZE 8*4 + 16*4 + 4*WORD_SZ - #define H(i) [BASE+ASM_MOD(1024+7-(i),8)*4] - #define G(i) H(i+1) - #define F(i) H(i+2) - #define E(i) H(i+3) - #define D(i) H(i+4) - #define C(i) H(i+5) - #define B(i) H(i+6) - #define A(i) H(i+7) - #define Wt(i) BASE+8*4+ASM_MOD(1024+15-(i),16)*4 - #define Wt_2(i) Wt((i)-2) - #define Wt_15(i) Wt((i)-15) - #define Wt_7(i) Wt((i)-7) - #define K_END [BASE+8*4+16*4+0*WORD_SZ] - #define STATE_SAVE [BASE+8*4+16*4+1*WORD_SZ] - #define DATA_SAVE [BASE+8*4+16*4+2*WORD_SZ] - #define DATA_END [BASE+8*4+16*4+3*WORD_SZ] - #define Kt(i) WORD_REG(si)+(i)*4 -#if CRYPTOPP_BOOL_X86 - #define BASE esp+4 -#elif defined(__GNUC__) - #define BASE r8 -#else - #define BASE rsp -#endif - -#define RA0(i, edx, edi) \ - AS2( add edx, [Kt(i)] )\ - AS2( add edx, [Wt(i)] )\ - AS2( add edx, H(i) )\ - -#define RA1(i, edx, edi) - -#define RB0(i, edx, edi) - -#define RB1(i, edx, edi) \ - AS2( mov AS_REG_7d, [Wt_2(i)] )\ - AS2( mov edi, [Wt_15(i)])\ - AS2( mov ebx, AS_REG_7d )\ - AS2( shr AS_REG_7d, 10 )\ - AS2( ror ebx, 17 )\ - AS2( xor AS_REG_7d, ebx )\ - AS2( ror ebx, 2 )\ - AS2( xor ebx, AS_REG_7d )/* s1(W_t-2) */\ - AS2( add ebx, [Wt_7(i)])\ - AS2( mov AS_REG_7d, edi )\ - AS2( shr AS_REG_7d, 3 )\ - AS2( ror edi, 7 )\ - AS2( add ebx, [Wt(i)])/* s1(W_t-2) + W_t-7 + W_t-16 */\ - AS2( xor AS_REG_7d, edi )\ - AS2( add edx, [Kt(i)])\ - AS2( ror edi, 11 )\ - AS2( add edx, H(i) )\ - AS2( xor AS_REG_7d, edi )/* s0(W_t-15) */\ - AS2( add AS_REG_7d, ebx )/* W_t = s1(W_t-2) + W_t-7 + s0(W_t-15) W_t-16*/\ - AS2( mov [Wt(i)], AS_REG_7d)\ - AS2( add edx, AS_REG_7d )\ - -#define ROUND(i, r, eax, ecx, edi, edx)\ - /* in: edi = E */\ - /* unused: eax, ecx, temp: ebx, AS_REG_7d, out: edx = T1 */\ - AS2( mov edx, F(i) )\ - AS2( xor edx, G(i) )\ - AS2( and edx, edi )\ - AS2( xor edx, G(i) )/* Ch(E,F,G) = (G^(E&(F^G))) */\ - AS2( mov AS_REG_7d, edi )\ - AS2( ror edi, 6 )\ - AS2( ror AS_REG_7d, 25 )\ - RA##r(i, edx, edi )/* H + Wt + Kt + Ch(E,F,G) */\ - AS2( xor AS_REG_7d, edi )\ - AS2( ror edi, 5 )\ - AS2( xor AS_REG_7d, edi )/* S1(E) */\ - AS2( add edx, AS_REG_7d )/* T1 = S1(E) + Ch(E,F,G) + H + Wt + Kt */\ - RB##r(i, edx, edi )/* H + Wt + Kt + Ch(E,F,G) */\ - /* in: ecx = A, eax = B^C, edx = T1 */\ - /* unused: edx, temp: ebx, AS_REG_7d, out: eax = A, ecx = B^C, edx = E */\ - AS2( mov ebx, ecx )\ - AS2( xor ecx, B(i) )/* A^B */\ - AS2( and eax, ecx )\ - AS2( xor eax, B(i) )/* Maj(A,B,C) = B^((A^B)&(B^C) */\ - AS2( mov AS_REG_7d, ebx )\ - AS2( ror ebx, 2 )\ - AS2( add eax, edx )/* T1 + Maj(A,B,C) */\ - AS2( add edx, D(i) )\ - AS2( mov D(i), edx )\ - AS2( ror AS_REG_7d, 22 )\ - AS2( xor AS_REG_7d, ebx )\ - AS2( ror ebx, 11 )\ - AS2( xor AS_REG_7d, ebx )\ - AS2( add eax, AS_REG_7d )/* T1 + S0(A) + Maj(A,B,C) */\ - AS2( mov H(i), eax )\ - -#define SWAP_COPY(i) \ - AS2( mov WORD_REG(bx), [WORD_REG(dx)+i*WORD_SZ])\ - AS1( bswap WORD_REG(bx))\ - AS2( mov [Wt(i*(1+CRYPTOPP_BOOL_X64)+CRYPTOPP_BOOL_X64)], WORD_REG(bx)) - -#if defined(__GNUC__) - #if CRYPTOPP_BOOL_X64 - FixedSizeAlignedSecBlock<byte, LOCALS_SIZE> workspace; - #endif - __asm__ __volatile__ - ( - #if CRYPTOPP_BOOL_X64 - "lea %4, %%r8;" - #endif - ".intel_syntax noprefix;" -#elif defined(CRYPTOPP_GENERATE_X64_MASM) - ALIGN 8 - X86_SHA256_HashBlocks PROC FRAME - rex_push_reg rsi - push_reg rdi - push_reg rbx - push_reg rbp - alloc_stack(LOCALS_SIZE+8) - .endprolog - mov rdi, r8 - lea rsi, [?SHA256_K@CryptoPP@@3QBIB + 48*4] -#endif - -#if CRYPTOPP_BOOL_X86 - #ifndef __GNUC__ - AS2( mov edi, [len]) - AS2( lea WORD_REG(si), [SHA256_K+48*4]) - #endif - #if !defined(_MSC_VER) || (_MSC_VER < 1400) - AS_PUSH_IF86(bx) - #endif - - AS_PUSH_IF86(bp) - AS2( mov ebx, esp) - AS2( and esp, -16) - AS2( sub WORD_REG(sp), LOCALS_SIZE) - AS_PUSH_IF86(bx) -#endif - AS2( mov STATE_SAVE, WORD_REG(cx)) - AS2( mov DATA_SAVE, WORD_REG(dx)) - AS2( add WORD_REG(di), WORD_REG(dx)) - AS2( mov DATA_END, WORD_REG(di)) - AS2( mov K_END, WORD_REG(si)) - -#if CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE -#if CRYPTOPP_BOOL_X86 - AS2( test edi, 1) - ASJ( jnz, 2, f) -#endif - AS2( movdqa xmm0, XMMWORD_PTR [WORD_REG(cx)+0*16]) - AS2( movdqa xmm1, XMMWORD_PTR [WORD_REG(cx)+1*16]) -#endif - -#if CRYPTOPP_BOOL_X86 -#if CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE - ASJ( jmp, 0, f) -#endif - ASL(2) // non-SSE2 - AS2( mov esi, ecx) - AS2( lea edi, A(0)) - AS2( mov ecx, 8) - AS1( rep movsd) - AS2( mov esi, K_END) - ASJ( jmp, 3, f) -#endif - -#if CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE - ASL(0) - AS2( movdqa E(0), xmm1) - AS2( movdqa A(0), xmm0) -#endif -#if CRYPTOPP_BOOL_X86 - ASL(3) -#endif - AS2( sub WORD_REG(si), 48*4) - SWAP_COPY(0) SWAP_COPY(1) SWAP_COPY(2) SWAP_COPY(3) - SWAP_COPY(4) SWAP_COPY(5) SWAP_COPY(6) SWAP_COPY(7) -#if CRYPTOPP_BOOL_X86 - SWAP_COPY(8) SWAP_COPY(9) SWAP_COPY(10) SWAP_COPY(11) - SWAP_COPY(12) SWAP_COPY(13) SWAP_COPY(14) SWAP_COPY(15) -#endif - AS2( mov edi, E(0)) // E - AS2( mov eax, B(0)) // B - AS2( xor eax, C(0)) // B^C - AS2( mov ecx, A(0)) // A - - ROUND(0, 0, eax, ecx, edi, edx) - ROUND(1, 0, ecx, eax, edx, edi) - ROUND(2, 0, eax, ecx, edi, edx) - ROUND(3, 0, ecx, eax, edx, edi) - ROUND(4, 0, eax, ecx, edi, edx) - ROUND(5, 0, ecx, eax, edx, edi) - ROUND(6, 0, eax, ecx, edi, edx) - ROUND(7, 0, ecx, eax, edx, edi) - ROUND(8, 0, eax, ecx, edi, edx) - ROUND(9, 0, ecx, eax, edx, edi) - ROUND(10, 0, eax, ecx, edi, edx) - ROUND(11, 0, ecx, eax, edx, edi) - ROUND(12, 0, eax, ecx, edi, edx) - ROUND(13, 0, ecx, eax, edx, edi) - ROUND(14, 0, eax, ecx, edi, edx) - ROUND(15, 0, ecx, eax, edx, edi) - - ASL(1) - AS2(add WORD_REG(si), 4*16) - ROUND(0, 1, eax, ecx, edi, edx) - ROUND(1, 1, ecx, eax, edx, edi) - ROUND(2, 1, eax, ecx, edi, edx) - ROUND(3, 1, ecx, eax, edx, edi) - ROUND(4, 1, eax, ecx, edi, edx) - ROUND(5, 1, ecx, eax, edx, edi) - ROUND(6, 1, eax, ecx, edi, edx) - ROUND(7, 1, ecx, eax, edx, edi) - ROUND(8, 1, eax, ecx, edi, edx) - ROUND(9, 1, ecx, eax, edx, edi) - ROUND(10, 1, eax, ecx, edi, edx) - ROUND(11, 1, ecx, eax, edx, edi) - ROUND(12, 1, eax, ecx, edi, edx) - ROUND(13, 1, ecx, eax, edx, edi) - ROUND(14, 1, eax, ecx, edi, edx) - ROUND(15, 1, ecx, eax, edx, edi) - AS2( cmp WORD_REG(si), K_END) - ASJ( jne, 1, b) - - AS2( mov WORD_REG(dx), DATA_SAVE) - AS2( add WORD_REG(dx), 64) - AS2( mov AS_REG_7, STATE_SAVE) - AS2( mov DATA_SAVE, WORD_REG(dx)) - -#if CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE -#if CRYPTOPP_BOOL_X86 - AS2( test DWORD PTR DATA_END, 1) - ASJ( jnz, 4, f) -#endif - AS2( movdqa xmm1, XMMWORD_PTR [AS_REG_7+1*16]) - AS2( movdqa xmm0, XMMWORD_PTR [AS_REG_7+0*16]) - AS2( paddd xmm1, E(0)) - AS2( paddd xmm0, A(0)) - AS2( movdqa [AS_REG_7+1*16], xmm1) - AS2( movdqa [AS_REG_7+0*16], xmm0) - AS2( cmp WORD_REG(dx), DATA_END) - ASJ( jl, 0, b) -#endif - -#if CRYPTOPP_BOOL_X86 -#if CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE - ASJ( jmp, 5, f) - ASL(4) // non-SSE2 -#endif - AS2( add [AS_REG_7+0*4], ecx) // A - AS2( add [AS_REG_7+4*4], edi) // E - AS2( mov eax, B(0)) - AS2( mov ebx, C(0)) - AS2( mov ecx, D(0)) - AS2( add [AS_REG_7+1*4], eax) - AS2( add [AS_REG_7+2*4], ebx) - AS2( add [AS_REG_7+3*4], ecx) - AS2( mov eax, F(0)) - AS2( mov ebx, G(0)) - AS2( mov ecx, H(0)) - AS2( add [AS_REG_7+5*4], eax) - AS2( add [AS_REG_7+6*4], ebx) - AS2( add [AS_REG_7+7*4], ecx) - AS2( mov ecx, AS_REG_7d) - AS2( cmp WORD_REG(dx), DATA_END) - ASJ( jl, 2, b) -#if CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE - ASL(5) -#endif -#endif - - AS_POP_IF86(sp) - AS_POP_IF86(bp) - #if !defined(_MSC_VER) || (_MSC_VER < 1400) - AS_POP_IF86(bx) - #endif - -#ifdef CRYPTOPP_GENERATE_X64_MASM - add rsp, LOCALS_SIZE+8 - pop rbp - pop rbx - pop rdi - pop rsi - ret - X86_SHA256_HashBlocks ENDP -#endif - -#ifdef __GNUC__ - ".att_syntax prefix;" - : - : "c" (state), "d" (data), "S" (SHA256_K+48), "D" (len) - #if CRYPTOPP_BOOL_X64 - , "m" (workspace[0]) - #endif - : "memory", "cc", "%eax" - #if CRYPTOPP_BOOL_X64 - , "%rbx", "%r8" - #endif - ); -#endif -} - -#endif // #if defined(CRYPTOPP_X86_ASM_AVAILABLE) || defined(CRYPTOPP_GENERATE_X64_MASM) - -#ifndef CRYPTOPP_GENERATE_X64_MASM - -#ifdef CRYPTOPP_X64_MASM_AVAILABLE -extern "C" { -void CRYPTOPP_FASTCALL X86_SHA256_HashBlocks(word32 *state, const word32 *data, size_t len); -} -#endif - -#if defined(CRYPTOPP_X86_ASM_AVAILABLE) || defined(CRYPTOPP_X64_MASM_AVAILABLE) - -size_t SHA256::HashMultipleBlocks(const word32 *input, size_t length) -{ - X86_SHA256_HashBlocks(m_state, input, (length&(size_t(0)-BLOCKSIZE)) - !HasSSE2()); - return length % BLOCKSIZE; -} - -size_t SHA224::HashMultipleBlocks(const word32 *input, size_t length) -{ - X86_SHA256_HashBlocks(m_state, input, (length&(size_t(0)-BLOCKSIZE)) - !HasSSE2()); - return length % BLOCKSIZE; -} - -#endif - -#define blk2(i) (W[i&15]+=s1(W[(i-2)&15])+W[(i-7)&15]+s0(W[(i-15)&15])) - -#define Ch(x,y,z) (z^(x&(y^z))) -#define Maj(x,y,z) (y^((x^y)&(y^z))) - -#define a(i) T[(0-i)&7] -#define b(i) T[(1-i)&7] -#define c(i) T[(2-i)&7] -#define d(i) T[(3-i)&7] -#define e(i) T[(4-i)&7] -#define f(i) T[(5-i)&7] -#define g(i) T[(6-i)&7] -#define h(i) T[(7-i)&7] - -#define R(i) h(i)+=S1(e(i))+Ch(e(i),f(i),g(i))+SHA256_K[i+j]+(j?blk2(i):blk0(i));\ - d(i)+=h(i);h(i)+=S0(a(i))+Maj(a(i),b(i),c(i)) - -// for SHA256 -#define S0(x) (rotrFixed(x,2)^rotrFixed(x,13)^rotrFixed(x,22)) -#define S1(x) (rotrFixed(x,6)^rotrFixed(x,11)^rotrFixed(x,25)) -#define s0(x) (rotrFixed(x,7)^rotrFixed(x,18)^(x>>3)) -#define s1(x) (rotrFixed(x,17)^rotrFixed(x,19)^(x>>10)) - -void SHA256::Transform(word32 *state, const word32 *data) -{ - word32 W[16]; -#if defined(CRYPTOPP_X86_ASM_AVAILABLE) || defined(CRYPTOPP_X64_MASM_AVAILABLE) - // this byte reverse is a waste of time, but this function is only called by MDC - ByteReverse(W, data, BLOCKSIZE); - X86_SHA256_HashBlocks(state, W, BLOCKSIZE - !HasSSE2()); -#else - word32 T[8]; - /* Copy context->state[] to working vars */ - memcpy(T, state, sizeof(T)); - /* 64 operations, partially loop unrolled */ - for (unsigned int j=0; j<64; j+=16) - { - R( 0); R( 1); R( 2); R( 3); - R( 4); R( 5); R( 6); R( 7); - R( 8); R( 9); R(10); R(11); - R(12); R(13); R(14); R(15); - } - /* Add the working vars back into context.state[] */ - state[0] += a(0); - state[1] += b(0); - state[2] += c(0); - state[3] += d(0); - state[4] += e(0); - state[5] += f(0); - state[6] += g(0); - state[7] += h(0); -#endif -} - -/* -// smaller but slower -void SHA256::Transform(word32 *state, const word32 *data) -{ - word32 T[20]; - word32 W[32]; - unsigned int i = 0, j = 0; - word32 *t = T+8; - - memcpy(t, state, 8*4); - word32 e = t[4], a = t[0]; - - do - { - word32 w = data[j]; - W[j] = w; - w += SHA256_K[j]; - w += t[7]; - w += S1(e); - w += Ch(e, t[5], t[6]); - e = t[3] + w; - t[3] = t[3+8] = e; - w += S0(t[0]); - a = w + Maj(a, t[1], t[2]); - t[-1] = t[7] = a; - --t; - ++j; - if (j%8 == 0) - t += 8; - } while (j<16); - - do - { - i = j&0xf; - word32 w = s1(W[i+16-2]) + s0(W[i+16-15]) + W[i] + W[i+16-7]; - W[i+16] = W[i] = w; - w += SHA256_K[j]; - w += t[7]; - w += S1(e); - w += Ch(e, t[5], t[6]); - e = t[3] + w; - t[3] = t[3+8] = e; - w += S0(t[0]); - a = w + Maj(a, t[1], t[2]); - t[-1] = t[7] = a; - - w = s1(W[(i+1)+16-2]) + s0(W[(i+1)+16-15]) + W[(i+1)] + W[(i+1)+16-7]; - W[(i+1)+16] = W[(i+1)] = w; - w += SHA256_K[j+1]; - w += (t-1)[7]; - w += S1(e); - w += Ch(e, (t-1)[5], (t-1)[6]); - e = (t-1)[3] + w; - (t-1)[3] = (t-1)[3+8] = e; - w += S0((t-1)[0]); - a = w + Maj(a, (t-1)[1], (t-1)[2]); - (t-1)[-1] = (t-1)[7] = a; - - t-=2; - j+=2; - if (j%8 == 0) - t += 8; - } while (j<64); - - state[0] += a; - state[1] += t[1]; - state[2] += t[2]; - state[3] += t[3]; - state[4] += e; - state[5] += t[5]; - state[6] += t[6]; - state[7] += t[7]; -} -*/ - -#undef S0 -#undef S1 -#undef s0 -#undef s1 -#undef R - -// ************************************************************* - -void SHA384::InitState(HashWordType *state) -{ - static const word64 s[8] = { - W64LIT(0xcbbb9d5dc1059ed8), W64LIT(0x629a292a367cd507), - W64LIT(0x9159015a3070dd17), W64LIT(0x152fecd8f70e5939), - W64LIT(0x67332667ffc00b31), W64LIT(0x8eb44a8768581511), - W64LIT(0xdb0c2e0d64f98fa7), W64LIT(0x47b5481dbefa4fa4)}; - memcpy(state, s, sizeof(s)); -} - -void SHA512::InitState(HashWordType *state) -{ - static const word64 s[8] = { - W64LIT(0x6a09e667f3bcc908), W64LIT(0xbb67ae8584caa73b), - W64LIT(0x3c6ef372fe94f82b), W64LIT(0xa54ff53a5f1d36f1), - W64LIT(0x510e527fade682d1), W64LIT(0x9b05688c2b3e6c1f), - W64LIT(0x1f83d9abfb41bd6b), W64LIT(0x5be0cd19137e2179)}; - memcpy(state, s, sizeof(s)); -} - -#if CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE && CRYPTOPP_BOOL_X86 -CRYPTOPP_ALIGN_DATA(16) static const word64 SHA512_K[80] CRYPTOPP_SECTION_ALIGN16 = { -#else -static const word64 SHA512_K[80] = { -#endif - W64LIT(0x428a2f98d728ae22), W64LIT(0x7137449123ef65cd), - W64LIT(0xb5c0fbcfec4d3b2f), W64LIT(0xe9b5dba58189dbbc), - W64LIT(0x3956c25bf348b538), W64LIT(0x59f111f1b605d019), - W64LIT(0x923f82a4af194f9b), W64LIT(0xab1c5ed5da6d8118), - W64LIT(0xd807aa98a3030242), W64LIT(0x12835b0145706fbe), - W64LIT(0x243185be4ee4b28c), W64LIT(0x550c7dc3d5ffb4e2), - W64LIT(0x72be5d74f27b896f), W64LIT(0x80deb1fe3b1696b1), - W64LIT(0x9bdc06a725c71235), W64LIT(0xc19bf174cf692694), - W64LIT(0xe49b69c19ef14ad2), W64LIT(0xefbe4786384f25e3), - W64LIT(0x0fc19dc68b8cd5b5), W64LIT(0x240ca1cc77ac9c65), - W64LIT(0x2de92c6f592b0275), W64LIT(0x4a7484aa6ea6e483), - W64LIT(0x5cb0a9dcbd41fbd4), W64LIT(0x76f988da831153b5), - W64LIT(0x983e5152ee66dfab), W64LIT(0xa831c66d2db43210), - W64LIT(0xb00327c898fb213f), W64LIT(0xbf597fc7beef0ee4), - W64LIT(0xc6e00bf33da88fc2), W64LIT(0xd5a79147930aa725), - W64LIT(0x06ca6351e003826f), W64LIT(0x142929670a0e6e70), - W64LIT(0x27b70a8546d22ffc), W64LIT(0x2e1b21385c26c926), - W64LIT(0x4d2c6dfc5ac42aed), W64LIT(0x53380d139d95b3df), - W64LIT(0x650a73548baf63de), W64LIT(0x766a0abb3c77b2a8), - W64LIT(0x81c2c92e47edaee6), W64LIT(0x92722c851482353b), - W64LIT(0xa2bfe8a14cf10364), W64LIT(0xa81a664bbc423001), - W64LIT(0xc24b8b70d0f89791), W64LIT(0xc76c51a30654be30), - W64LIT(0xd192e819d6ef5218), W64LIT(0xd69906245565a910), - W64LIT(0xf40e35855771202a), W64LIT(0x106aa07032bbd1b8), - W64LIT(0x19a4c116b8d2d0c8), W64LIT(0x1e376c085141ab53), - W64LIT(0x2748774cdf8eeb99), W64LIT(0x34b0bcb5e19b48a8), - W64LIT(0x391c0cb3c5c95a63), W64LIT(0x4ed8aa4ae3418acb), - W64LIT(0x5b9cca4f7763e373), W64LIT(0x682e6ff3d6b2b8a3), - W64LIT(0x748f82ee5defb2fc), W64LIT(0x78a5636f43172f60), - W64LIT(0x84c87814a1f0ab72), W64LIT(0x8cc702081a6439ec), - W64LIT(0x90befffa23631e28), W64LIT(0xa4506cebde82bde9), - W64LIT(0xbef9a3f7b2c67915), W64LIT(0xc67178f2e372532b), - W64LIT(0xca273eceea26619c), W64LIT(0xd186b8c721c0c207), - W64LIT(0xeada7dd6cde0eb1e), W64LIT(0xf57d4f7fee6ed178), - W64LIT(0x06f067aa72176fba), W64LIT(0x0a637dc5a2c898a6), - W64LIT(0x113f9804bef90dae), W64LIT(0x1b710b35131c471b), - W64LIT(0x28db77f523047d84), W64LIT(0x32caab7b40c72493), - W64LIT(0x3c9ebe0a15c9bebc), W64LIT(0x431d67c49c100d4c), - W64LIT(0x4cc5d4becb3e42b6), W64LIT(0x597f299cfc657e2a), - W64LIT(0x5fcb6fab3ad6faec), W64LIT(0x6c44198c4a475817) -}; - -#if CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE && CRYPTOPP_BOOL_X86 -// put assembly version in separate function, otherwise MSVC 2005 SP1 doesn't generate correct code for the non-assembly version -CRYPTOPP_NAKED static void CRYPTOPP_FASTCALL SHA512_SSE2_Transform(word64 *state, const word64 *data) -{ -#ifdef __GNUC__ - __asm__ __volatile__ - ( - ".intel_syntax noprefix;" - AS1( push ebx) - AS2( mov ebx, eax) -#else - AS1( push ebx) - AS1( push esi) - AS1( push edi) - AS2( lea ebx, SHA512_K) -#endif - - AS2( mov eax, esp) - AS2( and esp, 0xfffffff0) - AS2( sub esp, 27*16) // 17*16 for expanded data, 20*8 for state - AS1( push eax) - AS2( xor eax, eax) - AS2( lea edi, [esp+4+8*8]) // start at middle of state buffer. will decrement pointer each round to avoid copying - AS2( lea esi, [esp+4+20*8+8]) // 16-byte alignment, then add 8 - - AS2( movdqa xmm0, [ecx+0*16]) - AS2( movdq2q mm4, xmm0) - AS2( movdqa [edi+0*16], xmm0) - AS2( movdqa xmm0, [ecx+1*16]) - AS2( movdqa [edi+1*16], xmm0) - AS2( movdqa xmm0, [ecx+2*16]) - AS2( movdq2q mm5, xmm0) - AS2( movdqa [edi+2*16], xmm0) - AS2( movdqa xmm0, [ecx+3*16]) - AS2( movdqa [edi+3*16], xmm0) - ASJ( jmp, 0, f) - -#define SSE2_S0_S1(r, a, b, c) \ - AS2( movq mm6, r)\ - AS2( psrlq r, a)\ - AS2( movq mm7, r)\ - AS2( psllq mm6, 64-c)\ - AS2( pxor mm7, mm6)\ - AS2( psrlq r, b-a)\ - AS2( pxor mm7, r)\ - AS2( psllq mm6, c-b)\ - AS2( pxor mm7, mm6)\ - AS2( psrlq r, c-b)\ - AS2( pxor r, mm7)\ - AS2( psllq mm6, b-a)\ - AS2( pxor r, mm6) - -#define SSE2_s0(r, a, b, c) \ - AS2( movdqa xmm6, r)\ - AS2( psrlq r, a)\ - AS2( movdqa xmm7, r)\ - AS2( psllq xmm6, 64-c)\ - AS2( pxor xmm7, xmm6)\ - AS2( psrlq r, b-a)\ - AS2( pxor xmm7, r)\ - AS2( psrlq r, c-b)\ - AS2( pxor r, xmm7)\ - AS2( psllq xmm6, c-a)\ - AS2( pxor r, xmm6) - -#define SSE2_s1(r, a, b, c) \ - AS2( movdqa xmm6, r)\ - AS2( psrlq r, a)\ - AS2( movdqa xmm7, r)\ - AS2( psllq xmm6, 64-c)\ - AS2( pxor xmm7, xmm6)\ - AS2( psrlq r, b-a)\ - AS2( pxor xmm7, r)\ - AS2( psllq xmm6, c-b)\ - AS2( pxor xmm7, xmm6)\ - AS2( psrlq r, c-b)\ - AS2( pxor r, xmm7) - - ASL(SHA512_Round) - // k + w is in mm0, a is in mm4, e is in mm5 - AS2( paddq mm0, [edi+7*8]) // h - AS2( movq mm2, [edi+5*8]) // f - AS2( movq mm3, [edi+6*8]) // g - AS2( pxor mm2, mm3) - AS2( pand mm2, mm5) - SSE2_S0_S1(mm5,14,18,41) - AS2( pxor mm2, mm3) - AS2( paddq mm0, mm2) // h += Ch(e,f,g) - AS2( paddq mm5, mm0) // h += S1(e) - AS2( movq mm2, [edi+1*8]) // b - AS2( movq mm1, mm2) - AS2( por mm2, mm4) - AS2( pand mm2, [edi+2*8]) // c - AS2( pand mm1, mm4) - AS2( por mm1, mm2) - AS2( paddq mm1, mm5) // temp = h + Maj(a,b,c) - AS2( paddq mm5, [edi+3*8]) // e = d + h - AS2( movq [edi+3*8], mm5) - AS2( movq [edi+11*8], mm5) - SSE2_S0_S1(mm4,28,34,39) // S0(a) - AS2( paddq mm4, mm1) // a = temp + S0(a) - AS2( movq [edi-8], mm4) - AS2( movq [edi+7*8], mm4) - AS1( ret) - - // first 16 rounds - ASL(0) - AS2( movq mm0, [edx+eax*8]) - AS2( movq [esi+eax*8], mm0) - AS2( movq [esi+eax*8+16*8], mm0) - AS2( paddq mm0, [ebx+eax*8]) - ASC( call, SHA512_Round) - AS1( inc eax) - AS2( sub edi, 8) - AS2( test eax, 7) - ASJ( jnz, 0, b) - AS2( add edi, 8*8) - AS2( cmp eax, 16) - ASJ( jne, 0, b) - - // rest of the rounds - AS2( movdqu xmm0, [esi+(16-2)*8]) - ASL(1) - // data expansion, W[i-2] already in xmm0 - AS2( movdqu xmm3, [esi]) - AS2( paddq xmm3, [esi+(16-7)*8]) - AS2( movdqa xmm2, [esi+(16-15)*8]) - SSE2_s1(xmm0, 6, 19, 61) - AS2( paddq xmm0, xmm3) - SSE2_s0(xmm2, 1, 7, 8) - AS2( paddq xmm0, xmm2) - AS2( movdq2q mm0, xmm0) - AS2( movhlps xmm1, xmm0) - AS2( paddq mm0, [ebx+eax*8]) - AS2( movlps [esi], xmm0) - AS2( movlps [esi+8], xmm1) - AS2( movlps [esi+8*16], xmm0) - AS2( movlps [esi+8*17], xmm1) - // 2 rounds - ASC( call, SHA512_Round) - AS2( sub edi, 8) - AS2( movdq2q mm0, xmm1) - AS2( paddq mm0, [ebx+eax*8+8]) - ASC( call, SHA512_Round) - // update indices and loop - AS2( add esi, 16) - AS2( add eax, 2) - AS2( sub edi, 8) - AS2( test eax, 7) - ASJ( jnz, 1, b) - // do housekeeping every 8 rounds - AS2( mov esi, 0xf) - AS2( and esi, eax) - AS2( lea esi, [esp+4+20*8+8+esi*8]) - AS2( add edi, 8*8) - AS2( cmp eax, 80) - ASJ( jne, 1, b) - -#define SSE2_CombineState(i) \ - AS2( movdqa xmm0, [edi+i*16])\ - AS2( paddq xmm0, [ecx+i*16])\ - AS2( movdqa [ecx+i*16], xmm0) - - SSE2_CombineState(0) - SSE2_CombineState(1) - SSE2_CombineState(2) - SSE2_CombineState(3) - - AS1( pop esp) - AS1( emms) - -#if defined(__GNUC__) - AS1( pop ebx) - ".att_syntax prefix;" - : - : "a" (SHA512_K), "c" (state), "d" (data) - : "%esi", "%edi", "memory", "cc" - ); -#else - AS1( pop edi) - AS1( pop esi) - AS1( pop ebx) - AS1( ret) -#endif -} -#endif // #if CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE - -void SHA512::Transform(word64 *state, const word64 *data) -{ -#if CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE && CRYPTOPP_BOOL_X86 - if (HasSSE2()) - { - SHA512_SSE2_Transform(state, data); - return; - } -#endif - -#define S0(x) (rotrFixed(x,28)^rotrFixed(x,34)^rotrFixed(x,39)) -#define S1(x) (rotrFixed(x,14)^rotrFixed(x,18)^rotrFixed(x,41)) -#define s0(x) (rotrFixed(x,1)^rotrFixed(x,8)^(x>>7)) -#define s1(x) (rotrFixed(x,19)^rotrFixed(x,61)^(x>>6)) - -#define R(i) h(i)+=S1(e(i))+Ch(e(i),f(i),g(i))+SHA512_K[i+j]+(j?blk2(i):blk0(i));\ - d(i)+=h(i);h(i)+=S0(a(i))+Maj(a(i),b(i),c(i)) - - word64 W[16]; - word64 T[8]; - /* Copy context->state[] to working vars */ - memcpy(T, state, sizeof(T)); - /* 80 operations, partially loop unrolled */ - for (unsigned int j=0; j<80; j+=16) - { - R( 0); R( 1); R( 2); R( 3); - R( 4); R( 5); R( 6); R( 7); - R( 8); R( 9); R(10); R(11); - R(12); R(13); R(14); R(15); - } - /* Add the working vars back into context.state[] */ - state[0] += a(0); - state[1] += b(0); - state[2] += c(0); - state[3] += d(0); - state[4] += e(0); - state[5] += f(0); - state[6] += g(0); - state[7] += h(0); -} - -NAMESPACE_END - -#endif // #ifndef CRYPTOPP_GENERATE_X64_MASM -#endif // #ifndef CRYPTOPP_IMPORTS diff --git a/src/cryptopp/sha.h b/src/cryptopp/sha.h deleted file mode 100644 index 679081e8fa..0000000000 --- a/src/cryptopp/sha.h +++ /dev/null @@ -1,63 +0,0 @@ -#ifndef CRYPTOPP_SHA_H -#define CRYPTOPP_SHA_H - -#include "iterhash.h" - -NAMESPACE_BEGIN(CryptoPP) - -/// <a href="http://www.weidai.com/scan-mirror/md.html#SHA-1">SHA-1</a> -class CRYPTOPP_DLL SHA1 : public IteratedHashWithStaticTransform<word32, BigEndian, 64, 20, SHA1> -{ -public: - static void CRYPTOPP_API InitState(HashWordType *state); - static void CRYPTOPP_API Transform(word32 *digest, const word32 *data); - static const char * CRYPTOPP_API StaticAlgorithmName() {return "SHA-1";} -}; - -typedef SHA1 SHA; // for backwards compatibility - -//! implements the SHA-256 standard -class CRYPTOPP_DLL SHA256 : public IteratedHashWithStaticTransform<word32, BigEndian, 64, 32, SHA256, 32, true> -{ -public: -#if defined(CRYPTOPP_X86_ASM_AVAILABLE) || defined(CRYPTOPP_X64_MASM_AVAILABLE) - size_t HashMultipleBlocks(const word32 *input, size_t length); -#endif - static void CRYPTOPP_API InitState(HashWordType *state); - static void CRYPTOPP_API Transform(word32 *digest, const word32 *data); - static const char * CRYPTOPP_API StaticAlgorithmName() {return "SHA-256";} -}; - -//! implements the SHA-224 standard -class CRYPTOPP_DLL SHA224 : public IteratedHashWithStaticTransform<word32, BigEndian, 64, 32, SHA224, 28, true> -{ -public: -#if defined(CRYPTOPP_X86_ASM_AVAILABLE) || defined(CRYPTOPP_X64_MASM_AVAILABLE) - size_t HashMultipleBlocks(const word32 *input, size_t length); -#endif - static void CRYPTOPP_API InitState(HashWordType *state); - static void CRYPTOPP_API Transform(word32 *digest, const word32 *data) {SHA256::Transform(digest, data);} - static const char * CRYPTOPP_API StaticAlgorithmName() {return "SHA-224";} -}; - -//! implements the SHA-512 standard -class CRYPTOPP_DLL SHA512 : public IteratedHashWithStaticTransform<word64, BigEndian, 128, 64, SHA512, 64, CRYPTOPP_BOOL_X86> -{ -public: - static void CRYPTOPP_API InitState(HashWordType *state); - static void CRYPTOPP_API Transform(word64 *digest, const word64 *data); - static const char * CRYPTOPP_API StaticAlgorithmName() {return "SHA-512";} -}; - -//! implements the SHA-384 standard -class CRYPTOPP_DLL SHA384 : public IteratedHashWithStaticTransform<word64, BigEndian, 128, 64, SHA384, 48, CRYPTOPP_BOOL_X86> -{ -public: - static void CRYPTOPP_API InitState(HashWordType *state); - static void CRYPTOPP_API Transform(word64 *digest, const word64 *data) {SHA512::Transform(digest, data);} - static const char * CRYPTOPP_API StaticAlgorithmName() {return "SHA-384";} -}; - -NAMESPACE_END - -#endif diff --git a/src/cryptopp/simple.h b/src/cryptopp/simple.h deleted file mode 100644 index 8b13789179..0000000000 --- a/src/cryptopp/simple.h +++ /dev/null @@ -1 +0,0 @@ - diff --git a/src/cryptopp/smartptr.h b/src/cryptopp/smartptr.h deleted file mode 100644 index 6b4040e999..0000000000 --- a/src/cryptopp/smartptr.h +++ /dev/null @@ -1,223 +0,0 @@ -#ifndef CRYPTOPP_SMARTPTR_H -#define CRYPTOPP_SMARTPTR_H - -#include "config.h" -#include <algorithm> - -NAMESPACE_BEGIN(CryptoPP) - -template <class T> class simple_ptr -{ -public: - simple_ptr() : m_p(NULL) {} - ~simple_ptr() {delete m_p;} - T *m_p; -}; - -template <class T> class member_ptr -{ -public: - explicit member_ptr(T *p = NULL) : m_p(p) {} - - ~member_ptr(); - - const T& operator*() const { return *m_p; } - T& operator*() { return *m_p; } - - const T* operator->() const { return m_p; } - T* operator->() { return m_p; } - - const T* get() const { return m_p; } - T* get() { return m_p; } - - T* release() - { - T *old_p = m_p; - m_p = 0; - return old_p; - } - - void reset(T *p = 0); - -protected: - member_ptr(const member_ptr<T>& rhs); // copy not allowed - void operator=(const member_ptr<T>& rhs); // assignment not allowed - - T *m_p; -}; - -template <class T> member_ptr<T>::~member_ptr() {delete m_p;} -template <class T> void member_ptr<T>::reset(T *p) {delete m_p; m_p = p;} - -// ******************************************************** - -template<class T> class value_ptr : public member_ptr<T> -{ -public: - value_ptr(const T &obj) : member_ptr<T>(new T(obj)) {} - value_ptr(T *p = NULL) : member_ptr<T>(p) {} - value_ptr(const value_ptr<T>& rhs) - : member_ptr<T>(rhs.m_p ? new T(*rhs.m_p) : NULL) {} - - value_ptr<T>& operator=(const value_ptr<T>& rhs); - bool operator==(const value_ptr<T>& rhs) - { - return (!this->m_p && !rhs.m_p) || (this->m_p && rhs.m_p && *this->m_p == *rhs.m_p); - } -}; - -template <class T> value_ptr<T>& value_ptr<T>::operator=(const value_ptr<T>& rhs) -{ - T *old_p = this->m_p; - this->m_p = rhs.m_p ? new T(*rhs.m_p) : NULL; - delete old_p; - return *this; -} - -// ******************************************************** - -template<class T> class clonable_ptr : public member_ptr<T> -{ -public: - clonable_ptr(const T &obj) : member_ptr<T>(obj.Clone()) {} - clonable_ptr(T *p = NULL) : member_ptr<T>(p) {} - clonable_ptr(const clonable_ptr<T>& rhs) - : member_ptr<T>(rhs.m_p ? rhs.m_p->Clone() : NULL) {} - - clonable_ptr<T>& operator=(const clonable_ptr<T>& rhs); -}; - -template <class T> clonable_ptr<T>& clonable_ptr<T>::operator=(const clonable_ptr<T>& rhs) -{ - T *old_p = this->m_p; - this->m_p = rhs.m_p ? rhs.m_p->Clone() : NULL; - delete old_p; - return *this; -} - -// ******************************************************** - -template<class T> class counted_ptr -{ -public: - explicit counted_ptr(T *p = 0); - counted_ptr(const T &r) : m_p(0) {attach(r);} - counted_ptr(const counted_ptr<T>& rhs); - - ~counted_ptr(); - - const T& operator*() const { return *m_p; } - T& operator*() { return *m_p; } - - const T* operator->() const { return m_p; } - T* operator->() { return get(); } - - const T* get() const { return m_p; } - T* get(); - - void attach(const T &p); - - counted_ptr<T> & operator=(const counted_ptr<T>& rhs); - -private: - T *m_p; -}; - -template <class T> counted_ptr<T>::counted_ptr(T *p) - : m_p(p) -{ - if (m_p) - m_p->m_referenceCount = 1; -} - -template <class T> counted_ptr<T>::counted_ptr(const counted_ptr<T>& rhs) - : m_p(rhs.m_p) -{ - if (m_p) - m_p->m_referenceCount++; -} - -template <class T> counted_ptr<T>::~counted_ptr() -{ - if (m_p && --m_p->m_referenceCount == 0) - delete m_p; -} - -template <class T> void counted_ptr<T>::attach(const T &r) -{ - if (m_p && --m_p->m_referenceCount == 0) - delete m_p; - if (r.m_referenceCount == 0) - { - m_p = r.clone(); - m_p->m_referenceCount = 1; - } - else - { - m_p = const_cast<T *>(&r); - m_p->m_referenceCount++; - } -} - -template <class T> T* counted_ptr<T>::get() -{ - if (m_p && m_p->m_referenceCount > 1) - { - T *temp = m_p->clone(); - m_p->m_referenceCount--; - m_p = temp; - m_p->m_referenceCount = 1; - } - return m_p; -} - -template <class T> counted_ptr<T> & counted_ptr<T>::operator=(const counted_ptr<T>& rhs) -{ - if (m_p != rhs.m_p) - { - if (m_p && --m_p->m_referenceCount == 0) - delete m_p; - m_p = rhs.m_p; - if (m_p) - m_p->m_referenceCount++; - } - return *this; -} - -// ******************************************************** - -template <class T> class vector_member_ptrs -{ -public: - vector_member_ptrs(size_t size=0) - : m_size(size), m_ptr(new member_ptr<T>[size]) {} - ~vector_member_ptrs() - {delete [] this->m_ptr;} - - member_ptr<T>& operator[](size_t index) - {assert(index<this->m_size); return this->m_ptr[index];} - const member_ptr<T>& operator[](size_t index) const - {assert(index<this->m_size); return this->m_ptr[index];} - - size_t size() const {return this->m_size;} - void resize(size_t newSize) - { - member_ptr<T> *newPtr = new member_ptr<T>[newSize]; - for (size_t i=0; i<this->m_size && i<newSize; i++) - newPtr[i].reset(this->m_ptr[i].release()); - delete [] this->m_ptr; - this->m_size = newSize; - this->m_ptr = newPtr; - } - -private: - vector_member_ptrs(const vector_member_ptrs<T> &c); // copy not allowed - void operator=(const vector_member_ptrs<T> &x); // assignment not allowed - - size_t m_size; - member_ptr<T> *m_ptr; -}; - -NAMESPACE_END - -#endif diff --git a/src/cryptopp/stdcpp.h b/src/cryptopp/stdcpp.h deleted file mode 100644 index 9a468ab61e..0000000000 --- a/src/cryptopp/stdcpp.h +++ /dev/null @@ -1,27 +0,0 @@ -#ifndef CRYPTOPP_STDCPP_H -#define CRYPTOPP_STDCPP_H - -#include <stddef.h> -#include <assert.h> -#include <limits.h> -#include <memory> -#include <string> -#include <exception> -#include <typeinfo> - - -#ifdef _MSC_VER -#include <string.h> // CodeWarrior doesn't have memory.h -#include <algorithm> -#include <map> -#include <vector> - -// re-disable this -#pragma warning(disable: 4231) -#endif - -#if defined(_MSC_VER) && defined(_CRTAPI1) -#define CRYPTOPP_MSVCRT6 -#endif - -#endif diff --git a/src/db.cpp b/src/db.cpp index f044355a35..f69bab4dff 100644 --- a/src/db.cpp +++ b/src/db.cpp @@ -1,4 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto +// Copyright (c) 2011 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. @@ -519,24 +520,6 @@ bool CAddrDB::LoadAddresses() { CRITICAL_BLOCK(cs_mapAddresses) { - // Load user provided addresses - CAutoFile filein = fopen((GetDataDir() + "/addr.txt").c_str(), "rt"); - if (filein) - { - try - { - char psz[1000]; - while (fgets(psz, sizeof(psz), filein)) - { - CAddress addr(psz, NODE_NETWORK); - addr.nTime = 0; // so it won't relay unless successfully connected - if (addr.IsValid()) - AddAddress(addr); - } - } - catch (...) { } - } - // Get cursor Dbc* pcursor = GetCursor(); if (!pcursor) @@ -610,7 +593,7 @@ bool CWalletDB::WriteAccount(const string& strAccount, const CAccount& account) bool CWalletDB::WriteAccountingEntry(const CAccountingEntry& acentry) { - return Write(make_tuple(string("acentry"), acentry.strAccount, ++nAccountingEntryNumber), acentry); + return Write(boost::make_tuple(string("acentry"), acentry.strAccount, ++nAccountingEntryNumber), acentry); } int64 CWalletDB::GetAccountCreditDebit(const string& strAccount) @@ -627,8 +610,6 @@ int64 CWalletDB::GetAccountCreditDebit(const string& strAccount) void CWalletDB::ListAccountCreditDebit(const string& strAccount, list<CAccountingEntry>& entries) { - int64 nCreditDebit = 0; - bool fAllAccounts = (strAccount == "*"); Dbc* pcursor = GetCursor(); @@ -640,7 +621,7 @@ void CWalletDB::ListAccountCreditDebit(const string& strAccount, list<CAccountin // Read next record CDataStream ssKey; if (fFlags == DB_SET_RANGE) - ssKey << make_tuple(string("acentry"), (fAllAccounts? string("") : strAccount), uint64(0)); + ssKey << boost::make_tuple(string("acentry"), (fAllAccounts? string("") : strAccount), uint64(0)); CDataStream ssValue; int ret = ReadAtCursor(pcursor, ssKey, ssValue, fFlags); fFlags = DB_NEXT; @@ -670,7 +651,7 @@ void CWalletDB::ListAccountCreditDebit(const string& strAccount, list<CAccountin } -bool CWalletDB::LoadWallet(CWallet* pwallet) +int CWalletDB::LoadWallet(CWallet* pwallet) { pwallet->vchDefaultKey.clear(); int nFileVersion = 0; @@ -684,13 +665,12 @@ bool CWalletDB::LoadWallet(CWallet* pwallet) #endif //// todo: shouldn't we catch exceptions and try to recover and continue? - CRITICAL_BLOCK(pwallet->cs_mapWallet) - CRITICAL_BLOCK(pwallet->cs_mapKeys) + CRITICAL_BLOCK(pwallet->cs_wallet) { // Get cursor Dbc* pcursor = GetCursor(); if (!pcursor) - return false; + return DB_CORRUPT; loop { @@ -701,7 +681,7 @@ bool CWalletDB::LoadWallet(CWallet* pwallet) if (ret == DB_NOTFOUND) break; else if (ret != 0) - return false; + return DB_CORRUPT; // Unserialize // Taking advantage of the fact that pair serialization @@ -765,14 +745,42 @@ bool CWalletDB::LoadWallet(CWallet* pwallet) { vector<unsigned char> vchPubKey; ssKey >> vchPubKey; - CWalletKey wkey; + CKey key; if (strType == "key") - ssValue >> wkey.vchPrivKey; + { + CPrivKey pkey; + ssValue >> pkey; + key.SetPrivKey(pkey); + } else + { + CWalletKey wkey; ssValue >> wkey; - - pwallet->mapKeys[vchPubKey] = wkey.vchPrivKey; - mapPubKeys[Hash160(vchPubKey)] = vchPubKey; + key.SetPrivKey(wkey.vchPrivKey); + } + if (!pwallet->LoadKey(key)) + return DB_CORRUPT; + } + else if (strType == "mkey") + { + unsigned int nID; + ssKey >> nID; + CMasterKey kMasterKey; + ssValue >> kMasterKey; + if(pwallet->mapMasterKeys.count(nID) != 0) + return DB_CORRUPT; + pwallet->mapMasterKeys[nID] = kMasterKey; + if (pwallet->nMasterKeyMaxID < nID) + pwallet->nMasterKeyMaxID = nID; + } + else if (strType == "ckey") + { + vector<unsigned char> vchPubKey; + ssKey >> vchPubKey; + vector<unsigned char> vchPrivKey; + ssValue >> vchPrivKey; + if (!pwallet->LoadCryptedKey(vchPubKey, vchPrivKey)) + return DB_CORRUPT; } else if (strType == "defaultkey") { @@ -796,11 +804,10 @@ bool CWalletDB::LoadWallet(CWallet* pwallet) ssKey >> strKey; // Options -#ifndef GUI +#ifndef QT_GUI if (strKey == "fGenerateBitcoins") ssValue >> fGenerateBitcoins; #endif if (strKey == "nTransactionFee") ssValue >> nTransactionFee; - if (strKey == "addrIncoming") ssValue >> addrIncoming; if (strKey == "fLimitProcessors") ssValue >> fLimitProcessors; if (strKey == "nLimitProcessors") ssValue >> nLimitProcessors; if (strKey == "fMinimizeToTray") ssValue >> fMinimizeToTray; @@ -809,6 +816,13 @@ bool CWalletDB::LoadWallet(CWallet* pwallet) if (strKey == "addrProxy") ssValue >> addrProxy; if (fHaveUPnP && strKey == "fUseUPnP") ssValue >> fUseUPnP; } + else if (strType == "minversion") + { + int nMinVersion = 0; + ssValue >> nMinVersion; + if (nMinVersion > VERSION) + return DB_TOO_NEW; + } } pcursor->close(); } @@ -819,7 +833,6 @@ bool CWalletDB::LoadWallet(CWallet* pwallet) printf("nFileVersion = %d\n", nFileVersion); printf("fGenerateBitcoins = %d\n", fGenerateBitcoins); printf("nTransactionFee = %"PRI64d"\n", nTransactionFee); - printf("addrIncoming = %s\n", addrIncoming.ToString().c_str()); printf("fMinimizeToTray = %d\n", fMinimizeToTray); printf("fMinimizeOnClose = %d\n", fMinimizeOnClose); printf("fUseProxy = %d\n", fUseProxy); @@ -839,7 +852,7 @@ bool CWalletDB::LoadWallet(CWallet* pwallet) } - return true; + return DB_LOAD_OK; } void ThreadFlushWalletDB(void* parg) @@ -1,4 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto +// Copyright (c) 2011 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. #ifndef BITCOIN_DB_H @@ -88,7 +89,7 @@ protected: if (!pdb) return false; if (fReadOnly) - assert(("Write called on database in read-only mode", false)); + assert(!"Write called on database in read-only mode"); // Key CDataStream ssKey(SER_DISK); @@ -117,7 +118,7 @@ protected: if (!pdb) return false; if (fReadOnly) - assert(("Erase called on database in read-only mode", false)); + assert(!"Erase called on database in read-only mode"); // Key CDataStream ssKey(SER_DISK); @@ -342,6 +343,14 @@ public: +enum DBErrors +{ + DB_LOAD_OK, + DB_CORRUPT, + DB_TOO_NEW, + DB_LOAD_FAIL, +}; + class CWalletDB : public CDB { public: @@ -391,6 +400,25 @@ public: return Write(std::make_pair(std::string("key"), vchPubKey), vchPrivKey, false); } + bool WriteCryptedKey(const std::vector<unsigned char>& vchPubKey, const std::vector<unsigned char>& vchCryptedSecret, bool fEraseUnencryptedKey = true) + { + nWalletDBUpdated++; + if (!Write(std::make_pair(std::string("ckey"), vchPubKey), vchCryptedSecret, false)) + return false; + if (fEraseUnencryptedKey) + { + Erase(std::make_pair(std::string("key"), vchPubKey)); + Erase(std::make_pair(std::string("wkey"), vchPubKey)); + } + return true; + } + + bool WriteMasterKey(unsigned int nID, const CMasterKey& kMasterKey) + { + nWalletDBUpdated++; + return Write(std::make_pair(std::string("mkey"), nID), kMasterKey, true); + } + bool WriteBestBlock(const CBlockLocator& locator) { nWalletDBUpdated++; @@ -450,7 +478,7 @@ public: int64 GetAccountCreditDebit(const std::string& strAccount); void ListAccountCreditDebit(const std::string& strAccount, std::list<CAccountingEntry>& acentries); - bool LoadWallet(CWallet* pwallet); + int LoadWallet(CWallet* pwallet); }; #endif diff --git a/src/headers.h b/src/headers.h index d1844eb24e..17e9b3bc52 100644 --- a/src/headers.h +++ b/src/headers.h @@ -1,4 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto +// Copyright (c) 2011 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. @@ -26,14 +27,6 @@ #define BSD 1 #endif #endif -#ifdef GUI -#include <wx/wx.h> -#include <wx/stdpaths.h> -#include <wx/snglinst.h> -#include <wx/utils.h> -#include <wx/clipbrd.h> -#include <wx/taskbar.h> -#endif #include <openssl/buffer.h> #include <openssl/ecdsa.h> #include <openssl/evp.h> @@ -94,24 +87,8 @@ #include "bignum.h" #include "base58.h" #include "main.h" -#ifdef GUI -#include "uibase.h" -#include "ui.h" +#ifdef QT_GUI +#include "qtui.h" #else #include "noui.h" #endif - -#ifdef GUI -#include "xpm/addressbook16.xpm" -#include "xpm/addressbook20.xpm" -#include "xpm/bitcoin16.xpm" -#include "xpm/bitcoin20.xpm" -#include "xpm/bitcoin32.xpm" -#include "xpm/bitcoin48.xpm" -#include "xpm/bitcoin80.xpm" -#include "xpm/check.xpm" -#include "xpm/send16.xpm" -#include "xpm/send16noshadow.xpm" -#include "xpm/send20.xpm" -#include "xpm/about.xpm" -#endif diff --git a/src/init.cpp b/src/init.cpp index 635799ccf9..f09e1d019e 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -1,9 +1,10 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto +// Copyright (c) 2011 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. #include "headers.h" #include "db.h" -#include "rpc.h" +#include "bitcoinrpc.h" #include "net.h" #include "init.h" #include "strlcpy.h" @@ -79,7 +80,7 @@ void HandleSIGTERM(int) // // Start // -#ifndef GUI +#if !defined(QT_GUI) int main(int argc, char* argv[]) { bool fRet = false; @@ -178,6 +179,8 @@ bool AppInit2(int argc, char* argv[]) " -addnode=<ip> \t " + _("Add a node to connect to\n") + " -connect=<ip> \t\t " + _("Connect only to the specified node\n") + " -nolisten \t " + _("Don't accept connections from outside\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") + #ifdef USE_UPNP #if USE_UPNP " -noupnp \t " + _("Don't attempt to use UPnP to map the listening port\n") + @@ -213,14 +216,9 @@ bool AppInit2(int argc, char* argv[]) strUsage += string() + " -? \t\t " + _("This help message\n"); -#if defined(__WXMSW__) && defined(GUI) - // Tabs make the columns line up in the message box - wxMessageBox(strUsage, "Bitcoin", wxOK); -#else // Remove tabs strUsage.erase(std::remove(strUsage.begin(), strUsage.end(), '\t'), strUsage.end()); fprintf(stderr, "%s", strUsage.c_str()); -#endif return false; } @@ -239,17 +237,18 @@ bool AppInit2(int argc, char* argv[]) fServer = GetBoolArg("-server"); /* force fServer when running without GUI */ -#ifndef GUI +#if !defined(QT_GUI) fServer = true; #endif - fPrintToConsole = GetBoolArg("-printtoconsole"); fPrintToDebugger = GetBoolArg("-printtodebugger"); fTestNet = GetBoolArg("-testnet"); - fNoListen = GetBoolArg("-nolisten"); + bool fTOR = (fUseProxy && addrProxy.port == htons(9050)); + fNoListen = GetBoolArg("-nolisten") || fTOR; fLogTimestamps = GetBoolArg("-logtimestamps"); +#ifndef QT_GUI for (int i = 1; i < argc; i++) if (!IsSwitchChar(argv[i][0])) fCommandLine = true; @@ -259,6 +258,7 @@ bool AppInit2(int argc, char* argv[]) int ret = CommandLineRPC(argc, argv); exit(ret); } +#endif #ifndef __WXMSW__ if (fDaemon) @@ -286,11 +286,6 @@ bool AppInit2(int argc, char* argv[]) ShrinkDebugFile(); printf("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"); printf("Bitcoin version %s\n", FormatFullVersion().c_str()); -#ifdef GUI - printf("OS version %s\n", ((string)wxGetOsDescription()).c_str()); - printf("System default language is %d %s\n", g_locale.GetSystemLanguage(), ((string)g_locale.GetSysName()).c_str()); - printf("Language file %s (%s)\n", (string("locale/") + (string)g_locale.GetCanonicalName() + "/LC_MESSAGES/bitcoin.mo").c_str(), ((string)g_locale.GetLocale()).c_str()); -#endif printf("Default data directory %s\n", GetDefaultDataDir().c_str()); if (GetBoolArg("-loadblockindextest")) @@ -301,46 +296,6 @@ bool AppInit2(int argc, char* argv[]) return false; } - // - // Limit to single instance per user - // Required to protect the database files if we're going to keep deleting log.* - // -#if defined(__WXMSW__) && defined(GUI) - // wxSingleInstanceChecker doesn't work on Linux - wxString strMutexName = wxString("bitcoin_running.") + getenv("HOMEPATH"); - for (int i = 0; i < strMutexName.size(); i++) - if (!isalnum(strMutexName[i])) - strMutexName[i] = '.'; - wxSingleInstanceChecker* psingleinstancechecker = new wxSingleInstanceChecker(strMutexName); - if (psingleinstancechecker->IsAnotherRunning()) - { - printf("Existing instance found\n"); - unsigned int nStart = GetTime(); - loop - { - // Show the previous instance and exit - HWND hwndPrev = FindWindowA("wxWindowClassNR", "Bitcoin"); - if (hwndPrev) - { - if (IsIconic(hwndPrev)) - ShowWindow(hwndPrev, SW_RESTORE); - SetForegroundWindow(hwndPrev); - return false; - } - - if (GetTime() > nStart + 60) - return false; - - // Resume this instance if the other exits - delete psingleinstancechecker; - Sleep(1000); - psingleinstancechecker = new wxSingleInstanceChecker(strMutexName); - if (!psingleinstancechecker->IsAnotherRunning()) - break; - } - } -#endif - // Make sure only a single bitcoin process is using the data directory. string strLockFile = GetDataDir() + "/.lock"; FILE* file = fopen(strLockFile.c_str(), "a"); // empty lock file; created if it doesn't exist. @@ -371,24 +326,35 @@ bool AppInit2(int argc, char* argv[]) strErrors = ""; int64 nStart; + 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...")); printf("Loading block index...\n"); nStart = GetTimeMillis(); if (!LoadBlockIndex()) strErrors += _("Error loading blkindex.dat \n"); printf(" block index %15"PRI64d"ms\n", GetTimeMillis() - nStart); + InitMessage(_("Loading wallet...")); printf("Loading wallet...\n"); nStart = GetTimeMillis(); bool fFirstRun; pwalletMain = new CWallet("wallet.dat"); - if (!pwalletMain->LoadWallet(fFirstRun)) - strErrors += _("Error loading wallet.dat \n"); + int nLoadWalletRet = pwalletMain->LoadWallet(fFirstRun); + if (nLoadWalletRet != DB_LOAD_OK) + { + if (nLoadWalletRet == DB_CORRUPT) + strErrors += _("Error loading wallet.dat: Wallet corrupted \n"); + else if (nLoadWalletRet == DB_TOO_NEW) + strErrors += _("Error loading wallet.dat: Wallet requires newer version of Bitcoin \n"); + else + strErrors += _("Error loading wallet.dat \n"); + } printf(" wallet %15"PRI64d"ms\n", GetTimeMillis() - nStart); RegisterWallet(pwalletMain); @@ -405,20 +371,20 @@ bool AppInit2(int argc, char* argv[]) } if (pindexBest != pindexRescan) { + 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")); printf("Done loading\n"); //// debug print printf("mapBlockIndex.size() = %d\n", mapBlockIndex.size()); printf("nBestHeight = %d\n", nBestHeight); - printf("mapKeys.size() = %d\n", pwalletMain->mapKeys.size()); printf("setKeyPool.size() = %d\n", pwalletMain->setKeyPool.size()); - printf("mapPubKeys.size() = %d\n", mapPubKeys.size()); printf("mapWallet.size() = %d\n", pwalletMain->mapWallet.size()); printf("mapAddressBook.size() = %d\n", pwalletMain->mapAddressBook.size()); @@ -522,30 +488,20 @@ bool AppInit2(int argc, char* argv[]) } // - // Create the main window and start the node + // Start the node // -#ifdef GUI - if (!fDaemon) - CreateMainWindow(); -#endif - if (!CheckDiskSpace()) return false; RandAddSeedPerfmon(); if (!CreateThread(StartNode, NULL)) - wxMessageBox("Error: CreateThread(StartNode) failed", "Bitcoin"); + wxMessageBox(_("Error: CreateThread(StartNode) failed"), "Bitcoin"); if (fServer) CreateThread(ThreadRPCServer, NULL); -#if defined(__WXMSW__) && defined(GUI) - if (fFirstRun) - SetStartOnSystemStartup(true); -#endif - -#ifndef GUI +#if !defined(QT_GUI) while (1) Sleep(5000); #endif diff --git a/src/init.h b/src/init.h index a02260c293..4017f25707 100644 --- a/src/init.h +++ b/src/init.h @@ -1,4 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto +// Copyright (c) 2011 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. #ifndef BITCOIN_INIT_H diff --git a/src/irc.cpp b/src/irc.cpp index cde934e80c..5278488dcd 100644 --- a/src/irc.cpp +++ b/src/irc.cpp @@ -1,4 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto +// Copyright (c) 2011 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. @@ -1,4 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto +// Copyright (c) 2011 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. #ifndef BITCOIN_IRC_H @@ -1,13 +1,21 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto +// Copyright (c) 2011 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. #ifndef BITCOIN_KEY_H #define BITCOIN_KEY_H +#include <stdexcept> +#include <vector> + #include <openssl/ec.h> #include <openssl/ecdsa.h> #include <openssl/obj_mac.h> +#include "serialize.h" +#include "uint256.h" +#include "base58.h" + // secp160k1 // const unsigned int PRIVATE_KEY_SIZE = 192; // const unsigned int PUBLIC_KEY_SIZE = 41; @@ -31,7 +39,112 @@ // see www.keylength.com // script supports up to 75 for single byte push +int static inline EC_KEY_regenerate_key(EC_KEY *eckey, BIGNUM *priv_key) +{ + int ok = 0; + BN_CTX *ctx = NULL; + EC_POINT *pub_key = NULL; + + if (!eckey) return 0; + + const EC_GROUP *group = EC_KEY_get0_group(eckey); + + if ((ctx = BN_CTX_new()) == NULL) + goto err; + + pub_key = EC_POINT_new(group); + + if (pub_key == NULL) + goto err; + + if (!EC_POINT_mul(group, pub_key, priv_key, NULL, NULL, ctx)) + goto err; + + EC_KEY_set_private_key(eckey,priv_key); + EC_KEY_set_public_key(eckey,pub_key); + + ok = 1; + +err: + + if (pub_key) + EC_POINT_free(pub_key); + if (ctx != NULL) + BN_CTX_free(ctx); + + return(ok); +} +int static inline ECDSA_SIG_recover_key_GFp(EC_KEY *eckey, ECDSA_SIG *ecsig, const unsigned char *msg, int msglen, int recid, int check) +{ + if (!eckey) return 0; + + int ret = 0; + BN_CTX *ctx = NULL; + + BIGNUM *x = NULL; + BIGNUM *e = NULL; + BIGNUM *order = NULL; + BIGNUM *sor = NULL; + BIGNUM *eor = NULL; + BIGNUM *field = NULL; + EC_POINT *R = NULL; + EC_POINT *O = NULL; + EC_POINT *Q = NULL; + BIGNUM *rr = NULL; + BIGNUM *zero = NULL; + int n = 0; + int i = recid / 2; + + const EC_GROUP *group = EC_KEY_get0_group(eckey); + if ((ctx = BN_CTX_new()) == NULL) { ret = -1; goto err; } + BN_CTX_start(ctx); + order = BN_CTX_get(ctx); + if (!EC_GROUP_get_order(group, order, ctx)) { ret = -2; goto err; } + x = BN_CTX_get(ctx); + if (!BN_copy(x, order)) { ret=-1; goto err; } + if (!BN_mul_word(x, i)) { ret=-1; goto err; } + if (!BN_add(x, x, ecsig->r)) { ret=-1; goto err; } + field = BN_CTX_get(ctx); + if (!EC_GROUP_get_curve_GFp(group, field, NULL, NULL, ctx)) { ret=-2; goto err; } + if (BN_cmp(x, field) >= 0) { ret=0; goto err; } + if ((R = EC_POINT_new(group)) == NULL) { ret = -2; goto err; } + if (!EC_POINT_set_compressed_coordinates_GFp(group, R, x, recid % 2, ctx)) { ret=0; goto err; } + if (check) + { + if ((O = EC_POINT_new(group)) == NULL) { ret = -2; goto err; } + if (!EC_POINT_mul(group, O, NULL, R, order, ctx)) { ret=-2; goto err; } + if (!EC_POINT_is_at_infinity(group, O)) { ret = 0; goto err; } + } + if ((Q = EC_POINT_new(group)) == NULL) { ret = -2; goto err; } + n = EC_GROUP_get_degree(group); + e = BN_CTX_get(ctx); + if (!BN_bin2bn(msg, msglen, e)) { ret=-1; goto err; } + if (8*msglen > n) BN_rshift(e, e, 8-(n & 7)); + zero = BN_CTX_get(ctx); + if (!BN_zero(zero)) { ret=-1; goto err; } + if (!BN_mod_sub(e, zero, e, order, ctx)) { ret=-1; goto err; } + rr = BN_CTX_get(ctx); + if (!BN_mod_inverse(rr, ecsig->r, order, ctx)) { ret=-1; goto err; } + sor = BN_CTX_get(ctx); + if (!BN_mod_mul(sor, ecsig->s, rr, order, ctx)) { ret=-1; goto err; } + eor = BN_CTX_get(ctx); + if (!BN_mod_mul(eor, e, rr, order, ctx)) { ret=-1; goto err; } + if (!EC_POINT_mul(group, Q, eor, R, sor, ctx)) { ret=-2; goto err; } + if (!EC_KEY_set_public_key(eckey, Q)) { ret=-2; goto err; } + + ret = 1; + +err: + if (ctx) { + BN_CTX_end(ctx); + BN_CTX_free(ctx); + } + if (R != NULL) EC_POINT_free(R); + if (O != NULL) EC_POINT_free(O); + if (Q != NULL) EC_POINT_free(Q); + return ret; +} class key_error : public std::runtime_error { @@ -42,8 +155,7 @@ public: // secure_allocator is defined in serialize.h typedef std::vector<unsigned char, secure_allocator<unsigned char> > CPrivKey; - - +typedef std::vector<unsigned char, secure_allocator<unsigned char> > CSecret; class CKey { @@ -102,6 +214,38 @@ public: return true; } + bool SetSecret(const CSecret& vchSecret) + { + EC_KEY_free(pkey); + pkey = EC_KEY_new_by_curve_name(NID_secp256k1); + if (pkey == NULL) + throw key_error("CKey::SetSecret() : EC_KEY_new_by_curve_name failed"); + if (vchSecret.size() != 32) + throw key_error("CKey::SetSecret() : secret must be 32 bytes"); + BIGNUM *bn = BN_bin2bn(&vchSecret[0],32,BN_new()); + if (bn == NULL) + throw key_error("CKey::SetSecret() : BN_bin2bn failed"); + if (!EC_KEY_regenerate_key(pkey,bn)) + throw key_error("CKey::SetSecret() : EC_KEY_regenerate_key failed"); + BN_clear_free(bn); + fSet = true; + return true; + } + + CSecret GetSecret() const + { + CSecret vchRet; + vchRet.resize(32); + const BIGNUM *bn = EC_KEY_get0_private_key(pkey); + int nBytes = BN_num_bytes(bn); + if (bn == NULL) + throw key_error("CKey::GetSecret() : EC_KEY_get0_private_key failed"); + int n=BN_bn2bin(bn,&vchRet[32 - nBytes]); + if (n != nBytes) + throw key_error("CKey::GetSecret(): BN_bn2bin failed"); + return vchRet; + } + CPrivKey GetPrivKey() const { unsigned int nSize = i2d_ECPrivateKey(pkey, NULL); @@ -147,6 +291,66 @@ public: return true; } + // create a compact signature (65 bytes), which allows reconstructing the used public key + bool SignCompact(uint256 hash, std::vector<unsigned char>& vchSig) + { + bool fOk = false; + ECDSA_SIG *sig = ECDSA_do_sign((unsigned char*)&hash, sizeof(hash), pkey); + if (sig==NULL) + return false; + vchSig.clear(); + vchSig.resize(65,0); + int nBitsR = BN_num_bits(sig->r); + int nBitsS = BN_num_bits(sig->s); + if (nBitsR <= 256 && nBitsS <= 256) + { + int nRecId = -1; + for (int i=0; i<4; i++) + { + CKey keyRec; + keyRec.fSet = true; + if (ECDSA_SIG_recover_key_GFp(keyRec.pkey, sig, (unsigned char*)&hash, sizeof(hash), i, 1) == 1) + if (keyRec.GetPubKey() == this->GetPubKey()) + { + nRecId = i; + break; + } + } + + if (nRecId == -1) + throw key_error("CKEy::SignCompact() : unable to construct recoverable key"); + + vchSig[0] = nRecId+27; + BN_bn2bin(sig->r,&vchSig[33-(nBitsR+7)/8]); + BN_bn2bin(sig->s,&vchSig[65-(nBitsS+7)/8]); + fOk = true; + } + ECDSA_SIG_free(sig); + return fOk; + } + + // reconstruct public key from a compact signature + bool SetCompactSignature(uint256 hash, const std::vector<unsigned char>& vchSig) + { + if (vchSig.size() != 65) + return false; + if (vchSig[0]<27 || vchSig[0]>=31) + return false; + ECDSA_SIG *sig = ECDSA_SIG_new(); + BN_bin2bn(&vchSig[1],32,sig->r); + BN_bin2bn(&vchSig[33],32,sig->s); + + EC_KEY_free(pkey); + pkey = EC_KEY_new_by_curve_name(NID_secp256k1); + if (ECDSA_SIG_recover_key_GFp(pkey, sig, (unsigned char*)&hash, sizeof(hash), vchSig[0] - 27, 0) == 1) + { + fSet = true; + ECDSA_SIG_free(sig); + return true; + } + return false; + } + bool Verify(uint256 hash, const std::vector<unsigned char>& vchSig) { // -1 = error, 0 = bad sig, 1 = good @@ -155,20 +359,19 @@ public: return true; } - static bool Sign(const CPrivKey& vchPrivKey, uint256 hash, std::vector<unsigned char>& vchSig) + bool VerifyCompact(uint256 hash, const std::vector<unsigned char>& vchSig) { CKey key; - if (!key.SetPrivKey(vchPrivKey)) + if (!key.SetCompactSignature(hash, vchSig)) + return false; + if (GetPubKey() != key.GetPubKey()) return false; - return key.Sign(hash, vchSig); + return true; } - static bool Verify(const std::vector<unsigned char>& vchPubKey, uint256 hash, const std::vector<unsigned char>& vchSig) + CBitcoinAddress GetAddress() const { - CKey key; - if (!key.SetPubKey(vchPubKey)) - return false; - return key.Verify(hash, vchSig); + return CBitcoinAddress(GetPubKey()); } }; diff --git a/src/keystore.cpp b/src/keystore.cpp index 7dd045fe5f..68f57e7e0e 100644 --- a/src/keystore.cpp +++ b/src/keystore.cpp @@ -1,33 +1,181 @@ -// Copyright (c) 2009-2011 Satoshi Nakamoto & Bitcoin developers +// Copyright (c) 2009-2010 Satoshi Nakamoto +// Copyright (c) 2011 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. #include "headers.h" #include "db.h" +#include "crypter.h" +std::vector<unsigned char> CKeyStore::GenerateNewKey() +{ + RandAddSeedPerfmon(); + CKey key; + key.MakeNewKey(); + if (!AddKey(key)) + throw std::runtime_error("CKeyStore::GenerateNewKey() : AddKey failed"); + return key.GetPubKey(); +} + +bool CKeyStore::GetPubKey(const CBitcoinAddress &address, std::vector<unsigned char> &vchPubKeyOut) const +{ + CKey key; + if (!GetKey(address, key)) + return false; + vchPubKeyOut = key.GetPubKey(); + return true; +} +bool CBasicKeyStore::AddKey(const CKey& key) +{ + CRITICAL_BLOCK(cs_KeyStore) + mapKeys[key.GetAddress()] = key.GetSecret(); + return true; +} -////////////////////////////////////////////////////////////////////////////// -// -// mapKeys -// +bool CCryptoKeyStore::SetCrypted() +{ + CRITICAL_BLOCK(cs_KeyStore) + { + if (fUseCrypto) + return true; + if (!mapKeys.empty()) + return false; + fUseCrypto = true; + } + return true; +} -std::vector<unsigned char> CKeyStore::GenerateNewKey() +std::vector<unsigned char> CCryptoKeyStore::GenerateNewKey() { RandAddSeedPerfmon(); CKey key; key.MakeNewKey(); if (!AddKey(key)) - throw std::runtime_error("GenerateNewKey() : AddKey failed"); + throw std::runtime_error("CCryptoKeyStore::GenerateNewKey() : AddKey failed"); return key.GetPubKey(); } -bool CKeyStore::AddKey(const CKey& key) +bool CCryptoKeyStore::Unlock(const CKeyingMaterial& vMasterKeyIn) +{ + CRITICAL_BLOCK(cs_KeyStore) + { + if (!SetCrypted()) + return false; + + CryptedKeyMap::const_iterator mi = mapCryptedKeys.begin(); + for (; mi != mapCryptedKeys.end(); ++mi) + { + const std::vector<unsigned char> &vchPubKey = (*mi).second.first; + const std::vector<unsigned char> &vchCryptedSecret = (*mi).second.second; + CSecret vchSecret; + if(!DecryptSecret(vMasterKeyIn, vchCryptedSecret, Hash(vchPubKey.begin(), vchPubKey.end()), vchSecret)) + return false; + CKey key; + key.SetSecret(vchSecret); + if (key.GetPubKey() == vchPubKey) + break; + return false; + } + vMasterKey = vMasterKeyIn; + } + return true; +} + +bool CCryptoKeyStore::AddKey(const CKey& key) +{ + CRITICAL_BLOCK(cs_KeyStore) + { + if (!IsCrypted()) + return CBasicKeyStore::AddKey(key); + + if (IsLocked()) + return false; + + std::vector<unsigned char> vchCryptedSecret; + std::vector<unsigned char> vchPubKey = key.GetPubKey(); + if (!EncryptSecret(vMasterKey, key.GetSecret(), Hash(vchPubKey.begin(), vchPubKey.end()), vchCryptedSecret)) + return false; + + if (!AddCryptedKey(key.GetPubKey(), vchCryptedSecret)) + return false; + } + return true; +} + + +bool CCryptoKeyStore::AddCryptedKey(const std::vector<unsigned char> &vchPubKey, const std::vector<unsigned char> &vchCryptedSecret) +{ + CRITICAL_BLOCK(cs_KeyStore) + { + if (!SetCrypted()) + return false; + + mapCryptedKeys[CBitcoinAddress(vchPubKey)] = make_pair(vchPubKey, vchCryptedSecret); + } + return true; +} + +bool CCryptoKeyStore::GetKey(const CBitcoinAddress &address, CKey& keyOut) const { - CRITICAL_BLOCK(cs_mapKeys) + CRITICAL_BLOCK(cs_KeyStore) { - mapKeys[key.GetPubKey()] = key.GetPrivKey(); - mapPubKeys[Hash160(key.GetPubKey())] = key.GetPubKey(); + if (!IsCrypted()) + return CBasicKeyStore::GetKey(address, keyOut); + + CryptedKeyMap::const_iterator mi = mapCryptedKeys.find(address); + if (mi != mapCryptedKeys.end()) + { + const std::vector<unsigned char> &vchPubKey = (*mi).second.first; + const std::vector<unsigned char> &vchCryptedSecret = (*mi).second.second; + CSecret vchSecret; + if (!DecryptSecret(vMasterKey, vchCryptedSecret, Hash(vchPubKey.begin(), vchPubKey.end()), vchSecret)) + return false; + keyOut.SetSecret(vchSecret); + return true; + } } + return false; } +bool CCryptoKeyStore::GetPubKey(const CBitcoinAddress &address, std::vector<unsigned char>& vchPubKeyOut) const +{ + CRITICAL_BLOCK(cs_KeyStore) + { + if (!IsCrypted()) + return CKeyStore::GetPubKey(address, vchPubKeyOut); + + CryptedKeyMap::const_iterator mi = mapCryptedKeys.find(address); + if (mi != mapCryptedKeys.end()) + { + vchPubKeyOut = (*mi).second.first; + return true; + } + } + return false; +} + +bool CCryptoKeyStore::EncryptKeys(CKeyingMaterial& vMasterKeyIn) +{ + CRITICAL_BLOCK(cs_KeyStore) + { + if (!mapCryptedKeys.empty() || IsCrypted()) + return false; + + fUseCrypto = true; + CKey key; + BOOST_FOREACH(KeyMap::value_type& mKey, mapKeys) + { + if (!key.SetSecret(mKey.second)) + return false; + const std::vector<unsigned char> vchPubKey = key.GetPubKey(); + std::vector<unsigned char> vchCryptedSecret; + if (!EncryptSecret(vMasterKeyIn, key.GetSecret(), Hash(vchPubKey.begin(), vchPubKey.end()), vchCryptedSecret)) + return false; + if (!AddCryptedKey(vchPubKey, vchCryptedSecret)) + return false; + } + mapKeys.clear(); + } + return true; +} diff --git a/src/keystore.h b/src/keystore.h index 6080d7d7f5..bbfac83d1f 100644 --- a/src/keystore.h +++ b/src/keystore.h @@ -1,30 +1,122 @@ -// Copyright (c) 2009-2011 Satoshi Nakamoto & Bitcoin developers +// Copyright (c) 2009-2010 Satoshi Nakamoto +// Copyright (c) 2011 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. #ifndef BITCOIN_KEYSTORE_H #define BITCOIN_KEYSTORE_H +#include "crypter.h" + class CKeyStore { +protected: + mutable CCriticalSection cs_KeyStore; + +public: + virtual bool AddKey(const CKey& key) =0; + virtual bool HaveKey(const CBitcoinAddress &address) const =0; + virtual bool GetKey(const CBitcoinAddress &address, CKey& keyOut) const =0; + virtual bool GetPubKey(const CBitcoinAddress &address, std::vector<unsigned char>& vchPubKeyOut) const; + virtual std::vector<unsigned char> GenerateNewKey(); +}; + +typedef std::map<CBitcoinAddress, CSecret> KeyMap; + +class CBasicKeyStore : public CKeyStore +{ +protected: + KeyMap mapKeys; + public: - std::map<std::vector<unsigned char>, CPrivKey> mapKeys; - mutable CCriticalSection cs_mapKeys; - virtual bool AddKey(const CKey& key); - bool HaveKey(const std::vector<unsigned char> &vchPubKey) const + bool AddKey(const CKey& key); + bool HaveKey(const CBitcoinAddress &address) const { - return (mapKeys.count(vchPubKey) > 0); + bool result; + CRITICAL_BLOCK(cs_KeyStore) + result = (mapKeys.count(address) > 0); + return result; } - bool GetPrivKey(const std::vector<unsigned char> &vchPubKey, CPrivKey& keyOut) const + bool GetKey(const CBitcoinAddress &address, CKey& keyOut) const { - std::map<std::vector<unsigned char>, CPrivKey>::const_iterator mi = mapKeys.find(vchPubKey); - if (mi != mapKeys.end()) + CRITICAL_BLOCK(cs_KeyStore) { - keyOut = (*mi).second; - return true; + KeyMap::const_iterator mi = mapKeys.find(address); + if (mi != mapKeys.end()) + { + keyOut.SetSecret((*mi).second); + return true; + } } return false; } +}; + +typedef std::map<CBitcoinAddress, std::pair<std::vector<unsigned char>, std::vector<unsigned char> > > CryptedKeyMap; + +class CCryptoKeyStore : public CBasicKeyStore +{ +private: + CryptedKeyMap mapCryptedKeys; + + CKeyingMaterial vMasterKey; + + // if fUseCrypto is true, mapKeys must be empty + // if fUseCrypto is false, vMasterKey must be empty + bool fUseCrypto; + +protected: + bool SetCrypted(); + + // will encrypt previously unencrypted keys + bool EncryptKeys(CKeyingMaterial& vMasterKeyIn); + + bool Unlock(const CKeyingMaterial& vMasterKeyIn); + +public: + CCryptoKeyStore() : fUseCrypto(false) + { + } + + bool IsCrypted() const + { + return fUseCrypto; + } + + bool IsLocked() const + { + if (!IsCrypted()) + return false; + bool result; + CRITICAL_BLOCK(cs_KeyStore) + result = vMasterKey.empty(); + return result; + } + + bool Lock() + { + if (!SetCrypted()) + return false; + + CRITICAL_BLOCK(cs_KeyStore) + vMasterKey.clear(); + + return true; + } + + virtual bool AddCryptedKey(const std::vector<unsigned char> &vchPubKey, const std::vector<unsigned char> &vchCryptedSecret); std::vector<unsigned char> GenerateNewKey(); + bool AddKey(const CKey& key); + bool HaveKey(const CBitcoinAddress &address) const + { + CRITICAL_BLOCK(cs_KeyStore) + { + if (!IsCrypted()) + return CBasicKeyStore::HaveKey(address); + return mapCryptedKeys.count(address) > 0; + } + } + bool GetKey(const CBitcoinAddress &address, CKey& keyOut) const; + bool GetPubKey(const CBitcoinAddress &address, std::vector<unsigned char>& vchPubKeyOut) const; }; #endif diff --git a/src/main.cpp b/src/main.cpp index 594f1d3bc4..9c780e2040 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,11 +1,11 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto +// Copyright (c) 2011 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. #include "headers.h" #include "db.h" #include "net.h" #include "init.h" -#include "cryptopp/sha.h" #include <boost/filesystem.hpp> #include <boost/filesystem/fstream.hpp> @@ -21,18 +21,15 @@ set<CWallet*> setpwalletRegistered; CCriticalSection cs_main; -CCriticalSection cs_mapPubKeys; -map<uint160, vector<unsigned char> > mapPubKeys; - -map<uint256, CTransaction> mapTransactions; +static map<uint256, CTransaction> mapTransactions; CCriticalSection cs_mapTransactions; unsigned int nTransactionsUpdated = 0; map<COutPoint, CInPoint> mapNextTx; map<uint256, CBlockIndex*> mapBlockIndex; uint256 hashGenesisBlock("0x000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f"); -CBigNum bnProofOfWorkLimit(~uint256(0) >> 32); -const int nTotalBlocksEstimate = 134444; // Conservative estimate of total nr of blocks on main chain +static CBigNum bnProofOfWorkLimit(~uint256(0) >> 32); +const int nTotalBlocksEstimate = 140700; // Conservative estimate of total nr of blocks on main chain const int nInitialBlockThreshold = 120; // Regard blocks up until N-threshold as "initial download" CBlockIndex* pindexGenesisBlock = NULL; int nBestHeight = -1; @@ -42,6 +39,8 @@ uint256 hashBestChain = 0; CBlockIndex* pindexBest = NULL; int64 nTimeBestReceived = 0; +CMedianFilter<int> cPeerBlockCounts(5, 0); // Amount of blocks that other nodes claim to have + map<uint256, CBlock*> mapOrphanBlocks; multimap<uint256, CBlock*> mapOrphanBlocksByPrev; @@ -55,7 +54,6 @@ int64 nHPSTimerStart; // Settings int fGenerateBitcoins = false; int64 nTransactionFee = 0; -CAddress addrIncoming; int fLimitProcessors = false; int nLimitProcessors = 1; int fMinimizeToTray = true; @@ -67,11 +65,6 @@ int fUseUPnP = false; #endif - - - - - ////////////////////////////////////////////////////////////////////////////// // // dispatching functions @@ -298,36 +291,46 @@ int CMerkleTx::SetMerkleBranch(const CBlock* pblock) bool CTransaction::CheckTransaction() const { // Basic checks that don't depend on any context - if (vin.empty() || vout.empty()) - return error("CTransaction::CheckTransaction() : vin or vout empty"); - + if (vin.empty()) + return DoS(10, error("CTransaction::CheckTransaction() : vin empty")); + if (vout.empty()) + return DoS(10, error("CTransaction::CheckTransaction() : vout empty")); // Size limits if (::GetSerializeSize(*this, SER_NETWORK) > MAX_BLOCK_SIZE) - return error("CTransaction::CheckTransaction() : size limits failed"); + return DoS(100, error("CTransaction::CheckTransaction() : size limits failed")); // Check for negative or overflow output values int64 nValueOut = 0; BOOST_FOREACH(const CTxOut& txout, vout) { if (txout.nValue < 0) - return error("CTransaction::CheckTransaction() : txout.nValue negative"); + return DoS(100, error("CTransaction::CheckTransaction() : txout.nValue negative")); if (txout.nValue > MAX_MONEY) - return error("CTransaction::CheckTransaction() : txout.nValue too high"); + return DoS(100, error("CTransaction::CheckTransaction() : txout.nValue too high")); nValueOut += txout.nValue; if (!MoneyRange(nValueOut)) - return error("CTransaction::CheckTransaction() : txout total out of range"); + return DoS(100, error("CTransaction::CheckTransaction() : txout total out of range")); + } + + // Check for duplicate inputs + set<COutPoint> vInOutPoints; + BOOST_FOREACH(const CTxIn& txin, vin) + { + if (vInOutPoints.count(txin.prevout)) + return false; + vInOutPoints.insert(txin.prevout); } if (IsCoinBase()) { if (vin[0].scriptSig.size() < 2 || vin[0].scriptSig.size() > 100) - return error("CTransaction::CheckTransaction() : coinbase script size"); + return DoS(100, error("CTransaction::CheckTransaction() : coinbase script size")); } else { BOOST_FOREACH(const CTxIn& txin, vin) if (txin.prevout.IsNull()) - return error("CTransaction::CheckTransaction() : prevout is null"); + return DoS(10, error("CTransaction::CheckTransaction() : prevout is null")); } return true; @@ -343,7 +346,7 @@ bool CTransaction::AcceptToMemoryPool(CTxDB& txdb, bool fCheckInputs, bool* pfMi // Coinbase is only valid in a block, not as a loose transaction if (IsCoinBase()) - return error("AcceptToMemoryPool() : coinbase as individual tx"); + return DoS(100, error("AcceptToMemoryPool() : coinbase as individual tx")); // To help v0.1.5 clients who would see it as a negative number if ((int64)nLockTime > INT_MAX) @@ -356,7 +359,7 @@ bool CTransaction::AcceptToMemoryPool(CTxDB& txdb, bool fCheckInputs, bool* pfMi // 34 bytes because a TxOut is: // 20-byte address + 8 byte bitcoin amount + 5 bytes of ops + 1 byte script length if (GetSigOpCount() > nSize / 34 || nSize < 100) - return error("AcceptToMemoryPool() : nonstandard transaction"); + return error("AcceptToMemoryPool() : transaction with out-of-bounds SigOpCount"); // Rather not work on nonstandard transactions (unless -testnet) if (!fTestNet && !IsStandard()) @@ -719,6 +722,12 @@ int GetTotalBlocksEstimate() } } +// Return maximum amount of blocks that other nodes claim to have +int GetNumBlocksOfPeers() +{ + return std::max(cPeerBlockCounts.median(), GetTotalBlocksEstimate()); +} + bool IsInitialBlockDownload() { if (pindexBest == NULL || nBestHeight < (GetTotalBlocksEstimate()-nInitialBlockThreshold)) @@ -796,6 +805,9 @@ bool CTransaction::ConnectInputs(CTxDB& txdb, map<uint256, CTxIndex>& mapTestPoo CBlockIndex* pindexBlock, int64& nFees, bool fBlock, bool fMiner, int64 nMinFee) { // Take over previous transactions' spent pointers + // fBlock is true when this is called from AcceptBlock when a new best-block is added to the blockchain + // fMiner is true when called from the internal bitcoin miner + // ... both are false when called from CTransaction::AcceptToMemoryPool if (!IsCoinBase()) { int64 nValueIn = 0; @@ -806,7 +818,7 @@ bool CTransaction::ConnectInputs(CTxDB& txdb, map<uint256, CTxIndex>& mapTestPoo // Read txindex CTxIndex txindex; bool fFound = true; - if (fMiner && mapTestPool.count(prevout.hash)) + if ((fBlock || fMiner) && mapTestPool.count(prevout.hash)) { // Get txindex from current proposed changes txindex = mapTestPool[prevout.hash]; @@ -841,7 +853,7 @@ bool CTransaction::ConnectInputs(CTxDB& txdb, map<uint256, CTxIndex>& mapTestPoo } if (prevout.n >= txPrev.vout.size() || prevout.n >= txindex.vSpent.size()) - return error("ConnectInputs() : %s prevout.n out of range %d %d %d prev tx %s\n%s", GetHash().ToString().substr(0,10).c_str(), prevout.n, txPrev.vout.size(), txindex.vSpent.size(), prevout.hash.ToString().substr(0,10).c_str(), txPrev.ToString().c_str()); + return DoS(100, error("ConnectInputs() : %s prevout.n out of range %d %d %d prev tx %s\n%s", GetHash().ToString().substr(0,10).c_str(), prevout.n, txPrev.vout.size(), txindex.vSpent.size(), prevout.hash.ToString().substr(0,10).c_str(), txPrev.ToString().c_str())); // If prev is coinbase, check that it's matured if (txPrev.IsCoinBase()) @@ -849,53 +861,53 @@ bool CTransaction::ConnectInputs(CTxDB& txdb, map<uint256, CTxIndex>& mapTestPoo if (pindex->nBlockPos == txindex.pos.nBlockPos && pindex->nFile == txindex.pos.nFile) return error("ConnectInputs() : tried to spend coinbase at depth %d", pindexBlock->nHeight - pindex->nHeight); - // Verify signature - if (!VerifySignature(txPrev, *this, i)) - return error("ConnectInputs() : %s VerifySignature failed", GetHash().ToString().substr(0,10).c_str()); - - // Check for conflicts + // Skip ECDSA signature verification when connecting blocks (fBlock=true) during initial download + // (before the last blockchain checkpoint). This is safe because block merkle hashes are + // still computed and checked, and any change will be caught at the next checkpoint. + if (!(fBlock && IsInitialBlockDownload())) + // Verify signature + if (!VerifySignature(txPrev, *this, i)) + return DoS(100,error("ConnectInputs() : %s VerifySignature failed", GetHash().ToString().substr(0,10).c_str())); + + // Check for conflicts (double-spend) + // This doesn't trigger the DoS code on purpose; if it did, it would make it easier + // for an attacker to attempt to split the network. if (!txindex.vSpent[prevout.n].IsNull()) return fMiner ? false : error("ConnectInputs() : %s prev tx already used at %s", GetHash().ToString().substr(0,10).c_str(), txindex.vSpent[prevout.n].ToString().c_str()); // Check for negative or overflow input values nValueIn += txPrev.vout[prevout.n].nValue; if (!MoneyRange(txPrev.vout[prevout.n].nValue) || !MoneyRange(nValueIn)) - return error("ConnectInputs() : txin values out of range"); + return DoS(100, error("ConnectInputs() : txin values out of range")); // Mark outpoints as spent txindex.vSpent[prevout.n] = posThisTx; // Write back - if (fBlock) - { - if (!txdb.UpdateTxIndex(prevout.hash, txindex)) - return error("ConnectInputs() : UpdateTxIndex failed"); - } - else if (fMiner) + if (fBlock || fMiner) { mapTestPool[prevout.hash] = txindex; } } if (nValueIn < GetValueOut()) - return error("ConnectInputs() : %s value in < value out", GetHash().ToString().substr(0,10).c_str()); + return DoS(100, error("ConnectInputs() : %s value in < value out", GetHash().ToString().substr(0,10).c_str())); // Tally transaction fees int64 nTxFee = nValueIn - GetValueOut(); if (nTxFee < 0) - return error("ConnectInputs() : %s nTxFee < 0", GetHash().ToString().substr(0,10).c_str()); + return DoS(100, error("ConnectInputs() : %s nTxFee < 0", GetHash().ToString().substr(0,10).c_str())); if (nTxFee < nMinFee) return false; nFees += nTxFee; if (!MoneyRange(nFees)) - return error("ConnectInputs() : nFees out of range"); + return DoS(100, error("ConnectInputs() : nFees out of range")); } if (fBlock) { - // Add transaction to disk index - if (!txdb.AddTxIndex(*this, posThisTx, pindexBlock->nHeight)) - return error("ConnectInputs() : AddTxPos failed"); + // Add transaction to changes + mapTestPool[GetHash()] = CTxIndex(posThisTx, vout.size()); } else if (fMiner) { @@ -984,16 +996,22 @@ bool CBlock::ConnectBlock(CTxDB& txdb, CBlockIndex* pindex) //// issue here: it doesn't know the version unsigned int nTxPos = pindex->nBlockPos + ::GetSerializeSize(CBlock(), SER_DISK) - 1 + GetSizeOfCompactSize(vtx.size()); - map<uint256, CTxIndex> mapUnused; + map<uint256, CTxIndex> mapQueuedChanges; int64 nFees = 0; BOOST_FOREACH(CTransaction& tx, vtx) { CDiskTxPos posThisTx(pindex->nFile, pindex->nBlockPos, nTxPos); nTxPos += ::GetSerializeSize(tx, SER_DISK); - if (!tx.ConnectInputs(txdb, mapUnused, posThisTx, pindex, nFees, true, false)) + if (!tx.ConnectInputs(txdb, mapQueuedChanges, posThisTx, pindex, nFees, true, false)) return false; } + // Write queued txindex changes + for (map<uint256, CTxIndex>::iterator mi = mapQueuedChanges.begin(); mi != mapQueuedChanges.end(); ++mi) + { + if (!txdb.UpdateTxIndex((*mi).first, (*mi).second)) + return error("ConnectBlock() : UpdateTxIndex failed"); + } if (vtx[0].GetValueOut() > GetBlockValue(pindex->nHeight, nFees)) return false; @@ -1226,11 +1244,11 @@ bool CBlock::CheckBlock() const // Size limits if (vtx.empty() || vtx.size() > MAX_BLOCK_SIZE || ::GetSerializeSize(*this, SER_NETWORK) > MAX_BLOCK_SIZE) - return error("CheckBlock() : size limits failed"); + return DoS(100, error("CheckBlock() : size limits failed")); // Check proof of work matches claimed amount if (!CheckProofOfWork(GetHash(), nBits)) - return error("CheckBlock() : proof of work failed"); + return DoS(50, error("CheckBlock() : proof of work failed")); // Check timestamp if (GetBlockTime() > GetAdjustedTime() + 2 * 60 * 60) @@ -1238,23 +1256,23 @@ bool CBlock::CheckBlock() const // First transaction must be coinbase, the rest must not be if (vtx.empty() || !vtx[0].IsCoinBase()) - return error("CheckBlock() : first tx is not coinbase"); + return DoS(100, error("CheckBlock() : first tx is not coinbase")); for (int i = 1; i < vtx.size(); i++) if (vtx[i].IsCoinBase()) - return error("CheckBlock() : more than one coinbase"); + return DoS(100, error("CheckBlock() : more than one coinbase")); // Check transactions BOOST_FOREACH(const CTransaction& tx, vtx) if (!tx.CheckTransaction()) - return error("CheckBlock() : CheckTransaction failed"); + return DoS(tx.nDoS, error("CheckBlock() : CheckTransaction failed")); // Check that it's not full of nonstandard transactions if (GetSigOpCount() > MAX_BLOCK_SIGOPS) - return error("CheckBlock() : too many nonstandard transactions"); + return DoS(100, error("CheckBlock() : out-of-bounds SigOpCount")); // Check merkleroot if (hashMerkleRoot != BuildMerkleTree()) - return error("CheckBlock() : hashMerkleRoot mismatch"); + return DoS(100, error("CheckBlock() : hashMerkleRoot mismatch")); return true; } @@ -1269,13 +1287,13 @@ bool CBlock::AcceptBlock() // Get prev block index map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hashPrevBlock); if (mi == mapBlockIndex.end()) - return error("AcceptBlock() : prev block not found"); + return DoS(10, error("AcceptBlock() : prev block not found")); CBlockIndex* pindexPrev = (*mi).second; int nHeight = pindexPrev->nHeight+1; // Check proof of work if (nBits != GetNextWorkRequired(pindexPrev)) - return error("AcceptBlock() : incorrect proof of work"); + return DoS(100, error("AcceptBlock() : incorrect proof of work")); // Check timestamp against prev if (GetBlockTime() <= pindexPrev->GetMedianTimePast()) @@ -1284,7 +1302,7 @@ bool CBlock::AcceptBlock() // Check that all transactions are finalized BOOST_FOREACH(const CTransaction& tx, vtx) if (!tx.IsFinal(nHeight, GetBlockTime())) - return error("AcceptBlock() : contains a non-final transaction"); + return DoS(10, error("AcceptBlock() : contains a non-final transaction")); // Check that the block chain matches the known block chain up to a checkpoint if (!fTestNet) @@ -1295,8 +1313,9 @@ bool CBlock::AcceptBlock() (nHeight == 74000 && hash != uint256("0x0000000000573993a3c9e41ce34471c079dcf5f52a0e824a81e7f953b8661a20")) || (nHeight == 105000 && hash != uint256("0x00000000000291ce28027faea320c8d2b054b2e0fe44a773f3eefb151d6bdc97")) || (nHeight == 118000 && hash != uint256("0x000000000000774a7f8a7a12dc906ddb9e17e75d684f15e00f8767f9e8f36553")) || - (nHeight == 134444 && hash != uint256("0x00000000000005b12ffd4cd315cd34ffd4a594f430ac814c91184a0d42d2b0fe"))) - return error("AcceptBlock() : rejected by checkpoint lockin at %d", nHeight); + (nHeight == 134444 && hash != uint256("0x00000000000005b12ffd4cd315cd34ffd4a594f430ac814c91184a0d42d2b0fe")) || + (nHeight == 140700 && hash != uint256("0x000000000000033b512028abb90e1626d8b346fd0ed598ac0a3c371138dce2bd"))) + return DoS(100, error("AcceptBlock() : rejected by checkpoint lockin at %d", nHeight)); // Write block to history file if (!CheckDiskSpace(::GetSerializeSize(*this, SER_DISK))) @@ -1312,13 +1331,13 @@ bool CBlock::AcceptBlock() if (hashBestChain == hash) CRITICAL_BLOCK(cs_vNodes) BOOST_FOREACH(CNode* pnode, vNodes) - if (nBestHeight > (pnode->nStartingHeight != -1 ? pnode->nStartingHeight - 2000 : 134444)) + if (nBestHeight > (pnode->nStartingHeight != -1 ? pnode->nStartingHeight - 2000 : 140700)) pnode->PushInventory(CInv(MSG_BLOCK, hash)); return true; } -bool static ProcessBlock(CNode* pfrom, CBlock* pblock) +bool ProcessBlock(CNode* pfrom, CBlock* pblock) { // Check for duplicate uint256 hash = pblock->GetHash(); @@ -1379,47 +1398,6 @@ bool static ProcessBlock(CNode* pfrom, CBlock* pblock) -template<typename Stream> -bool static ScanMessageStart(Stream& s) -{ - // Scan ahead to the next pchMessageStart, which should normally be immediately - // at the file pointer. Leaves file pointer at end of pchMessageStart. - s.clear(0); - short prevmask = s.exceptions(0); - const char* p = BEGIN(pchMessageStart); - try - { - loop - { - char c; - s.read(&c, 1); - if (s.fail()) - { - s.clear(0); - s.exceptions(prevmask); - return false; - } - if (*p != c) - p = BEGIN(pchMessageStart); - if (*p == c) - { - if (++p == END(pchMessageStart)) - { - s.clear(0); - s.exceptions(prevmask); - return true; - } - } - } - } - catch (...) - { - s.clear(0); - s.exceptions(prevmask); - return false; - } -} - bool CheckDiskSpace(uint64 nAdditionalBytes) { uint64 nFreeBytesAvailable = filesystem::space(GetDataDir()).available; @@ -1689,7 +1667,7 @@ string GetWarnings(string strFor) return strStatusBar; else if (strFor == "rpc") return strRPC; - assert(("GetWarnings() : invalid parameter", false)); + assert(!"GetWarnings() : invalid parameter"); return "error"; } @@ -1770,16 +1748,17 @@ bool static AlreadyHave(CTxDB& txdb, const CInv& inv) // The message start string is designed to be unlikely to occur in normal data. // The characters are rarely used upper ascii, not valid as UTF-8, and produce // a large 4-byte int at any alignment. -char pchMessageStart[4] = { 0xf9, 0xbe, 0xb4, 0xd9 }; +unsigned char pchMessageStart[4] = { 0xf9, 0xbe, 0xb4, 0xd9 }; bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) { static map<unsigned int, vector<unsigned char> > mapReuseKey; RandAddSeedPerfmon(); - if (fDebug) + if (fDebug) { printf("%s ", DateTimeStrFormat("%x %H:%M:%S", GetTime()).c_str()); - printf("received: %s (%d bytes)\n", strCommand.c_str(), vRecv.size()); + 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"); @@ -1794,7 +1773,10 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) { // Each connection can only send one version message if (pfrom->nVersion != 0) + { + pfrom->Misbehaving(1); return false; + } int64 nTime; CAddress addrMe; @@ -1856,7 +1838,9 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) // Ask the first connected node for block updates static int nAskedForBlocks; - if (!pfrom->fClient && (nAskedForBlocks < 1 || vNodes.size() <= 1)) + if (!pfrom->fClient && + (pfrom->nVersion < 32000 || pfrom->nVersion >= 32400) && + (nAskedForBlocks < 1 || vNodes.size() <= 1)) { nAskedForBlocks++; pfrom->PushGetBlocks(pindexBest, uint256(0)); @@ -1870,12 +1854,15 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) pfrom->fSuccessfullyConnected = true; printf("version message: version %d, blocks=%d\n", pfrom->nVersion, pfrom->nStartingHeight); + + cPeerBlockCounts.input(pfrom->nStartingHeight); } else if (pfrom->nVersion == 0) { // Must have a version message before anything else + pfrom->Misbehaving(1); return false; } @@ -1897,9 +1884,14 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) if (pfrom->nVersion < 31402 && mapAddresses.size() > 1000) return true; if (vAddr.size() > 1000) + { + pfrom->Misbehaving(20); return error("message addr size() = %d", vAddr.size()); + } // Store the new addresses + CAddrDB addrDB; + addrDB.TxnBegin(); int64 nNow = GetAdjustedTime(); int64 nSince = nNow - 10 * 60; BOOST_FOREACH(CAddress& addr, vAddr) @@ -1911,7 +1903,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) continue; if (addr.nTime <= 100000000 || addr.nTime > nNow + 10 * 60) addr.nTime = nNow - 5 * 24 * 60 * 60; - AddAddress(addr, 2 * 60 * 60); + AddAddress(addr, 2 * 60 * 60, &addrDB); pfrom->AddAddressKnown(addr); if (addr.nTime > nSince && !pfrom->fGetAddr && vAddr.size() <= 10 && addr.IsRoutable()) { @@ -1942,6 +1934,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) } } } + addrDB.TxnCommit(); // Save addresses (it's ok if this fails) if (vAddr.size() < 1000) pfrom->fGetAddr = false; } @@ -1952,7 +1945,10 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) vector<CInv> vInv; vRecv >> vInv; if (vInv.size() > 50000) + { + pfrom->Misbehaving(20); return error("message inv size() = %d", vInv.size()); + } CTxDB txdb("r"); BOOST_FOREACH(const CInv& inv, vInv) @@ -1962,7 +1958,8 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) pfrom->AddInventoryKnown(inv); bool fAlreadyHave = AlreadyHave(txdb, inv); - printf(" got inventory: %s %s\n", inv.ToString().c_str(), fAlreadyHave ? "have" : "new"); + if (fDebug) + printf(" got inventory: %s %s\n", inv.ToString().c_str(), fAlreadyHave ? "have" : "new"); if (!fAlreadyHave) pfrom->AskFor(inv); @@ -1980,7 +1977,10 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) vector<CInv> vInv; vRecv >> vInv; if (vInv.size() > 50000) + { + pfrom->Misbehaving(20); return error("message getdata size() = %d", vInv.size()); + } BOOST_FOREACH(const CInv& inv, vInv) { @@ -2152,6 +2152,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) printf("storing orphan tx %s\n", inv.hash.ToString().substr(0,10).c_str()); AddOrphanTx(vMsg); } + if (tx.nDoS) pfrom->Misbehaving(tx.nDoS); } @@ -2168,6 +2169,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) if (ProcessBlock(pfrom, &block)) mapAlreadyAskedFor.erase(inv); + if (block.nDoS) pfrom->Misbehaving(block.nDoS); } @@ -2213,7 +2215,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) // Keep giving the same key to the same ip until they use it if (!mapReuseKey.count(pfrom->addr.ip)) - mapReuseKey[pfrom->addr.ip] = pwalletMain->GetKeyFromKeyPool(); + pwalletMain->GetKeyFromPool(mapReuseKey[pfrom->addr.ip], true); // Send back approval of order and pubkey to use CScript scriptPubKey; @@ -2568,6 +2570,7 @@ bool SendMessages(CNode* pto, bool fSendTrickle) vGetData.clear(); } } + mapAlreadyAskedFor[inv] = nNow; pto->mapAskFor.erase(pto->mapAskFor.begin()); } if (!vGetData.empty()) @@ -2610,15 +2613,25 @@ int static FormatHashBlocks(void* pbuffer, unsigned int len) return blocks; } -using CryptoPP::ByteReverse; - static const unsigned int pSHA256InitState[8] = {0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19}; -inline void SHA256Transform(void* pstate, void* pinput, const void* pinit) +void SHA256Transform(void* pstate, void* pinput, const void* pinit) { - memcpy(pstate, pinit, 32); - CryptoPP::SHA256::Transform((CryptoPP::word32*)pstate, (CryptoPP::word32*)pinput); + SHA256_CTX ctx; + unsigned char data[64]; + + SHA256_Init(&ctx); + + for (int i = 0; i < 16; i++) + ((uint32_t*)data)[i] = ByteReverse(((uint32_t*)pinput)[i]); + + for (int i = 0; i < 8; i++) + ctx.h[i] = ((uint32_t*)pinit)[i]; + + SHA256_Update(&ctx, data, sizeof(data)); + for (int i = 0; i < 8; i++) + ((uint32_t*)pstate)[i] = ctx.h[i]; } // @@ -2654,7 +2667,7 @@ unsigned int static ScanHash_CryptoPP(char* pmidstate, char* pdata, char* phash1 } } - +// Some explaining would be appreciated class COrphan { public: @@ -2825,16 +2838,17 @@ CBlock* CreateNewBlock(CReserveKey& reservekey) } -void IncrementExtraNonce(CBlock* pblock, CBlockIndex* pindexPrev, unsigned int& nExtraNonce, int64& nPrevTime) +void IncrementExtraNonce(CBlock* pblock, CBlockIndex* pindexPrev, unsigned int& nExtraNonce) { // Update nExtraNonce - int64 nNow = max(pindexPrev->GetMedianTimePast()+1, GetAdjustedTime()); - if (++nExtraNonce >= 0x7f && nNow > nPrevTime+1) + static uint256 hashPrevBlock; + if (hashPrevBlock != pblock->hashPrevBlock) { - nExtraNonce = 1; - nPrevTime = nNow; + nExtraNonce = 0; + hashPrevBlock = pblock->hashPrevBlock; } - pblock->vtx[0].vin[0].scriptSig = CScript() << pblock->nBits << CBigNum(nExtraNonce); + ++nExtraNonce; + pblock->vtx[0].vin[0].scriptSig = CScript() << pblock->nTime << CBigNum(nExtraNonce); pblock->hashMerkleRoot = pblock->BuildMerkleTree(); } @@ -2910,7 +2924,7 @@ bool CheckWork(CBlock* pblock, CWallet& wallet, CReserveKey& reservekey) reservekey.KeepKey(); // Track how many getdata requests this block gets - CRITICAL_BLOCK(wallet.cs_mapRequestCount) + CRITICAL_BLOCK(wallet.cs_wallet) wallet.mapRequestCount[pblock->GetHash()] = 0; // Process this block the same as if we had received it from another node @@ -2932,7 +2946,6 @@ void static BitcoinMiner(CWallet *pwallet) // Each thread has its own key and counter CReserveKey reservekey(pwallet); unsigned int nExtraNonce = 0; - int64 nPrevTime = 0; while (fGenerateBitcoins) { @@ -2959,7 +2972,7 @@ void static BitcoinMiner(CWallet *pwallet) auto_ptr<CBlock> pblock(CreateNewBlock(reservekey)); if (!pblock.get()) return; - IncrementExtraNonce(pblock.get(), pindexPrev, nExtraNonce, nPrevTime); + IncrementExtraNonce(pblock.get(), pindexPrev, nExtraNonce); printf("Running BitcoinMiner with %d transactions in block\n", pblock->vtx.size()); diff --git a/src/main.h b/src/main.h index aa74ac5ab3..329035dc5a 100644 --- a/src/main.h +++ b/src/main.h @@ -1,4 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto +// Copyright (c) 2011 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. #ifndef BITCOIN_MAIN_H @@ -20,7 +21,6 @@ class CKeyItem; class CReserveKey; class CWalletDB; -class CMessageHeader; class CAddress; class CInv; class CRequestTracker; @@ -37,6 +37,8 @@ static const int64 MIN_RELAY_TX_FEE = 10000; 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 #ifdef USE_UPNP static const int fHaveUPnP = true; #else @@ -51,7 +53,6 @@ static const int fHaveUPnP = false; extern CCriticalSection cs_main; extern std::map<uint256, CBlockIndex*> mapBlockIndex; extern uint256 hashGenesisBlock; -extern CBigNum bnProofOfWorkLimit; extern CBlockIndex* pindexGenesisBlock; extern int nBestHeight; extern CBigNum bnBestChainWork; @@ -68,7 +69,6 @@ extern std::set<CWallet*> setpwalletRegistered; // Settings extern int fGenerateBitcoins; extern int64 nTransactionFee; -extern CAddress addrIncoming; extern int fLimitProcessors; extern int nLimitProcessors; extern int fMinimizeToTray; @@ -85,6 +85,7 @@ class CTxIndex; void RegisterWallet(CWallet* pwalletIn); void UnregisterWallet(CWallet* pwalletIn); +bool ProcessBlock(CNode* pfrom, CBlock* pblock); bool CheckDiskSpace(uint64 nAdditionalBytes=0); FILE* OpenBlockFile(unsigned int nFile, unsigned int nBlockPos, const char* pszMode="rb"); FILE* AppendBlockFile(unsigned int& nFileRet); @@ -94,11 +95,12 @@ bool ProcessMessages(CNode* pfrom); bool SendMessages(CNode* pto, bool fSendTrickle); void GenerateBitcoins(bool fGenerate, CWallet* pwallet); CBlock* CreateNewBlock(CReserveKey& reservekey); -void IncrementExtraNonce(CBlock* pblock, CBlockIndex* pindexPrev, unsigned int& nExtraNonce, int64& nPrevTime); +void IncrementExtraNonce(CBlock* pblock, CBlockIndex* pindexPrev, unsigned int& nExtraNonce); void FormatHashBuffers(CBlock* pblock, char* pmidstate, char* pdata, char* phash1); bool CheckWork(CBlock* pblock, CWallet& wallet, CReserveKey& reservekey); bool CheckProofOfWork(uint256 hash, unsigned int nBits); int GetTotalBlocksEstimate(); +int GetNumBlocksOfPeers(); bool IsInitialBlockDownload(); std::string GetWarnings(std::string strFor); @@ -399,6 +401,9 @@ public: std::vector<CTxOut> vout; unsigned int nLockTime; + // Denial-of-service detection: + mutable int nDoS; + bool DoS(int nDoSIn, bool fIn) const { nDoS += nDoSIn; return fIn; } CTransaction() { @@ -420,6 +425,7 @@ public: vin.clear(); vout.clear(); nLockTime = 0; + nDoS = 0; // Denial-of-service prevention } bool IsNull() const @@ -441,7 +447,7 @@ public: nBlockHeight = nBestHeight; if (nBlockTime == 0) nBlockTime = GetAdjustedTime(); - if ((int64)nLockTime < (nLockTime < 500000000 ? (int64)nBlockHeight : nBlockTime)) + if ((int64)nLockTime < (nLockTime < LOCKTIME_THRESHOLD ? (int64)nBlockHeight : nBlockTime)) return true; BOOST_FOREACH(const CTxIn& txin, vin) if (!txin.IsFinal()) @@ -786,6 +792,9 @@ public: // memory only mutable std::vector<uint256> vMerkleTree; + // Denial-of-service detection: + mutable int nDoS; + bool DoS(int nDoSIn, bool fIn) const { nDoS += nDoSIn; return fIn; } CBlock() { @@ -819,6 +828,7 @@ public: nNonce = 0; vtx.clear(); vMerkleTree.clear(); + nDoS = 0; } bool IsNull() const @@ -1556,18 +1566,4 @@ public: bool ProcessAlert(); }; - - - - - - - - - - -extern std::map<uint256, CTransaction> mapTransactions; -extern std::map<uint160, std::vector<unsigned char> > mapPubKeys; -extern CCriticalSection cs_mapPubKeys; - #endif diff --git a/src/makefile.linux-mingw b/src/makefile.linux-mingw index 3fb18ff28d..b8ca9e6a1e 100644 --- a/src/makefile.linux-mingw +++ b/src/makefile.linux-mingw @@ -4,22 +4,18 @@ DEPSDIR:=/usr/i586-mingw32msvc +USE_UPNP:=0 + INCLUDEPATHS= \ - -I"$(DEPSDIR)/boost_1_43_0" \ - -I"$(DEPSDIR)/db-4.7.25.NC/build_unix" \ + -I"$(DEPSDIR)/boost_1_47_0" \ + -I"$(DEPSDIR)/db-4.8.30.NC/build_unix" \ -I"$(DEPSDIR)/openssl-1.0.0d/include" \ - -I"$(DEPSDIR)/wxWidgets-2.9.1/lib/gcc_lib/mswud" \ - -I"$(DEPSDIR)/wxWidgets-2.9.1/include" \ - -I"$(DEPSDIR)/wxWidgets-2.9.1/lib/wx/include/i586-mingw32msvc-msw-unicode-static-2.9/" \ -I"$(DEPSDIR)" LIBPATHS= \ - -L"$(DEPSDIR)/boost_1_43_0/stage/lib" \ - -L"$(DEPSDIR)/db-4.7.25.NC/build_unix" \ - -L"$(DEPSDIR)/openssl-1.0.0d" \ - -L"$(DEPSDIR)/wxWidgets-2.9.1/lib" - -WXLIBS= -l wx_mswu-2.9-i586-mingw32msvc + -L"$(DEPSDIR)/boost_1_47_0/stage/lib" \ + -L"$(DEPSDIR)/db-4.8.30.NC/build_unix" \ + -L"$(DEPSDIR)/openssl-1.0.0d" LIBS= \ -l boost_system-mt-s \ @@ -30,60 +26,55 @@ LIBS= \ -l ssl \ -l crypto -DEFS=-D_MT -DWIN32 -D__WXMSW__ -D_WINDOWS -DNOPCH -DUSE_SSL -DEBUGFLAGS=-g -D__WXDEBUG__ +DEFS=-D_MT -DWIN32 -D_WINDOWS -DNOPCH -DUSE_SSL -DBOOST_THREAD_USE_LIB +DEBUGFLAGS=-g CFLAGS=-O2 -w -Wno-invalid-offsetof -Wformat $(DEBUGFLAGS) $(DEFS) $(INCLUDEPATHS) -HEADERS=headers.h strlcpy.h serialize.h uint256.h util.h key.h bignum.h base58.h \ - script.h db.h net.h irc.h keystore.h main.h wallet.h rpc.h uibase.h ui.h noui.h init.h - -bitcoin.exe: USE_UPNP:=1 - ifdef USE_UPNP - INCLUDEPATHS += -I"$(DEPSDIR)/upnpc-exe-win32-20110215" - LIBPATHS += -L"$(DEPSDIR)/upnpc-exe-win32-20110215" - LIBS += -l miniupnpc -l iphlpapi - DEFS += -DSTATICLIB -DUSE_UPNP=$(USE_UPNP) - endif - -bitcoind.exe: USE_UPNP:=0 - ifdef USE_UPNP - INCLUDEPATHS += -I"$(DEPSDIR)/upnpc-exe-win32-20110215" - LIBPATHS += -L"$(DEPSDIR)/upnpc-exe-win32-20110215" - LIBS += -l miniupnpc -l iphlpapi - DEFS += -DSTATICLIB -DUSE_UPNP=$(USE_UPNP) - endif +HEADERS = \ + base58.h \ + bignum.h \ + crypter.h \ + db.h \ + headers.h \ + init.h \ + irc.h \ + key.h \ + keystore.h \ + main.h \ + net.h \ + noui.h \ + protocol.h \ + bitcoinrpc.h \ + script.h \ + serialize.h \ + strlcpy.h \ + uint256.h \ + util.h \ + wallet.h + + +ifdef USE_UPNP + LIBPATHS += -L"$(DEPSDIR)/miniupnpc" + LIBS += -l miniupnpc -l iphlpapi + DEFS += -DSTATICLIB -DUSE_UPNP=$(USE_UPNP) +endif LIBS += -l mingwthrd -l kernel32 -l user32 -l gdi32 -l comdlg32 -l winspool -l winmm -l shell32 -l comctl32 -l ole32 -l oleaut32 -l uuid -l rpcrt4 -l advapi32 -l ws2_32 -l shlwapi OBJS= \ - obj/util.o \ - obj/script.o \ + obj/crypter.o \ obj/db.o \ - obj/net.o \ + obj/init.o \ obj/irc.o \ obj/keystore.o \ obj/main.o \ - obj/wallet.o \ - obj/rpc.o \ - obj/init.o \ - cryptopp/obj/sha.o \ - cryptopp/obj/cpu.o - - -all: bitcoin.exe - - -obj/%.o: %.cpp $(HEADERS) - i586-mingw32msvc-g++ -c $(CFLAGS) -DGUI -o $@ $< - -cryptopp/obj/%.o: cryptopp/%.cpp - i586-mingw32msvc-g++ -c $(CFLAGS) -O3 -DCRYPTOPP_DISABLE_ASM -o $@ $< - -obj/ui_res.o: ../share/ui.rc ../share/pixmaps/bitcoin.ico ../share/pixmaps/check.ico ../share/pixmaps/send16.bmp ../share/pixmaps/send16mask.bmp ../share/pixmaps/send16masknoshadow.bmp ../share/pixmaps/send20.bmp ../share/pixmaps/send20mask.bmp ../share/pixmaps/addressbook16.bmp ../share/pixmaps/addressbook16mask.bmp ../share/pixmaps/addressbook20.bmp ../share/pixmaps/addressbook20mask.bmp - i586-mingw32msvc-windres $(DEFS) $(INCLUDEPATHS) -o $@ -i $< - -bitcoin.exe: $(OBJS) obj/ui.o obj/uibase.o obj/ui_res.o - i586-mingw32msvc-g++ $(CFLAGS) -mwindows -Wl,--subsystem,windows -o $@ $(LIBPATHS) $^ $(WXLIBS) $(LIBS) + obj/net.o \ + obj/protocol.o \ + obj/bitcoinrpc.o \ + obj/script.o \ + obj/util.o \ + obj/wallet.o +all: bitcoind.exe obj/nogui/%.o: %.cpp $(HEADERS) i586-mingw32msvc-g++ -c $(CFLAGS) -o $@ $< @@ -95,7 +86,7 @@ bitcoind.exe: $(OBJS:obj/%=obj/nogui/%) obj/ui_res.o obj/test/%.o: obj/test/%.cpp $(HEADERS) i586-mingw32msvc-g++ -c $(CFLAGS) -o $@ $< -test_bitcoin.exe: obj/test/test_bitcoin.o +test_bitcoin.exe: obj/test/test_bitcoin.o $(filter-out obj/nogui/init.o,$(OBJS:obj/%=obj/nogui/%)) i586-mingw32msvc-g++ $(CFLAGS) -o $@ $(LIBPATHS) $^ $(LIBS) -lboost_unit_test_framework-mt-s @@ -103,9 +94,7 @@ clean: -rm -f obj/*.o -rm -f obj/nogui/*.o -rm -f obj/test/*.o - -rm -f cryptopp/obj/*.o -rm -f test/*.o -rm -f headers.h.gch - -rm -f bitcoin.exe -rm -f bitcoind.exe -rm -f test_bitcoin.exe diff --git a/src/makefile.mingw b/src/makefile.mingw index 507833be48..73d3940a5c 100644 --- a/src/makefile.mingw +++ b/src/makefile.mingw @@ -5,39 +5,52 @@ USE_UPNP:=0 INCLUDEPATHS= \ - -I"C:\boost-1.43.0-mgw" \ - -I"C:\db-4.7.25.NC-mgw\build_unix" \ - -I"C:\openssl-1.0.0d-mgw\include" \ - -I"C:\wxWidgets-2.9.1-mgw\lib\gcc_lib\mswud" \ - -I"C:\wxWidgets-2.9.1-mgw\include" + -I"C:\boost-1.47.0-mgw" \ + -I"C:\db-4.8.30.NC-mgw\build_unix" \ + -I"C:\openssl-1.0.0d-mgw\include" LIBPATHS= \ - -L"C:\boost-1.43.0-mgw\stage\lib" \ - -L"C:\db-4.7.25.NC-mgw\build_unix" \ - -L"C:\openssl-1.0.0d-mgw" \ - -L"C:\wxWidgets-2.9.1-mgw\lib\gcc_lib" - -WXLIBS= \ - -l wxmsw29ud_html -l wxmsw29ud_core -l wxmsw29ud_adv -l wxbase29ud -l wxtiffd -l wxjpegd -l wxpngd -l wxzlibd + -L"C:\boost-1.47.0-mgw\stage\lib" \ + -L"C:\db-4.8.30.NC-mgw\build_unix" \ + -L"C:\openssl-1.0.0d-mgw" LIBS= \ - -l boost_system-mgw45-mt-s-1_43 \ - -l boost_filesystem-mgw45-mt-s-1_43 \ - -l boost_program_options-mgw45-mt-s-1_43 \ - -l boost_thread-mgw45-mt-s-1_43 \ + -l boost_system-mgw45-mt-s-1_47 \ + -l boost_filesystem-mgw45-mt-s-1_47 \ + -l boost_program_options-mgw45-mt-s-1_47 \ + -l boost_thread-mgw45-mt-s-1_47 \ -l db_cxx \ -l ssl \ -l crypto -DEFS=-DWIN32 -D__WXMSW__ -D_WINDOWS -DNOPCH -DUSE_SSL -DEBUGFLAGS=-g -D__WXDEBUG__ +DEFS=-DWIN32 -D_WINDOWS -DNOPCH -DUSE_SSL -DBOOST_THREAD_USE_LIB +DEBUGFLAGS=-g CFLAGS=-mthreads -O2 -w -Wno-invalid-offsetof -Wformat $(DEBUGFLAGS) $(DEFS) $(INCLUDEPATHS) -HEADERS=headers.h strlcpy.h serialize.h uint256.h util.h key.h bignum.h base58.h \ - script.h db.h net.h irc.h keystore.h main.h wallet.h rpc.h uibase.h ui.h noui.h init.h +HEADERS = \ + base58.h \ + bignum.h \ + crypter.h \ + db.h \ + headers.h \ + init.h \ + irc.h \ + key.h \ + keystore.h \ + main.h \ + net.h \ + noui.h \ + protocol.h \ + bitcoinrpc.h \ + script.h \ + serialize.h \ + strlcpy.h \ + uint256.h \ + util.h \ + wallet.h ifdef USE_UPNP - INCLUDEPATHS += -I"C:\upnpc-exe-win32-20110215" - LIBPATHS += -L"C:\upnpc-exe-win32-20110215" + INCLUDEPATHS += -I"C:\miniupnpc-1.6-mgw" + LIBPATHS += -L"C:\miniupnpc-1.6-mgw" LIBS += -l miniupnpc -l iphlpapi DEFS += -DSTATICLIB -DUSE_UPNP=$(USE_UPNP) endif @@ -45,35 +58,21 @@ endif LIBS += -l kernel32 -l user32 -l gdi32 -l comdlg32 -l winspool -l winmm -l shell32 -l comctl32 -l ole32 -l oleaut32 -l uuid -l rpcrt4 -l advapi32 -l ws2_32 -l shlwapi OBJS= \ - obj/util.o \ - obj/script.o \ + obj/crypter.o \ obj/db.o \ - obj/net.o \ + obj/init.o \ obj/irc.o \ obj/keystore.o \ obj/main.o \ - obj/wallet.o \ - obj/rpc.o \ - obj/init.o \ - cryptopp/obj/sha.o \ - cryptopp/obj/cpu.o - - -all: bitcoin.exe - - -obj/%.o: %.cpp $(HEADERS) - g++ -c $(CFLAGS) -DGUI -o $@ $< - -cryptopp/obj/%.o: cryptopp/%.cpp - g++ -c $(CFLAGS) -O3 -DCRYPTOPP_X86_ASM_AVAILABLE -o $@ $< - -obj/ui_res.o: ../share/ui.rc ../share/pixmaps/bitcoin.ico ../share/pixmaps/check.ico ../share/pixmaps/send16.bmp ../share/pixmaps/send16mask.bmp ../share/pixmaps/send16masknoshadow.bmp ../share/pixmaps/send20.bmp ../share/pixmaps/send20mask.bmp ../share/pixmaps/addressbook16.bmp ../share/pixmaps/addressbook16mask.bmp ../share/pixmaps/addressbook20.bmp ../share/pixmaps/addressbook20mask.bmp - windres $(DEFS) $(INCLUDEPATHS) -o $@ -i $< + obj/net.o \ + obj/protocol.o \ + obj/bitcoinrpc.o \ + obj/script.o \ + obj/util.o \ + obj/wallet.o -bitcoin.exe: $(OBJS) obj/ui.o obj/uibase.o obj/ui_res.o - g++ $(CFLAGS) -mwindows -Wl,--subsystem,windows -o $@ $(LIBPATHS) $^ $(WXLIBS) $(LIBS) +all: bitcoind.exe obj/nogui/%.o: %.cpp $(HEADERS) g++ -c $(CFLAGS) -o $@ $< @@ -81,17 +80,16 @@ obj/nogui/%.o: %.cpp $(HEADERS) bitcoind.exe: $(OBJS:obj/%=obj/nogui/%) obj/ui_res.o g++ $(CFLAGS) -o $@ $(LIBPATHS) $^ $(LIBS) -obj/test/%.o: obj/test/%.cpp $(HEADERS) - g++ -c $(CFLAGS) -o $@ $< +obj/test/test_bitcoin.o: $(wildcard test/*.cpp) $(HEADERS) + g++ -c $(CFLAGS) -o $@ test/test_bitcoin.cpp -test_bitcoin: obj/test/test_bitcoin.o +test_bitcoin.exe: obj/test/test_bitcoin.o $(filter-out obj/nogui/init.o,$(OBJS:obj/%=obj/nogui/%)) g++ $(CFLAGS) -o $@ $(LIBPATHS) $^ $(LIBS) clean: - -del /Q bitcoin bitcoind test_bitcoin + -del /Q bitcoind test_bitcoin -del /Q obj\* -del /Q obj\nogui\* -del /Q obj\test\* - -del /Q cryptopp\obj\* -del /Q test\*.o -del /Q headers.h.gch diff --git a/src/makefile.osx b/src/makefile.osx index 784596b72d..74af308759 100644 --- a/src/makefile.osx +++ b/src/makefile.osx @@ -1,88 +1,111 @@ -# Copyright (c) 2010 Laszlo Hanyecz +# -*- mode: Makefile; -*- +# Copyright (c) 2011 Bitcoin Developers # Distributed under the MIT/X11 software license, see the accompanying # file license.txt or http://www.opensource.org/licenses/mit-license.php. # Mac OS X makefile for bitcoin -# Laszlo Hanyecz (solar@heliacal.net) +# Originally by Laszlo Hanyecz (solar@heliacal.net) CXX=llvm-g++ -DEPSDIR=/Users/macosuser/bitcoin/deps +DEPSDIR=/opt/local INCLUDEPATHS= \ - -I"$(DEPSDIR)/include" + -I"$(DEPSDIR)/include" \ + -I"$(DEPSDIR)/include/db48" LIBPATHS= \ - -L"$(DEPSDIR)/lib" + -L"$(DEPSDIR)/lib" \ + -L"$(DEPSDIR)/lib/db48" -WXLIBS=$(shell $(DEPSDIR)/bin/wx-config --libs --static) - -USE_UPNP:=0 +USE_UPNP:=1 LIBS= -dead_strip \ - $(DEPSDIR)/lib/libdb_cxx-4.8.a \ - $(DEPSDIR)/lib/libboost_system.a \ - $(DEPSDIR)/lib/libboost_filesystem.a \ - $(DEPSDIR)/lib/libboost_program_options.a \ - $(DEPSDIR)/lib/libboost_thread.a \ - $(DEPSDIR)/lib/libssl.a \ - $(DEPSDIR)/lib/libcrypto.a + -ldb_cxx-4.8 \ + -lboost_system-mt \ + -lboost_filesystem-mt \ + -lboost_program_options-mt \ + -lboost_thread-mt \ + -lssl \ + -lcrypto -DEFS=$(shell $(DEPSDIR)/bin/wx-config --cxxflags) -D__WXMAC_OSX__ -DNOPCH -DMSG_NOSIGNAL=0 -DUSE_SSL +DEFS=-DMSG_NOSIGNAL=0 -DUSE_SSL -DEBUGFLAGS=-g -DwxDEBUG_LEVEL=0 +DEBUGFLAGS=-g # ppc doesn't work because we don't support big-endian -CFLAGS=-mmacosx-version-min=10.5 -arch i386 -arch x86_64 -O3 -Wno-invalid-offsetof -Wformat $(DEBUGFLAGS) $(DEFS) $(INCLUDEPATHS) -HEADERS=headers.h strlcpy.h serialize.h uint256.h util.h key.h bignum.h base58.h \ - script.h db.h net.h irc.h keystore.h main.h wallet.h rpc.h uibase.h ui.h noui.h init.h +CFLAGS=-mmacosx-version-min=10.5 -arch i386 -O3 -Wno-invalid-offsetof -Wformat $(DEBUGFLAGS) $(DEFS) $(INCLUDEPATHS) +HEADERS = \ + base58.h \ + bignum.h \ + crypter.h \ + db.h \ + headers.h \ + init.h \ + irc.h \ + key.h \ + keystore.h \ + main.h \ + net.h \ + noui.h \ + protocol.h \ + bitcoinrpc.h \ + script.h \ + serialize.h \ + strlcpy.h \ + uint256.h \ + util.h \ + wallet.h OBJS= \ - obj/util.o \ - obj/script.o \ + obj/crypter.o \ obj/db.o \ - obj/net.o \ + obj/init.o \ obj/irc.o \ obj/keystore.o \ obj/main.o \ - obj/wallet.o \ - obj/rpc.o \ - obj/init.o \ - cryptopp/obj/sha.o \ - cryptopp/obj/cpu.o + obj/net.o \ + obj/protocol.o \ + obj/bitcoinrpc.o \ + obj/script.o \ + obj/util.o \ + obj/wallet.o ifdef USE_UPNP - LIBS += $(DEPSDIR)/lib/libminiupnpc.a + LIBS += -lminiupnpc DEFS += -DUSE_UPNP=$(USE_UPNP) endif -all: bitcoin - - -obj/%.o: %.cpp $(HEADERS) - $(CXX) -c $(CFLAGS) -DGUI -o $@ $< - -cryptopp/obj/%.o: cryptopp/%.cpp - $(CXX) -c $(CFLAGS) -O3 -DCRYPTOPP_DISABLE_ASM -o $@ $< - -bitcoin: $(OBJS) obj/ui.o obj/uibase.o - $(CXX) $(CFLAGS) -o $@ $(LIBPATHS) $^ $(WXLIBS) $(LIBS) +all: bitcoind +# auto-generated dependencies: +-include obj/nogui/*.P +-include obj/test/*.P -obj/nogui/%.o: %.cpp $(HEADERS) - $(CXX) -c $(CFLAGS) -o $@ $< +obj/nogui/%.o: %.cpp + $(CXX) -c $(CFLAGS) -MMD -o $@ $< + @cp $(@:%.o=%.d) $(@:%.o=%.P); \ + sed -e 's/#.*//' -e 's/^[^:]*: *//' -e 's/ *\\$$//' \ + -e '/^$$/ d' -e 's/$$/ :/' < $(@:%.o=%.d) >> $(@:%.o=%.P); \ + rm -f $(@:%.o=%.d) bitcoind: $(OBJS:obj/%=obj/nogui/%) $(CXX) $(CFLAGS) -o $@ $(LIBPATHS) $^ $(LIBS) -obj/test/%.o: test/%.cpp $(HEADERS) - $(CXX) -c $(CFLAGS) -o $@ $< +obj/test/%.o: test/%.cpp + $(CXX) -c $(CFLAGS) -MMD -o $@ $< + @cp $(@:%.o=%.d) $(@:%.o=%.P); \ + sed -e 's/#.*//' -e 's/^[^:]*: *//' -e 's/ *\\$$//' \ + -e '/^$$/ d' -e 's/$$/ :/' < $(@:%.o=%.d) >> $(@:%.o=%.P); \ + rm -f $(@:%.o=%.d) -test_bitcoin: obj/test/test_bitcoin.o - $(CXX) $(CFLAGS) -o $@ $(LIBPATHS) $^ $(LIBS) -lboost_unit_test_framework +test_bitcoin: obj/test/test_bitcoin.o $(filter-out obj/nogui/init.o,$(OBJS:obj/%=obj/nogui/%)) + $(CXX) $(CFLAGS) -o $@ $(LIBPATHS) $^ $(LIBS) $(DEPSDIR)/lib/libboost_unit_test_framework-mt.a clean: - -rm -f bitcoin bitcoind test_bitcoin + -rm -f bitcoind test_bitcoin -rm -f obj/*.o -rm -f obj/nogui/*.o -rm -f obj/test/*.o - -rm -f cryptopp/obj/*.o + -rm -f obj/*.P + -rm -f obj/nogui/*.P + -rm -f obj/test/*.P diff --git a/src/makefile.unix b/src/makefile.unix index bb26bf5edd..1ef7caaad7 100644 --- a/src/makefile.unix +++ b/src/makefile.unix @@ -4,13 +4,9 @@ CXX=g++ -WXINCLUDEPATHS=$(shell wx-config --cxxflags) - -WXLIBS=$(shell wx-config --libs) - USE_UPNP:=0 -DEFS=-DNOPCH -DFOURWAYSSE2 -DUSE_SSL +DEFS=-DNOPCH -DUSE_SSL # for boost 1.37, add -mt to the boost libraries LIBS= \ @@ -36,55 +32,104 @@ LIBS+= \ -l pthread -DEBUGFLAGS=-g -D__WXDEBUG__ -CXXFLAGS=-O2 -Wno-invalid-offsetof -Wformat $(DEBUGFLAGS) $(DEFS) -HEADERS=headers.h strlcpy.h serialize.h uint256.h util.h key.h bignum.h base58.h \ - script.h db.h net.h irc.h keystore.h main.h wallet.h rpc.h uibase.h ui.h noui.h init.h +# Hardening +# Make some classes of vulnerabilities unexploitable in case one is discovered. +# + # Stack Canaries + # Put numbers at the beginning of each stack frame and check that they are the same. + # If a stack buffer if overflowed, it writes over the canary number and then on return + # when that number is checked, it won't be the same and the program will exit with + # a "Stack smashing detected" error instead of being exploited. + HARDENING=-fstack-protector-all -Wstack-protector + + # Make some important things such as the global offset table read only as soon as + # the dynamic linker is finished building it. This will prevent overwriting of addresses + # which would later be jumped to. + HARDENING+=-Wl,-z,relro -Wl,-z,now + + # Build position independent code to take advantage of Address Space Layout Randomization + # offered by some kernels. + # see doc/build-unix.txt for more information. + ifdef PIE + HARDENING+=-fPIE -pie + endif + + # -D_FORTIFY_SOURCE=2 does some checking for potentially exploitable code patterns in + # the source such overflowing a statically defined buffer. + HARDENING+=-D_FORTIFY_SOURCE=2 +# + + +DEBUGFLAGS=-g +CXXFLAGS=-O2 -Wno-invalid-offsetof -Wformat $(DEBUGFLAGS) $(DEFS) $(HARDENING) +HEADERS = \ + base58.h \ + bignum.h \ + crypter.h \ + db.h \ + headers.h \ + init.h \ + irc.h \ + key.h \ + keystore.h \ + main.h \ + net.h \ + noui.h \ + protocol.h \ + bitcoinrpc.h \ + script.h \ + serialize.h \ + strlcpy.h \ + uint256.h \ + util.h \ + wallet.h OBJS= \ - obj/util.o \ - obj/script.o \ + obj/crypter.o \ obj/db.o \ - obj/net.o \ + obj/init.o \ obj/irc.o \ obj/keystore.o \ obj/main.o \ - obj/wallet.o \ - obj/rpc.o \ - obj/init.o \ - cryptopp/obj/sha.o \ - cryptopp/obj/cpu.o - - -all: bitcoin - - -obj/%.o: %.cpp $(HEADERS) - $(CXX) -c $(CXXFLAGS) $(WXINCLUDEPATHS) -DGUI -o $@ $< + obj/net.o \ + obj/protocol.o \ + obj/bitcoinrpc.o \ + obj/script.o \ + obj/util.o \ + obj/wallet.o -cryptopp/obj/%.o: cryptopp/%.cpp - $(CXX) -c $(CXXFLAGS) -O3 -o $@ $< -bitcoin: $(OBJS) obj/ui.o obj/uibase.o - $(CXX) $(CXXFLAGS) -o $@ $^ $(WXLIBS) $(LIBS) +all: bitcoind +# auto-generated dependencies: +-include obj/nogui/*.P +-include obj/test/*.P -obj/nogui/%.o: %.cpp $(HEADERS) - $(CXX) -c $(CXXFLAGS) -o $@ $< +obj/nogui/%.o: %.cpp + $(CXX) -c $(CXXFLAGS) -MMD -o $@ $< + @cp $(@:%.o=%.d) $(@:%.o=%.P); \ + sed -e 's/#.*//' -e 's/^[^:]*: *//' -e 's/ *\\$$//' \ + -e '/^$$/ d' -e 's/$$/ :/' < $(@:%.o=%.d) >> $(@:%.o=%.P); \ + rm -f $(@:%.o=%.d) bitcoind: $(OBJS:obj/%=obj/nogui/%) $(CXX) $(CXXFLAGS) -o $@ $^ $(LIBS) -obj/test/%.o: test/%.cpp $(HEADERS) - $(CXX) -c $(CFLAGS) -o $@ $< +obj/test/%.o: test/%.cpp + $(CXX) -c $(CXXFLAGS) -MMD -o $@ $< + @cp $(@:%.o=%.d) $(@:%.o=%.P); \ + sed -e 's/#.*//' -e 's/^[^:]*: *//' -e 's/ *\\$$//' \ + -e '/^$$/ d' -e 's/$$/ :/' < $(@:%.o=%.d) >> $(@:%.o=%.P); \ + rm -f $(@:%.o=%.d) -test_bitcoin: obj/test/test_bitcoin.o - $(CXX) $(CFLAGS) -o $@ $(LIBPATHS) $^ $(LIBS) -lboost_unit_test_framework +test_bitcoin: obj/test/test_bitcoin.o $(filter-out obj/nogui/init.o,$(OBJS:obj/%=obj/nogui/%)) + $(CXX) $(CXXFLAGS) -o $@ $(LIBPATHS) $^ -Wl,-Bstatic -lboost_unit_test_framework $(LIBS) clean: - -rm -f bitcoin bitcoind test_bitcoin + -rm -f bitcoind test_bitcoin -rm -f obj/*.o -rm -f obj/nogui/*.o -rm -f obj/test/*.o - -rm -f cryptopp/obj/*.o - -rm -f headers.h.gch + -rm -f obj/*.P + -rm -f obj/nogui/*.P + -rm -f obj/test/*.P diff --git a/src/makefile.vc b/src/makefile.vc index b25ba60c50..c7e8578a95 100644 --- a/src/makefile.vc +++ b/src/makefile.vc @@ -7,25 +7,20 @@ INCLUDEPATHS= \ /I"/boost" \ /I"/db/build_windows" \ /I"/openssl/include" \ - /I"/wxwidgets/lib/vc_lib/mswu" \ - /I"/wxwidgets/include" / /I"/miniupnpc" LIBPATHS= \ /LIBPATH:"/boost/stage/lib" \ /LIBPATH:"/db/build_windows/Release" \ /LIBPATH:"/openssl/lib" \ - /LIBPATH:"/wxwidgets/lib/vc_lib" \ /LIBPATH:"/miniupnpc/msvc/Release" \ /NODEFAULTLIB:libc.lib /NODEFAULTLIB:libcmt.lib \ /NODEFAULTLIB:libcd.lib /NODEFAULTLIB:libcmtd.lib \ /NODEFAULTLIB:msvcrtd.lib -WXLIBS=wxmsw29u.lib wxtiff.lib wxjpeg.lib wxpng.lib wxzlib.lib - USE_UPNP=0 -DEFS=/DWIN32 /D__WXMSW__ /D_WINDOWS /DNOPCH /DNOMINMAX +DEFS=/DWIN32 /D_WINDOWS /DNOPCH /DNOMINMAX LIBS= \ libboost_system-vc100-mt.lib \ @@ -41,33 +36,52 @@ DEFS=$(DEFS) /DUSE_UPNP=$(USE_UPNP) !ENDIF LIBS=$(LIBS) \ - kernel32.lib user32.lib gdi32.lib comdlg32.lib winspool.lib winmm.lib shell32.lib comctl32.lib ole32.lib oleaut32.lib uuid.lib rpcrt4.lib advapi32.lib ws2_32.lib shlwapi.lib + kernel32.lib user32.lib gdi32.lib comdlg32.lib winspool.lib winmm.lib shell32.lib comctl32.lib ole32.lib oleaut32.lib uuid.lib rpcrt4.lib advapi32.lib ws2_32.lib shlwapi.lib iphlpapi.lib DEBUGFLAGS=/Os CFLAGS=/MD /c /nologo /EHsc /GR /Zm300 $(DEBUGFLAGS) $(DEFS) $(INCLUDEPATHS) -HEADERS=headers.h strlcpy.h serialize.h uint256.h util.h key.h bignum.h base58.h \ - script.h db.h net.h irc.h main.h rpc.h uibase.h ui.h noui.h init.h wallet.h keystore.h +HEADERS = \ + base58.h \ + bignum.h \ + crypter.h \ + db.h \ + headers.h \ + init.h \ + irc.h \ + key.h \ + keystore.h \ + main.h \ + net.h \ + noui.h \ + protocol.h \ + bitcoinrpc.h \ + script.h \ + serialize.h \ + strlcpy.h \ + ui.h \ + uibase.h \ + uint256.h \ + util.h \ + wallet.h OBJS= \ - obj\util.obj \ - obj\script.obj \ - obj\db.obj \ - obj\net.obj \ - obj\irc.obj \ - obj\keystore.obj \ - obj\main.obj \ - obj\wallet.obj \ - obj\rpc.obj \ - obj\init.obj - -CRYPTOPP_OBJS= \ - cryptopp\obj\sha.obj \ - cryptopp\obj\cpu.obj + obj\crypter.o \ + obj\db.o \ + obj\init.o \ + obj\irc.o \ + obj\keystore.o \ + obj\main.o \ + obj\net.o \ + obj\rpc.o \ + obj\protocol.o \ + obj\script.o \ + obj\util.o \ + obj\wallet.o RC=../share -all: bitcoin.exe +all: bitcoind.exe .cpp{obj}.obj: @@ -93,23 +107,12 @@ obj\rpc.obj: $(HEADERS) obj\init.obj: $(HEADERS) +obj\crypter.obj: $(HEADERS) + obj\ui.obj: $(HEADERS) obj\uibase.obj: $(HEADERS) -cryptopp\obj\sha.obj: cryptopp\sha.cpp - cl $(CFLAGS) /O2 /DCRYPTOPP_DISABLE_ASM /Fo$@ %s - -cryptopp\obj\cpu.obj: cryptopp\cpu.cpp - cl $(CFLAGS) /O2 /DCRYPTOPP_DISABLE_ASM /Fo$@ %s - -obj\ui.res: $(RC)/ui.rc $(RC)/pixmaps/bitcoin.ico $(RC)/pixmaps/check.ico $(RC)/pixmaps/send16.bmp $(RC)/pixmaps/send16mask.bmp $(RC)/pixmaps/send16masknoshadow.bmp $(RC)/pixmaps/send20.bmp $(RC)/pixmaps/send20mask.bmp $(RC)/pixmaps/addressbook16.bmp $(RC)/pixmaps/addressbook16mask.bmp $(RC)/pixmaps/addressbook20.bmp $(RC)/pixmaps/addressbook20mask.bmp - rc $(INCLUDEPATHS) $(DEFS) /Fo$@ %s - -bitcoin.exe: $(OBJS) $(CRYPTOPP_OBJS) obj\ui.obj obj\uibase.obj obj\ui.res - link /nologo /SUBSYSTEM:WINDOWS /OUT:$@ $(LIBPATHS) $** $(WXLIBS) $(LIBS) - - .cpp{obj\nogui}.obj: cl $(CFLAGS) /Fo$@ %s @@ -133,13 +136,12 @@ obj\nogui\rpc.obj: $(HEADERS) obj\nogui\init.obj: $(HEADERS) -bitcoind.exe: $(OBJS:obj\=obj\nogui\) $(CRYPTOPP_OBJS) obj\ui.res +bitcoind.exe: $(OBJS:obj\=obj\nogui\) obj\ui.res link /nologo /OUT:$@ $(LIBPATHS) $** $(LIBS) - clean: -del /Q obj\* -del /Q obj\nogui\* - -del /Q cryptopp\obj\* -del /Q *.ilk -del /Q *.pdb + -del /Q bitcoind.exe diff --git a/src/net.cpp b/src/net.cpp index 0d3348da72..0e861236df 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -1,4 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto +// Copyright (c) 2011 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. @@ -11,11 +12,6 @@ #ifdef __WXMSW__ #include <string.h> -// This file can be downloaded as a part of the Windows Platform SDK -// and is required for Bitcoin binaries to work properly on versions -// of Windows before XP. If you are doing builds of Bitcoin for -// public release, you should uncomment this line. -//#include <WSPiApi.h> #endif #ifdef USE_UPNP @@ -49,10 +45,10 @@ bool fClient = false; bool fAllowDNS = false; uint64 nLocalServices = (fClient ? 0 : NODE_NETWORK); CAddress addrLocalHost("0.0.0.0", 0, false, nLocalServices); -CNode* pnodeLocalHost = NULL; +static CNode* pnodeLocalHost = NULL; uint64 nLocalHostNonce = 0; array<int, 10> vnThreadsRunning; -SOCKET hListenSocket = INVALID_SOCKET; +static SOCKET hListenSocket = INVALID_SOCKET; vector<CNode*> vNodes; CCriticalSection cs_vNodes; @@ -98,7 +94,7 @@ bool ConnectSocket(const CAddress& addrConnect, SOCKET& hSocketRet, int nTimeout SOCKET hSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (hSocket == INVALID_SOCKET) return false; -#ifdef BSD +#ifdef SO_NOSIGPIPE int set = 1; setsockopt(hSocket, SOL_SOCKET, SO_NOSIGPIPE, (void*)&set, sizeof(int)); #endif @@ -440,13 +436,17 @@ void ThreadGetMyExternalIP(void* parg) -bool AddAddress(CAddress addr, int64 nTimePenalty) +bool AddAddress(CAddress addr, int64 nTimePenalty, CAddrDB *pAddrDB) { if (!addr.IsRoutable()) return false; if (addr.ip == addrLocalHost.ip) return false; addr.nTime = max((int64)0, (int64)addr.nTime - nTimePenalty); + bool fUpdated = false; + bool fNew = false; + CAddress addrFound = addr; + CRITICAL_BLOCK(cs_mapAddresses) { map<vector<unsigned char>, CAddress>::iterator it = mapAddresses.find(addr.GetKey()); @@ -455,13 +455,12 @@ bool AddAddress(CAddress addr, int64 nTimePenalty) // New address printf("AddAddress(%s)\n", addr.ToString().c_str()); mapAddresses.insert(make_pair(addr.GetKey(), addr)); - CAddrDB().WriteAddress(addr); - return true; + fUpdated = true; + fNew = true; } else { - bool fUpdated = false; - CAddress& addrFound = (*it).second; + addrFound = (*it).second; if ((addrFound.nServices | addr.nServices) != addrFound.nServices) { // Services have been added @@ -476,11 +475,22 @@ bool AddAddress(CAddress addr, int64 nTimePenalty) addrFound.nTime = addr.nTime; fUpdated = true; } - if (fUpdated) - CAddrDB().WriteAddress(addrFound); } } - return false; + // There is a nasty deadlock bug if this is done inside the cs_mapAddresses + // CRITICAL_BLOCK: + // Thread 1: begin db transaction (locks inside-db-mutex) + // then AddAddress (locks cs_mapAddresses) + // Thread 2: AddAddress (locks cs_mapAddresses) + // ... then db operation hangs waiting for inside-db-mutex + if (fUpdated) + { + if (pAddrDB) + pAddrDB->WriteAddress(addrFound); + else + CAddrDB().WriteAddress(addrFound); + } + return fNew; } void AddressCurrentlyConnected(const CAddress& addr) @@ -716,6 +726,52 @@ void CNode::Cleanup() } +std::map<unsigned int, int64> CNode::setBanned; +CCriticalSection CNode::cs_setBanned; + +void CNode::ClearBanned() +{ + setBanned.clear(); +} + +bool CNode::IsBanned(unsigned int ip) +{ + bool fResult = false; + CRITICAL_BLOCK(cs_setBanned) + { + std::map<unsigned int, int64>::iterator i = setBanned.find(ip); + if (i != setBanned.end()) + { + int64 t = (*i).second; + if (GetTime() < t) + fResult = true; + } + } + return fResult; +} + +bool CNode::Misbehaving(int howmuch) +{ + if (addr.IsLocal()) + { + printf("Warning: local node %s misbehaving\n", addr.ToString().c_str()); + return false; + } + + nMisbehavior += howmuch; + if (nMisbehavior >= GetArg("-banscore", 100)) + { + int64 banTime = GetTime()+GetArg("-bantime", 60*60*24); // Default 24-hour ban + CRITICAL_BLOCK(cs_setBanned) + if (setBanned[addr.ip] < banTime) + setBanned[addr.ip] = banTime; + CloseSocketDisconnect(); + printf("Disconnected %s for misbehavior (score=%d)\n", addr.ToString().c_str(), nMisbehavior); + return true; + } + return false; +} + @@ -831,7 +887,7 @@ void ThreadSocketHandler2(void* parg) { BOOST_FOREACH(CNode* pnode, vNodes) { - if (pnode->hSocket == INVALID_SOCKET || pnode->hSocket < 0) + if (pnode->hSocket == INVALID_SOCKET) continue; FD_SET(pnode->hSocket, &fdsetRecv); FD_SET(pnode->hSocket, &fdsetError); @@ -886,6 +942,11 @@ void ThreadSocketHandler2(void* parg) { closesocket(hSocket); } + else if (CNode::IsBanned(addr.ip)) + { + printf("connetion from %s dropped (banned)\n", addr.ToString().c_str()); + closesocket(hSocket); + } else { printf("accepted connection %s\n", addr.ToString().c_str()); @@ -1070,10 +1131,11 @@ void ThreadMapPort2(void* parg) const char * rootdescurl = 0; const char * multicastif = 0; const char * minissdpdpath = 0; + int error = 0; struct UPNPDev * devlist = 0; char lanaddr[64]; - devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0); + devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0, 0, &error); struct UPNPUrls urls; struct IGDdatas data; @@ -1084,14 +1146,10 @@ void ThreadMapPort2(void* parg) { char intClient[16]; char intPort[6]; - -#ifndef __WXMSW__ - r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype, - port, port, lanaddr, 0, "TCP", 0); -#else + string strDesc = "Bitcoin " + FormatFullVersion(); r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype, - port, port, lanaddr, 0, "TCP", 0, "0"); -#endif + port, port, lanaddr, strDesc.c_str(), "TCP", 0, "0"); + if(r!=UPNPCOMMAND_SUCCESS) printf("AddPortMapping(%s, %s, %s) failed with code %d (%s)\n", port, port, lanaddr, r, strupnperror(r)); @@ -1134,6 +1192,11 @@ void MapPort(bool fMapPort) printf("Error: ThreadMapPort(ThreadMapPort) failed\n"); } } +#else +void MapPort(bool /* unused fMapPort */) +{ + // Intentionally left blank. +} #endif @@ -1158,6 +1221,8 @@ void DNSAddressSeed() if (!fTestNet) { printf("Loading addresses from DNS seeds (could take a while)\n"); + CAddrDB addrDB; + addrDB.TxnBegin(); for (int seed_idx = 0; seed_idx < ARRAYLEN(strDNSSeed); seed_idx++) { vector<CAddress> vaddr; @@ -1168,12 +1233,14 @@ void DNSAddressSeed() if (addr.GetByte(3) != 127) { addr.nTime = 0; - AddAddress(addr); + AddAddress(addr, 0, &addrDB); found++; } } } } + + addrDB.TxnCommit(); // Save addresses (it's ok if this fails) } printf("%d addresses found from DNS seeds\n", found); @@ -1183,46 +1250,70 @@ void DNSAddressSeed() unsigned int pnSeed[] = { - 0x1ddb1032, 0x6242ce40, 0x52d6a445, 0x2dd7a445, 0x8a53cd47, 0x73263750, 0xda23c257, 0xecd4ed57, - 0x0a40ec59, 0x75dce160, 0x7df76791, 0x89370bad, 0xa4f214ad, 0x767700ae, 0x638b0418, 0x868a1018, - 0xcd9f332e, 0x0129653e, 0xcc92dc3e, 0x96671640, 0x56487e40, 0x5b66f440, 0xb1d01f41, 0xf1dc6041, - 0xc1d12b42, 0x86ba1243, 0x6be4df43, 0x6d4cef43, 0xd18e0644, 0x1ab0b344, 0x6584a345, 0xe7c1a445, - 0x58cea445, 0xc5daa445, 0x21dda445, 0x3d3b5346, 0x13e55347, 0x1080d24a, 0x8e611e4b, 0x81518e4b, - 0x6c839e4b, 0xe2ad0a4c, 0xfbbc0a4c, 0x7f5b6e4c, 0x7244224e, 0x1300554e, 0x20690652, 0x5a48b652, - 0x75c5c752, 0x4335cc54, 0x340fd154, 0x87c07455, 0x087b2b56, 0x8a133a57, 0xac23c257, 0x70374959, - 0xfb63d45b, 0xb9a1685c, 0x180d765c, 0x674f645d, 0x04d3495e, 0x1de44b5e, 0x4ee8a362, 0x0ded1b63, - 0xc1b04b6d, 0x8d921581, 0x97b7ea82, 0x1cf83a8e, 0x91490bad, 0x09dc75ae, 0x9a6d79ae, 0xa26d79ae, - 0x0fd08fae, 0x0f3e3fb2, 0x4f944fb2, 0xcca448b8, 0x3ecd6ab8, 0xa9d5a5bc, 0x8d0119c1, 0x045997d5, - 0xca019dd9, 0x0d526c4d, 0xabf1ba44, 0x66b1ab55, 0x1165f462, 0x3ed7cbad, 0xa38fae6e, 0x3bd2cbad, - 0xd36f0547, 0x20df7840, 0x7a337742, 0x549f8e4b, 0x9062365c, 0xd399f562, 0x2b5274a1, 0x8edfa153, - 0x3bffb347, 0x7074bf58, 0xb74fcbad, 0x5b5a795b, 0x02fa29ce, 0x5a6738d4, 0xe8a1d23e, 0xef98c445, - 0x4b0f494c, 0xa2bc1e56, 0x7694ad63, 0xa4a800c3, 0x05fda6cd, 0x9f22175e, 0x364a795b, 0x536285d5, - 0xac44c9d4, 0x0b06254d, 0x150c2fd4, 0x32a50dcc, 0xfd79ce48, 0xf15cfa53, 0x66c01e60, 0x6bc26661, - 0xc03b47ae, 0x4dda1b81, 0x3285a4c1, 0x883ca96d, 0x35d60a4c, 0xdae09744, 0x2e314d61, 0x84e247cf, - 0x6c814552, 0x3a1cc658, 0x98d8f382, 0xe584cb5b, 0x15e86057, 0x7b01504e, 0xd852dd48, 0x56382f56, - 0x0a5df454, 0xa0d18d18, 0x2e89b148, 0xa79c114c, 0xcbdcd054, 0x5523bc43, 0xa9832640, 0x8a066144, - 0x3894c3bc, 0xab76bf58, 0x6a018ac1, 0xfebf4f43, 0x2f26c658, 0x31102f4e, 0x85e929d5, 0x2a1c175e, - 0xfc6c2cd1, 0x27b04b6d, 0xdf024650, 0x161748b8, 0x28be6580, 0x57be6580, 0x1cee677a, 0xaa6bb742, - 0x9a53964b, 0x0a5a2d4d, 0x2434c658, 0x9a494f57, 0x1ebb0e48, 0xf610b85d, 0x077ecf44, 0x085128bc, - 0x5ba17a18, 0x27ca1b42, 0xf8a00b56, 0xfcd4c257, 0xcf2fc15e, 0xd897e052, 0x4cada04f, 0x2f35f6d5, - 0x382ce8c9, 0xe523984b, 0x3f946846, 0x60c8be43, 0x41da6257, 0xde0be142, 0xae8a544b, 0xeff0c254, - 0x1e0f795b, 0xaeb28890, 0xca16acd9, 0x1e47ddd8, 0x8c8c4829, 0xd27dc747, 0xd53b1663, 0x4096b163, - 0x9c8dd958, 0xcb12f860, 0x9e79305c, 0x40c1a445, 0x4a90c2bc, 0x2c3a464d, 0x2727f23c, 0x30b04b6d, - 0x59024cb8, 0xa091e6ad, 0x31b04b6d, 0xc29d46a6, 0x63934fb2, 0xd9224dbe, 0x9f5910d8, 0x7f530a6b, - 0x752e9c95, 0x65453548, 0xa484be46, 0xce5a1b59, 0x710e0718, 0x46a13d18, 0xdaaf5318, 0xc4a8ff53, - 0x87abaa52, 0xb764cf51, 0xb2025d4a, 0x6d351e41, 0xc035c33e, 0xa432c162, 0x61ef34ae, 0xd16fddbc, - 0x0870e8c1, 0x3070e8c1, 0x9c71e8c1, 0xa4992363, 0x85a1f663, 0x4184e559, 0x18d96ed8, 0x17b8dbd5, - 0x60e7cd18, 0xe5ee104c, 0xab17ac62, 0x1e786e1b, 0x5d23b762, 0xf2388fae, 0x88270360, 0x9e5b3d80, - 0x7da518b2, 0xb5613b45, 0x1ad41f3e, 0xd550854a, 0x8617e9a9, 0x925b229c, 0xf2e92542, 0x47af0544, - 0x73b5a843, 0xb9b7a0ad, 0x03a748d0, 0x0a6ff862, 0x6694df62, 0x3bfac948, 0x8e098f4f, 0x746916c3, - 0x02f38e4f, 0x40bb1243, 0x6a54d162, 0x6008414b, 0xa513794c, 0x514aa343, 0x63781747, 0xdbb6795b, - 0xed065058, 0x42d24b46, 0x1518794c, 0x9b271681, 0x73e4ffad, 0x0654784f, 0x438dc945, 0x641846a6, - 0x2d1b0944, 0x94b59148, 0x8d369558, 0xa5a97662, 0x8b705b42, 0xce9204ae, 0x8d584450, 0x2df61555, - 0xeebff943, 0x2e75fb4d, 0x3ef8fc57, 0x9921135e, 0x8e31042e, 0xb5afad43, 0x89ecedd1, 0x9cfcc047, - 0x8fcd0f4c, 0xbe49f5ad, 0x146a8d45, 0x98669ab8, 0x98d9175e, 0xd1a8e46d, 0x839a3ab8, 0x40a0016c, - 0x6d27c257, 0x977fffad, 0x7baa5d5d, 0x1213be43, 0xb167e5a9, 0x640fe8ca, 0xbc9ea655, 0x0f820a4c, - 0x0f097059, 0x69ac957c, 0x366d8453, 0xb1ba2844, 0x8857f081, 0x70b5be63, 0xc545454b, 0xaf36ded1, - 0xb5a4b052, 0x21f062d1, 0x72ab89b2, 0x74a45318, 0x8312e6bc, 0xb916965f, 0x8aa7c858, 0xfe7effad, + 0x6884ac63, 0x3ffecead, 0x2919b953, 0x0942fe50, 0x7a1d922e, 0xcdd6734a, 0x953a5bb6, 0x2c46922e, + 0xe2a5f143, 0xaa39103a, 0xa06afa5c, 0x135ffd59, 0xe8e82863, 0xf61ef029, 0xf75f042e, 0x2b363532, + 0x29b2df42, 0x16b1f64e, 0xd46e281b, 0x5280bf58, 0x60372229, 0x1be58e4f, 0xa8496f45, 0x1fb1a057, + 0x756b3844, 0x3bb79445, 0x0b375518, 0xcccb0102, 0xb682bf2e, 0x46431c02, 0x3a81073a, 0xa3771f1f, + 0x213a121f, 0x85dc2c1b, 0x56b4323b, 0xb34e8945, 0x3c40b33d, 0xfa276418, 0x1f818d29, 0xebe1e344, + 0xf6160a18, 0xf4fa384a, 0x34b09558, 0xb882b543, 0xe3ce2253, 0x6abf56d8, 0xe91b1155, 0x688ee6ad, + 0x2efc6058, 0x4792cd47, 0x0c32f757, 0x4c813a46, 0x8c93644a, 0x37507444, 0x813ad218, 0xdac06d4a, + 0xe4c63e4b, 0x21a1ea3c, 0x8d88556f, 0x30e9173a, 0x041f681b, 0xdc77ba50, 0xc0072753, 0xceddd44f, + 0x052d1743, 0xe3c77a4a, 0x13981c3a, 0x5685d918, 0x3c0e4e70, 0x3e56fb54, 0xb676ae0c, 0xac93c859, + 0x22279f43, 0x975a4542, 0xe527f071, 0xea162f2e, 0x3c65a32e, 0x5be5713b, 0x961ec418, 0xb202922e, + 0x5ef7be50, 0xce49f53e, 0x05803b47, 0x8463b055, 0x78576153, 0x3ec2ae3a, 0x4bbd7118, 0xafcee043, + 0x56a3e8ba, 0x6174de4d, 0x8d01ba4b, 0xc9af564e, 0xdbc9c547, 0xa627474d, 0xdada9244, 0xd3b3083a, + 0x523e071f, 0xd6b96f18, 0xbd527c46, 0xdf2bbb4d, 0xd37b4a4b, 0x3a6a2158, 0xc064b055, 0x18a8e055, + 0xec4dae3b, 0x0540416c, 0x475b4fbe, 0x064803b2, 0x48e9f062, 0x2898524b, 0xd315ff43, 0xf786d247, + 0xc7ea2f3e, 0xc087f043, 0xc163354b, 0x8250284d, 0xed300029, 0xbf36e05c, 0x8eb3ae4c, 0xe7aa623e, + 0x7ced0274, 0xdd362c1b, 0x362b995a, 0xca26b629, 0x3fc41618, 0xb97b364e, 0xa05b8729, 0x0f5e3c43, + 0xdf942618, 0x6aeb9b5b, 0xbf04762e, 0xfaaeb118, 0x87579958, 0x76520044, 0xc2660c5b, 0x628b201b, + 0xf193932e, 0x1c0ad045, 0xff908346, 0x8da9d4da, 0xed201c1f, 0xa47a2b1b, 0x330007d4, 0x8ba1ed47, + 0xb2f02d44, 0x7db62c1b, 0x781c454b, 0xc0300029, 0xb7062a45, 0x88b52e3a, 0x78dd6b63, 0x1cb9b718, + 0x5d358e47, 0x59912c3b, 0x79607544, 0x5197f759, 0xc023be48, 0xd1013743, 0x0f354057, 0x8e3aac3b, + 0x4114693e, 0x22316318, 0xe27dda50, 0x878eac3b, 0x4948a21f, 0x5db7f24c, 0x8ccb6157, 0x26a5de18, + 0x0a11bd43, 0x27bb1e41, 0x60a7a951, 0x3e16b35e, 0x07888b53, 0x5648a853, 0x0149fe50, 0xd070a34f, + 0x6454c96d, 0xd6e54758, 0xa96dc152, 0x65447861, 0xf6bdf95e, 0x10400202, 0x2c29d483, 0x18174732, + 0x1d840618, 0x12e61818, 0x089d3f3c, 0x917e931f, 0xd1b0c90e, 0x25bd3c42, 0xeb05775b, 0x7d550c59, + 0x6cfacb01, 0xe4224444, 0xa41dd943, 0x0f5aa643, 0x5e33731b, 0x81036d50, 0x6f46a0d1, 0x7731be43, + 0x14840e18, 0xf1e8d059, 0x661d2b1f, 0x40a3201b, 0x9407b843, 0xedf0254d, 0x7bd1a5bc, 0x073dbe51, + 0xe864a97b, 0x2efd947b, 0xb9ca0e45, 0x4e2113ad, 0xcc305731, 0xd39ca63c, 0x733df918, 0xda172b1f, + 0xaa03b34d, 0x7230fd4d, 0xf1ce6e3a, 0x2e9fab43, 0xa4010750, 0xa928bd18, 0x6809be42, 0xb19de348, + 0xff956270, 0x0d795f51, 0xd2dec247, 0x6df5774b, 0xbac11f79, 0xdfb05c75, 0x887683d8, 0xa1e83632, + 0x2c0f7671, 0x28bcb65d, 0xac2a7545, 0x3eebfc60, 0x304ad7c4, 0xa215a462, 0xc86f0f58, 0xcfb92ebe, + 0x5e23ed82, 0xf506184b, 0xec0f19b7, 0x060c59ad, 0x86ee3174, 0x85380774, 0xa199a562, 0x02b507ae, + 0x33eb2163, 0xf2112b1f, 0xb702ba50, 0x131b9618, 0x90ccd04a, 0x08f3273b, 0xecb61718, 0x64b8b44d, + 0x182bf4dc, 0xc7b68286, 0x6e318d5f, 0xfdb03654, 0xb3272e54, 0xe014ad4b, 0x274e4a31, 0x7806375c, + 0xbc34a748, 0x1b5ad94a, 0x6b54d10e, 0x73e2ae6e, 0x5529d483, 0x8455a76d, 0x99c13f47, 0x1d811741, + 0xa9782a78, 0x0b00464d, 0x7266ea50, 0x532dab46, 0x33e1413e, 0x780d0c18, 0x0fb0854e, 0x03370155, + 0x2693042e, 0xfa3d824a, 0x2bb1681b, 0x37ea2a18, 0x7fb8414b, 0x32e0713b, 0xacf38d3f, 0xa282716f, + 0xb1a09d7b, 0xa04b764b, 0x83c94d18, 0x05ee4c6d, 0x0e795f51, 0x46984352, 0xf80fc247, 0x3fccb946, + 0xd7ae244b, 0x0a8e0a4c, 0x57b141bc, 0x3647bed1, 0x1431b052, 0x803a8bbb, 0xfc69056b, 0xf5991862, + 0x14963b2e, 0xd35d5dda, 0xc6c73574, 0xc8f1405b, 0x0ca4224d, 0xecd36071, 0xa9461754, 0xe7a0ed72, + 0x559e8346, 0x1c9beec1, 0xc786ea4a, 0x9561b44d, 0x9788074d, 0x1a69934f, 0x23c5614c, 0x07c79d4b, + 0xc7ee52db, 0xc72df351, 0xcb135e44, 0xa0988346, 0xc211fc4c, 0x87dec34b, 0x1381074d, 0x04a65cb7, + 0x4409083a, 0x4a407a4c, 0x92b8d37d, 0xacf50b4d, 0xa58aa5bc, 0x448f801f, 0x9c83762e, 0x6fd5734a, + 0xfe2d454b, 0x84144c55, 0x05190e4c, 0xb2151448, 0x63867a3e, 0x16099018, 0x9c010d3c, 0x962d8f3d, + 0xd51ee453, 0x9d86801f, 0x68e87b47, 0x6bf7bb73, 0x5fc7910e, 0x10d90118, 0x3db04442, 0x729d3e4b, + 0xc397d842, 0x57bb15ad, 0x72f31f4e, 0xc9380043, 0x2bb24e18, 0xd9b8ab50, 0xb786801f, 0xf4dc4847, + 0x85f4bb51, 0x4435995b, 0x5ba07e40, 0x2c57392e, 0x3628124b, 0x9839b64b, 0x6fe8b24d, 0xaddce847, + 0x75260e45, 0x0c572a43, 0xfea21902, 0xb9f9742e, 0x5a70d443, 0x8fc5910e, 0x868d4744, 0x56245e02, + 0xd7eb5f02, 0x35c12c1b, 0x4373034b, 0x8786554c, 0xa6facf18, 0x4b11a31f, 0x3570664e, 0x5a64bc42, + 0x0b03983f, 0x8f457e4c, 0x0fd874c3, 0xb6cf31b2, 0x2bbc2d4e, 0x146ca5b2, 0x9d00b150, 0x048a4153, + 0xca4dcd43, 0xc1607cca, 0x8234cf57, 0x9c7daead, 0x3dc07658, 0xea5c6e4c, 0xf1a0084e, 0x16d2ee53, + 0x1b849418, 0xfe913a47, 0x1e988f62, 0x208b644c, 0xc55ee980, 0xbdbce747, 0xf59a384e, 0x0f56091b, + 0x7417b745, 0x0c37344e, 0x2c62ab47, 0xf8533a4d, 0x8030084d, 0x76b93c4b, 0xda6ea0ad, 0x3c54f618, + 0x63b0de1f, 0x7370d858, 0x1a70bb4c, 0xdda63b2e, 0x60b2ba50, 0x1ba7d048, 0xbe1b2c1b, 0xabea5747, + 0x29ad2e4d, 0xe8cd7642, 0x66c80e18, 0x138bf34a, 0xc6145e44, 0x2586794c, 0x07bc5478, 0x0da0b14d, + 0x8f95354e, 0x9eb11c62, 0xa1545e46, 0x2e7a2602, 0x408c9c3d, 0x59065d55, 0xf51d1a4c, 0x3bbc6a4e, + 0xc71b2a2e, 0xcdaaa545, 0x17d659d0, 0x5202e7ad, 0xf1b68445, 0x93375961, 0xbd88a043, 0x066ad655, + 0x890f6318, 0x7b7dca47, 0x99bdd662, 0x3bb4fc53, 0x1231efdc, 0xc0a99444, 0x96bbea47, 0x61ed8748, + 0x27dfa73b, 0x8d4d1754, 0x3460042e, 0x551f0c4c, 0x8d0e0718, 0x162ddc53, 0x53231718, 0x1ecd65d0, + 0x944d28bc, 0x3b79d058, 0xaff97fbc, 0x4860006c, 0xc101c90e, 0xace41743, 0xa5975d4c, 0x5cc2703e, + 0xb55a4450, 0x02d18840, 0xee2765ae, 0xd6012fd5, 0x24c94d7d, 0x8c6eec47, 0x7520ba5d, 0x9e15e460, + 0x8510b04c, 0x75ec3847, 0x1dfa6661, 0xe172b3ad, 0x5744c90e, 0x52a0a152, 0x8d6fad18, 0x67b74b6d, + 0x93a089b2, 0x0f3ac5d5, 0xe5de1855, 0x43d25747, 0x4bad804a, 0x55b408d8, 0x60a36441, 0xf553e860, + 0xdb2fa2c8, 0x03152b32, 0xdd27a7d5, 0x3116a8b8, 0x0a1d708c, 0xeee2f13c, 0x6acf436f, 0xce6eb4ca, + 0x101cd3d9, 0x1c48a6b8, 0xe57d6f44, 0x93dcf562, }; @@ -1315,7 +1406,6 @@ void ThreadOpenConnections2(void* parg) CRITICAL_BLOCK(cs_mapAddresses) { // Add seed nodes if IRC isn't working - static bool fSeedUsed; bool fTOR = (fUseProxy && addrProxy.port == htons(9050)); if (mapAddresses.empty() && (GetTime() - nStart > 60 || fTOR) && !fTestNet) { @@ -1323,40 +1413,14 @@ void ThreadOpenConnections2(void* parg) { // It'll only connect to one or two seed nodes because once it connects, // it'll get a pile of addresses with newer timestamps. + // Seed nodes are given a random 'last seen time' of between one and two + // weeks ago. + const int64 nOneWeek = 7*24*60*60; CAddress addr; addr.ip = pnSeed[i]; - addr.nTime = 0; + addr.nTime = GetTime()-GetRand(nOneWeek)-nOneWeek; AddAddress(addr); } - fSeedUsed = true; - } - - if (fSeedUsed && mapAddresses.size() > ARRAYLEN(pnSeed) + 100) - { - // Disconnect seed nodes - set<unsigned int> setSeed(pnSeed, pnSeed + ARRAYLEN(pnSeed)); - static int64 nSeedDisconnected; - if (nSeedDisconnected == 0) - { - nSeedDisconnected = GetTime(); - CRITICAL_BLOCK(cs_vNodes) - BOOST_FOREACH(CNode* pnode, vNodes) - if (setSeed.count(pnode->addr.ip)) - pnode->fDisconnect = true; - } - - // Keep setting timestamps to 0 so they won't reconnect - if (GetTime() - nSeedDisconnected < 60 * 60) - { - BOOST_FOREACH(PAIRTYPE(const vector<unsigned char>, CAddress)& item, mapAddresses) - { - if (setSeed.count(item.second.ip) && item.second.nTime != 0) - { - item.second.nTime = 0; - CAddrDB().WriteAddress(item.second); - } - } - } } } @@ -1374,6 +1438,8 @@ void ThreadOpenConnections2(void* parg) BOOST_FOREACH(CNode* pnode, vNodes) setConnected.insert(pnode->addr.ip & 0x0000ffff); + int64 nANow = GetAdjustedTime(); + CRITICAL_BLOCK(cs_mapAddresses) { BOOST_FOREACH(const PAIRTYPE(vector<unsigned char>, CAddress)& item, mapAddresses) @@ -1381,8 +1447,8 @@ void ThreadOpenConnections2(void* parg) const CAddress& addr = item.second; if (!addr.IsIPv4() || !addr.IsValid() || setConnected.count(addr.ip & 0x0000ffff)) continue; - int64 nSinceLastSeen = GetAdjustedTime() - addr.nTime; - int64 nSinceLastTry = GetAdjustedTime() - addr.nLastTry; + int64 nSinceLastSeen = nANow - addr.nTime; + int64 nSinceLastTry = nANow - addr.nLastTry; // Randomize the order in a deterministic way, putting the standard port first int64 nRandomizer = (uint64)(nStart * 4951 + addr.nLastTry * 9567851 + addr.ip * 7789) % (2 * 60 * 60); @@ -1441,7 +1507,8 @@ bool OpenNetworkConnection(const CAddress& addrConnect) // if (fShutdown) return false; - if (addrConnect.ip == addrLocalHost.ip || !addrConnect.IsIPv4() || FindNode(addrConnect.ip)) + if (addrConnect.ip == addrLocalHost.ip || !addrConnect.IsIPv4() || + FindNode(addrConnect.ip) || CNode::IsBanned(addrConnect.ip)) return false; vnThreadsRunning[1]--; @@ -1566,7 +1633,7 @@ bool BindListenPort(string& strError) return false; } -#ifdef BSD +#ifdef SO_NOSIGPIPE // Different way of disabling SIGPIPE on BSD setsockopt(hListenSocket, SOL_SOCKET, SO_NOSIGPIPE, (void*)&nOne, sizeof(int)); #endif @@ -1700,7 +1767,8 @@ void StartNode(void* parg) printf("Error: CreateThread(ThreadIRCSeed) failed\n"); // Send and receive from sockets, accept connections - pthread_t hThreadSocketHandler = CreateThread(ThreadSocketHandler, NULL, true); + if (!CreateThread(ThreadSocketHandler, NULL)) + printf("Error: CreateThread(ThreadSocketHandler) failed\n"); // Initiate outbound connections if (!CreateThread(ThreadOpenConnections, NULL)) @@ -1,4 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto +// Copyright (c) 2011 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. #ifndef BITCOIN_NET_H @@ -6,15 +7,16 @@ #include <deque> #include <boost/array.hpp> +#include <boost/foreach.hpp> #include <openssl/rand.h> #ifndef __WXMSW__ #include <arpa/inet.h> #endif -class CMessageHeader; -class CAddress; -class CInv; +#include "protocol.h" + +class CAddrDB; class CRequestTracker; class CNode; class CBlockIndex; @@ -25,21 +27,13 @@ extern int nConnectTimeout; inline unsigned int ReceiveBufferSize() { return 1000*GetArg("-maxreceivebuffer", 10*1000); } inline unsigned int SendBufferSize() { return 1000*GetArg("-maxsendbuffer", 10*1000); } -inline unsigned short GetDefaultPort() { return fTestNet ? 18333 : 8333; } static const unsigned int PUBLISH_HOPS = 5; -enum -{ - NODE_NETWORK = (1 << 0), -}; - - - bool ConnectSocket(const CAddress& addrConnect, SOCKET& hSocketRet, int nTimeout=nConnectTimeout); bool Lookup(const char *pszName, std::vector<CAddress>& vaddr, int nServices, int nMaxSolutions, bool fAllowLookup = false, int portDefault = 0, bool fAllowPort = false); bool Lookup(const char *pszName, CAddress& addr, int nServices, bool fAllowLookup = false, int portDefault = 0, bool fAllowPort = false); bool GetMyExternalIP(unsigned int& ipRet); -bool AddAddress(CAddress addr, int64 nTimePenalty=0); +bool AddAddress(CAddress addr, int64 nTimePenalty=0, CAddrDB *pAddrDB=NULL); void AddressCurrentlyConnected(const CAddress& addr); CNode* FindNode(unsigned int ip); CNode* ConnectNode(CAddress addrConnect, int64 nTimeout=0); @@ -51,402 +45,12 @@ bool BindListenPort(std::string& strError=REF(std::string())); void StartNode(void* parg); bool StopNode(); - - - - - - - -// -// Message header -// (4) message start -// (12) command -// (4) size -// (4) checksum - -extern char pchMessageStart[4]; - -class CMessageHeader -{ -public: - enum { COMMAND_SIZE=12 }; - char pchMessageStart[sizeof(::pchMessageStart)]; - char pchCommand[COMMAND_SIZE]; - unsigned int nMessageSize; - unsigned int nChecksum; - - CMessageHeader() - { - memcpy(pchMessageStart, ::pchMessageStart, sizeof(pchMessageStart)); - memset(pchCommand, 0, sizeof(pchCommand)); - pchCommand[1] = 1; - nMessageSize = -1; - nChecksum = 0; - } - - CMessageHeader(const char* pszCommand, unsigned int nMessageSizeIn) - { - memcpy(pchMessageStart, ::pchMessageStart, sizeof(pchMessageStart)); - strncpy(pchCommand, pszCommand, COMMAND_SIZE); - nMessageSize = nMessageSizeIn; - nChecksum = 0; - } - - IMPLEMENT_SERIALIZE - ( - READWRITE(FLATDATA(pchMessageStart)); - READWRITE(FLATDATA(pchCommand)); - READWRITE(nMessageSize); - if (nVersion >= 209) - READWRITE(nChecksum); - ) - - std::string GetCommand() - { - if (pchCommand[COMMAND_SIZE-1] == 0) - return std::string(pchCommand, pchCommand + strlen(pchCommand)); - else - return std::string(pchCommand, pchCommand + COMMAND_SIZE); - } - - bool IsValid() - { - // Check start string - if (memcmp(pchMessageStart, ::pchMessageStart, sizeof(pchMessageStart)) != 0) - return false; - - // Check the command string for errors - for (char* p1 = pchCommand; p1 < pchCommand + COMMAND_SIZE; p1++) - { - if (*p1 == 0) - { - // Must be all zeros after the first zero - for (; p1 < pchCommand + COMMAND_SIZE; p1++) - if (*p1 != 0) - return false; - } - else if (*p1 < ' ' || *p1 > 0x7E) - return false; - } - - // Message size - if (nMessageSize > MAX_SIZE) - { - printf("CMessageHeader::IsValid() : (%s, %u bytes) nMessageSize > MAX_SIZE\n", GetCommand().c_str(), nMessageSize); - return false; - } - - return true; - } -}; - - - - - - -static const unsigned char pchIPv4[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff }; - -class CAddress -{ -public: - uint64 nServices; - unsigned char pchReserved[12]; - unsigned int ip; - unsigned short port; - - // disk and network only - unsigned int nTime; - - // memory only - unsigned int nLastTry; - - CAddress() - { - Init(); - } - - CAddress(unsigned int ipIn, unsigned short portIn=0, uint64 nServicesIn=NODE_NETWORK) - { - Init(); - ip = ipIn; - port = htons(portIn == 0 ? GetDefaultPort() : portIn); - nServices = nServicesIn; - } - - explicit CAddress(const struct sockaddr_in& sockaddr, uint64 nServicesIn=NODE_NETWORK) - { - Init(); - ip = sockaddr.sin_addr.s_addr; - port = sockaddr.sin_port; - nServices = nServicesIn; - } - - explicit CAddress(const char* pszIn, int portIn, bool fNameLookup = false, uint64 nServicesIn=NODE_NETWORK) - { - Init(); - Lookup(pszIn, *this, nServicesIn, fNameLookup, portIn); - } - - explicit CAddress(const char* pszIn, bool fNameLookup = false, uint64 nServicesIn=NODE_NETWORK) - { - Init(); - Lookup(pszIn, *this, nServicesIn, fNameLookup, 0, true); - } - - explicit CAddress(std::string strIn, int portIn, bool fNameLookup = false, uint64 nServicesIn=NODE_NETWORK) - { - Init(); - Lookup(strIn.c_str(), *this, nServicesIn, fNameLookup, portIn); - } - - explicit CAddress(std::string strIn, bool fNameLookup = false, uint64 nServicesIn=NODE_NETWORK) - { - Init(); - Lookup(strIn.c_str(), *this, nServicesIn, fNameLookup, 0, true); - } - - void Init() - { - nServices = NODE_NETWORK; - memcpy(pchReserved, pchIPv4, sizeof(pchReserved)); - ip = INADDR_NONE; - port = htons(GetDefaultPort()); - nTime = 100000000; - nLastTry = 0; - } - - IMPLEMENT_SERIALIZE - ( - if (fRead) - const_cast<CAddress*>(this)->Init(); - if (nType & SER_DISK) - READWRITE(nVersion); - if ((nType & SER_DISK) || (nVersion >= 31402 && !(nType & SER_GETHASH))) - READWRITE(nTime); - READWRITE(nServices); - READWRITE(FLATDATA(pchReserved)); // for IPv6 - READWRITE(ip); - READWRITE(port); - ) - - friend inline bool operator==(const CAddress& a, const CAddress& b) - { - return (memcmp(a.pchReserved, b.pchReserved, sizeof(a.pchReserved)) == 0 && - a.ip == b.ip && - a.port == b.port); - } - - friend inline bool operator!=(const CAddress& a, const CAddress& b) - { - return (!(a == b)); - } - - friend inline bool operator<(const CAddress& a, const CAddress& b) - { - int ret = memcmp(a.pchReserved, b.pchReserved, sizeof(a.pchReserved)); - if (ret < 0) - return true; - else if (ret == 0) - { - if (ntohl(a.ip) < ntohl(b.ip)) - return true; - else if (a.ip == b.ip) - return ntohs(a.port) < ntohs(b.port); - } - return false; - } - - std::vector<unsigned char> GetKey() const - { - CDataStream ss; - ss.reserve(18); - ss << FLATDATA(pchReserved) << ip << port; - - #if defined(_MSC_VER) && _MSC_VER < 1300 - return std::vector<unsigned char>((unsigned char*)&ss.begin()[0], (unsigned char*)&ss.end()[0]); - #else - return std::vector<unsigned char>(ss.begin(), ss.end()); - #endif - } - - struct sockaddr_in GetSockAddr() const - { - struct sockaddr_in sockaddr; - memset(&sockaddr, 0, sizeof(sockaddr)); - sockaddr.sin_family = AF_INET; - sockaddr.sin_addr.s_addr = ip; - sockaddr.sin_port = port; - return sockaddr; - } - - bool IsIPv4() const - { - return (memcmp(pchReserved, pchIPv4, sizeof(pchIPv4)) == 0); - } - - bool IsRFC1918() const - { - return IsIPv4() && (GetByte(3) == 10 || - (GetByte(3) == 192 && GetByte(2) == 168) || - (GetByte(3) == 172 && - (GetByte(2) >= 16 && GetByte(2) <= 31))); - } - - bool IsRFC3927() const - { - return IsIPv4() && (GetByte(3) == 169 && GetByte(2) == 254); - } - - bool IsLocal() const - { - return IsIPv4() && (GetByte(3) == 127 || - GetByte(3) == 0); - } - - bool IsRoutable() const - { - return IsValid() && - !(IsRFC1918() || IsRFC3927() || IsLocal()); - } - - bool IsValid() const - { - // Clean up 3-byte shifted addresses caused by garbage in size field - // of addr messages from versions before 0.2.9 checksum. - // Two consecutive addr messages look like this: - // header20 vectorlen3 addr26 addr26 addr26 header20 vectorlen3 addr26 addr26 addr26... - // so if the first length field is garbled, it reads the second batch - // of addr misaligned by 3 bytes. - if (memcmp(pchReserved, pchIPv4+3, sizeof(pchIPv4)-3) == 0) - return false; - - return (ip != 0 && ip != INADDR_NONE && port != htons(USHRT_MAX)); - } - - unsigned char GetByte(int n) const - { - return ((unsigned char*)&ip)[3-n]; - } - - std::string ToStringIPPort() const - { - return strprintf("%u.%u.%u.%u:%u", GetByte(3), GetByte(2), GetByte(1), GetByte(0), ntohs(port)); - } - - std::string ToStringIP() const - { - return strprintf("%u.%u.%u.%u", GetByte(3), GetByte(2), GetByte(1), GetByte(0)); - } - - std::string ToStringPort() const - { - return strprintf("%u", ntohs(port)); - } - - std::string ToString() const - { - return strprintf("%u.%u.%u.%u:%u", GetByte(3), GetByte(2), GetByte(1), GetByte(0), ntohs(port)); - } - - void print() const - { - printf("CAddress(%s)\n", ToString().c_str()); - } -}; - - - - - - - enum { MSG_TX = 1, MSG_BLOCK, }; -static const char* ppszTypeName[] = -{ - "ERROR", - "tx", - "block", -}; - -class CInv -{ -public: - int type; - uint256 hash; - - CInv() - { - type = 0; - hash = 0; - } - - CInv(int typeIn, const uint256& hashIn) - { - type = typeIn; - hash = hashIn; - } - - CInv(const std::string& strType, const uint256& hashIn) - { - int i; - for (i = 1; i < ARRAYLEN(ppszTypeName); i++) - { - if (strType == ppszTypeName[i]) - { - type = i; - break; - } - } - if (i == ARRAYLEN(ppszTypeName)) - throw std::out_of_range(strprintf("CInv::CInv(string, uint256) : unknown type '%s'", strType.c_str())); - hash = hashIn; - } - - IMPLEMENT_SERIALIZE - ( - READWRITE(type); - READWRITE(hash); - ) - - friend inline bool operator<(const CInv& a, const CInv& b) - { - return (a.type < b.type || (a.type == b.type && a.hash < b.hash)); - } - - bool IsKnownType() const - { - return (type >= 1 && type < ARRAYLEN(ppszTypeName)); - } - - const char* GetCommand() const - { - if (!IsKnownType()) - throw std::out_of_range(strprintf("CInv::GetCommand() : type=%d unknown type", type)); - return ppszTypeName[type]; - } - - std::string ToString() const - { - return strprintf("%s %s", GetCommand(), hash.ToString().substr(0,20).c_str()); - } - - void print() const - { - printf("CInv(%s)\n", ToString().c_str()); - } -}; - - - - - class CRequestTracker { public: @@ -473,10 +77,8 @@ extern bool fClient; extern bool fAllowDNS; extern uint64 nLocalServices; extern CAddress addrLocalHost; -extern CNode* pnodeLocalHost; extern uint64 nLocalHostNonce; extern boost::array<int, 10> vnThreadsRunning; -extern SOCKET hListenSocket; extern std::vector<CNode*> vNodes; extern CCriticalSection cs_vNodes; @@ -522,6 +124,13 @@ public: bool fDisconnect; protected: int nRefCount; + + // Denial-of-service detection/prevention + // Key is ip address, value is banned-until-time + static std::map<unsigned int, int64> setBanned; + static CCriticalSection cs_setBanned; + int nMisbehavior; + public: int64 nReleaseTime; std::map<uint256, CRequestTracker> mapRequests; @@ -546,7 +155,6 @@ public: // publish and subscription std::vector<char> vfSubscribe; - CNode(SOCKET hSocketIn, CAddress addrIn, bool fInboundIn=false) { nServices = 0; @@ -583,6 +191,7 @@ public: nStartingHeight = -1; fGetAddr = false; vfSubscribe.assign(256, false); + nMisbehavior = 0; // Be shy and don't send version until we hear if (!fInbound) @@ -674,15 +283,16 @@ public: void BeginMessage(const char* pszCommand) { - cs_vSend.Enter(); + cs_vSend.Enter("cs_vSend", __FILE__, __LINE__); if (nHeaderStart != -1) AbortMessage(); nHeaderStart = vSend.size(); vSend << CMessageHeader(pszCommand, 0); nMessageStart = vSend.size(); - if (fDebug) + if (fDebug) { printf("%s ", DateTimeStrFormat("%x %H:%M:%S", GetTime()).c_str()); - printf("sending: %s ", pszCommand); + printf("sending: %s ", pszCommand); + } } void AbortMessage() @@ -693,7 +303,9 @@ public: nHeaderStart = -1; nMessageStart = -1; cs_vSend.Leave(); - printf("(aborted)\n"); + + if (fDebug) + printf("(aborted)\n"); } void EndMessage() @@ -722,8 +334,9 @@ public: memcpy((char*)&vSend[nHeaderStart] + offsetof(CMessageHeader, nChecksum), &nChecksum, sizeof(nChecksum)); } - printf("(%d bytes) ", nSize); - printf("\n"); + if (fDebug) { + printf("(%d bytes)\n", nSize); + } nHeaderStart = -1; nMessageStart = -1; @@ -962,6 +575,25 @@ public: void CancelSubscribe(unsigned int nChannel); void CloseSocketDisconnect(); void Cleanup(); + + + // Denial-of-service detection/prevention + // The idea is to detect peers that are behaving + // badly and disconnect/ban them, but do it in a + // one-coding-mistake-won't-shatter-the-entire-network + // way. + // IMPORTANT: There should be nothing I can give a + // node that it will forward on that will make that + // node's peers drop it. If there is, an attacker + // can isolate a node and/or try to split the network. + // Dropping a node for sending stuff that is invalid + // now but might be valid in a later version is also + // dangerous, because it can cause a network split + // between nodes running old code and nodes running + // new code. + static void ClearBanned(); // needed for unit testing + static bool IsBanned(unsigned int ip); + bool Misbehaving(int howmuch); // 1 == a little, 100 == a lot }; diff --git a/src/noui.h b/src/noui.h index d0072df7f2..754c2225fc 100644 --- a/src/noui.h +++ b/src/noui.h @@ -1,4 +1,5 @@ // Copyright (c) 2010 Satoshi Nakamoto +// Copyright (c) 2011 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. #ifndef BITCOIN_NOUI_H @@ -66,4 +67,8 @@ inline void MainFrameRepaint() { } +inline void InitMessage(const std::string &message) +{ +} + #endif diff --git a/src/protocol.cpp b/src/protocol.cpp new file mode 100644 index 0000000000..48784b9cfb --- /dev/null +++ b/src/protocol.cpp @@ -0,0 +1,312 @@ +// Copyright (c) 2009-2010 Satoshi Nakamoto +// Copyright (c) 2011 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. + +#include "protocol.h" +#include "util.h" + +#ifndef __WXMSW__ +# include <arpa/inet.h> +#endif + +// Prototypes from net.h, but that header (currently) stinks, can't #include it without breaking things +bool Lookup(const char *pszName, std::vector<CAddress>& vaddr, int nServices, int nMaxSolutions, bool fAllowLookup = false, int portDefault = 0, bool fAllowPort = false); +bool Lookup(const char *pszName, CAddress& addr, int nServices, bool fAllowLookup = false, int portDefault = 0, bool fAllowPort = false); + +static const unsigned char pchIPv4[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff }; +static const char* ppszTypeName[] = +{ + "ERROR", + "tx", + "block", +}; + +CMessageHeader::CMessageHeader() +{ + memcpy(pchMessageStart, ::pchMessageStart, sizeof(pchMessageStart)); + memset(pchCommand, 0, sizeof(pchCommand)); + pchCommand[1] = 1; + nMessageSize = -1; + nChecksum = 0; +} + +CMessageHeader::CMessageHeader(const char* pszCommand, unsigned int nMessageSizeIn) +{ + memcpy(pchMessageStart, ::pchMessageStart, sizeof(pchMessageStart)); + strncpy(pchCommand, pszCommand, COMMAND_SIZE); + nMessageSize = nMessageSizeIn; + nChecksum = 0; +} + +std::string CMessageHeader::GetCommand() const +{ + if (pchCommand[COMMAND_SIZE-1] == 0) + return std::string(pchCommand, pchCommand + strlen(pchCommand)); + else + return std::string(pchCommand, pchCommand + COMMAND_SIZE); +} + +bool CMessageHeader::IsValid() const +{ + // Check start string + if (memcmp(pchMessageStart, ::pchMessageStart, sizeof(pchMessageStart)) != 0) + return false; + + // Check the command string for errors + for (const char* p1 = pchCommand; p1 < pchCommand + COMMAND_SIZE; p1++) + { + if (*p1 == 0) + { + // Must be all zeros after the first zero + for (; p1 < pchCommand + COMMAND_SIZE; p1++) + if (*p1 != 0) + return false; + } + else if (*p1 < ' ' || *p1 > 0x7E) + return false; + } + + // Message size + if (nMessageSize > MAX_SIZE) + { + printf("CMessageHeader::IsValid() : (%s, %u bytes) nMessageSize > MAX_SIZE\n", GetCommand().c_str(), nMessageSize); + return false; + } + + return true; +} + +CAddress::CAddress() +{ + Init(); +} + +CAddress::CAddress(unsigned int ipIn, unsigned short portIn, uint64 nServicesIn) +{ + Init(); + ip = ipIn; + port = htons(portIn == 0 ? GetDefaultPort() : portIn); + nServices = nServicesIn; +} + +CAddress::CAddress(const struct sockaddr_in& sockaddr, uint64 nServicesIn) +{ + Init(); + ip = sockaddr.sin_addr.s_addr; + port = sockaddr.sin_port; + nServices = nServicesIn; +} + +CAddress::CAddress(const char* pszIn, int portIn, bool fNameLookup, uint64 nServicesIn) +{ + Init(); + Lookup(pszIn, *this, nServicesIn, fNameLookup, portIn); +} + +CAddress::CAddress(const char* pszIn, bool fNameLookup, uint64 nServicesIn) +{ + Init(); + Lookup(pszIn, *this, nServicesIn, fNameLookup, 0, true); +} + +CAddress::CAddress(std::string strIn, int portIn, bool fNameLookup, uint64 nServicesIn) +{ + Init(); + Lookup(strIn.c_str(), *this, nServicesIn, fNameLookup, portIn); +} + +CAddress::CAddress(std::string strIn, bool fNameLookup, uint64 nServicesIn) +{ + Init(); + Lookup(strIn.c_str(), *this, nServicesIn, fNameLookup, 0, true); +} + +void CAddress::Init() +{ + nServices = NODE_NETWORK; + memcpy(pchReserved, pchIPv4, sizeof(pchReserved)); + ip = INADDR_NONE; + port = htons(GetDefaultPort()); + nTime = 100000000; + nLastTry = 0; +} + +bool operator==(const CAddress& a, const CAddress& b) +{ + return (memcmp(a.pchReserved, b.pchReserved, sizeof(a.pchReserved)) == 0 && + a.ip == b.ip && + a.port == b.port); +} + +bool operator!=(const CAddress& a, const CAddress& b) +{ + return (!(a == b)); +} + +bool operator<(const CAddress& a, const CAddress& b) +{ + int ret = memcmp(a.pchReserved, b.pchReserved, sizeof(a.pchReserved)); + if (ret < 0) + return true; + else if (ret == 0) + { + if (ntohl(a.ip) < ntohl(b.ip)) + return true; + else if (a.ip == b.ip) + return ntohs(a.port) < ntohs(b.port); + } + return false; +} + +std::vector<unsigned char> CAddress::GetKey() const +{ + CDataStream ss; + ss.reserve(18); + ss << FLATDATA(pchReserved) << ip << port; + + #if defined(_MSC_VER) && _MSC_VER < 1300 + return std::vector<unsigned char>((unsigned char*)&ss.begin()[0], (unsigned char*)&ss.end()[0]); + #else + return std::vector<unsigned char>(ss.begin(), ss.end()); + #endif +} + +struct sockaddr_in CAddress::GetSockAddr() const +{ + struct sockaddr_in sockaddr; + memset(&sockaddr, 0, sizeof(sockaddr)); + sockaddr.sin_family = AF_INET; + sockaddr.sin_addr.s_addr = ip; + sockaddr.sin_port = port; + return sockaddr; +} + +bool CAddress::IsIPv4() const +{ + return (memcmp(pchReserved, pchIPv4, sizeof(pchIPv4)) == 0); +} + +bool CAddress::IsRFC1918() const +{ + return IsIPv4() && (GetByte(3) == 10 || + (GetByte(3) == 192 && GetByte(2) == 168) || + (GetByte(3) == 172 && + (GetByte(2) >= 16 && GetByte(2) <= 31))); +} + +bool CAddress::IsRFC3927() const +{ + return IsIPv4() && (GetByte(3) == 169 && GetByte(2) == 254); +} + +bool CAddress::IsLocal() const +{ + return IsIPv4() && (GetByte(3) == 127 || + GetByte(3) == 0); +} + +bool CAddress::IsRoutable() const +{ + return IsValid() && + !(IsRFC1918() || IsRFC3927() || IsLocal()); +} + +bool CAddress::IsValid() const +{ + // Clean up 3-byte shifted addresses caused by garbage in size field + // of addr messages from versions before 0.2.9 checksum. + // Two consecutive addr messages look like this: + // header20 vectorlen3 addr26 addr26 addr26 header20 vectorlen3 addr26 addr26 addr26... + // so if the first length field is garbled, it reads the second batch + // of addr misaligned by 3 bytes. + if (memcmp(pchReserved, pchIPv4+3, sizeof(pchIPv4)-3) == 0) + return false; + + return (ip != 0 && ip != INADDR_NONE && port != htons(USHRT_MAX)); +} + +unsigned char CAddress::GetByte(int n) const +{ + return ((unsigned char*)&ip)[3-n]; +} + +std::string CAddress::ToStringIPPort() const +{ + return strprintf("%u.%u.%u.%u:%u", GetByte(3), GetByte(2), GetByte(1), GetByte(0), ntohs(port)); +} + +std::string CAddress::ToStringIP() const +{ + return strprintf("%u.%u.%u.%u", GetByte(3), GetByte(2), GetByte(1), GetByte(0)); +} + +std::string CAddress::ToStringPort() const +{ + return strprintf("%u", ntohs(port)); +} + +std::string CAddress::ToString() const +{ + return strprintf("%u.%u.%u.%u:%u", GetByte(3), GetByte(2), GetByte(1), GetByte(0), ntohs(port)); +} + +void CAddress::print() const +{ + printf("CAddress(%s)\n", ToString().c_str()); +} + +CInv::CInv() +{ + type = 0; + hash = 0; +} + +CInv::CInv(int typeIn, const uint256& hashIn) +{ + type = typeIn; + hash = hashIn; +} + +CInv::CInv(const std::string& strType, const uint256& hashIn) +{ + int i; + for (i = 1; i < ARRAYLEN(ppszTypeName); i++) + { + if (strType == ppszTypeName[i]) + { + type = i; + break; + } + } + if (i == ARRAYLEN(ppszTypeName)) + throw std::out_of_range(strprintf("CInv::CInv(string, uint256) : unknown type '%s'", strType.c_str())); + hash = hashIn; +} + +bool operator<(const CInv& a, const CInv& b) +{ + return (a.type < b.type || (a.type == b.type && a.hash < b.hash)); +} + +bool CInv::IsKnownType() const +{ + return (type >= 1 && type < ARRAYLEN(ppszTypeName)); +} + +const char* CInv::GetCommand() const +{ + if (!IsKnownType()) + throw std::out_of_range(strprintf("CInv::GetCommand() : type=%d unknown type", type)); + return ppszTypeName[type]; +} + +std::string CInv::ToString() const +{ + return strprintf("%s %s", GetCommand(), hash.ToString().substr(0,20).c_str()); +} + +void CInv::print() const +{ + printf("CInv(%s)\n", ToString().c_str()); +} diff --git a/src/protocol.h b/src/protocol.h new file mode 100644 index 0000000000..53d3eef4d5 --- /dev/null +++ b/src/protocol.h @@ -0,0 +1,150 @@ +// Copyright (c) 2009-2010 Satoshi Nakamoto +// Copyright (c) 2011 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. + +#ifndef __cplusplus +# error This header can only be compiled as C++. +#endif + +#ifndef __INCLUDED_PROTOCOL_H__ +#define __INCLUDED_PROTOCOL_H__ + +#include "serialize.h" +#include <string> +#include "uint256.h" + +extern bool fTestNet; +static inline unsigned short GetDefaultPort(const bool testnet = fTestNet) +{ + return testnet ? 18333 : 8333; +} + +// +// Message header +// (4) message start +// (12) command +// (4) size +// (4) checksum + +extern unsigned char pchMessageStart[4]; + +class CMessageHeader +{ + public: + CMessageHeader(); + CMessageHeader(const char* pszCommand, unsigned int nMessageSizeIn); + + std::string GetCommand() const; + bool IsValid() const; + + IMPLEMENT_SERIALIZE + ( + READWRITE(FLATDATA(pchMessageStart)); + READWRITE(FLATDATA(pchCommand)); + READWRITE(nMessageSize); + if (nVersion >= 209) + READWRITE(nChecksum); + ) + + // TODO: make private (improves encapsulation) + public: + enum { COMMAND_SIZE=12 }; + char pchMessageStart[sizeof(::pchMessageStart)]; + char pchCommand[COMMAND_SIZE]; + unsigned int nMessageSize; + unsigned int nChecksum; +}; + +enum +{ + NODE_NETWORK = (1 << 0), +}; + +class CAddress +{ + public: + CAddress(); + CAddress(unsigned int ipIn, unsigned short portIn=0, uint64 nServicesIn=NODE_NETWORK); + explicit CAddress(const struct sockaddr_in& sockaddr, uint64 nServicesIn=NODE_NETWORK); + explicit CAddress(const char* pszIn, int portIn, bool fNameLookup = false, uint64 nServicesIn=NODE_NETWORK); + explicit CAddress(const char* pszIn, bool fNameLookup = false, uint64 nServicesIn=NODE_NETWORK); + explicit CAddress(std::string strIn, int portIn, bool fNameLookup = false, uint64 nServicesIn=NODE_NETWORK); + explicit CAddress(std::string strIn, bool fNameLookup = false, uint64 nServicesIn=NODE_NETWORK); + + void Init(); + + IMPLEMENT_SERIALIZE + ( + if (fRead) + const_cast<CAddress*>(this)->Init(); + if (nType & SER_DISK) + READWRITE(nVersion); + if ((nType & SER_DISK) || (nVersion >= 31402 && !(nType & SER_GETHASH))) + READWRITE(nTime); + READWRITE(nServices); + READWRITE(FLATDATA(pchReserved)); // for IPv6 + READWRITE(ip); + READWRITE(port); + ) + + friend bool operator==(const CAddress& a, const CAddress& b); + friend bool operator!=(const CAddress& a, const CAddress& b); + friend bool operator<(const CAddress& a, const CAddress& b); + + std::vector<unsigned char> GetKey() const; + struct sockaddr_in GetSockAddr() const; + bool IsIPv4() const; + bool IsRFC1918() const; + bool IsRFC3927() const; + bool IsLocal() const; + bool IsRoutable() const; + bool IsValid() const; + unsigned char GetByte(int n) const; + std::string ToStringIPPort() const; + std::string ToStringIP() const; + std::string ToStringPort() const; + std::string ToString() const; + void print() const; + + // TODO: make private (improves encapsulation) + public: + uint64 nServices; + unsigned char pchReserved[12]; + unsigned int ip; + unsigned short port; + + // disk and network only + unsigned int nTime; + + // memory only + unsigned int nLastTry; +}; + +class CInv +{ + public: + CInv(); + CInv(int typeIn, const uint256& hashIn); + CInv(const std::string& strType, const uint256& hashIn); + + IMPLEMENT_SERIALIZE + ( + READWRITE(type); + READWRITE(hash); + ) + + friend bool operator<(const CInv& a, const CInv& b); + + bool IsKnownType() const; + const char* GetCommand() const; + std::string ToString() const; + void print() const; + + // TODO: make private (improves encapsulation) + public: + int type; + uint256 hash; +}; + +#endif // __INCLUDED_PROTOCOL_H__ diff --git a/src/qt/aboutdialog.cpp b/src/qt/aboutdialog.cpp new file mode 100644 index 0000000000..13d263b75c --- /dev/null +++ b/src/qt/aboutdialog.cpp @@ -0,0 +1,26 @@ +#include "aboutdialog.h" +#include "ui_aboutdialog.h" +#include "clientmodel.h" + +AboutDialog::AboutDialog(QWidget *parent) : + QDialog(parent), + ui(new Ui::AboutDialog) +{ + ui->setupUi(this); + +} + +void AboutDialog::setModel(ClientModel *model) +{ + ui->versionLabel->setText(model->formatFullVersion()); +} + +AboutDialog::~AboutDialog() +{ + delete ui; +} + +void AboutDialog::on_buttonBox_accepted() +{ + close(); +} diff --git a/src/qt/aboutdialog.h b/src/qt/aboutdialog.h new file mode 100644 index 0000000000..d2caa3eedf --- /dev/null +++ b/src/qt/aboutdialog.h @@ -0,0 +1,27 @@ +#ifndef ABOUTDIALOG_H +#define ABOUTDIALOG_H + +#include <QDialog> + +namespace Ui { + class AboutDialog; +} +class ClientModel; + +class AboutDialog : public QDialog +{ + Q_OBJECT + +public: + explicit AboutDialog(QWidget *parent = 0); + ~AboutDialog(); + + void setModel(ClientModel *model); +private: + Ui::AboutDialog *ui; + +private slots: + void on_buttonBox_accepted(); +}; + +#endif // ABOUTDIALOG_H diff --git a/src/qt/addressbookpage.cpp b/src/qt/addressbookpage.cpp new file mode 100644 index 0000000000..ee64cc2c80 --- /dev/null +++ b/src/qt/addressbookpage.cpp @@ -0,0 +1,215 @@ +#include "addressbookpage.h" +#include "ui_addressbookpage.h" + +#include "addresstablemodel.h" +#include "editaddressdialog.h" +#include "csvmodelwriter.h" + +#include <QSortFilterProxyModel> +#include <QClipboard> +#include <QFileDialog> +#include <QMessageBox> + +AddressBookPage::AddressBookPage(Mode mode, Tabs tab, QWidget *parent) : + QDialog(parent), + ui(new Ui::AddressBookPage), + model(0), + mode(mode), + tab(tab) +{ + ui->setupUi(this); + switch(mode) + { + case ForSending: + connect(ui->tableView, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(accept())); + ui->tableView->setEditTriggers(QAbstractItemView::NoEditTriggers); + ui->tableView->setFocus(); + break; + case ForEditing: + ui->buttonBox->hide(); + break; + } + switch(tab) + { + case SendingTab: + ui->labelExplanation->hide(); + break; + case ReceivingTab: + break; + } + ui->tableView->setTabKeyNavigation(false); + + connect(ui->buttonBox, SIGNAL(accepted()), this, SLOT(accept())); +} + +AddressBookPage::~AddressBookPage() +{ + delete ui; +} + +void AddressBookPage::setModel(AddressTableModel *model) +{ + this->model = model; + // Refresh list from core + model->updateList(); + + proxyModel = new QSortFilterProxyModel(this); + proxyModel->setSourceModel(model); + proxyModel->setDynamicSortFilter(true); + switch(tab) + { + case ReceivingTab: + // Receive filter + proxyModel->setFilterRole(AddressTableModel::TypeRole); + proxyModel->setFilterFixedString(AddressTableModel::Receive); + break; + case SendingTab: + // Send filter + proxyModel->setFilterRole(AddressTableModel::TypeRole); + proxyModel->setFilterFixedString(AddressTableModel::Send); + break; + } + ui->tableView->setModel(proxyModel); + ui->tableView->sortByColumn(0, Qt::AscendingOrder); + + // Set column widths + ui->tableView->horizontalHeader()->resizeSection( + AddressTableModel::Address, 320); + ui->tableView->horizontalHeader()->setResizeMode( + AddressTableModel::Label, QHeaderView::Stretch); + + connect(ui->tableView->selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)), + this, SLOT(selectionChanged())); + + if(mode == ForSending) + { + // Auto-select first row when in sending mode + ui->tableView->selectRow(0); + } + selectionChanged(); +} + +QTableView *AddressBookPage::getCurrentTable() +{ + return ui->tableView; +} + +void AddressBookPage::on_copyToClipboard_clicked() +{ + // Copy currently selected address to clipboard + // (or nothing, if nothing selected) + QTableView *table = getCurrentTable(); + QModelIndexList indexes = table->selectionModel()->selectedRows(AddressTableModel::Address); + + foreach (QModelIndex index, indexes) + { + QVariant address = index.data(); + QApplication::clipboard()->setText(address.toString()); + } +} + +void AddressBookPage::on_newAddressButton_clicked() +{ + EditAddressDialog dlg( + tab == SendingTab ? + EditAddressDialog::NewSendingAddress : + EditAddressDialog::NewReceivingAddress); + 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()); + } + } +} + +void AddressBookPage::on_deleteButton_clicked() +{ + QTableView *table = getCurrentTable(); + QModelIndexList indexes = table->selectionModel()->selectedRows(); + if(!indexes.isEmpty()) + { + table->model()->removeRow(indexes.at(0).row()); + } +} + +void AddressBookPage::selectionChanged() +{ + // Set button states based on selected tab and selection + QTableView *table = getCurrentTable(); + + if(table->selectionModel()->hasSelection()) + { + switch(tab) + { + case SendingTab: + ui->deleteButton->setEnabled(true); + break; + case ReceivingTab: + ui->deleteButton->setEnabled(false); + break; + } + ui->copyToClipboard->setEnabled(true); + } + else + { + ui->deleteButton->setEnabled(false); + ui->copyToClipboard->setEnabled(false); + } +} + +void AddressBookPage::done(int retval) +{ + // When this is a tab/widget and not a model dialog, ignore "done" + if(mode == ForEditing) + return; + + // Figure out which address was selected, and return it + QTableView *table = getCurrentTable(); + QModelIndexList indexes = table->selectionModel()->selectedRows(AddressTableModel::Address); + + foreach (QModelIndex index, indexes) + { + QVariant address = table->model()->data(index); + returnValue = address.toString(); + } + + if(returnValue.isEmpty()) + { + retval = Rejected; + } + + QDialog::done(retval); +} + +void AddressBookPage::exportClicked() +{ + // CSV is currently the only supported format + QString filename = QFileDialog::getSaveFileName( + this, + tr("Export Address Book Data"), + QDir::currentPath(), + tr("Comma separated file (*.csv)")); + + if (filename.isNull()) return; + + CSVModelWriter writer(filename); + + // name, column, role + writer.setModel(proxyModel); + writer.addColumn("Label", AddressTableModel::Label, Qt::EditRole); + writer.addColumn("Address", AddressTableModel::Address, Qt::EditRole); + + if(!writer.write()) + { + QMessageBox::critical(this, tr("Error exporting"), tr("Could not write to file %1.").arg(filename), + QMessageBox::Abort, QMessageBox::Abort); + } +} diff --git a/src/qt/addressbookpage.h b/src/qt/addressbookpage.h new file mode 100644 index 0000000000..53c7728c8c --- /dev/null +++ b/src/qt/addressbookpage.h @@ -0,0 +1,59 @@ +#ifndef ADDRESSBOOKPAGE_H +#define ADDRESSBOOKPAGE_H + +#include <QDialog> + +namespace Ui { + class AddressBookPage; +} +class AddressTableModel; + +QT_BEGIN_NAMESPACE +class QTableView; +class QItemSelection; +class QSortFilterProxyModel; +QT_END_NAMESPACE + +class AddressBookPage : public QDialog +{ + Q_OBJECT + +public: + enum Tabs { + SendingTab = 0, + ReceivingTab = 1 + }; + + enum Mode { + ForSending, // Pick address for sending + ForEditing // Open address book for editing + }; + + explicit AddressBookPage(Mode mode, Tabs tab, QWidget *parent = 0); + ~AddressBookPage(); + + void setModel(AddressTableModel *model); + const QString &getReturnValue() const { return returnValue; } + +public slots: + void done(int retval); + void exportClicked(); + +private: + Ui::AddressBookPage *ui; + AddressTableModel *model; + Mode mode; + Tabs tab; + QString returnValue; + QSortFilterProxyModel *proxyModel; + + QTableView *getCurrentTable(); + +private slots: + void on_deleteButton_clicked(); + void on_newAddressButton_clicked(); + void on_copyToClipboard_clicked(); + void selectionChanged(); +}; + +#endif // ADDRESSBOOKDIALOG_H diff --git a/src/qt/addresstablemodel.cpp b/src/qt/addresstablemodel.cpp new file mode 100644 index 0000000000..8fd6d52b7e --- /dev/null +++ b/src/qt/addresstablemodel.cpp @@ -0,0 +1,347 @@ +#include "addresstablemodel.h" +#include "guiutil.h" +#include "walletmodel.h" + +#include "headers.h" + +#include <QFont> +#include <QColor> + +const QString AddressTableModel::Send = "S"; +const QString AddressTableModel::Receive = "R"; + +struct AddressTableEntry +{ + enum Type { + Sending, + Receiving + }; + + Type type; + QString label; + QString address; + + AddressTableEntry() {} + AddressTableEntry(Type type, const QString &label, const QString &address): + type(type), label(label), address(address) {} +}; + +// Private implementation +struct AddressTablePriv +{ + CWallet *wallet; + QList<AddressTableEntry> cachedAddressTable; + + AddressTablePriv(CWallet *wallet): + wallet(wallet) {} + + void refreshAddressTable() + { + cachedAddressTable.clear(); + + CRITICAL_BLOCK(wallet->cs_wallet) + { + BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress, std::string)& item, wallet->mapAddressBook) + { + const CBitcoinAddress& address = item.first; + const std::string& strName = item.second; + bool fMine = wallet->HaveKey(address); + cachedAddressTable.append(AddressTableEntry(fMine ? AddressTableEntry::Receiving : AddressTableEntry::Sending, + QString::fromStdString(strName), + QString::fromStdString(address.ToString()))); + } + } + } + + int size() + { + return cachedAddressTable.size(); + } + + AddressTableEntry *index(int idx) + { + if(idx >= 0 && idx < cachedAddressTable.size()) + { + return &cachedAddressTable[idx]; + } + else + { + return 0; + } + } +}; + +AddressTableModel::AddressTableModel(CWallet *wallet, WalletModel *parent) : + QAbstractTableModel(parent),walletModel(parent),wallet(wallet),priv(0) +{ + columns << tr("Label") << tr("Address"); + priv = new AddressTablePriv(wallet); + priv->refreshAddressTable(); +} + +AddressTableModel::~AddressTableModel() +{ + delete priv; +} + +int AddressTableModel::rowCount(const QModelIndex &parent) const +{ + Q_UNUSED(parent); + return priv->size(); +} + +int AddressTableModel::columnCount(const QModelIndex &parent) const +{ + Q_UNUSED(parent); + return columns.length(); +} + +QVariant AddressTableModel::data(const QModelIndex &index, int role) const +{ + if(!index.isValid()) + return QVariant(); + + AddressTableEntry *rec = static_cast<AddressTableEntry*>(index.internalPointer()); + + if(role == Qt::DisplayRole || role == Qt::EditRole) + { + switch(index.column()) + { + case Label: + if(rec->label.isEmpty() && role == Qt::DisplayRole) + { + return tr("(no label)"); + } + else + { + return rec->label; + } + case Address: + return rec->address; + } + } + else if (role == Qt::FontRole) + { + QFont font; + if(index.column() == Address) + { + font = GUIUtil::bitcoinAddressFont(); + } + return font; + } + else if (role == TypeRole) + { + switch(rec->type) + { + case AddressTableEntry::Sending: + return Send; + case AddressTableEntry::Receiving: + return Receive; + default: break; + } + } + return QVariant(); +} + +bool AddressTableModel::setData(const QModelIndex & index, const QVariant & value, int role) +{ + if(!index.isValid()) + return false; + AddressTableEntry *rec = static_cast<AddressTableEntry*>(index.internalPointer()); + + editStatus = OK; + + if(role == Qt::EditRole) + { + switch(index.column()) + { + 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 + if(!walletModel->validateAddress(value.toString())) + { + editStatus = INVALID_ADDRESS; + return false; + } + // Double-check that we're not overwriting a receiving address + if(rec->type == AddressTableEntry::Sending) + { + CRITICAL_BLOCK(wallet->cs_wallet) + { + // Remove old entry + wallet->DelAddressBookName(rec->address.toStdString()); + // 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; + } + return false; +} + +QVariant AddressTableModel::headerData(int section, Qt::Orientation orientation, int role) const +{ + if(orientation == Qt::Horizontal) + { + if(role == Qt::DisplayRole) + { + return columns[section]; + } + } + return QVariant(); +} + +Qt::ItemFlags AddressTableModel::flags(const QModelIndex & index) const +{ + if(!index.isValid()) + return 0; + AddressTableEntry *rec = static_cast<AddressTableEntry*>(index.internalPointer()); + + Qt::ItemFlags retval = Qt::ItemIsSelectable | Qt::ItemIsEnabled; + // Can edit address and label for sending addresses, + // and only label for receiving addresses. + if(rec->type == AddressTableEntry::Sending || + (rec->type == AddressTableEntry::Receiving && index.column()==Label)) + { + retval |= Qt::ItemIsEditable; + } + return retval; +} + +QModelIndex AddressTableModel::index(int row, int column, const QModelIndex & parent) const +{ + Q_UNUSED(parent); + AddressTableEntry *data = priv->index(row); + if(data) + { + return createIndex(row, column, priv->index(row)); + } + else + { + return QModelIndex(); + } +} + +void AddressTableModel::updateList() +{ + // Update address book model from Bitcoin core + beginResetModel(); + priv->refreshAddressTable(); + endResetModel(); +} + +QString AddressTableModel::addRow(const QString &type, const QString &label, const QString &address) +{ + std::string strLabel = label.toStdString(); + std::string strAddress = address.toStdString(); + + editStatus = OK; + + if(type == Send) + { + if(!walletModel->validateAddress(address)) + { + editStatus = INVALID_ADDRESS; + return QString(); + } + // Check for duplicate addresses + CRITICAL_BLOCK(wallet->cs_wallet) + { + if(wallet->mapAddressBook.count(strAddress)) + { + editStatus = DUPLICATE_ADDRESS; + return QString(); + } + } + } + else if(type == Receive) + { + // Generate a new address to associate with given label + WalletModel::UnlockContext ctx(walletModel->requestUnlock()); + if(!ctx.isValid()) + { + // Unlock wallet failed or was cancelled + editStatus = WALLET_UNLOCK_FAILURE; + return QString(); + } + std::vector<unsigned char> newKey; + if(!wallet->GetKeyFromPool(newKey, true)) + { + editStatus = KEY_GENERATION_FAILURE; + return QString(); + } + strAddress = CBitcoinAddress(newKey).ToString(); + } + else + { + return QString(); + } + // Add entry and update list + CRITICAL_BLOCK(wallet->cs_wallet) + wallet->SetAddressBookName(strAddress, strLabel); + updateList(); + return QString::fromStdString(strAddress); +} + +bool AddressTableModel::removeRows(int row, int count, const QModelIndex & parent) +{ + Q_UNUSED(parent); + AddressTableEntry *rec = priv->index(row); + if(count != 1 || !rec || rec->type == AddressTableEntry::Receiving) + { + // Can only remove one row at a time, and cannot remove rows not in model. + // Also refuse to remove receiving addresses. + return false; + } + CRITICAL_BLOCK(wallet->cs_wallet) + { + wallet->DelAddressBookName(rec->address.toStdString()); + } + updateList(); + return true; +} + +void AddressTableModel::update() +{ + +} + +/* Look up label for address in address book, if not found return empty string. + */ +QString AddressTableModel::labelForAddress(const QString &address) const +{ + CRITICAL_BLOCK(wallet->cs_wallet) + { + CBitcoinAddress address_parsed(address.toStdString()); + std::map<CBitcoinAddress, std::string>::iterator mi = wallet->mapAddressBook.find(address_parsed); + if (mi != wallet->mapAddressBook.end()) + { + return QString::fromStdString(mi->second); + } + } + return QString(); +} + +int AddressTableModel::lookupAddress(const QString &address) const +{ + QModelIndexList lst = match(index(0, Address, QModelIndex()), + Qt::EditRole, address, 1, Qt::MatchExactly); + if(lst.isEmpty()) + { + return -1; + } + else + { + return lst.at(0).row(); + } +} + diff --git a/src/qt/addresstablemodel.h b/src/qt/addresstablemodel.h new file mode 100644 index 0000000000..f4a8dad845 --- /dev/null +++ b/src/qt/addresstablemodel.h @@ -0,0 +1,83 @@ +#ifndef ADDRESSTABLEMODEL_H +#define ADDRESSTABLEMODEL_H + +#include <QAbstractTableModel> +#include <QStringList> + +class AddressTablePriv; +class CWallet; +class WalletModel; + +class AddressTableModel : public QAbstractTableModel +{ + Q_OBJECT +public: + explicit AddressTableModel(CWallet *wallet, WalletModel *parent = 0); + ~AddressTableModel(); + + enum ColumnIndex { + Label = 0, /* User specified label */ + Address = 1 /* Bitcoin address */ + }; + + enum RoleIndex { + TypeRole = Qt::UserRole + }; + + // Return status of last edit/insert operation + enum EditStatus { + OK, + INVALID_ADDRESS, + DUPLICATE_ADDRESS, + WALLET_UNLOCK_FAILURE, + KEY_GENERATION_FAILURE + }; + + static const QString Send; /* Send addres */ + static const QString Receive; /* Receive address */ + + /* Overridden methods from QAbstractTableModel */ + int rowCount(const QModelIndex &parent) const; + int columnCount(const QModelIndex &parent) const; + QVariant data(const QModelIndex &index, int role) const; + bool setData(const QModelIndex & index, const QVariant & value, int role); + QVariant headerData(int section, Qt::Orientation orientation, int role) const; + QModelIndex index(int row, int column, const QModelIndex & parent) const; + bool removeRows(int row, int count, const QModelIndex & parent = QModelIndex()); + Qt::ItemFlags flags(const QModelIndex & index) const; + + /* Add an address to the model. + Returns the added address on success, and an empty string otherwise. + */ + QString addRow(const QString &type, const QString &label, const QString &address); + + /* Update address list from core. Invalidates any indices. + */ + void updateList(); + + /* Look up label for address in address book, if not found return empty string. + */ + QString labelForAddress(const QString &address) const; + + /* Look up row index of an address in the model. + Return -1 if not found. + */ + int lookupAddress(const QString &address) const; + + EditStatus getEditStatus() const { return editStatus; } + +private: + WalletModel *walletModel; + CWallet *wallet; + AddressTablePriv *priv; + QStringList columns; + EditStatus editStatus; + +signals: + void defaultAddressChanged(const QString &address); + +public slots: + void update(); +}; + +#endif // ADDRESSTABLEMODEL_H diff --git a/src/qt/askpassphrasedialog.cpp b/src/qt/askpassphrasedialog.cpp new file mode 100644 index 0000000000..a297513a62 --- /dev/null +++ b/src/qt/askpassphrasedialog.cpp @@ -0,0 +1,186 @@ +#include "askpassphrasedialog.h" +#include "ui_askpassphrasedialog.h" + +#include "guiconstants.h" +#include "walletmodel.h" + +#include <QMessageBox> +#include <QPushButton> + +AskPassphraseDialog::AskPassphraseDialog(Mode mode, QWidget *parent) : + QDialog(parent), + ui(new Ui::AskPassphraseDialog), + mode(mode), + model(0) +{ + ui->setupUi(this); + ui->passEdit1->setMaxLength(MAX_PASSPHRASE_SIZE); + ui->passEdit2->setMaxLength(MAX_PASSPHRASE_SIZE); + ui->passEdit3->setMaxLength(MAX_PASSPHRASE_SIZE); + + switch(mode) + { + case Encrypt: // Ask passphrase x2 + ui->passLabel1->hide(); + ui->passEdit1->hide(); + ui->warningLabel->setText(tr("Enter the new passphrase to the wallet.<br/>Please use a passphrase of <b>10 or more random characters</b>, or <b>eight or more words</b>.")); + setWindowTitle(tr("Encrypt wallet")); + break; + case Unlock: // Ask passphrase + ui->warningLabel->setText(tr("This operation needs your wallet passphrase to unlock the wallet.")); + ui->passLabel2->hide(); + ui->passEdit2->hide(); + ui->passLabel3->hide(); + ui->passEdit3->hide(); + setWindowTitle(tr("Unlock wallet")); + break; + case Decrypt: // Ask passphrase + ui->warningLabel->setText(tr("This operation needs your wallet passphrase to decrypt the wallet.")); + ui->passLabel2->hide(); + ui->passEdit2->hide(); + ui->passLabel3->hide(); + ui->passEdit3->hide(); + setWindowTitle(tr("Decrypt wallet")); + break; + case ChangePass: // Ask old passphrase + new passphrase x2 + setWindowTitle(tr("Change passphrase")); + ui->warningLabel->setText(tr("Enter the old and new passphrase to the wallet.")); + break; + } + resize(minimumSize()); // Get rid of extra space in dialog + + textChanged(); + connect(ui->passEdit1, SIGNAL(textChanged(QString)), this, SLOT(textChanged())); + connect(ui->passEdit2, SIGNAL(textChanged(QString)), this, SLOT(textChanged())); + connect(ui->passEdit3, SIGNAL(textChanged(QString)), this, SLOT(textChanged())); +} + +AskPassphraseDialog::~AskPassphraseDialog() +{ + // Attempt to overwrite text so that they do not linger around in memory + ui->passEdit1->setText(QString(" ").repeated(ui->passEdit1->text().size())); + ui->passEdit2->setText(QString(" ").repeated(ui->passEdit2->text().size())); + ui->passEdit3->setText(QString(" ").repeated(ui->passEdit3->text().size())); + delete ui; +} + +void AskPassphraseDialog::setModel(WalletModel *model) +{ + this->model = model; +} + +void AskPassphraseDialog::accept() +{ + std::string oldpass, newpass1, newpass2; + // TODO: mlock memory / munlock on return so they will not be swapped out, really need "mlockedstring" wrapper class to do this safely + oldpass.reserve(MAX_PASSPHRASE_SIZE); + newpass1.reserve(MAX_PASSPHRASE_SIZE); + newpass2.reserve(MAX_PASSPHRASE_SIZE); + oldpass.assign(ui->passEdit1->text().toStdString()); + newpass1.assign(ui->passEdit2->text().toStdString()); + newpass2.assign(ui->passEdit3->text().toStdString()); + + switch(mode) + { + case Encrypt: { + if(newpass1.empty() || newpass2.empty()) + { + // Cannot encrypt with empty passphrase + break; + } + QMessageBox::StandardButton retval = QMessageBox::question(this, tr("Confirm wallet encryption"), + tr("WARNING: If you encrypt your wallet and lose your passphrase, you will <b>LOSE ALL OF YOUR BITCOINS</b>!\nAre you sure you wish to encrypt your wallet?"), + QMessageBox::Yes|QMessageBox::Cancel, + QMessageBox::Cancel); + if(retval == QMessageBox::Yes) + { + if(newpass1 == newpass2) + { + if(model->setWalletEncrypted(true, newpass1)) + { + QMessageBox::warning(this, tr("Wallet encrypted"), + tr("Remember that encrypting your wallet cannot fully protect your bitcoins from being stolen by malware infecting your computer.")); + } + else + { + QMessageBox::critical(this, tr("Wallet encryption failed"), + tr("Wallet encryption failed due to an internal error. Your wallet was not encrypted.")); + } + QDialog::accept(); // Success + } + else + { + QMessageBox::critical(this, tr("Wallet encryption failed"), + tr("The supplied passphrases do not match.")); + } + } + else + { + QDialog::reject(); // Cancelled + } + } break; + case Unlock: + if(!model->setWalletLocked(false, oldpass)) + { + QMessageBox::critical(this, tr("Wallet unlock failed"), + tr("The passphrase entered for the wallet decryption was incorrect.")); + } + else + { + QDialog::accept(); // Success + } + break; + case Decrypt: + if(!model->setWalletEncrypted(false, oldpass)) + { + QMessageBox::critical(this, tr("Wallet decryption failed"), + tr("The passphrase entered for the wallet decryption was incorrect.")); + } + else + { + QDialog::accept(); // Success + } + break; + case ChangePass: + if(newpass1 == newpass2) + { + if(model->changePassphrase(oldpass, newpass1)) + { + QMessageBox::information(this, tr("Wallet encrypted"), + tr("Wallet passphrase was succesfully changed.")); + QDialog::accept(); // Success + } + else + { + QMessageBox::critical(this, tr("Wallet encryption failed"), + tr("The passphrase entered for the wallet decryption was incorrect.")); + } + } + else + { + QMessageBox::critical(this, tr("Wallet encryption failed"), + tr("The supplied passphrases do not match.")); + } + break; + } +} + +void AskPassphraseDialog::textChanged() +{ + // Validate input, set Ok button to enabled when accepable + bool acceptable = false; + switch(mode) + { + case Encrypt: // New passphrase x2 + acceptable = !ui->passEdit2->text().isEmpty() && !ui->passEdit3->text().isEmpty(); + break; + case Unlock: // Old passphrase x1 + case Decrypt: + acceptable = !ui->passEdit1->text().isEmpty(); + break; + case ChangePass: // Old passphrase x1, new passphrase x2 + acceptable = !ui->passEdit1->text().isEmpty() && !ui->passEdit2->text().isEmpty() && !ui->passEdit3->text().isEmpty(); + break; + } + ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(acceptable); +} diff --git a/src/qt/askpassphrasedialog.h b/src/qt/askpassphrasedialog.h new file mode 100644 index 0000000000..761612cbfd --- /dev/null +++ b/src/qt/askpassphrasedialog.h @@ -0,0 +1,40 @@ +#ifndef ASKPASSPHRASEDIALOG_H +#define ASKPASSPHRASEDIALOG_H + +#include <QDialog> + +namespace Ui { + class AskPassphraseDialog; +} + +class WalletModel; + +class AskPassphraseDialog : public QDialog +{ + Q_OBJECT + +public: + enum Mode { + Encrypt, // Ask passphrase x2 + Unlock, // Ask passphrase + ChangePass, // Ask old passphrase + new passphrase x2 + Decrypt // Ask passphrase + }; + + explicit AskPassphraseDialog(Mode mode, QWidget *parent = 0); + ~AskPassphraseDialog(); + + void accept(); + + void setModel(WalletModel *model); + +private: + Ui::AskPassphraseDialog *ui; + Mode mode; + WalletModel *model; + +private slots: + void textChanged(); +}; + +#endif // ASKPASSPHRASEDIALOG_H diff --git a/src/qt/bitcoin.cpp b/src/qt/bitcoin.cpp new file mode 100644 index 0000000000..60a9074204 --- /dev/null +++ b/src/qt/bitcoin.cpp @@ -0,0 +1,170 @@ +/* + * W.J. van der Laan 2011 + */ +#include "bitcoingui.h" +#include "clientmodel.h" +#include "walletmodel.h" +#include "optionsmodel.h" + +#include "headers.h" +#include "init.h" + +#include <QApplication> +#include <QMessageBox> +#include <QThread> +#include <QTextCodec> +#include <QLocale> +#include <QTranslator> +#include <QSplashScreen> + +// Need a global reference for the notifications to find the GUI +BitcoinGUI *guiref; +QSplashScreen *splashref; + +int MyMessageBox(const std::string& message, const std::string& caption, int style, wxWindow* parent, int x, int y) +{ + // Message from main thread + if(guiref) + { + guiref->error(QString::fromStdString(caption), + QString::fromStdString(message)); + } + else + { + QMessageBox::critical(0, QString::fromStdString(caption), + QString::fromStdString(message), + QMessageBox::Ok, QMessageBox::Ok); + } + return 4; +} + +int ThreadSafeMessageBox(const std::string& message, const std::string& caption, int style, wxWindow* parent, int x, int y) +{ + // Message from network thread + if(guiref) + { + QMetaObject::invokeMethod(guiref, "error", Qt::QueuedConnection, + Q_ARG(QString, QString::fromStdString(caption)), + Q_ARG(QString, QString::fromStdString(message))); + } + else + { + 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, wxWindow* parent) +{ + if(!guiref) + return false; + if(nFeeRequired < MIN_TX_FEE || nFeeRequired <= nTransactionFee || fDaemon) + return true; + bool payFee = false; + + // Call slot on GUI thread. + // If called from another thread, use a blocking QueuedConnection. + Qt::ConnectionType connectionType = Qt::DirectConnection; + if(QThread::currentThread() != QCoreApplication::instance()->thread()) + { + connectionType = Qt::BlockingQueuedConnection; + } + + QMetaObject::invokeMethod(guiref, "askFee", connectionType, + Q_ARG(qint64, nFeeRequired), + Q_ARG(bool*, &payFee)); + + return payFee; +} + +void CalledSetStatusBar(const std::string& strText, int nField) +{ + // Only used for built-in mining, which is disabled, simple ignore +} + +void UIThreadCall(boost::function0<void> fn) +{ + // Only used for built-in mining, which is disabled, simple ignore +} + +void MainFrameRepaint() +{ +} + +void InitMessage(const std::string &message) +{ + if(splashref) + { + splashref->showMessage(QString::fromStdString(message), Qt::AlignBottom|Qt::AlignHCenter, QColor(255,255,200)); + QApplication::instance()->processEvents(); + } +} + +/* + Translate string to current locale using Qt. + */ +std::string _(const char* psz) +{ + return QCoreApplication::translate("bitcoin-core", psz).toStdString(); +} + +int main(int argc, char *argv[]) +{ + QTextCodec::setCodecForTr(QTextCodec::codecForName("UTF-8")); + QTextCodec::setCodecForCStrings(QTextCodec::codecForTr()); + + Q_INIT_RESOURCE(bitcoin); + QApplication app(argc, argv); + + // Load language file for system locale + QString locale = QLocale::system().name(); + QTranslator translator; + translator.load(":/translations/"+locale); + app.installTranslator(&translator); + + QSplashScreen splash(QPixmap(":/images/splash"), 0); + splash.show(); + splash.setAutoFillBackground(true); + splashref = &splash; + + app.processEvents(); + + app.setQuitOnLastWindowClosed(false); + + try + { + if(AppInit2(argc, argv)) + { + { + // Put this in a block, so that BitcoinGUI is cleaned up properly before + // calling Shutdown(). + BitcoinGUI window; + splash.finish(&window); + OptionsModel optionsModel(pwalletMain); + ClientModel clientModel(&optionsModel); + WalletModel walletModel(pwalletMain, &optionsModel); + + guiref = &window; + window.setClientModel(&clientModel); + window.setWalletModel(&walletModel); + + window.show(); + + app.exec(); + + guiref = 0; + } + Shutdown(NULL); + } + else + { + return 1; + } + } catch (std::exception& e) { + PrintException(&e, "Runaway exception"); + } catch (...) { + PrintException(NULL, "Runaway exception"); + } + return 0; +} diff --git a/src/qt/bitcoin.qrc b/src/qt/bitcoin.qrc new file mode 100644 index 0000000000..2985bb60ef --- /dev/null +++ b/src/qt/bitcoin.qrc @@ -0,0 +1,53 @@ +<RCC> + <qresource prefix="/icons" lang="edit"> + <file alias="bitcoin">res/icons/bitcoin.png</file> + <file alias="address-book">res/icons/address-book.png</file> + <file alias="quit">res/icons/quit.png</file> + <file alias="send">res/icons/send.png</file> + <file alias="toolbar">res/icons/toolbar.png</file> + <file alias="connect_0">res/icons/connect0_16.png</file> + <file alias="connect_1">res/icons/connect1_16.png</file> + <file alias="connect_2">res/icons/connect2_16.png</file> + <file alias="connect_3">res/icons/connect3_16.png</file> + <file alias="connect_4">res/icons/connect4_16.png</file> + <file alias="transaction_0">res/icons/transaction0.png</file> + <file alias="transaction_confirmed">res/icons/transaction2.png</file> + <file alias="transaction_1">res/icons/clock1.png</file> + <file alias="transaction_2">res/icons/clock2.png</file> + <file alias="transaction_3">res/icons/clock3.png</file> + <file alias="transaction_4">res/icons/clock4.png</file> + <file alias="transaction_5">res/icons/clock5.png</file> + <file alias="options">res/icons/configure.png</file> + <file alias="receiving_addresses">res/icons/receive.png</file> + <file alias="editpaste">res/icons/editpaste.png</file> + <file alias="editcopy">res/icons/editcopy.png</file> + <file alias="add">res/icons/add.png</file> + <file alias="bitcoin_testnet">res/icons/bitcoin_testnet.png</file> + <file alias="toolbar_testnet">res/icons/toolbar_testnet.png</file> + <file alias="edit">res/icons/edit.png</file> + <file alias="history">res/icons/history.png</file> + <file alias="overview">res/icons/overview.png</file> + <file alias="export">res/icons/export.png</file> + <file alias="synced">res/icons/synced.png</file> + <file alias="remove">res/icons/remove.png</file> + <file alias="tx_mined">res/icons/tx_mined.png</file> + <file alias="tx_input">res/icons/tx_input.png</file> + <file alias="tx_output">res/icons/tx_output.png</file> + <file alias="tx_inout">res/icons/tx_inout.png</file> + <file alias="lock_closed">res/icons/lock_closed.png</file> + <file alias="lock_open">res/icons/lock_open.png</file> + <file alias="key">res/icons/key.png</file> + </qresource> + <qresource prefix="/images"> + <file alias="about">res/images/about.png</file> + <file alias="splash">res/images/splash2.jpg</file> + </qresource> + <qresource prefix="/movies"> + <file alias="update_spinner">res/movies/update_spinner.mng</file> + </qresource> + <qresource prefix="/translations"> + <file alias="de_DE">locale/bitcoin_de.qm</file> + <file alias="nl_NL">locale/bitcoin_nl.qm</file> + <file alias="ru_RU">locale/bitcoin_ru.qm</file> + </qresource> +</RCC> diff --git a/src/qt/bitcoinaddressvalidator.cpp b/src/qt/bitcoinaddressvalidator.cpp new file mode 100644 index 0000000000..373877808f --- /dev/null +++ b/src/qt/bitcoinaddressvalidator.cpp @@ -0,0 +1,67 @@ +#include "bitcoinaddressvalidator.h" + +/* Base58 characters are: + "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz" + + This is: + - All numbers except for '0' + - All uppercase letters except for 'I' and 'O' + - All lowercase letters except for 'l' + + User friendly Base58 input can map + - 'l' and 'I' to '1' + - '0' and 'O' to 'o' +*/ + +BitcoinAddressValidator::BitcoinAddressValidator(QObject *parent) : + QValidator(parent) +{ +} + +QValidator::State BitcoinAddressValidator::validate(QString &input, int &pos) const +{ + // Correction + for(int idx=0; idx<input.size(); ++idx) + { + switch(input.at(idx).unicode()) + { + case 'l': + case 'I': + input[idx] = QChar('1'); + break; + case '0': + case 'O': + input[idx] = QChar('o'); + break; + default: + break; + } + } + + // Validation + QValidator::State state = QValidator::Acceptable; + for(int idx=0; idx<input.size(); ++idx) + { + int ch = input.at(idx).unicode(); + + if(((ch >= '0' && ch<='9') || + (ch >= 'a' && ch<='z') || + (ch >= 'A' && ch<='Z')) && + ch != 'l' && ch != 'I' && ch != '0' && ch != 'O') + { + // Alphanumeric and not a 'forbidden' character + } + else + { + state = QValidator::Invalid; + } + } + + // Empty address is "intermediate" input + if(input.isEmpty()) + { + state = QValidator::Intermediate; + } + + return state; +} diff --git a/src/qt/bitcoinaddressvalidator.h b/src/qt/bitcoinaddressvalidator.h new file mode 100644 index 0000000000..73f6ea1f61 --- /dev/null +++ b/src/qt/bitcoinaddressvalidator.h @@ -0,0 +1,24 @@ +#ifndef BITCOINADDRESSVALIDATOR_H +#define BITCOINADDRESSVALIDATOR_H + +#include <QRegExpValidator> + +/* Base48 entry widget validator. + Corrects near-miss characters and refuses characters that are no part of base48. + */ +class BitcoinAddressValidator : public QValidator +{ + Q_OBJECT +public: + explicit BitcoinAddressValidator(QObject *parent = 0); + + State validate(QString &input, int &pos) const; + + static const int MaxAddressLength = 34; +signals: + +public slots: + +}; + +#endif // BITCOINADDRESSVALIDATOR_H diff --git a/src/qt/bitcoinamountfield.cpp b/src/qt/bitcoinamountfield.cpp new file mode 100644 index 0000000000..f1edc62bbe --- /dev/null +++ b/src/qt/bitcoinamountfield.cpp @@ -0,0 +1,178 @@ +#include "bitcoinamountfield.h" +#include "qvalidatedlineedit.h" +#include "qvaluecombobox.h" +#include "bitcoinunits.h" + +#include <QLabel> +#include <QLineEdit> +#include <QRegExpValidator> +#include <QHBoxLayout> +#include <QKeyEvent> +#include <QComboBox> + +BitcoinAmountField::BitcoinAmountField(QWidget *parent): + QWidget(parent), amount(0), decimals(0), currentUnit(-1) +{ + amount = new QValidatedLineEdit(this); + amount->setValidator(new QRegExpValidator(QRegExp("[0-9]*"), this)); + amount->setAlignment(Qt::AlignRight|Qt::AlignVCenter); + amount->installEventFilter(this); + amount->setMaximumWidth(75); + decimals = new QValidatedLineEdit(this); + decimals->setValidator(new QRegExpValidator(QRegExp("[0-9]+"), this)); + decimals->setAlignment(Qt::AlignLeft|Qt::AlignVCenter); + decimals->setMaximumWidth(75); + + QHBoxLayout *layout = new QHBoxLayout(this); + layout->setSpacing(0); + layout->addWidget(amount); + layout->addWidget(new QLabel(QString("<b>.</b>"))); + layout->addWidget(decimals); + unit = new QValueComboBox(this); + unit->setModel(new BitcoinUnits(this)); + layout->addWidget(unit); + layout->addStretch(1); + layout->setContentsMargins(0,0,0,0); + + setLayout(layout); + + setFocusPolicy(Qt::TabFocus); + setFocusProxy(amount); + + // If one if the widgets changes, the combined content changes as well + connect(amount, SIGNAL(textChanged(QString)), this, SIGNAL(textChanged())); + connect(decimals, SIGNAL(textChanged(QString)), this, SIGNAL(textChanged())); + connect(unit, SIGNAL(currentIndexChanged(int)), this, SLOT(unitChanged(int))); + + // Set default based on configuration + unitChanged(unit->currentIndex()); +} + +void BitcoinAmountField::setText(const QString &text) +{ + const QStringList parts = text.split(QString(".")); + if(parts.size() == 2) + { + amount->setText(parts[0]); + decimals->setText(parts[1]); + } + else + { + amount->setText(QString()); + decimals->setText(QString()); + } +} + +void BitcoinAmountField::clear() +{ + amount->clear(); + decimals->clear(); + unit->setCurrentIndex(0); +} + +bool BitcoinAmountField::validate() +{ + bool valid = true; + if(decimals->text().isEmpty()) + { + decimals->setValid(false); + valid = false; + } + if(!BitcoinUnits::parse(currentUnit, text(), 0)) + { + setValid(false); + valid = false; + } + + return valid; +} + +void BitcoinAmountField::setValid(bool valid) +{ + amount->setValid(valid); + decimals->setValid(valid); +} + +QString BitcoinAmountField::text() const +{ + if(decimals->text().isEmpty() && amount->text().isEmpty()) + { + return QString(); + } + return amount->text() + QString(".") + decimals->text(); +} + +// Intercept '.' and ',' keys, if pressed focus a specified widget +bool BitcoinAmountField::eventFilter(QObject *object, QEvent *event) +{ + Q_UNUSED(object); + if(event->type() == QEvent::KeyPress) + { + QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event); + if(keyEvent->key() == Qt::Key_Period || keyEvent->key() == Qt::Key_Comma) + { + decimals->setFocus(); + decimals->selectAll(); + } + } + return false; +} + +QWidget *BitcoinAmountField::setupTabChain(QWidget *prev) +{ + QWidget::setTabOrder(prev, amount); + QWidget::setTabOrder(amount, decimals); + return decimals; +} + +qint64 BitcoinAmountField::value(bool *valid_out) const +{ + qint64 val_out = 0; + bool valid = BitcoinUnits::parse(currentUnit, text(), &val_out); + if(valid_out) + { + *valid_out = valid; + } + return val_out; +} + +void BitcoinAmountField::setValue(qint64 value) +{ + setText(BitcoinUnits::format(currentUnit, value)); +} + +void BitcoinAmountField::unitChanged(int idx) +{ + // Use description tooltip for current unit for the combobox + unit->setToolTip(unit->itemData(idx, Qt::ToolTipRole).toString()); + + // Determine new unit ID + int newUnit = unit->itemData(idx, BitcoinUnits::UnitRole).toInt(); + + // Parse current value and convert to new unit + bool valid = false; + qint64 currentValue = value(&valid); + + currentUnit = newUnit; + + // Set max length after retrieving the value, to prevent truncation + amount->setMaxLength(BitcoinUnits::amountDigits(currentUnit)); + decimals->setMaxLength(BitcoinUnits::decimals(currentUnit)); + + if(valid) + { + // If value was valid, re-place it in the widget with the new unit + setValue(currentValue); + } + else + { + // If current value is invalid, just clear field + setText(""); + } + setValid(true); +} + +void BitcoinAmountField::setDisplayUnit(int newUnit) +{ + unit->setValue(newUnit); +} diff --git a/src/qt/bitcoinamountfield.h b/src/qt/bitcoinamountfield.h new file mode 100644 index 0000000000..cc92159fed --- /dev/null +++ b/src/qt/bitcoinamountfield.h @@ -0,0 +1,59 @@ +#ifndef BITCOINFIELD_H +#define BITCOINFIELD_H + +#include <QWidget> + +QT_BEGIN_NAMESPACE +class QValidatedLineEdit; +class QValueComboBox; +QT_END_NAMESPACE + +// Coin amount entry widget with separate parts for whole +// coins and decimals. +class BitcoinAmountField: public QWidget +{ + Q_OBJECT + Q_PROPERTY(qint64 value READ value WRITE setValue NOTIFY textChanged USER true); +public: + explicit BitcoinAmountField(QWidget *parent = 0); + + qint64 value(bool *valid=0) const; + void setValue(qint64 value); + + // Mark current valid as invalid in UI + void setValid(bool valid); + bool validate(); + + // Change current unit + void setDisplayUnit(int unit); + + // Make field empty and ready for new input + void clear(); + + // Qt messes up the tab chain by default in some cases (issue http://bugreports.qt.nokia.com/browse/QTBUG-10907) + // Hence we have to set it up manually + QWidget *setupTabChain(QWidget *prev); + +signals: + void textChanged(); + +protected: + // Intercept '.' and ',' keys, if pressed focus a specified widget + bool eventFilter(QObject *object, QEvent *event); + +private: + QValidatedLineEdit *amount; + QValidatedLineEdit *decimals; + QValueComboBox *unit; + int currentUnit; + + void setText(const QString &text); + QString text() const; + +private slots: + void unitChanged(int idx); + +}; + + +#endif // BITCOINFIELD_H diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp new file mode 100644 index 0000000000..be10b97c0f --- /dev/null +++ b/src/qt/bitcoingui.cpp @@ -0,0 +1,608 @@ +/* + * Qt4 bitcoin GUI. + * + * W.J. van der Laan 2011 + */ +#include "bitcoingui.h" +#include "transactiontablemodel.h" +#include "addressbookpage.h" +#include "sendcoinsdialog.h" +#include "optionsdialog.h" +#include "aboutdialog.h" +#include "clientmodel.h" +#include "walletmodel.h" +#include "editaddressdialog.h" +#include "optionsmodel.h" +#include "transactiondescdialog.h" +#include "addresstablemodel.h" +#include "transactionview.h" +#include "overviewpage.h" +#include "bitcoinunits.h" +#include "guiconstants.h" +#include "askpassphrasedialog.h" +#include "notificator.h" + +#include <QApplication> +#include <QMainWindow> +#include <QMenuBar> +#include <QMenu> +#include <QIcon> +#include <QTabWidget> +#include <QVBoxLayout> +#include <QToolBar> +#include <QStatusBar> +#include <QLabel> +#include <QLineEdit> +#include <QPushButton> +#include <QLocale> +#include <QMessageBox> +#include <QProgressBar> +#include <QStackedWidget> +#include <QDateTime> +#include <QMovie> + +#include <QDragEnterEvent> +#include <QUrl> + +#include <iostream> + +BitcoinGUI::BitcoinGUI(QWidget *parent): + QMainWindow(parent), + clientModel(0), + walletModel(0), + encryptWalletAction(0), + changePassphraseAction(0), + trayIcon(0), + notificator(0) +{ + resize(850, 550); + setWindowTitle(tr("Bitcoin Wallet")); + setWindowIcon(QIcon(":icons/bitcoin")); + // Accept D&D of URIs + setAcceptDrops(true); + + createActions(); + + // Menus + QMenu *file = menuBar()->addMenu(tr("&File")); + file->addAction(sendCoinsAction); + file->addAction(receiveCoinsAction); + file->addSeparator(); + file->addAction(quitAction); + + QMenu *settings = menuBar()->addMenu(tr("&Settings")); + settings->addAction(encryptWalletAction); + settings->addAction(changePassphraseAction); + settings->addSeparator(); + settings->addAction(optionsAction); + + QMenu *help = menuBar()->addMenu(tr("&Help")); + help->addAction(aboutAction); + + // Toolbars + QToolBar *toolbar = addToolBar(tr("Tabs toolbar")); + toolbar->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); + toolbar->addAction(overviewAction); + toolbar->addAction(sendCoinsAction); + toolbar->addAction(receiveCoinsAction); + toolbar->addAction(historyAction); + toolbar->addAction(addressBookAction); + + QToolBar *toolbar2 = addToolBar(tr("Actions toolbar")); + toolbar2->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); + toolbar2->addAction(exportAction); + + // Create tabs + overviewPage = new OverviewPage(); + + transactionsPage = new QWidget(this); + QVBoxLayout *vbox = new QVBoxLayout(); + transactionView = new TransactionView(this); + vbox->addWidget(transactionView); + transactionsPage->setLayout(vbox); + + addressBookPage = new AddressBookPage(AddressBookPage::ForEditing, AddressBookPage::SendingTab); + + receiveCoinsPage = new AddressBookPage(AddressBookPage::ForEditing, AddressBookPage::ReceivingTab); + + sendCoinsPage = new SendCoinsDialog(this); + + centralWidget = new QStackedWidget(this); + centralWidget->addWidget(overviewPage); + centralWidget->addWidget(transactionsPage); + centralWidget->addWidget(addressBookPage); + centralWidget->addWidget(receiveCoinsPage); + centralWidget->addWidget(sendCoinsPage); + setCentralWidget(centralWidget); + + // Create status bar + statusBar(); + + // Status bar notification icons + QFrame *frameBlocks = new QFrame(); + //frameBlocks->setFrameStyle(QFrame::Panel | QFrame::Sunken); + frameBlocks->setContentsMargins(0,0,0,0); + frameBlocks->setMinimumWidth(56); + frameBlocks->setMaximumWidth(56); + QHBoxLayout *frameBlocksLayout = new QHBoxLayout(frameBlocks); + frameBlocksLayout->setContentsMargins(3,0,3,0); + frameBlocksLayout->setSpacing(3); + labelEncryptionIcon = new QLabel(); + labelConnectionsIcon = new QLabel(); + labelBlocksIcon = new QLabel(); + frameBlocksLayout->addStretch(); + frameBlocksLayout->addWidget(labelEncryptionIcon); + frameBlocksLayout->addStretch(); + frameBlocksLayout->addWidget(labelConnectionsIcon); + frameBlocksLayout->addStretch(); + frameBlocksLayout->addWidget(labelBlocksIcon); + frameBlocksLayout->addStretch(); + + // Progress bar for blocks download + progressBarLabel = new QLabel(tr("Synchronizing with network...")); + progressBarLabel->setVisible(false); + progressBar = new QProgressBar(); + progressBar->setToolTip(tr("Block chain synchronization in progress")); + progressBar->setVisible(false); + + statusBar()->addWidget(progressBarLabel); + statusBar()->addWidget(progressBar); + statusBar()->addPermanentWidget(frameBlocks); + + createTrayIcon(); + + syncIconMovie = new QMovie(":/movies/update_spinner", "mng", this); + + // Clicking on a transaction on the overview page simply sends you to transaction history page + connect(overviewPage, SIGNAL(transactionClicked(QModelIndex)), this, SLOT(gotoHistoryPage())); + + // Doubleclicking on a transaction on the transaction history page shows details + connect(transactionView, SIGNAL(doubleClicked(QModelIndex)), transactionView, SLOT(showDetails())); + + gotoOverviewPage(); +} + +void BitcoinGUI::createActions() +{ + QActionGroup *tabGroup = new QActionGroup(this); + + overviewAction = new QAction(QIcon(":/icons/overview"), tr("&Overview"), this); + overviewAction->setToolTip(tr("Show general overview of wallet")); + overviewAction->setCheckable(true); + tabGroup->addAction(overviewAction); + + historyAction = new QAction(QIcon(":/icons/history"), tr("&Transactions"), this); + historyAction->setToolTip(tr("Browse transaction history")); + historyAction->setCheckable(true); + tabGroup->addAction(historyAction); + + addressBookAction = new QAction(QIcon(":/icons/address-book"), tr("&Address Book"), this); + addressBookAction->setToolTip(tr("Edit the list of stored addresses and labels")); + addressBookAction->setCheckable(true); + tabGroup->addAction(addressBookAction); + + receiveCoinsAction = new QAction(QIcon(":/icons/receiving_addresses"), tr("&Receive coins"), this); + receiveCoinsAction->setToolTip(tr("Show the list of addresses for receiving payments")); + receiveCoinsAction->setCheckable(true); + tabGroup->addAction(receiveCoinsAction); + + sendCoinsAction = new QAction(QIcon(":/icons/send"), tr("&Send coins"), this); + sendCoinsAction->setToolTip(tr("Send coins to a bitcoin address")); + sendCoinsAction->setCheckable(true); + tabGroup->addAction(sendCoinsAction); + + connect(overviewAction, SIGNAL(triggered()), this, SLOT(gotoOverviewPage())); + connect(historyAction, SIGNAL(triggered()), this, SLOT(gotoHistoryPage())); + connect(addressBookAction, SIGNAL(triggered()), this, SLOT(gotoAddressBookPage())); + connect(receiveCoinsAction, SIGNAL(triggered()), this, SLOT(gotoReceiveCoinsPage())); + connect(sendCoinsAction, SIGNAL(triggered()), this, SLOT(gotoSendCoinsPage())); + + quitAction = new QAction(QIcon(":/icons/quit"), tr("&Exit"), this); + quitAction->setToolTip(tr("Quit application")); + aboutAction = new QAction(QIcon(":/icons/bitcoin"), tr("&About"), this); + aboutAction->setToolTip(tr("Show information about Bitcoin")); + optionsAction = new QAction(QIcon(":/icons/options"), tr("&Options..."), this); + optionsAction->setToolTip(tr("Modify configuration options for bitcoin")); + openBitcoinAction = new QAction(QIcon(":/icons/bitcoin"), tr("Open &Bitcoin"), this); + openBitcoinAction->setToolTip(tr("Show the Bitcoin window")); + exportAction = new QAction(QIcon(":/icons/export"), tr("&Export..."), this); + exportAction->setToolTip(tr("Export the current view to a file")); + encryptWalletAction = new QAction(QIcon(":/icons/lock_closed"), tr("&Encrypt Wallet"), this); + encryptWalletAction->setToolTip(tr("Encrypt or decrypt wallet")); + encryptWalletAction->setCheckable(true); + changePassphraseAction = new QAction(QIcon(":/icons/key"), tr("&Change Passphrase"), this); + changePassphraseAction->setToolTip(tr("Change the passphrase used for wallet encryption")); + + connect(quitAction, SIGNAL(triggered()), qApp, SLOT(quit())); + connect(optionsAction, SIGNAL(triggered()), this, SLOT(optionsClicked())); + connect(aboutAction, SIGNAL(triggered()), this, SLOT(aboutClicked())); + connect(openBitcoinAction, SIGNAL(triggered()), this, SLOT(showNormal())); + connect(encryptWalletAction, SIGNAL(triggered(bool)), this, SLOT(encryptWallet(bool))); + connect(changePassphraseAction, SIGNAL(triggered()), this, SLOT(changePassphrase())); +} + +void BitcoinGUI::setClientModel(ClientModel *clientModel) +{ + this->clientModel = clientModel; + + if(clientModel->isTestNet()) + { + QString title_testnet = windowTitle() + QString(" ") + tr("[testnet]"); + setWindowTitle(title_testnet); + setWindowIcon(QIcon(":icons/bitcoin_testnet")); + if(trayIcon) + { + trayIcon->setToolTip(title_testnet); + trayIcon->setIcon(QIcon(":/icons/toolbar_testnet")); + } + } + + // Keep up to date with client + setNumConnections(clientModel->getNumConnections()); + connect(clientModel, SIGNAL(numConnectionsChanged(int)), this, SLOT(setNumConnections(int))); + + setNumBlocks(clientModel->getNumBlocks()); + connect(clientModel, SIGNAL(numBlocksChanged(int)), this, SLOT(setNumBlocks(int))); + + // Report errors from network/worker thread + connect(clientModel, SIGNAL(error(QString,QString)), this, SLOT(error(QString,QString))); +} + +void BitcoinGUI::setWalletModel(WalletModel *walletModel) +{ + this->walletModel = walletModel; + + // Report errors from wallet thread + connect(walletModel, SIGNAL(error(QString,QString)), this, SLOT(error(QString,QString))); + + // Put transaction list in tabs + transactionView->setModel(walletModel); + + overviewPage->setModel(walletModel); + addressBookPage->setModel(walletModel->getAddressTableModel()); + receiveCoinsPage->setModel(walletModel->getAddressTableModel()); + sendCoinsPage->setModel(walletModel); + + setEncryptionStatus(walletModel->getEncryptionStatus()); + connect(walletModel, SIGNAL(encryptionStatusChanged(int)), this, SLOT(setEncryptionStatus(int))); + + // Balloon popup for new transaction + connect(walletModel->getTransactionTableModel(), SIGNAL(rowsInserted(QModelIndex,int,int)), + this, SLOT(incomingTransaction(QModelIndex,int,int))); + + // Ask for passphrase if needed + connect(walletModel, SIGNAL(requireUnlock()), this, SLOT(unlockWallet())); +} + +void BitcoinGUI::createTrayIcon() +{ + QMenu *trayIconMenu = new QMenu(this); + trayIconMenu->addAction(openBitcoinAction); + trayIconMenu->addAction(optionsAction); + trayIconMenu->addSeparator(); + trayIconMenu->addAction(quitAction); + + trayIcon = new QSystemTrayIcon(this); + trayIcon->setContextMenu(trayIconMenu); + trayIcon->setToolTip("Bitcoin client"); + trayIcon->setIcon(QIcon(":/icons/toolbar")); + connect(trayIcon, SIGNAL(activated(QSystemTrayIcon::ActivationReason)), + this, SLOT(trayIconActivated(QSystemTrayIcon::ActivationReason))); + trayIcon->show(); + + notificator = new Notificator(tr("bitcoin-qt"), trayIcon); +} + +void BitcoinGUI::trayIconActivated(QSystemTrayIcon::ActivationReason reason) +{ + if(reason == QSystemTrayIcon::Trigger) + { + // Click on system tray icon triggers "open bitcoin" + openBitcoinAction->trigger(); + } + +} + +void BitcoinGUI::optionsClicked() +{ + OptionsDialog dlg; + dlg.setModel(clientModel->getOptionsModel()); + dlg.exec(); +} + +void BitcoinGUI::aboutClicked() +{ + AboutDialog dlg; + dlg.setModel(clientModel); + dlg.exec(); +} + +void BitcoinGUI::setNumConnections(int count) +{ + QString icon; + switch(count) + { + case 0: icon = ":/icons/connect_0"; break; + case 1: case 2: case 3: icon = ":/icons/connect_1"; break; + case 4: case 5: case 6: icon = ":/icons/connect_2"; break; + case 7: case 8: case 9: icon = ":/icons/connect_3"; break; + default: icon = ":/icons/connect_4"; break; + } + labelConnectionsIcon->setPixmap(QIcon(icon).pixmap(STATUSBAR_ICONSIZE,STATUSBAR_ICONSIZE)); + labelConnectionsIcon->setToolTip(tr("%n active connection(s) to Bitcoin network", "", count)); +} + +void BitcoinGUI::setNumBlocks(int count) +{ + int initTotal = clientModel->getNumBlocksAtStartup(); + int total = clientModel->getNumBlocksOfPeers(); + QString tooltip; + + if(count < total) + { + progressBarLabel->setVisible(true); + progressBar->setVisible(true); + progressBar->setMaximum(total - initTotal); + progressBar->setValue(count - initTotal); + tooltip = tr("Downloaded %1 of %2 blocks of transaction history.").arg(count).arg(total); + } + else + { + progressBarLabel->setVisible(false); + progressBar->setVisible(false); + tooltip = tr("Downloaded %1 blocks of transaction history.").arg(count); + } + + QDateTime now = QDateTime::currentDateTime(); + QDateTime lastBlockDate = clientModel->getLastBlockDate(); + int secs = lastBlockDate.secsTo(now); + QString text; + + // Represent time from last generated block in human readable text + if(secs < 60) + { + text = tr("%n second(s) ago","",secs); + } + else if(secs < 60*60) + { + text = tr("%n minute(s) ago","",secs/60); + } + else if(secs < 24*60*60) + { + text = tr("%n hour(s) ago","",secs/(60*60)); + } + else + { + text = tr("%n day(s) ago","",secs/(60*60*24)); + } + + // Set icon state: spinning if catching up, tick otherwise + if(secs < 30*60) + { + tooltip = tr("Up to date") + QString("\n") + tooltip; + labelBlocksIcon->setPixmap(QIcon(":/icons/synced").pixmap(STATUSBAR_ICONSIZE,STATUSBAR_ICONSIZE)); + } + else + { + tooltip = tr("Catching up...") + QString("\n") + tooltip; + labelBlocksIcon->setMovie(syncIconMovie); + syncIconMovie->start(); + } + + tooltip += QString("\n"); + tooltip += tr("Last received block was generated %1.").arg(text); + + labelBlocksIcon->setToolTip(tooltip); + progressBarLabel->setToolTip(tooltip); + progressBar->setToolTip(tooltip); +} + +void BitcoinGUI::error(const QString &title, const QString &message) +{ + // Report errors from network/worker thread + notificator->notify(Notificator::Critical, title, message); +} + +void BitcoinGUI::changeEvent(QEvent *e) +{ + if (e->type() == QEvent::WindowStateChange) + { + if(clientModel->getOptionsModel()->getMinimizeToTray()) + { + if (isMinimized()) + { + hide(); + e->ignore(); + } + else + { + show(); + e->accept(); + } + } + } + QMainWindow::changeEvent(e); +} + +void BitcoinGUI::closeEvent(QCloseEvent *event) +{ + if(!clientModel->getOptionsModel()->getMinimizeToTray() && + !clientModel->getOptionsModel()->getMinimizeOnClose()) + { + qApp->quit(); + } + QMainWindow::closeEvent(event); +} + +void BitcoinGUI::askFee(qint64 nFeeRequired, bool *payFee) +{ + QString strMessage = + tr("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?").arg( + BitcoinUnits::formatWithUnit(BitcoinUnits::BTC, nFeeRequired)); + QMessageBox::StandardButton retval = QMessageBox::question( + this, tr("Sending..."), strMessage, + QMessageBox::Yes|QMessageBox::Cancel, QMessageBox::Yes); + *payFee = (retval == QMessageBox::Yes); +} + +void BitcoinGUI::incomingTransaction(const QModelIndex & parent, int start, int end) +{ + TransactionTableModel *ttm = walletModel->getTransactionTableModel(); + qint64 amount = ttm->index(start, TransactionTableModel::Amount, parent) + .data(Qt::EditRole).toULongLong(); + if(!clientModel->inInitialBlockDownload()) + { + // On new transaction, make an info balloon + // Unless the initial block download is in progress, to prevent balloon-spam + QString date = ttm->index(start, TransactionTableModel::Date, parent) + .data().toString(); + QString type = ttm->index(start, TransactionTableModel::Type, parent) + .data().toString(); + QString address = ttm->index(start, TransactionTableModel::ToAddress, parent) + .data().toString(); + QIcon icon = qvariant_cast<QIcon>(ttm->index(start, + TransactionTableModel::ToAddress, parent) + .data(Qt::DecorationRole)); + + notificator->notify(Notificator::Information, + (amount)<0 ? tr("Sent transaction") : + tr("Incoming transaction"), + tr("Date: %1\n" + "Amount: %2\n" + "Type: %3\n" + "Address: %4\n") + .arg(date) + .arg(BitcoinUnits::formatWithUnit(walletModel->getOptionsModel()->getDisplayUnit(), amount, true)) + .arg(type) + .arg(address), icon); + } +} + +void BitcoinGUI::gotoOverviewPage() +{ + overviewAction->setChecked(true); + centralWidget->setCurrentWidget(overviewPage); + + exportAction->setEnabled(false); + disconnect(exportAction, SIGNAL(triggered()), 0, 0); +} + +void BitcoinGUI::gotoHistoryPage() +{ + historyAction->setChecked(true); + centralWidget->setCurrentWidget(transactionsPage); + + exportAction->setEnabled(true); + disconnect(exportAction, SIGNAL(triggered()), 0, 0); + connect(exportAction, SIGNAL(triggered()), transactionView, SLOT(exportClicked())); +} + +void BitcoinGUI::gotoAddressBookPage() +{ + addressBookAction->setChecked(true); + centralWidget->setCurrentWidget(addressBookPage); + + exportAction->setEnabled(true); + disconnect(exportAction, SIGNAL(triggered()), 0, 0); + connect(exportAction, SIGNAL(triggered()), addressBookPage, SLOT(exportClicked())); +} + +void BitcoinGUI::gotoReceiveCoinsPage() +{ + receiveCoinsAction->setChecked(true); + centralWidget->setCurrentWidget(receiveCoinsPage); + + exportAction->setEnabled(true); + disconnect(exportAction, SIGNAL(triggered()), 0, 0); + connect(exportAction, SIGNAL(triggered()), receiveCoinsPage, SLOT(exportClicked())); +} + +void BitcoinGUI::gotoSendCoinsPage() +{ + sendCoinsAction->setChecked(true); + centralWidget->setCurrentWidget(sendCoinsPage); + + exportAction->setEnabled(false); + disconnect(exportAction, SIGNAL(triggered()), 0, 0); +} + +void BitcoinGUI::dragEnterEvent(QDragEnterEvent *event) +{ + // Accept only URLs + if(event->mimeData()->hasUrls()) + event->acceptProposedAction(); +} + +void BitcoinGUI::dropEvent(QDropEvent *event) +{ + if(event->mimeData()->hasUrls()) + { + gotoSendCoinsPage(); + QList<QUrl> urls = event->mimeData()->urls(); + foreach(const QUrl &url, urls) + { + sendCoinsPage->handleURL(&url); + } + } + + event->acceptProposedAction(); +} + +void BitcoinGUI::setEncryptionStatus(int status) +{ + switch(status) + { + case WalletModel::Unencrypted: + labelEncryptionIcon->hide(); + encryptWalletAction->setChecked(false); + changePassphraseAction->setEnabled(false); + encryptWalletAction->setEnabled(true); + break; + case WalletModel::Unlocked: + labelEncryptionIcon->show(); + labelEncryptionIcon->setPixmap(QIcon(":/icons/lock_open").pixmap(STATUSBAR_ICONSIZE,STATUSBAR_ICONSIZE)); + labelEncryptionIcon->setToolTip(tr("Wallet is <b>encrypted</b> and currently <b>unlocked</b>")); + encryptWalletAction->setChecked(true); + changePassphraseAction->setEnabled(true); + encryptWalletAction->setEnabled(false); // TODO: decrypt currently not supported + break; + case WalletModel::Locked: + labelEncryptionIcon->show(); + labelEncryptionIcon->setPixmap(QIcon(":/icons/lock_closed").pixmap(STATUSBAR_ICONSIZE,STATUSBAR_ICONSIZE)); + labelEncryptionIcon->setToolTip(tr("Wallet is <b>encrypted</b> and currently <b>locked</b>")); + encryptWalletAction->setChecked(true); + changePassphraseAction->setEnabled(true); + encryptWalletAction->setEnabled(false); // TODO: decrypt currently not supported + break; + } +} + +void BitcoinGUI::encryptWallet(bool status) +{ + AskPassphraseDialog dlg(status ? AskPassphraseDialog::Encrypt: + AskPassphraseDialog::Decrypt, this); + dlg.setModel(walletModel); + dlg.exec(); + + setEncryptionStatus(walletModel->getEncryptionStatus()); +} + +void BitcoinGUI::changePassphrase() +{ + AskPassphraseDialog dlg(AskPassphraseDialog::ChangePass, this); + dlg.setModel(walletModel); + dlg.exec(); +} + +void BitcoinGUI::unlockWallet() +{ + // Unlock wallet when requested by wallet model + if(walletModel->getEncryptionStatus() == WalletModel::Locked) + { + AskPassphraseDialog dlg(AskPassphraseDialog::Unlock, this); + dlg.setModel(walletModel); + dlg.exec(); + } +} diff --git a/src/qt/bitcoingui.h b/src/qt/bitcoingui.h new file mode 100644 index 0000000000..59661350c3 --- /dev/null +++ b/src/qt/bitcoingui.h @@ -0,0 +1,120 @@ +#ifndef BITCOINGUI_H +#define BITCOINGUI_H + +#include <QMainWindow> +#include <QSystemTrayIcon> + +class TransactionTableModel; +class ClientModel; +class WalletModel; +class TransactionView; +class OverviewPage; +class AddressBookPage; +class SendCoinsDialog; +class Notificator; + +QT_BEGIN_NAMESPACE +class QLabel; +class QLineEdit; +class QTableView; +class QAbstractItemModel; +class QModelIndex; +class QProgressBar; +class QStackedWidget; +class QUrl; +QT_END_NAMESPACE + +class BitcoinGUI : public QMainWindow +{ + Q_OBJECT +public: + explicit BitcoinGUI(QWidget *parent = 0); + void setClientModel(ClientModel *clientModel); + void setWalletModel(WalletModel *walletModel); + + /* Transaction table tab indices */ + enum { + AllTransactions = 0, + SentReceived = 1, + Sent = 2, + Received = 3 + } TabIndex; + +protected: + void changeEvent(QEvent *e); + void closeEvent(QCloseEvent *event); + void dragEnterEvent(QDragEnterEvent *event); + void dropEvent(QDropEvent *event); + +private: + ClientModel *clientModel; + WalletModel *walletModel; + + QStackedWidget *centralWidget; + + OverviewPage *overviewPage; + QWidget *transactionsPage; + AddressBookPage *addressBookPage; + AddressBookPage *receiveCoinsPage; + SendCoinsDialog *sendCoinsPage; + + QLabel *labelEncryptionIcon; + QLabel *labelConnectionsIcon; + QLabel *labelBlocksIcon; + QLabel *progressBarLabel; + QProgressBar *progressBar; + + QAction *overviewAction; + QAction *historyAction; + QAction *quitAction; + QAction *sendCoinsAction; + QAction *addressBookAction; + QAction *aboutAction; + QAction *receiveCoinsAction; + QAction *optionsAction; + QAction *openBitcoinAction; + QAction *exportAction; + QAction *encryptWalletAction; + QAction *changePassphraseAction; + + QSystemTrayIcon *trayIcon; + Notificator *notificator; + TransactionView *transactionView; + + QMovie *syncIconMovie; + + void createActions(); + QWidget *createTabs(); + void createTrayIcon(); + +public slots: + void setNumConnections(int count); + void setNumBlocks(int count); + void setEncryptionStatus(int status); + + void error(const QString &title, const QString &message); + /* It is currently not possible to pass a return value to another thread through + BlockingQueuedConnection, so use an indirected pointer. + http://bugreports.qt.nokia.com/browse/QTBUG-10440 + */ + void askFee(qint64 nFeeRequired, bool *payFee); + +private slots: + // UI pages + void gotoOverviewPage(); + void gotoHistoryPage(); + void gotoAddressBookPage(); + void gotoReceiveCoinsPage(); + void gotoSendCoinsPage(); + + // Misc actions + void optionsClicked(); + void aboutClicked(); + void trayIconActivated(QSystemTrayIcon::ActivationReason reason); + void incomingTransaction(const QModelIndex & parent, int start, int end); + void encryptWallet(bool status); + void changePassphrase(); + void unlockWallet(); +}; + +#endif diff --git a/src/qt/bitcoinstrings.cpp b/src/qt/bitcoinstrings.cpp new file mode 100644 index 0000000000..45aadd49a5 --- /dev/null +++ b/src/qt/bitcoinstrings.cpp @@ -0,0 +1,217 @@ +#include <QtGlobal> +// Automatically generated by extract_strings.py +static const char *bitcoin_strings[] = {QT_TRANSLATE_NOOP("bitcoin-core", "Bitcoin version"), +QT_TRANSLATE_NOOP("bitcoin-core", "Usage:"), +QT_TRANSLATE_NOOP("bitcoin-core", "Send command to -server or bitcoind\n"), +QT_TRANSLATE_NOOP("bitcoin-core", "List commands\n"), +QT_TRANSLATE_NOOP("bitcoin-core", "Get help for a command\n"), +QT_TRANSLATE_NOOP("bitcoin-core", "Options:\n"), +QT_TRANSLATE_NOOP("bitcoin-core", "Specify configuration file (default: bitcoin.conf)\n"), +QT_TRANSLATE_NOOP("bitcoin-core", "Specify pid file (default: bitcoind.pid)\n"), +QT_TRANSLATE_NOOP("bitcoin-core", "Generate coins\n"), +QT_TRANSLATE_NOOP("bitcoin-core", "Don't generate coins\n"), +QT_TRANSLATE_NOOP("bitcoin-core", "Start minimized\n"), +QT_TRANSLATE_NOOP("bitcoin-core", "Specify data directory\n"), +QT_TRANSLATE_NOOP("bitcoin-core", "Specify connection timeout (in milliseconds)\n"), +QT_TRANSLATE_NOOP("bitcoin-core", "Connect through socks4 proxy\n"), +QT_TRANSLATE_NOOP("bitcoin-core", "Allow DNS lookups for addnode and connect\n"), +QT_TRANSLATE_NOOP("bitcoin-core", "Add a node to connect to\n"), +QT_TRANSLATE_NOOP("bitcoin-core", "Connect only to the specified node\n"), +QT_TRANSLATE_NOOP("bitcoin-core", "Don't accept connections from outside\n"), +QT_TRANSLATE_NOOP("bitcoin-core", "Don't attempt to use UPnP to map the listening port\n"), +QT_TRANSLATE_NOOP("bitcoin-core", "Attempt to use UPnP to map the listening port\n"), +QT_TRANSLATE_NOOP("bitcoin-core", "Fee per KB to add to transactions you send\n"), +QT_TRANSLATE_NOOP("bitcoin-core", "Accept command line and JSON-RPC commands\n"), +QT_TRANSLATE_NOOP("bitcoin-core", "Run in the background as a daemon and accept commands\n"), +QT_TRANSLATE_NOOP("bitcoin-core", "Use the test network\n"), +QT_TRANSLATE_NOOP("bitcoin-core", "Username for JSON-RPC connections\n"), +QT_TRANSLATE_NOOP("bitcoin-core", "Password for JSON-RPC connections\n"), +QT_TRANSLATE_NOOP("bitcoin-core", "Listen for JSON-RPC connections on <port> (default: 8332)\n"), +QT_TRANSLATE_NOOP("bitcoin-core", "Allow JSON-RPC connections from specified IP address\n"), +QT_TRANSLATE_NOOP("bitcoin-core", "Send commands to node running on <ip> (default: 127.0.0.1)\n"), +QT_TRANSLATE_NOOP("bitcoin-core", "Set key pool size to <n> (default: 100)\n"), +QT_TRANSLATE_NOOP("bitcoin-core", "Rescan the block chain for missing wallet transactions\n"), +QT_TRANSLATE_NOOP("bitcoin-core", "" +"\n" +"SSL options: (see the Bitcoin Wiki for SSL setup instructions)\n"), +QT_TRANSLATE_NOOP("bitcoin-core", "Use OpenSSL (https) for JSON-RPC connections\n"), +QT_TRANSLATE_NOOP("bitcoin-core", "Server certificate file (default: server.cert)\n"), +QT_TRANSLATE_NOOP("bitcoin-core", "Server private key (default: server.pem)\n"), +QT_TRANSLATE_NOOP("bitcoin-core", "" +"Acceptable ciphers (default: TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!AH:!3DES:" +"@STRENGTH)\n"), +QT_TRANSLATE_NOOP("bitcoin-core", "This help message\n"), +QT_TRANSLATE_NOOP("bitcoin-core", "" +"Cannot obtain a lock on data directory %s. Bitcoin is probably already " +"running."), +QT_TRANSLATE_NOOP("bitcoin-core", "Loading addresses..."), +QT_TRANSLATE_NOOP("bitcoin-core", "Error loading addr.dat \n"), +QT_TRANSLATE_NOOP("bitcoin-core", "Loading block index..."), +QT_TRANSLATE_NOOP("bitcoin-core", "Error loading blkindex.dat \n"), +QT_TRANSLATE_NOOP("bitcoin-core", "Loading wallet..."), +QT_TRANSLATE_NOOP("bitcoin-core", "Error loading wallet.dat: Wallet corrupted \n"), +QT_TRANSLATE_NOOP("bitcoin-core", "" +"Error loading wallet.dat: Wallet requires newer version of Bitcoin \n"), +QT_TRANSLATE_NOOP("bitcoin-core", "Error loading wallet.dat \n"), +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", "" +"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", "Warning: Disk space is low "), +QT_TRANSLATE_NOOP("bitcoin-core", "" +"Unable to bind to port %d on this computer. Bitcoin is probably already " +"running."), +QT_TRANSLATE_NOOP("bitcoin-core", "" +"This transaction is over the size limit. You can still send it for a fee of " +"%s, which goes to the nodes that process your transaction and helps to " +"support the network. Do you want to pay the fee?"), +QT_TRANSLATE_NOOP("bitcoin-core", "Enter the current passphrase to the wallet."), +QT_TRANSLATE_NOOP("bitcoin-core", "Passphrase"), +QT_TRANSLATE_NOOP("bitcoin-core", "Please supply the current wallet decryption passphrase."), +QT_TRANSLATE_NOOP("bitcoin-core", "The passphrase entered for the wallet decryption was incorrect."), +QT_TRANSLATE_NOOP("bitcoin-core", "Status"), +QT_TRANSLATE_NOOP("bitcoin-core", "Date"), +QT_TRANSLATE_NOOP("bitcoin-core", "Description"), +QT_TRANSLATE_NOOP("bitcoin-core", "Debit"), +QT_TRANSLATE_NOOP("bitcoin-core", "Credit"), +QT_TRANSLATE_NOOP("bitcoin-core", "Open for %d blocks"), +QT_TRANSLATE_NOOP("bitcoin-core", "Open until %s"), +QT_TRANSLATE_NOOP("bitcoin-core", "%d/offline?"), +QT_TRANSLATE_NOOP("bitcoin-core", "%d/unconfirmed"), +QT_TRANSLATE_NOOP("bitcoin-core", "%d confirmations"), +QT_TRANSLATE_NOOP("bitcoin-core", "Generated"), +QT_TRANSLATE_NOOP("bitcoin-core", "Generated (%s matures in %d more blocks)"), +QT_TRANSLATE_NOOP("bitcoin-core", "" +"Generated - Warning: This block was not received by any other nodes and will " +"probably not be accepted!"), +QT_TRANSLATE_NOOP("bitcoin-core", "Generated (not accepted)"), +QT_TRANSLATE_NOOP("bitcoin-core", "From: "), +QT_TRANSLATE_NOOP("bitcoin-core", "Received with: "), +QT_TRANSLATE_NOOP("bitcoin-core", "Payment to yourself"), +QT_TRANSLATE_NOOP("bitcoin-core", "To: "), +QT_TRANSLATE_NOOP("bitcoin-core", " Generating"), +QT_TRANSLATE_NOOP("bitcoin-core", "(not connected)"), +QT_TRANSLATE_NOOP("bitcoin-core", " %d connections %d blocks %d transactions"), +QT_TRANSLATE_NOOP("bitcoin-core", "Wallet already encrypted."), +QT_TRANSLATE_NOOP("bitcoin-core", "" +"Enter the new passphrase to the wallet.\n" +"Please use a passphrase of 10 or more random characters, or eight or more " +"words."), +QT_TRANSLATE_NOOP("bitcoin-core", "Error: The supplied passphrase was too short."), +QT_TRANSLATE_NOOP("bitcoin-core", "" +"WARNING: If you encrypt your wallet and lose your passphrase, you will LOSE " +"ALL OF YOUR BITCOINS!\n" +"Are you sure you wish to encrypt your wallet?"), +QT_TRANSLATE_NOOP("bitcoin-core", "Please re-enter your new wallet passphrase."), +QT_TRANSLATE_NOOP("bitcoin-core", "Error: the supplied passphrases didn't match."), +QT_TRANSLATE_NOOP("bitcoin-core", "Wallet encryption failed."), +QT_TRANSLATE_NOOP("bitcoin-core", "" +"Wallet Encrypted.\n" +"Remember that encrypting your wallet cannot fully protect your bitcoins from " +"being stolen by malware infecting your computer."), +QT_TRANSLATE_NOOP("bitcoin-core", "Wallet is unencrypted, please encrypt it first."), +QT_TRANSLATE_NOOP("bitcoin-core", "Enter the new passphrase for the wallet."), +QT_TRANSLATE_NOOP("bitcoin-core", "Re-enter the new passphrase for the wallet."), +QT_TRANSLATE_NOOP("bitcoin-core", "Wallet Passphrase Changed."), +QT_TRANSLATE_NOOP("bitcoin-core", "New Receiving Address"), +QT_TRANSLATE_NOOP("bitcoin-core", "" +"You should use a new address for each payment you receive.\n" +"\n" +"Label"), +QT_TRANSLATE_NOOP("bitcoin-core", "<b>Status:</b> "), +QT_TRANSLATE_NOOP("bitcoin-core", ", has not been successfully broadcast yet"), +QT_TRANSLATE_NOOP("bitcoin-core", ", broadcast through %d node"), +QT_TRANSLATE_NOOP("bitcoin-core", ", broadcast through %d nodes"), +QT_TRANSLATE_NOOP("bitcoin-core", "<b>Date:</b> "), +QT_TRANSLATE_NOOP("bitcoin-core", "<b>Source:</b> Generated<br>"), +QT_TRANSLATE_NOOP("bitcoin-core", "<b>From:</b> "), +QT_TRANSLATE_NOOP("bitcoin-core", "unknown"), +QT_TRANSLATE_NOOP("bitcoin-core", "<b>To:</b> "), +QT_TRANSLATE_NOOP("bitcoin-core", " (yours, label: "), +QT_TRANSLATE_NOOP("bitcoin-core", " (yours)"), +QT_TRANSLATE_NOOP("bitcoin-core", "<b>Credit:</b> "), +QT_TRANSLATE_NOOP("bitcoin-core", "(%s matures in %d more blocks)"), +QT_TRANSLATE_NOOP("bitcoin-core", "(not accepted)"), +QT_TRANSLATE_NOOP("bitcoin-core", "<b>Debit:</b> "), +QT_TRANSLATE_NOOP("bitcoin-core", "<b>Transaction fee:</b> "), +QT_TRANSLATE_NOOP("bitcoin-core", "<b>Net amount:</b> "), +QT_TRANSLATE_NOOP("bitcoin-core", "Message:"), +QT_TRANSLATE_NOOP("bitcoin-core", "Comment:"), +QT_TRANSLATE_NOOP("bitcoin-core", "" +"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 \"not " +"accepted\" and not be spendable. This may occasionally happen if another " +"node generates a block within a few seconds of yours."), +QT_TRANSLATE_NOOP("bitcoin-core", "Cannot write autostart/bitcoin.desktop file"), +QT_TRANSLATE_NOOP("bitcoin-core", "Main"), +QT_TRANSLATE_NOOP("bitcoin-core", "&Start Bitcoin on window system startup"), +QT_TRANSLATE_NOOP("bitcoin-core", "&Minimize on close"), +QT_TRANSLATE_NOOP("bitcoin-core", "version %s"), +QT_TRANSLATE_NOOP("bitcoin-core", "Error in amount "), +QT_TRANSLATE_NOOP("bitcoin-core", "Send Coins"), +QT_TRANSLATE_NOOP("bitcoin-core", "Amount exceeds your balance "), +QT_TRANSLATE_NOOP("bitcoin-core", "Total exceeds your balance when the "), +QT_TRANSLATE_NOOP("bitcoin-core", " transaction fee is included "), +QT_TRANSLATE_NOOP("bitcoin-core", "Payment sent "), +QT_TRANSLATE_NOOP("bitcoin-core", "Sending..."), +QT_TRANSLATE_NOOP("bitcoin-core", "Invalid address "), +QT_TRANSLATE_NOOP("bitcoin-core", "Sending %s to %s"), +QT_TRANSLATE_NOOP("bitcoin-core", "CANCELLED"), +QT_TRANSLATE_NOOP("bitcoin-core", "Cancelled"), +QT_TRANSLATE_NOOP("bitcoin-core", "Transfer cancelled "), +QT_TRANSLATE_NOOP("bitcoin-core", "Error: "), +QT_TRANSLATE_NOOP("bitcoin-core", "Insufficient funds"), +QT_TRANSLATE_NOOP("bitcoin-core", "Connecting..."), +QT_TRANSLATE_NOOP("bitcoin-core", "Unable to connect"), +QT_TRANSLATE_NOOP("bitcoin-core", "Requesting public key..."), +QT_TRANSLATE_NOOP("bitcoin-core", "Received public key..."), +QT_TRANSLATE_NOOP("bitcoin-core", "Recipient is not accepting transactions sent by IP address"), +QT_TRANSLATE_NOOP("bitcoin-core", "Transfer was not accepted"), +QT_TRANSLATE_NOOP("bitcoin-core", "Invalid response received"), +QT_TRANSLATE_NOOP("bitcoin-core", "Creating transaction..."), +QT_TRANSLATE_NOOP("bitcoin-core", "" +"This transaction requires a transaction fee of at least %s because of its " +"amount, complexity, or use of recently received funds"), +QT_TRANSLATE_NOOP("bitcoin-core", "Transaction creation failed"), +QT_TRANSLATE_NOOP("bitcoin-core", "Transaction aborted"), +QT_TRANSLATE_NOOP("bitcoin-core", "Lost connection, transaction cancelled"), +QT_TRANSLATE_NOOP("bitcoin-core", "Sending payment..."), +QT_TRANSLATE_NOOP("bitcoin-core", "" +"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."), +QT_TRANSLATE_NOOP("bitcoin-core", "Waiting for confirmation..."), +QT_TRANSLATE_NOOP("bitcoin-core", "" +"The payment was sent, but the recipient was unable to verify it.\n" +"The transaction is recorded and will credit to the recipient,\n" +"but the comment information will be blank."), +QT_TRANSLATE_NOOP("bitcoin-core", "Payment was sent, but an invalid response was received"), +QT_TRANSLATE_NOOP("bitcoin-core", "Payment completed"), +QT_TRANSLATE_NOOP("bitcoin-core", "Name"), +QT_TRANSLATE_NOOP("bitcoin-core", "Address"), +QT_TRANSLATE_NOOP("bitcoin-core", "Label"), +QT_TRANSLATE_NOOP("bitcoin-core", "Bitcoin Address"), +QT_TRANSLATE_NOOP("bitcoin-core", "" +"This is one of your own addresses for receiving payments and cannot be " +"entered in the address book. "), +QT_TRANSLATE_NOOP("bitcoin-core", "Edit Address"), +QT_TRANSLATE_NOOP("bitcoin-core", "Edit Address Label"), +QT_TRANSLATE_NOOP("bitcoin-core", "Add Address"), +QT_TRANSLATE_NOOP("bitcoin-core", "Bitcoin"), +QT_TRANSLATE_NOOP("bitcoin-core", "Bitcoin - Generating"), +QT_TRANSLATE_NOOP("bitcoin-core", "Bitcoin - (not connected)"), +QT_TRANSLATE_NOOP("bitcoin-core", "&Open Bitcoin"), +QT_TRANSLATE_NOOP("bitcoin-core", "&Send Bitcoins"), +QT_TRANSLATE_NOOP("bitcoin-core", "O&ptions..."), +QT_TRANSLATE_NOOP("bitcoin-core", "E&xit"), +QT_TRANSLATE_NOOP("bitcoin-core", "Program has crashed and will terminate. "), +QT_TRANSLATE_NOOP("bitcoin-core", "" +"Warning: Please check that your computer's date and time are correct. If " +"your clock is wrong Bitcoin will not work properly."), +QT_TRANSLATE_NOOP("bitcoin-core", "beta"), +};
\ No newline at end of file diff --git a/src/qt/bitcoinunits.cpp b/src/qt/bitcoinunits.cpp new file mode 100644 index 0000000000..9a9a4890dc --- /dev/null +++ b/src/qt/bitcoinunits.cpp @@ -0,0 +1,181 @@ +#include "bitcoinunits.h" + +#include <QStringList> + +BitcoinUnits::BitcoinUnits(QObject *parent): + QAbstractListModel(parent), + unitlist(availableUnits()) +{ +} + +QList<BitcoinUnits::Unit> BitcoinUnits::availableUnits() +{ + QList<BitcoinUnits::Unit> unitlist; + unitlist.append(BTC); + unitlist.append(mBTC); + unitlist.append(uBTC); + return unitlist; +} + +bool BitcoinUnits::valid(int unit) +{ + switch(unit) + { + case BTC: + case mBTC: + case uBTC: + return true; + default: + return false; + } +} + +QString BitcoinUnits::name(int unit) +{ + switch(unit) + { + case BTC: return QString("BTC"); + case mBTC: return QString("mBTC"); + case uBTC: return QString::fromUtf8("μBTC"); + default: return QString("???"); + } +} + +QString BitcoinUnits::description(int unit) +{ + switch(unit) + { + case BTC: return QString("Bitcoins"); + case mBTC: return QString("Milli-Bitcoins (1 / 1,000)"); + case uBTC: return QString("Micro-Bitcoins (1 / 1,000,000)"); + default: return QString("???"); + } +} + +qint64 BitcoinUnits::factor(int unit) +{ + switch(unit) + { + case BTC: return 100000000; + case mBTC: return 100000; + case uBTC: return 100; + default: return 100000000; + } +} + +int BitcoinUnits::amountDigits(int unit) +{ + switch(unit) + { + case BTC: return 8; // 21,000,000 (# digits, without commas) + case mBTC: return 11; // 21,000,000,000 + case uBTC: return 14; // 21,000,000,000,000 + default: return 0; + } +} + +int BitcoinUnits::decimals(int unit) +{ + switch(unit) + { + case BTC: return 8; + case mBTC: return 5; + case uBTC: return 2; + default: return 0; + } +} + +QString BitcoinUnits::format(int unit, qint64 n, bool fPlus) +{ + // Note: not using straight sprintf here because we do NOT want + // localized number formatting. + if(!valid(unit)) + return QString(); // Refuse to format invalid unit + qint64 coin = factor(unit); + int num_decimals = decimals(unit); + qint64 n_abs = (n > 0 ? n : -n); + qint64 quotient = n_abs / coin; + qint64 remainder = n_abs % coin; + QString quotient_str = QString::number(quotient); + QString remainder_str = QString::number(remainder).rightJustified(num_decimals, '0'); + + // Right-trim excess 0's after the decimal point + int nTrim = 0; + for (int i = remainder_str.size()-1; i>=2 && (remainder_str.at(i) == '0'); --i) + ++nTrim; + remainder_str.chop(nTrim); + + if (n < 0) + quotient_str.insert(0, '-'); + else if (fPlus && n > 0) + quotient_str.insert(0, '+'); + return quotient_str + QString(".") + remainder_str; +} + +QString BitcoinUnits::formatWithUnit(int unit, qint64 amount, bool plussign) +{ + return format(unit, amount, plussign) + QString(" ") + name(unit); +} + +bool BitcoinUnits::parse(int unit, const QString &value, qint64 *val_out) +{ + if(!valid(unit) || value.isEmpty()) + return false; // Refuse to parse invalid unit or empty string + int num_decimals = decimals(unit); + QStringList parts = value.split("."); + + if(parts.size() > 2) + { + return false; // More than one dot + } + QString whole = parts[0]; + QString decimals; + + if(parts.size() > 1) + { + decimals = parts[1]; + } + if(decimals.size() > num_decimals) + { + return false; // Exceeds max precision + } + bool ok = false; + QString str = whole + decimals.leftJustified(num_decimals, '0'); + + if(str.size() > 18) + { + return false; // Longer numbers will exceed 63 bits + } + qint64 retvalue = str.toLongLong(&ok); + if(val_out) + { + *val_out = retvalue; + } + return ok; +} + +int BitcoinUnits::rowCount(const QModelIndex &parent) const +{ + Q_UNUSED(parent); + return unitlist.size(); +} + +QVariant BitcoinUnits::data(const QModelIndex &index, int role) const +{ + int row = index.row(); + if(row >= 0 && row < unitlist.size()) + { + Unit unit = unitlist.at(row); + switch(role) + { + case Qt::EditRole: + case Qt::DisplayRole: + return QVariant(name(unit)); + case Qt::ToolTipRole: + return QVariant(description(unit)); + case UnitRole: + return QVariant(static_cast<int>(unit)); + } + } + return QVariant(); +} diff --git a/src/qt/bitcoinunits.h b/src/qt/bitcoinunits.h new file mode 100644 index 0000000000..a7bebbc3e4 --- /dev/null +++ b/src/qt/bitcoinunits.h @@ -0,0 +1,57 @@ +#ifndef BITCOINUNITS_H +#define BITCOINUNITS_H + +#include <QString> +#include <QAbstractListModel> + +// Bitcoin unit definitions, encapsulates parsing and formatting +// and serves as list model for dropdown selection boxes. +class BitcoinUnits: public QAbstractListModel +{ +public: + explicit BitcoinUnits(QObject *parent); + + enum Unit + { + // Source: https://en.bitcoin.it/wiki/Units + // Please add only sensible ones + BTC, + mBTC, + uBTC + }; + + /// Static API + // Get list of units, for dropdown box + static QList<Unit> availableUnits(); + // Is unit ID valid? + static bool valid(int unit); + // Short name + static QString name(int unit); + // Longer description + static QString description(int unit); + // Number of satoshis / unit + static qint64 factor(int unit); + // Number of amount digits (to represent max number of coins) + static int amountDigits(int unit); + // Number of decimals left + static int decimals(int unit); + // Format as string + static QString format(int unit, qint64 amount, bool plussign=false); + // Format as string (with unit) + static QString formatWithUnit(int unit, qint64 amount, bool plussign=false); + // Parse string to coin amount + static bool parse(int unit, const QString &value, qint64 *val_out); + + /// AbstractListModel implementation + enum { + // Unit identifier + UnitRole = Qt::UserRole + } RoleIndex; + int rowCount(const QModelIndex &parent) const; + QVariant data(const QModelIndex &index, int role) const; +private: + QList<BitcoinUnits::Unit> unitlist; +}; +typedef BitcoinUnits::Unit BitcoinUnit; + +#endif // BITCOINUNITS_H diff --git a/src/qt/clientmodel.cpp b/src/qt/clientmodel.cpp new file mode 100644 index 0000000000..2ed3ce51df --- /dev/null +++ b/src/qt/clientmodel.cpp @@ -0,0 +1,83 @@ +#include "clientmodel.h" +#include "guiconstants.h" +#include "optionsmodel.h" +#include "addresstablemodel.h" +#include "transactiontablemodel.h" + +#include "headers.h" + +#include <QTimer> +#include <QDateTime> + +ClientModel::ClientModel(OptionsModel *optionsModel, QObject *parent) : + QObject(parent), optionsModel(optionsModel), + cachedNumConnections(0), cachedNumBlocks(0) +{ + // Until signal notifications is built into the bitcoin core, + // simply update everything after polling using a timer. + QTimer *timer = new QTimer(this); + connect(timer, SIGNAL(timeout()), this, SLOT(update())); + timer->start(MODEL_UPDATE_DELAY); + + numBlocksAtStartup = -1; +} + +int ClientModel::getNumConnections() const +{ + return vNodes.size(); +} + +int ClientModel::getNumBlocks() const +{ + return nBestHeight; +} + +int ClientModel::getNumBlocksAtStartup() +{ + if (numBlocksAtStartup == -1) numBlocksAtStartup = getNumBlocks(); + return numBlocksAtStartup; +} + +QDateTime ClientModel::getLastBlockDate() const +{ + return QDateTime::fromTime_t(pindexBest->GetBlockTime()); +} + +void ClientModel::update() +{ + int newNumConnections = getNumConnections(); + int newNumBlocks = getNumBlocks(); + + if(cachedNumConnections != newNumConnections) + emit numConnectionsChanged(newNumConnections); + if(cachedNumBlocks != newNumBlocks) + emit numBlocksChanged(newNumBlocks); + + cachedNumConnections = newNumConnections; + cachedNumBlocks = newNumBlocks; +} + +bool ClientModel::isTestNet() const +{ + return fTestNet; +} + +bool ClientModel::inInitialBlockDownload() const +{ + return IsInitialBlockDownload(); +} + +int ClientModel::getNumBlocksOfPeers() const +{ + return GetNumBlocksOfPeers(); +} + +OptionsModel *ClientModel::getOptionsModel() +{ + return optionsModel; +} + +QString ClientModel::formatFullVersion() const +{ + return QString::fromStdString(FormatFullVersion()); +} diff --git a/src/qt/clientmodel.h b/src/qt/clientmodel.h new file mode 100644 index 0000000000..c68fb0f035 --- /dev/null +++ b/src/qt/clientmodel.h @@ -0,0 +1,60 @@ +#ifndef CLIENTMODEL_H +#define CLIENTMODEL_H + +#include <QObject> + +class OptionsModel; +class AddressTableModel; +class TransactionTableModel; +class CWallet; + +QT_BEGIN_NAMESPACE +class QDateTime; +QT_END_NAMESPACE + +// Model for Bitcoin network client +class ClientModel : public QObject +{ + Q_OBJECT +public: + explicit ClientModel(OptionsModel *optionsModel, QObject *parent = 0); + + OptionsModel *getOptionsModel(); + + int getNumConnections() const; + int getNumBlocks() const; + int getNumBlocksAtStartup(); + + QDateTime getLastBlockDate() const; + + // Return true if client connected to testnet + bool isTestNet() const; + // Return true if core is doing initial block download + bool inInitialBlockDownload() const; + // Return conservative estimate of total number of blocks, or 0 if unknown + int getNumBlocksOfPeers() const; + + QString formatFullVersion() const; + +private: + OptionsModel *optionsModel; + + int cachedNumConnections; + int cachedNumBlocks; + + int numBlocksAtStartup; + +signals: + void numConnectionsChanged(int count); + void numBlocksChanged(int count); + + // Asynchronous error notification + void error(const QString &title, const QString &message); + +public slots: + +private slots: + void update(); +}; + +#endif // CLIENTMODEL_H diff --git a/src/qt/csvmodelwriter.cpp b/src/qt/csvmodelwriter.cpp new file mode 100644 index 0000000000..62c0b949aa --- /dev/null +++ b/src/qt/csvmodelwriter.cpp @@ -0,0 +1,83 @@ +#include "csvmodelwriter.h" + +#include <QAbstractItemModel> +#include <QFile> +#include <QTextStream> + +CSVModelWriter::CSVModelWriter(const QString &filename, QObject *parent) : + QObject(parent), + filename(filename) +{ +} + +void CSVModelWriter::setModel(const QAbstractItemModel *model) +{ + this->model = model; +} + +void CSVModelWriter::addColumn(const QString &title, int column, int role) +{ + Column col; + col.title = title; + col.column = column; + col.role = role; + + columns.append(col); +} + +static void writeValue(QTextStream &f, const QString &value) +{ + // TODO: quoting if " or \n in string + f << "\"" << value << "\""; +} + +static void writeSep(QTextStream &f) +{ + f << ","; +} + +static void writeNewline(QTextStream &f) +{ + f << "\n"; +} + +bool CSVModelWriter::write() +{ + QFile file(filename); + if(!file.open(QIODevice::WriteOnly | QIODevice::Text)) + return false; + QTextStream out(&file); + + int numRows = model->rowCount(); + + // Header row + for(int i=0; i<columns.size(); ++i) + { + if(i!=0) + { + writeSep(out); + } + writeValue(out, columns[i].title); + } + writeNewline(out); + + // Data rows + for(int j=0; j<numRows; ++j) + { + for(int i=0; i<columns.size(); ++i) + { + if(i!=0) + { + writeSep(out); + } + QVariant data = model->index(j, columns[i].column).data(columns[i].role); + writeValue(out, data.toString()); + } + writeNewline(out); + } + + file.close(); + + return file.error() == QFile::NoError; +} + diff --git a/src/qt/csvmodelwriter.h b/src/qt/csvmodelwriter.h new file mode 100644 index 0000000000..7367f3a6a9 --- /dev/null +++ b/src/qt/csvmodelwriter.h @@ -0,0 +1,43 @@ +#ifndef CSVMODELWRITER_H +#define CSVMODELWRITER_H + +#include <QObject> +#include <QList> + +QT_BEGIN_NAMESPACE +class QAbstractItemModel; +QT_END_NAMESPACE + +// Export TableModel to CSV file +class CSVModelWriter : public QObject +{ + Q_OBJECT +public: + explicit CSVModelWriter(const QString &filename, QObject *parent = 0); + + void setModel(const QAbstractItemModel *model); + void addColumn(const QString &title, int column, int role=Qt::EditRole); + + // Perform write operation + // Returns true on success, false otherwise + bool write(); + +private: + QString filename; + const QAbstractItemModel *model; + + struct Column + { + QString title; + int column; + int role; + }; + QList<Column> columns; + +signals: + +public slots: + +}; + +#endif // CSVMODELWRITER_H diff --git a/src/qt/editaddressdialog.cpp b/src/qt/editaddressdialog.cpp new file mode 100644 index 0000000000..b8e6fe4578 --- /dev/null +++ b/src/qt/editaddressdialog.cpp @@ -0,0 +1,115 @@ +#include "editaddressdialog.h" +#include "ui_editaddressdialog.h" +#include "addresstablemodel.h" +#include "guiutil.h" + +#include <QDataWidgetMapper> +#include <QMessageBox> + +EditAddressDialog::EditAddressDialog(Mode mode, QWidget *parent) : + QDialog(parent), + ui(new Ui::EditAddressDialog), mapper(0), mode(mode), model(0) +{ + ui->setupUi(this); + + GUIUtil::setupAddressWidget(ui->addressEdit, this); + + switch(mode) + { + case NewReceivingAddress: + setWindowTitle(tr("New receiving address")); + ui->addressEdit->setEnabled(false); + break; + case NewSendingAddress: + setWindowTitle(tr("New sending address")); + break; + case EditReceivingAddress: + setWindowTitle(tr("Edit receiving address")); + ui->addressEdit->setDisabled(true); + break; + case EditSendingAddress: + setWindowTitle(tr("Edit sending address")); + break; + } + + mapper = new QDataWidgetMapper(this); + mapper->setSubmitPolicy(QDataWidgetMapper::ManualSubmit); +} + +EditAddressDialog::~EditAddressDialog() +{ + delete ui; +} + +void EditAddressDialog::setModel(AddressTableModel *model) +{ + this->model = model; + mapper->setModel(model); + mapper->addMapping(ui->labelEdit, AddressTableModel::Label); + mapper->addMapping(ui->addressEdit, AddressTableModel::Address); +} + +void EditAddressDialog::loadRow(int row) +{ + mapper->setCurrentIndex(row); +} + +bool EditAddressDialog::saveCurrentRow() +{ + switch(mode) + { + case NewReceivingAddress: + case NewSendingAddress: + address = model->addRow( + mode == NewSendingAddress ? AddressTableModel::Send : AddressTableModel::Receive, + ui->labelEdit->text(), + ui->addressEdit->text()); + break; + case EditReceivingAddress: + case EditSendingAddress: + if(mapper->submit()) + { + address = ui->addressEdit->text(); + } + break; + } + return !address.isEmpty(); +} + +void EditAddressDialog::accept() +{ + if(!saveCurrentRow()) + { + switch(model->getEditStatus()) + { + case AddressTableModel::DUPLICATE_ADDRESS: + QMessageBox::warning(this, windowTitle(), + tr("The entered address \"%1\" is already in the address book.").arg(ui->addressEdit->text()), + QMessageBox::Ok, QMessageBox::Ok); + break; + case AddressTableModel::INVALID_ADDRESS: + QMessageBox::warning(this, windowTitle(), + 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: + QMessageBox::critical(this, windowTitle(), + tr("Could not unlock wallet."), + QMessageBox::Ok, QMessageBox::Ok); + return; + case AddressTableModel::KEY_GENERATION_FAILURE: + QMessageBox::critical(this, windowTitle(), + tr("New key generation failed."), + QMessageBox::Ok, QMessageBox::Ok); + return; + } + + return; + } + QDialog::accept(); +} + +QString EditAddressDialog::getAddress() const +{ + return address; +} diff --git a/src/qt/editaddressdialog.h b/src/qt/editaddressdialog.h new file mode 100644 index 0000000000..81086a45a8 --- /dev/null +++ b/src/qt/editaddressdialog.h @@ -0,0 +1,47 @@ +#ifndef EDITADDRESSDIALOG_H +#define EDITADDRESSDIALOG_H + +#include <QDialog> + +QT_BEGIN_NAMESPACE +class QDataWidgetMapper; +QT_END_NAMESPACE + +namespace Ui { + class EditAddressDialog; +} +class AddressTableModel; + +class EditAddressDialog : public QDialog +{ + Q_OBJECT + +public: + enum Mode { + NewReceivingAddress, + NewSendingAddress, + EditReceivingAddress, + EditSendingAddress + }; + + explicit EditAddressDialog(Mode mode, QWidget *parent = 0); + ~EditAddressDialog(); + + void setModel(AddressTableModel *model); + void loadRow(int row); + + void accept(); + + QString getAddress() const; +private: + bool saveCurrentRow(); + + Ui::EditAddressDialog *ui; + QDataWidgetMapper *mapper; + Mode mode; + AddressTableModel *model; + + QString address; +}; + +#endif // EDITADDRESSDIALOG_H diff --git a/src/qt/forms/aboutdialog.ui b/src/qt/forms/aboutdialog.ui new file mode 100644 index 0000000000..cf7997326c --- /dev/null +++ b/src/qt/forms/aboutdialog.ui @@ -0,0 +1,162 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>AboutDialog</class> + <widget class="QDialog" name="AboutDialog"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>593</width> + <height>319</height> + </rect> + </property> + <property name="windowTitle"> + <string>About Bitcoin</string> + </property> + <layout class="QHBoxLayout" name="horizontalLayout_2"> + <item> + <widget class="QLabel" name="label_4"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Ignored"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string/> + </property> + <property name="pixmap"> + <pixmap resource="../bitcoin.qrc">:/images/about</pixmap> + </property> + </widget> + </item> + <item> + <layout class="QVBoxLayout" name="verticalLayout_2"> + <item> + <spacer name="verticalSpacer_2"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>40</height> + </size> + </property> + </spacer> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout"> + <item> + <widget class="QLabel" name="label"> + <property name="text"> + <string><b>Bitcoin</b> version</string> + </property> + </widget> + </item> + <item> + <widget class="QLabel" name="versionLabel"> + <property name="text"> + <string notr="true">0.3.666-beta</string> + </property> + <property name="textFormat"> + <enum>Qt::RichText</enum> + </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="QLabel" name="label_2"> + <property name="text"> + <string>Copyright © 2009-2011 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.</string> + </property> + <property name="wordWrap"> + <bool>true</bool> + </property> + </widget> + </item> + <item> + <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> + <item> + <widget class="QDialogButtonBox" name="buttonBox"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="standardButtons"> + <set>QDialogButtonBox::Ok</set> + </property> + </widget> + </item> + </layout> + </item> + </layout> + </widget> + <resources> + <include location="../bitcoin.qrc"/> + </resources> + <connections> + <connection> + <sender>buttonBox</sender> + <signal>accepted()</signal> + <receiver>AboutDialog</receiver> + <slot>accept()</slot> + <hints> + <hint type="sourcelabel"> + <x>360</x> + <y>308</y> + </hint> + <hint type="destinationlabel"> + <x>157</x> + <y>274</y> + </hint> + </hints> + </connection> + <connection> + <sender>buttonBox</sender> + <signal>rejected()</signal> + <receiver>AboutDialog</receiver> + <slot>reject()</slot> + <hints> + <hint type="sourcelabel"> + <x>428</x> + <y>308</y> + </hint> + <hint type="destinationlabel"> + <x>286</x> + <y>274</y> + </hint> + </hints> + </connection> + </connections> +</ui> diff --git a/src/qt/forms/addressbookpage.ui b/src/qt/forms/addressbookpage.ui new file mode 100644 index 0000000000..fb098c8280 --- /dev/null +++ b/src/qt/forms/addressbookpage.ui @@ -0,0 +1,130 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>AddressBookPage</class> + <widget class="QWidget" name="AddressBookPage"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>627</width> + <height>347</height> + </rect> + </property> + <property name="windowTitle"> + <string>Address Book</string> + </property> + <layout class="QVBoxLayout" name="verticalLayout"> + <item> + <widget class="QLabel" name="labelExplanation"> + <property name="text"> + <string>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.</string> + </property> + <property name="textFormat"> + <enum>Qt::AutoText</enum> + </property> + <property name="wordWrap"> + <bool>true</bool> + </property> + </widget> + </item> + <item> + <widget class="QTableView" name="tableView"> + <property name="toolTip"> + <string>Double-click to edit address or label</string> + </property> + <property name="alternatingRowColors"> + <bool>true</bool> + </property> + <property name="selectionMode"> + <enum>QAbstractItemView::SingleSelection</enum> + </property> + <property name="selectionBehavior"> + <enum>QAbstractItemView::SelectRows</enum> + </property> + <property name="sortingEnabled"> + <bool>true</bool> + </property> + <attribute name="verticalHeaderVisible"> + <bool>false</bool> + </attribute> + </widget> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout"> + <item> + <widget class="QPushButton" name="newAddressButton"> + <property name="toolTip"> + <string>Create a new address</string> + </property> + <property name="text"> + <string>&New Address...</string> + </property> + <property name="icon"> + <iconset resource="../bitcoin.qrc"> + <normaloff>:/icons/add</normaloff>:/icons/add</iconset> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="copyToClipboard"> + <property name="toolTip"> + <string>Copy the currently selected address to the system clipboard</string> + </property> + <property name="text"> + <string>&Copy to Clipboard</string> + </property> + <property name="icon"> + <iconset resource="../bitcoin.qrc"> + <normaloff>:/icons/editcopy</normaloff>:/icons/editcopy</iconset> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="deleteButton"> + <property name="toolTip"> + <string>Delete the currently selected address from the list. Only sending addresses can be deleted.</string> + </property> + <property name="text"> + <string>&Delete</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> + <item> + <widget class="QDialogButtonBox" name="buttonBox"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Maximum" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="standardButtons"> + <set>QDialogButtonBox::Ok</set> + </property> + </widget> + </item> + </layout> + </item> + </layout> + </widget> + <resources> + <include location="../bitcoin.qrc"/> + </resources> + <connections/> +</ui> diff --git a/src/qt/forms/askpassphrasedialog.ui b/src/qt/forms/askpassphrasedialog.ui new file mode 100644 index 0000000000..70d9180e75 --- /dev/null +++ b/src/qt/forms/askpassphrasedialog.ui @@ -0,0 +1,148 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>AskPassphraseDialog</class> + <widget class="QDialog" name="AskPassphraseDialog"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>589</width> + <height>228</height> + </rect> + </property> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Minimum"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>550</width> + <height>0</height> + </size> + </property> + <property name="windowTitle"> + <string>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> + </widget> + </item> + <item> + <layout class="QFormLayout" name="formLayout"> + <property name="fieldGrowthPolicy"> + <enum>QFormLayout::AllNonFixedFieldsGrow</enum> + </property> + <item row="1" column="0"> + <widget class="QLabel" name="passLabel1"> + <property name="text"> + <string>Enter passphrase</string> + </property> + </widget> + </item> + <item row="1" column="1"> + <widget class="QLineEdit" name="passEdit1"> + <property name="echoMode"> + <enum>QLineEdit::Password</enum> + </property> + </widget> + </item> + <item row="2" column="0"> + <widget class="QLabel" name="passLabel2"> + <property name="text"> + <string>New passphrase</string> + </property> + </widget> + </item> + <item row="2" column="1"> + <widget class="QLineEdit" name="passEdit2"> + <property name="echoMode"> + <enum>QLineEdit::Password</enum> + </property> + </widget> + </item> + <item row="3" column="0"> + <widget class="QLabel" name="passLabel3"> + <property name="text"> + <string>Repeat new passphrase</string> + </property> + </widget> + </item> + <item row="3" column="1"> + <widget class="QLineEdit" name="passEdit3"> + <property name="echoMode"> + <enum>QLineEdit::Password</enum> + </property> + </widget> + </item> + </layout> + </item> + <item> + <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> + <item> + <widget class="QDialogButtonBox" name="buttonBox"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="standardButtons"> + <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set> + </property> + </widget> + </item> + </layout> + </widget> + <resources/> + <connections> + <connection> + <sender>buttonBox</sender> + <signal>accepted()</signal> + <receiver>AskPassphraseDialog</receiver> + <slot>accept()</slot> + <hints> + <hint type="sourcelabel"> + <x>248</x> + <y>254</y> + </hint> + <hint type="destinationlabel"> + <x>157</x> + <y>274</y> + </hint> + </hints> + </connection> + <connection> + <sender>buttonBox</sender> + <signal>rejected()</signal> + <receiver>AskPassphraseDialog</receiver> + <slot>reject()</slot> + <hints> + <hint type="sourcelabel"> + <x>316</x> + <y>260</y> + </hint> + <hint type="destinationlabel"> + <x>286</x> + <y>274</y> + </hint> + </hints> + </connection> + </connections> +</ui> diff --git a/src/qt/forms/editaddressdialog.ui b/src/qt/forms/editaddressdialog.ui new file mode 100644 index 0000000000..b4a4c1b1e9 --- /dev/null +++ b/src/qt/forms/editaddressdialog.ui @@ -0,0 +1,105 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>EditAddressDialog</class> + <widget class="QDialog" name="EditAddressDialog"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>457</width> + <height>126</height> + </rect> + </property> + <property name="windowTitle"> + <string>Edit Address</string> + </property> + <layout class="QVBoxLayout" name="verticalLayout"> + <item> + <layout class="QFormLayout" name="formLayout"> + <property name="fieldGrowthPolicy"> + <enum>QFormLayout::AllNonFixedFieldsGrow</enum> + </property> + <item row="0" column="0"> + <widget class="QLabel" name="label"> + <property name="text"> + <string>&Label</string> + </property> + <property name="buddy"> + <cstring>labelEdit</cstring> + </property> + </widget> + </item> + <item row="0" column="1"> + <widget class="QLineEdit" name="labelEdit"> + <property name="toolTip"> + <string>The label associated with this address book entry</string> + </property> + </widget> + </item> + <item row="1" column="0"> + <widget class="QLabel" name="label_2"> + <property name="text"> + <string>&Address</string> + </property> + <property name="buddy"> + <cstring>addressEdit</cstring> + </property> + </widget> + </item> + <item row="1" column="1"> + <widget class="QLineEdit" name="addressEdit"> + <property name="toolTip"> + <string>The address associated with this address book entry. This can only be modified for sending addresses.</string> + </property> + </widget> + </item> + </layout> + </item> + <item> + <widget class="QDialogButtonBox" name="buttonBox"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="standardButtons"> + <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set> + </property> + </widget> + </item> + </layout> + </widget> + <resources/> + <connections> + <connection> + <sender>buttonBox</sender> + <signal>accepted()</signal> + <receiver>EditAddressDialog</receiver> + <slot>accept()</slot> + <hints> + <hint type="sourcelabel"> + <x>248</x> + <y>254</y> + </hint> + <hint type="destinationlabel"> + <x>157</x> + <y>274</y> + </hint> + </hints> + </connection> + <connection> + <sender>buttonBox</sender> + <signal>rejected()</signal> + <receiver>EditAddressDialog</receiver> + <slot>reject()</slot> + <hints> + <hint type="sourcelabel"> + <x>316</x> + <y>260</y> + </hint> + <hint type="destinationlabel"> + <x>286</x> + <y>274</y> + </hint> + </hints> + </connection> + </connections> +</ui> diff --git a/src/qt/forms/overviewpage.ui b/src/qt/forms/overviewpage.ui new file mode 100644 index 0000000000..cc67fae533 --- /dev/null +++ b/src/qt/forms/overviewpage.ui @@ -0,0 +1,161 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>OverviewPage</class> + <widget class="QWidget" name="OverviewPage"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>552</width> + <height>342</height> + </rect> + </property> + <property name="windowTitle"> + <string>Form</string> + </property> + <layout class="QHBoxLayout" name="horizontalLayout" stretch="1,1"> + <item> + <layout class="QVBoxLayout" name="verticalLayout_2"> + <item> + <widget class="QFrame" name="frame"> + <property name="frameShape"> + <enum>QFrame::StyledPanel</enum> + </property> + <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> + </item> + <item row="3" column="0"> + <widget class="QLabel" name="label_3"> + <property name="text"> + <string>Unconfirmed:</string> + </property> + </widget> + </item> + <item row="3" column="1"> + <widget class="QLabel" name="labelUnconfirmed"> + <property name="text"> + <string>0 BTC</string> + </property> + </widget> + </item> + <item row="1" column="0"> + <widget class="QLabel" name="label_5"> + <property name="text"> + <string><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Ubuntu'; font-size:11pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600;">Wallet</span></p></body></html></string> + </property> + </widget> + </item> + </layout> + </widget> + </item> + <item> + <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> + </item> + <item> + <layout class="QVBoxLayout" name="verticalLayout_3"> + <item> + <widget class="QFrame" name="frame_2"> + <property name="frameShape"> + <enum>QFrame::StyledPanel</enum> + </property> + <property name="frameShadow"> + <enum>QFrame::Raised</enum> + </property> + <layout class="QVBoxLayout" name="verticalLayout"> + <item> + <widget class="QLabel" name="label_4"> + <property name="text"> + <string><b>Recent transactions</b></string> + </property> + </widget> + </item> + <item> + <widget class="QListView" name="listTransactions"> + <property name="frameShape"> + <enum>QFrame::NoFrame</enum> + </property> + <property name="verticalScrollBarPolicy"> + <enum>Qt::ScrollBarAlwaysOff</enum> + </property> + <property name="horizontalScrollBarPolicy"> + <enum>Qt::ScrollBarAlwaysOff</enum> + </property> + </widget> + </item> + </layout> + </widget> + </item> + <item> + <spacer name="verticalSpacer_2"> + <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> + </item> + </layout> + </widget> + <resources/> + <connections/> +</ui> diff --git a/src/qt/forms/sendcoinsdialog.ui b/src/qt/forms/sendcoinsdialog.ui new file mode 100644 index 0000000000..f9dd02fef5 --- /dev/null +++ b/src/qt/forms/sendcoinsdialog.ui @@ -0,0 +1,166 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>SendCoinsDialog</class> + <widget class="QDialog" name="SendCoinsDialog"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>686</width> + <height>217</height> + </rect> + </property> + <property name="windowTitle"> + <string>Send Coins</string> + </property> + <layout class="QVBoxLayout" name="verticalLayout"> + <item> + <widget class="QScrollArea" name="scrollArea"> + <property name="widgetResizable"> + <bool>true</bool> + </property> + <widget class="QWidget" name="scrollAreaWidgetContents"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>666</width> + <height>165</height> + </rect> + </property> + <layout class="QVBoxLayout" name="verticalLayout_2"> + <property name="margin"> + <number>0</number> + </property> + <item> + <layout class="QVBoxLayout" name="entries"> + <property name="spacing"> + <number>6</number> + </property> + </layout> + </item> + <item> + <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> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout"> + <property name="spacing"> + <number>6</number> + </property> + <item> + <widget class="QPushButton" name="addButton"> + <property name="toolTip"> + <string>Send to multiple recipients at once</string> + </property> + <property name="text"> + <string>&Add recipient...</string> + </property> + <property name="icon"> + <iconset resource="../bitcoin.qrc"> + <normaloff>:/icons/add</normaloff>:/icons/add</iconset> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="clearButton"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Minimum" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>Clear all</string> + </property> + <property name="icon"> + <iconset resource="../bitcoin.qrc"> + <normaloff>:/icons/remove</normaloff>:/icons/remove</iconset> + </property> + <property name="autoRepeatDelay"> + <number>300</number> + </property> + </widget> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_2"> + <property name="spacing"> + <number>3</number> + </property> + <item> + <widget class="QLabel" name="label"> + <property name="text"> + <string>Balance:</string> + </property> + </widget> + </item> + <item> + <widget class="QLabel" name="labelBalance"> + <property name="text"> + <string>123.456 BTC</string> + </property> + <property name="textInteractionFlags"> + <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set> + </property> + </widget> + </item> + </layout> + </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> + <item> + <widget class="QPushButton" name="sendButton"> + <property name="minimumSize"> + <size> + <width>150</width> + <height>0</height> + </size> + </property> + <property name="toolTip"> + <string>Confirm the send action</string> + </property> + <property name="text"> + <string>&Send</string> + </property> + <property name="icon"> + <iconset resource="../bitcoin.qrc"> + <normaloff>:/icons/send</normaloff>:/icons/send</iconset> + </property> + <property name="default"> + <bool>true</bool> + </property> + </widget> + </item> + </layout> + </item> + </layout> + </widget> + <resources> + <include location="../bitcoin.qrc"/> + </resources> + <connections/> +</ui> diff --git a/src/qt/forms/sendcoinsentry.ui b/src/qt/forms/sendcoinsentry.ui new file mode 100644 index 0000000000..13593c2c1e --- /dev/null +++ b/src/qt/forms/sendcoinsentry.ui @@ -0,0 +1,178 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>SendCoinsEntry</class> + <widget class="QFrame" name="SendCoinsEntry"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>729</width> + <height>136</height> + </rect> + </property> + <property name="windowTitle"> + <string>Form</string> + </property> + <property name="frameShape"> + <enum>QFrame::StyledPanel</enum> + </property> + <property name="frameShadow"> + <enum>QFrame::Sunken</enum> + </property> + <layout class="QGridLayout" name="gridLayout"> + <property name="spacing"> + <number>12</number> + </property> + <item row="5" column="0"> + <widget class="QLabel" name="label"> + <property name="text"> + <string>A&mount:</string> + </property> + <property name="alignment"> + <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + </property> + <property name="buddy"> + <cstring>payAmount</cstring> + </property> + </widget> + </item> + <item row="3" column="0"> + <widget class="QLabel" name="label_2"> + <property name="text"> + <string>Pay &To:</string> + </property> + <property name="alignment"> + <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + </property> + <property name="buddy"> + <cstring>payTo</cstring> + </property> + </widget> + </item> + <item row="5" column="1"> + <widget class="BitcoinAmountField" name="payAmount"/> + </item> + <item row="4" column="1"> + <layout class="QHBoxLayout" name="horizontalLayout_2"> + <property name="spacing"> + <number>0</number> + </property> + <item> + <widget class="QValidatedLineEdit" name="addAsLabel"> + <property name="enabled"> + <bool>true</bool> + </property> + <property name="toolTip"> + <string>Enter a label for this address to add it to your address book</string> + </property> + </widget> + </item> + </layout> + </item> + <item row="4" column="0"> + <widget class="QLabel" name="label_4"> + <property name="text"> + <string>&Label:</string> + </property> + <property name="alignment"> + <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + </property> + <property name="buddy"> + <cstring>addAsLabel</cstring> + </property> + </widget> + </item> + <item row="3" column="1"> + <layout class="QHBoxLayout" name="horizontalLayout_3"> + <property name="spacing"> + <number>0</number> + </property> + <item> + <widget class="QValidatedLineEdit" name="payTo"> + <property name="toolTip"> + <string>The address to send the payment to (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L)</string> + </property> + <property name="maxLength"> + <number>34</number> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="addressBookButton"> + <property name="toolTip"> + <string>Choose adress from address book</string> + </property> + <property name="text"> + <string/> + </property> + <property name="icon"> + <iconset resource="../bitcoin.qrc"> + <normaloff>:/icons/address-book</normaloff>:/icons/address-book</iconset> + </property> + <property name="shortcut"> + <string>Alt+A</string> + </property> + <property name="autoDefault"> + <bool>false</bool> + </property> + <property name="flat"> + <bool>false</bool> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="pasteButton"> + <property name="toolTip"> + <string>Paste address from clipboard</string> + </property> + <property name="text"> + <string/> + </property> + <property name="icon"> + <iconset resource="../bitcoin.qrc"> + <normaloff>:/icons/editpaste</normaloff>:/icons/editpaste</iconset> + </property> + <property name="shortcut"> + <string>Alt+P</string> + </property> + <property name="autoDefault"> + <bool>false</bool> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="deleteButton"> + <property name="toolTip"> + <string>Remove this recipient</string> + </property> + <property name="text"> + <string/> + </property> + <property name="icon"> + <iconset resource="../bitcoin.qrc"> + <normaloff>:/icons/remove</normaloff>:/icons/remove</iconset> + </property> + </widget> + </item> + </layout> + </item> + </layout> + </widget> + <customwidgets> + <customwidget> + <class>BitcoinAmountField</class> + <extends>QLineEdit</extends> + <header>bitcoinamountfield.h</header> + <container>1</container> + </customwidget> + <customwidget> + <class>QValidatedLineEdit</class> + <extends>QLineEdit</extends> + <header>qvalidatedlineedit.h</header> + </customwidget> + </customwidgets> + <resources> + <include location="../bitcoin.qrc"/> + </resources> + <connections/> +</ui> diff --git a/src/qt/forms/transactiondescdialog.ui b/src/qt/forms/transactiondescdialog.ui new file mode 100644 index 0000000000..2f70a38214 --- /dev/null +++ b/src/qt/forms/transactiondescdialog.ui @@ -0,0 +1,71 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>TransactionDescDialog</class> + <widget class="QDialog" name="TransactionDescDialog"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>400</width> + <height>300</height> + </rect> + </property> + <property name="windowTitle"> + <string>Transaction details</string> + </property> + <layout class="QVBoxLayout" name="verticalLayout"> + <item> + <widget class="QTextEdit" name="detailText"> + <property name="toolTip"> + <string>This pane shows a detailed description of the transaction</string> + </property> + </widget> + </item> + <item> + <widget class="QDialogButtonBox" name="buttonBox"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="standardButtons"> + <set>QDialogButtonBox::Close</set> + </property> + </widget> + </item> + </layout> + </widget> + <resources/> + <connections> + <connection> + <sender>buttonBox</sender> + <signal>accepted()</signal> + <receiver>TransactionDescDialog</receiver> + <slot>accept()</slot> + <hints> + <hint type="sourcelabel"> + <x>248</x> + <y>254</y> + </hint> + <hint type="destinationlabel"> + <x>157</x> + <y>274</y> + </hint> + </hints> + </connection> + <connection> + <sender>buttonBox</sender> + <signal>rejected()</signal> + <receiver>TransactionDescDialog</receiver> + <slot>reject()</slot> + <hints> + <hint type="sourcelabel"> + <x>316</x> + <y>260</y> + </hint> + <hint type="destinationlabel"> + <x>286</x> + <y>274</y> + </hint> + </hints> + </connection> + </connections> +</ui> diff --git a/src/qt/guiconstants.h b/src/qt/guiconstants.h new file mode 100644 index 0000000000..0cb507501a --- /dev/null +++ b/src/qt/guiconstants.h @@ -0,0 +1,23 @@ +#ifndef GUICONSTANTS_H +#define GUICONSTANTS_H + +/* Milliseconds between model updates */ +static const int MODEL_UPDATE_DELAY = 500; + +/* Maximum passphrase length */ +static const int MAX_PASSPHRASE_SIZE = 1024; + +/* Size of icons in status bar */ +static const int STATUSBAR_ICONSIZE = 16; + +/* Invalid field background style */ +#define STYLE_INVALID "background:#FF8080" + +/* Transaction list -- unconfirmed transaction */ +#define COLOR_UNCONFIRMED QColor(128, 128, 128) +/* Transaction list -- negative amount */ +#define COLOR_NEGATIVE QColor(255, 0, 0) +/* Transaction list -- bare address (without label) */ +#define COLOR_BAREADDRESS QColor(140, 140, 140) + +#endif // GUICONSTANTS_H diff --git a/src/qt/guiutil.cpp b/src/qt/guiutil.cpp new file mode 100644 index 0000000000..158b84a285 --- /dev/null +++ b/src/qt/guiutil.cpp @@ -0,0 +1,74 @@ +#include "guiutil.h" +#include "bitcoinaddressvalidator.h" +#include "walletmodel.h" +#include "bitcoinunits.h" + +#include "headers.h" + +#include <QString> +#include <QDateTime> +#include <QDoubleValidator> +#include <QFont> +#include <QLineEdit> +#include <QUrl> + +QString GUIUtil::dateTimeStr(qint64 nTime) +{ + return dateTimeStr(QDateTime::fromTime_t((qint32)nTime)); +} + +QString GUIUtil::dateTimeStr(const QDateTime &date) +{ + return date.date().toString(Qt::SystemLocaleShortDate) + QString(" ") + date.toString("hh:mm"); +} + +QFont GUIUtil::bitcoinAddressFont() +{ + QFont font("Monospace"); + font.setStyleHint(QFont::TypeWriter); + return font; +} + +void GUIUtil::setupAddressWidget(QLineEdit *widget, QWidget *parent) +{ + widget->setMaxLength(BitcoinAddressValidator::MaxAddressLength); + widget->setValidator(new BitcoinAddressValidator(parent)); + widget->setFont(bitcoinAddressFont()); +} + +void GUIUtil::setupAmountWidget(QLineEdit *widget, QWidget *parent) +{ + QDoubleValidator *amountValidator = new QDoubleValidator(parent); + amountValidator->setDecimals(8); + amountValidator->setBottom(0.0); + widget->setValidator(amountValidator); + widget->setAlignment(Qt::AlignRight|Qt::AlignVCenter); +} + +bool GUIUtil::parseBitcoinURL(const QUrl *url, SendCoinsRecipient *out) +{ + if(url->scheme() != QString("bitcoin")) + return false; + + SendCoinsRecipient rv; + rv.address = url->path(); + rv.label = url->queryItemValue("label"); + + QString amount = url->queryItemValue("amount"); + if(amount.isEmpty()) + { + rv.amount = 0; + } + else // Amount is non-empty + { + if(!BitcoinUnits::parse(BitcoinUnits::BTC, amount, &rv.amount)) + { + return false; + } + } + if(out) + { + *out = rv; + } + return true; +} diff --git a/src/qt/guiutil.h b/src/qt/guiutil.h new file mode 100644 index 0000000000..bc4ddb8aae --- /dev/null +++ b/src/qt/guiutil.h @@ -0,0 +1,34 @@ +#ifndef GUIUTIL_H +#define GUIUTIL_H + +#include <QString> + +QT_BEGIN_NAMESPACE +class QFont; +class QLineEdit; +class QWidget; +class QDateTime; +class QUrl; +QT_END_NAMESPACE +class SendCoinsRecipient; + +class GUIUtil +{ +public: + // Create human-readable string from date + static QString dateTimeStr(qint64 nTime); + static QString dateTimeStr(const QDateTime &datetime); + + // Render bitcoin addresses in monospace font + static QFont bitcoinAddressFont(); + + // Set up widgets for address and amounts + static void setupAddressWidget(QLineEdit *widget, QWidget *parent); + static void setupAmountWidget(QLineEdit *widget, QWidget *parent); + + // Parse "bitcoin:" URL into recipient object, return true on succesful parsing + // See Bitcoin URL definition discussion here: https://bitcointalk.org/index.php?topic=33490.0 + static bool parseBitcoinURL(const QUrl *url, SendCoinsRecipient *out); +}; + +#endif // GUIUTIL_H diff --git a/src/qt/locale/bitcoin_de.ts b/src/qt/locale/bitcoin_de.ts new file mode 100644 index 0000000000..1978f06d41 --- /dev/null +++ b/src/qt/locale/bitcoin_de.ts @@ -0,0 +1,1155 @@ +<?xml version="1.0" encoding="utf-8"?> +<!DOCTYPE TS> +<TS version="2.0" language="de_DE"> +<defaultcodec>UTF-8</defaultcodec> +<context> + <name>AboutDialog</name> + <message> + <location filename="../forms/aboutdialog.ui" line="14"/> + <source>About Bitcoin</source> + <translation>Über Bitcoin</translation> + </message> + <message> + <location filename="../forms/aboutdialog.ui" line="53"/> + <source><b>Bitcoin</b> version</source> + <translation><b>Bitcoin</b> Version</translation> + </message> + <message> + <location filename="../forms/aboutdialog.ui" line="85"/> + <source>Copyright © 2009-2011 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-2011 Bitcoin Developers + +Dies ist experimentelle Software. + +Veröffentlicht unter der MIT/X11 Software-Lizenz. Sie können diese in der beiligenden Datei license.txt oder unter http://www.opensource.org/licenses/mit-license.php nachlesen. + +Dieses Produkt enthält Software, welche vom OpenSSL Projekt zur Verwendung im OpenSSL Toolkit (http://www.openssl.org/) entwickelt wurde, kryptographische Software von Eric Young (eay@cryptsoft.com) und UPnP Software von Thomas-Bernard.</translation> + </message> +</context> +<context> + <name>AddressBookPage</name> + <message> + <location filename="../forms/addressbookpage.ui" line="14"/> + <source>Address Book</source> + <translation>Adressbuch</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>Dies sind ihre Bitcoin-Adressen zum empfangen von Zahlungen. Um Ihre Zahlungen zurückverfolgen zu können ist es möglich jedem Sender eine andere Empfangsaddresse mitzuteilen.</translation> + </message> + <message> + <location filename="../forms/addressbookpage.ui" line="33"/> + <source>Double-click to edit address or label</source> + <translation>Doppelklick zum Ändern der Adresse oder Beschreibung</translation> + </message> + <message> + <location filename="../forms/addressbookpage.ui" line="57"/> + <source>Create a new address</source> + <translation>Neue Adresse erstellen</translation> + </message> + <message> + <location filename="../forms/addressbookpage.ui" line="60"/> + <source>&New Address...</source> + <translation>&Neue Adresse...</translation> + </message> + <message> + <location filename="../forms/addressbookpage.ui" line="71"/> + <source>Copy the currently selected address to the system clipboard</source> + <translation>Ausgewählte Adresse in die Zwischenablage kopieren</translation> + </message> + <message> + <location filename="../forms/addressbookpage.ui" line="74"/> + <source>&Copy to Clipboard</source> + <translation>&In die Zwischenablage kopieren</translation> + </message> + <message> + <location filename="../forms/addressbookpage.ui" line="85"/> + <source>Delete the currently selected address from the list. Only sending addresses can be deleted.</source> + <translation>Die ausgewählte Adresse aus der Liste entfernen. Sie können nur ausgehende Adressen entfernen.</translation> + </message> + <message> + <location filename="../forms/addressbookpage.ui" line="88"/> + <source>&Delete</source> + <translation>&Löschen</translation> + </message> +</context> +<context> + <name>AddressTableModel</name> + <message> + <location filename="../addresstablemodel.cpp" line="78"/> + <source>Label</source> + <translation>Bezeichnung</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>(keine Bezeichnung)</translation> + </message> +</context> +<context> + <name>BitcoinGUI</name> + <message> + <location filename="../bitcoingui.cpp" line="50"/> + <source>Bitcoin Wallet</source> + <translation>Bitcoin Wallet</translation> + </message> + <message> + <location filename="../bitcoingui.cpp" line="112"/> + <source>Number of connections to other clients</source> + <translation>Anzahl der Verbindungen zu anderen Clients</translation> + </message> + <message> + <location filename="../bitcoingui.cpp" line="117"/> + <source>Number of blocks in the block chain</source> + <translation>Anzahl der Blöcke in der Block-Chain</translation> + </message> + <message> + <location filename="../bitcoingui.cpp" line="120"/> + <source>Synchronizing with network...</source> + <translation>Mit Netzwerk synchronisieren...</translation> + </message> + <message> + <location filename="../bitcoingui.cpp" line="123"/> + <source>Block chain synchronization in progress</source> + <translation>Synchronisierung der Block-Chain...</translation> + </message> + <message> + <location filename="../bitcoingui.cpp" line="140"/> + <source>&Overview</source> + <translation>Übersicht</translation> + </message> + <message> + <location filename="../bitcoingui.cpp" line="144"/> + <source>&Transactions</source> + <translation>Transaktionen</translation> + </message> + <message> + <location filename="../bitcoingui.cpp" line="148"/> + <source>&Address Book</source> + <translation>Adressbuch</translation> + </message> + <message> + <location filename="../bitcoingui.cpp" line="149"/> + <source>Edit the list of stored addresses and labels</source> + <translation>Adressen bearbeiten</translation> + </message> + <message> + <location filename="../bitcoingui.cpp" line="153"/> + <source>&Receive coins</source> + <translation>Bitcoins empfangen</translation> + </message> + <message> + <location filename="../bitcoingui.cpp" line="154"/> + <source>Show the list of addresses for receiving payments</source> + <translation>Empfangsadressen anzeigen</translation> + </message> + <message> + <location filename="../bitcoingui.cpp" line="158"/> + <source>&Send coins</source> + <translation>Bitcoins senden</translation> + </message> + <message> + <location filename="../bitcoingui.cpp" line="159"/> + <source>Send coins to a bitcoin address</source> + <translation>Bitcoins an eine Bitcoin-Adresse senden</translation> + </message> + <message> + <location filename="../bitcoingui.cpp" line="169"/> + <source>&Exit</source> + <translation>Beenden</translation> + </message> + <message> + <location filename="../bitcoingui.cpp" line="170"/> + <source>Quit application</source> + <translation>Anwendung beenden</translation> + </message> + <message> + <location filename="../bitcoingui.cpp" line="171"/> + <source>&About</source> + <translation>Über</translation> + </message> + <message> + <location filename="../bitcoingui.cpp" line="172"/> + <source>Show information about Bitcoin</source> + <translation>Informationen über Bitcoin</translation> + </message> + <message> + <location filename="../bitcoingui.cpp" line="173"/> + <source>&Options...</source> + <translation>Einstellungen</translation> + </message> + <message> + <location filename="../bitcoingui.cpp" line="174"/> + <source>Modify configuration options for bitcoin</source> + <translation>Einstellungen ändern</translation> + </message> + <message> + <location filename="../bitcoingui.cpp" line="175"/> + <source>Open &Bitcoin</source> + <translation>Bitcoin öffnen</translation> + </message> + <message> + <location filename="../bitcoingui.cpp" line="176"/> + <source>Show the Bitcoin window</source> + <translation>Bitcoin-Fenster anzeigen</translation> + </message> + <message> + <location filename="../bitcoingui.cpp" line="177"/> + <source>&Export...</source> + <translation>Exportieren...</translation> + </message> + <message> + <location filename="../bitcoingui.cpp" line="178"/> + <source>Export data in current view to a file</source> + <translation>Angezeigte Daten als Datei exportieren</translation> + </message> + <message> + <location filename="../bitcoingui.cpp" line="193"/> + <source>Bitcoin Wallet [testnet]</source> + <translation>Bitcoin Wallet [testnet]</translation> + </message> + <message numerus="yes"> + <location filename="../bitcoingui.cpp" line="298"/> + <source>%n connection(s)</source> + <translation> + <numerusform>%n Verbindung(en)</numerusform> + <numerusform></numerusform> + </translation> + </message> + <message numerus="yes"> + <location filename="../bitcoingui.cpp" line="317"/> + <source>%n block(s)</source> + <translation> + <numerusform>%n Blöcke</numerusform> + <numerusform></numerusform> + </translation> + </message> + <message> + <location filename="../bitcoingui.cpp" line="375"/> + <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>Die Größe dieser Transaktion übersteigt das Limit. + Sie können die Coins jedoch senden, wenn sie einen zusätzlichen Betrag von 1% zahlen, +welcher an die Teilnehmer des Bitcoin-Netzwerkes ausgeschüttet wird und dieses unterstützt. +Möchten Sie die zusätzliche Gebühr zahlen?</translation> + </message> + <message> + <location filename="../bitcoingui.cpp" line="379"/> + <source>Sending...</source> + <translation>Senden...</translation> + </message> + <message> + <location filename="../bitcoingui.cpp" line="407"/> + <source>Incoming transaction</source> + <translation>Eingehende Transaktion</translation> + </message> + <message> + <location filename="../bitcoingui.cpp" line="408"/> + <source>Date: </source> + <translation>Datum:</translation> + </message> + <message> + <location filename="../bitcoingui.cpp" line="409"/> + <source>Amount: </source> + <translation>Betrag:</translation> + </message> + <message> + <location filename="../bitcoingui.cpp" line="410"/> + <source>Type: </source> + <translation>Beschreibung:</translation> + </message> + <message> + <location filename="../bitcoingui.cpp" line="411"/> + <source>Address: </source> + <translation>Adresse:</translation> + </message> +</context> +<context> + <name>EditAddressDialog</name> + <message> + <location filename="../forms/editaddressdialog.ui" line="14"/> + <source>Edit Address</source> + <translation>Adresse bearbeiten</translation> + </message> + <message> + <location filename="../forms/editaddressdialog.ui" line="25"/> + <source>&Label</source> + <translation>Beschreibung</translation> + </message> + <message> + <location filename="../forms/editaddressdialog.ui" line="35"/> + <source>The label associated with this address book entry</source> + <translation>Name/Beschreibung des Adressbucheintrags</translation> + </message> + <message> + <location filename="../forms/editaddressdialog.ui" line="42"/> + <source>&Address</source> + <translation>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>Die Adresse des Adressbucheintrag. Diese kann nur für Zahlungsadressen bearbeitet werden.</translation> + </message> + <message> + <location filename="../editaddressdialog.cpp" line="20"/> + <source>New receiving address</source> + <translation>Neue Empfangsadresse</translation> + </message> + <message> + <location filename="../editaddressdialog.cpp" line="24"/> + <source>New sending address</source> + <translation>Neue Zahlungsadresse</translation> + </message> + <message> + <location filename="../editaddressdialog.cpp" line="27"/> + <source>Edit receiving address</source> + <translation>Empfangsadresse bearbeiten</translation> + </message> + <message> + <location filename="../editaddressdialog.cpp" line="31"/> + <source>Edit sending address</source> + <translation>Zahlungsadresse bearbeiten</translation> + </message> + <message> + <location filename="../editaddressdialog.cpp" line="89"/> + <source>The entered address "%1" is not a valid bitcoin address.</source> + <translation>Die eingegebene Adresse ("%1") ist keine gültige Bitcoin-Adresse.</translation> + </message> + <message> + <location filename="../editaddressdialog.cpp" line="97"/> + <source>The entered address "%1" is already in the address book.</source> + <translation>Die eingegebene Adresse ("%1") befindet sich bereits in Ihrem Adressbuch.</translation> + </message> +</context> +<context> + <name>MainOptionsPage</name> + <message> + <location filename="../optionsdialog.cpp" line="142"/> + <source>&Start Bitcoin on window system startup</source> + <translation>Bitcoin beim Start des Systems ausführen</translation> + </message> + <message> + <location filename="../optionsdialog.cpp" line="143"/> + <source>Automatically start Bitcoin after the computer is turned on</source> + <translation>Bitcoin automatisch beim Systemstart ausführen</translation> + </message> + <message> + <location filename="../optionsdialog.cpp" line="146"/> + <source>&Minimize to the tray instead of the taskbar</source> + <translation>In den Infobereich statt der Taskleiste minimieren</translation> + </message> + <message> + <location filename="../optionsdialog.cpp" line="147"/> + <source>Show only a tray icon after minimizing the window</source> + <translation>Minimiert nur im Infobereich anzeigen.</translation> + </message> + <message> + <location filename="../optionsdialog.cpp" line="150"/> + <source>Map port using &UPnP</source> + <translation>Portweiterleitung via UPnP</translation> + </message> + <message> + <location filename="../optionsdialog.cpp" line="151"/> + <source>Automatically open the Bitcoin client port on the router. This only works when your router supports UPnP and it is enabled.</source> + <translation>Öffnet den Bitcoin Client-Port automatisch auf dem Router. Dies funktioniert nur, wenn Ihr Router UPnP unterstützt und dies aktiviert ist.</translation> + </message> + <message> + <location filename="../optionsdialog.cpp" line="154"/> + <source>M&inimize on close</source> + <translation>Beim Schließen minimieren</translation> + </message> + <message> + <location filename="../optionsdialog.cpp" line="155"/> + <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>Minimiert die Anwendung, wenn das Fenster geschlossen wird. Wenn dies aktiviert ist, müssen Sie das Programm über "Beenden" im Menü schließen.</translation> + </message> + <message> + <location filename="../optionsdialog.cpp" line="158"/> + <source>&Connect through SOCKS4 proxy:</source> + <translation>Über SOCKS4-Proxy verbinden:</translation> + </message> + <message> + <location filename="../optionsdialog.cpp" line="159"/> + <source>Connect to the Bitcon network through a SOCKS4 proxy (e.g. when connecting through Tor)</source> + <translation>Über SOCKS4-Proxy zum Bitcoin-Netzwerk verbinden (bspw. für eine Verbindung über Tor)</translation> + </message> + <message> + <location filename="../optionsdialog.cpp" line="164"/> + <source>Proxy &IP: </source> + <translation>Proxy-IP:</translation> + </message> + <message> + <location filename="../optionsdialog.cpp" line="170"/> + <source>IP address of the proxy (e.g. 127.0.0.1)</source> + <translation>IP-Adresse des Proxys (z.B. 127.0.0.1)</translation> + </message> + <message> + <location filename="../optionsdialog.cpp" line="173"/> + <source>&Port: </source> + <translation>Port:</translation> + </message> + <message> + <location filename="../optionsdialog.cpp" line="179"/> + <source>Port of the proxy (e.g. 1234)</source> + <translation>Port des Proxy-Servers (z.B. 1234)</translation> + </message> + <message> + <location filename="../optionsdialog.cpp" line="185"/> + <source>Optional transaction fee per KB that helps make sure your transactions are processed quickly. Most transactions are 1KB. Fee 0.01 recommended.</source> + <translation>Zusätzliche Transaktionsgebühr per KB, welche sicherstellt dass Ihre Transaktionen schnell bearbeitet werden. Die meisten Transaktionen sind 1KB groß. Eine Gebühr von 0.01 wird empfohlen.</translation> + </message> + <message> + <location filename="../optionsdialog.cpp" line="191"/> + <source>Pay transaction &fee</source> + <translation>Transaktionsgebühr bezahlen</translation> + </message> + <message> + <location filename="../optionsdialog.cpp" line="194"/> + <source>Optional transaction fee per KB that helps make sure your transactions are processed quickly. Most transactions are 1KB. Fee 0.01 recommended.</source> + <translation>Zusätzliche Transaktionsgebühr per KB, welche sicherstellt dass Ihre Transaktionen schnell bearbeitet werden. Die meisten Transaktionen sind 1KB groß. Eine Gebühr von 0.01 wird empfohlen.</translation> + </message> +</context> +<context> + <name>OptionsDialog</name> + <message> + <location filename="../optionsdialog.cpp" line="54"/> + <source>Main</source> + <translation>Haupt</translation> + </message> + <message> + <location filename="../optionsdialog.cpp" line="74"/> + <source>Options</source> + <translation>Einstellungen</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="38"/> + <source>Balance:</source> + <translation>Kontostand:</translation> + </message> + <message> + <location filename="../forms/overviewpage.ui" line="45"/> + <source>123.456 BTC</source> + <translation></translation> + </message> + <message> + <location filename="../forms/overviewpage.ui" line="52"/> + <source>Number of transactions:</source> + <translation>Anzahl der Transaktionen:</translation> + </message> + <message> + <location filename="../forms/overviewpage.ui" line="59"/> + <source>0</source> + <translation></translation> + </message> + <message> + <location filename="../overviewpage.cpp" line="14"/> + <source>Your current balance</source> + <translation>Kontostand</translation> + </message> +</context> +<context> + <name>SendCoinsDialog</name> + <message> + <location filename="../forms/sendcoinsdialog.ui" line="14"/> + <location filename="../sendcoinsdialog.cpp" line="56"/> + <location filename="../sendcoinsdialog.cpp" line="78"/> + <location filename="../sendcoinsdialog.cpp" line="84"/> + <location filename="../sendcoinsdialog.cpp" line="90"/> + <location filename="../sendcoinsdialog.cpp" line="96"/> + <source>Send Coins</source> + <translation>Bitcoins überweisen</translation> + </message> + <message> + <location filename="../forms/sendcoinsdialog.ui" line="27"/> + <source>The address to send the payment to (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L)</source> + <translation>Empfangsadresse für die Überweisung (z.B. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L)</translation> + </message> + <message> + <location filename="../forms/sendcoinsdialog.ui" line="37"/> + <source>Look up adress in address book</source> + <translation>Adressbuch</translation> + </message> + <message> + <location filename="../forms/sendcoinsdialog.ui" line="47"/> + <source>Alt+A</source> + <translation>Alt+A</translation> + </message> + <message> + <location filename="../forms/sendcoinsdialog.ui" line="60"/> + <source>Paste address from system clipboard</source> + <translation>Adresse aus der Zwischenanlage einfügen</translation> + </message> + <message> + <location filename="../forms/sendcoinsdialog.ui" line="70"/> + <source>Alt+P</source> + <translation>Alt+P</translation> + </message> + <message> + <location filename="../forms/sendcoinsdialog.ui" line="82"/> + <source>A&mount:</source> + <translation>Betrag:</translation> + </message> + <message> + <location filename="../forms/sendcoinsdialog.ui" line="95"/> + <source>Pay &To:</source> + <translation>Empfänger:</translation> + </message> + <message> + <location filename="../forms/sendcoinsdialog.ui" line="113"/> + <source>Enter a Bitcoin address (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L)</source> + <translation>Bitcoin-Adresse eingeben (z.B. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L)</translation> + </message> + <message> + <location filename="../forms/sendcoinsdialog.ui" line="131"/> + <location filename="../sendcoinsdialog.cpp" line="23"/> + <source>Enter a label for this address to add it to your address book</source> + <translation>Beschreibung der Adresse im Adressbuch</translation> + </message> + <message> + <location filename="../forms/sendcoinsdialog.ui" line="140"/> + <source>&Label:</source> + <translation>Beschreibung:</translation> + </message> + <message> + <location filename="../forms/sendcoinsdialog.ui" line="183"/> + <source>Confirm the send action</source> + <translation>Überweisung bestätigen</translation> + </message> + <message> + <location filename="../forms/sendcoinsdialog.ui" line="186"/> + <source>&Send</source> + <translation>Überweisen</translation> + </message> + <message> + <location filename="../forms/sendcoinsdialog.ui" line="206"/> + <source>Abort the send action</source> + <translation>Überweisung abbrechen</translation> + </message> + <message> + <location filename="../sendcoinsdialog.cpp" line="57"/> + <source>Must fill in an amount to pay.</source> + <translation>Bitte geben Sie einen Betrag ein.</translation> + </message> + <message> + <location filename="../sendcoinsdialog.cpp" line="65"/> + <source>Confirm send coins</source> + <translation>Überweisung bestätigen</translation> + </message> + <message> + <location filename="../sendcoinsdialog.cpp" line="66"/> + <source>Are you sure you want to send %1 BTC to %2 (%3)?</source> + <translation>Möchten Sie %1 BTC an %2 (%3) überweisen?</translation> + </message> + <message> + <location filename="../sendcoinsdialog.cpp" line="79"/> + <source>The recepient address is not valid, please recheck.</source> + <translation>Die Empfangsadresse ist ungültig.</translation> + </message> + <message> + <location filename="../sendcoinsdialog.cpp" line="85"/> + <source>The amount to pay must be larger than 0.</source> + <translation>Der Betrag muss mehr als 0 betragen.</translation> + </message> + <message> + <location filename="../sendcoinsdialog.cpp" line="91"/> + <source>Amount exceeds your balance</source> + <translation>Der Betrag übersteigt ihren Kontostand</translation> + </message> + <message> + <location filename="../sendcoinsdialog.cpp" line="97"/> + <source>Total exceeds your balance when the %1 transaction fee is included</source> + <translation>Betrag übersteigt ihren Kontostand aufgrund der Transaktionsgebühren in Höhe von %1</translation> + </message> +</context> +<context> + <name>TransactionDescDialog</name> + <message> + <location filename="../forms/transactiondescdialog.ui" line="14"/> + <source>Transaction details</source> + <translation>Transaktionsübersicht</translation> + </message> + <message> + <location filename="../forms/transactiondescdialog.ui" line="20"/> + <source>This pane shows a detailed description of the transaction</source> + <translation>Dieses Fenster zeigt ihnen eine detaillierte Übersicht der Transaktion an</translation> + </message> +</context> +<context> + <name>TransactionTableModel</name> + <message> + <location filename="../transactiontablemodel.cpp" line="211"/> + <source>Status</source> + <translation>Status</translation> + </message> + <message> + <location filename="../transactiontablemodel.cpp" line="211"/> + <source>Date</source> + <translation>Datum</translation> + </message> + <message> + <location filename="../transactiontablemodel.cpp" line="211"/> + <source>Type</source> + <translation>Beschreibung</translation> + </message> + <message> + <location filename="../transactiontablemodel.cpp" line="211"/> + <source>Address</source> + <translation>Adresse</translation> + </message> + <message> + <location filename="../transactiontablemodel.cpp" line="211"/> + <source>Amount</source> + <translation>Betrag</translation> + </message> + <message numerus="yes"> + <location filename="../transactiontablemodel.cpp" line="272"/> + <source>Open for %n block(s)</source> + <translation> + <numerusform>Offen für %n Blöcke</numerusform> + <numerusform></numerusform> + </translation> + </message> + <message> + <location filename="../transactiontablemodel.cpp" line="275"/> + <source>Open until %1</source> + <translation>Offen bis %1</translation> + </message> + <message> + <location filename="../transactiontablemodel.cpp" line="278"/> + <source>Offline (%1 confirmations)</source> + <translation>Nicht verbunden (%1 Bestätigungen)</translation> + </message> + <message> + <location filename="../transactiontablemodel.cpp" line="281"/> + <source>Unconfirmed (%1/%2 confirmations)</source> + <translation>Unbestätigt (%1/%2 Bestätigungen)</translation> + </message> + <message> + <location filename="../transactiontablemodel.cpp" line="284"/> + <source>Confirmed (%1 confirmations)</source> + <translation>Bestätigt (%1 Bestätigungen)</translation> + </message> + <message numerus="yes"> + <location filename="../transactiontablemodel.cpp" line="293"/> + <source>Mined balance will be available in %n more blocks</source> + <translation> + <numerusform>Der Betrag wird in %n Blöcken verfügbar sein</numerusform> + <numerusform></numerusform> + </translation> + </message> + <message> + <location filename="../transactiontablemodel.cpp" line="299"/> + <source>This block was not received by any other nodes and will probably not be accepted!</source> + <translation>Dieser Block wurde vom Netzwerk nicht angenommen und wird wahrscheinlich nicht bestätigt werden!</translation> + </message> + <message> + <location filename="../transactiontablemodel.cpp" line="302"/> + <source>Generated but not accepted</source> + <translation>Generiert, jedoch nicht angenommen</translation> + </message> + <message> + <location filename="../transactiontablemodel.cpp" line="348"/> + <source>Received with</source> + <translation>Empfangen durch</translation> + </message> + <message> + <location filename="../transactiontablemodel.cpp" line="351"/> + <source>Received from IP</source> + <translation>Empfangen durch IP</translation> + </message> + <message> + <location filename="../transactiontablemodel.cpp" line="354"/> + <source>Sent to</source> + <translation>An</translation> + </message> + <message> + <location filename="../transactiontablemodel.cpp" line="357"/> + <source>Sent to IP</source> + <translation>An IP</translation> + </message> + <message> + <location filename="../transactiontablemodel.cpp" line="360"/> + <source>Payment to yourself</source> + <translation>Überweisung an Sie selbst</translation> + </message> + <message> + <location filename="../transactiontablemodel.cpp" line="363"/> + <source>Mined</source> + <translation>Erarbeitet</translation> + </message> + <message> + <location filename="../transactiontablemodel.cpp" line="578"/> + <source>Transaction status. Hover over this field to show number of confirmations.</source> + <translation>Transaktionsstatus. Fahren Sie mit der Maus über dieses Feld um die Anzahl der Bestätigungen zu sehen.</translation> + </message> + <message> + <location filename="../transactiontablemodel.cpp" line="580"/> + <source>Date and time that the transaction was received.</source> + <translation>Datum und Uhrzeit als die Transaktion empfangen wurde.</translation> + </message> + <message> + <location filename="../transactiontablemodel.cpp" line="582"/> + <source>Type of transaction.</source> + <translation>Art der Transaktion.</translation> + </message> + <message> + <location filename="../transactiontablemodel.cpp" line="584"/> + <source>Destination address of transaction.</source> + <translation>Empfangsadresse der Transaktion</translation> + </message> + <message> + <location filename="../transactiontablemodel.cpp" line="586"/> + <source>Amount removed from or added to balance.</source> + <translation>Betrag vom Kontostand entfernt oder hinzugefügt.</translation> + </message> +</context> +<context> + <name>TransactionView</name> + <message> + <location filename="../transactionview.cpp" line="39"/> + <location filename="../transactionview.cpp" line="52"/> + <source>All</source> + <translation>Alle</translation> + </message> + <message> + <location filename="../transactionview.cpp" line="40"/> + <source>Today</source> + <translation>Heute</translation> + </message> + <message> + <location filename="../transactionview.cpp" line="41"/> + <source>This week</source> + <translation>Diese Woche</translation> + </message> + <message> + <location filename="../transactionview.cpp" line="42"/> + <source>This month</source> + <translation>Diesen Monat</translation> + </message> + <message> + <location filename="../transactionview.cpp" line="43"/> + <source>Last month</source> + <translation>Letzten Monat</translation> + </message> + <message> + <location filename="../transactionview.cpp" line="44"/> + <source>This year</source> + <translation>Dieses Jahr</translation> + </message> + <message> + <location filename="../transactionview.cpp" line="45"/> + <source>Range...</source> + <translation>Bereich...</translation> + </message> + <message> + <location filename="../transactionview.cpp" line="53"/> + <source>Received with</source> + <translation>Empfangen durch</translation> + </message> + <message> + <location filename="../transactionview.cpp" line="55"/> + <source>Sent to</source> + <translation>An</translation> + </message> + <message> + <location filename="../transactionview.cpp" line="57"/> + <source>To yourself</source> + <translation>Zu Ihnen selbst</translation> + </message> + <message> + <location filename="../transactionview.cpp" line="58"/> + <source>Mined</source> + <translation>Erarbeitet</translation> + </message> + <message> + <location filename="../transactionview.cpp" line="59"/> + <source>Other</source> + <translation>Andere</translation> + </message> + <message> + <location filename="../transactionview.cpp" line="208"/> + <source>Export Transaction Data</source> + <translation>Transaktionen exportieren</translation> + </message> + <message> + <location filename="../transactionview.cpp" line="210"/> + <source>Comma separated file (*.csv)</source> + <translation></translation> + </message> + <message> + <location filename="../transactionview.cpp" line="230"/> + <source>Error exporting</source> + <translation>Fehler beim exportieren</translation> + </message> + <message> + <location filename="../transactionview.cpp" line="230"/> + <source>Could not write to file %1.</source> + <translation>Konnte Datei %1 nicht zum beschreiben öffnen</translation> + </message> +</context> +<context> + <name>WalletModel</name> + <message> + <location filename="../walletmodel.cpp" line="95"/> + <source>Sending...</source> + <translation>Senden...</translation> + </message> +</context> +<context> + <name>bitcoin-core</name> + <message> + <location filename="../bitcoinstrings.cpp" line="3"/> + <source>Bitcoin version</source> + <translation>Bitcoin Version</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="4"/> + <source>Usage:</source> + <translation>Verwendung:</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="5"/> + <source>Send command to -server or bitcoind +</source> + <translation>RPC-Befehl an bitcoind schicken</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="6"/> + <source>List commands +</source> + <translation>RPC-Befehle auflisten</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="7"/> + <source>Get help for a command +</source> + <translation>Hilfe</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="8"/> + <source>Options: +</source> + <translation>Einstellungen</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="9"/> + <source>Specify configuration file (default: bitcoin.conf) +</source> + <translation>Bitte wählen Sie eine Konfigurationsdatei (Standard: bitcoin.conf)</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="10"/> + <source>Specify pid file (default: bitcoind.pid) +</source> + <translation>Bitte wählen Sie den Namen der PID Datei (Standard bitcoind.pid)</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="11"/> + <source>Generate coins +</source> + <translation>Erarbeite Bitcoins</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="12"/> + <source>Don't generate coins +</source> + <translation>Keine BitCoins erstellen</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="13"/> + <source>Start minimized +</source> + <translation>minimiert starten</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="14"/> + <source>Specify data directory +</source> + <translation>Bitte wählen Sie das Datenverzeichnis</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="15"/> + <source>Specify connection timeout (in milliseconds) +</source> + <translation>Netzwerkverbindungsabbruch nach (in Millisekunden)</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="16"/> + <source>Connect through socks4 proxy +</source> + <translation>Durch SOCKS4-Proxy verbinden</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="17"/> + <source>Allow DNS lookups for addnode and connect +</source> + <translation>Erlaube DNS Namensauflösung für addnode und connect</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="18"/> + <source>Add a node to connect to +</source> + <translation>Bitcoin Server registrieren</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="19"/> + <source>Connect only to the specified node +</source> + <translation>Nur zu den angegebenen Servern verbinden</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="20"/> + <source>Don't accept connections from outside +</source> + <translation>Keine externen Transatkionen akzeptieren</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="21"/> + <source>Don't attempt to use UPnP to map the listening port +</source> + <translation>UPnP nicht verwenden</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="22"/> + <source>Attempt to use UPnP to map the listening port +</source> + <translation>Versuche eine Verbindung mittels UPnP herzustellen</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="23"/> + <source>Fee per KB to add to transactions you send +</source> + <translation>Gebühr pro KB (je von Ihnen verschickte Transatkion)</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="24"/> + <source>Accept command line and JSON-RPC commands +</source> + <translation>Erlaube Kommandozeilen und RPC Befehle</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="25"/> + <source>Run in the background as a daemon and accept commands +</source> + <translation>Als Hintergrunddienst starten</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="26"/> + <source>Use the test network +</source> + <translation>Im Testnetz starten</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="27"/> + <source>Username for JSON-RPC connections +</source> + <translation>Benutzername für RPC Befehle</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="28"/> + <source>Password for JSON-RPC connections +</source> + <translation>Passwort für RPC Befehle</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="29"/> + <source>Listen for JSON-RPC connections on <port> (default: 8332) +</source> + <translation>Port für RPC Befehle</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="30"/> + <source>Allow JSON-RPC connections from specified IP address +</source> + <translation>RPC Befehle nur von dieser IP-Adresse erlauben</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="31"/> + <source>Send commands to node running on <ip> (default: 127.0.0.1) +</source> + <translation>Befehl an einen anderen BitCoin Server senden</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="32"/> + <source>Set key pool size to <n> (default: 100) +</source> + <translation>Menge der vorgenerierten Adressen</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="33"/> + <source>Rescan the block chain for missing wallet transactions +</source> + <translation>Block-Chain nach verlorenen Transaktionen durchsuchen (rescan)</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="34"/> + <source> +SSL options: (see the Bitcoin Wiki for SSL setup instructions) +</source> + <translation>SSL Einstellungen (Bitte sehen Sie für eine detallierte Beschreibung im BitCoin-Wiki nach</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="37"/> + <source>Use OpenSSL (https) for JSON-RPC connections +</source> + <translation>RPC Befehle über HTTPS</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="38"/> + <source>Server certificate file (default: server.cert) +</source> + <translation>SSL Server Zertifikat</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="39"/> + <source>Server private key (default: server.pem) +</source> + <translation>Privater SSL Schlüssel (Standard: server.pem)</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="40"/> + <source>Acceptable ciphers (default: TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!AH:!3DES:@STRENGTH) +</source> + <translation>Erlaubte Kryptographiealgorithmen (Standard: TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!AH:!3DES:@STRENGTH)</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="43"/> + <source>This help message +</source> + <translation>Dieser Hilfetext</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="44"/> + <source>Cannot obtain a lock on data directory %s. Bitcoin is probably already running.</source> + <translation>Konnte das Datenverzeichnis %s nicht sperren. Evtl. wurde das Programm mehrfach gestartet.</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="47"/> + <source>Error loading addr.dat +</source> + <translation>Fehler beim laden der addr.dat</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="48"/> + <source>Error loading blkindex.dat +</source> + <translation>Fehler beim laden der blkindex.dat</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="49"/> + <source>Error loading wallet.dat +</source> + <translation>Fehler beim laden von wallet.dat</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="50"/> + <source>Invalid -proxy address</source> + <translation>Fehlerhafte Proxy Adresse</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="51"/> + <source>Invalid amount for -paytxfee=<amount></source> + <translation>Ungültige Angabe für -paytxfee=<Betrag></translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="52"/> + <source>Warning: -paytxfee is set very high. This is the transaction fee you will pay if you send a transaction.</source> + <translation>Warnung: -paytxfee ist auf einen sehr hohen Wert gesetzt. Dies ist die Gebühr die beim senden einer Transaktion fällig wird.</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="55"/> + <source>Warning: Disk space is low </source> + <translation>Warnung: Festplattenplatz wird knapp.</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="56"/> + <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>Fehler: Diese Transaktion erfordert eine Gebühr von mindestens %s. Die Gebühr wird fällig aufgrund der Größe, der Komplexität oder der Verwendung erst kürzlich erhaltener BitCoins</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="59"/> + <source>Error: Transaction creation failed </source> + <translation>Fehler: Die Transaktion konnte nicht erstellt werden.</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="60"/> + <source>Sending...</source> + <translation>Senden...</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="61"/> + <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>Fehler: Die Transaktion wurde zurückgewiesen. Dies kann passieren wenn einige Ihrer BitCoins bereits ausgegeben wurde (zB aus einer Sicherungskopie Ihrer wallet.dat)</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="65"/> + <source>Invalid amount</source> + <translation>Fehlerhafter Betrag</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="66"/> + <source>Insufficient funds</source> + <translation>Unzureichender Kontostand</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="67"/> + <source>Invalid bitcoin address</source> + <translation>Fehlerhafte Bitcoin Adresse</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="68"/> + <source>Unable to bind to port %d on this computer. Bitcoin is probably already running.</source> + <translation>Fehler beim registrieren des Ports %d auf diesem Computer. Evtl. läuft BitCoin bereits</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="71"/> + <source>To use the %s option</source> + <translation>Um die Option %s zuu verwenden</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="72"/> + <source>Warning: %s, you must set rpcpassword=<password> +in the configuration file: %s +If the file does not exist, create it with owner-readable-only file permissions. +</source> + <translation>Warnung: Sie müssen rpcpassword=password in der Konfigurationsdatei angeben.</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="77"/> + <source>You must set rpcpassword=<password> in the configuration file: +%s +If the file does not exist, create it with owner-readable-only file permissions.</source> + <translation>Sie müssen rpcpassword=password in der Konfigurationsdatei angeben.</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="82"/> + <source>Warning: Please check that your computer's date and time are correct. If your clock is wrong Bitcoin will not work properly.</source> + <translation>Bitte prüfen Sie Ihre Datums- und Uhrzeiteinstellungen, ansonsten kann es sein das BitCoin nicht ordnungsgemäss funktioniert.</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="85"/> + <source>-beta</source> + <translation>-beta</translation> + </message> +</context> +</TS> diff --git a/src/qt/locale/bitcoin_nl.ts b/src/qt/locale/bitcoin_nl.ts new file mode 100644 index 0000000000..afe0dc89e2 --- /dev/null +++ b/src/qt/locale/bitcoin_nl.ts @@ -0,0 +1,1441 @@ +<?xml version="1.0" encoding="utf-8"?> +<!DOCTYPE TS> +<TS version="2.0" language="nl_NL"> +<defaultcodec>UTF-8</defaultcodec> +<context> + <name>AboutDialog</name> + <message> + <location filename="../forms/aboutdialog.ui" line="14"/> + <source>About Bitcoin</source> + <translation>Over Bitcoin +</translation> + </message> + <message> + <location filename="../forms/aboutdialog.ui" line="53"/> + <source><b>Bitcoin</b> version</source> + <translation><b>Bitcoin</b> versie</translation> + </message> + <message> + <location filename="../forms/aboutdialog.ui" line="85"/> + <source>Copyright © 2009-2011 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-2011 Bitcoin-ontwikkelaars + +Dit is experimentele software. + +Gedistributeerd onder de MIT/X11 software licentie, zie het bijgevoegde bestand +license.txt of kijk op http://www.opensource.org/licenses/mit-license.php. + +Dit product bevat software ontwikkeld door het OpenSSL project for gebruik +in de OpenSSL Toolkit (http://www.openssl.org/), en cryptografische +software geschreven door Eric Young (eay@cryptsoft.com)) en UPnP software geschreven +door Thomas Bernard. +</translation> + </message> +</context> +<context> + <name>AddressBookDialog</name> + <message> + <source>Address Book</source> + <translation type="obsolete">Adresboek</translation> + </message> + <message> + <source>Sending</source> + <translation type="obsolete">Versturen</translation> + </message> + <message> + <source>Receiving</source> + <translation type="obsolete">Ontvangen</translation> + </message> + <message> + <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. The highlighted address is displayed in the main window.</source> + <translation type="obsolete">Dit zijn je bitcoin-adressen voor het ontvangen van betalingen. Het is een goed idee iedere afzender een ander adres te geven zodat je bij kunt houden wie je een betaling stuurt. Het geselecteerde adres is zichtbaar in het hoofdscherm.</translation> + </message> + <message> + <source>Create a new address</source> + <translation type="obsolete">Voeg een nieuw adres toe</translation> + </message> + <message> + <source>&New Address...</source> + <translation type="obsolete">&Nieuw adres...</translation> + </message> + <message> + <source>Copy the currently selected address to the system clipboard</source> + <translation type="obsolete">Kopieer het geselecteerde adres naar het plakbord</translation> + </message> + <message> + <source>&Copy to Clipboard</source> + <translation type="obsolete">&Kopieer naar plakbord</translation> + </message> + <message> + <source>Edit the currently selected address</source> + <translation type="obsolete">Bewerk het geselecteerde adres</translation> + </message> + <message> + <source>&Edit...</source> + <translation type="obsolete">&Bewerken...</translation> + </message> + <message> + <source>Delete the currently selected address from the list. Only sending addresses can be deleted.</source> + <translation type="obsolete">Verwijder het geselecteerde adres. Alleen verstuur-adressen kunnen worden verwijderd.</translation> + </message> + <message> + <source>&Delete</source> + <translation type="obsolete">&Verwijderen</translation> + </message> +</context> +<context> + <name>AddressBookPage</name> + <message> + <location filename="../forms/addressbookpage.ui" line="14"/> + <source>Address Book</source> + <translation type="unfinished">Adresboek</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 type="unfinished"></translation> + </message> + <message> + <location filename="../forms/addressbookpage.ui" line="33"/> + <source>Double-click to edit address or label</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../forms/addressbookpage.ui" line="57"/> + <source>Create a new address</source> + <translation type="unfinished">Voeg een nieuw adres toe</translation> + </message> + <message> + <location filename="../forms/addressbookpage.ui" line="60"/> + <source>&New Address...</source> + <translation type="unfinished">&Nieuw adres...</translation> + </message> + <message> + <location filename="../forms/addressbookpage.ui" line="71"/> + <source>Copy the currently selected address to the system clipboard</source> + <translation type="unfinished">Kopieer het geselecteerde adres naar het plakbord</translation> + </message> + <message> + <location filename="../forms/addressbookpage.ui" line="74"/> + <source>&Copy to Clipboard</source> + <translation type="unfinished">&Kopieer naar plakbord</translation> + </message> + <message> + <location filename="../forms/addressbookpage.ui" line="85"/> + <source>Delete the currently selected address from the list. Only sending addresses can be deleted.</source> + <translation type="unfinished">Verwijder het geselecteerde adres. Alleen verstuur-adressen kunnen worden verwijderd.</translation> + </message> + <message> + <location filename="../forms/addressbookpage.ui" line="88"/> + <source>&Delete</source> + <translation type="unfinished">&Verwijderen</translation> + </message> +</context> +<context> + <name>AddressTableModel</name> + <message> + <location filename="../addresstablemodel.cpp" line="78"/> + <source>Label</source> + <translation>Label</translation> + </message> + <message> + <location filename="../addresstablemodel.cpp" line="78"/> + <source>Address</source> + <translation>Adres</translation> + </message> + <message> + <location filename="../addresstablemodel.cpp" line="114"/> + <source>(no label)</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Default receiving address</source> + <translation type="obsolete">Standaard ontvangst-adres</translation> + </message> +</context> +<context> + <name>BitcoinGUI</name> + <message> + <source>Bitcoin</source> + <translation type="obsolete">Bitcoin</translation> + </message> + <message> + <source>Your Bitcoin address:</source> + <translation type="obsolete">Uw bitcoin-adres:</translation> + </message> + <message> + <source>Your current default receiving address</source> + <translation type="obsolete">Uw huidig standaard ontvangst-adres</translation> + </message> + <message> + <source>&New...</source> + <translation type="obsolete">&Nieuw...</translation> + </message> + <message> + <source>Create new receiving address</source> + <translation type="obsolete">Maak nieuw ontvangst-adres</translation> + </message> + <message> + <source>&Copy to clipboard</source> + <translation type="obsolete">&Kopieer naar plakbord</translation> + </message> + <message> + <source>Copy current receiving address to the system clipboard</source> + <translation type="obsolete">Kopieer huidig ontvangst-adres naar plakbord</translation> + </message> + <message> + <source>Balance:</source> + <translation type="obsolete">Saldo:</translation> + </message> + <message> + <source>Your current balance</source> + <translation type="obsolete">Uw huidige saldo</translation> + </message> + <message> + <location filename="../bitcoingui.cpp" line="112"/> + <source>Number of connections to other clients</source> + <translation>Aantal verbindingen met andere clients</translation> + </message> + <message> + <location filename="../bitcoingui.cpp" line="117"/> + <source>Number of blocks in the block chain</source> + <translation>Aantal blokken in de block-chain</translation> + </message> + <message> + <source>Number of transactions in your wallet</source> + <translation type="obsolete">Aantal transacties in je portefeuille</translation> + </message> + <message> + <location filename="../bitcoingui.cpp" line="120"/> + <source>Synchronizing with network...</source> + <translation>Synchroniseren met netwerk...</translation> + </message> + <message> + <location filename="../bitcoingui.cpp" line="123"/> + <source>Block chain synchronization in progress</source> + <translation>Bezig met blokken-database-synchronisatie</translation> + </message> + <message> + <location filename="../bitcoingui.cpp" line="169"/> + <source>&Exit</source> + <translation>A&fsluiten</translation> + </message> + <message> + <location filename="../bitcoingui.cpp" line="170"/> + <source>Quit application</source> + <translation>De applicatie afsluiten</translation> + </message> + <message> + <location filename="../bitcoingui.cpp" line="158"/> + <source>&Send coins</source> + <translation>&Verstuur coins</translation> + </message> + <message> + <location filename="../bitcoingui.cpp" line="159"/> + <source>Send coins to a bitcoin address</source> + <translation>Coins versturen naar een bitcoin-adres</translation> + </message> + <message> + <location filename="../bitcoingui.cpp" line="148"/> + <source>&Address Book</source> + <translation>&Adresboek</translation> + </message> + <message> + <location filename="../bitcoingui.cpp" line="50"/> + <source>Bitcoin Wallet</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../bitcoingui.cpp" line="140"/> + <source>&Overview</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../bitcoingui.cpp" line="144"/> + <source>&Transactions</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../bitcoingui.cpp" line="149"/> + <source>Edit the list of stored addresses and labels</source> + <translation>Bewerk de lijst van adressen en labels</translation> + </message> + <message> + <location filename="../bitcoingui.cpp" line="153"/> + <source>&Receive coins</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../bitcoingui.cpp" line="154"/> + <source>Show the list of addresses for receiving payments</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../bitcoingui.cpp" line="171"/> + <source>&About</source> + <translation>&Over Bitcoin</translation> + </message> + <message> + <location filename="../bitcoingui.cpp" line="172"/> + <source>Show information about Bitcoin</source> + <translation>Laat informatie zien over Bitcoin</translation> + </message> + <message> + <location filename="../bitcoingui.cpp" line="177"/> + <source>&Export...</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../bitcoingui.cpp" line="178"/> + <source>Export data in current view to a file</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../bitcoingui.cpp" line="193"/> + <source>[testnet]</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../bitcoingui.cpp" line="408"/> + <source>Date: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../bitcoingui.cpp" line="409"/> + <source>Amount: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../bitcoingui.cpp" line="410"/> + <source>Type: </source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../bitcoingui.cpp" line="411"/> + <source>Address: </source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Your &Receiving Addresses...</source> + <translation type="obsolete">&Uw ontvangstadressen...</translation> + </message> + <message> + <source>Show the list of receiving addresses and edit their labels</source> + <translation type="obsolete">Laat de lijst zien van ontvangst-adressen en bewerk de labels</translation> + </message> + <message> + <location filename="../bitcoingui.cpp" line="173"/> + <source>&Options...</source> + <translation>&Opties...</translation> + </message> + <message> + <location filename="../bitcoingui.cpp" line="174"/> + <source>Modify configuration options for bitcoin</source> + <translation>Verander instellingen van Bitcoin</translation> + </message> + <message> + <location filename="../bitcoingui.cpp" line="175"/> + <source>Open &Bitcoin</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../bitcoingui.cpp" line="176"/> + <source>Show the Bitcoin window</source> + <translation>Laat het Bitcoin-venster zien</translation> + </message> + <message> + <source>All transactions</source> + <translation type="obsolete">Alle transacties</translation> + </message> + <message> + <source>Sent/Received</source> + <translation type="obsolete">Verzonden/Ontvangen</translation> + </message> + <message> + <source>Sent</source> + <translation type="obsolete">Verzonden</translation> + </message> + <message> + <source>Received</source> + <translation type="obsolete">Ontvangen</translation> + </message> + <message numerus="yes"> + <location filename="../bitcoingui.cpp" line="298"/> + <source>%n connection(s)</source> + <translation> + <numerusform>%n verbinding</numerusform> + <numerusform>%n verbindingen</numerusform> + </translation> + </message> + <message numerus="yes"> + <location filename="../bitcoingui.cpp" line="317"/> + <source>%n block(s)</source> + <translation> + <numerusform>%n blok</numerusform> + <numerusform>%n blokken</numerusform> + </translation> + </message> + <message numerus="yes"> + <source>%n transaction(s)</source> + <translation type="obsolete"> + <numerusform>%n transactie</numerusform> + <numerusform>%n transacties</numerusform> + </translation> + </message> + <message> + <location filename="../bitcoingui.cpp" line="375"/> + <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>Deze transactie overschrijdt de limiet. Om de transactie alsnog te verwerken kun je een fooi betalen van %1. Deze zal betaald worden aan de node die uw transactie verwerkt. Wil je doorgaan en deze fooi betalen?</translation> + </message> + <message> + <location filename="../bitcoingui.cpp" line="379"/> + <source>Sending...</source> + <translation>Versturen...</translation> + </message> + <message> + <location filename="../bitcoingui.cpp" line="407"/> + <source>Incoming transaction</source> + <translation>Binnenkomende transactie</translation> + </message> +</context> +<context> + <name>ClientModel</name> + <message> + <source>Sending...</source> + <translation type="obsolete">Versturen...</translation> + </message> +</context> +<context> + <name>EditAddressDialog</name> + <message> + <location filename="../forms/editaddressdialog.ui" line="14"/> + <source>Edit Address</source> + <translation>Bewerk Adres</translation> + </message> + <message> + <location filename="../forms/editaddressdialog.ui" line="25"/> + <source>&Label</source> + <translation>&Label</translation> + </message> + <message> + <location filename="../forms/editaddressdialog.ui" line="42"/> + <source>&Address</source> + <translation>&Adres</translation> + </message> + <message> + <location filename="../forms/editaddressdialog.ui" line="35"/> + <source>The label associated with this address book entry</source> + <translation>Het label dat is geassocieerd met dit adres</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>Het adres dat is geassocieerd met de label. Dit kan alleen worden veranderd voor verzend-adressen.</translation> + </message> + <message> + <source>Set as default receiving address</source> + <translation type="obsolete">Stel in as standaard ontvangst-adres</translation> + </message> + <message> + <location filename="../editaddressdialog.cpp" line="20"/> + <source>New receiving address</source> + <translation>Nieuw ontvangst-adres</translation> + </message> + <message> + <location filename="../editaddressdialog.cpp" line="24"/> + <source>New sending address</source> + <translation>Nieuw verzend-adres</translation> + </message> + <message> + <location filename="../editaddressdialog.cpp" line="27"/> + <source>Edit receiving address</source> + <translation>Bewerk ontvangst-adres</translation> + </message> + <message> + <location filename="../editaddressdialog.cpp" line="31"/> + <source>Edit sending address</source> + <translation>Bewerk ontvangst-adres</translation> + </message> + <message> + <location filename="../editaddressdialog.cpp" line="89"/> + <source>The entered address "%1" is not a valid bitcoin address.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../editaddressdialog.cpp" line="97"/> + <source>The entered address "%1" is already in the address book.</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>The address %1 is already in the address book.</source> + <translation type="obsolete">Het adres %1 staat al in het adresboek.</translation> + </message> +</context> +<context> + <name>MainOptionsPage</name> + <message> + <location filename="../optionsdialog.cpp" line="142"/> + <source>&Start Bitcoin on window system startup</source> + <translation>&Start Bitcoin wanneer het systeem opstart</translation> + </message> + <message> + <location filename="../optionsdialog.cpp" line="143"/> + <source>Automatically start Bitcoin after the computer is turned on</source> + <translation>Start Bitcoin automatisch wanneer het systeem start</translation> + </message> + <message> + <location filename="../optionsdialog.cpp" line="146"/> + <source>&Minimize to the tray instead of the taskbar</source> + <translation>&Minimaliseer tot systeemvak in plaats van de taakbalk</translation> + </message> + <message> + <location filename="../optionsdialog.cpp" line="147"/> + <source>Show only a tray icon after minimizing the window</source> + <translation>Laat alleen een systeemvak-icoon zien wanneer het venster geminimaliseerd is</translation> + </message> + <message> + <location filename="../optionsdialog.cpp" line="150"/> + <source>Map port using &UPnP</source> + <translation>Portmapping via &UPnP</translation> + </message> + <message> + <location filename="../optionsdialog.cpp" line="151"/> + <source>Automatically open the Bitcoin client port on the router. This only works when your router supports UPnP and it is enabled.</source> + <translation>Open de Bitcoin-poort automatisch op de router. Dit werkt alleen als de router UPnP ondersteunt.</translation> + </message> + <message> + <location filename="../optionsdialog.cpp" line="154"/> + <source>M&inimize on close</source> + <translation>&Minimaliseer bij sluiten van het venster</translation> + </message> + <message> + <location filename="../optionsdialog.cpp" line="155"/> + <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>Minimiliseer het venster in de plaats van de applicatie af te sluiten als het venster gesloten wordt. Wanneer deze optie aan staan, kan de applicatie alleen worden afgesloten door Afsluiten te kiezen in het menu.</translation> + </message> + <message> + <location filename="../optionsdialog.cpp" line="158"/> + <source>&Connect through SOCKS4 proxy:</source> + <translation>&Verbind via socks4 proxy: </translation> + </message> + <message> + <location filename="../optionsdialog.cpp" line="159"/> + <source>Connect to the Bitcon network through a SOCKS4 proxy (e.g. when connecting through Tor)</source> + <translation>Verbind met het Bitcoin-netwerk door een SOCKS4 proxy (bijvoorbeeld Tor)</translation> + </message> + <message> + <location filename="../optionsdialog.cpp" line="164"/> + <source>Proxy &IP: </source> + <translation>Proxy &IP:</translation> + </message> + <message> + <location filename="../optionsdialog.cpp" line="170"/> + <source>IP address of the proxy (e.g. 127.0.0.1)</source> + <translation>IP adres van de proxy (bijv. 127.0.0.1)</translation> + </message> + <message> + <location filename="../optionsdialog.cpp" line="173"/> + <source>&Port: </source> + <translation>&Poort:</translation> + </message> + <message> + <location filename="../optionsdialog.cpp" line="179"/> + <source>Port of the proxy (e.g. 1234)</source> + <translation>Poort waarop de proxy luistert (bijv. 1234)</translation> + </message> + <message> + <location filename="../optionsdialog.cpp" line="185"/> + <source>Optional transaction fee per KB that helps make sure your transactions are processed quickly. Most transactions are 1KB. Fee 0.01 recommended.</source> + <translation>Optionele transactiefooi per KB die helpt ervoor zorgen dat uw transacties snel verwerkt worden. De meeste transacties zijn 1KB. Fooi 0.01 is aangeraden.</translation> + </message> + <message> + <location filename="../optionsdialog.cpp" line="191"/> + <source>Pay transaction &fee</source> + <translation>Transactie&fooi</translation> + </message> + <message> + <location filename="../optionsdialog.cpp" line="194"/> + <source>Optional transaction fee per KB that helps make sure your transactions are processed quickly. Most transactions are 1KB. Fee 0.01 recommended.</source> + <translation>Optionele transactiefooi per KB die helpt ervoor zorgen dat uw transacties snel verwerkt worden. De meeste transacties zijn 1KB. Fooi 0.01 is aangeraden.</translation> + </message> +</context> +<context> + <name>OptionsDialog</name> + <message> + <location filename="../optionsdialog.cpp" line="54"/> + <source>Main</source> + <translation>Algemeen</translation> + </message> + <message> + <location filename="../optionsdialog.cpp" line="74"/> + <source>Options</source> + <translation>Opties</translation> + </message> +</context> +<context> + <name>OverviewPage</name> + <message> + <location filename="../forms/overviewpage.ui" line="14"/> + <source>Form</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../forms/overviewpage.ui" line="38"/> + <source>Balance:</source> + <translation type="unfinished">Saldo:</translation> + </message> + <message> + <location filename="../forms/overviewpage.ui" line="45"/> + <source>123.456 BTC</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../forms/overviewpage.ui" line="52"/> + <source>Number of transactions:</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../forms/overviewpage.ui" line="59"/> + <source>0</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../overviewpage.cpp" line="14"/> + <source>Your current balance</source> + <translation type="unfinished">Uw huidige saldo</translation> + </message> +</context> +<context> + <name>SendCoinsDialog</name> + <message> + <location filename="../forms/sendcoinsdialog.ui" line="14"/> + <location filename="../sendcoinsdialog.cpp" line="56"/> + <location filename="../sendcoinsdialog.cpp" line="78"/> + <location filename="../sendcoinsdialog.cpp" line="84"/> + <location filename="../sendcoinsdialog.cpp" line="90"/> + <location filename="../sendcoinsdialog.cpp" line="96"/> + <source>Send Coins</source> + <translation>Verstuur coins</translation> + </message> + <message> + <source>&Amount:</source> + <translation type="obsolete">&Hoeveelheid:</translation> + </message> + <message> + <location filename="../forms/sendcoinsdialog.ui" line="95"/> + <source>Pay &To:</source> + <translation>Betaal &aan:</translation> + </message> + <message> + <location filename="../forms/sendcoinsdialog.ui" line="27"/> + <source>The address to send the payment to (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L)</source> + <translation>Voer een bitcoin-adres (bijvoorbeeld: 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L)</translation> + </message> + <message> + <location filename="../forms/sendcoinsdialog.ui" line="47"/> + <source>Alt+A</source> + <translation>Alt+A</translation> + </message> + <message> + <location filename="../forms/sendcoinsdialog.ui" line="60"/> + <source>Paste address from system clipboard</source> + <translation>Plak adres uit systeemplakbord</translation> + </message> + <message> + <location filename="../forms/sendcoinsdialog.ui" line="131"/> + <location filename="../sendcoinsdialog.cpp" line="23"/> + <source>Enter a label for this address to add it to your address book</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../forms/sendcoinsdialog.ui" line="140"/> + <source>&Label:</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>&Paste</source> + <translation type="obsolete">&Plakken</translation> + </message> + <message> + <location filename="../forms/sendcoinsdialog.ui" line="37"/> + <source>Look up adress in address book</source> + <translation>Opzoeken in adresboek</translation> + </message> + <message> + <source>Address &Book...</source> + <translation type="obsolete">Adres&boek....</translation> + </message> + <message> + <location filename="../forms/sendcoinsdialog.ui" line="70"/> + <source>Alt+P</source> + <translation>Alt+P</translation> + </message> + <message> + <location filename="../forms/sendcoinsdialog.ui" line="82"/> + <source>A&mount:</source> + <translation>&Hoeveelheid:</translation> + </message> + <message> + <location filename="../forms/sendcoinsdialog.ui" line="113"/> + <source>Enter a Bitcoin address (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L)</source> + <translation>Voer een bitcoin-adres in (bijvoorbeeld: 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L)</translation> + </message> + <message> + <source>Add specified destination address to address book</source> + <translation type="obsolete">Voeg het ingevoerde doel-adres toe aan het adresboek</translation> + </message> + <message> + <source>A&dd to address book as</source> + <translation type="obsolete">&Voeg toe aan adresboek als</translation> + </message> + <message> + <source>Label to add address as</source> + <translation type="obsolete">Label om toe te kennen aan adres in adresboek</translation> + </message> + <message> + <location filename="../forms/sendcoinsdialog.ui" line="183"/> + <source>Confirm the send action</source> + <translation>Bevestig de zend-transactie</translation> + </message> + <message> + <location filename="../forms/sendcoinsdialog.ui" line="186"/> + <source>&Send</source> + <translation>&Versturen</translation> + </message> + <message> + <location filename="../forms/sendcoinsdialog.ui" line="206"/> + <source>Abort the send action</source> + <translation>De transactie annuleren</translation> + </message> + <message> + <source>The amount to pay must be a valid number.</source> + <translation type="obsolete">Het ingevoerde bedrag is geen geldig getal.</translation> + </message> + <message> + <location filename="../sendcoinsdialog.cpp" line="57"/> + <source>Must fill in an amount to pay.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../sendcoinsdialog.cpp" line="65"/> + <source>Confirm send coins</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../sendcoinsdialog.cpp" line="66"/> + <source>Are you sure you want to send %1 BTC to %2 (%3)?</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../sendcoinsdialog.cpp" line="79"/> + <source>The recepient address is not valid, please recheck.</source> + <translation>Het verzendadres is niet geld.</translation> + </message> + <message> + <location filename="../sendcoinsdialog.cpp" line="85"/> + <source>The amount to pay must be larger than 0.</source> + <translation>Het ingevoerde gedrag moet groter zijn dan 0.</translation> + </message> + <message> + <location filename="../sendcoinsdialog.cpp" line="91"/> + <source>Amount exceeds your balance</source> + <translation>Hoeveelheid overschrijdt uw huidige balans</translation> + </message> + <message> + <location filename="../sendcoinsdialog.cpp" line="97"/> + <source>Total exceeds your balance when the %1 transaction fee is included</source> + <translation>Totaal overschrijdt uw huidige balans wanneer de %1 transactiefooi is meegerekend</translation> + </message> +</context> +<context> + <name>TransactionDescDialog</name> + <message> + <location filename="../forms/transactiondescdialog.ui" line="14"/> + <source>Transaction details</source> + <translation>Transactiedetails</translation> + </message> + <message> + <location filename="../forms/transactiondescdialog.ui" line="20"/> + <source>This pane shows a detailed description of the transaction</source> + <translation>Dit venster laat een uitgebreide beschrijving van de transactie zien</translation> + </message> +</context> +<context> + <name>TransactionTableModel</name> + <message> + <location filename="../transactiontablemodel.cpp" line="211"/> + <source>Status</source> + <translation>Status</translation> + </message> + <message> + <location filename="../transactiontablemodel.cpp" line="211"/> + <source>Date</source> + <translation>Datum</translation> + </message> + <message> + <location filename="../transactiontablemodel.cpp" line="211"/> + <source>Type</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../transactiontablemodel.cpp" line="211"/> + <source>Address</source> + <translation type="unfinished">Adres</translation> + </message> + <message> + <location filename="../transactiontablemodel.cpp" line="211"/> + <source>Amount</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../transactiontablemodel.cpp" line="278"/> + <source>Offline (%1 confirmations)</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../transactiontablemodel.cpp" line="281"/> + <source>Unconfirmed (%1/%2 confirmations)</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../transactiontablemodel.cpp" line="284"/> + <source>Confirmed (%1 confirmations)</source> + <translation type="unfinished"></translation> + </message> + <message numerus="yes"> + <location filename="../transactiontablemodel.cpp" line="293"/> + <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="299"/> + <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="302"/> + <source>Generated but not accepted</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../transactiontablemodel.cpp" line="348"/> + <source>Received with</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../transactiontablemodel.cpp" line="351"/> + <source>Received from IP</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../transactiontablemodel.cpp" line="354"/> + <source>Sent to</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../transactiontablemodel.cpp" line="357"/> + <source>Sent to IP</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../transactiontablemodel.cpp" line="363"/> + <source>Mined</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../transactiontablemodel.cpp" line="582"/> + <source>Type of transaction.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../transactiontablemodel.cpp" line="584"/> + <source>Destination address of transaction.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../transactiontablemodel.cpp" line="586"/> + <source>Amount removed from or added to balance.</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Description</source> + <translation type="obsolete">Beschrijving</translation> + </message> + <message> + <source>Debit</source> + <translation type="obsolete">Debet</translation> + </message> + <message> + <source>Credit</source> + <translation type="obsolete">Credit</translation> + </message> + <message numerus="yes"> + <location filename="../transactiontablemodel.cpp" line="272"/> + <source>Open for %n block(s)</source> + <translation> + <numerusform>Open gedurende %n blok</numerusform> + <numerusform>Open gedurende %n blokken</numerusform> + </translation> + </message> + <message> + <location filename="../transactiontablemodel.cpp" line="275"/> + <source>Open until %1</source> + <translation>Open tot %1</translation> + </message> + <message> + <source>Offline (%1)</source> + <translation type="obsolete">Offline (%1)</translation> + </message> + <message> + <source>Unconfirmed (%1/%2)</source> + <translation type="obsolete">Niet bevestigd (%1/%2)</translation> + </message> + <message> + <source>Confirmed (%1)</source> + <translation type="obsolete">Bevestigd (%1)</translation> + </message> + <message> + <source>Received with: </source> + <translation type="obsolete">Ontvangen met:</translation> + </message> + <message> + <source>Received from IP: </source> + <translation type="obsolete">Ontvangen van IP:</translation> + </message> + <message> + <source>Sent to: </source> + <translation type="obsolete">Verzonden aan:</translation> + </message> + <message> + <source>Sent to IP: </source> + <translation type="obsolete">Verzonden aan IP:</translation> + </message> + <message> + <location filename="../transactiontablemodel.cpp" line="360"/> + <source>Payment to yourself</source> + <translation>Betaling aan uzelf</translation> + </message> + <message numerus="yes"> + <source>Generated (matures in %n more blocks)</source> + <translation type="obsolete"> + <numerusform>Gegenereerd (wordt volwassen na %n blok)</numerusform> + <numerusform>Gegenereerd (wordt volwassen na %n blokken)</numerusform> + </translation> + </message> + <message> + <source>Generated</source> + <translation type="obsolete">Gegenereerd</translation> + </message> + <message> + <source>Generated - Warning: This block was not received by any other nodes and will probably not be accepted!</source> + <translation type="obsolete">Gegenereerd - Waarschuwing: Dit blok is niet ontvangen door andere nodes en zal waarschijnlijk niet geaccepteerd worden!</translation> + </message> + <message> + <source>Generated (not accepted)</source> + <translation type="obsolete">Gegenereerd (niet geaccepteerd)</translation> + </message> + <message> + <location filename="../transactiontablemodel.cpp" line="578"/> + <source>Transaction status. Hover over this field to show number of confirmations.</source> + <translation>Transactiestatus. Hou de muiscursor boven dit veld om het aantal bevestigingen te laten zien.</translation> + </message> + <message> + <location filename="../transactiontablemodel.cpp" line="580"/> + <source>Date and time that the transaction was received.</source> + <translation>Datum en tijd waarop deze transactie is ontvangen.</translation> + </message> + <message> + <source>Short description of the transaction.</source> + <translation type="obsolete">Korte beschrijving van de transactie.</translation> + </message> + <message> + <source>Amount removed from balance.</source> + <translation type="obsolete">Bedrag afgeschreven van saldo.</translation> + </message> + <message> + <source>Amount added to balance.</source> + <translation type="obsolete">Bedrag bijgeschreven bij saldo.</translation> + </message> +</context> +<context> + <name>TransactionView</name> + <message> + <location filename="../transactionview.cpp" line="39"/> + <location filename="../transactionview.cpp" line="52"/> + <source>All</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../transactionview.cpp" line="40"/> + <source>Today</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../transactionview.cpp" line="41"/> + <source>This week</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../transactionview.cpp" line="42"/> + <source>This month</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../transactionview.cpp" line="43"/> + <source>Last month</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../transactionview.cpp" line="44"/> + <source>This year</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../transactionview.cpp" line="45"/> + <source>Range...</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../transactionview.cpp" line="53"/> + <source>Received with</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../transactionview.cpp" line="55"/> + <source>Sent to</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../transactionview.cpp" line="57"/> + <source>To yourself</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../transactionview.cpp" line="58"/> + <source>Mined</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../transactionview.cpp" line="59"/> + <source>Other</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../transactionview.cpp" line="209"/> + <source>Export Transaction Data</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../transactionview.cpp" line="211"/> + <source>Comma separated file (*.csv)</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../transactionview.cpp" line="231"/> + <source>Error exporting</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../transactionview.cpp" line="231"/> + <source>Could not write to file %1.</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>WalletModel</name> + <message> + <location filename="../walletmodel.cpp" line="95"/> + <source>Sending...</source> + <translation type="unfinished">Versturen...</translation> + </message> +</context> +<context> + <name>bitcoin-core</name> + <message> + <location filename="../bitcoinstrings.cpp" line="3"/> + <source>Bitcoin version</source> + <translation>Bitcoin</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="4"/> + <source>Usage:</source> + <translation>Gebruik:</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="5"/> + <source>Send command to -server or bitcoind +</source> + <translation>Zend commando naar -server of bitcoind +</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="6"/> + <source>List commands +</source> + <translation>List van commando's +</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="7"/> + <source>Get help for a command +</source> + <translation>Toon hulp voor een commando +</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="8"/> + <source>Options: +</source> + <translation>Opties: +</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="9"/> + <source>Specify configuration file (default: bitcoin.conf) +</source> + <translation>Specifieer configuratiebestand (standaard: bitcoin.conf) +</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="10"/> + <source>Specify pid file (default: bitcoind.pid) +</source> + <translation>Specifieer pid-bestand (standaard: bitcoind.pid) +</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="11"/> + <source>Generate coins +</source> + <translation>Genereer coins +</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="12"/> + <source>Don't generate coins +</source> + <translation>Genereer geen coins +</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="13"/> + <source>Start minimized +</source> + <translation>Geminimaliseerd starten +</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="14"/> + <source>Specify data directory +</source> + <translation>Stel datamap in +</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="15"/> + <source>Specify connection timeout (in milliseconds) +</source> + <translation>Gelieve de time-out tijd te specifieren (in milliseconden) +</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="16"/> + <source>Connect through socks4 proxy +</source> + <translation>Verbind via socks4 proxy +</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="17"/> + <source>Allow DNS lookups for addnode and connect +</source> + <translation>Sta DNS-opzoeking toe voor addnode en connect +</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="18"/> + <source>Add a node to connect to +</source> + <translation>Voeg een node toe om mee te verbinden +</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="19"/> + <source>Connect only to the specified node +</source> + <translation>Verbind alleen met deze node +</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="20"/> + <source>Don't accept connections from outside +</source> + <translation>Sta geen verbindingen van buitenaf toe +</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="21"/> + <source>Don't attempt to use UPnP to map the listening port +</source> + <translation>Probeer geen UPnP te gebruiken om de poort waarop geluisterd wordt te mappen +</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="22"/> + <source>Attempt to use UPnP to map the listening port +</source> + <translation>Probeer UPnP te gebruiken om de poort waarop geluisterd wordt te mappen +</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="23"/> + <source>Fee per KB to add to transactions you send +</source> + <translation>Fooi per KB om aan transacties die gezonden worden toe te voegen +</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="24"/> + <source>Accept command line and JSON-RPC commands +</source> + <translation>Aanvaard commandolijn en JSON-RPC commando's +</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="25"/> + <source>Run in the background as a daemon and accept commands +</source> + <translation>Draai in de achtergrond als daemon en aanvaard commando's +</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="26"/> + <source>Use the test network +</source> + <translation>Gebruik het test-netwerk +</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="27"/> + <source>Username for JSON-RPC connections +</source> + <translation>Gebruikersnaam voor JSON-RPC verbindingen +</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="28"/> + <source>Password for JSON-RPC connections +</source> + <translation>Wachtwoord voor JSON-RPC verbindingen +</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="29"/> + <source>Listen for JSON-RPC connections on <port> (default: 8332) +</source> + <translation>Luister voor JSON-RPC verbindingen op <poort> (standaard: 8332) +</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="30"/> + <source>Allow JSON-RPC connections from specified IP address +</source> + <translation>Enkel JSON-RPC verbindingen van opgegeven IP adres toestaan +</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="31"/> + <source>Send commands to node running on <ip> (default: 127.0.0.1) +</source> + <translation>Zend commando's naar proces dat op <ip> draait (standaard: 127.0.0.1) +</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="32"/> + <source>Set key pool size to <n> (default: 100) +</source> + <translation>Stel sleutelpoelgrootte in op <n> (standaard: 100) +</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="33"/> + <source>Rescan the block chain for missing wallet transactions +</source> + <translation>Doorzoek de blokken database op ontbrekende portefeuille-transacties +</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="34"/> + <source> +SSL options: (see the Bitcoin Wiki for SSL setup instructions) +</source> + <translation> +SSL opties: (zie de Bitcoin wiki voor SSL instructies) +</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="37"/> + <source>Use OpenSSL (https) for JSON-RPC connections +</source> + <translation>Gebruik OpenSSL (https) voor JSON-RPC verbindingen +</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="38"/> + <source>Server certificate file (default: server.cert) +</source> + <translation>Certificaat-bestand voor server (standaard: server.cert) +</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="39"/> + <source>Server private key (default: server.pem) +</source> + <translation>Geheime sleutel voor server (standaard: server.pem) +</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="40"/> + <source>Acceptable ciphers (default: TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!AH:!3DES:@STRENGTH) +</source> + <translation>Aanvaardbare ciphers (standaard: TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!AH:!3DES:@STRENGTH)</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="43"/> + <source>This help message +</source> + <translation>Dit helpbericht +</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="44"/> + <source>Cannot obtain a lock on data directory %s. Bitcoin is probably already running.</source> + <translation>Kan geen lock op de gegevensdirectory %s verkrijgen. Bitcoin draait vermoedelijk reeds.</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="47"/> + <source>Error loading addr.dat +</source> + <translation>Fout bij laden van bestand addr.dat +</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="48"/> + <source>Error loading blkindex.dat +</source> + <translation>Fout bij laden van bestand addr.dat +</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="49"/> + <source>Error loading wallet.dat +</source> + <translation>Fout bij laden van bestand wallet.dat +</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="50"/> + <source>Invalid -proxy address</source> + <translation>Foutief -proxy adres</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="51"/> + <source>Invalid amount for -paytxfee=<amount></source> + <translation>Ongeldig bedrag voor -paytxfee=<bedrag></translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="52"/> + <source>Warning: -paytxfee is set very high. This is the transaction fee you will pay if you send a transaction.</source> + <translation>Waarschuwing: -paytxfee is zeer hoog ingesteld. Dit is de fooi die betaald wordt bij het zenden van een transactie.</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="55"/> + <source>Warning: Disk space is low </source> + <translation>Waarschuwing: Weinig schijfruimte over </translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="56"/> + <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>Fout: Deze transactie vergt een fooi van ten minste %s omwille van zijn bedrag, complexiteit, of gebruik van recent ontvangen coins </translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="59"/> + <source>Error: Transaction creation failed </source> + <translation>Fout: Aanmaken van transactie mislukt </translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="60"/> + <source>Sending...</source> + <translation>Versturen...</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="61"/> + <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>Fout: De transactie is afgekeurd. Dit kan gebeuren als bepaalde coins in je Portefeuille al zijn uitgegeven. Dit kan veroorzaakt worden doordat je een kopie van wallet.dat gebruikt hebt en enkel daar je uitgave geregistreerd is.</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="65"/> + <source>Invalid amount</source> + <translation>Foutieve hoeveelheid</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="66"/> + <source>Insufficient funds</source> + <translation>Onvoldoende saldo</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="67"/> + <source>Invalid bitcoin address</source> + <translation>Foutief bitcoin-adres</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="68"/> + <source>Unable to bind to port %d on this computer. Bitcoin is probably already running.</source> + <translation>Kan niet binden met poort %d op deze computer. Bitcoin draait vermoedelijk reeds.</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="71"/> + <source>To use the %s option</source> + <translation>Om de %s optie te gebruiken</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="72"/> + <source>Warning: %s, you must set rpcpassword=<password> +in the configuration file: %s +If the file does not exist, create it with owner-readable-only file permissions. +</source> + <translation>Waarschuwing: %s, rpcpassword=<password> moet ingesteld zijn +in het configuratie bestand: %s +Als het bestand nog niet bestaat, maak het dan aan met enkel-leesbaar-door-eigenaar rechten. +</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="77"/> + <source>You must set rpcpassword=<password> in the configuration file: +%s +If the file does not exist, create it with owner-readable-only file permissions.</source> + <translation>rpcpassword=<password> moet ingesteld in het configuratie bestand: +%s +Als het bestand nog niet bestaat, maak het dan aan met enkel-leesbaar-door-eigenaar rechten.</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="82"/> + <source>Warning: Please check that your computer's date and time are correct. If your clock is wrong Bitcoin will not work properly.</source> + <translation>Waarschuwing: Controleer of uw computers datum en tijd correct ingesteld zijn. Als uw klok fout staat zal Bitcoin niet correct werken.</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="85"/> + <source>-beta</source> + <translation>-beta</translation> + </message> +</context> +</TS> diff --git a/src/qt/locale/bitcoin_ru.ts b/src/qt/locale/bitcoin_ru.ts new file mode 100644 index 0000000000..6085602f9c --- /dev/null +++ b/src/qt/locale/bitcoin_ru.ts @@ -0,0 +1,2173 @@ +<?xml version="1.0" encoding="utf-8"?> +<!DOCTYPE TS> +<TS version="2.0" language="ru_RU"> +<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><b>Bitcoin</b> version</source> + <translation>Версия Bitcoin'а</translation> + </message> + <message utf8="true"> + <location filename="../forms/aboutdialog.ui" line="85"/> + <source>Copyright © 2009-2011 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-2011 Разработчики сети Bitcoin + +ВНИМАНИЕ: этот софт является экспериментальным! + +Распространяется под лицензией MIT/X11, за дополнительной информацией обращайтесь к прилагающемуся файлу license.txt или документу по данной ссылке: http://www.opensource.org/licenses/mit-license.php. + +Данный продукт включает в себя разработки проекта OpenSSL (http://www.openssl.org/), криптографические функции и алгоритмы, написанные Эриком Янгом (eay@cryptsoft.com) и функции для работы с UPnP за авторством Томаса Бернарда.</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>Здесь перечислены Ваши адреса для получения платежей. Вы можете использовать их для того, чтобы давать разным людям разные адреса и таким образом иметь возможность отслеживать кто и сколько Вам платил, а так же поддерживать бо́льшую анонимность..</translation> + </message> + <message> + <location filename="../forms/addressbookpage.ui" line="33"/> + <source>Double-click to edit address or label</source> + <translation>Для того, чтобы изменить адрес или метку давжды кликните по изменяемому объекту</translation> + </message> + <message> + <location filename="../forms/addressbookpage.ui" line="57"/> + <source>Create a new address</source> + <translation>Создать новый адрес</translation> + </message> + <message> + <location filename="../forms/addressbookpage.ui" line="60"/> + <source>&New Address...</source> + <translation>&Создать адрес...</translation> + </message> + <message> + <location filename="../forms/addressbookpage.ui" line="71"/> + <source>Copy the currently selected address to the system clipboard</source> + <translation>Копировать текущий выделенный адрес в буфер обмена</translation> + </message> + <message> + <location filename="../forms/addressbookpage.ui" line="74"/> + <source>&Copy to Clipboard</source> + <translation>&Kопировать</translation> + </message> + <message> + <location filename="../forms/addressbookpage.ui" line="85"/> + <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="88"/> + <source>&Delete</source> + <translation>&Удалить</translation> + </message> + <message> + <location filename="../addressbookpage.cpp" line="197"/> + <source>Export Address Book Data</source> + <translation>Экспортировать адресную книгу</translation> + </message> + <message> + <location filename="../addressbookpage.cpp" line="199"/> + <source>Comma separated file (*.csv)</source> + <translation>Текст, разделённый запятыми (*.csv)</translation> + </message> + <message> + <location filename="../addressbookpage.cpp" line="212"/> + <source>Error exporting</source> + <translation>Ошибка экспорта</translation> + </message> + <message> + <location filename="../addressbookpage.cpp" line="212"/> + <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>BitcoinGUI</name> + <message> + <location filename="../bitcoingui.cpp" line="53"/> + <source>Bitcoin Wallet</source> + <translation>Bitcoin-бумажник</translation> + </message> + <message> + <location filename="../bitcoingui.cpp" line="61"/> + <source>&File</source> + <translation>&Файл</translation> + </message> + <message> + <location filename="../bitcoingui.cpp" line="67"/> + <source>&Settings</source> + <translation>&Настройки</translation> + </message> + <message> + <location filename="../bitcoingui.cpp" line="70"/> + <source>&Help</source> + <translation>&Помощь</translation> + </message> + <message> + <location filename="../bitcoingui.cpp" line="74"/> + <source>Tabs toolbar</source> + <translation>Панель вкладок</translation> + </message> + <message> + <location filename="../bitcoingui.cpp" line="82"/> + <source>Actions toolbar</source> + <translation>Панель действий</translation> + </message> + <message> + <location filename="../bitcoingui.cpp" line="130"/> + <source>Synchronizing with network...</source> + <translation>Синхронизация с сетью...</translation> + </message> + <message> + <location filename="../bitcoingui.cpp" line="133"/> + <source>Block chain synchronization in progress</source> + <translation>Идёт синхронизация цепочки блоков</translation> + </message> + <message> + <location filename="../bitcoingui.cpp" line="157"/> + <source>&Overview</source> + <translation>О&бзор</translation> + </message> + <message> + <location filename="../bitcoingui.cpp" line="158"/> + <source>Show general overview of wallet</source> + <translation>Показать общий обзор действий с бумажником</translation> + </message> + <message> + <location filename="../bitcoingui.cpp" line="162"/> + <source>&Transactions</source> + <translation>&Транзакции</translation> + </message> + <message> + <location filename="../bitcoingui.cpp" line="163"/> + <source>Browse transaction history</source> + <translation>Показать историю транзакций</translation> + </message> + <message> + <location filename="../bitcoingui.cpp" line="167"/> + <source>&Address Book</source> + <translation>&Адресная книга</translation> + </message> + <message> + <location filename="../bitcoingui.cpp" line="168"/> + <source>Edit the list of stored addresses and labels</source> + <translation>Изменить список сохранённых адресов и меток к ним</translation> + </message> + <message> + <location filename="../bitcoingui.cpp" line="172"/> + <source>&Receive coins</source> + <translation>&Получение</translation> + </message> + <message> + <location filename="../bitcoingui.cpp" line="173"/> + <source>Show the list of addresses for receiving payments</source> + <translation>Показать список адресов для получения платежей</translation> + </message> + <message> + <location filename="../bitcoingui.cpp" line="177"/> + <source>&Send coins</source> + <translation>Отп&равка</translation> + </message> + <message> + <location filename="../bitcoingui.cpp" line="178"/> + <source>Send coins to a bitcoin address</source> + <translation>Отправить монеты на указанный адрес</translation> + </message> + <message> + <location filename="../bitcoingui.cpp" line="188"/> + <source>&Exit</source> + <translation>Вы&ход</translation> + </message> + <message> + <location filename="../bitcoingui.cpp" line="189"/> + <source>Quit application</source> + <translation>Закрыть приложение</translation> + </message> + <message> + <location filename="../bitcoingui.cpp" line="190"/> + <source>&About</source> + <translation>&Информация</translation> + </message> + <message> + <location filename="../bitcoingui.cpp" line="191"/> + <source>Show information about Bitcoin</source> + <translation>Показать информацию о Bitcoin'е</translation> + </message> + <message> + <location filename="../bitcoingui.cpp" line="192"/> + <source>&Options...</source> + <translation>Оп&ции...</translation> + </message> + <message> + <location filename="../bitcoingui.cpp" line="193"/> + <source>Modify configuration options for bitcoin</source> + <translation>Изменить настройки</translation> + </message> + <message> + <location filename="../bitcoingui.cpp" line="194"/> + <source>Open &Bitcoin</source> + <translation>&Показать бумажник</translation> + </message> + <message> + <location filename="../bitcoingui.cpp" line="195"/> + <source>Show the Bitcoin window</source> + <translation>Показать окно бумажника</translation> + </message> + <message> + <location filename="../bitcoingui.cpp" line="196"/> + <source>&Export...</source> + <translation>&Экспорт...</translation> + </message> + <message> + <location filename="../bitcoingui.cpp" line="197"/> + <source>Export the current view to a file</source> + <translation>Экспортировать в файл</translation> + </message> + <message> + <location filename="../bitcoingui.cpp" line="211"/> + <source>[testnet]</source> + <translation>[тестовая сеть]</translation> + </message> + <message numerus="yes"> + <location filename="../bitcoingui.cpp" line="304"/> + <source>%n active connection(s) to Bitcoin network</source> + <translation> + <numerusform>%n активное соединение с сетью</numerusform> + <numerusform>%n активных соединений с сетью</numerusform> + <numerusform>%n активных соединений с сетью</numerusform> + </translation> + </message> + <message> + <location filename="../bitcoingui.cpp" line="318"/> + <source>Downloaded %1 of %2 blocks of transaction history.</source> + <translation>Загружено %1 из %2 блоков истории транзакций.</translation> + </message> + <message> + <location filename="../bitcoingui.cpp" line="324"/> + <source>Downloaded %1 blocks of transaction history.</source> + <translation>Загружено %1 блоков истории транзакций.</translation> + </message> + <message numerus="yes"> + <location filename="../bitcoingui.cpp" line="335"/> + <source>%n second(s) ago</source> + <translation> + <numerusform>%n секунду назад</numerusform> + <numerusform>%n секунды назад</numerusform> + <numerusform>%n секунд назад</numerusform> + </translation> + </message> + <message numerus="yes"> + <location filename="../bitcoingui.cpp" line="339"/> + <source>%n minute(s) ago</source> + <translation> + <numerusform>%n минуту назад</numerusform> + <numerusform>%n минуты назад</numerusform> + <numerusform>%n минут назад</numerusform> + </translation> + </message> + <message numerus="yes"> + <location filename="../bitcoingui.cpp" line="343"/> + <source>%n hour(s) ago</source> + <translation> + <numerusform>%n час назад</numerusform> + <numerusform>%n часа назад</numerusform> + <numerusform>%n часов назад</numerusform> + </translation> + </message> + <message numerus="yes"> + <location filename="../bitcoingui.cpp" line="347"/> + <source>%n day(s) ago</source> + <translation> + <numerusform>%n день назад</numerusform> + <numerusform>%n дня назад</numerusform> + <numerusform>%n дней назад</numerusform> + </translation> + </message> + <message> + <location filename="../bitcoingui.cpp" line="353"/> + <source>Up to date</source> + <translation>Синхронизированно</translation> + </message> + <message> + <location filename="../bitcoingui.cpp" line="358"/> + <source>Catching up...</source> + <translation>Синхронизируется...</translation> + </message> + <message> + <location filename="../bitcoingui.cpp" line="364"/> + <source>Last received block was generated %1.</source> + <translation>Последний полученный блок был сгенерирован %1.</translation> + </message> + <message> + <location filename="../bitcoingui.cpp" line="421"/> + <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="426"/> + <source>Sending...</source> + <translation>Отправка...</translation> + </message> + <message> + <location filename="../bitcoingui.cpp" line="449"/> + <source>Sent transaction</source> + <translation>Исходящая транзакция</translation> + </message> + <message> + <location filename="../bitcoingui.cpp" line="450"/> + <source>Incoming transaction</source> + <translation>Входящая транзакция</translation> + </message> + <message> + <location filename="../bitcoingui.cpp" line="451"/> + <source>Date: </source> + <translation>Дата: </translation> + </message> + <message> + <location filename="../bitcoingui.cpp" line="452"/> + <source>Amount: </source> + <translation>Количество: </translation> + </message> + <message> + <location filename="../bitcoingui.cpp" line="453"/> + <source>Type: </source> + <translation>Тип: </translation> + </message> + <message> + <location filename="../bitcoingui.cpp" line="454"/> + <source>Address: </source> + <translation>Адрес: </translation> + </message> +</context> +<context> + <name>DisplayOptionsPage</name> + <message> + <location filename="../optionsdialog.cpp" line="254"/> + <source>&Unit to show amounts in: </source> + <translation>&Измерять монеты в: </translation> + </message> + <message> + <location filename="../optionsdialog.cpp" line="258"/> + <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="265"/> + <source>Display addresses in transaction list</source> + <translation>Показывать адреса в списке транзакций</translation> + </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>&Label</source> + <translation>&Метка</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>&Address</source> + <translation>&Адрес</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="87"/> + <source>The entered address "%1" is already in the address book.</source> + <translation>Введённый адрес «%1» уже находится в адресной книге.</translation> + </message> + <message> + <location filename="../editaddressdialog.cpp" line="92"/> + <source>The entered address "%1" is not a valid bitcoin address.</source> + <translation>Введённый адрес «%1» не является правильным Bitcoin-адресом.</translation> + </message> +</context> +<context> + <name>MainOptionsPage</name> + <message> + <location filename="../optionsdialog.cpp" line="162"/> + <source>&Start Bitcoin on window system startup</source> + <translation>&Запускать бумажник при входе в систему</translation> + </message> + <message> + <location filename="../optionsdialog.cpp" line="163"/> + <source>Automatically start Bitcoin after the computer is turned on</source> + <translation>Автоматически запускать бумажник, когда включается компьютер</translation> + </message> + <message> + <location filename="../optionsdialog.cpp" line="166"/> + <source>&Minimize to the tray instead of the taskbar</source> + <translation>&Cворачивать в системный лоток вместо панели задач</translation> + </message> + <message> + <location filename="../optionsdialog.cpp" line="167"/> + <source>Show only a tray icon after minimizing the window</source> + <translation>Показывать только иконку в системном лотке при сворачивании окна</translation> + </message> + <message> + <location filename="../optionsdialog.cpp" line="170"/> + <source>Map port using &UPnP</source> + <translation>Пробросить порт через &UPnP</translation> + </message> + <message> + <location filename="../optionsdialog.cpp" line="171"/> + <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="174"/> + <source>M&inimize on close</source> + <translation>С&ворачивать вместо закрытия</translation> + </message> + <message> + <location filename="../optionsdialog.cpp" line="175"/> + <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="178"/> + <source>&Connect through SOCKS4 proxy:</source> + <translation>&Подключаться через SOCKS4 прокси:</translation> + </message> + <message> + <location filename="../optionsdialog.cpp" line="179"/> + <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="184"/> + <source>Proxy &IP: </source> + <translation>&IP Прокси: </translation> + </message> + <message> + <location filename="../optionsdialog.cpp" line="190"/> + <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="193"/> + <source>&Port: </source> + <translation>По&рт: </translation> + </message> + <message> + <location filename="../optionsdialog.cpp" line="199"/> + <source>Port of the proxy (e.g. 1234)</source> + <translation>Порт прокси-сервера (например 1234)</translation> + </message> + <message> + <location filename="../optionsdialog.cpp" line="205"/> + <source>Optional transaction fee per KB that helps make sure your transactions are processed quickly. Most transactions are 1KB. Fee 0.01 recommended.</source> + <translation>Опциональная комиссия за кадый KB транзакции, которое позволяет быть уверенным, что Ваша транзакция будет обработана быстро. Большинство транщакций занимают 1 KB. Рекомендованная комиссия: 0.01 BTC.</translation> + </message> + <message> + <location filename="../optionsdialog.cpp" line="211"/> + <source>Pay transaction &fee</source> + <translation>Добавлять ко&миссию</translation> + </message> + <message> + <location filename="../optionsdialog.cpp" line="214"/> + <source>Optional transaction fee per KB that helps make sure your transactions are processed quickly. Most transactions are 1KB. Fee 0.01 recommended.</source> + <translation>Опциональная комиссия за кадый KB транзакции, которая позволяет быть уверенным, что Ваша транзакция будет обработана быстро. Большинство транзакций занимают 1 KB. Рекомендованная комиссия: 0.01 BTC.</translation> + </message> +</context> +<context> + <name>OptionsDialog</name> + <message> + <location filename="../optionsdialog.cpp" line="71"/> + <source>Main</source> + <translation>Основное</translation> + </message> + <message> + <location filename="../optionsdialog.cpp" line="76"/> + <source>Display</source> + <translation>Отображение</translation> + </message> + <message> + <location filename="../optionsdialog.cpp" line="96"/> + <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="82"/> + <source><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Ubuntu'; font-size:11pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600;">Wallet</span></p></body></html></source> + <translation><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Ubuntu'; font-size:11pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600;">Бумажник</span></p></body></html></translation> + </message> + <message> + <location filename="../forms/overviewpage.ui" line="122"/> + <source><b>Recent transactions</b></source> + <translation><b>Последние транзакции</b></translation> + </message> + <message> + <location filename="../overviewpage.cpp" line="102"/> + <source>Your current balance</source> + <translation>Ваш текущий баланс</translation> + </message> + <message> + <location filename="../overviewpage.cpp" line="107"/> + <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="110"/> + <source>Total number of transactions in wallet</source> + <translation>Общая количество транзакций в Вашем бумажнике</translation> + </message> +</context> +<context> + <name>SendCoinsDialog</name> + <message> + <location filename="../forms/sendcoinsdialog.ui" line="14"/> + <location filename="../sendcoinsdialog.cpp" line="91"/> + <location filename="../sendcoinsdialog.cpp" line="96"/> + <location filename="../sendcoinsdialog.cpp" line="101"/> + <location filename="../sendcoinsdialog.cpp" line="106"/> + <location filename="../sendcoinsdialog.cpp" line="112"/> + <location filename="../sendcoinsdialog.cpp" line="117"/> + <location filename="../sendcoinsdialog.cpp" line="123"/> + <source>Send Coins</source> + <translation>Отправка</translation> + </message> + <message> + <location filename="../forms/sendcoinsdialog.ui" line="67"/> + <source>Send to multiple recipients at once</source> + <translation>Отправить нескольким получателям одновременно</translation> + </message> + <message> + <location filename="../forms/sendcoinsdialog.ui" line="70"/> + <source>&Add recipient...</source> + <translation>&Добавить получателя...</translation> + </message> + <message> + <location filename="../forms/sendcoinsdialog.ui" line="100"/> + <source>Confirm the send action</source> + <translation>Подтвердить отправку</translation> + </message> + <message> + <location filename="../forms/sendcoinsdialog.ui" line="103"/> + <source>&Send</source> + <translation>&Отправить</translation> + </message> + <message> + <location filename="../sendcoinsdialog.cpp" line="74"/> + <source><b>%1</b> to %2 (%3)</source> + <translation><b>%1</b> адресату %2 (%3)</translation> + </message> + <message> + <location filename="../sendcoinsdialog.cpp" line="77"/> + <source>Confirm send coins</source> + <translation>Подтвердите отправку монет</translation> + </message> + <message> + <location filename="../sendcoinsdialog.cpp" line="78"/> + <source>Are you sure you want to send %1?</source> + <translation>Вы уверены, что хотите отправить %1?</translation> + </message> + <message> + <location filename="../sendcoinsdialog.cpp" line="78"/> + <source> and </source> + <translation> и </translation> + </message> + <message> + <location filename="../sendcoinsdialog.cpp" line="92"/> + <source>The recepient address is not valid, please recheck.</source> + <translation>Адрес получателя неверный, пожалуйста, перепроверьте.</translation> + </message> + <message> + <location filename="../sendcoinsdialog.cpp" line="97"/> + <source>The amount to pay must be larger than 0.</source> + <translation>Количество монет для отправки должно быть больше 0.</translation> + </message> + <message> + <location filename="../sendcoinsdialog.cpp" line="102"/> + <source>Amount exceeds your balance</source> + <translation>Количество отправляемых монет превышает Ваш баланс</translation> + </message> + <message> + <location filename="../sendcoinsdialog.cpp" line="107"/> + <source>Total exceeds your balance when the %1 transaction fee is included</source> + <translation>Сумма превысит Ваш баланс, если комиссия в %1 будет добавлена к транзакции</translation> + </message> + <message> + <location filename="../sendcoinsdialog.cpp" line="113"/> + <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="118"/> + <source>Error: Transaction creation failed </source> + <translation>Ошибка: Создание транзакции не удалось </translation> + </message> + <message> + <location filename="../sendcoinsdialog.cpp" line="124"/> + <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&mount:</source> + <translation>Ко&личество:</translation> + </message> + <message> + <location filename="../forms/sendcoinsentry.ui" line="42"/> + <source>Pay &To:</source> + <translation>Полу&чатель:</translation> + </message> + <message> + <location filename="../forms/sendcoinsentry.ui" line="66"/> + <location filename="../sendcoinsentry.cpp" line="22"/> + <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>&Label:</source> + <translation>&Метка:</translation> + </message> + <message> + <location filename="../forms/sendcoinsentry.ui" line="93"/> + <source>The address to send the payment to (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L)</source> + <translation>Адрес получателя платежа (например 1LA5FtQhnnWnkK6zjFfutR7Stiit4wKd63)</translation> + </message> + <message> + <location filename="../forms/sendcoinsentry.ui" line="103"/> + <source>Choose adress from address book</source> + <translation>Выбрать адрес из адресной книги</translation> + </message> + <message> + <location filename="../forms/sendcoinsentry.ui" line="113"/> + <source>Alt+A</source> + <translation></translation> + </message> + <message> + <location filename="../forms/sendcoinsentry.ui" line="126"/> + <source>Paste address from clipboard</source> + <translation>Вставить адрес из буфера обмена</translation> + </message> + <message> + <location filename="../forms/sendcoinsentry.ui" line="136"/> + <source>Alt+P</source> + <translation></translation> + </message> + <message> + <location filename="../forms/sendcoinsentry.ui" line="146"/> + <source>Remove this recipient</source> + <translation>Удалить этого получателя</translation> + </message> + <message> + <location filename="../sendcoinsentry.cpp" line="21"/> + <source>Enter a Bitcoin address (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L)</source> + <translation>Введите Bitcoin-адрес (например 1LA5FtQhnnWnkK6zjFfutR7Stiit4wKd63)</translation> + </message> +</context> +<context> + <name>TransactionDesc</name> + <message> + <location filename="../transactiondesc.cpp" line="34"/> + <source>Open for %1 blocks</source> + <translation type="unfinished">Открыто до получения %1 блоков</translation> + </message> + <message> + <location filename="../transactiondesc.cpp" line="36"/> + <source>Open until %1</source> + <translation type="unfinished">Открыто до %1</translation> + </message> + <message> + <location filename="../transactiondesc.cpp" line="42"/> + <source>%1/offline?</source> + <translation>%1/оффлайн?</translation> + </message> + <message> + <location filename="../transactiondesc.cpp" line="44"/> + <source>%1/unconfirmed</source> + <translation>%1/не подтверждено</translation> + </message> + <message> + <location filename="../transactiondesc.cpp" line="46"/> + <source>%1 confirmations</source> + <translation>%1 подтверждений</translation> + </message> + <message> + <location filename="../transactiondesc.cpp" line="63"/> + <source><b>Status:</b> </source> + <translation><b>Статус:</b> </translation> + </message> + <message> + <location filename="../transactiondesc.cpp" line="68"/> + <source>, has not been successfully broadcast yet</source> + <translation>, ещё не было успешно разослано</translation> + </message> + <message> + <location filename="../transactiondesc.cpp" line="70"/> + <source>, broadcast through %1 node</source> + <translation>, разослано через %1 узел</translation> + </message> + <message> + <location filename="../transactiondesc.cpp" line="72"/> + <source>, broadcast through %1 nodes</source> + <translation>, разослано через %1 узлов</translation> + </message> + <message> + <location filename="../transactiondesc.cpp" line="76"/> + <source><b>Date:</b> </source> + <translation><b>Дата:</b> </translation> + </message> + <message> + <location filename="../transactiondesc.cpp" line="83"/> + <source><b>Source:</b> Generated<br></source> + <translation><b>Источник:</b> [сгенерированно]<br></translation> + </message> + <message> + <location filename="../transactiondesc.cpp" line="89"/> + <location filename="../transactiondesc.cpp" line="106"/> + <source><b>From:</b> </source> + <translation><b>Отправитель:</b> </translation> + </message> + <message> + <location filename="../transactiondesc.cpp" line="106"/> + <source>unknown</source> + <translation>неизвестно</translation> + </message> + <message> + <location filename="../transactiondesc.cpp" line="107"/> + <location filename="../transactiondesc.cpp" line="130"/> + <location filename="../transactiondesc.cpp" line="189"/> + <source><b>To:</b> </source> + <translation><b>Получатель:</b> </translation> + </message> + <message> + <location filename="../transactiondesc.cpp" line="110"/> + <source> (yours, label: </source> + <translation> (Ваш, метка:</translation> + </message> + <message> + <location filename="../transactiondesc.cpp" line="112"/> + <source> (yours)</source> + <translation> (ваш)</translation> + </message> + <message> + <location filename="../transactiondesc.cpp" line="147"/> + <location filename="../transactiondesc.cpp" line="161"/> + <location filename="../transactiondesc.cpp" line="206"/> + <location filename="../transactiondesc.cpp" line="223"/> + <source><b>Credit:</b> </source> + <translation><b>Кредит:</b> </translation> + </message> + <message> + <location filename="../transactiondesc.cpp" line="149"/> + <source>(%1 matures in %2 more blocks)</source> + <translation type="unfinished">(%1 «созреет» через %2 блоков)</translation> + </message> + <message> + <location filename="../transactiondesc.cpp" line="153"/> + <source>(not accepted)</source> + <translation>(не принято)</translation> + </message> + <message> + <location filename="../transactiondesc.cpp" line="197"/> + <location filename="../transactiondesc.cpp" line="205"/> + <location filename="../transactiondesc.cpp" line="220"/> + <source><b>Debit:</b> </source> + <translation><b>Дебет:</b> </translation> + </message> + <message> + <location filename="../transactiondesc.cpp" line="211"/> + <source><b>Transaction fee:</b> </source> + <translation><b>Комиссия:</b> </translation> + </message> + <message> + <location filename="../transactiondesc.cpp" line="227"/> + <source><b>Net amount:</b> </source> + <translation><b>Общая сумма:</b> </translation> + </message> + <message> + <location filename="../transactiondesc.cpp" line="233"/> + <source>Message:</source> + <translation>Сообщение:</translation> + </message> + <message> + <location filename="../transactiondesc.cpp" line="235"/> + <source>Comment:</source> + <translation>Комментарий:</translation> + </message> + <message> + <location filename="../transactiondesc.cpp" line="238"/> + <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 "not accepted" and not be spendable. This may occasionally happen if another node generates a block within a few seconds of yours.</source> + <translation></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="213"/> + <source>Date</source> + <translation>Дата</translation> + </message> + <message> + <location filename="../transactiontablemodel.cpp" line="213"/> + <source>Type</source> + <translation>Тип</translation> + </message> + <message> + <location filename="../transactiontablemodel.cpp" line="213"/> + <source>Address</source> + <translation>Адрес</translation> + </message> + <message> + <location filename="../transactiontablemodel.cpp" line="213"/> + <source>Amount</source> + <translation>Количество</translation> + </message> + <message numerus="yes"> + <location filename="../transactiontablemodel.cpp" line="274"/> + <source>Open for %n block(s)</source> + <translation type="unfinished"> + <numerusform>Открыто до получения %n блока</numerusform> + <numerusform>Открыто до получения %n блоков</numerusform> + <numerusform>Открыто до получения %n блоков</numerusform> + </translation> + </message> + <message> + <location filename="../transactiontablemodel.cpp" line="277"/> + <source>Open until %1</source> + <translation type="unfinished">Открыто до %1</translation> + </message> + <message> + <location filename="../transactiontablemodel.cpp" line="280"/> + <source>Offline (%1 confirmations)</source> + <translation>Оффлайн (%1 подтверждений)</translation> + </message> + <message> + <location filename="../transactiontablemodel.cpp" line="283"/> + <source>Unconfirmed (%1 of %2 confirmations)</source> + <translation>Не подтверждено (%1 из %2 подтверждений)</translation> + </message> + <message> + <location filename="../transactiontablemodel.cpp" line="286"/> + <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> + <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 IP</source> + <translation>Получено с IP-адреса </translation> + </message> + <message> + <location filename="../transactiontablemodel.cpp" line="351"/> + <source>Sent to</source> + <translation>Отправлено</translation> + </message> + <message> + <location filename="../transactiontablemodel.cpp" line="353"/> + <source>Sent to IP</source> + <translation>Отправлено на IP-адрес </translation> + </message> + <message> + <location filename="../transactiontablemodel.cpp" line="355"/> + <source>Payment to yourself</source> + <translation>Отправлено себе</translation> + </message> + <message> + <location filename="../transactiontablemodel.cpp" line="357"/> + <source>Mined</source> + <translation>Добыто</translation> + </message> + <message> + <location filename="../transactiontablemodel.cpp" line="395"/> + <source>(n/a)</source> + <translation>[не доступно]</translation> + </message> + <message> + <location filename="../transactiontablemodel.cpp" line="594"/> + <source>Transaction status. Hover over this field to show number of confirmations.</source> + <translation>Статус транзакции. Подведите курсор к нужному полю для того, чтобы увидеть количество подтверждений.</translation> + </message> + <message> + <location filename="../transactiontablemodel.cpp" line="596"/> + <source>Date and time that the transaction was received.</source> + <translation>Дата и время, когда транзакция была получена.</translation> + </message> + <message> + <location filename="../transactiontablemodel.cpp" line="598"/> + <source>Type of transaction.</source> + <translation>Тип транзакции.</translation> + </message> + <message> + <location filename="../transactiontablemodel.cpp" line="600"/> + <source>Destination address of transaction.</source> + <translation>Адрес назначения транзакции.</translation> + </message> + <message> + <location filename="../transactiontablemodel.cpp" line="602"/> + <source>Amount removed from or added to balance.</source> + <translation>Сумма, добавленная, или снятая с баланса.</translation> + </message> +</context> +<context> + <name>TransactionView</name> + <message> + <location filename="../transactionview.cpp" line="48"/> + <location filename="../transactionview.cpp" line="61"/> + <source>All</source> + <translation>Все</translation> + </message> + <message> + <location filename="../transactionview.cpp" line="49"/> + <source>Today</source> + <translation>Сегодня</translation> + </message> + <message> + <location filename="../transactionview.cpp" line="50"/> + <source>This week</source> + <translation>На этой неделе</translation> + </message> + <message> + <location filename="../transactionview.cpp" line="51"/> + <source>This month</source> + <translation>В этом месяце</translation> + </message> + <message> + <location filename="../transactionview.cpp" line="52"/> + <source>Last month</source> + <translation>За последний месяц</translation> + </message> + <message> + <location filename="../transactionview.cpp" line="53"/> + <source>This year</source> + <translation>В этом году</translation> + </message> + <message> + <location filename="../transactionview.cpp" line="54"/> + <source>Range...</source> + <translation>Промежуток...</translation> + </message> + <message> + <location filename="../transactionview.cpp" line="62"/> + <source>Received with</source> + <translation>Получено на</translation> + </message> + <message> + <location filename="../transactionview.cpp" line="64"/> + <source>Sent to</source> + <translation>Отправлено на</translation> + </message> + <message> + <location filename="../transactionview.cpp" line="66"/> + <source>To yourself</source> + <translation>Отправленные себе</translation> + </message> + <message> + <location filename="../transactionview.cpp" line="67"/> + <source>Mined</source> + <translation>Добытые</translation> + </message> + <message> + <location filename="../transactionview.cpp" line="68"/> + <source>Other</source> + <translation>Другое</translation> + </message> + <message> + <location filename="../transactionview.cpp" line="74"/> + <source>Enter address or label to search</source> + <translation>Введите адрес или метку для поиска</translation> + </message> + <message> + <location filename="../transactionview.cpp" line="80"/> + <source>Min amount</source> + <translation>Мин. сумма</translation> + </message> + <message> + <location filename="../transactionview.cpp" line="108"/> + <source>Copy address</source> + <translation>Копировать адрес</translation> + </message> + <message> + <location filename="../transactionview.cpp" line="109"/> + <source>Copy label</source> + <translation>Копировать метку</translation> + </message> + <message> + <location filename="../transactionview.cpp" line="110"/> + <source>Edit label</source> + <translation>Изменить метку</translation> + </message> + <message> + <location filename="../transactionview.cpp" line="111"/> + <source>Show details...</source> + <translation>Показать детали...</translation> + </message> + <message> + <location filename="../transactionview.cpp" line="244"/> + <source>Export Transaction Data</source> + <translation>Экспортировать данные транзакций</translation> + </message> + <message> + <location filename="../transactionview.cpp" line="246"/> + <source>Comma separated file (*.csv)</source> + <translation>Текс, разделённый запятыми (*.csv)</translation> + </message> + <message> + <location filename="../transactionview.cpp" line="254"/> + <source>Confirmed</source> + <translation>Подтверждено</translation> + </message> + <message> + <location filename="../transactionview.cpp" line="255"/> + <source>Date</source> + <translation>Дата</translation> + </message> + <message> + <location filename="../transactionview.cpp" line="256"/> + <source>Type</source> + <translation>Тип</translation> + </message> + <message> + <location filename="../transactionview.cpp" line="257"/> + <source>Label</source> + <translation>Метка</translation> + </message> + <message> + <location filename="../transactionview.cpp" line="258"/> + <source>Address</source> + <translation>Адрес</translation> + </message> + <message> + <location filename="../transactionview.cpp" line="259"/> + <source>Amount</source> + <translation>Количество</translation> + </message> + <message> + <location filename="../transactionview.cpp" line="260"/> + <source>ID</source> + <translation></translation> + </message> + <message> + <location filename="../transactionview.cpp" line="264"/> + <source>Error exporting</source> + <translation>Ошибка экспорта</translation> + </message> + <message> + <location filename="../transactionview.cpp" line="264"/> + <source>Could not write to file %1.</source> + <translation>Невозможно записать в файл %1.</translation> + </message> + <message> + <location filename="../transactionview.cpp" line="352"/> + <source>Range:</source> + <translation>Промежуток от:</translation> + </message> + <message> + <location filename="../transactionview.cpp" line="360"/> + <source>to</source> + <translation>до</translation> + </message> +</context> +<context> + <name>WalletModel</name> + <message> + <location filename="../walletmodel.cpp" line="139"/> + <source>Sending...</source> + <translation>Отправка....</translation> + </message> +</context> +<context> + <name>bitcoin-core</name> + <message> + <location filename="../bitcoinstrings.cpp" line="3"/> + <source>Bitcoin version</source> + <translation>Версия</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="4"/> + <source>Usage:</source> + <translation>Использование:</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="5"/> + <source>Send command to -server or bitcoind +</source> + <translation>Отправить команду на сервер ( -server ) или демону +</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="6"/> + <source>List commands +</source> + <translation>Список команд +</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="7"/> + <source>Get help for a command +</source> + <translation>Получить помощь по команде</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="8"/> + <source>Options: +</source> + <translation>Опции: +</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="9"/> + <source>Specify configuration file (default: bitcoin.conf) +</source> + <translation>Указать конфигурационный файл вместо используемого по умолчанию (bitcoin.conf) +</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="10"/> + <source>Specify pid file (default: bitcoind.pid) +</source> + <translation>Указать pid-файл вместо используемого по умолчанию (bitcoin.pid) +</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="11"/> + <source>Generate coins +</source> + <translation>Включить добычу монет +</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="12"/> + <source>Don't generate coins +</source> + <translation>Выключить добычу монет +</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="13"/> + <source>Start minimized +</source> + <translation>Запускать минимизированным +</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="14"/> + <source>Specify data directory +</source> + <translation>Указать рабочую директорию +</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="15"/> + <source>Specify connection timeout (in milliseconds) +</source> + <translation>Указать таймаут соединения (в миллисекундах) +</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="16"/> + <source>Connect through socks4 proxy +</source> + <translation>Соединяться через socks4-прокси +</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="17"/> + <source>Allow DNS lookups for addnode and connect +</source> + <translation>Разрешить поиск в DNS для комманд "addnode" и "connect" +</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="18"/> + <source>Add a node to connect to +</source> + <translation>Добавить узел для соединения +</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="19"/> + <source>Connect only to the specified node +</source> + <translation>Соединяться только с указанным узлом +</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="20"/> + <source>Don't accept connections from outside +</source> + <translation>Не принимать внешние соединения +</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="21"/> + <source>Don't attempt to use UPnP to map the listening port +</source> + <translation>Не пытаться использовать UPnP +</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="22"/> + <source>Attempt to use UPnP to map the listening port +</source> + <translation>Попытаться использовать UPnP для проброса прослушиваемого порта на роутере +</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="23"/> + <source>Fee per KB to add to transactions you send +</source> + <translation>Комиссия (за каждый KB транзакции) +</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="24"/> + <source>Accept command line and JSON-RPC commands +</source> + <translation>Принимать команды из командной строки и через JSON-RPC +</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="25"/> + <source>Run in the background as a daemon and accept commands +</source> + <translation>Запустить в бекграунде (как демон) и принимать команды +</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="26"/> + <source>Use the test network +</source> + <translation>Использовать тестовую сеть +</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="27"/> + <source>Username for JSON-RPC connections +</source> + <translation>Имя пользователя для JSON-RPC соединений +</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="28"/> + <source>Password for JSON-RPC connections +</source> + <translation>Пароль для JSON-RPC соединений +</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="29"/> + <source>Listen for JSON-RPC connections on <port> (default: 8332) +</source> + <translation>Слушать <порт> для JSON-RPC соединений (по умолчанию: 8332) +</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="30"/> + <source>Allow JSON-RPC connections from specified IP address +</source> + <translation>Разрешить JSON-RPC соединения с указанного адреса +</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="31"/> + <source>Send commands to node running on <ip> (default: 127.0.0.1) +</source> + <translation>Отправлять команды на узел,запущенный на <IP> (по умолчанию: 127.0.0.1) +</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="32"/> + <source>Set key pool size to <n> (default: 100) +</source> + <translation>Установить размер key pool'а в <n> (по умолчанию: 100) +</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="33"/> + <source>Rescan the block chain for missing wallet transactions +</source> + <translation>Просканировать цепочку блоков в поисках пропущенных транзакций для бумажника +</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="34"/> + <source> +SSL options: (see the Bitcoin Wiki for SSL setup instructions) +</source> + <translation>Опции SSL: (см. Bitcoin Wiki для инструкций) +</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="37"/> + <source>Use OpenSSL (https) for JSON-RPC connections +</source> + <translation>Использовать OpenSSL (https) для JSON-RPC соединений +</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="38"/> + <source>Server certificate file (default: server.cert) +</source> + <translation>Сертификат (публичный ключ) сервера (по умолчанию: server.cert) +</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="39"/> + <source>Server private key (default: server.pem) +</source> + <translation>Закрытый ключ сервера (по умолчанию: server.pem) +</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="40"/> + <source>Acceptable ciphers (default: TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!AH:!3DES:@STRENGTH) +</source> + <translation>Допустимые Cipher'ы для сервера (по умолчанию: TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!AH:!3DES:@STRENGTH) +</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="43"/> + <source>This help message +</source> + <translation>Данная справка +</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="44"/> + <source>Cannot obtain a lock on data directory %s. Bitcoin is probably already running.</source> + <translation>Невозможно установить блокировку на рабочую директорию %s. Возможно, бумажник уже запущен.</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="47"/> + <source>Loading addresses...</source> + <translation>Загрузка адресов...</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="48"/> + <source>Error loading addr.dat +</source> + <translation>Ошибка при загрузке addr.dat +</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="49"/> + <source>Loading block index...</source> + <translation>Загрузка индекса блоков...</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="50"/> + <source>Error loading blkindex.dat +</source> + <translation>Ошибка при загрузке blkindex.dat +</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="51"/> + <source>Loading wallet...</source> + <translation>Загрузка бумажника...</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="52"/> + <source>Error loading wallet.dat: Wallet corrupted +</source> + <translation>Ошибка загрузки wallet.dat: Бумажник повреждён</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="53"/> + <source>Error loading wallet.dat: Wallet requires newer version of Bitcoin +</source> + <translation>Ошибка загрузки wallet.dat: Для данного бумажника требуется более новая версия Bitcoin +</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="55"/> + <source>Error loading wallet.dat +</source> + <translation>Ошибка при загрузке wallet.dat +</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="56"/> + <source>Rescanning...</source> + <translation>Сканирование...</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="57"/> + <source>Done loading</source> + <translation>Загрузка завершена</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="58"/> + <source>Invalid -proxy address</source> + <translation>Ошибка в адресе прокси</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="59"/> + <source>Invalid amount for -paytxfee=<amount></source> + <translation>Ошибка в сумме комиссии</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="60"/> + <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="63"/> + <source>Error: CreateThread(StartNode) failed</source> + <translation>Ошибка: Созданиние потока (запуск узла) не удался</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="64"/> + <source>Warning: Disk space is low </source> + <translation>ВНИМАНИЕ: На диске заканчивается свободное пространство </translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="68"/> + <source>This transaction is over the size limit. You can still send it for a fee of %s, which goes to the nodes that process your transaction and helps to support the network. Do you want to pay the fee?</source> + <translation>Данная транзакция превышает предельно допустимый размер. Но Вы можете всё равно совершить ей, добавив комиссию в %s, которая отправится тем узлам, которые обработают Вашу транзакцию и поможет поддержать сеть. Вы хотите добавить комиссию?</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="72"/> + <source>Enter the current passphrase to the wallet.</source> + <translation>Введите текущий пароль от бумажника.</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="73"/> + <source>Passphrase</source> + <translation>Пароль</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="74"/> + <source>Please supply the current wallet decryption passphrase.</source> + <translation>Пожалуйста, укажите текущий пароль для расшифровки бумажника.</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="75"/> + <source>The passphrase entered for the wallet decryption was incorrect.</source> + <translation>Указанный пароль не подходит.</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="76"/> + <source>Status</source> + <translation>Статус</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="77"/> + <source>Date</source> + <translation>Дата</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="78"/> + <source>Description</source> + <translation>Описание</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="79"/> + <source>Debit</source> + <translation>Дебет</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="80"/> + <source>Credit</source> + <translation>Кредит</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="81"/> + <source>Open for %d blocks</source> + <translation>Открыто до получения %d блоков</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="82"/> + <source>Open until %s</source> + <translation>Открыто до %s</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="83"/> + <source>%d/offline?</source> + <translation>%d/оффлайн?</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="84"/> + <source>%d/unconfirmed</source> + <translation>%d/не подтверждено</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="85"/> + <source>%d confirmations</source> + <translation>%d подтверждений</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="86"/> + <source>Generated</source> + <translation>Сгенерированно</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="87"/> + <source>Generated (%s matures in %d more blocks)</source> + <translation>Сгенерированно (%s «созреет» через %d блоков)</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="88"/> + <source>Generated - Warning: This block was not received by any other nodes and will probably not be accepted!</source> + <translation>Сгенерированно - ВНИМАНИЕ: Данный блок не был получен ни одним другим узлом и, возможно, не будет подтверждён!</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="91"/> + <source>Generated (not accepted)</source> + <translation>Сгенерированно (не подтверждено)</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="92"/> + <source>From: </source> + <translation>Отправитель: </translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="93"/> + <source>Received with: </source> + <translation>Получатель: </translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="94"/> + <source>Payment to yourself</source> + <translation>Отправлено себе</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="95"/> + <source>To: </source> + <translation>Получатель: </translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="96"/> + <source> Generating</source> + <translation> Генерация</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="97"/> + <source>(not connected)</source> + <translation>(не подключено)</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="98"/> + <source> %d connections %d blocks %d transactions</source> + <translation> %d подключений %d блоков %d транзакций</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="99"/> + <source>Wallet already encrypted.</source> + <translation>Бумажник уже зашифрован.</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="100"/> + <source>Enter the new passphrase to the wallet. +Please use a passphrase of 10 or more random characters, or eight or more words.</source> + <translation>Введите новый пароль для бумажника. +Пожалуйста, используейте пароль из 10 и более случайных символов или из 8 и более слов.</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="104"/> + <source>Error: The supplied passphrase was too short.</source> + <translation>ОШИБКА: Указанный пароль слишком короткий.</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="105"/> + <source>WARNING: If you encrypt your wallet and lose your passphrase, you will LOSE ALL OF YOUR BITCOINS! +Are you sure you wish to encrypt your wallet?</source> + <translation>ВНИМАНИЕ: Если Вы зашифруете Ваш бумажник и потеряете Ваш пароль — Вы ПОТЕРЯЕТЕ ВСЕ ВАШИ БИТКОИНЫ!!! +Вы уверены, что хотите зашифровать бумажник?</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="109"/> + <source>Please re-enter your new wallet passphrase.</source> + <translation>Пожалуйста, повторите ввод нового пароля.</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="110"/> + <source>Error: the supplied passphrases didn't match.</source> + <translation>ОШИБКА: указанные пароли не совпадают.</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="111"/> + <source>Wallet encryption failed.</source> + <translation>Шифрование бумажника не удалось.</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="112"/> + <source>Wallet Encrypted. +Remember that encrypting your wallet cannot fully protect your bitcoins from being stolen by malware infecting your computer.</source> + <translation>Бумажник зашифрован. +Запомните, что шифрование Вашего бумажника не может ПОЛНОСТЬЮ гарантировать защиту Ваших биткоинов от того, чтобы быть украденными с помощью шпионского ПО на Вашем компьютере. Пожалуйста, следите за безопасностью Вашего компьютера самостоятельно.</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="116"/> + <source>Wallet is unencrypted, please encrypt it first.</source> + <translation>Бумажник не зашифрован. Сначала зашифруйте его.</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="117"/> + <source>Enter the new passphrase for the wallet.</source> + <translation>Введите новый пароль для бумажника.</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="118"/> + <source>Re-enter the new passphrase for the wallet.</source> + <translation>Пожалуйста, повторите ввод нового пароля.</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="119"/> + <source>Wallet Passphrase Changed.</source> + <translation>Пароль от бумажника изменён.</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="120"/> + <source>New Receiving Address</source> + <translation>Новый адрес для получения</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="121"/> + <source>You should use a new address for each payment you receive. + +Label</source> + <translation>Вы должны использовать новый адрес для каждого платежа, который Вы получаете. + +Метка</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="125"/> + <source><b>Status:</b> </source> + <translation><b>Статус:</b> </translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="126"/> + <source>, has not been successfully broadcast yet</source> + <translation>, ещё не было успешно разослано</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="127"/> + <source>, broadcast through %d node</source> + <translation>, разослано через %d узел</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="128"/> + <source>, broadcast through %d nodes</source> + <translation>, разослано через %d узлов</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="129"/> + <source><b>Date:</b> </source> + <translation><b>Дата:</b> </translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="130"/> + <source><b>Source:</b> Generated<br></source> + <translation><b>Источник:</b> [сгенерированно]<br></translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="131"/> + <source><b>From:</b> </source> + <translation><b>Отправитель:</b> </translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="132"/> + <source>unknown</source> + <translation>неизвестно</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="133"/> + <source><b>To:</b> </source> + <translation><b>Получатель:</b> </translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="134"/> + <source> (yours, label: </source> + <translation> (Ваш, метка: </translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="135"/> + <source> (yours)</source> + <translation> (ваш)</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="136"/> + <source><b>Credit:</b> </source> + <translation><b>Кредит:</b> </translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="137"/> + <source>(%s matures in %d more blocks)</source> + <translation>(%s «созреет» через %d блоков)</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="138"/> + <source>(not accepted)</source> + <translation>(не принято)</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="139"/> + <source><b>Debit:</b> </source> + <translation><b>Дебет:</b> </translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="140"/> + <source><b>Transaction fee:</b> </source> + <translation><b>Комиссия:</b> </translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="141"/> + <source><b>Net amount:</b> </source> + <translation><b>Общая сумма:</b> </translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="142"/> + <source>Message:</source> + <translation>Сообщение:</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="143"/> + <source>Comment:</source> + <translation>Комментарий:</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="144"/> + <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 "not accepted" and not be spendable. This may occasionally happen if another node generates a block within a few seconds of yours.</source> + <translation>Сгенерированные монеты должны подождать 120 блоков прежде, чем они смогут быть отправлены. Когда Вы сгенерировали этот блок он был отправлен в сеть, чтобы он был добавлен к цепочке блоков. Если данная процедура не удастся, статус изменится на «не подтверждено» и монеты будут непередаваемыми. Такое может случайно происходить в случае, если другой узел сгенерирует блок на несколько секунд раньше.</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="150"/> + <source>Cannot write autostart/bitcoin.desktop file</source> + <translation>Не возможно записать файл autostart/bitcoin.desktop</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="151"/> + <source>Main</source> + <translation>Основное</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="152"/> + <source>&Start Bitcoin on window system startup</source> + <translation>&Запускать бумажник при входе в систему</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="153"/> + <source>&Minimize on close</source> + <translation>С&ворачивать вместо закрытия</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="154"/> + <source>version %s</source> + <translation>версия %s</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="155"/> + <source>Error in amount </source> + <translation>Ошибка в количестве </translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="156"/> + <source>Send Coins</source> + <translation>Отправка</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="157"/> + <source>Amount exceeds your balance </source> + <translation>Сумма превышает Ваш баланс </translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="158"/> + <source>Total exceeds your balance when the </source> + <translation>Общая сумма превысит Ваш баланс, если к транзакции будет добавлено ещё</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="159"/> + <source> transaction fee is included </source> + <translation>в качестве комиссии </translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="160"/> + <source>Payment sent </source> + <translation>Платёж отправлен</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="162"/> + <source>Invalid address </source> + <translation>Ошибочный адрес </translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="163"/> + <source>Sending %s to %s</source> + <translation>Отправка %s адресату %s</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="164"/> + <source>CANCELLED</source> + <translation>ОТМЕНЕНО</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="165"/> + <source>Cancelled</source> + <translation>Отменено</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="166"/> + <source>Transfer cancelled </source> + <translation>Транзакция отменена </translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="167"/> + <source>Error: </source> + <translation>ОШИБКА: </translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="169"/> + <source>Connecting...</source> + <translation>Подключение...</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="170"/> + <source>Unable to connect</source> + <translation>Невозможно подключиться</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="171"/> + <source>Requesting public key...</source> + <translation>Запрашивается открытый ключ...</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="172"/> + <source>Received public key...</source> + <translation>Получается публичный ключ...</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="173"/> + <source>Recipient is not accepting transactions sent by IP address</source> + <translation>Получатель не принимает транзакции, отправленные на IP адрес</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="174"/> + <source>Transfer was not accepted</source> + <translation>Передача была отвергнута</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="175"/> + <source>Invalid response received</source> + <translation>Получен неверный ответ</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="176"/> + <source>Creating transaction...</source> + <translation>Создание транзакции...</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="177"/> + <source>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="180"/> + <source>Transaction creation failed</source> + <translation>Создание транзакции провалилось</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="181"/> + <source>Transaction aborted</source> + <translation>Транзакция отменена</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="182"/> + <source>Lost connection, transaction cancelled</source> + <translation>Потеряно соединение, транзакция отменена</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="183"/> + <source>Sending payment...</source> + <translation>Отправка платежа...</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="184"/> + <source>The transaction was rejected. This might happen if some of the coins in your wallet were already spent, such as if you used a copy of wallet.dat and coins were spent in the copy but not marked as spent here.</source> + <translation>В транзакции отказано. Такое может произойти, если некоторые монеты уже были потрачены, например, если Вы используете одну копию бумажника (wallet.dat), а монеты были потрачены из другой копии, но не были отмечены как потраченные в этой. Или в случае кражи (компрометации) Вашего бумажника.</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="188"/> + <source>Waiting for confirmation...</source> + <translation>Ожидание подтверждения...</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="189"/> + <source>The payment was sent, but the recipient was unable to verify it. +The transaction is recorded and will credit to the recipient, +but the comment information will be blank.</source> + <translation>Платёж был отправлен, но получатель не смог подтвердить его. +Транзакция записана и будет зачислена получателю, +но комментарий к платежу будет пустым.</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="193"/> + <source>Payment was sent, but an invalid response was received</source> + <translation>Платёж был отправлен, но был получен неверный ответ</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="194"/> + <source>Payment completed</source> + <translation>Платёж завершён</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="195"/> + <source>Name</source> + <translation>Имя</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="196"/> + <source>Address</source> + <translation>Адрес</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="197"/> + <source>Label</source> + <translation>Метка</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="198"/> + <source>Bitcoin Address</source> + <translation>Bitcoin-адрес</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="199"/> + <source>This is one of your own addresses for receiving payments and cannot be entered in the address book. </source> + <translation>Это один из Ваших личных адресов для получения платежей. Он не может быть добавлен в адресную книгу. </translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="202"/> + <source>Edit Address</source> + <translation>Изменить адрес</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="203"/> + <source>Edit Address Label</source> + <translation>Изменить метку</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="204"/> + <source>Add Address</source> + <translation>Добавить адрес</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="205"/> + <source>Bitcoin</source> + <translation></translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="206"/> + <source>Bitcoin - Generating</source> + <translation>Bitcoin - Генерация</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="207"/> + <source>Bitcoin - (not connected)</source> + <translation>Bitcoin - (нет связи)</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="208"/> + <source>&Open Bitcoin</source> + <translation>&Показать бумажник</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="209"/> + <source>&Send Bitcoins</source> + <translation>Отп&равка</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="210"/> + <source>O&ptions...</source> + <translation>Оп&ции...</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="211"/> + <source>E&xit</source> + <translation>Вы&ход</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="212"/> + <source>Program has crashed and will terminate. </source> + <translation>Программа экстренно завершилась и будет уничтожена. </translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="216"/> + <source>beta</source> + <translation>бета</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="161"/> + <source>Sending...</source> + <translation>Отправка...</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="168"/> + <source>Insufficient funds</source> + <translation>Недостаточно монет</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="65"/> + <source>Unable to bind to port %d on this computer. Bitcoin is probably already running.</source> + <translation>Невозможно забиндить порт %d на данном компьютере. Возможно, бумажник ужк запущен.</translation> + </message> + <message> + <location filename="../bitcoinstrings.cpp" line="213"/> + <source>Warning: Please check that your computer's date and time are correct. If your clock is wrong Bitcoin will not work properly.</source> + <translation>ВНИМАНИЕ: Проверьте дату и время, установленные на Вашем компьютере. Если Ваши часы идут не правильно Bitcoin может наботать не корректно.</translation> + </message> +</context> +</TS> diff --git a/src/qt/monitoreddatamapper.cpp b/src/qt/monitoreddatamapper.cpp new file mode 100644 index 0000000000..88948d07bf --- /dev/null +++ b/src/qt/monitoreddatamapper.cpp @@ -0,0 +1,36 @@ +#include "monitoreddatamapper.h" + +#include <QWidget> +#include <QMetaObject> +#include <QMetaProperty> + +MonitoredDataMapper::MonitoredDataMapper(QObject *parent) : + QDataWidgetMapper(parent) +{ +} + + +void MonitoredDataMapper::addMapping(QWidget *widget, int section) +{ + QDataWidgetMapper::addMapping(widget, section); + addChangeMonitor(widget); +} + +void MonitoredDataMapper::addMapping(QWidget *widget, int section, const QByteArray &propertyName) +{ + QDataWidgetMapper::addMapping(widget, section, propertyName); + addChangeMonitor(widget); +} + +void MonitoredDataMapper::addChangeMonitor(QWidget *widget) +{ + // Watch user property of widget for changes, and connect + // the signal to our viewModified signal. + QMetaProperty prop = widget->metaObject()->userProperty(); + int signal = prop.notifySignalIndex(); + int method = this->metaObject()->indexOfMethod("viewModified()"); + if(signal != -1 && method != -1) + { + QMetaObject::connect(widget, signal, this, method); + } +} diff --git a/src/qt/monitoreddatamapper.h b/src/qt/monitoreddatamapper.h new file mode 100644 index 0000000000..4dd2d1a86a --- /dev/null +++ b/src/qt/monitoreddatamapper.h @@ -0,0 +1,32 @@ +#ifndef MONITOREDDATAMAPPER_H +#define MONITOREDDATAMAPPER_H + +#include <QDataWidgetMapper> + +QT_BEGIN_NAMESPACE +class QWidget; +QT_END_NAMESPACE + +/* Data <-> Widget mapper that watches for changes, + to be able to notify when 'dirty' (for example, to + enable a commit/apply button). + */ +class MonitoredDataMapper : public QDataWidgetMapper +{ + Q_OBJECT +public: + explicit MonitoredDataMapper(QObject *parent=0); + + void addMapping(QWidget *widget, int section); + void addMapping(QWidget *widget, int section, const QByteArray &propertyName); +private: + void addChangeMonitor(QWidget *widget); + +signals: + void viewModified(); + +}; + + + +#endif // MONITOREDDATAMAPPER_H diff --git a/src/qt/notificator.cpp b/src/qt/notificator.cpp new file mode 100644 index 0000000000..cf0c0a3901 --- /dev/null +++ b/src/qt/notificator.cpp @@ -0,0 +1,224 @@ +#include "notificator.h" + +#include <QMetaType> +#include <QVariant> +#include <QIcon> +#include <QApplication> +#include <QStyle> +#include <QByteArray> +#include <QSystemTrayIcon> +#include <QMessageBox> + +#ifdef USE_DBUS +#include <QtDBus/QtDBus> +#include <stdint.h> +#endif + +// https://wiki.ubuntu.com/NotificationDevelopmentGuidelines recommends at least 128 +const int FREEDESKTOP_NOTIFICATION_ICON_SIZE = 128; + +Notificator::Notificator(const QString &programName, QSystemTrayIcon *trayicon, QWidget *parent): + QObject(parent), + parent(parent), + programName(programName), + mode(None), + trayIcon(trayicon) +#ifdef USE_DBUS + ,interface(0) +#endif +{ + if(trayicon && trayicon->supportsMessages()) + { + mode = QSystemTray; + } +#ifdef USE_DBUS + interface = new QDBusInterface("org.freedesktop.Notifications", + "/org/freedesktop/Notifications", "org.freedesktop.Notifications"); + if(interface->isValid()) + { + mode = Freedesktop; + } +#endif +} + +Notificator::~Notificator() +{ +#ifdef USE_DBUS + delete interface; +#endif +} + +#ifdef USE_DBUS + +// Loosely based on http://www.qtcentre.org/archive/index.php/t-25879.html +class FreedesktopImage +{ +public: + FreedesktopImage() {} + FreedesktopImage(const QImage &img); + + static int metaType(); + + // Image to variant that can be marshaled over DBus + static QVariant toVariant(const QImage &img); + +private: + int width, height, stride; + bool hasAlpha; + int channels; + int bitsPerSample; + QByteArray image; + + friend QDBusArgument &operator<<(QDBusArgument &a, const FreedesktopImage &i); + friend const QDBusArgument &operator>>(const QDBusArgument &a, FreedesktopImage &i); +}; + +Q_DECLARE_METATYPE(FreedesktopImage); + +// Image configuration settings +const int CHANNELS = 4; +const int BYTES_PER_PIXEL = 4; +const int BITS_PER_SAMPLE = 8; + +FreedesktopImage::FreedesktopImage(const QImage &img): + width(img.width()), + height(img.height()), + stride(img.width() * BYTES_PER_PIXEL), + hasAlpha(true), + channels(CHANNELS), + bitsPerSample(BITS_PER_SAMPLE) +{ + // Convert 00xAARRGGBB to RGBA bytewise (endian-independent) format + QImage tmp = img.convertToFormat(QImage::Format_ARGB32); + const uint32_t *data = reinterpret_cast<const uint32_t*>(tmp.constBits()); + + unsigned int num_pixels = width * height; + image.resize(num_pixels * BYTES_PER_PIXEL); + + for(unsigned int ptr = 0; ptr < num_pixels; ++ptr) + { + image[ptr*BYTES_PER_PIXEL+0] = data[ptr] >> 16; // R + image[ptr*BYTES_PER_PIXEL+1] = data[ptr] >> 8; // G + image[ptr*BYTES_PER_PIXEL+2] = data[ptr]; // B + image[ptr*BYTES_PER_PIXEL+3] = data[ptr] >> 24; // A + } +} + +QDBusArgument &operator<<(QDBusArgument &a, const FreedesktopImage &i) +{ + a.beginStructure(); + a << i.width << i.height << i.stride << i.hasAlpha << i.bitsPerSample << i.channels << i.image; + a.endStructure(); + return a; +} + +const QDBusArgument &operator>>(const QDBusArgument &a, FreedesktopImage &i) +{ + a.beginStructure(); + a >> i.width >> i.height >> i.stride >> i.hasAlpha >> i.bitsPerSample >> i.channels >> i.image; + a.endStructure(); + return a; +} + +int FreedesktopImage::metaType() +{ + return qDBusRegisterMetaType<FreedesktopImage>(); +} + +QVariant FreedesktopImage::toVariant(const QImage &img) +{ + FreedesktopImage fimg(img); + return QVariant(FreedesktopImage::metaType(), &fimg); +} + +void Notificator::notifyDBus(Class cls, const QString &title, const QString &text, const QIcon &icon, int millisTimeout) +{ + Q_UNUSED(cls); + // Arguments for DBus call: + QList<QVariant> args; + + // Program Name: + args.append(programName); + + // Unique ID of this notification type: + args.append(0U); + + // Application Icon, empty string + args.append(QString()); + + // Summary + args.append(title); + + // Body + args.append(text); + + // Actions (none, actions are deprecated) + QStringList actions; + args.append(actions); + + // Hints + QVariantMap hints; + + // If no icon specified, set icon based on class + QIcon tmpicon; + if(icon.isNull()) + { + QStyle::StandardPixmap sicon = QStyle::SP_MessageBoxQuestion; + switch(cls) + { + case Information: sicon = QStyle::SP_MessageBoxInformation; break; + case Warning: sicon = QStyle::SP_MessageBoxWarning; break; + case Critical: sicon = QStyle::SP_MessageBoxCritical; break; + default: break; + } + tmpicon = QApplication::style()->standardIcon(sicon); + } + else + { + tmpicon = icon; + } + hints["icon_data"] = FreedesktopImage::toVariant(tmpicon.pixmap(FREEDESKTOP_NOTIFICATION_ICON_SIZE).toImage()); + args.append(hints); + + // Timeout (in msec) + args.append(millisTimeout); + + // "Fire and forget" + interface->callWithArgumentList(QDBus::NoBlock, "Notify", args); +} +#endif + +void Notificator::notifySystray(Class cls, const QString &title, const QString &text, const QIcon &icon, int millisTimeout) +{ + Q_UNUSED(icon); + QSystemTrayIcon::MessageIcon sicon = QSystemTrayIcon::NoIcon; + switch(cls) // Set icon based on class + { + case Information: sicon = QSystemTrayIcon::Information; break; + case Warning: sicon = QSystemTrayIcon::Warning; break; + case Critical: sicon = QSystemTrayIcon::Critical; break; + } + trayIcon->showMessage(title, text, sicon, millisTimeout); +} + +void Notificator::notify(Class cls, const QString &title, const QString &text, const QIcon &icon, int millisTimeout) +{ + switch(mode) + { +#ifdef USE_DBUS + case Freedesktop: + notifyDBus(cls, title, text, icon, millisTimeout); + break; +#endif + case QSystemTray: + notifySystray(cls, title, text, icon, millisTimeout); + break; + default: + if(cls == Critical) + { + // Fall back to old fashioned popup dialog if critical and no other notification available + QMessageBox::critical(parent, title, text, QMessageBox::Ok, QMessageBox::Ok); + } + break; + } +} diff --git a/src/qt/notificator.h b/src/qt/notificator.h new file mode 100644 index 0000000000..4217f7e06f --- /dev/null +++ b/src/qt/notificator.h @@ -0,0 +1,63 @@ +#ifndef NOTIFICATOR_H +#define NOTIFICATOR_H + +#include <QObject> +#include <QIcon> + +QT_BEGIN_NAMESPACE +class QSystemTrayIcon; +#ifdef USE_DBUS +class QDBusInterface; +#endif +QT_END_NAMESPACE + +// Cross-platform desktop notification client +class Notificator: public QObject +{ + Q_OBJECT +public: + // Create a new notificator + // Ownership of trayIcon is not transferred to this object + Notificator(const QString &programName=QString(), QSystemTrayIcon *trayIcon=0, QWidget *parent=0); + ~Notificator(); + + // Message class + enum Class + { + Information, + Warning, + Critical, + }; + +public slots: + + /* Show notification message. + * + * cls: general message class + * title: title shown with message + * text: message content + * icon: optional icon to show with message + * millisTimeout: notification timeout in milliseconds (default 10 seconds) + */ + void notify(Class cls, const QString &title, const QString &text, + const QIcon &icon = QIcon(), int millisTimeout = 10000); + +private: + QWidget *parent; + enum Mode { + None, + Freedesktop, // Use DBus org.freedesktop.Notifications + QSystemTray, // Use QSystemTray::showMessage + }; + QString programName; + Mode mode; + QSystemTrayIcon *trayIcon; +#ifdef USE_DBUS + QDBusInterface *interface; + + void notifyDBus(Class cls, const QString &title, const QString &text, const QIcon &icon, int millisTimeout); +#endif + void notifySystray(Class cls, const QString &title, const QString &text, const QIcon &icon, int millisTimeout); +}; + +#endif // NOTIFICATOR_H diff --git a/src/qt/optionsdialog.cpp b/src/qt/optionsdialog.cpp new file mode 100644 index 0000000000..7267e3d103 --- /dev/null +++ b/src/qt/optionsdialog.cpp @@ -0,0 +1,281 @@ +#include "optionsdialog.h" +#include "optionsmodel.h" +#include "bitcoinamountfield.h" +#include "monitoreddatamapper.h" +#include "guiutil.h" +#include "bitcoinunits.h" +#include "qvaluecombobox.h" + +#include <QHBoxLayout> +#include <QVBoxLayout> +#include <QPushButton> +#include <QListWidget> +#include <QStackedWidget> + +#include <QCheckBox> +#include <QLabel> +#include <QLineEdit> +#include <QIntValidator> +#include <QDoubleValidator> +#include <QRegExpValidator> +#include <QDialogButtonBox> + +/* First page of options */ +class MainOptionsPage : public QWidget +{ + Q_OBJECT +public: + explicit MainOptionsPage(QWidget *parent=0); + + void setMapper(MonitoredDataMapper *mapper); +private: + QCheckBox *bitcoin_at_startup; + QCheckBox *minimize_to_tray; + QCheckBox *map_port_upnp; + QCheckBox *minimize_on_close; + QCheckBox *connect_socks4; + QLineEdit *proxy_ip; + QLineEdit *proxy_port; + BitcoinAmountField *fee_edit; + +signals: + +public slots: + +}; + +class DisplayOptionsPage : public QWidget +{ + Q_OBJECT +public: + explicit DisplayOptionsPage(QWidget *parent=0); + + void setMapper(MonitoredDataMapper *mapper); +private: + QValueComboBox *unit; + QCheckBox *display_addresses; +signals: + +public slots: + +}; + +#include "optionsdialog.moc" + +OptionsDialog::OptionsDialog(QWidget *parent): + QDialog(parent), contents_widget(0), pages_widget(0), + model(0), main_page(0), display_page(0) +{ + contents_widget = new QListWidget(); + contents_widget->setMaximumWidth(128); + + pages_widget = new QStackedWidget(); + pages_widget->setMinimumWidth(300); + + QListWidgetItem *item_main = new QListWidgetItem(tr("Main")); + contents_widget->addItem(item_main); + main_page = new MainOptionsPage(this); + pages_widget->addWidget(main_page); + + QListWidgetItem *item_display = new QListWidgetItem(tr("Display")); + contents_widget->addItem(item_display); + display_page = new DisplayOptionsPage(this); + pages_widget->addWidget(display_page); + + contents_widget->setCurrentRow(0); + + QHBoxLayout *main_layout = new QHBoxLayout(); + main_layout->addWidget(contents_widget); + main_layout->addWidget(pages_widget, 1); + + QVBoxLayout *layout = new QVBoxLayout(); + layout->addLayout(main_layout); + + QDialogButtonBox *buttonbox = new QDialogButtonBox(); + buttonbox->setStandardButtons(QDialogButtonBox::Apply|QDialogButtonBox::Ok|QDialogButtonBox::Cancel); + apply_button = buttonbox->button(QDialogButtonBox::Apply); + layout->addWidget(buttonbox); + + setLayout(layout); + setWindowTitle(tr("Options")); + + /* Widget-to-option mapper */ + mapper = new MonitoredDataMapper(this); + mapper->setSubmitPolicy(QDataWidgetMapper::ManualSubmit); + mapper->setOrientation(Qt::Vertical); + /* enable apply button when data modified */ + connect(mapper, SIGNAL(viewModified()), this, SLOT(enableApply())); + /* disable apply button when new data loaded */ + connect(mapper, SIGNAL(currentIndexChanged(int)), this, SLOT(disableApply())); + + /* Event bindings */ + connect(contents_widget, SIGNAL(currentRowChanged(int)), this, SLOT(changePage(int))); + connect(buttonbox->button(QDialogButtonBox::Ok), SIGNAL(clicked()), this, SLOT(okClicked())); + connect(buttonbox->button(QDialogButtonBox::Cancel), SIGNAL(clicked()), this, SLOT(cancelClicked())); + connect(buttonbox->button(QDialogButtonBox::Apply), SIGNAL(clicked()), this, SLOT(applyClicked())); +} + +void OptionsDialog::setModel(OptionsModel *model) +{ + this->model = model; + + mapper->setModel(model); + main_page->setMapper(mapper); + display_page->setMapper(mapper); + + mapper->toFirst(); +} + +void OptionsDialog::changePage(int index) +{ + pages_widget->setCurrentIndex(index); +} + +void OptionsDialog::okClicked() +{ + mapper->submit(); + accept(); +} + +void OptionsDialog::cancelClicked() +{ + reject(); +} + +void OptionsDialog::applyClicked() +{ + mapper->submit(); + apply_button->setEnabled(false); +} + +void OptionsDialog::enableApply() +{ + apply_button->setEnabled(true); +} + +void OptionsDialog::disableApply() +{ + apply_button->setEnabled(false); +} + +MainOptionsPage::MainOptionsPage(QWidget *parent): + QWidget(parent) +{ + QVBoxLayout *layout = new QVBoxLayout(); + + 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")); + layout->addWidget(bitcoin_at_startup); + + 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")); + layout->addWidget(minimize_to_tray); + + 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); + + minimize_on_close = new QCheckBox(tr("M&inimize on close")); + minimize_on_close->setToolTip(tr("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.")); + layout->addWidget(minimize_on_close); + + connect_socks4 = new QCheckBox(tr("&Connect through SOCKS4 proxy:")); + connect_socks4->setToolTip(tr("Connect to the Bitcon network through a SOCKS4 proxy (e.g. when connecting through Tor)")); + layout->addWidget(connect_socks4); + + QHBoxLayout *proxy_hbox = new QHBoxLayout(); + proxy_hbox->addSpacing(18); + QLabel *proxy_ip_label = new QLabel(tr("Proxy &IP: ")); + proxy_hbox->addWidget(proxy_ip_label); + proxy_ip = new QLineEdit(); + proxy_ip->setMaximumWidth(140); + proxy_ip->setEnabled(false); + proxy_ip->setValidator(new QRegExpValidator(QRegExp("[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}"), this)); + 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: ")); + proxy_hbox->addWidget(proxy_port_label); + proxy_port = new QLineEdit(); + proxy_port->setMaximumWidth(55); + proxy_port->setValidator(new QIntValidator(0, 65535, this)); + proxy_port->setEnabled(false); + proxy_port->setToolTip(tr("Port of the proxy (e.g. 1234)")); + 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 1KB. 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 1KB. Fee 0.01 recommended.")); + + fee_label->setBuddy(fee_edit); + fee_hbox->addWidget(fee_edit); + fee_hbox->addStretch(1); + + layout->addLayout(fee_hbox); + + layout->addStretch(1); // Extra space at bottom + + setLayout(layout); + + connect(connect_socks4, SIGNAL(toggled(bool)), proxy_ip, SLOT(setEnabled(bool))); + connect(connect_socks4, SIGNAL(toggled(bool)), proxy_port, SLOT(setEnabled(bool))); + +#ifndef USE_UPNP + map_port_upnp->setDisabled(true); +#endif +} + +void MainOptionsPage::setMapper(MonitoredDataMapper *mapper) +{ + // Map model to widgets + mapper->addMapping(bitcoin_at_startup, OptionsModel::StartAtStartup); + mapper->addMapping(minimize_to_tray, OptionsModel::MinimizeToTray); + mapper->addMapping(map_port_upnp, OptionsModel::MapPortUPnP); + mapper->addMapping(minimize_on_close, OptionsModel::MinimizeOnClose); + mapper->addMapping(connect_socks4, OptionsModel::ConnectSOCKS4); + mapper->addMapping(proxy_ip, OptionsModel::ProxyIP); + mapper->addMapping(proxy_port, OptionsModel::ProxyPort); + mapper->addMapping(fee_edit, OptionsModel::Fee); +} + +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); + 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 new file mode 100644 index 0000000000..d5238a3664 --- /dev/null +++ b/src/qt/optionsdialog.h @@ -0,0 +1,50 @@ +#ifndef OPTIONSDIALOG_H +#define OPTIONSDIALOG_H + +#include <QDialog> + +QT_BEGIN_NAMESPACE +class QStackedWidget; +class QListWidget; +class QListWidgetItem; +class QPushButton; +QT_END_NAMESPACE +class OptionsModel; +class MainOptionsPage; +class DisplayOptionsPage; +class MonitoredDataMapper; + +class OptionsDialog : public QDialog +{ + Q_OBJECT +public: + explicit OptionsDialog(QWidget *parent=0); + + void setModel(OptionsModel *model); + +signals: + +public slots: + void changePage(int index); + +private slots: + void okClicked(); + void cancelClicked(); + void applyClicked(); + void enableApply(); + void disableApply(); +private: + QListWidget *contents_widget; + QStackedWidget *pages_widget; + OptionsModel *model; + MonitoredDataMapper *mapper; + QPushButton *apply_button; + + // Pages + MainOptionsPage *main_page; + DisplayOptionsPage *display_page; + + void setupMainPage(); +}; + +#endif // OPTIONSDIALOG_H diff --git a/src/qt/optionsmodel.cpp b/src/qt/optionsmodel.cpp new file mode 100644 index 0000000000..efc216dab8 --- /dev/null +++ b/src/qt/optionsmodel.cpp @@ -0,0 +1,162 @@ +#include "optionsmodel.h" +#include "bitcoinunits.h" + +#include "headers.h" + +OptionsModel::OptionsModel(CWallet *wallet, QObject *parent) : + QAbstractListModel(parent), + wallet(wallet), + nDisplayUnit(BitcoinUnits::BTC), + bDisplayAddresses(false) +{ + // Read our specific settings from the wallet db + CWalletDB walletdb(wallet->strWalletFile); + walletdb.ReadSetting("nDisplayUnit", nDisplayUnit); + walletdb.ReadSetting("bDisplayAddresses", bDisplayAddresses); +} + +int OptionsModel::rowCount(const QModelIndex & parent) const +{ + return OptionIDRowCount; +} + +QVariant OptionsModel::data(const QModelIndex & index, int role) const +{ + if(role == Qt::EditRole) + { + switch(index.row()) + { + case StartAtStartup: + return QVariant(); + case MinimizeToTray: + return QVariant(fMinimizeToTray); + case MapPortUPnP: + return QVariant(fUseUPnP); + case MinimizeOnClose: + return QVariant(fMinimizeOnClose); + case ConnectSOCKS4: + return QVariant(fUseProxy); + case ProxyIP: + return QVariant(QString::fromStdString(addrProxy.ToStringIP())); + case ProxyPort: + return QVariant(QString::fromStdString(addrProxy.ToStringPort())); + case Fee: + return QVariant(nTransactionFee); + case DisplayUnit: + return QVariant(nDisplayUnit); + case DisplayAddresses: + return QVariant(bDisplayAddresses); + default: + return QVariant(); + } + } + return QVariant(); +} + +bool OptionsModel::setData(const QModelIndex & index, const QVariant & value, int role) +{ + bool successful = true; /* set to false on parse error */ + if(role == Qt::EditRole) + { + CWalletDB walletdb(wallet->strWalletFile); + switch(index.row()) + { + case StartAtStartup: + successful = false; /*TODO*/ + break; + case MinimizeToTray: + fMinimizeToTray = value.toBool(); + walletdb.WriteSetting("fMinimizeToTray", fMinimizeToTray); + break; + case MapPortUPnP: + fUseUPnP = value.toBool(); + walletdb.WriteSetting("fUseUPnP", fUseUPnP); +#ifdef USE_UPNP + MapPort(fUseUPnP); +#endif + break; + case MinimizeOnClose: + fMinimizeOnClose = value.toBool(); + walletdb.WriteSetting("fMinimizeOnClose", fMinimizeOnClose); + break; + case ConnectSOCKS4: + fUseProxy = value.toBool(); + walletdb.WriteSetting("fUseProxy", fUseProxy); + break; + case ProxyIP: + { + // Use CAddress to parse and check IP + CAddress addr(value.toString().toStdString() + ":1"); + if (addr.ip != INADDR_NONE) + { + addrProxy.ip = addr.ip; + walletdb.WriteSetting("addrProxy", addrProxy); + } + else + { + successful = false; + } + } + break; + case ProxyPort: + { + int nPort = atoi(value.toString().toAscii().data()); + if (nPort > 0 && nPort < USHRT_MAX) + { + addrProxy.port = htons(nPort); + walletdb.WriteSetting("addrProxy", addrProxy); + } + else + { + successful = false; + } + } + break; + case Fee: { + nTransactionFee = value.toLongLong(); + walletdb.WriteSetting("nTransactionFee", nTransactionFee); + } + break; + case DisplayUnit: { + int unit = value.toInt(); + nDisplayUnit = unit; + walletdb.WriteSetting("nDisplayUnit", nDisplayUnit); + emit displayUnitChanged(unit); + } + case DisplayAddresses: { + bDisplayAddresses = value.toBool(); + walletdb.WriteSetting("bDisplayAddresses", bDisplayAddresses); + } + default: + break; + } + } + emit dataChanged(index, index); + + return successful; +} + +qint64 OptionsModel::getTransactionFee() +{ + return nTransactionFee; +} + +bool OptionsModel::getMinimizeToTray() +{ + return fMinimizeToTray; +} + +bool OptionsModel::getMinimizeOnClose() +{ + return fMinimizeOnClose; +} + +int OptionsModel::getDisplayUnit() +{ + return nDisplayUnit; +} + +bool OptionsModel::getDisplayAddresses() +{ + return bDisplayAddresses; +} diff --git a/src/qt/optionsmodel.h b/src/qt/optionsmodel.h new file mode 100644 index 0000000000..7f489c5014 --- /dev/null +++ b/src/qt/optionsmodel.h @@ -0,0 +1,56 @@ +#ifndef OPTIONSMODEL_H +#define OPTIONSMODEL_H + +#include <QAbstractListModel> + +class CWallet; + +/* 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. + */ +class OptionsModel : public QAbstractListModel +{ + Q_OBJECT +public: + explicit OptionsModel(CWallet *wallet, QObject *parent = 0); + + enum OptionID { + StartAtStartup, // bool + MinimizeToTray, // bool + MapPortUPnP, // bool + MinimizeOnClose, // bool + ConnectSOCKS4, // bool + ProxyIP, // QString + ProxyPort, // QString + Fee, // qint64 + DisplayUnit, // BitcoinUnits::Unit + DisplayAddresses, // bool + OptionIDRowCount + }; + + int rowCount(const QModelIndex & parent = QModelIndex()) const; + QVariant data(const QModelIndex & index, int role = Qt::DisplayRole) const; + bool setData(const QModelIndex & index, const QVariant & value, int role = Qt::EditRole); + + /* Explicit getters */ + qint64 getTransactionFee(); + bool getMinimizeToTray(); + bool getMinimizeOnClose(); + int getDisplayUnit(); + bool getDisplayAddresses(); +private: + // Wallet stores persistent options + CWallet *wallet; + int nDisplayUnit; + bool bDisplayAddresses; +signals: + void displayUnitChanged(int unit); + +public slots: + +}; + +#endif // OPTIONSMODEL_H diff --git a/src/qt/overviewpage.cpp b/src/qt/overviewpage.cpp new file mode 100644 index 0000000000..f84a79fe30 --- /dev/null +++ b/src/qt/overviewpage.cpp @@ -0,0 +1,174 @@ +#include "overviewpage.h" +#include "ui_overviewpage.h" + +#include "walletmodel.h" +#include "bitcoinunits.h" +#include "optionsmodel.h" +#include "transactiontablemodel.h" +#include "transactionfilterproxy.h" +#include "guiutil.h" +#include "guiconstants.h" + +#include <QAbstractItemDelegate> +#include <QPainter> + +#define DECORATION_SIZE 64 +#define NUM_ITEMS 3 + +class TxViewDelegate : public QAbstractItemDelegate +{ + Q_OBJECT +public: + TxViewDelegate(): QAbstractItemDelegate(), unit(BitcoinUnits::BTC) + { + + } + + inline void paint(QPainter *painter, const QStyleOptionViewItem &option, + const QModelIndex &index ) const + { + painter->save(); + + QIcon icon = qvariant_cast<QIcon>(index.data(Qt::DecorationRole)); + QRect mainRect = option.rect; + QRect decorationRect(mainRect.topLeft(), QSize(DECORATION_SIZE, DECORATION_SIZE)); + int xspace = DECORATION_SIZE + 8; + int ypad = 6; + int halfheight = (mainRect.height() - 2*ypad)/2; + QRect amountRect(mainRect.left() + xspace, mainRect.top()+ypad, mainRect.width() - xspace, halfheight); + QRect addressRect(mainRect.left() + xspace, mainRect.top()+ypad+halfheight, mainRect.width() - xspace, halfheight); + icon.paint(painter, decorationRect); + + QDateTime date = index.data(TransactionTableModel::DateRole).toDateTime(); + QString address = index.data(Qt::DisplayRole).toString(); + qint64 amount = index.data(TransactionTableModel::AmountRole).toLongLong(); + bool confirmed = index.data(TransactionTableModel::ConfirmedRole).toBool(); + QVariant value = index.data(Qt::ForegroundRole); + QColor foreground = option.palette.color(QPalette::Text); + if(qVariantCanConvert<QColor>(value)) + { + foreground = qvariant_cast<QColor>(value); + } + + painter->setPen(foreground); + painter->drawText(addressRect, Qt::AlignLeft|Qt::AlignVCenter, address); + + if(amount < 0) + { + foreground = COLOR_NEGATIVE; + } + else if(!confirmed) + { + foreground = COLOR_UNCONFIRMED; + } + else + { + foreground = option.palette.color(QPalette::Text); + } + painter->setPen(foreground); + QString amountText = BitcoinUnits::formatWithUnit(unit, amount, true); + if(!confirmed) + { + amountText = QString("[") + amountText + QString("]"); + } + painter->drawText(amountRect, Qt::AlignRight|Qt::AlignVCenter, amountText); + + painter->setPen(option.palette.color(QPalette::Text)); + painter->drawText(amountRect, Qt::AlignLeft|Qt::AlignVCenter, GUIUtil::dateTimeStr(date)); + + painter->restore(); + } + + inline QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const + { + return QSize(DECORATION_SIZE, DECORATION_SIZE); + } + + int unit; + +}; +#include "overviewpage.moc" + +OverviewPage::OverviewPage(QWidget *parent) : + QWidget(parent), + ui(new Ui::OverviewPage), + currentBalance(-1), + currentUnconfirmedBalance(-1), + txdelegate(new TxViewDelegate()) +{ + 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("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)); + + connect(ui->listTransactions, SIGNAL(clicked(QModelIndex)), this, SIGNAL(transactionClicked(QModelIndex))); +} + +OverviewPage::~OverviewPage() +{ + delete ui; +} + +void OverviewPage::setBalance(qint64 balance, qint64 unconfirmedBalance) +{ + int unit = model->getOptionsModel()->getDisplayUnit(); + currentBalance = balance; + currentUnconfirmedBalance = unconfirmedBalance; + ui->labelBalance->setText(BitcoinUnits::formatWithUnit(unit, balance)); + ui->labelUnconfirmed->setText(BitcoinUnits::formatWithUnit(unit, unconfirmedBalance)); +} + +void OverviewPage::setNumTransactions(int count) +{ + ui->labelNumTransactions->setText(QLocale::system().toString(count)); +} + +void OverviewPage::setModel(WalletModel *model) +{ + this->model = model; + + // Set up transaction list + TransactionFilterProxy *filter = new TransactionFilterProxy(); + filter->setSourceModel(model->getTransactionTableModel()); + filter->setLimit(NUM_ITEMS); + filter->setDynamicSortFilter(true); + filter->setSortRole(Qt::EditRole); + filter->sort(TransactionTableModel::Status, Qt::DescendingOrder); + + ui->listTransactions->setModel(filter); + ui->listTransactions->setModelColumn(TransactionTableModel::ToAddress); + + // Keep up to date with wallet + setBalance(model->getBalance(), model->getUnconfirmedBalance()); + connect(model, SIGNAL(balanceChanged(qint64, qint64)), this, SLOT(setBalance(qint64, qint64))); + + setNumTransactions(model->getNumTransactions()); + connect(model, SIGNAL(numTransactionsChanged(int)), this, SLOT(setNumTransactions(int))); + + connect(model->getOptionsModel(), SIGNAL(displayUnitChanged(int)), this, SLOT(displayUnitChanged())); +} + +void OverviewPage::displayUnitChanged() +{ + if(currentBalance != -1) + setBalance(currentBalance, currentUnconfirmedBalance); + + txdelegate->unit = model->getOptionsModel()->getDisplayUnit(); + ui->listTransactions->update(); +} diff --git a/src/qt/overviewpage.h b/src/qt/overviewpage.h new file mode 100644 index 0000000000..4b4cc922ca --- /dev/null +++ b/src/qt/overviewpage.h @@ -0,0 +1,45 @@ +#ifndef OVERVIEWPAGE_H +#define OVERVIEWPAGE_H + +#include <QWidget> + +QT_BEGIN_NAMESPACE +class QModelIndex; +QT_END_NAMESPACE + +namespace Ui { + class OverviewPage; +} +class WalletModel; +class TxViewDelegate; + +class OverviewPage : public QWidget +{ + Q_OBJECT + +public: + explicit OverviewPage(QWidget *parent = 0); + ~OverviewPage(); + + void setModel(WalletModel *model); + +public slots: + void setBalance(qint64 balance, qint64 unconfirmedBalance); + void setNumTransactions(int count); + +signals: + void transactionClicked(const QModelIndex &index); + +private: + Ui::OverviewPage *ui; + WalletModel *model; + qint64 currentBalance; + qint64 currentUnconfirmedBalance; + + TxViewDelegate *txdelegate; + +private slots: + void displayUnitChanged(); +}; + +#endif // OVERVIEWPAGE_H diff --git a/src/qt/qvalidatedlineedit.cpp b/src/qt/qvalidatedlineedit.cpp new file mode 100644 index 0000000000..8ca230c9d7 --- /dev/null +++ b/src/qt/qvalidatedlineedit.cpp @@ -0,0 +1,45 @@ +#include "qvalidatedlineedit.h" + +#include "guiconstants.h" + +QValidatedLineEdit::QValidatedLineEdit(QWidget *parent) : + QLineEdit(parent), valid(true) +{ + connect(this, SIGNAL(textChanged(QString)), this, SLOT(markValid())); +} + +void QValidatedLineEdit::setValid(bool valid) +{ + if(valid == this->valid) + { + return; + } + + if(valid) + { + setStyleSheet(""); + } + else + { + setStyleSheet(STYLE_INVALID); + } + this->valid = valid; +} + +void QValidatedLineEdit::focusInEvent(QFocusEvent *evt) +{ + // Clear invalid flag on focus + setValid(true); + QLineEdit::focusInEvent(evt); +} + +void QValidatedLineEdit::markValid() +{ + setValid(true); +} + +void QValidatedLineEdit::clear() +{ + setValid(true); + QLineEdit::clear(); +} diff --git a/src/qt/qvalidatedlineedit.h b/src/qt/qvalidatedlineedit.h new file mode 100644 index 0000000000..f7b9486a6e --- /dev/null +++ b/src/qt/qvalidatedlineedit.h @@ -0,0 +1,28 @@ +#ifndef QVALIDATEDLINEEDIT_H +#define QVALIDATEDLINEEDIT_H + +#include <QLineEdit> + +// Line edit that can be marked as "invalid". When marked as invalid, +// it will get a red background until it is focused. +class QValidatedLineEdit : public QLineEdit +{ + Q_OBJECT +public: + explicit QValidatedLineEdit(QWidget *parent = 0); + void clear(); + +protected: + void focusInEvent(QFocusEvent *evt); + +private: + bool valid; + +public slots: + void setValid(bool valid); + +private slots: + void markValid(); +}; + +#endif // QVALIDATEDLINEEDIT_H diff --git a/src/qt/qvaluecombobox.cpp b/src/qt/qvaluecombobox.cpp new file mode 100644 index 0000000000..c0ad8c12e5 --- /dev/null +++ b/src/qt/qvaluecombobox.cpp @@ -0,0 +1,27 @@ +#include "qvaluecombobox.h" + +QValueComboBox::QValueComboBox(QWidget *parent) : + QComboBox(parent), role(Qt::UserRole) +{ + connect(this, SIGNAL(currentIndexChanged(int)), this, SLOT(handleSelectionChanged(int))); +} + +int QValueComboBox::value() const +{ + return itemData(currentIndex(), role).toInt(); +} + +void QValueComboBox::setValue(int value) +{ + setCurrentIndex(findData(value, role)); +} + +void QValueComboBox::setRole(int role) +{ + this->role = role; +} + +void QValueComboBox::handleSelectionChanged(int idx) +{ + emit valueChanged(); +} diff --git a/src/qt/qvaluecombobox.h b/src/qt/qvaluecombobox.h new file mode 100644 index 0000000000..2a3533da9e --- /dev/null +++ b/src/qt/qvaluecombobox.h @@ -0,0 +1,33 @@ +#ifndef QVALUECOMBOBOX_H +#define QVALUECOMBOBOX_H + +#include <QComboBox> + +// 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); +public: + explicit QValueComboBox(QWidget *parent = 0); + + int value() const; + void setValue(int value); + + // Model role to use as value + void setRole(int role); + +signals: + void valueChanged(); + +public slots: + +private: + int role; + +private slots: + void handleSelectionChanged(int idx); +}; + +#endif // QVALUECOMBOBOX_H diff --git a/src/qt/res/bitcoin-qt.rc b/src/qt/res/bitcoin-qt.rc new file mode 100644 index 0000000000..1a1ab53be4 --- /dev/null +++ b/src/qt/res/bitcoin-qt.rc @@ -0,0 +1 @@ +IDI_ICON1 ICON DISCARDABLE "icons/bitcoin.ico" diff --git a/src/qt/res/icons/add.png b/src/qt/res/icons/add.png Binary files differnew file mode 100644 index 0000000000..f98e2a8ca7 --- /dev/null +++ b/src/qt/res/icons/add.png diff --git a/src/qt/res/icons/address-book.png b/src/qt/res/icons/address-book.png Binary files differnew file mode 100644 index 0000000000..1086fbeb63 --- /dev/null +++ b/src/qt/res/icons/address-book.png diff --git a/src/qt/res/icons/bitcoin.icns b/src/qt/res/icons/bitcoin.icns Binary files differnew file mode 100644 index 0000000000..3c757080aa --- /dev/null +++ b/src/qt/res/icons/bitcoin.icns diff --git a/src/qt/res/icons/bitcoin.ico b/src/qt/res/icons/bitcoin.ico Binary files differnew file mode 100644 index 0000000000..01afd3c6da --- /dev/null +++ b/src/qt/res/icons/bitcoin.ico diff --git a/src/qt/res/icons/bitcoin.png b/src/qt/res/icons/bitcoin.png Binary files differnew file mode 100644 index 0000000000..bf43144e5e --- /dev/null +++ b/src/qt/res/icons/bitcoin.png diff --git a/src/qt/res/icons/bitcoin_testnet.png b/src/qt/res/icons/bitcoin_testnet.png Binary files differnew file mode 100644 index 0000000000..ee2dc40563 --- /dev/null +++ b/src/qt/res/icons/bitcoin_testnet.png diff --git a/src/qt/res/icons/clock1.png b/src/qt/res/icons/clock1.png Binary files differnew file mode 100644 index 0000000000..448e47f947 --- /dev/null +++ b/src/qt/res/icons/clock1.png diff --git a/src/qt/res/icons/clock2.png b/src/qt/res/icons/clock2.png Binary files differnew file mode 100644 index 0000000000..c1a6e99f7f --- /dev/null +++ b/src/qt/res/icons/clock2.png diff --git a/src/qt/res/icons/clock3.png b/src/qt/res/icons/clock3.png Binary files differnew file mode 100644 index 0000000000..e429a402cf --- /dev/null +++ b/src/qt/res/icons/clock3.png diff --git a/src/qt/res/icons/clock4.png b/src/qt/res/icons/clock4.png Binary files differnew file mode 100644 index 0000000000..ba036f47d3 --- /dev/null +++ b/src/qt/res/icons/clock4.png diff --git a/src/qt/res/icons/clock5.png b/src/qt/res/icons/clock5.png Binary files differnew file mode 100644 index 0000000000..411d7a78a0 --- /dev/null +++ b/src/qt/res/icons/clock5.png diff --git a/src/qt/res/icons/configure.png b/src/qt/res/icons/configure.png Binary files differnew file mode 100644 index 0000000000..95bd319ce1 --- /dev/null +++ b/src/qt/res/icons/configure.png diff --git a/src/qt/res/icons/connect0_16.png b/src/qt/res/icons/connect0_16.png Binary files differnew file mode 100644 index 0000000000..66f3ae4f86 --- /dev/null +++ b/src/qt/res/icons/connect0_16.png diff --git a/src/qt/res/icons/connect1_16.png b/src/qt/res/icons/connect1_16.png Binary files differnew file mode 100644 index 0000000000..76000beee2 --- /dev/null +++ b/src/qt/res/icons/connect1_16.png diff --git a/src/qt/res/icons/connect2_16.png b/src/qt/res/icons/connect2_16.png Binary files differnew file mode 100644 index 0000000000..6d9a37281a --- /dev/null +++ b/src/qt/res/icons/connect2_16.png diff --git a/src/qt/res/icons/connect3_16.png b/src/qt/res/icons/connect3_16.png Binary files differnew file mode 100644 index 0000000000..a211700785 --- /dev/null +++ b/src/qt/res/icons/connect3_16.png diff --git a/src/qt/res/icons/connect4_16.png b/src/qt/res/icons/connect4_16.png Binary files differnew file mode 100644 index 0000000000..e2fe97d496 --- /dev/null +++ b/src/qt/res/icons/connect4_16.png diff --git a/src/qt/res/icons/edit.png b/src/qt/res/icons/edit.png Binary files differnew file mode 100644 index 0000000000..1d69145151 --- /dev/null +++ b/src/qt/res/icons/edit.png diff --git a/src/qt/res/icons/editcopy.png b/src/qt/res/icons/editcopy.png Binary files differnew file mode 100644 index 0000000000..f882aa2ad8 --- /dev/null +++ b/src/qt/res/icons/editcopy.png diff --git a/src/qt/res/icons/editpaste.png b/src/qt/res/icons/editpaste.png Binary files differnew file mode 100644 index 0000000000..a192060bdd --- /dev/null +++ b/src/qt/res/icons/editpaste.png diff --git a/src/qt/res/icons/export.png b/src/qt/res/icons/export.png Binary files differnew file mode 100644 index 0000000000..69d59a38d2 --- /dev/null +++ b/src/qt/res/icons/export.png diff --git a/src/qt/res/icons/history.png b/src/qt/res/icons/history.png Binary files differnew file mode 100644 index 0000000000..60f1351783 --- /dev/null +++ b/src/qt/res/icons/history.png diff --git a/src/qt/res/icons/key.png b/src/qt/res/icons/key.png Binary files differnew file mode 100644 index 0000000000..757cad47ed --- /dev/null +++ b/src/qt/res/icons/key.png diff --git a/src/qt/res/icons/lock_closed.png b/src/qt/res/icons/lock_closed.png Binary files differnew file mode 100644 index 0000000000..ce8da0bec7 --- /dev/null +++ b/src/qt/res/icons/lock_closed.png diff --git a/src/qt/res/icons/lock_open.png b/src/qt/res/icons/lock_open.png Binary files differnew file mode 100644 index 0000000000..6a3a8edb23 --- /dev/null +++ b/src/qt/res/icons/lock_open.png diff --git a/src/qt/res/icons/notsynced.png b/src/qt/res/icons/notsynced.png Binary files differnew file mode 100644 index 0000000000..c9e71184c5 --- /dev/null +++ b/src/qt/res/icons/notsynced.png diff --git a/src/qt/res/icons/overview.png b/src/qt/res/icons/overview.png Binary files differnew file mode 100644 index 0000000000..6b94b43a2c --- /dev/null +++ b/src/qt/res/icons/overview.png diff --git a/src/qt/res/icons/quit.png b/src/qt/res/icons/quit.png Binary files differnew file mode 100644 index 0000000000..0dde6f395c --- /dev/null +++ b/src/qt/res/icons/quit.png diff --git a/src/qt/res/icons/receive.png b/src/qt/res/icons/receive.png Binary files differnew file mode 100644 index 0000000000..e8f418a4f8 --- /dev/null +++ b/src/qt/res/icons/receive.png diff --git a/src/qt/res/icons/remove.png b/src/qt/res/icons/remove.png Binary files differnew file mode 100644 index 0000000000..a44b6d130b --- /dev/null +++ b/src/qt/res/icons/remove.png diff --git a/src/qt/res/icons/send.png b/src/qt/res/icons/send.png Binary files differnew file mode 100644 index 0000000000..55ce550b4f --- /dev/null +++ b/src/qt/res/icons/send.png diff --git a/src/qt/res/icons/synced.png b/src/qt/res/icons/synced.png Binary files differnew file mode 100644 index 0000000000..8e428b6a70 --- /dev/null +++ b/src/qt/res/icons/synced.png diff --git a/src/qt/res/icons/toolbar.png b/src/qt/res/icons/toolbar.png Binary files differnew file mode 100644 index 0000000000..84c18e29fa --- /dev/null +++ b/src/qt/res/icons/toolbar.png diff --git a/src/qt/res/icons/toolbar_testnet.png b/src/qt/res/icons/toolbar_testnet.png Binary files differnew file mode 100644 index 0000000000..90ed6d99f4 --- /dev/null +++ b/src/qt/res/icons/toolbar_testnet.png diff --git a/src/qt/res/icons/transaction0.png b/src/qt/res/icons/transaction0.png Binary files differnew file mode 100644 index 0000000000..4578666ee4 --- /dev/null +++ b/src/qt/res/icons/transaction0.png diff --git a/src/qt/res/icons/transaction2.png b/src/qt/res/icons/transaction2.png Binary files differnew file mode 100644 index 0000000000..01bb558a10 --- /dev/null +++ b/src/qt/res/icons/transaction2.png diff --git a/src/qt/res/icons/tx_inout.png b/src/qt/res/icons/tx_inout.png Binary files differnew file mode 100644 index 0000000000..5f092f97aa --- /dev/null +++ b/src/qt/res/icons/tx_inout.png diff --git a/src/qt/res/icons/tx_input.png b/src/qt/res/icons/tx_input.png Binary files differnew file mode 100644 index 0000000000..0f5fea3a84 --- /dev/null +++ b/src/qt/res/icons/tx_input.png diff --git a/src/qt/res/icons/tx_mined.png b/src/qt/res/icons/tx_mined.png Binary files differnew file mode 100644 index 0000000000..613f30fecc --- /dev/null +++ b/src/qt/res/icons/tx_mined.png diff --git a/src/qt/res/icons/tx_output.png b/src/qt/res/icons/tx_output.png Binary files differnew file mode 100644 index 0000000000..9ae39fb329 --- /dev/null +++ b/src/qt/res/icons/tx_output.png diff --git a/src/qt/res/images/about.png b/src/qt/res/images/about.png Binary files differnew file mode 100644 index 0000000000..c9ab9511ef --- /dev/null +++ b/src/qt/res/images/about.png diff --git a/src/qt/res/images/splash2.jpg b/src/qt/res/images/splash2.jpg Binary files differnew file mode 100644 index 0000000000..3846e6f68d --- /dev/null +++ b/src/qt/res/images/splash2.jpg diff --git a/src/qt/res/movies/update_spinner.mng b/src/qt/res/movies/update_spinner.mng Binary files differnew file mode 100644 index 0000000000..7df3baac6f --- /dev/null +++ b/src/qt/res/movies/update_spinner.mng diff --git a/src/qt/res/src/bitcoin.svg b/src/qt/res/src/bitcoin.svg new file mode 100644 index 0000000000..96f10178a2 --- /dev/null +++ b/src/qt/res/src/bitcoin.svg @@ -0,0 +1,115 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!-- Created with Inkscape (http://www.inkscape.org/) --> + +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + xmlns:xlink="http://www.w3.org/1999/xlink" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + id="svg2" + version="1.1" + inkscape:version="0.48.0 r9654" + width="256" + height="256" + sodipodi:docname="bitcoin.svg" + inkscape:export-filename="/store/orion/projects/bitcoin/BC_Logo_icon32.png" + inkscape:export-xdpi="11.25" + inkscape:export-ydpi="11.25" + style="display:inline"> + <metadata + id="metadata8"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + <dc:title></dc:title> + </cc:Work> + </rdf:RDF> + </metadata> + <defs + id="defs6"> + <linearGradient + id="linearGradient3800"> + <stop + style="stop-color:#fbba6c;stop-opacity:1;" + offset="0" + id="stop3802" /> + <stop + style="stop-color:#f89825;stop-opacity:1;" + offset="1" + id="stop3804" /> + </linearGradient> + <filter + inkscape:collect="always" + id="filter3788"> + <feGaussianBlur + inkscape:collect="always" + stdDeviation="7.7328864" + id="feGaussianBlur3790" /> + </filter> + <radialGradient + inkscape:collect="always" + xlink:href="#linearGradient3800" + id="radialGradient3806" + cx="137.01819" + cy="136.81316" + fx="137.01819" + fy="136.81316" + r="120.22619" + gradientTransform="matrix(1,0,0,0.99768745,0,0.29784356)" + gradientUnits="userSpaceOnUse" /> + </defs> + <sodipodi:namedview + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1" + objecttolerance="10" + gridtolerance="10" + guidetolerance="10" + inkscape:pageopacity="0" + inkscape:pageshadow="2" + inkscape:window-width="1204" + inkscape:window-height="972" + id="namedview4" + showgrid="false" + inkscape:zoom="1" + inkscape:cx="-54.927212" + inkscape:cy="128" + inkscape:window-x="238" + inkscape:window-y="143" + inkscape:window-maximized="0" + inkscape:current-layer="layer1" /> + <g + inkscape:groupmode="layer" + id="layer2" + inkscape:label="Shadow" + style="display:inline" + sodipodi:insensitive="true"> + <path + sodipodi:nodetypes="sssssssssssscssssscsssscscssssssssssscscsssssssscscssssscssscssssssscsssssssss" + inkscape:connector-curvature="0" + id="path2986" + d="M 111.77934,251.6677 C 67.147549,243.82973 30.788461,211.94464 17.111244,168.64858 7.1011053,136.9609 11.409199,100.0445 28.433065,71.630835 45.23974,43.579693 71.151762,24.409692 103.78036,15.888094 c 12.1652,-3.177178 33.00458,-3.99623 46.6577,-1.833789 45.59908,7.22219 82.56109,39.080427 96.48709,83.164011 10.01013,31.687684 5.70204,68.604084 -11.32183,97.017744 -16.8025,28.04418 -42.64131,47.16473 -75.34729,55.75648 -7.52834,1.97768 -11.60054,2.41566 -24.95273,2.68377 -10.90952,0.21906 -18.34974,-0.0999 -23.52396,-1.00861 z m 20.17619,-31.35425 c 0.63075,-2.39846 2.14458,-8.28561 3.36407,-13.08254 1.56481,-6.15521 2.69488,-8.60563 3.84031,-8.32722 0.89267,0.21696 7.39067,0.68131 14.43998,1.03189 16.31195,0.81124 23.9944,-1.14509 31.43693,-8.00537 7.63877,-7.04117 11.30337,-15.63267 11.82635,-27.72636 0.37592,-8.69327 0.10152,-10.44523 -2.27687,-14.53617 -1.48738,-2.55836 -5.17935,-6.48313 -8.20438,-8.7217 l -5.50006,-4.07013 4.37131,-1.87838 c 9.83682,-4.22697 14.47489,-11.84516 15.1401,-24.86816 0.41587,-8.14174 0.12573,-9.95645 -2.32406,-14.536178 -3.41249,-6.379435 -11.7129,-12.875301 -21.81801,-17.074696 -4.15735,-1.727672 -7.66196,-3.187464 -7.78803,-3.243983 -0.12607,-0.05651 1.28534,-6.088871 3.13645,-13.405229 1.85112,-7.316357 3.26253,-13.372021 3.13645,-13.457031 -0.12607,-0.08501 -2.84573,-0.778731 -6.04368,-1.541604 -3.19796,-0.762872 -6.6666,-1.640092 -7.70811,-1.949379 -1.54868,-0.459905 -2.47321,1.773902 -5.07541,12.262964 -2.215,8.928331 -3.69157,12.825303 -4.85951,12.825303 -2.30435,0 -12.01076,-2.489633 -12.01076,-3.080685 0,-0.263336 1.37739,-5.975631 3.06085,-12.693987 1.68345,-6.718356 2.78086,-12.49516 2.43868,-12.837341 -1.06646,-1.066455 -13.66473,-4.07084 -14.61292,-3.484827 -0.49474,0.305758 -2.13899,5.806491 -3.65393,12.223852 -1.51493,6.417361 -3.0693,12.177423 -3.45416,12.800138 -0.42537,0.68826 -6.84309,-0.416984 -16.36715,-2.818708 -8.617084,-2.173005 -15.989649,-3.583696 -16.383486,-3.13487 -0.393848,0.448826 -1.334199,3.432558 -2.089673,6.630515 -0.755474,3.197957 -1.623352,6.656241 -1.928612,7.685075 -0.438573,1.478093 0.970946,2.194444 6.717302,3.413902 7.407149,1.571906 12.549199,5.114005 12.549199,8.644526 0,3.559986 -18.770806,76.736553 -20.092504,78.329103 -1.007682,1.21419 -2.807318,1.40957 -7.196833,0.78135 -11.551776,-1.65329 -10.897277,-1.95681 -14.648875,6.7937 -1.878049,4.38054 -3.41465,8.32832 -3.41465,8.77286 0,0.44453 6.14881,2.29784 13.664008,4.11848 7.515199,1.82065 14.792647,3.72851 16.172114,4.23971 l 2.508106,0.92945 -3.31877,13.11716 c -1.825323,7.21442 -3.215633,13.21726 -3.089563,13.33965 0.549874,0.53382 15.058297,4.01313 15.382497,3.68892 0.19792,-0.19791 1.74688,-5.83164 3.44215,-12.51942 1.69526,-6.68778 3.30839,-12.52544 3.58472,-12.97256 0.443,-0.71676 11.73522,1.68597 12.76544,2.7162 0.21981,0.21981 -1.08467,6.26629 -2.89884,13.43664 l -3.29849,13.03696 4.8136,1.23571 c 2.6475,0.67965 5.33693,1.42786 5.97652,1.66271 3.63321,1.33406 5.19855,0.40079 6.2902,-3.75024 z m 0.68716,-43.88623 c -0.63959,-0.21166 -5.21848,-1.29512 -10.17531,-2.40768 -4.95684,-1.11255 -9.01243,-2.23295 -9.01243,-2.48975 0,-0.65492 8.11353,-33.1852 8.69895,-34.87745 0.34957,-1.01046 3.32218,-0.62569 10.96233,1.41895 12.84914,3.43866 18.00073,5.54314 23.11146,9.44128 8.35514,6.37277 10.49752,14.36232 5.75489,21.46161 -3.94917,5.91153 -9.15813,8.03413 -19.45529,7.92788 -4.79693,-0.0496 -9.245,-0.26317 -9.8846,-0.47484 z m 2.50991,-54.7082 c -3.73627,-0.93479 -7.21128,-1.958 -7.72221,-2.27376 -0.72057,-0.44534 6.3168,-31.740173 7.3756,-32.798964 0.64276,-0.642776 19.09068,4.708848 22.8588,6.631196 2.34875,1.19824 5.92162,4.059214 7.93975,6.357724 2.94919,3.358944 3.66929,5.201504 3.66929,9.388734 0,4.31035 -0.68714,5.95944 -3.98073,9.55341 -3.93586,4.2948 -4.08991,4.34657 -13.664,4.59252 -5.49512,0.14117 -12.62142,-0.48635 -16.4765,-1.45086 z" + style="opacity:0.8176923;fill:#000000;fill-opacity:1;filter:url(#filter3788)" /> + </g> + <g + inkscape:groupmode="layer" + id="layer1" + inkscape:label="Front" + style="display:inline"> + <path + style="fill:url(#radialGradient3806);fill-opacity:1;display:inline" + d="M 107.77934,247.6677 C 63.147549,239.82973 26.788461,207.94464 13.111244,164.64858 3.1011053,132.9609 7.4091993,96.044496 24.433065,67.630835 41.23974,39.579693 67.151762,20.409692 99.780356,11.888094 111.94556,8.7109163 132.78494,7.8918643 146.43806,10.054305 c 45.59908,7.22219 82.56109,39.080427 96.48709,83.164011 10.01013,31.687684 5.70204,68.604084 -11.32183,97.017744 -16.8025,28.04418 -42.64131,47.16473 -75.34729,55.75648 -7.52834,1.97768 -11.60054,2.41566 -24.95273,2.68377 -10.90952,0.21906 -18.34974,-0.0999 -23.52396,-1.00861 z m 20.17619,-31.35425 c 0.63075,-2.39846 2.14458,-8.28561 3.36407,-13.08254 1.56481,-6.15521 2.69488,-8.60563 3.84031,-8.32722 0.89267,0.21696 7.39067,0.68131 14.43998,1.03189 16.31195,0.81124 23.9944,-1.14509 31.43693,-8.00537 7.63877,-7.04117 11.30337,-15.63267 11.82635,-27.72636 0.37592,-8.69327 0.10152,-10.44523 -2.27687,-14.53617 -1.48738,-2.55836 -5.17935,-6.48313 -8.20438,-8.7217 l -5.50006,-4.07013 4.37131,-1.87838 c 9.83682,-4.22697 14.47489,-11.84516 15.1401,-24.86816 0.41587,-8.141744 0.12573,-9.956454 -2.32406,-14.536178 -3.41249,-6.379435 -11.7129,-12.875301 -21.81801,-17.074696 -4.15735,-1.727672 -7.66196,-3.187464 -7.78803,-3.243983 -0.12607,-0.05651 1.28534,-6.088871 3.13645,-13.405229 1.85112,-7.316357 3.26253,-13.372021 3.13645,-13.457031 -0.12607,-0.08501 -2.84573,-0.778731 -6.04368,-1.541604 -3.19796,-0.762872 -6.6666,-1.640092 -7.70811,-1.949379 -1.54868,-0.459905 -2.47321,1.773902 -5.07541,12.262964 -2.215,8.928331 -3.69157,12.825303 -4.85951,12.825303 -2.30435,0 -12.01076,-2.489633 -12.01076,-3.080685 0,-0.263336 1.37739,-5.975631 3.06085,-12.693987 1.68345,-6.718356 2.78086,-12.49516 2.43868,-12.837341 -1.06646,-1.066455 -13.66473,-4.07084 -14.61292,-3.484827 -0.49474,0.305758 -2.13899,5.806491 -3.65393,12.223852 -1.51493,6.417361 -3.0693,12.177423 -3.45416,12.800138 -0.42537,0.68826 -6.84309,-0.416984 -16.36715,-2.818708 -8.617084,-2.173005 -15.989649,-3.583696 -16.383486,-3.13487 -0.393848,0.448826 -1.334199,3.432558 -2.089673,6.630515 -0.755474,3.197957 -1.623352,6.656241 -1.928612,7.685075 -0.438573,1.478093 0.970946,2.194444 6.717302,3.413902 7.407145,1.571906 12.549199,5.114005 12.549199,8.644526 0,3.559986 -18.770806,76.736553 -20.092504,78.329103 -1.007682,1.21419 -2.807318,1.40957 -7.196833,0.78135 -11.551776,-1.65329 -10.897277,-1.95681 -14.648875,6.7937 -1.878049,4.38054 -3.41465,8.32832 -3.41465,8.77286 0,0.44453 6.14881,2.29784 13.664008,4.11848 7.515199,1.82065 14.792647,3.72851 16.172114,4.23971 l 2.508106,0.92945 -3.31877,13.11716 c -1.825323,7.21442 -3.215633,13.21726 -3.089563,13.33965 0.549874,0.53382 15.058293,4.01313 15.382493,3.68892 0.19792,-0.19791 1.74688,-5.83164 3.442154,-12.51942 1.69526,-6.68778 3.30839,-12.52544 3.58472,-12.97256 0.443,-0.71676 11.73522,1.68597 12.76544,2.7162 0.21981,0.21981 -1.08467,6.26629 -2.89884,13.43664 l -3.29849,13.03696 4.8136,1.23571 c 2.6475,0.67965 5.33693,1.42786 5.97652,1.66271 3.63321,1.33406 5.19855,0.40079 6.2902,-3.75024 z m 0.68716,-43.88623 c -0.63959,-0.21166 -5.21848,-1.29512 -10.17531,-2.40768 -4.95684,-1.11255 -9.01243,-2.23295 -9.01243,-2.48975 0,-0.65492 8.11353,-33.1852 8.69895,-34.87745 0.34957,-1.01046 3.32218,-0.62569 10.96233,1.41895 12.84914,3.43866 18.00073,5.54314 23.11146,9.44128 8.35514,6.37277 10.49752,14.36232 5.75489,21.46161 -3.94917,5.91153 -9.15813,8.03413 -19.45529,7.92788 -4.79693,-0.0496 -9.245,-0.26317 -9.8846,-0.47484 z m 2.50991,-54.7082 c -3.73627,-0.93479 -7.21128,-1.958 -7.72221,-2.27376 -0.72057,-0.44534 6.3168,-31.740173 7.3756,-32.798964 0.64276,-0.642776 19.09068,4.708848 22.8588,6.631196 2.34875,1.19824 5.92162,4.059214 7.93975,6.357724 2.94919,3.35894 3.66929,5.201504 3.66929,9.388734 0,4.31035 -0.68714,5.95944 -3.98073,9.55341 -3.93586,4.2948 -4.08991,4.34657 -13.664,4.59252 -5.49512,0.14117 -12.62142,-0.48635 -16.4765,-1.45086 z" + id="path2987" + inkscape:connector-curvature="0" + sodipodi:nodetypes="sssssssssssscssssscsssscscssssssssssscscsssssssscscssssscssscssssssscsssssssss" + inkscape:export-xdpi="11.98" + inkscape:export-ydpi="11.98" /> + </g> +</svg> diff --git a/src/qt/res/src/clock1.svg b/src/qt/res/src/clock1.svg new file mode 100644 index 0000000000..793dc7f91c --- /dev/null +++ b/src/qt/res/src/clock1.svg @@ -0,0 +1,261 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!-- Created with Inkscape (http://www.inkscape.org/) --> + +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + xmlns:xlink="http://www.w3.org/1999/xlink" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + width="16px" + height="16px" + id="svg2987" + version="1.1" + inkscape:version="0.48.0 r9654" + sodipodi:docname="clock0.svg"> + <defs + id="defs2989"> + <linearGradient + id="linearGradient4465"> + <stop + id="stop4467" + offset="0" + style="stop-color:#c1c1c1;stop-opacity:1;" /> + <stop + id="stop4469" + offset="1" + style="stop-color:#8c8c8c;stop-opacity:1;" /> + </linearGradient> + <linearGradient + id="linearGradient4424"> + <stop + style="stop-color:#000000;stop-opacity:1;" + offset="0" + id="stop4426" /> + <stop + style="stop-color:#b3b3b3;stop-opacity:1;" + offset="1" + id="stop4428" /> + </linearGradient> + <linearGradient + id="linearGradient4357"> + <stop + id="stop4359" + offset="0" + style="stop-color:#ffffff;stop-opacity:1;" /> + <stop + style="stop-color:#ff84a6;stop-opacity:0.49803922;" + offset="0.36363637" + id="stop4473" /> + <stop + id="stop4361" + offset="1" + style="stop-color:#ff0a4d;stop-opacity:0;" /> + </linearGradient> + <linearGradient + id="linearGradient4347"> + <stop + id="stop4349" + offset="0" + style="stop-color:#909090;stop-opacity:1;" /> + <stop + id="stop4351" + offset="1" + style="stop-color:#3c3c3c;stop-opacity:1;" /> + </linearGradient> + <linearGradient + id="linearGradient3767"> + <stop + style="stop-color:#ff8282;stop-opacity:1;" + offset="0" + id="stop3769" /> + <stop + style="stop-color:#ff1919;stop-opacity:1;" + offset="1" + id="stop3771" /> + </linearGradient> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient4347" + id="linearGradient3779" + x1="2.224874" + y1="2.8301363" + x2="14.038582" + y2="13.171574" + gradientUnits="userSpaceOnUse" /> + <filter + inkscape:collect="always" + id="filter4339"> + <feGaussianBlur + inkscape:collect="always" + stdDeviation="0.3240906" + id="feGaussianBlur4341" /> + </filter> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient3767" + id="linearGradient4345" + gradientUnits="userSpaceOnUse" + x1="2.224874" + y1="2.8301363" + x2="14.038582" + y2="13.171574" /> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient4424" + id="linearGradient4430" + x1="10.740074" + y1="16.148634" + x2="6.3055735" + y2="-1.2798394" + gradientUnits="userSpaceOnUse" /> + <radialGradient + inkscape:collect="always" + xlink:href="#linearGradient4357" + id="radialGradient4440" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(1.5712985,0.01074232,-0.01353758,1.9801676,-4.5655476,-0.68355868)" + cx="8.1975746" + cy="-0.080271922" + fx="8.1975746" + fy="-0.080271922" + r="7.7781744" /> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient4465" + id="linearGradient4471" + gradientUnits="userSpaceOnUse" + x1="2.224874" + y1="2.8301363" + x2="14.038582" + y2="13.171574" /> + </defs> + <sodipodi:namedview + id="base" + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1.0" + inkscape:pageopacity="0.0" + inkscape:pageshadow="2" + inkscape:zoom="1" + inkscape:cx="0.31530906" + inkscape:cy="12.478576" + inkscape:current-layer="layer4" + showgrid="true" + inkscape:grid-bbox="true" + inkscape:document-units="px" + inkscape:window-width="1920" + inkscape:window-height="1127" + inkscape:window-x="0" + inkscape:window-y="25" + inkscape:window-maximized="1" + showguides="true" + inkscape:guide-bbox="true" /> + <metadata + id="metadata2992"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + <dc:title></dc:title> + </cc:Work> + </rdf:RDF> + </metadata> + <g + inkscape:groupmode="layer" + id="layer4" + inkscape:label="Shadow" + style="display:inline"> + <path + sodipodi:type="arc" + style="fill:url(#linearGradient3779);fill-opacity:1;stroke:none;display:inline;filter:url(#filter4339)" + id="path2997" + sodipodi:cx="8.0433397" + sodipodi:cy="8.1334372" + sodipodi:rx="7.7781744" + sodipodi:ry="7.7781744" + d="m 15.821514,8.1334372 a 7.7781744,7.7781744 0 1 1 -15.55634867,0 7.7781744,7.7781744 0 1 1 15.55634867,0 z" + transform="translate(0,-0.08838835)" /> + </g> + <g + id="layer1" + inkscape:label="Clock" + inkscape:groupmode="layer" + style="display:inline" + sodipodi:insensitive="true"> + <path + transform="matrix(0.91562931,0,0,0.91562931,0.64737218,0.56658541)" + d="m 15.821514,8.1334372 a 7.7781744,7.7781744 0 1 1 -15.55634867,0 7.7781744,7.7781744 0 1 1 15.55634867,0 z" + sodipodi:ry="7.7781744" + sodipodi:rx="7.7781744" + sodipodi:cy="8.1334372" + sodipodi:cx="8.0433397" + id="path4343" + style="fill:url(#linearGradient4345);fill-opacity:1;stroke:none" + sodipodi:type="arc" /> + </g> + <g + inkscape:groupmode="layer" + id="layer5" + inkscape:label="Block" + sodipodi:insensitive="true" + style="display:inline"> + <path + sodipodi:type="arc" + style="fill:url(#linearGradient4471);fill-opacity:1;stroke:none;display:inline" + id="path4462" + sodipodi:cx="8.0433397" + sodipodi:cy="8.1334372" + sodipodi:rx="7.7781744" + sodipodi:ry="7.7781744" + d="M 14.4287,3.6919089 A 7.7781744,7.7781744 0 1 1 8.0707322,0.35531099 L 8.0433397,8.1334372 z" + transform="matrix(0.91562931,0,0,0.91562931,0.64737218,0.56658541)" + sodipodi:start="5.675432" + sodipodi:end="10.999096" /> + </g> + <g + inkscape:groupmode="layer" + id="layer2" + inkscape:label="Ticks" + style="display:inline" + sodipodi:insensitive="true"> + <path + id="use4309" + transform="matrix(0.77323696,-0.44642857,0.44642857,0.77323696,-1.9715899,5.5529328)" + style="fill:url(#linearGradient4430);fill-opacity:1;stroke:none" + d="M 8.875,2.03125 C 8.875,2.5317581 8.4832492,2.9375 8,2.9375 7.5167508,2.9375 7.125,2.5317581 7.125,2.03125 7.125,1.5307419 7.5167508,1.125 8,1.125 c 0.4832492,0 0.875,0.4057419 0.875,0.90625 z M 5.8484195,2.6358993 C 6.0986735,3.069352 5.9622783,3.6166102 5.5437722,3.8582348 5.1252661,4.0998594 4.583129,3.944352 4.332875,3.5108993 4.082621,3.0774465 4.2190162,2.5301884 4.6375222,2.2885638 5.0560283,2.0469392 5.5981654,2.2024466 5.8484195,2.6358993 z M 3.5296488,4.6728304 C 3.9631015,4.9230844 4.1186089,5.4652215 3.8769843,5.8837276 3.6353597,6.3022337 3.0881015,6.4386289 2.6546488,6.1883748 2.221196,5.9381208 2.0656886,5.3959837 2.3073132,4.9774776 2.5489379,4.5589715 3.096196,4.4225763 3.5296488,4.6728304 z m -0.989649,2.9234201 c 0.5005081,0 0.90625,0.3917508 0.90625,0.875 0,0.4832492 -0.4057419,0.875 -0.90625,0.875 -0.5005081,0 -0.90625,-0.3917508 -0.90625,-0.875 0,-0.4832492 0.4057419,-0.875 0.90625,-0.875 z M 3.144649,10.622831 c 0.4334527,-0.250254 0.9807109,-0.113859 1.2223355,0.304647 0.2416246,0.418506 0.086117,0.960643 -0.3473355,1.210897 C 3.5861963,12.388629 3.0389381,12.252234 2.7973135,11.833728 2.5556889,11.415222 2.7111963,10.873085 3.144649,10.622831 z m 2.036931,2.31877 c 0.2502541,-0.433452 0.7923912,-0.58896 1.2108973,-0.347335 0.4185061,0.241624 0.5549012,0.788883 0.3046472,1.222335 -0.2502541,0.433453 -0.7923912,0.58896 -1.2108972,0.347336 C 5.0677212,13.922312 4.931326,13.375054 5.18158,12.941601 z m 2.9234201,0.989649 c 0,-0.500508 0.3917508,-0.90625 0.875,-0.90625 0.4832492,0 0.875,0.405742 0.875,0.90625 0,0.500509 -0.3917508,0.90625 -0.875,0.90625 -0.4832492,0 -0.875,-0.405741 -0.875,-0.90625 z M 11.13158,13.326601 c -0.250254,-0.433453 -0.113859,-0.980711 0.304647,-1.222335 0.418507,-0.241625 0.960644,-0.08612 1.210898,0.347335 0.250254,0.433453 0.113859,0.980711 -0.304648,1.222336 -0.418506,0.241624 -0.960643,0.08612 -1.210897,-0.347336 z m 2.318771,-2.036931 c -0.433453,-0.250254 -0.58896,-0.792391 -0.347335,-1.210897 0.241624,-0.4185064 0.788882,-0.5549016 1.222335,-0.3046476 0.433453,0.2502536 0.58896,0.7923916 0.347336,1.2108976 -0.241625,0.418506 -0.788883,0.554901 -1.222336,0.304647 z M 14.44,8.36625 c -0.500508,0 -0.90625,-0.3917508 -0.90625,-0.875 0,-0.4832492 0.405742,-0.875 0.90625,-0.875 0.500508,0 0.90625,0.3917508 0.90625,0.875 0,0.4832492 -0.405742,0.875 -0.90625,0.875 z M 13.835351,5.3396697 C 13.401898,5.5899238 12.85464,5.4535286 12.613016,5.0350225 12.371391,4.6165164 12.526898,4.0743793 12.960351,3.8241252 c 0.433453,-0.250254 0.980711,-0.1138588 1.222336,0.3046473 0.241624,0.4185061 0.08612,0.9606432 -0.347336,1.2108972 z M 11.79842,3.0208989 C 11.548166,3.4543516 11.006029,3.609859 10.587523,3.3682344 10.169017,3.1266098 10.032621,2.5793516 10.282875,2.1458989 10.533129,1.7124461 11.075267,1.5569388 11.493773,1.7985634 11.912279,2.040188 12.048674,2.5874462 11.79842,3.0208989 z" + inkscape:connector-curvature="0" /> + <path + style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + d="m 7.875,2.8017767 0,5.25" + id="path4436" + inkscape:connector-curvature="0" /> + <path + style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + d="M 7.7781746,7.4629419 10.783378,7.6397186" + id="path4438" + inkscape:connector-curvature="0" /> + </g> + <g + inkscape:groupmode="layer" + id="layer3" + inkscape:label="Shine" + style="display:inline" + sodipodi:insensitive="true"> + <path + sodipodi:type="arc" + style="fill:url(#radialGradient4440);fill-opacity:1;stroke:none" + id="path4353" + sodipodi:cx="8.0433397" + sodipodi:cy="8.1334372" + sodipodi:rx="7.3686199" + sodipodi:ry="7.4368792" + d="m 15.41196,8.1334372 a 7.3686199,7.4368792 0 1 1 -14.73724019,0 7.3686199,7.4368792 0 1 1 14.73724019,0 z" + transform="matrix(0.91562931,0,0,0.91562931,0.64737218,0.56658541)" /> + </g> +</svg> diff --git a/src/qt/res/src/clock2.svg b/src/qt/res/src/clock2.svg new file mode 100644 index 0000000000..6a78adf700 --- /dev/null +++ b/src/qt/res/src/clock2.svg @@ -0,0 +1,262 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!-- Created with Inkscape (http://www.inkscape.org/) --> + +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + xmlns:xlink="http://www.w3.org/1999/xlink" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + width="16px" + height="16px" + id="svg2987" + version="1.1" + inkscape:version="0.48.0 r9654" + sodipodi:docname="clock0.svg"> + <defs + id="defs2989"> + <linearGradient + id="linearGradient4465"> + <stop + id="stop4467" + offset="0" + style="stop-color:#c1c1c1;stop-opacity:1;" /> + <stop + id="stop4469" + offset="1" + style="stop-color:#8c8c8c;stop-opacity:1;" /> + </linearGradient> + <linearGradient + id="linearGradient4424"> + <stop + style="stop-color:#000000;stop-opacity:1;" + offset="0" + id="stop4426" /> + <stop + style="stop-color:#b3b3b3;stop-opacity:1;" + offset="1" + id="stop4428" /> + </linearGradient> + <linearGradient + id="linearGradient4357"> + <stop + id="stop4359" + offset="0" + style="stop-color:#ffffff;stop-opacity:1;" /> + <stop + style="stop-color:#ff848d;stop-opacity:0.49803922;" + offset="0.36363637" + id="stop4473" /> + <stop + id="stop4361" + offset="1" + style="stop-color:#ff0a1b;stop-opacity:0;" /> + </linearGradient> + <linearGradient + id="linearGradient4347"> + <stop + id="stop4349" + offset="0" + style="stop-color:#909090;stop-opacity:1;" /> + <stop + id="stop4351" + offset="1" + style="stop-color:#3c3c3c;stop-opacity:1;" /> + </linearGradient> + <linearGradient + id="linearGradient3767"> + <stop + style="stop-color:#ffae82;stop-opacity:1;" + offset="0" + id="stop3769" /> + <stop + style="stop-color:#ff6a19;stop-opacity:1;" + offset="1" + id="stop3771" /> + </linearGradient> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient4347" + id="linearGradient3779" + x1="2.224874" + y1="2.8301363" + x2="14.038582" + y2="13.171574" + gradientUnits="userSpaceOnUse" /> + <filter + inkscape:collect="always" + id="filter4339"> + <feGaussianBlur + inkscape:collect="always" + stdDeviation="0.3240906" + id="feGaussianBlur4341" /> + </filter> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient3767" + id="linearGradient4345" + gradientUnits="userSpaceOnUse" + x1="2.224874" + y1="2.8301363" + x2="14.038582" + y2="13.171574" /> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient4424" + id="linearGradient4430" + x1="10.740074" + y1="16.148634" + x2="6.3055735" + y2="-1.2798394" + gradientUnits="userSpaceOnUse" /> + <radialGradient + inkscape:collect="always" + xlink:href="#linearGradient4357" + id="radialGradient4440" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(1.5712985,0.01074232,-0.01353758,1.9801676,-4.5655476,-0.68355868)" + cx="8.1975746" + cy="-0.080271922" + fx="8.1975746" + fy="-0.080271922" + r="7.7781744" /> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient4465" + id="linearGradient4471" + gradientUnits="userSpaceOnUse" + x1="2.224874" + y1="2.8301363" + x2="14.038582" + y2="13.171574" /> + </defs> + <sodipodi:namedview + id="base" + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1.0" + inkscape:pageopacity="0.0" + inkscape:pageshadow="2" + inkscape:zoom="1" + inkscape:cx="10.569917" + inkscape:cy="10.828475" + inkscape:current-layer="layer5" + showgrid="true" + inkscape:grid-bbox="true" + inkscape:document-units="px" + inkscape:window-width="1920" + inkscape:window-height="1127" + inkscape:window-x="0" + inkscape:window-y="25" + inkscape:window-maximized="1" + showguides="true" + inkscape:guide-bbox="true" /> + <metadata + id="metadata2992"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + <dc:title></dc:title> + </cc:Work> + </rdf:RDF> + </metadata> + <g + inkscape:groupmode="layer" + id="layer4" + inkscape:label="Shadow" + style="display:inline" + sodipodi:insensitive="true"> + <path + sodipodi:type="arc" + style="fill:url(#linearGradient3779);fill-opacity:1;stroke:none;display:inline;filter:url(#filter4339)" + id="path2997" + sodipodi:cx="8.0433397" + sodipodi:cy="8.1334372" + sodipodi:rx="7.7781744" + sodipodi:ry="7.7781744" + d="m 15.821514,8.1334372 a 7.7781744,7.7781744 0 1 1 -15.55634867,0 7.7781744,7.7781744 0 1 1 15.55634867,0 z" + transform="translate(0,-0.08838835)" /> + </g> + <g + id="layer1" + inkscape:label="Clock" + inkscape:groupmode="layer" + style="display:inline" + sodipodi:insensitive="true"> + <path + transform="matrix(0.91562931,0,0,0.91562931,0.64737218,0.56658541)" + d="m 15.821514,8.1334372 a 7.7781744,7.7781744 0 1 1 -15.55634867,0 7.7781744,7.7781744 0 1 1 15.55634867,0 z" + sodipodi:ry="7.7781744" + sodipodi:rx="7.7781744" + sodipodi:cy="8.1334372" + sodipodi:cx="8.0433397" + id="path4343" + style="fill:url(#linearGradient4345);fill-opacity:1;stroke:none" + sodipodi:type="arc" /> + </g> + <g + inkscape:groupmode="layer" + id="layer5" + inkscape:label="Block" + style="display:inline" + sodipodi:insensitive="true"> + <path + sodipodi:type="arc" + style="fill:url(#linearGradient4471);fill-opacity:1;stroke:none;display:inline" + id="path4462" + sodipodi:cx="8.0433397" + sodipodi:cy="8.1334372" + sodipodi:rx="7.7781744" + sodipodi:ry="7.7781744" + d="M 15.197954,11.184912 A 7.7781744,7.7781744 0 1 1 8.0707322,0.35531099 L 8.0433397,8.1334372 z" + transform="matrix(0.91562931,0,0,0.91562931,0.64737218,0.56658541)" + sodipodi:start="0.4031442" + sodipodi:end="4.7159107" /> + </g> + <g + inkscape:groupmode="layer" + id="layer2" + inkscape:label="Ticks" + style="display:inline" + sodipodi:insensitive="true"> + <path + id="use4309" + transform="matrix(0.77323696,-0.44642857,0.44642857,0.77323696,-1.9715899,5.5529328)" + style="fill:url(#linearGradient4430);fill-opacity:1;stroke:none" + d="M 8.875,2.03125 C 8.875,2.5317581 8.4832492,2.9375 8,2.9375 7.5167508,2.9375 7.125,2.5317581 7.125,2.03125 7.125,1.5307419 7.5167508,1.125 8,1.125 c 0.4832492,0 0.875,0.4057419 0.875,0.90625 z M 5.8484195,2.6358993 C 6.0986735,3.069352 5.9622783,3.6166102 5.5437722,3.8582348 5.1252661,4.0998594 4.583129,3.944352 4.332875,3.5108993 4.082621,3.0774465 4.2190162,2.5301884 4.6375222,2.2885638 5.0560283,2.0469392 5.5981654,2.2024466 5.8484195,2.6358993 z M 3.5296488,4.6728304 C 3.9631015,4.9230844 4.1186089,5.4652215 3.8769843,5.8837276 3.6353597,6.3022337 3.0881015,6.4386289 2.6546488,6.1883748 2.221196,5.9381208 2.0656886,5.3959837 2.3073132,4.9774776 2.5489379,4.5589715 3.096196,4.4225763 3.5296488,4.6728304 z m -0.989649,2.9234201 c 0.5005081,0 0.90625,0.3917508 0.90625,0.875 0,0.4832492 -0.4057419,0.875 -0.90625,0.875 -0.5005081,0 -0.90625,-0.3917508 -0.90625,-0.875 0,-0.4832492 0.4057419,-0.875 0.90625,-0.875 z M 3.144649,10.622831 c 0.4334527,-0.250254 0.9807109,-0.113859 1.2223355,0.304647 0.2416246,0.418506 0.086117,0.960643 -0.3473355,1.210897 C 3.5861963,12.388629 3.0389381,12.252234 2.7973135,11.833728 2.5556889,11.415222 2.7111963,10.873085 3.144649,10.622831 z m 2.036931,2.31877 c 0.2502541,-0.433452 0.7923912,-0.58896 1.2108973,-0.347335 0.4185061,0.241624 0.5549012,0.788883 0.3046472,1.222335 -0.2502541,0.433453 -0.7923912,0.58896 -1.2108972,0.347336 C 5.0677212,13.922312 4.931326,13.375054 5.18158,12.941601 z m 2.9234201,0.989649 c 0,-0.500508 0.3917508,-0.90625 0.875,-0.90625 0.4832492,0 0.875,0.405742 0.875,0.90625 0,0.500509 -0.3917508,0.90625 -0.875,0.90625 -0.4832492,0 -0.875,-0.405741 -0.875,-0.90625 z M 11.13158,13.326601 c -0.250254,-0.433453 -0.113859,-0.980711 0.304647,-1.222335 0.418507,-0.241625 0.960644,-0.08612 1.210898,0.347335 0.250254,0.433453 0.113859,0.980711 -0.304648,1.222336 -0.418506,0.241624 -0.960643,0.08612 -1.210897,-0.347336 z m 2.318771,-2.036931 c -0.433453,-0.250254 -0.58896,-0.792391 -0.347335,-1.210897 0.241624,-0.4185064 0.788882,-0.5549016 1.222335,-0.3046476 0.433453,0.2502536 0.58896,0.7923916 0.347336,1.2108976 -0.241625,0.418506 -0.788883,0.554901 -1.222336,0.304647 z M 14.44,8.36625 c -0.500508,0 -0.90625,-0.3917508 -0.90625,-0.875 0,-0.4832492 0.405742,-0.875 0.90625,-0.875 0.500508,0 0.90625,0.3917508 0.90625,0.875 0,0.4832492 -0.405742,0.875 -0.90625,0.875 z M 13.835351,5.3396697 C 13.401898,5.5899238 12.85464,5.4535286 12.613016,5.0350225 12.371391,4.6165164 12.526898,4.0743793 12.960351,3.8241252 c 0.433453,-0.250254 0.980711,-0.1138588 1.222336,0.3046473 0.241624,0.4185061 0.08612,0.9606432 -0.347336,1.2108972 z M 11.79842,3.0208989 C 11.548166,3.4543516 11.006029,3.609859 10.587523,3.3682344 10.169017,3.1266098 10.032621,2.5793516 10.282875,2.1458989 10.533129,1.7124461 11.075267,1.5569388 11.493773,1.7985634 11.912279,2.040188 12.048674,2.5874462 11.79842,3.0208989 z" + inkscape:connector-curvature="0" /> + <path + style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + d="m 7.875,2.8017767 0,5.25" + id="path4436" + inkscape:connector-curvature="0" /> + <path + style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + d="M 7.7781746,7.4629419 10.783378,7.6397186" + id="path4438" + inkscape:connector-curvature="0" /> + </g> + <g + inkscape:groupmode="layer" + id="layer3" + inkscape:label="Shine" + style="display:inline" + sodipodi:insensitive="true"> + <path + sodipodi:type="arc" + style="fill:url(#radialGradient4440);fill-opacity:1;stroke:none" + id="path4353" + sodipodi:cx="8.0433397" + sodipodi:cy="8.1334372" + sodipodi:rx="7.3686199" + sodipodi:ry="7.4368792" + d="m 15.41196,8.1334372 a 7.3686199,7.4368792 0 1 1 -14.73724019,0 7.3686199,7.4368792 0 1 1 14.73724019,0 z" + transform="matrix(0.91562931,0,0,0.91562931,0.64737218,0.56658541)" /> + </g> +</svg> diff --git a/src/qt/res/src/clock3.svg b/src/qt/res/src/clock3.svg new file mode 100644 index 0000000000..09ccc2549f --- /dev/null +++ b/src/qt/res/src/clock3.svg @@ -0,0 +1,261 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!-- Created with Inkscape (http://www.inkscape.org/) --> + +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + xmlns:xlink="http://www.w3.org/1999/xlink" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + width="16px" + height="16px" + id="svg2987" + version="1.1" + inkscape:version="0.48.0 r9654" + sodipodi:docname="clock1.svg"> + <defs + id="defs2989"> + <linearGradient + id="linearGradient4465"> + <stop + id="stop4467" + offset="0" + style="stop-color:#c1c1c1;stop-opacity:1;" /> + <stop + id="stop4469" + offset="1" + style="stop-color:#8c8c8c;stop-opacity:1;" /> + </linearGradient> + <linearGradient + id="linearGradient4424"> + <stop + style="stop-color:#000000;stop-opacity:1;" + offset="0" + id="stop4426" /> + <stop + style="stop-color:#b3b3b3;stop-opacity:1;" + offset="1" + id="stop4428" /> + </linearGradient> + <linearGradient + id="linearGradient4357"> + <stop + id="stop4359" + offset="0" + style="stop-color:#ffffff;stop-opacity:1;" /> + <stop + style="stop-color:#ffa184;stop-opacity:0.49803922;" + offset="0.36363637" + id="stop4473" /> + <stop + id="stop4361" + offset="1" + style="stop-color:#ff440a;stop-opacity:0;" /> + </linearGradient> + <linearGradient + id="linearGradient4347"> + <stop + id="stop4349" + offset="0" + style="stop-color:#909090;stop-opacity:1;" /> + <stop + id="stop4351" + offset="1" + style="stop-color:#3c3c3c;stop-opacity:1;" /> + </linearGradient> + <linearGradient + id="linearGradient3767"> + <stop + style="stop-color:#ffda82;stop-opacity:1;" + offset="0" + id="stop3769" /> + <stop + style="stop-color:#ffbb19;stop-opacity:1;" + offset="1" + id="stop3771" /> + </linearGradient> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient4347" + id="linearGradient3779" + x1="2.224874" + y1="2.8301363" + x2="14.038582" + y2="13.171574" + gradientUnits="userSpaceOnUse" /> + <filter + inkscape:collect="always" + id="filter4339"> + <feGaussianBlur + inkscape:collect="always" + stdDeviation="0.3240906" + id="feGaussianBlur4341" /> + </filter> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient3767" + id="linearGradient4345" + gradientUnits="userSpaceOnUse" + x1="2.224874" + y1="2.8301363" + x2="14.038582" + y2="13.171574" /> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient4424" + id="linearGradient4430" + x1="10.740074" + y1="16.148634" + x2="6.3055735" + y2="-1.2798394" + gradientUnits="userSpaceOnUse" /> + <radialGradient + inkscape:collect="always" + xlink:href="#linearGradient4357" + id="radialGradient4440" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(1.5712985,0.01074232,-0.01353758,1.9801676,-4.5655476,-0.68355868)" + cx="8.1975746" + cy="-0.080271922" + fx="8.1975746" + fy="-0.080271922" + r="7.7781744" /> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient4465" + id="linearGradient4471" + gradientUnits="userSpaceOnUse" + x1="2.224874" + y1="2.8301363" + x2="14.038582" + y2="13.171574" /> + </defs> + <sodipodi:namedview + id="base" + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1.0" + inkscape:pageopacity="0.0" + inkscape:pageshadow="2" + inkscape:zoom="23.894737" + inkscape:cx="16" + inkscape:cy="-1" + inkscape:current-layer="layer5" + showgrid="true" + inkscape:grid-bbox="true" + inkscape:document-units="px" + inkscape:window-width="1920" + inkscape:window-height="1127" + inkscape:window-x="0" + inkscape:window-y="25" + inkscape:window-maximized="1" + showguides="true" + inkscape:guide-bbox="true" /> + <metadata + id="metadata2992"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + <dc:title></dc:title> + </cc:Work> + </rdf:RDF> + </metadata> + <g + inkscape:groupmode="layer" + id="layer4" + inkscape:label="Shadow" + style="display:inline" + sodipodi:insensitive="true"> + <path + sodipodi:type="arc" + style="fill:url(#linearGradient3779);fill-opacity:1;stroke:none;display:inline;filter:url(#filter4339)" + id="path2997" + sodipodi:cx="8.0433397" + sodipodi:cy="8.1334372" + sodipodi:rx="7.7781744" + sodipodi:ry="7.7781744" + d="m 15.821514,8.1334372 a 7.7781744,7.7781744 0 1 1 -15.55634867,0 7.7781744,7.7781744 0 1 1 15.55634867,0 z" + transform="translate(0,-0.08838835)" /> + </g> + <g + id="layer1" + inkscape:label="Clock" + inkscape:groupmode="layer" + style="display:inline" + sodipodi:insensitive="true"> + <path + transform="matrix(0.91562931,0,0,0.91562931,0.64737218,0.56658541)" + d="m 15.821514,8.1334372 a 7.7781744,7.7781744 0 1 1 -15.55634867,0 7.7781744,7.7781744 0 1 1 15.55634867,0 z" + sodipodi:ry="7.7781744" + sodipodi:rx="7.7781744" + sodipodi:cy="8.1334372" + sodipodi:cx="8.0433397" + id="path4343" + style="fill:url(#linearGradient4345);fill-opacity:1;stroke:none" + sodipodi:type="arc" /> + </g> + <g + inkscape:groupmode="layer" + id="layer5" + inkscape:label="Block" + style="display:inline"> + <path + sodipodi:type="arc" + style="fill:url(#linearGradient4471);fill-opacity:1;stroke:none;display:inline" + id="path4462" + sodipodi:cx="8.0433397" + sodipodi:cy="8.1334372" + sodipodi:rx="7.7781744" + sodipodi:ry="7.7781744" + d="M 8.2135533,15.909749 A 7.7781744,7.7781744 0 1 1 8.0707322,0.35531099 L 8.0433397,8.1334372 z" + transform="matrix(0.91562931,0,0,0.91562931,0.64737218,0.56658541)" + sodipodi:start="1.5489111" + sodipodi:end="4.7159107" /> + </g> + <g + inkscape:groupmode="layer" + id="layer2" + inkscape:label="Ticks" + style="display:inline" + sodipodi:insensitive="true"> + <path + id="use4309" + transform="matrix(0.77323696,-0.44642857,0.44642857,0.77323696,-1.9715899,5.5529328)" + style="fill:url(#linearGradient4430);fill-opacity:1;stroke:none" + d="M 8.875,2.03125 C 8.875,2.5317581 8.4832492,2.9375 8,2.9375 7.5167508,2.9375 7.125,2.5317581 7.125,2.03125 7.125,1.5307419 7.5167508,1.125 8,1.125 c 0.4832492,0 0.875,0.4057419 0.875,0.90625 z M 5.8484195,2.6358993 C 6.0986735,3.069352 5.9622783,3.6166102 5.5437722,3.8582348 5.1252661,4.0998594 4.583129,3.944352 4.332875,3.5108993 4.082621,3.0774465 4.2190162,2.5301884 4.6375222,2.2885638 5.0560283,2.0469392 5.5981654,2.2024466 5.8484195,2.6358993 z M 3.5296488,4.6728304 C 3.9631015,4.9230844 4.1186089,5.4652215 3.8769843,5.8837276 3.6353597,6.3022337 3.0881015,6.4386289 2.6546488,6.1883748 2.221196,5.9381208 2.0656886,5.3959837 2.3073132,4.9774776 2.5489379,4.5589715 3.096196,4.4225763 3.5296488,4.6728304 z m -0.989649,2.9234201 c 0.5005081,0 0.90625,0.3917508 0.90625,0.875 0,0.4832492 -0.4057419,0.875 -0.90625,0.875 -0.5005081,0 -0.90625,-0.3917508 -0.90625,-0.875 0,-0.4832492 0.4057419,-0.875 0.90625,-0.875 z M 3.144649,10.622831 c 0.4334527,-0.250254 0.9807109,-0.113859 1.2223355,0.304647 0.2416246,0.418506 0.086117,0.960643 -0.3473355,1.210897 C 3.5861963,12.388629 3.0389381,12.252234 2.7973135,11.833728 2.5556889,11.415222 2.7111963,10.873085 3.144649,10.622831 z m 2.036931,2.31877 c 0.2502541,-0.433452 0.7923912,-0.58896 1.2108973,-0.347335 0.4185061,0.241624 0.5549012,0.788883 0.3046472,1.222335 -0.2502541,0.433453 -0.7923912,0.58896 -1.2108972,0.347336 C 5.0677212,13.922312 4.931326,13.375054 5.18158,12.941601 z m 2.9234201,0.989649 c 0,-0.500508 0.3917508,-0.90625 0.875,-0.90625 0.4832492,0 0.875,0.405742 0.875,0.90625 0,0.500509 -0.3917508,0.90625 -0.875,0.90625 -0.4832492,0 -0.875,-0.405741 -0.875,-0.90625 z M 11.13158,13.326601 c -0.250254,-0.433453 -0.113859,-0.980711 0.304647,-1.222335 0.418507,-0.241625 0.960644,-0.08612 1.210898,0.347335 0.250254,0.433453 0.113859,0.980711 -0.304648,1.222336 -0.418506,0.241624 -0.960643,0.08612 -1.210897,-0.347336 z m 2.318771,-2.036931 c -0.433453,-0.250254 -0.58896,-0.792391 -0.347335,-1.210897 0.241624,-0.4185064 0.788882,-0.5549016 1.222335,-0.3046476 0.433453,0.2502536 0.58896,0.7923916 0.347336,1.2108976 -0.241625,0.418506 -0.788883,0.554901 -1.222336,0.304647 z M 14.44,8.36625 c -0.500508,0 -0.90625,-0.3917508 -0.90625,-0.875 0,-0.4832492 0.405742,-0.875 0.90625,-0.875 0.500508,0 0.90625,0.3917508 0.90625,0.875 0,0.4832492 -0.405742,0.875 -0.90625,0.875 z M 13.835351,5.3396697 C 13.401898,5.5899238 12.85464,5.4535286 12.613016,5.0350225 12.371391,4.6165164 12.526898,4.0743793 12.960351,3.8241252 c 0.433453,-0.250254 0.980711,-0.1138588 1.222336,0.3046473 0.241624,0.4185061 0.08612,0.9606432 -0.347336,1.2108972 z M 11.79842,3.0208989 C 11.548166,3.4543516 11.006029,3.609859 10.587523,3.3682344 10.169017,3.1266098 10.032621,2.5793516 10.282875,2.1458989 10.533129,1.7124461 11.075267,1.5569388 11.493773,1.7985634 11.912279,2.040188 12.048674,2.5874462 11.79842,3.0208989 z" + inkscape:connector-curvature="0" /> + <path + style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + d="m 7.875,2.8017767 0,5.25" + id="path4436" + inkscape:connector-curvature="0" /> + <path + style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + d="M 7.7781746,7.4629419 10.783378,7.6397186" + id="path4438" + inkscape:connector-curvature="0" /> + </g> + <g + inkscape:groupmode="layer" + id="layer3" + inkscape:label="Shine" + style="display:inline" + sodipodi:insensitive="true"> + <path + sodipodi:type="arc" + style="fill:url(#radialGradient4440);fill-opacity:1;stroke:none" + id="path4353" + sodipodi:cx="8.0433397" + sodipodi:cy="8.1334372" + sodipodi:rx="7.3686199" + sodipodi:ry="7.4368792" + d="m 15.41196,8.1334372 a 7.3686199,7.4368792 0 1 1 -14.73724019,0 7.3686199,7.4368792 0 1 1 14.73724019,0 z" + transform="matrix(0.91562931,0,0,0.91562931,0.64737218,0.56658541)" /> + </g> +</svg> diff --git a/src/qt/res/src/clock4.svg b/src/qt/res/src/clock4.svg new file mode 100644 index 0000000000..7d9dc37acb --- /dev/null +++ b/src/qt/res/src/clock4.svg @@ -0,0 +1,261 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!-- Created with Inkscape (http://www.inkscape.org/) --> + +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + xmlns:xlink="http://www.w3.org/1999/xlink" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + width="16px" + height="16px" + id="svg2987" + version="1.1" + inkscape:version="0.48.0 r9654" + sodipodi:docname="clock2.svg"> + <defs + id="defs2989"> + <linearGradient + id="linearGradient4465"> + <stop + id="stop4467" + offset="0" + style="stop-color:#c1c1c1;stop-opacity:1;" /> + <stop + id="stop4469" + offset="1" + style="stop-color:#8c8c8c;stop-opacity:1;" /> + </linearGradient> + <linearGradient + id="linearGradient4424"> + <stop + style="stop-color:#000000;stop-opacity:1;" + offset="0" + id="stop4426" /> + <stop + style="stop-color:#b3b3b3;stop-opacity:1;" + offset="1" + id="stop4428" /> + </linearGradient> + <linearGradient + id="linearGradient4357"> + <stop + id="stop4359" + offset="0" + style="stop-color:#ffffff;stop-opacity:1;" /> + <stop + style="stop-color:#ffcc84;stop-opacity:0.49803922;" + offset="0.36363637" + id="stop4473" /> + <stop + id="stop4361" + offset="1" + style="stop-color:#ff9a0a;stop-opacity:0;" /> + </linearGradient> + <linearGradient + id="linearGradient4347"> + <stop + id="stop4349" + offset="0" + style="stop-color:#909090;stop-opacity:1;" /> + <stop + id="stop4351" + offset="1" + style="stop-color:#3c3c3c;stop-opacity:1;" /> + </linearGradient> + <linearGradient + id="linearGradient3767"> + <stop + style="stop-color:#f8ff82;stop-opacity:1;" + offset="0" + id="stop3769" /> + <stop + style="stop-color:#f1ff19;stop-opacity:1;" + offset="1" + id="stop3771" /> + </linearGradient> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient4347" + id="linearGradient3779" + x1="2.224874" + y1="2.8301363" + x2="14.038582" + y2="13.171574" + gradientUnits="userSpaceOnUse" /> + <filter + inkscape:collect="always" + id="filter4339"> + <feGaussianBlur + inkscape:collect="always" + stdDeviation="0.3240906" + id="feGaussianBlur4341" /> + </filter> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient3767" + id="linearGradient4345" + gradientUnits="userSpaceOnUse" + x1="2.224874" + y1="2.8301363" + x2="14.038582" + y2="13.171574" /> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient4424" + id="linearGradient4430" + x1="10.740074" + y1="16.148634" + x2="6.3055735" + y2="-1.2798394" + gradientUnits="userSpaceOnUse" /> + <radialGradient + inkscape:collect="always" + xlink:href="#linearGradient4357" + id="radialGradient4440" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(1.5712985,0.01074232,-0.01353758,1.9801676,-4.5655476,-0.68355868)" + cx="8.1975746" + cy="-0.080271922" + fx="8.1975746" + fy="-0.080271922" + r="7.7781744" /> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient4465" + id="linearGradient4471" + gradientUnits="userSpaceOnUse" + x1="2.224874" + y1="2.8301363" + x2="14.038582" + y2="13.171574" /> + </defs> + <sodipodi:namedview + id="base" + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1.0" + inkscape:pageopacity="0.0" + inkscape:pageshadow="2" + inkscape:zoom="16" + inkscape:cx="8.6111742" + inkscape:cy="6.6684704" + inkscape:current-layer="layer5" + showgrid="true" + inkscape:grid-bbox="true" + inkscape:document-units="px" + inkscape:window-width="1920" + inkscape:window-height="1127" + inkscape:window-x="0" + inkscape:window-y="25" + inkscape:window-maximized="1" + showguides="true" + inkscape:guide-bbox="true" /> + <metadata + id="metadata2992"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + <dc:title></dc:title> + </cc:Work> + </rdf:RDF> + </metadata> + <g + inkscape:groupmode="layer" + id="layer4" + inkscape:label="Shadow" + style="display:inline" + sodipodi:insensitive="true"> + <path + sodipodi:type="arc" + style="fill:url(#linearGradient3779);fill-opacity:1;stroke:none;display:inline;filter:url(#filter4339)" + id="path2997" + sodipodi:cx="8.0433397" + sodipodi:cy="8.1334372" + sodipodi:rx="7.7781744" + sodipodi:ry="7.7781744" + d="m 15.821514,8.1334372 a 7.7781744,7.7781744 0 1 1 -15.55634867,0 7.7781744,7.7781744 0 1 1 15.55634867,0 z" + transform="translate(0,-0.08838835)" /> + </g> + <g + id="layer1" + inkscape:label="Clock" + inkscape:groupmode="layer" + style="display:inline" + sodipodi:insensitive="true"> + <path + transform="matrix(0.91562931,0,0,0.91562931,0.64737218,0.56658541)" + d="m 15.821514,8.1334372 a 7.7781744,7.7781744 0 1 1 -15.55634867,0 7.7781744,7.7781744 0 1 1 15.55634867,0 z" + sodipodi:ry="7.7781744" + sodipodi:rx="7.7781744" + sodipodi:cy="8.1334372" + sodipodi:cx="8.0433397" + id="path4343" + style="fill:url(#linearGradient4345);fill-opacity:1;stroke:none" + sodipodi:type="arc" /> + </g> + <g + inkscape:groupmode="layer" + id="layer5" + inkscape:label="Block" + style="display:inline"> + <path + sodipodi:type="arc" + style="fill:url(#linearGradient4471);fill-opacity:1;stroke:none;display:inline" + id="path4462" + sodipodi:cx="8.0433397" + sodipodi:cy="8.1334372" + sodipodi:rx="7.7781744" + sodipodi:ry="7.7781744" + d="M 1.7005474,12.635546 A 7.7781744,7.7781744 0 0 1 8.0707322,0.35531099 L 8.0433397,8.1334372 z" + transform="matrix(0.91562931,0,0,0.91562931,0.64737218,0.56658541)" + sodipodi:start="2.5243203" + sodipodi:end="4.7159107" /> + </g> + <g + inkscape:groupmode="layer" + id="layer2" + inkscape:label="Ticks" + style="display:inline" + sodipodi:insensitive="true"> + <path + id="use4309" + transform="matrix(0.77323696,-0.44642857,0.44642857,0.77323696,-1.9715899,5.5529328)" + style="fill:url(#linearGradient4430);fill-opacity:1;stroke:none" + d="M 8.875,2.03125 C 8.875,2.5317581 8.4832492,2.9375 8,2.9375 7.5167508,2.9375 7.125,2.5317581 7.125,2.03125 7.125,1.5307419 7.5167508,1.125 8,1.125 c 0.4832492,0 0.875,0.4057419 0.875,0.90625 z M 5.8484195,2.6358993 C 6.0986735,3.069352 5.9622783,3.6166102 5.5437722,3.8582348 5.1252661,4.0998594 4.583129,3.944352 4.332875,3.5108993 4.082621,3.0774465 4.2190162,2.5301884 4.6375222,2.2885638 5.0560283,2.0469392 5.5981654,2.2024466 5.8484195,2.6358993 z M 3.5296488,4.6728304 C 3.9631015,4.9230844 4.1186089,5.4652215 3.8769843,5.8837276 3.6353597,6.3022337 3.0881015,6.4386289 2.6546488,6.1883748 2.221196,5.9381208 2.0656886,5.3959837 2.3073132,4.9774776 2.5489379,4.5589715 3.096196,4.4225763 3.5296488,4.6728304 z m -0.989649,2.9234201 c 0.5005081,0 0.90625,0.3917508 0.90625,0.875 0,0.4832492 -0.4057419,0.875 -0.90625,0.875 -0.5005081,0 -0.90625,-0.3917508 -0.90625,-0.875 0,-0.4832492 0.4057419,-0.875 0.90625,-0.875 z M 3.144649,10.622831 c 0.4334527,-0.250254 0.9807109,-0.113859 1.2223355,0.304647 0.2416246,0.418506 0.086117,0.960643 -0.3473355,1.210897 C 3.5861963,12.388629 3.0389381,12.252234 2.7973135,11.833728 2.5556889,11.415222 2.7111963,10.873085 3.144649,10.622831 z m 2.036931,2.31877 c 0.2502541,-0.433452 0.7923912,-0.58896 1.2108973,-0.347335 0.4185061,0.241624 0.5549012,0.788883 0.3046472,1.222335 -0.2502541,0.433453 -0.7923912,0.58896 -1.2108972,0.347336 C 5.0677212,13.922312 4.931326,13.375054 5.18158,12.941601 z m 2.9234201,0.989649 c 0,-0.500508 0.3917508,-0.90625 0.875,-0.90625 0.4832492,0 0.875,0.405742 0.875,0.90625 0,0.500509 -0.3917508,0.90625 -0.875,0.90625 -0.4832492,0 -0.875,-0.405741 -0.875,-0.90625 z M 11.13158,13.326601 c -0.250254,-0.433453 -0.113859,-0.980711 0.304647,-1.222335 0.418507,-0.241625 0.960644,-0.08612 1.210898,0.347335 0.250254,0.433453 0.113859,0.980711 -0.304648,1.222336 -0.418506,0.241624 -0.960643,0.08612 -1.210897,-0.347336 z m 2.318771,-2.036931 c -0.433453,-0.250254 -0.58896,-0.792391 -0.347335,-1.210897 0.241624,-0.4185064 0.788882,-0.5549016 1.222335,-0.3046476 0.433453,0.2502536 0.58896,0.7923916 0.347336,1.2108976 -0.241625,0.418506 -0.788883,0.554901 -1.222336,0.304647 z M 14.44,8.36625 c -0.500508,0 -0.90625,-0.3917508 -0.90625,-0.875 0,-0.4832492 0.405742,-0.875 0.90625,-0.875 0.500508,0 0.90625,0.3917508 0.90625,0.875 0,0.4832492 -0.405742,0.875 -0.90625,0.875 z M 13.835351,5.3396697 C 13.401898,5.5899238 12.85464,5.4535286 12.613016,5.0350225 12.371391,4.6165164 12.526898,4.0743793 12.960351,3.8241252 c 0.433453,-0.250254 0.980711,-0.1138588 1.222336,0.3046473 0.241624,0.4185061 0.08612,0.9606432 -0.347336,1.2108972 z M 11.79842,3.0208989 C 11.548166,3.4543516 11.006029,3.609859 10.587523,3.3682344 10.169017,3.1266098 10.032621,2.5793516 10.282875,2.1458989 10.533129,1.7124461 11.075267,1.5569388 11.493773,1.7985634 11.912279,2.040188 12.048674,2.5874462 11.79842,3.0208989 z" + inkscape:connector-curvature="0" /> + <path + style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + d="m 7.875,2.8017767 0,5.25" + id="path4436" + inkscape:connector-curvature="0" /> + <path + style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + d="M 7.7781746,7.4629419 10.783378,7.6397186" + id="path4438" + inkscape:connector-curvature="0" /> + </g> + <g + inkscape:groupmode="layer" + id="layer3" + inkscape:label="Shine" + style="display:inline" + sodipodi:insensitive="true"> + <path + sodipodi:type="arc" + style="fill:url(#radialGradient4440);fill-opacity:1;stroke:none" + id="path4353" + sodipodi:cx="8.0433397" + sodipodi:cy="8.1334372" + sodipodi:rx="7.3686199" + sodipodi:ry="7.4368792" + d="m 15.41196,8.1334372 a 7.3686199,7.4368792 0 1 1 -14.73724019,0 7.3686199,7.4368792 0 1 1 14.73724019,0 z" + transform="matrix(0.91562931,0,0,0.91562931,0.64737218,0.56658541)" /> + </g> +</svg> diff --git a/src/qt/res/src/clock5.svg b/src/qt/res/src/clock5.svg new file mode 100644 index 0000000000..9fd58d9d97 --- /dev/null +++ b/src/qt/res/src/clock5.svg @@ -0,0 +1,262 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!-- Created with Inkscape (http://www.inkscape.org/) --> + +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + xmlns:xlink="http://www.w3.org/1999/xlink" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + width="16px" + height="16px" + id="svg2987" + version="1.1" + inkscape:version="0.48.0 r9654" + sodipodi:docname="clock3.svg"> + <defs + id="defs2989"> + <linearGradient + id="linearGradient4465"> + <stop + id="stop4467" + offset="0" + style="stop-color:#c1c1c1;stop-opacity:1;" /> + <stop + id="stop4469" + offset="1" + style="stop-color:#8c8c8c;stop-opacity:1;" /> + </linearGradient> + <linearGradient + id="linearGradient4424"> + <stop + style="stop-color:#000000;stop-opacity:1;" + offset="0" + id="stop4426" /> + <stop + style="stop-color:#b3b3b3;stop-opacity:1;" + offset="1" + id="stop4428" /> + </linearGradient> + <linearGradient + id="linearGradient4357"> + <stop + id="stop4359" + offset="0" + style="stop-color:#ffffff;stop-opacity:1;" /> + <stop + style="stop-color:#fff884;stop-opacity:0.49803922;" + offset="0.36363637" + id="stop4473" /> + <stop + id="stop4361" + offset="1" + style="stop-color:#fff10a;stop-opacity:0;" /> + </linearGradient> + <linearGradient + id="linearGradient4347"> + <stop + id="stop4349" + offset="0" + style="stop-color:#909090;stop-opacity:1;" /> + <stop + id="stop4351" + offset="1" + style="stop-color:#3c3c3c;stop-opacity:1;" /> + </linearGradient> + <linearGradient + id="linearGradient3767"> + <stop + style="stop-color:#ccff82;stop-opacity:1;" + offset="0" + id="stop3769" /> + <stop + style="stop-color:#a0ff19;stop-opacity:1;" + offset="1" + id="stop3771" /> + </linearGradient> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient4347" + id="linearGradient3779" + x1="2.224874" + y1="2.8301363" + x2="14.038582" + y2="13.171574" + gradientUnits="userSpaceOnUse" /> + <filter + inkscape:collect="always" + id="filter4339"> + <feGaussianBlur + inkscape:collect="always" + stdDeviation="0.3240906" + id="feGaussianBlur4341" /> + </filter> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient3767" + id="linearGradient4345" + gradientUnits="userSpaceOnUse" + x1="2.224874" + y1="2.8301363" + x2="14.038582" + y2="13.171574" /> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient4424" + id="linearGradient4430" + x1="10.740074" + y1="16.148634" + x2="6.3055735" + y2="-1.2798394" + gradientUnits="userSpaceOnUse" /> + <radialGradient + inkscape:collect="always" + xlink:href="#linearGradient4357" + id="radialGradient4440" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(1.5712985,0.01074232,-0.01353758,1.9801676,-4.5655476,-0.68355868)" + cx="8.1975746" + cy="-0.080271922" + fx="8.1975746" + fy="-0.080271922" + r="7.7781744" /> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient4465" + id="linearGradient4471" + gradientUnits="userSpaceOnUse" + x1="2.224874" + y1="2.8301363" + x2="14.038582" + y2="13.171574" /> + </defs> + <sodipodi:namedview + id="base" + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1.0" + inkscape:pageopacity="0.0" + inkscape:pageshadow="2" + inkscape:zoom="16" + inkscape:cx="8.6111742" + inkscape:cy="6.6684704" + inkscape:current-layer="layer3" + showgrid="true" + inkscape:grid-bbox="true" + inkscape:document-units="px" + inkscape:window-width="1920" + inkscape:window-height="1127" + inkscape:window-x="0" + inkscape:window-y="25" + inkscape:window-maximized="1" + showguides="true" + inkscape:guide-bbox="true" /> + <metadata + id="metadata2992"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + <dc:title></dc:title> + </cc:Work> + </rdf:RDF> + </metadata> + <g + inkscape:groupmode="layer" + id="layer4" + inkscape:label="Shadow" + style="display:inline" + sodipodi:insensitive="true"> + <path + sodipodi:type="arc" + style="fill:url(#linearGradient3779);fill-opacity:1;stroke:none;display:inline;filter:url(#filter4339)" + id="path2997" + sodipodi:cx="8.0433397" + sodipodi:cy="8.1334372" + sodipodi:rx="7.7781744" + sodipodi:ry="7.7781744" + d="m 15.821514,8.1334372 a 7.7781744,7.7781744 0 1 1 -15.55634867,0 7.7781744,7.7781744 0 1 1 15.55634867,0 z" + transform="translate(0,-0.08838835)" /> + </g> + <g + id="layer1" + inkscape:label="Clock" + inkscape:groupmode="layer" + style="display:inline" + sodipodi:insensitive="true"> + <path + transform="matrix(0.91562931,0,0,0.91562931,0.64737218,0.56658541)" + d="m 15.821514,8.1334372 a 7.7781744,7.7781744 0 1 1 -15.55634867,0 7.7781744,7.7781744 0 1 1 15.55634867,0 z" + sodipodi:ry="7.7781744" + sodipodi:rx="7.7781744" + sodipodi:cy="8.1334372" + sodipodi:cx="8.0433397" + id="path4343" + style="fill:url(#linearGradient4345);fill-opacity:1;stroke:none" + sodipodi:type="arc" /> + </g> + <g + inkscape:groupmode="layer" + id="layer5" + inkscape:label="Block" + style="display:inline" + sodipodi:insensitive="true"> + <path + sodipodi:type="arc" + style="fill:url(#linearGradient4471);fill-opacity:1;stroke:none;display:inline" + id="path4462" + sodipodi:cx="8.0433397" + sodipodi:cy="8.1334372" + sodipodi:rx="7.7781744" + sodipodi:ry="7.7781744" + d="M 1.0968082,4.6340519 A 7.7781744,7.7781744 0 0 1 8.0707322,0.35531099 L 8.0433397,8.1334372 z" + transform="matrix(0.91562931,0,0,0.91562931,0.64737218,0.56658541)" + sodipodi:start="3.6082438" + sodipodi:end="4.7159107" /> + </g> + <g + inkscape:groupmode="layer" + id="layer2" + inkscape:label="Ticks" + style="display:inline" + sodipodi:insensitive="true"> + <path + id="use4309" + transform="matrix(0.77323696,-0.44642857,0.44642857,0.77323696,-1.9715899,5.5529328)" + style="fill:url(#linearGradient4430);fill-opacity:1;stroke:none" + d="M 8.875,2.03125 C 8.875,2.5317581 8.4832492,2.9375 8,2.9375 7.5167508,2.9375 7.125,2.5317581 7.125,2.03125 7.125,1.5307419 7.5167508,1.125 8,1.125 c 0.4832492,0 0.875,0.4057419 0.875,0.90625 z M 5.8484195,2.6358993 C 6.0986735,3.069352 5.9622783,3.6166102 5.5437722,3.8582348 5.1252661,4.0998594 4.583129,3.944352 4.332875,3.5108993 4.082621,3.0774465 4.2190162,2.5301884 4.6375222,2.2885638 5.0560283,2.0469392 5.5981654,2.2024466 5.8484195,2.6358993 z M 3.5296488,4.6728304 C 3.9631015,4.9230844 4.1186089,5.4652215 3.8769843,5.8837276 3.6353597,6.3022337 3.0881015,6.4386289 2.6546488,6.1883748 2.221196,5.9381208 2.0656886,5.3959837 2.3073132,4.9774776 2.5489379,4.5589715 3.096196,4.4225763 3.5296488,4.6728304 z m -0.989649,2.9234201 c 0.5005081,0 0.90625,0.3917508 0.90625,0.875 0,0.4832492 -0.4057419,0.875 -0.90625,0.875 -0.5005081,0 -0.90625,-0.3917508 -0.90625,-0.875 0,-0.4832492 0.4057419,-0.875 0.90625,-0.875 z M 3.144649,10.622831 c 0.4334527,-0.250254 0.9807109,-0.113859 1.2223355,0.304647 0.2416246,0.418506 0.086117,0.960643 -0.3473355,1.210897 C 3.5861963,12.388629 3.0389381,12.252234 2.7973135,11.833728 2.5556889,11.415222 2.7111963,10.873085 3.144649,10.622831 z m 2.036931,2.31877 c 0.2502541,-0.433452 0.7923912,-0.58896 1.2108973,-0.347335 0.4185061,0.241624 0.5549012,0.788883 0.3046472,1.222335 -0.2502541,0.433453 -0.7923912,0.58896 -1.2108972,0.347336 C 5.0677212,13.922312 4.931326,13.375054 5.18158,12.941601 z m 2.9234201,0.989649 c 0,-0.500508 0.3917508,-0.90625 0.875,-0.90625 0.4832492,0 0.875,0.405742 0.875,0.90625 0,0.500509 -0.3917508,0.90625 -0.875,0.90625 -0.4832492,0 -0.875,-0.405741 -0.875,-0.90625 z M 11.13158,13.326601 c -0.250254,-0.433453 -0.113859,-0.980711 0.304647,-1.222335 0.418507,-0.241625 0.960644,-0.08612 1.210898,0.347335 0.250254,0.433453 0.113859,0.980711 -0.304648,1.222336 -0.418506,0.241624 -0.960643,0.08612 -1.210897,-0.347336 z m 2.318771,-2.036931 c -0.433453,-0.250254 -0.58896,-0.792391 -0.347335,-1.210897 0.241624,-0.4185064 0.788882,-0.5549016 1.222335,-0.3046476 0.433453,0.2502536 0.58896,0.7923916 0.347336,1.2108976 -0.241625,0.418506 -0.788883,0.554901 -1.222336,0.304647 z M 14.44,8.36625 c -0.500508,0 -0.90625,-0.3917508 -0.90625,-0.875 0,-0.4832492 0.405742,-0.875 0.90625,-0.875 0.500508,0 0.90625,0.3917508 0.90625,0.875 0,0.4832492 -0.405742,0.875 -0.90625,0.875 z M 13.835351,5.3396697 C 13.401898,5.5899238 12.85464,5.4535286 12.613016,5.0350225 12.371391,4.6165164 12.526898,4.0743793 12.960351,3.8241252 c 0.433453,-0.250254 0.980711,-0.1138588 1.222336,0.3046473 0.241624,0.4185061 0.08612,0.9606432 -0.347336,1.2108972 z M 11.79842,3.0208989 C 11.548166,3.4543516 11.006029,3.609859 10.587523,3.3682344 10.169017,3.1266098 10.032621,2.5793516 10.282875,2.1458989 10.533129,1.7124461 11.075267,1.5569388 11.493773,1.7985634 11.912279,2.040188 12.048674,2.5874462 11.79842,3.0208989 z" + inkscape:connector-curvature="0" /> + <path + style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + d="m 7.875,2.8017767 0,5.25" + id="path4436" + inkscape:connector-curvature="0" /> + <path + style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + d="M 7.7781746,7.4629419 10.783378,7.6397186" + id="path4438" + inkscape:connector-curvature="0" /> + </g> + <g + inkscape:groupmode="layer" + id="layer3" + inkscape:label="Shine" + style="display:inline" + sodipodi:insensitive="true"> + <path + sodipodi:type="arc" + style="fill:url(#radialGradient4440);fill-opacity:1;stroke:none" + id="path4353" + sodipodi:cx="8.0433397" + sodipodi:cy="8.1334372" + sodipodi:rx="7.3686199" + sodipodi:ry="7.4368792" + d="m 15.41196,8.1334372 a 7.3686199,7.4368792 0 1 1 -14.73724019,0 7.3686199,7.4368792 0 1 1 14.73724019,0 z" + transform="matrix(0.91562931,0,0,0.91562931,0.64737218,0.56658541)" /> + </g> +</svg> diff --git a/src/qt/res/src/clock_green.svg b/src/qt/res/src/clock_green.svg new file mode 100644 index 0000000000..e31f0e7995 --- /dev/null +++ b/src/qt/res/src/clock_green.svg @@ -0,0 +1,262 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!-- Created with Inkscape (http://www.inkscape.org/) --> + +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + xmlns:xlink="http://www.w3.org/1999/xlink" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + width="16px" + height="16px" + id="svg2987" + version="1.1" + inkscape:version="0.48.0 r9654" + sodipodi:docname="clock_green.svg"> + <defs + id="defs2989"> + <linearGradient + id="linearGradient4465"> + <stop + id="stop4467" + offset="0" + style="stop-color:#c1c1c1;stop-opacity:1;" /> + <stop + id="stop4469" + offset="1" + style="stop-color:#8c8c8c;stop-opacity:1;" /> + </linearGradient> + <linearGradient + id="linearGradient4424"> + <stop + style="stop-color:#000000;stop-opacity:1;" + offset="0" + id="stop4426" /> + <stop + style="stop-color:#b3b3b3;stop-opacity:1;" + offset="1" + id="stop4428" /> + </linearGradient> + <linearGradient + id="linearGradient4357"> + <stop + id="stop4359" + offset="0" + style="stop-color:#ffffff;stop-opacity:1;" /> + <stop + style="stop-color:#baff84;stop-opacity:0.49803922;" + offset="0.36363637" + id="stop4473" /> + <stop + id="stop4361" + offset="1" + style="stop-color:#76ff0a;stop-opacity:0;" /> + </linearGradient> + <linearGradient + id="linearGradient4347"> + <stop + id="stop4349" + offset="0" + style="stop-color:#c1c1c1;stop-opacity:1;" /> + <stop + id="stop4351" + offset="1" + style="stop-color:#8c8c8c;stop-opacity:1;" /> + </linearGradient> + <linearGradient + id="linearGradient3767"> + <stop + style="stop-color:#82ff82;stop-opacity:1;" + offset="0" + id="stop3769" /> + <stop + style="stop-color:#19ff19;stop-opacity:1;" + offset="1" + id="stop3771" /> + </linearGradient> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient4347" + id="linearGradient3779" + x1="2.224874" + y1="2.8301363" + x2="14.038582" + y2="13.171574" + gradientUnits="userSpaceOnUse" /> + <filter + inkscape:collect="always" + id="filter4339"> + <feGaussianBlur + inkscape:collect="always" + stdDeviation="0.3240906" + id="feGaussianBlur4341" /> + </filter> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient3767" + id="linearGradient4345" + gradientUnits="userSpaceOnUse" + x1="2.224874" + y1="2.8301363" + x2="14.038582" + y2="13.171574" /> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient4424" + id="linearGradient4430" + x1="10.740074" + y1="16.148634" + x2="6.3055735" + y2="-1.2798394" + gradientUnits="userSpaceOnUse" /> + <radialGradient + inkscape:collect="always" + xlink:href="#linearGradient4357" + id="radialGradient4440" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(1.5712985,0.01074232,-0.01353758,1.9801676,-4.5655476,-0.68355868)" + cx="8.1975746" + cy="-0.080271922" + fx="8.1975746" + fy="-0.080271922" + r="7.7781744" /> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient4465" + id="linearGradient4471" + gradientUnits="userSpaceOnUse" + x1="2.224874" + y1="2.8301363" + x2="14.038582" + y2="13.171574" /> + </defs> + <sodipodi:namedview + id="base" + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1.0" + inkscape:pageopacity="0.0" + inkscape:pageshadow="2" + inkscape:zoom="8" + inkscape:cx="9.1870806" + inkscape:cy="14.089546" + inkscape:current-layer="layer3" + showgrid="true" + inkscape:grid-bbox="true" + inkscape:document-units="px" + inkscape:window-width="1920" + inkscape:window-height="1127" + inkscape:window-x="0" + inkscape:window-y="25" + inkscape:window-maximized="1" + showguides="true" + inkscape:guide-bbox="true" /> + <metadata + id="metadata2992"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + <dc:title></dc:title> + </cc:Work> + </rdf:RDF> + </metadata> + <g + inkscape:groupmode="layer" + id="layer4" + inkscape:label="Shadow" + style="display:inline" + sodipodi:insensitive="true"> + <path + sodipodi:type="arc" + style="fill:url(#linearGradient3779);fill-opacity:1;stroke:none;display:inline;filter:url(#filter4339)" + id="path2997" + sodipodi:cx="8.0433397" + sodipodi:cy="8.1334372" + sodipodi:rx="7.7781744" + sodipodi:ry="7.7781744" + d="m 15.821514,8.1334372 a 7.7781744,7.7781744 0 1 1 -15.55634867,0 7.7781744,7.7781744 0 1 1 15.55634867,0 z" + transform="translate(0,-0.08838835)" /> + </g> + <g + id="layer1" + inkscape:label="Clock" + inkscape:groupmode="layer" + style="display:inline" + sodipodi:insensitive="true"> + <path + transform="matrix(0.91562931,0,0,0.91562931,0.64737218,0.56658541)" + d="m 15.821514,8.1334372 a 7.7781744,7.7781744 0 1 1 -15.55634867,0 7.7781744,7.7781744 0 1 1 15.55634867,0 z" + sodipodi:ry="7.7781744" + sodipodi:rx="7.7781744" + sodipodi:cy="8.1334372" + sodipodi:cx="8.0433397" + id="path4343" + style="fill:url(#linearGradient4345);fill-opacity:1;stroke:none" + sodipodi:type="arc" /> + </g> + <g + inkscape:groupmode="layer" + id="layer5" + inkscape:label="Block" + sodipodi:insensitive="true" + style="display:inline"> + <path + sodipodi:type="arc" + style="fill:url(#linearGradient4471);fill-opacity:1;stroke:none;display:inline" + id="path4462" + sodipodi:cx="8.0433397" + sodipodi:cy="8.1334372" + sodipodi:rx="7.7781744" + sodipodi:ry="7.7781744" + d="M 14.4287,3.6919089 A 7.7781744,7.7781744 0 1 1 8.0707322,0.35531099 L 8.0433397,8.1334372 z" + transform="matrix(0.91562931,0,0,0.91562931,0.64737218,0.56658541)" + sodipodi:start="5.675432" + sodipodi:end="10.999096" /> + </g> + <g + inkscape:groupmode="layer" + id="layer2" + inkscape:label="Ticks" + style="display:inline" + sodipodi:insensitive="true"> + <path + id="use4309" + transform="matrix(0.77323696,-0.44642857,0.44642857,0.77323696,-1.9715899,5.5529328)" + style="fill:url(#linearGradient4430);fill-opacity:1;stroke:none" + d="M 8.875,2.03125 C 8.875,2.5317581 8.4832492,2.9375 8,2.9375 7.5167508,2.9375 7.125,2.5317581 7.125,2.03125 7.125,1.5307419 7.5167508,1.125 8,1.125 c 0.4832492,0 0.875,0.4057419 0.875,0.90625 z M 5.8484195,2.6358993 C 6.0986735,3.069352 5.9622783,3.6166102 5.5437722,3.8582348 5.1252661,4.0998594 4.583129,3.944352 4.332875,3.5108993 4.082621,3.0774465 4.2190162,2.5301884 4.6375222,2.2885638 5.0560283,2.0469392 5.5981654,2.2024466 5.8484195,2.6358993 z M 3.5296488,4.6728304 C 3.9631015,4.9230844 4.1186089,5.4652215 3.8769843,5.8837276 3.6353597,6.3022337 3.0881015,6.4386289 2.6546488,6.1883748 2.221196,5.9381208 2.0656886,5.3959837 2.3073132,4.9774776 2.5489379,4.5589715 3.096196,4.4225763 3.5296488,4.6728304 z m -0.989649,2.9234201 c 0.5005081,0 0.90625,0.3917508 0.90625,0.875 0,0.4832492 -0.4057419,0.875 -0.90625,0.875 -0.5005081,0 -0.90625,-0.3917508 -0.90625,-0.875 0,-0.4832492 0.4057419,-0.875 0.90625,-0.875 z M 3.144649,10.622831 c 0.4334527,-0.250254 0.9807109,-0.113859 1.2223355,0.304647 0.2416246,0.418506 0.086117,0.960643 -0.3473355,1.210897 C 3.5861963,12.388629 3.0389381,12.252234 2.7973135,11.833728 2.5556889,11.415222 2.7111963,10.873085 3.144649,10.622831 z m 2.036931,2.31877 c 0.2502541,-0.433452 0.7923912,-0.58896 1.2108973,-0.347335 0.4185061,0.241624 0.5549012,0.788883 0.3046472,1.222335 -0.2502541,0.433453 -0.7923912,0.58896 -1.2108972,0.347336 C 5.0677212,13.922312 4.931326,13.375054 5.18158,12.941601 z m 2.9234201,0.989649 c 0,-0.500508 0.3917508,-0.90625 0.875,-0.90625 0.4832492,0 0.875,0.405742 0.875,0.90625 0,0.500509 -0.3917508,0.90625 -0.875,0.90625 -0.4832492,0 -0.875,-0.405741 -0.875,-0.90625 z M 11.13158,13.326601 c -0.250254,-0.433453 -0.113859,-0.980711 0.304647,-1.222335 0.418507,-0.241625 0.960644,-0.08612 1.210898,0.347335 0.250254,0.433453 0.113859,0.980711 -0.304648,1.222336 -0.418506,0.241624 -0.960643,0.08612 -1.210897,-0.347336 z m 2.318771,-2.036931 c -0.433453,-0.250254 -0.58896,-0.792391 -0.347335,-1.210897 0.241624,-0.4185064 0.788882,-0.5549016 1.222335,-0.3046476 0.433453,0.2502536 0.58896,0.7923916 0.347336,1.2108976 -0.241625,0.418506 -0.788883,0.554901 -1.222336,0.304647 z M 14.44,8.36625 c -0.500508,0 -0.90625,-0.3917508 -0.90625,-0.875 0,-0.4832492 0.405742,-0.875 0.90625,-0.875 0.500508,0 0.90625,0.3917508 0.90625,0.875 0,0.4832492 -0.405742,0.875 -0.90625,0.875 z M 13.835351,5.3396697 C 13.401898,5.5899238 12.85464,5.4535286 12.613016,5.0350225 12.371391,4.6165164 12.526898,4.0743793 12.960351,3.8241252 c 0.433453,-0.250254 0.980711,-0.1138588 1.222336,0.3046473 0.241624,0.4185061 0.08612,0.9606432 -0.347336,1.2108972 z M 11.79842,3.0208989 C 11.548166,3.4543516 11.006029,3.609859 10.587523,3.3682344 10.169017,3.1266098 10.032621,2.5793516 10.282875,2.1458989 10.533129,1.7124461 11.075267,1.5569388 11.493773,1.7985634 11.912279,2.040188 12.048674,2.5874462 11.79842,3.0208989 z" + inkscape:connector-curvature="0" /> + <path + style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + d="m 7.875,2.8017767 0,5.25" + id="path4436" + inkscape:connector-curvature="0" /> + <path + style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + d="M 7.7781746,7.4629419 10.783378,7.6397186" + id="path4438" + inkscape:connector-curvature="0" /> + </g> + <g + inkscape:groupmode="layer" + id="layer3" + inkscape:label="Shine" + style="display:inline" + sodipodi:insensitive="true"> + <path + sodipodi:type="arc" + style="fill:url(#radialGradient4440);fill-opacity:1;stroke:none" + id="path4353" + sodipodi:cx="8.0433397" + sodipodi:cy="8.1334372" + sodipodi:rx="7.3686199" + sodipodi:ry="7.4368792" + d="m 15.41196,8.1334372 a 7.3686199,7.4368792 0 1 1 -14.73724019,0 7.3686199,7.4368792 0 1 1 14.73724019,0 z" + transform="matrix(0.91562931,0,0,0.91562931,0.64737218,0.56658541)" /> + </g> +</svg> diff --git a/src/qt/res/src/inout.svg b/src/qt/res/src/inout.svg new file mode 100644 index 0000000000..bfab8ef6ab --- /dev/null +++ b/src/qt/res/src/inout.svg @@ -0,0 +1,122 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!-- Created with Inkscape (http://www.inkscape.org/) --> + +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + id="svg3039" + version="1.1" + inkscape:version="0.48.0 r9654" + width="120" + height="120" + sodipodi:docname="inout3.svg" + inkscape:export-filename="/home/orion/projects2/bitcoin/tx_mined.png" + inkscape:export-xdpi="12" + inkscape:export-ydpi="12" + style="display:inline"> + <metadata + id="metadata3045"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + <dc:title></dc:title> + </cc:Work> + </rdf:RDF> + </metadata> + <defs + id="defs3043" /> + <sodipodi:namedview + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1" + objecttolerance="10" + gridtolerance="10" + guidetolerance="10" + inkscape:pageopacity="0" + inkscape:pageshadow="2" + inkscape:window-width="1920" + inkscape:window-height="1127" + id="namedview3041" + showgrid="false" + inkscape:zoom="1" + inkscape:cx="87.12655" + inkscape:cy="67.287943" + inkscape:window-x="0" + inkscape:window-y="25" + inkscape:window-maximized="1" + inkscape:current-layer="layer7" /> + <g + inkscape:groupmode="layer" + id="layer2" + inkscape:label="base" + style="display:none"> + <path + style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;color:#000000;fill:#afafaf;fill-opacity:1;stroke:none;stroke-width:7;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Sans;-inkscape-font-specification:Sans" + d="m 45.375,17 c -13.984022,0.241082 -24.968241,3.28976 -37.4375,9.59375 -8.9920665,21.871558 -6.680947,46.393002 -1.96875,69 26.190925,13.15317 55.594909,12.97748 81.75,-0.21875 3.852144,-9.729509 1.599587,-12.800015 2.375,-23.15625 C 83.917272,72.423868 77.129905,67.688094 74.1875,75.25 72.702487,79.722025 76.119709,82.645519 69.15625,83.34375 53.023957,88.536726 37.721719,89.140031 21.875,82.28125 19.715285,68.367979 18.599566,53.65725 22.5,40 c 16.868164,-6.642068 33.121079,-6.120062 50.03125,-0.15625 1.285344,5.854815 1.574746,5.763255 2.375,11.6875 C 80.46378,51.970623 89.644961,53.334736 91.3125,46 91.85305,36.007959 89.372312,31.625095 87.1875,25.6875 73.709743,21.03478 59.804255,16.698888 45.375,17 z" + id="path3053" + inkscape:connector-curvature="0" + sodipodi:nodetypes="cccccccccccccc" /> + </g> + <g + inkscape:groupmode="layer" + id="layer3" + inkscape:label="arrow_out" + style="display:none"> + <path + style="fill:#6e6e6e;fill-opacity:1;stroke:none;display:inline" + d="m 63.983409,65.48134 0.267857,-9.514444 36.161424,-0.194173 -7.414458,-8.757971 3.798312,-7.572721 c 0,0 23.437946,20.796656 22.500436,21.185 -0.93751,0.388345 -23.170094,22.73838 -23.170094,22.73838 l -3.128654,-8.931927 7.548388,-8.5638 z" + id="path3844" + inkscape:connector-curvature="0" + sodipodi:nodetypes="cccccscccc" /> + </g> + <g + inkscape:groupmode="layer" + id="layer4" + inkscape:label="arrow_in" + style="display:none"> + <path + inkscape:connector-curvature="0" + id="path4080" + d="m 99.28763,65.48134 -0.26786,-9.514444 -36.161422,-0.194173 7.768009,-6.283097 -4.151865,-9.279828 c 0,0 -23.43795,20.028889 -22.500436,20.417233 0.937514,0.388345 23.170094,20.970613 23.170094,20.970613 l 3.482207,-9.639034 -7.901936,-6.088926 z" + style="fill:#6e6e6e;fill-opacity:1;stroke:none;display:inline" + sodipodi:nodetypes="cccccscccc" /> + </g> + <g + inkscape:groupmode="layer" + id="layer7" + inkscape:label="mined" + style="display:inline"> + <path + style="fill:#a9a9a9;fill-opacity:1;stroke:none;display:inline" + d="M 9.4375,99.758169 78.14665,33.110294 73.680556,28.300653 67.153187,8.375 l 18.55147,6.527369 4.80964,3.779003 4.809641,-4.80964 11.680552,12.367647 -6.18382,4.80964 13.74183,14.085377 -12.71119,14.42892 -14.77247,-16.14665 -65.273693,70.770424 z" + id="path4103" + inkscape:connector-curvature="0" + sodipodi:nodetypes="cccccccccccccc" /> + <path + sodipodi:nodetypes="cccccccccccccc" + inkscape:connector-curvature="0" + id="path4619" + d="M 114.5625,99.758169 45.85335,33.110294 50.319444,28.300653 56.846813,8.375 l -18.55147,6.527369 -4.80964,3.779003 -4.809641,-4.80964 -11.680556,12.367647 6.183825,4.80964 L 9.4375,45.134396 22.148693,59.563316 36.92116,43.416666 102.19485,114.18709 z" + style="fill:#a9a9a9;fill-opacity:1;stroke:none;display:inline" /> + <path + style="fill:#6e6e6e;fill-opacity:1;stroke:none" + d="M 10.960155,44.693128 38.53732,16.408856 54.093669,10.752002 48.436815,28.076118 22.273864,56.713943 z" + id="path5256" + inkscape:connector-curvature="0" + sodipodi:nodetypes="cccccc" /> + <path + style="fill:#6e6e6e;fill-opacity:1;stroke:none" + d="M 69.296465,10.398449 85.559921,17.115963 111.72287,45.046681 102.17693,56.713943 74.953319,27.722565 z" + id="path5258" + inkscape:connector-curvature="0" + sodipodi:nodetypes="cccccc" /> + </g> +</svg> diff --git a/src/qt/res/src/questionmark.svg b/src/qt/res/src/questionmark.svg new file mode 100644 index 0000000000..c03c159a5f --- /dev/null +++ b/src/qt/res/src/questionmark.svg @@ -0,0 +1,159 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!-- Created with Inkscape (http://www.inkscape.org/) --> + +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + xmlns:xlink="http://www.w3.org/1999/xlink" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + width="16px" + height="16px" + id="svg2993" + version="1.1" + inkscape:version="0.48.0 r9654" + sodipodi:docname="questionmark.svg" + inkscape:export-filename="/store/orion/projects/bitcoin/questionmark.png" + inkscape:export-xdpi="90" + inkscape:export-ydpi="90"> + <defs + id="defs2995"> + <linearGradient + id="linearGradient3808"> + <stop + style="stop-color:#c8c8c8;stop-opacity:1;" + offset="0" + id="stop3810" /> + <stop + style="stop-color:#959595;stop-opacity:1" + offset="1" + id="stop3812" /> + </linearGradient> + <filter + inkscape:collect="always" + id="filter3804" + x="-0.2510722" + width="1.5021444" + y="-0.13164773" + height="1.2632955"> + <feGaussianBlur + inkscape:collect="always" + stdDeviation="0.73280473" + id="feGaussianBlur3806" /> + </filter> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient3808" + id="linearGradient3844" + x1="8.4916801" + y1="1.4395804" + x2="8.6022711" + y2="14.211697" + gradientUnits="userSpaceOnUse" /> + <filter + inkscape:collect="always" + id="filter3889" + x="-0.13954329" + width="1.2790866" + y="-0.073168421" + height="1.1463368"> + <feGaussianBlur + inkscape:collect="always" + stdDeviation="0.40728516" + id="feGaussianBlur3891" /> + </filter> + <filter + inkscape:collect="always" + id="filter3897" + x="-0.17178624" + width="1.3435725" + y="-0.090074761" + height="1.1801495"> + <feGaussianBlur + inkscape:collect="always" + stdDeviation="0.50139271" + id="feGaussianBlur3899" /> + </filter> + </defs> + <sodipodi:namedview + id="base" + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1.0" + inkscape:pageopacity="0.0" + inkscape:pageshadow="2" + inkscape:zoom="1" + inkscape:cx="10.789648" + inkscape:cy="7.6382159" + inkscape:current-layer="layer2" + showgrid="true" + inkscape:grid-bbox="true" + inkscape:document-units="px" + inkscape:window-width="1920" + inkscape:window-height="1127" + inkscape:window-x="0" + inkscape:window-y="25" + inkscape:window-maximized="1" /> + <metadata + id="metadata2998"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + <dc:title></dc:title> + </cc:Work> + </rdf:RDF> + </metadata> + <g + inkscape:groupmode="layer" + id="layer2" + inkscape:label="Below" + style="display:inline"> + <text + sodipodi:linespacing="125%" + id="text3006" + y="14.748394" + x="4.1060953" + style="font-size:18px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;filter:url(#filter3897)" + xml:space="preserve"><tspan + y="14.748394" + x="4.1060953" + id="tspan3008" + sodipodi:role="line">?</tspan></text> + <text + xml:space="preserve" + style="font-size:18px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;filter:url(#filter3889)" + x="4.1060953" + y="14.748394" + id="text3824" + sodipodi:linespacing="125%"><tspan + sodipodi:role="line" + id="tspan3826" + x="4.1060953" + y="14.748394">?</tspan></text> + </g> + <g + id="layer1" + inkscape:label="QuestionMark" + inkscape:groupmode="layer" + style="display:inline" + sodipodi:insensitive="true"> + <text + xml:space="preserve" + style="font-size:18px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:url(#linearGradient3844);fill-opacity:1;stroke:none;font-family:Sans" + x="4.1060953" + y="14.748394" + id="text3001" + sodipodi:linespacing="125%"><tspan + sodipodi:role="line" + id="tspan3003" + x="4.1060953" + y="14.748394" + style="fill:url(#linearGradient3844);fill-opacity:1">?</tspan></text> + </g> +</svg> diff --git a/src/qt/sendcoinsdialog.cpp b/src/qt/sendcoinsdialog.cpp new file mode 100644 index 0000000000..58eb5c21f7 --- /dev/null +++ b/src/qt/sendcoinsdialog.cpp @@ -0,0 +1,254 @@ +#include "sendcoinsdialog.h" +#include "ui_sendcoinsdialog.h" +#include "walletmodel.h" +#include "bitcoinunits.h" +#include "addressbookpage.h" +#include "optionsmodel.h" +#include "sendcoinsentry.h" +#include "guiutil.h" +#include "askpassphrasedialog.h" + +#include <QMessageBox> +#include <QLocale> +#include <QTextDocument> + +SendCoinsDialog::SendCoinsDialog(QWidget *parent) : + QDialog(parent), + ui(new Ui::SendCoinsDialog), + model(0) +{ + ui->setupUi(this); + + addEntry(); + + connect(ui->addButton, SIGNAL(clicked()), this, SLOT(addEntry())); + connect(ui->clearButton, SIGNAL(clicked()), this, SLOT(clear())); +} + +void SendCoinsDialog::setModel(WalletModel *model) +{ + this->model = model; + + for(int i = 0; i < ui->entries->count(); ++i) + { + SendCoinsEntry *entry = qobject_cast<SendCoinsEntry*>(ui->entries->itemAt(i)->widget()); + if(entry) + { + entry->setModel(model); + } + } + + setBalance(model->getBalance(), model->getUnconfirmedBalance()); + connect(model, SIGNAL(balanceChanged(qint64, qint64)), this, SLOT(setBalance(qint64, qint64))); +} + +SendCoinsDialog::~SendCoinsDialog() +{ + delete ui; +} + +void SendCoinsDialog::on_sendButton_clicked() +{ + QList<SendCoinsRecipient> recipients; + bool valid = true; + for(int i = 0; i < ui->entries->count(); ++i) + { + SendCoinsEntry *entry = qobject_cast<SendCoinsEntry*>(ui->entries->itemAt(i)->widget()); + if(entry) + { + if(entry->validate()) + { + recipients.append(entry->getValue()); + } + else + { + valid = false; + } + } + } + + if(!valid || recipients.isEmpty()) + { + return; + } + + // Format confirmation message + QStringList formatted; + foreach(const SendCoinsRecipient &rcp, recipients) + { + formatted.append(tr("<b>%1</b> to %2 (%3)").arg(BitcoinUnits::formatWithUnit(BitcoinUnits::BTC, rcp.amount), Qt::escape(rcp.label), rcp.address)); + } + + QMessageBox::StandardButton retval = QMessageBox::question(this, tr("Confirm send coins"), + tr("Are you sure you want to send %1?").arg(formatted.join(tr(" and "))), + QMessageBox::Yes|QMessageBox::Cancel, + QMessageBox::Cancel); + + if(retval != QMessageBox::Yes) + { + return; + } + + WalletModel::UnlockContext ctx(model->requestUnlock()); + if(!ctx.isValid()) + { + // Unlock wallet was cancelled + return; + } + + WalletModel::SendCoinsReturn sendstatus = model->sendCoins(recipients); + switch(sendstatus.status) + { + case WalletModel::InvalidAddress: + QMessageBox::warning(this, tr("Send Coins"), + tr("The recepient address is not valid, please recheck."), + QMessageBox::Ok, QMessageBox::Ok); + break; + case WalletModel::InvalidAmount: + QMessageBox::warning(this, tr("Send Coins"), + tr("The amount to pay must be larger than 0."), + QMessageBox::Ok, QMessageBox::Ok); + break; + case WalletModel::AmountExceedsBalance: + QMessageBox::warning(this, tr("Send Coins"), + tr("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"). + 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"), + QMessageBox::Ok, QMessageBox::Ok); + break; + case WalletModel::TransactionCreationFailed: + QMessageBox::warning(this, tr("Send Coins"), + 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."), + QMessageBox::Ok, QMessageBox::Ok); + break; + case WalletModel::OK: + accept(); + break; + } +} + +void SendCoinsDialog::clear() +{ + // Remove entries until only one left + while(ui->entries->count()) + { + delete ui->entries->takeAt(0)->widget(); + } + addEntry(); + + updateRemoveEnabled(); + + ui->sendButton->setDefault(true); +} + +void SendCoinsDialog::reject() +{ + clear(); +} + +void SendCoinsDialog::accept() +{ + clear(); +} + +SendCoinsEntry *SendCoinsDialog::addEntry() +{ + SendCoinsEntry *entry = new SendCoinsEntry(this); + entry->setModel(model); + ui->entries->addWidget(entry); + connect(entry, SIGNAL(removeEntry(SendCoinsEntry*)), this, SLOT(removeEntry(SendCoinsEntry*))); + + updateRemoveEnabled(); + + // Focus the field, so that entry can start immediately + entry->clear(); + return entry; +} + +void SendCoinsDialog::updateRemoveEnabled() +{ + // Remove buttons are enabled as soon as there is more than one send-entry + bool enabled = (ui->entries->count() > 1); + for(int i = 0; i < ui->entries->count(); ++i) + { + SendCoinsEntry *entry = qobject_cast<SendCoinsEntry*>(ui->entries->itemAt(i)->widget()); + if(entry) + { + entry->setRemoveEnabled(enabled); + } + } + setupTabChain(0); +} + +void SendCoinsDialog::removeEntry(SendCoinsEntry* entry) +{ + delete entry; + updateRemoveEnabled(); +} + +QWidget *SendCoinsDialog::setupTabChain(QWidget *prev) +{ + for(int i = 0; i < ui->entries->count(); ++i) + { + SendCoinsEntry *entry = qobject_cast<SendCoinsEntry*>(ui->entries->itemAt(i)->widget()); + if(entry) + { + prev = entry->setupTabChain(prev); + } + } + QWidget::setTabOrder(prev, ui->addButton); + QWidget::setTabOrder(ui->addButton, ui->sendButton); + return ui->sendButton; +} + +void SendCoinsDialog::pasteEntry(const SendCoinsRecipient &rv) +{ + SendCoinsEntry *entry = 0; + // Replace the first entry if it is still unused + if(ui->entries->count() == 1) + { + SendCoinsEntry *first = qobject_cast<SendCoinsEntry*>(ui->entries->itemAt(0)->widget()); + if(first->isClear()) + { + entry = first; + } + } + if(!entry) + { + entry = addEntry(); + } + + entry->setValue(rv); +} + + +void SendCoinsDialog::handleURL(const QUrl *url) +{ + SendCoinsRecipient rv; + if(!GUIUtil::parseBitcoinURL(url, &rv)) + { + return; + } + pasteEntry(rv); +} + +void SendCoinsDialog::setBalance(qint64 balance, qint64 unconfirmedBalance) +{ + Q_UNUSED(unconfirmedBalance); + int unit = model->getOptionsModel()->getDisplayUnit(); + ui->labelBalance->setText(BitcoinUnits::formatWithUnit(unit, balance)); +} diff --git a/src/qt/sendcoinsdialog.h b/src/qt/sendcoinsdialog.h new file mode 100644 index 0000000000..a14f99e8b2 --- /dev/null +++ b/src/qt/sendcoinsdialog.h @@ -0,0 +1,52 @@ +#ifndef SENDCOINSDIALOG_H +#define SENDCOINSDIALOG_H + +#include <QDialog> + +namespace Ui { + class SendCoinsDialog; +} +class WalletModel; +class SendCoinsEntry; +class SendCoinsRecipient; + +QT_BEGIN_NAMESPACE +class QUrl; +QT_END_NAMESPACE + +class SendCoinsDialog : public QDialog +{ + Q_OBJECT + +public: + explicit SendCoinsDialog(QWidget *parent = 0); + ~SendCoinsDialog(); + + void setModel(WalletModel *model); + + // Qt messes up the tab chain by default in some cases (issue http://bugreports.qt.nokia.com/browse/QTBUG-10907) + // Hence we have to set it up manually + QWidget *setupTabChain(QWidget *prev); + + void pasteEntry(const SendCoinsRecipient &rv); + void handleURL(const QUrl *url); + +public slots: + void clear(); + void reject(); + void accept(); + SendCoinsEntry *addEntry(); + void updateRemoveEnabled(); + void setBalance(qint64 balance, qint64 unconfirmedBalance); + +private: + Ui::SendCoinsDialog *ui; + WalletModel *model; + +private slots: + void on_sendButton_clicked(); + + void removeEntry(SendCoinsEntry* entry); +}; + +#endif // SENDCOINSDIALOG_H diff --git a/src/qt/sendcoinsentry.cpp b/src/qt/sendcoinsentry.cpp new file mode 100644 index 0000000000..fccef232bb --- /dev/null +++ b/src/qt/sendcoinsentry.cpp @@ -0,0 +1,145 @@ +#include "sendcoinsentry.h" +#include "ui_sendcoinsentry.h" +#include "guiutil.h" +#include "bitcoinunits.h" +#include "addressbookpage.h" +#include "walletmodel.h" +#include "optionsmodel.h" +#include "addresstablemodel.h" + +#include <QApplication> +#include <QClipboard> + +SendCoinsEntry::SendCoinsEntry(QWidget *parent) : + QFrame(parent), + ui(new Ui::SendCoinsEntry), + model(0) +{ + ui->setupUi(this); + +#if QT_VERSION >= 0x040700 + ui->payTo->setPlaceholderText(tr("Enter a Bitcoin address (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L)")); + ui->addAsLabel->setPlaceholderText(tr("Enter a label for this address to add it to your address book")); +#endif + setFocusPolicy(Qt::TabFocus); + setFocusProxy(ui->payTo); + + GUIUtil::setupAddressWidget(ui->payTo, this); +} + +SendCoinsEntry::~SendCoinsEntry() +{ + delete ui; +} + +void SendCoinsEntry::on_pasteButton_clicked() +{ + // Paste text from clipboard into recipient field + ui->payTo->setText(QApplication::clipboard()->text()); +} + +void SendCoinsEntry::on_addressBookButton_clicked() +{ + AddressBookPage dlg(AddressBookPage::ForSending, AddressBookPage::SendingTab, this); + dlg.setModel(model->getAddressTableModel()); + if(dlg.exec()) + { + ui->payTo->setText(dlg.getReturnValue()); + ui->payAmount->setFocus(); + } +} + +void SendCoinsEntry::on_payTo_textChanged(const QString &address) +{ + ui->addAsLabel->setText(model->getAddressTableModel()->labelForAddress(address)); +} + +void SendCoinsEntry::setModel(WalletModel *model) +{ + this->model = model; +} + +void SendCoinsEntry::setRemoveEnabled(bool enabled) +{ + ui->deleteButton->setEnabled(enabled); +} + +void SendCoinsEntry::clear() +{ + ui->payTo->clear(); + ui->addAsLabel->clear(); + ui->payAmount->clear(); + ui->payTo->setFocus(); + if(model) + { + ui->payAmount->setDisplayUnit(model->getOptionsModel()->getDisplayUnit()); + } +} + +void SendCoinsEntry::on_deleteButton_clicked() +{ + emit removeEntry(this); +} + +bool SendCoinsEntry::validate() +{ + // Check input validity + bool retval = true; + + if(!ui->payAmount->validate()) + { + retval = false; + } + else + { + if(ui->payAmount->value() <= 0) + { + // Cannot send 0 coins or less + ui->payAmount->setValid(false); + retval = false; + } + } + + if(!ui->payTo->hasAcceptableInput() || + (model && !model->validateAddress(ui->payTo->text()))) + { + ui->payTo->setValid(false); + retval = false; + } + + return retval; +} + +SendCoinsRecipient SendCoinsEntry::getValue() +{ + SendCoinsRecipient rv; + + rv.address = ui->payTo->text(); + rv.label = ui->addAsLabel->text(); + rv.amount = ui->payAmount->value(); + + return rv; +} + +QWidget *SendCoinsEntry::setupTabChain(QWidget *prev) +{ + QWidget::setTabOrder(prev, ui->payTo); + QWidget::setTabOrder(ui->payTo, ui->addressBookButton); + QWidget::setTabOrder(ui->addressBookButton, ui->pasteButton); + QWidget::setTabOrder(ui->pasteButton, ui->deleteButton); + QWidget::setTabOrder(ui->deleteButton, ui->addAsLabel); + return ui->payAmount->setupTabChain(ui->addAsLabel); +} + +void SendCoinsEntry::setValue(const SendCoinsRecipient &value) +{ + ui->payTo->setText(value.address); + ui->addAsLabel->setText(value.label); + ui->payAmount->setValue(value.amount); +} + +bool SendCoinsEntry::isClear() +{ + return ui->payTo->text().isEmpty(); +} + diff --git a/src/qt/sendcoinsentry.h b/src/qt/sendcoinsentry.h new file mode 100644 index 0000000000..ccc223b5f5 --- /dev/null +++ b/src/qt/sendcoinsentry.h @@ -0,0 +1,51 @@ +#ifndef SENDCOINSENTRY_H +#define SENDCOINSENTRY_H + +#include <QFrame> + +namespace Ui { + class SendCoinsEntry; +} +class WalletModel; +class SendCoinsRecipient; + +class SendCoinsEntry : public QFrame +{ + Q_OBJECT + +public: + explicit SendCoinsEntry(QWidget *parent = 0); + ~SendCoinsEntry(); + + void setModel(WalletModel *model); + bool validate(); + SendCoinsRecipient getValue(); + + // Return true if the entry is still empty and unedited + bool isClear(); + + void setValue(const SendCoinsRecipient &value); + + // Qt messes up the tab chain by default in some cases (issue http://bugreports.qt.nokia.com/browse/QTBUG-10907) + // Hence we have to set it up manually + QWidget *setupTabChain(QWidget *prev); + +public slots: + void setRemoveEnabled(bool enabled); + void clear(); + +signals: + void removeEntry(SendCoinsEntry *entry); + +private slots: + void on_deleteButton_clicked(); + void on_payTo_textChanged(const QString &address); + void on_addressBookButton_clicked(); + void on_pasteButton_clicked(); + +private: + Ui::SendCoinsEntry *ui; + WalletModel *model; +}; + +#endif // SENDCOINSENTRY_H diff --git a/src/qt/transactiondesc.cpp b/src/qt/transactiondesc.cpp new file mode 100644 index 0000000000..6ca3ac8c4b --- /dev/null +++ b/src/qt/transactiondesc.cpp @@ -0,0 +1,292 @@ +#include <transactiondesc.h> + +#include "guiutil.h" +#include "bitcoinunits.h" + +#include "headers.h" +#include "qtui.h" + +#include <QString> +#include <QTextDocument> // For Qt::escape + +using namespace std; + +QString TransactionDesc::HtmlEscape(const QString& str, bool fMultiLine) +{ + QString escaped = Qt::escape(str); + if(fMultiLine) + { + escaped = escaped.replace("\n", "<br>\n"); + } + return escaped; +} + +QString TransactionDesc::HtmlEscape(const std::string& str, bool fMultiLine) +{ + return HtmlEscape(QString::fromStdString(str), fMultiLine); +} + +QString TransactionDesc::FormatTxStatus(const CWalletTx& wtx) +{ + if (!wtx.IsFinal()) + { + if (wtx.nLockTime < LOCKTIME_THRESHOLD) + return tr("Open for %1 blocks").arg(nBestHeight - wtx.nLockTime); + else + return tr("Open until %1").arg(GUIUtil::dateTimeStr(wtx.nLockTime)); + } + else + { + int nDepth = wtx.GetDepthInMainChain(); + if (GetAdjustedTime() - wtx.nTimeReceived > 2 * 60 && wtx.GetRequestCount() == 0) + return tr("%1/offline?").arg(nDepth); + else if (nDepth < 6) + return tr("%1/unconfirmed").arg(nDepth); + else + return tr("%1 confirmations").arg(nDepth); + } +} + +QString TransactionDesc::toHTML(CWallet *wallet, CWalletTx &wtx) +{ + QString strHTML; + CRITICAL_BLOCK(wallet->cs_wallet) + { + strHTML.reserve(4000); + strHTML += "<html><font face='verdana, arial, helvetica, sans-serif'>"; + + int64 nTime = wtx.GetTxTime(); + int64 nCredit = wtx.GetCredit(); + int64 nDebit = wtx.GetDebit(); + int64 nNet = nCredit - nDebit; + + strHTML += tr("<b>Status:</b> ") + FormatTxStatus(wtx); + int nRequests = wtx.GetRequestCount(); + if (nRequests != -1) + { + if (nRequests == 0) + strHTML += tr(", has not been successfully broadcast yet"); + else if (nRequests == 1) + strHTML += tr(", broadcast through %1 node").arg(nRequests); + else + strHTML += tr(", broadcast through %1 nodes").arg(nRequests); + } + strHTML += "<br>"; + + strHTML += tr("<b>Date:</b> ") + (nTime ? GUIUtil::dateTimeStr(nTime) : QString("")) + "<br>"; + + // + // From + // + if (wtx.IsCoinBase()) + { + strHTML += tr("<b>Source:</b> Generated<br>"); + } + else if (!wtx.mapValue["from"].empty()) + { + // Online transaction + if (!wtx.mapValue["from"].empty()) + strHTML += tr("<b>From:</b> ") + HtmlEscape(wtx.mapValue["from"]) + "<br>"; + } + else + { + // Offline transaction + if (nNet > 0) + { + // Credit + BOOST_FOREACH(const CTxOut& txout, wtx.vout) + { + if (wallet->IsMine(txout)) + { + CBitcoinAddress address; + if (ExtractAddress(txout.scriptPubKey, wallet, address)) + { + if (wallet->mapAddressBook.count(address)) + { + strHTML += tr("<b>From:</b> ") + tr("unknown") + "<br>"; + strHTML += tr("<b>To:</b> "); + strHTML += HtmlEscape(address.ToString()); + if (!wallet->mapAddressBook[address].empty()) + strHTML += tr(" (yours, label: ") + HtmlEscape(wallet->mapAddressBook[address]) + ")"; + else + strHTML += tr(" (yours)"); + strHTML += "<br>"; + } + } + break; + } + } + } + } + + // + // To + // + string strAddress; + if (!wtx.mapValue["to"].empty()) + { + // Online transaction + strAddress = wtx.mapValue["to"]; + strHTML += tr("<b>To:</b> "); + if (wallet->mapAddressBook.count(strAddress) && !wallet->mapAddressBook[strAddress].empty()) + strHTML += HtmlEscape(wallet->mapAddressBook[strAddress]) + " "; + strHTML += HtmlEscape(strAddress) + "<br>"; + } + + // + // Amount + // + if (wtx.IsCoinBase() && nCredit == 0) + { + // + // Coinbase + // + int64 nUnmatured = 0; + BOOST_FOREACH(const CTxOut& txout, wtx.vout) + nUnmatured += wallet->GetCredit(txout); + strHTML += tr("<b>Credit:</b> "); + if (wtx.IsInMainChain()) + strHTML += tr("(%1 matures in %2 more blocks)") + .arg(BitcoinUnits::formatWithUnit(BitcoinUnits::BTC, nUnmatured)) + .arg(wtx.GetBlocksToMaturity()); + else + strHTML += tr("(not accepted)"); + strHTML += "<br>"; + } + else if (nNet > 0) + { + // + // Credit + // + strHTML += tr("<b>Credit:</b> ") + BitcoinUnits::formatWithUnit(BitcoinUnits::BTC, nNet) + "<br>"; + } + 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) + { + // + // Debit + // + BOOST_FOREACH(const CTxOut& txout, wtx.vout) + { + if (wallet->IsMine(txout)) + continue; + + if (wtx.mapValue["to"].empty()) + { + // Offline transaction + CBitcoinAddress address; + if (ExtractAddress(txout.scriptPubKey, 0, address)) + { + strHTML += tr("<b>To:</b> "); + if (wallet->mapAddressBook.count(address) && !wallet->mapAddressBook[address].empty()) + strHTML += HtmlEscape(wallet->mapAddressBook[address]) + " "; + strHTML += HtmlEscape(address.ToString()); + strHTML += "<br>"; + } + } + + strHTML += tr("<b>Debit:</b> ") + BitcoinUnits::formatWithUnit(BitcoinUnits::BTC, -txout.nValue) + "<br>"; + } + + if (fAllToMe) + { + // Payment to self + int64 nChange = wtx.GetChange(); + int64 nValue = nCredit - nChange; + strHTML += tr("<b>Debit:</b> ") + BitcoinUnits::formatWithUnit(BitcoinUnits::BTC, -nValue) + "<br>"; + strHTML += tr("<b>Credit:</b> ") + BitcoinUnits::formatWithUnit(BitcoinUnits::BTC, nValue) + "<br>"; + } + + int64 nTxFee = nDebit - wtx.GetValueOut(); + if (nTxFee > 0) + strHTML += tr("<b>Transaction fee:</b> ") + BitcoinUnits::formatWithUnit(BitcoinUnits::BTC,-nTxFee) + "<br>"; + } + else + { + // + // Mixed debit transaction + // + BOOST_FOREACH(const CTxIn& txin, wtx.vin) + if (wallet->IsMine(txin)) + strHTML += tr("<b>Debit:</b> ") + BitcoinUnits::formatWithUnit(BitcoinUnits::BTC,-wallet->GetDebit(txin)) + "<br>"; + BOOST_FOREACH(const CTxOut& txout, wtx.vout) + if (wallet->IsMine(txout)) + strHTML += tr("<b>Credit:</b> ") + BitcoinUnits::formatWithUnit(BitcoinUnits::BTC,wallet->GetCredit(txout)) + "<br>"; + } + } + + strHTML += tr("<b>Net amount:</b> ") + BitcoinUnits::formatWithUnit(BitcoinUnits::BTC,nNet, true) + "<br>"; + + // + // Message + // + if (!wtx.mapValue["message"].empty()) + strHTML += QString("<br><b>") + tr("Message:") + "</b><br>" + HtmlEscape(wtx.mapValue["message"], true) + "<br>"; + if (!wtx.mapValue["comment"].empty()) + strHTML += QString("<br><b>") + tr("Comment:") + "</b><br>" + HtmlEscape(wtx.mapValue["comment"], true) + "<br>"; + + if (wtx.IsCoinBase()) + strHTML += QString("<br>") + tr("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 \"not accepted\" and not be spendable. This may occasionally happen if another node generates a block within a few seconds of yours.") + "<br>"; + + // + // Debug view + // + if (fDebug) + { + strHTML += "<hr><br>Debug information<br><br>"; + BOOST_FOREACH(const CTxIn& txin, wtx.vin) + if(wallet->IsMine(txin)) + strHTML += "<b>Debit:</b> " + BitcoinUnits::formatWithUnit(BitcoinUnits::BTC,-wallet->GetDebit(txin)) + "<br>"; + BOOST_FOREACH(const CTxOut& txout, wtx.vout) + if(wallet->IsMine(txout)) + strHTML += "<b>Credit:</b> " + BitcoinUnits::formatWithUnit(BitcoinUnits::BTC,wallet->GetCredit(txout)) + "<br>"; + + strHTML += "<br><b>Transaction:</b><br>"; + strHTML += HtmlEscape(wtx.ToString(), true); + + CTxDB txdb("r"); // To fetch source txouts + + strHTML += "<br><b>Inputs:</b>"; + strHTML += "<ul>"; + CRITICAL_BLOCK(wallet->cs_wallet) + { + BOOST_FOREACH(const CTxIn& txin, wtx.vin) + { + COutPoint prevout = txin.prevout; + + CTransaction prev; + if(txdb.ReadDiskTx(prevout.hash, prev)) + { + if (prevout.n < prev.vout.size()) + { + strHTML += "<li>"; + const CTxOut &vout = prev.vout[prevout.n]; + CBitcoinAddress address; + if (ExtractAddress(vout.scriptPubKey, 0, address)) + { + if (wallet->mapAddressBook.count(address) && !wallet->mapAddressBook[address].empty()) + strHTML += HtmlEscape(wallet->mapAddressBook[address]) + " "; + strHTML += QString::fromStdString(address.ToString()); + } + strHTML = strHTML + " Amount=" + BitcoinUnits::formatWithUnit(BitcoinUnits::BTC,vout.nValue); + strHTML = strHTML + " IsMine=" + (wallet->IsMine(vout) ? "true" : "false") + "</li>"; + } + } + } + } + strHTML += "</ul>"; + } + + strHTML += "</font></html>"; + } + return strHTML; +} diff --git a/src/qt/transactiondesc.h b/src/qt/transactiondesc.h new file mode 100644 index 0000000000..484bb1230e --- /dev/null +++ b/src/qt/transactiondesc.h @@ -0,0 +1,25 @@ +#ifndef TRANSACTIONDESC_H +#define TRANSACTIONDESC_H + +#include <QString> +#include <QObject> +#include <string> + +class CWallet; +class CWalletTx; + +class TransactionDesc: public QObject +{ + Q_OBJECT +public: + // Provide human-readable extended HTML description of a transaction + static QString toHTML(CWallet *wallet, CWalletTx &wtx); +private: + TransactionDesc() {} + + static QString HtmlEscape(const QString& str, bool fMultiLine=false); + static QString HtmlEscape(const std::string &str, bool fMultiLine=false); + static QString FormatTxStatus(const CWalletTx& wtx); +}; + +#endif // TRANSACTIONDESC_H diff --git a/src/qt/transactiondescdialog.cpp b/src/qt/transactiondescdialog.cpp new file mode 100644 index 0000000000..3bd4808cb6 --- /dev/null +++ b/src/qt/transactiondescdialog.cpp @@ -0,0 +1,20 @@ +#include "transactiondescdialog.h" +#include "ui_transactiondescdialog.h" + +#include "transactiontablemodel.h" + +#include <QModelIndex> + +TransactionDescDialog::TransactionDescDialog(const QModelIndex &idx, QWidget *parent) : + QDialog(parent), + ui(new Ui::TransactionDescDialog) +{ + ui->setupUi(this); + QString desc = idx.data(TransactionTableModel::LongDescriptionRole).toString(); + ui->detailText->setHtml(desc); +} + +TransactionDescDialog::~TransactionDescDialog() +{ + delete ui; +} diff --git a/src/qt/transactiondescdialog.h b/src/qt/transactiondescdialog.h new file mode 100644 index 0000000000..4f8f754b2b --- /dev/null +++ b/src/qt/transactiondescdialog.h @@ -0,0 +1,25 @@ +#ifndef TRANSACTIONDESCDIALOG_H +#define TRANSACTIONDESCDIALOG_H + +#include <QDialog> + +namespace Ui { + class TransactionDescDialog; +} +QT_BEGIN_NAMESPACE +class QModelIndex; +QT_END_NAMESPACE + +class TransactionDescDialog : public QDialog +{ + Q_OBJECT + +public: + explicit TransactionDescDialog(const QModelIndex &idx, QWidget *parent = 0); + ~TransactionDescDialog(); + +private: + Ui::TransactionDescDialog *ui; +}; + +#endif // TRANSACTIONDESCDIALOG_H diff --git a/src/qt/transactionfilterproxy.cpp b/src/qt/transactionfilterproxy.cpp new file mode 100644 index 0000000000..a4c5b37171 --- /dev/null +++ b/src/qt/transactionfilterproxy.cpp @@ -0,0 +1,86 @@ +#include "transactionfilterproxy.h" +#include "transactiontablemodel.h" + +#include <QDateTime> + +#include <cstdlib> + +// Earliest date that can be represented (far in the past) +const QDateTime TransactionFilterProxy::MIN_DATE = QDateTime::fromTime_t(0); +// Last date that can be represented (far in the future) +const QDateTime TransactionFilterProxy::MAX_DATE = QDateTime::fromTime_t(0xFFFFFFFF); + +TransactionFilterProxy::TransactionFilterProxy(QObject *parent) : + QSortFilterProxyModel(parent), + dateFrom(MIN_DATE), + dateTo(MAX_DATE), + addrPrefix(), + typeFilter(ALL_TYPES), + minAmount(0), + limitRows(-1) +{ +} + +bool TransactionFilterProxy::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const +{ + QModelIndex index = sourceModel()->index(sourceRow, 0, sourceParent); + + int type = index.data(TransactionTableModel::TypeRole).toInt(); + QDateTime datetime = index.data(TransactionTableModel::DateRole).toDateTime(); + QString address = index.data(TransactionTableModel::AddressRole).toString(); + QString label = index.data(TransactionTableModel::LabelRole).toString(); + qint64 amount = llabs(index.data(TransactionTableModel::AmountRole).toLongLong()); + + if(!(TYPE(type) & typeFilter)) + return false; + if(datetime < dateFrom || datetime > dateTo) + return false; + if(!address.startsWith(addrPrefix) && !label.startsWith(addrPrefix)) + return false; + if(amount < minAmount) + return false; + + return true; +} + +void TransactionFilterProxy::setDateRange(const QDateTime &from, const QDateTime &to) +{ + this->dateFrom = from; + this->dateTo = to; + invalidateFilter(); +} + +void TransactionFilterProxy::setAddressPrefix(const QString &addrPrefix) +{ + this->addrPrefix = addrPrefix; + invalidateFilter(); +} + +void TransactionFilterProxy::setTypeFilter(quint32 modes) +{ + this->typeFilter = modes; + invalidateFilter(); +} + +void TransactionFilterProxy::setMinAmount(qint64 minimum) +{ + this->minAmount = minimum; + invalidateFilter(); +} + +void TransactionFilterProxy::setLimit(int limit) +{ + this->limitRows = limit; +} + +int TransactionFilterProxy::rowCount(const QModelIndex &parent) const +{ + if(limitRows != -1) + { + return std::min(QSortFilterProxyModel::rowCount(parent), limitRows); + } + else + { + return QSortFilterProxyModel::rowCount(parent); + } +} diff --git a/src/qt/transactionfilterproxy.h b/src/qt/transactionfilterproxy.h new file mode 100644 index 0000000000..4dd2a8e5c6 --- /dev/null +++ b/src/qt/transactionfilterproxy.h @@ -0,0 +1,50 @@ +#ifndef TRANSACTIONFILTERPROXY_H +#define TRANSACTIONFILTERPROXY_H + +#include <QSortFilterProxyModel> +#include <QDateTime> + +// Filter transaction list according to pre-specified rules +class TransactionFilterProxy : public QSortFilterProxyModel +{ + Q_OBJECT +public: + explicit TransactionFilterProxy(QObject *parent = 0); + + // Earliest date that can be represented (far in the past) + static const QDateTime MIN_DATE; + // Last date that can be represented (far in the future) + static const QDateTime MAX_DATE; + // Type filter bit field (all types) + static const quint32 ALL_TYPES = 0xFFFFFFFF; + + static quint32 TYPE(int type) { return 1<<type; } + + void setDateRange(const QDateTime &from, const QDateTime &to); + void setAddressPrefix(const QString &addrPrefix); + // Type filter takes a bitfield created with TYPE() or ALL_TYPES + void setTypeFilter(quint32 modes); + void setMinAmount(qint64 minimum); + + // Set maximum number of rows returned, -1 if unlimited + void setLimit(int limit); + + int rowCount(const QModelIndex &parent = QModelIndex()) const; +protected: + bool filterAcceptsRow(int source_row, const QModelIndex & source_parent) const; + +private: + QDateTime dateFrom; + QDateTime dateTo; + QString addrPrefix; + quint32 typeFilter; + qint64 minAmount; + int limitRows; + +signals: + +public slots: + +}; + +#endif // TRANSACTIONFILTERPROXY_H diff --git a/src/qt/transactionrecord.cpp b/src/qt/transactionrecord.cpp new file mode 100644 index 0000000000..77c5a01260 --- /dev/null +++ b/src/qt/transactionrecord.cpp @@ -0,0 +1,264 @@ +#include "transactionrecord.h" + +#include "headers.h" + +/* Return positive answer if transaction should be shown in list. + */ +bool TransactionRecord::showTransaction(const CWalletTx &wtx) +{ + if (wtx.IsCoinBase()) + { + // Don't show generated coin until confirmed by at least one block after it + // so we don't get the user's hopes up until it looks like it's probably accepted. + // + // It is not an error when generated blocks are not accepted. By design, + // some percentage of blocks, like 10% or more, will end up not accepted. + // This is the normal mechanism by which the network copes with latency. + // + // We display regular transactions right away before any confirmation + // because they can always get into some block eventually. Generated coins + // are special because if their block is not accepted, they are not valid. + // + if (wtx.GetDepthInMainChain() < 2) + { + return false; + } + } + return true; +} + +/* + * Decompose CWallet transaction to model transaction records. + */ +QList<TransactionRecord> TransactionRecord::decomposeTransaction(const CWallet *wallet, const CWalletTx &wtx) +{ + QList<TransactionRecord> parts; + int64 nTime = wtx.nTimeDisplayed = wtx.GetTxTime(); + int64 nCredit = wtx.GetCredit(true); + int64 nDebit = wtx.GetDebit(); + int64 nNet = nCredit - nDebit; + uint256 hash = wtx.GetHash(); + std::map<std::string, std::string> mapValue = wtx.mapValue; + + if (showTransaction(wtx)) + { + if (nNet > 0 || wtx.IsCoinBase()) + { + // + // Credit + // + TransactionRecord sub(hash, nTime); + + sub.credit = nNet; + + if (wtx.IsCoinBase()) + { + // Generated + sub.type = TransactionRecord::Generated; + + if (nCredit == 0) + { + int64 nUnmatured = 0; + BOOST_FOREACH(const CTxOut& txout, wtx.vout) + nUnmatured += wallet->GetCredit(txout); + sub.credit = nUnmatured; + } + } + else if (!mapValue["from"].empty() || !mapValue["message"].empty()) + { + // Received by IP connection + sub.type = TransactionRecord::RecvFromIP; + if (!mapValue["from"].empty()) + sub.address = mapValue["from"]; + } + else + { + // Received by Bitcoin Address + sub.type = TransactionRecord::RecvWithAddress; + BOOST_FOREACH(const CTxOut& txout, wtx.vout) + { + if(wallet->IsMine(txout)) + { + CBitcoinAddress address; + if (ExtractAddress(txout.scriptPubKey, wallet, address)) + { + sub.address = address.ToString(); + } + break; + } + } + } + parts.append(sub); + } + 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) + { + // Payment to self + int64 nChange = wtx.GetChange(); + + parts.append(TransactionRecord(hash, nTime, TransactionRecord::SendToSelf, "", + -(nDebit - nChange), nCredit - nChange)); + } + else if (fAllFromMe) + { + // + // Debit + // + int64 nTxFee = nDebit - wtx.GetValueOut(); + + for (int nOut = 0; nOut < wtx.vout.size(); nOut++) + { + 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; + } + else if(!mapValue["to"].empty()) + { + // Sent to IP + sub.type = TransactionRecord::SendToIP; + sub.address = mapValue["to"]; + } + else + { + // Sent to Bitcoin Address + sub.type = TransactionRecord::SendToAddress; + CBitcoinAddress address; + if (ExtractAddress(txout.scriptPubKey, 0, address)) + { + sub.address = address.ToString(); + } + } + + 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 + // + bool fAllMine = true; + BOOST_FOREACH(const CTxOut& txout, wtx.vout) + fAllMine = fAllMine && wallet->IsMine(txout); + BOOST_FOREACH(const CTxIn& txin, wtx.vin) + fAllMine = fAllMine && wallet->IsMine(txin); + + parts.append(TransactionRecord(hash, nTime, TransactionRecord::Other, "", nNet, 0)); + } + } + } + + return parts; +} + +void TransactionRecord::updateStatus(const CWalletTx &wtx) +{ + // Determine transaction status + + // Find the block the tx is in + CBlockIndex* pindex = NULL; + std::map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(wtx.hashBlock); + if (mi != mapBlockIndex.end()) + pindex = (*mi).second; + + // Sort order, unrecorded transactions sort to the top + status.sortKey = strprintf("%010d-%01d-%010u-%03d", + (pindex ? pindex->nHeight : INT_MAX), + (wtx.IsCoinBase() ? 1 : 0), + wtx.nTimeReceived, + idx); + status.confirmed = wtx.IsConfirmed(); + status.depth = wtx.GetDepthInMainChain(); + status.cur_num_blocks = nBestHeight; + + if (!wtx.IsFinal()) + { + if (wtx.nLockTime < LOCKTIME_THRESHOLD) + { + status.status = TransactionStatus::OpenUntilBlock; + status.open_for = nBestHeight - wtx.nLockTime; + } + else + { + status.status = TransactionStatus::OpenUntilDate; + status.open_for = wtx.nLockTime; + } + } + else + { + if (GetAdjustedTime() - wtx.nTimeReceived > 2 * 60 && wtx.GetRequestCount() == 0) + { + status.status = TransactionStatus::Offline; + } + else if (status.depth < NumConfirmations) + { + status.status = TransactionStatus::Unconfirmed; + } + else + { + status.status = TransactionStatus::HaveConfirmations; + } + } + + // For generated transactions, determine maturity + if(type == TransactionRecord::Generated) + { + int64 nCredit = wtx.GetCredit(true); + if (nCredit == 0) + { + status.maturity = TransactionStatus::Immature; + + if (wtx.IsInMainChain()) + { + status.matures_in = wtx.GetBlocksToMaturity(); + + // Check if the block was requested by anyone + if (GetAdjustedTime() - wtx.nTimeReceived > 2 * 60 && wtx.GetRequestCount() == 0) + status.maturity = TransactionStatus::MaturesWarning; + } + else + { + status.maturity = TransactionStatus::NotAccepted; + } + } + else + { + status.maturity = TransactionStatus::Mature; + } + } +} + +bool TransactionRecord::statusUpdateNeeded() +{ + return status.cur_num_blocks != nBestHeight; +} + +std::string TransactionRecord::getTxID() +{ + return hash.ToString() + strprintf("-%03d", idx); +} + diff --git a/src/qt/transactionrecord.h b/src/qt/transactionrecord.h new file mode 100644 index 0000000000..0050c878ee --- /dev/null +++ b/src/qt/transactionrecord.h @@ -0,0 +1,118 @@ +#ifndef TRANSACTIONRECORD_H +#define TRANSACTIONRECORD_H + +#include "uint256.h" + +#include <QList> + +class CWallet; +class CWalletTx; + +class TransactionStatus +{ +public: + TransactionStatus(): + confirmed(false), sortKey(""), maturity(Mature), + matures_in(0), status(Offline), depth(0), open_for(0), cur_num_blocks(-1) + { } + + enum Maturity + { + Immature, + Mature, + MaturesWarning, /* Will likely not mature because no nodes have confirmed */ + NotAccepted + }; + + enum Status { + OpenUntilDate, + OpenUntilBlock, + Offline, + Unconfirmed, + HaveConfirmations + }; + + bool confirmed; + std::string sortKey; + + /* For "Generated" transactions */ + Maturity maturity; + int matures_in; + + /* Reported status */ + Status status; + int64 depth; + int64 open_for; /* Timestamp if status==OpenUntilDate, otherwise number of blocks */ + + /* Current number of blocks (to know whether cached status is still valid. */ + int cur_num_blocks; +}; + +class TransactionRecord +{ +public: + enum Type + { + Other, + Generated, + SendToAddress, + SendToIP, + RecvWithAddress, + RecvFromIP, + SendToSelf + }; + + /* Number of confirmation needed for transaction */ + static const int NumConfirmations = 6; + + TransactionRecord(): + hash(), time(0), type(Other), address(""), debit(0), credit(0), idx(0) + { + } + + TransactionRecord(uint256 hash, int64 time): + hash(hash), time(time), type(Other), address(""), debit(0), + credit(0), idx(0) + { + } + + TransactionRecord(uint256 hash, int64 time, + Type type, const std::string &address, + int64 debit, int64 credit): + hash(hash), time(time), type(type), address(address), debit(debit), credit(credit), + idx(0) + { + } + + /* Decompose CWallet transaction to model transaction records. + */ + static bool showTransaction(const CWalletTx &wtx); + static QList<TransactionRecord> decomposeTransaction(const CWallet *wallet, const CWalletTx &wtx); + + /* Fixed */ + uint256 hash; + int64 time; + Type type; + std::string address; + int64 debit; + int64 credit; + + /* Subtransaction index, for sort key */ + int idx; + + /* Status: can change with block chain update */ + TransactionStatus status; + + /* Return the unique identifier for this transaction (part) */ + std::string getTxID(); + + /* Update status from wallet tx. + */ + void updateStatus(const CWalletTx &wtx); + + /* Is a status update needed? + */ + bool statusUpdateNeeded(); +}; + +#endif // TRANSACTIONRECORD_H diff --git a/src/qt/transactiontablemodel.cpp b/src/qt/transactiontablemodel.cpp new file mode 100644 index 0000000000..0e1733f156 --- /dev/null +++ b/src/qt/transactiontablemodel.cpp @@ -0,0 +1,622 @@ +#include "transactiontablemodel.h" +#include "guiutil.h" +#include "transactionrecord.h" +#include "guiconstants.h" +#include "transactiondesc.h" +#include "walletmodel.h" +#include "optionsmodel.h" +#include "addresstablemodel.h" +#include "bitcoinunits.h" + +#include "headers.h" + +#include <QLocale> +#include <QList> +#include <QColor> +#include <QTimer> +#include <QIcon> +#include <QDateTime> +#include <QtAlgorithms> + +// Amount column is right-aligned it contains numbers +static int column_alignments[] = { + Qt::AlignLeft|Qt::AlignVCenter, + Qt::AlignLeft|Qt::AlignVCenter, + Qt::AlignLeft|Qt::AlignVCenter, + Qt::AlignLeft|Qt::AlignVCenter, + Qt::AlignRight|Qt::AlignVCenter + }; + +// Comparison operator for sort/binary search of model tx list +struct TxLessThan +{ + bool operator()(const TransactionRecord &a, const TransactionRecord &b) const + { + return a.hash < b.hash; + } + bool operator()(const TransactionRecord &a, const uint256 &b) const + { + return a.hash < b; + } + bool operator()(const uint256 &a, const TransactionRecord &b) const + { + return a < b.hash; + } +}; + +// Private implementation +struct TransactionTablePriv +{ + TransactionTablePriv(CWallet *wallet, TransactionTableModel *parent): + wallet(wallet), + parent(parent) + { + } + CWallet *wallet; + TransactionTableModel *parent; + + /* Local cache of wallet. + * As it is in the same order as the CWallet, by definition + * this is sorted by sha256. + */ + QList<TransactionRecord> cachedWallet; + + /* Query entire wallet anew from core. + */ + void refreshWallet() + { +#ifdef WALLET_UPDATE_DEBUG + qDebug() << "refreshWallet"; +#endif + cachedWallet.clear(); + CRITICAL_BLOCK(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)); + } + } + } + + /* 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. + */ + void updateWallet(const QList<uint256> &updated) + { + // 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); + + CRITICAL_BLOCK(wallet->cs_wallet) + { + for(int update_idx = updated_sorted.size()-1; update_idx >= 0; --update_idx) + { + 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; + } + +#ifdef WALLET_UPDATE_DEBUG + qDebug() << " " << QString::fromStdString(hash.ToString()) << inWallet << " " << inModel + << lowerIndex << "-" << upperIndex; +#endif + + if(inWallet && !inModel) + { + // Added -- insert at the right position + QList<TransactionRecord> toInsert = + TransactionRecord::decomposeTransaction(wallet, mi->second); + if(!toInsert.isEmpty()) /* only if something to insert */ + { + parent->beginInsertRows(QModelIndex(), lowerIndex, lowerIndex+toInsert.size()-1); + int insert_idx = lowerIndex; + foreach(const TransactionRecord &rec, toInsert) + { + cachedWallet.insert(insert_idx, rec); + insert_idx += 1; + } + 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) + { + // Updated -- nothing to do, status update will take care of this + } + } + } + } + + int size() + { + return cachedWallet.size(); + } + + TransactionRecord *index(int idx) + { + if(idx >= 0 && idx < cachedWallet.size()) + { + TransactionRecord *rec = &cachedWallet[idx]; + + // If a status update is needed (blocks came in since last check), + // update the status of this transaction from the wallet. Otherwise, + // simply re-use the cached status. + if(rec->statusUpdateNeeded()) + { + CRITICAL_BLOCK(wallet->cs_wallet) + { + std::map<uint256, CWalletTx>::iterator mi = wallet->mapWallet.find(rec->hash); + + if(mi != wallet->mapWallet.end()) + { + rec->updateStatus(mi->second); + } + } + } + return rec; + } + else + { + return 0; + } + } + + QString describe(TransactionRecord *rec) + { + CRITICAL_BLOCK(wallet->cs_wallet) + { + std::map<uint256, CWalletTx>::iterator mi = wallet->mapWallet.find(rec->hash); + if(mi != wallet->mapWallet.end()) + { + return TransactionDesc::toHTML(wallet, mi->second); + } + } + return QString(""); + } + +}; + +TransactionTableModel::TransactionTableModel(CWallet* wallet, WalletModel *parent): + QAbstractTableModel(parent), + wallet(wallet), + walletModel(parent), + priv(new TransactionTablePriv(wallet, this)) +{ + columns << QString() << tr("Date") << tr("Type") << tr("Address") << tr("Amount"); + + priv->refreshWallet(); + + QTimer *timer = new QTimer(this); + connect(timer, SIGNAL(timeout()), this, SLOT(update())); + timer->start(MODEL_UPDATE_DELAY); +} + +TransactionTableModel::~TransactionTableModel() +{ + delete priv; +} + +void TransactionTableModel::update() +{ + QList<uint256> updated; + + // Check if there are changes to wallet map + TRY_CRITICAL_BLOCK(wallet->cs_wallet) + { + if(!wallet->vWalletUpdated.empty()) + { + BOOST_FOREACH(uint256 hash, wallet->vWalletUpdated) + { + updated.append(hash); + } + wallet->vWalletUpdated.clear(); + } + } + + if(!updated.empty()) + { + priv->updateWallet(updated); + + // Status (number of confirmations) and (possibly) description + // columns changed for all rows. + emit dataChanged(index(0, Status), index(priv->size()-1, Status)); + emit dataChanged(index(0, ToAddress), index(priv->size()-1, ToAddress)); + } +} + +int TransactionTableModel::rowCount(const QModelIndex &parent) const +{ + Q_UNUSED(parent); + return priv->size(); +} + +int TransactionTableModel::columnCount(const QModelIndex &parent) const +{ + Q_UNUSED(parent); + return columns.length(); +} + +QString TransactionTableModel::formatTxStatus(const TransactionRecord *wtx) const +{ + QString status; + + switch(wtx->status.status) + { + case TransactionStatus::OpenUntilBlock: + status = tr("Open for %n block(s)","",wtx->status.open_for); + break; + case TransactionStatus::OpenUntilDate: + status = tr("Open until %1").arg(GUIUtil::dateTimeStr(wtx->status.open_for)); + break; + case TransactionStatus::Offline: + status = tr("Offline (%1 confirmations)").arg(wtx->status.depth); + break; + case TransactionStatus::Unconfirmed: + status = tr("Unconfirmed (%1 of %2 confirmations)").arg(wtx->status.depth).arg(TransactionRecord::NumConfirmations); + break; + case TransactionStatus::HaveConfirmations: + status = tr("Confirmed (%1 confirmations)").arg(wtx->status.depth); + break; + } + if(wtx->type == TransactionRecord::Generated) + { + status += "\n"; + switch(wtx->status.maturity) + { + case TransactionStatus::Immature: + status += tr("Mined balance will be available in %n more blocks", "", + wtx->status.matures_in); + break; + case TransactionStatus::Mature: + break; + case TransactionStatus::MaturesWarning: + status += tr("This block was not received by any other nodes and will probably not be accepted!"); + break; + case TransactionStatus::NotAccepted: + status += tr("Generated but not accepted"); + break; + } + } + + return status; +} + +QString TransactionTableModel::formatTxDate(const TransactionRecord *wtx) const +{ + if(wtx->time) + { + return GUIUtil::dateTimeStr(wtx->time); + } + else + { + return QString(); + } +} + +/* Look up address in address book, if found return label (address) + otherwise just return (address) + */ +QString TransactionTableModel::lookupAddress(const std::string &address, bool tooltip) const +{ + QString label = walletModel->getAddressTableModel()->labelForAddress(QString::fromStdString(address)); + QString description; + if(!label.isEmpty()) + { + description += label + QString(" "); + } + if(label.isEmpty() || walletModel->getOptionsModel()->getDisplayAddresses() || tooltip) + { + description += QString("(") + QString::fromStdString(address) + QString(")"); + } + return description; +} + +QString TransactionTableModel::formatTxType(const TransactionRecord *wtx) const +{ + switch(wtx->type) + { + case TransactionRecord::RecvWithAddress: + return tr("Received with"); + case TransactionRecord::RecvFromIP: + return tr("Received from IP"); + case TransactionRecord::SendToAddress: + return tr("Sent to"); + case TransactionRecord::SendToIP: + return tr("Sent to IP"); + case TransactionRecord::SendToSelf: + return tr("Payment to yourself"); + case TransactionRecord::Generated: + return tr("Mined"); + default: + return QString(); + } +} + +QVariant TransactionTableModel::txAddressDecoration(const TransactionRecord *wtx) const +{ + switch(wtx->type) + { + case TransactionRecord::Generated: + return QIcon(":/icons/tx_mined"); + case TransactionRecord::RecvWithAddress: + case TransactionRecord::RecvFromIP: + return QIcon(":/icons/tx_input"); + case TransactionRecord::SendToAddress: + case TransactionRecord::SendToIP: + return QIcon(":/icons/tx_output"); + default: + return QIcon(":/icons/tx_inout"); + } + return QVariant(); +} + +QString TransactionTableModel::formatTxToAddress(const TransactionRecord *wtx, bool tooltip) const +{ + switch(wtx->type) + { + case TransactionRecord::RecvFromIP: + return QString::fromStdString(wtx->address); + case TransactionRecord::RecvWithAddress: + case TransactionRecord::SendToAddress: + return lookupAddress(wtx->address, tooltip); + case TransactionRecord::SendToIP: + return QString::fromStdString(wtx->address); + case TransactionRecord::SendToSelf: + case TransactionRecord::Generated: + default: + return tr("(n/a)"); + } +} + +QVariant TransactionTableModel::addressColor(const TransactionRecord *wtx) const +{ + // Show addresses without label in a less visible color + switch(wtx->type) + { + case TransactionRecord::RecvWithAddress: + case TransactionRecord::SendToAddress: + { + QString label = walletModel->getAddressTableModel()->labelForAddress(QString::fromStdString(wtx->address)); + if(label.isEmpty()) + return COLOR_BAREADDRESS; + } break; + case TransactionRecord::SendToSelf: + case TransactionRecord::Generated: + return COLOR_BAREADDRESS; + default: + break; + } + return QVariant(); +} + +QString TransactionTableModel::formatTxAmount(const TransactionRecord *wtx, bool showUnconfirmed) const +{ + QString str = BitcoinUnits::format(walletModel->getOptionsModel()->getDisplayUnit(), wtx->credit + wtx->debit); + if(showUnconfirmed) + { + if(!wtx->status.confirmed || wtx->status.maturity != TransactionStatus::Mature) + { + str = QString("[") + str + QString("]"); + } + } + return QString(str); +} + +QVariant TransactionTableModel::txStatusDecoration(const TransactionRecord *wtx) const +{ + if(wtx->type == TransactionRecord::Generated) + { + switch(wtx->status.maturity) + { + case TransactionStatus::Immature: { + int total = wtx->status.depth + wtx->status.matures_in; + int part = (wtx->status.depth * 4 / total) + 1; + return QIcon(QString(":/icons/transaction_%1").arg(part)); + } + case TransactionStatus::Mature: + return QIcon(":/icons/transaction_confirmed"); + case TransactionStatus::MaturesWarning: + case TransactionStatus::NotAccepted: + return QIcon(":/icons/transaction_0"); + } + } + else + { + switch(wtx->status.status) + { + case TransactionStatus::OpenUntilBlock: + case TransactionStatus::OpenUntilDate: + return QColor(64,64,255); + break; + case TransactionStatus::Offline: + return QColor(192,192,192); + case TransactionStatus::Unconfirmed: + switch(wtx->status.depth) + { + case 0: return QIcon(":/icons/transaction_0"); + case 1: return QIcon(":/icons/transaction_1"); + case 2: return QIcon(":/icons/transaction_2"); + case 3: return QIcon(":/icons/transaction_3"); + case 4: return QIcon(":/icons/transaction_4"); + default: return QIcon(":/icons/transaction_5"); + }; + case TransactionStatus::HaveConfirmations: + return QIcon(":/icons/transaction_confirmed"); + } + } + return QColor(0,0,0); +} + +QString TransactionTableModel::formatTooltip(const TransactionRecord *rec) const +{ + QString tooltip = formatTxStatus(rec) + QString("\n") + formatTxType(rec); + if(rec->type==TransactionRecord::RecvFromIP || rec->type==TransactionRecord::SendToIP || + rec->type==TransactionRecord::SendToAddress || rec->type==TransactionRecord::RecvWithAddress) + { + tooltip += QString(" ") + formatTxToAddress(rec, true); + } + return tooltip; +} + +QVariant TransactionTableModel::data(const QModelIndex &index, int role) const +{ + if(!index.isValid()) + return QVariant(); + TransactionRecord *rec = static_cast<TransactionRecord*>(index.internalPointer()); + + switch(role) + { + case Qt::DecorationRole: + switch(index.column()) + { + case Status: + return txStatusDecoration(rec); + case ToAddress: + return txAddressDecoration(rec); + } + break; + case Qt::DisplayRole: + switch(index.column()) + { + case Date: + return formatTxDate(rec); + case Type: + return formatTxType(rec); + case ToAddress: + return formatTxToAddress(rec, false); + case Amount: + return formatTxAmount(rec); + } + break; + case Qt::EditRole: + // Edit role is used for sorting, so return the unformatted values + switch(index.column()) + { + case Status: + return QString::fromStdString(rec->status.sortKey); + case Date: + return rec->time; + case Type: + return formatTxType(rec); + case ToAddress: + return formatTxToAddress(rec, true); + case Amount: + return rec->credit + rec->debit; + } + break; + case Qt::ToolTipRole: + return formatTooltip(rec); + case Qt::TextAlignmentRole: + return column_alignments[index.column()]; + case Qt::ForegroundRole: + // Non-confirmed transactions are grey + if(!rec->status.confirmed) + { + return COLOR_UNCONFIRMED; + } + if(index.column() == Amount && (rec->credit+rec->debit) < 0) + { + return COLOR_NEGATIVE; + } + if(index.column() == ToAddress) + { + return addressColor(rec); + } + break; + case TypeRole: + return rec->type; + case DateRole: + return QDateTime::fromTime_t(static_cast<uint>(rec->time)); + case LongDescriptionRole: + return priv->describe(rec); + case AddressRole: + return QString::fromStdString(rec->address); + case LabelRole: + return walletModel->getAddressTableModel()->labelForAddress(QString::fromStdString(rec->address)); + case AmountRole: + return rec->credit + rec->debit; + case TxIDRole: + return QString::fromStdString(rec->getTxID()); + case ConfirmedRole: + // Return True if transaction counts for balance + return rec->status.confirmed && !(rec->type == TransactionRecord::Generated && + rec->status.maturity != TransactionStatus::Mature); + case FormattedAmountRole: + return formatTxAmount(rec, false); + } + return QVariant(); +} + +QVariant TransactionTableModel::headerData(int section, Qt::Orientation orientation, int role) const +{ + if(orientation == Qt::Horizontal) + { + if(role == Qt::DisplayRole) + { + return columns[section]; + } + else if (role == Qt::TextAlignmentRole) + { + return column_alignments[section]; + } else if (role == Qt::ToolTipRole) + { + switch(section) + { + case Status: + return tr("Transaction status. Hover over this field to show number of confirmations."); + case Date: + return tr("Date and time that the transaction was received."); + case Type: + return tr("Type of transaction."); + case ToAddress: + return tr("Destination address of transaction."); + case Amount: + return tr("Amount removed from or added to balance."); + } + } + } + return QVariant(); +} + +QModelIndex TransactionTableModel::index(int row, int column, const QModelIndex &parent) const +{ + Q_UNUSED(parent); + TransactionRecord *data = priv->index(row); + if(data) + { + return createIndex(row, column, priv->index(row)); + } + else + { + return QModelIndex(); + } +} + diff --git a/src/qt/transactiontablemodel.h b/src/qt/transactiontablemodel.h new file mode 100644 index 0000000000..da55495e1e --- /dev/null +++ b/src/qt/transactiontablemodel.h @@ -0,0 +1,79 @@ +#ifndef TRANSACTIONTABLEMODEL_H +#define TRANSACTIONTABLEMODEL_H + +#include <QAbstractTableModel> +#include <QStringList> + +class CWallet; +class TransactionTablePriv; +class TransactionRecord; +class WalletModel; + +class TransactionTableModel : public QAbstractTableModel +{ + Q_OBJECT +public: + explicit TransactionTableModel(CWallet* wallet, WalletModel *parent = 0); + ~TransactionTableModel(); + + enum { + Status = 0, + Date = 1, + Type = 2, + ToAddress = 3, + Amount = 4 + } ColumnIndex; + + // Roles to get specific information from a transaction row + // These are independent of column + enum { + // Type of transaction + TypeRole = Qt::UserRole, + // Date and time this transaction was created + DateRole, + // Long description (HTML format) + LongDescriptionRole, + // Address of transaction + AddressRole, + // Label of address related to transaction + LabelRole, + // Net amount of transaction + AmountRole, + // Unique identifier + TxIDRole, + // Is transaction confirmed? + ConfirmedRole, + // Formatted amount, without brackets when unconfirmed + FormattedAmountRole + } RoleIndex; + + int rowCount(const QModelIndex &parent) const; + int columnCount(const QModelIndex &parent) const; + QVariant data(const QModelIndex &index, int role) const; + QVariant headerData(int section, Qt::Orientation orientation, int role) const; + QModelIndex index(int row, int column, const QModelIndex & parent = QModelIndex()) const; +private: + CWallet* wallet; + WalletModel *walletModel; + QStringList columns; + TransactionTablePriv *priv; + + QString lookupAddress(const std::string &address, bool tooltip) const; + QVariant addressColor(const TransactionRecord *wtx) const; + QString formatTxStatus(const TransactionRecord *wtx) const; + QString formatTxDate(const TransactionRecord *wtx) const; + QString formatTxType(const TransactionRecord *wtx) const; + QString formatTxToAddress(const TransactionRecord *wtx, bool tooltip) const; + QString formatTxAmount(const TransactionRecord *wtx, bool showUnconfirmed=true) const; + QString formatTooltip(const TransactionRecord *rec) const; + QVariant txStatusDecoration(const TransactionRecord *wtx) const; + QVariant txAddressDecoration(const TransactionRecord *wtx) const; + +private slots: + void update(); + + friend class TransactionTablePriv; +}; + +#endif + diff --git a/src/qt/transactionview.cpp b/src/qt/transactionview.cpp new file mode 100644 index 0000000000..b2777b7b20 --- /dev/null +++ b/src/qt/transactionview.cpp @@ -0,0 +1,385 @@ +#include "transactionview.h" + +#include "transactionfilterproxy.h" +#include "transactionrecord.h" +#include "walletmodel.h" +#include "addresstablemodel.h" +#include "transactiontablemodel.h" +#include "bitcoinunits.h" +#include "csvmodelwriter.h" +#include "transactiondescdialog.h" +#include "editaddressdialog.h" +#include "optionsmodel.h" + +#include <QScrollBar> +#include <QComboBox> +#include <QDoubleValidator> +#include <QHBoxLayout> +#include <QVBoxLayout> +#include <QLineEdit> +#include <QTableView> +#include <QHeaderView> +#include <QPushButton> +#include <QFileDialog> +#include <QMessageBox> +#include <QPoint> +#include <QMenu> +#include <QApplication> +#include <QClipboard> +#include <QLabel> +#include <QDateTimeEdit> + +TransactionView::TransactionView(QWidget *parent) : + QWidget(parent), model(0), transactionProxyModel(0), + transactionView(0) +{ + // Build filter row + setContentsMargins(0,0,0,0); + + QHBoxLayout *hlayout = new QHBoxLayout(); + hlayout->setContentsMargins(0,0,0,0); + hlayout->setSpacing(0); + + hlayout->addSpacing(23); + + dateWidget = new QComboBox(this); + dateWidget->setMaximumWidth(120); + dateWidget->setMinimumWidth(120); + dateWidget->addItem(tr("All"), All); + dateWidget->addItem(tr("Today"), Today); + dateWidget->addItem(tr("This week"), ThisWeek); + dateWidget->addItem(tr("This month"), ThisMonth); + dateWidget->addItem(tr("Last month"), LastMonth); + dateWidget->addItem(tr("This year"), ThisYear); + dateWidget->addItem(tr("Range..."), Range); + hlayout->addWidget(dateWidget); + + typeWidget = new QComboBox(this); + typeWidget->setMaximumWidth(120); + typeWidget->setMinimumWidth(120); + + typeWidget->addItem(tr("All"), TransactionFilterProxy::ALL_TYPES); + typeWidget->addItem(tr("Received with"), TransactionFilterProxy::TYPE(TransactionRecord::RecvWithAddress) | + TransactionFilterProxy::TYPE(TransactionRecord::RecvFromIP)); + typeWidget->addItem(tr("Sent to"), TransactionFilterProxy::TYPE(TransactionRecord::SendToAddress) | + TransactionFilterProxy::TYPE(TransactionRecord::SendToIP)); + typeWidget->addItem(tr("To yourself"), TransactionFilterProxy::TYPE(TransactionRecord::SendToSelf)); + typeWidget->addItem(tr("Mined"), TransactionFilterProxy::TYPE(TransactionRecord::Generated)); + typeWidget->addItem(tr("Other"), TransactionFilterProxy::TYPE(TransactionRecord::Other)); + + hlayout->addWidget(typeWidget); + + addressWidget = new QLineEdit(this); +#if QT_VERSION >= 0x040700 + addressWidget->setPlaceholderText(tr("Enter address or label to search")); +#endif + hlayout->addWidget(addressWidget); + + amountWidget = new QLineEdit(this); +#if QT_VERSION >= 0x040700 + amountWidget->setPlaceholderText(tr("Min amount")); +#endif + amountWidget->setMaximumWidth(100); + amountWidget->setMinimumWidth(100); + amountWidget->setValidator(new QDoubleValidator(0, 1e20, 8, this)); + hlayout->addWidget(amountWidget); + + QVBoxLayout *vlayout = new QVBoxLayout(this); + vlayout->setContentsMargins(0,0,0,0); + vlayout->setSpacing(0); + //vlayout->addLayout(hlayout2); + + QTableView *view = new QTableView(this); + vlayout->addLayout(hlayout); + vlayout->addWidget(createDateRangeWidget()); + vlayout->addWidget(view); + vlayout->setSpacing(0); + int width = view->verticalScrollBar()->sizeHint().width(); + // Cover scroll bar width with spacing + hlayout->addSpacing(width); + // Always show scroll bar + view->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn); + view->setTabKeyNavigation(false); + view->setContextMenuPolicy(Qt::CustomContextMenu); + + transactionView = view; + + // Actions + QAction *copyAddressAction = new QAction(tr("Copy address"), this); + QAction *copyLabelAction = new QAction(tr("Copy label"), this); + QAction *editLabelAction = new QAction(tr("Edit label"), this); + QAction *showDetailsAction = new QAction(tr("Show details..."), this); + + contextMenu = new QMenu(); + contextMenu->addAction(copyAddressAction); + contextMenu->addAction(copyLabelAction); + contextMenu->addAction(editLabelAction); + contextMenu->addAction(showDetailsAction); + + // Connect actions + connect(dateWidget, SIGNAL(activated(int)), this, SLOT(chooseDate(int))); + connect(typeWidget, SIGNAL(activated(int)), this, SLOT(chooseType(int))); + connect(addressWidget, SIGNAL(textChanged(QString)), this, SLOT(changedPrefix(QString))); + connect(amountWidget, SIGNAL(textChanged(QString)), this, SLOT(changedAmount(QString))); + + connect(view, SIGNAL(doubleClicked(QModelIndex)), this, SIGNAL(doubleClicked(QModelIndex))); + + connect(view, + SIGNAL(customContextMenuRequested(QPoint)), + this, + SLOT(contextualMenu(QPoint))); + + connect(copyAddressAction, SIGNAL(triggered()), this, SLOT(copyAddress())); + connect(copyLabelAction, SIGNAL(triggered()), this, SLOT(copyLabel())); + connect(editLabelAction, SIGNAL(triggered()), this, SLOT(editLabel())); + connect(showDetailsAction, SIGNAL(triggered()), this, SLOT(showDetails())); +} + +void TransactionView::setModel(WalletModel *model) +{ + this->model = model; + + transactionProxyModel = new TransactionFilterProxy(this); + transactionProxyModel->setSourceModel(model->getTransactionTableModel()); + transactionProxyModel->setDynamicSortFilter(true); + + transactionProxyModel->setSortRole(Qt::EditRole); + + transactionView->setModel(transactionProxyModel); + transactionView->setAlternatingRowColors(true); + transactionView->setSelectionBehavior(QAbstractItemView::SelectRows); + transactionView->setSelectionMode(QAbstractItemView::ExtendedSelection); + transactionView->setSortingEnabled(true); + transactionView->sortByColumn(TransactionTableModel::Status, Qt::DescendingOrder); + transactionView->verticalHeader()->hide(); + + transactionView->horizontalHeader()->resizeSection( + TransactionTableModel::Status, 23); + transactionView->horizontalHeader()->resizeSection( + TransactionTableModel::Date, 120); + transactionView->horizontalHeader()->resizeSection( + TransactionTableModel::Type, 120); + transactionView->horizontalHeader()->setResizeMode( + TransactionTableModel::ToAddress, QHeaderView::Stretch); + transactionView->horizontalHeader()->resizeSection( + TransactionTableModel::Amount, 100); + +} + +void TransactionView::chooseDate(int idx) +{ + QDate current = QDate::currentDate(); + dateRangeWidget->setVisible(false); + switch(dateWidget->itemData(idx).toInt()) + { + case All: + transactionProxyModel->setDateRange( + TransactionFilterProxy::MIN_DATE, + TransactionFilterProxy::MAX_DATE); + break; + case Today: + transactionProxyModel->setDateRange( + QDateTime(current), + TransactionFilterProxy::MAX_DATE); + break; + case ThisWeek: { + // Find last monday + QDate startOfWeek = current.addDays(-(current.dayOfWeek()-1)); + transactionProxyModel->setDateRange( + QDateTime(startOfWeek), + TransactionFilterProxy::MAX_DATE); + + } break; + case ThisMonth: + transactionProxyModel->setDateRange( + QDateTime(QDate(current.year(), current.month(), 1)), + TransactionFilterProxy::MAX_DATE); + break; + case LastMonth: + transactionProxyModel->setDateRange( + QDateTime(QDate(current.year(), current.month()-1, 1)), + QDateTime(QDate(current.year(), current.month(), 1))); + break; + case ThisYear: + transactionProxyModel->setDateRange( + QDateTime(QDate(current.year(), 1, 1)), + TransactionFilterProxy::MAX_DATE); + break; + case Range: + dateRangeWidget->setVisible(true); + dateRangeChanged(); + break; + } +} + +void TransactionView::chooseType(int idx) +{ + transactionProxyModel->setTypeFilter( + typeWidget->itemData(idx).toInt()); +} + +void TransactionView::changedPrefix(const QString &prefix) +{ + transactionProxyModel->setAddressPrefix(prefix); +} + +void TransactionView::changedAmount(const QString &amount) +{ + qint64 amount_parsed = 0; + if(BitcoinUnits::parse(model->getOptionsModel()->getDisplayUnit(), amount, &amount_parsed)) + { + transactionProxyModel->setMinAmount(amount_parsed); + } + else + { + transactionProxyModel->setMinAmount(0); + } +} + +void TransactionView::exportClicked() +{ + // CSV is currently the only supported format + QString filename = QFileDialog::getSaveFileName( + this, + tr("Export Transaction Data"), + QDir::currentPath(), + tr("Comma separated file (*.csv)")); + + if (filename.isNull()) return; + + CSVModelWriter writer(filename); + + // name, column, role + writer.setModel(transactionProxyModel); + writer.addColumn(tr("Confirmed"), 0, TransactionTableModel::ConfirmedRole); + writer.addColumn(tr("Date"), 0, TransactionTableModel::DateRole); + writer.addColumn(tr("Type"), TransactionTableModel::Type, Qt::EditRole); + writer.addColumn(tr("Label"), 0, TransactionTableModel::LabelRole); + writer.addColumn(tr("Address"), 0, TransactionTableModel::AddressRole); + writer.addColumn(tr("Amount"), 0, TransactionTableModel::FormattedAmountRole); + writer.addColumn(tr("ID"), 0, TransactionTableModel::TxIDRole); + + if(!writer.write()) + { + QMessageBox::critical(this, tr("Error exporting"), tr("Could not write to file %1.").arg(filename), + QMessageBox::Abort, QMessageBox::Abort); + } +} + +void TransactionView::contextualMenu(const QPoint &point) +{ + QModelIndex index = transactionView->indexAt(point); + if(index.isValid()) + { + contextMenu->exec(QCursor::pos()); + } +} + +void TransactionView::copyAddress() +{ + QModelIndexList selection = transactionView->selectionModel()->selectedRows(); + if(!selection.isEmpty()) + { + QApplication::clipboard()->setText(selection.at(0).data(TransactionTableModel::AddressRole).toString()); + } +} + +void TransactionView::copyLabel() +{ + QModelIndexList selection = transactionView->selectionModel()->selectedRows(); + if(!selection.isEmpty()) + { + QApplication::clipboard()->setText(selection.at(0).data(TransactionTableModel::LabelRole).toString()); + } +} + +void TransactionView::editLabel() +{ + QModelIndexList selection = transactionView->selectionModel()->selectedRows(); + if(!selection.isEmpty()) + { + AddressTableModel *addressBook = model->getAddressTableModel(); + QString address = selection.at(0).data(TransactionTableModel::AddressRole).toString(); + if(address.isEmpty()) + { + // If this transaction has no associated address, exit + return; + } + int idx = addressBook->lookupAddress(address); + if(idx != -1) + { + // Edit sending / receiving address + QModelIndex modelIdx = addressBook->index(idx, 0, QModelIndex()); + // Determine type of address, launch appropriate editor dialog type + QString type = modelIdx.data(AddressTableModel::TypeRole).toString(); + + EditAddressDialog dlg(type==AddressTableModel::Receive + ? EditAddressDialog::EditReceivingAddress + : EditAddressDialog::EditSendingAddress, + this); + dlg.setModel(addressBook); + dlg.loadRow(idx); + dlg.exec(); + } + else + { + // Add sending address + EditAddressDialog dlg(EditAddressDialog::NewSendingAddress, + this); + dlg.exec(); + } + } +} + +void TransactionView::showDetails() +{ + QModelIndexList selection = transactionView->selectionModel()->selectedRows(); + if(!selection.isEmpty()) + { + TransactionDescDialog dlg(selection.at(0)); + dlg.exec(); + } +} + +QWidget *TransactionView::createDateRangeWidget() +{ + dateRangeWidget = new QFrame(); + dateRangeWidget->setFrameStyle(QFrame::Panel | QFrame::Raised); + dateRangeWidget->setContentsMargins(1,1,1,1); + QHBoxLayout *layout = new QHBoxLayout(dateRangeWidget); + layout->setContentsMargins(0,0,0,0); + layout->addSpacing(23); + layout->addWidget(new QLabel(tr("Range:"))); + + dateFrom = new QDateTimeEdit(this); + dateFrom->setDisplayFormat("dd/MM/yy"); + dateFrom->setCalendarPopup(true); + dateFrom->setMinimumWidth(100); + dateFrom->setDate(QDate::currentDate().addDays(-7)); + layout->addWidget(dateFrom); + layout->addWidget(new QLabel(tr("to"))); + + dateTo = new QDateTimeEdit(this); + dateTo->setDisplayFormat("dd/MM/yy"); + dateTo->setCalendarPopup(true); + dateTo->setMinimumWidth(100); + dateTo->setDate(QDate::currentDate()); + layout->addWidget(dateTo); + layout->addStretch(); + + // Hide by default + dateRangeWidget->setVisible(false); + + // Notify on change + connect(dateFrom, SIGNAL(dateChanged(QDate)), this, SLOT(dateRangeChanged())); + connect(dateTo, SIGNAL(dateChanged(QDate)), this, SLOT(dateRangeChanged())); + + return dateRangeWidget; +} + +void TransactionView::dateRangeChanged() +{ + transactionProxyModel->setDateRange( + QDateTime(dateFrom->date()), + QDateTime(dateTo->date()).addDays(1)); +} diff --git a/src/qt/transactionview.h b/src/qt/transactionview.h new file mode 100644 index 0000000000..f4f815b162 --- /dev/null +++ b/src/qt/transactionview.h @@ -0,0 +1,77 @@ +#ifndef TRANSACTIONVIEW_H +#define TRANSACTIONVIEW_H + +#include <QWidget> + +class WalletModel; +class TransactionFilterProxy; + +QT_BEGIN_NAMESPACE +class QTableView; +class QComboBox; +class QLineEdit; +class QModelIndex; +class QMenu; +class QFrame; +class QDateTimeEdit; +QT_END_NAMESPACE + +class TransactionView : public QWidget +{ + Q_OBJECT +public: + explicit TransactionView(QWidget *parent = 0); + + void setModel(WalletModel *model); + + // Date ranges for filter + enum DateEnum + { + All, + Today, + ThisWeek, + ThisMonth, + LastMonth, + ThisYear, + Range + }; + +private: + WalletModel *model; + TransactionFilterProxy *transactionProxyModel; + QTableView *transactionView; + + QComboBox *dateWidget; + QComboBox *typeWidget; + QLineEdit *addressWidget; + QLineEdit *amountWidget; + + QMenu *contextMenu; + + QFrame *dateRangeWidget; + QDateTimeEdit *dateFrom; + QDateTimeEdit *dateTo; + + QWidget *createDateRangeWidget(); + +private slots: + void contextualMenu(const QPoint &); + void dateRangeChanged(); + +signals: + void doubleClicked(const QModelIndex&); + +public slots: + void chooseDate(int idx); + void chooseType(int idx); + void changedPrefix(const QString &prefix); + void changedAmount(const QString &amount); + void exportClicked(); + void showDetails(); + void copyAddress(); + void editLabel(); + void copyLabel(); + +}; + +#endif // TRANSACTIONVIEW_H diff --git a/src/qt/walletmodel.cpp b/src/qt/walletmodel.cpp new file mode 100644 index 0000000000..2f989661f0 --- /dev/null +++ b/src/qt/walletmodel.cpp @@ -0,0 +1,277 @@ +#include "walletmodel.h" +#include "guiconstants.h" +#include "optionsmodel.h" +#include "addresstablemodel.h" +#include "transactiontablemodel.h" + +#include "headers.h" + +#include <QTimer> +#include <QSet> + +WalletModel::WalletModel(CWallet *wallet, OptionsModel *optionsModel, QObject *parent) : + QObject(parent), wallet(wallet), optionsModel(optionsModel), addressTableModel(0), + transactionTableModel(0), + cachedBalance(0), cachedUnconfirmedBalance(0), cachedNumTransactions(0), + cachedEncryptionStatus(Unencrypted) +{ + // Until signal notifications is built into the bitcoin core, + // simply update everything after polling using a timer. + QTimer *timer = new QTimer(this); + connect(timer, SIGNAL(timeout()), this, SLOT(update())); + timer->start(MODEL_UPDATE_DELAY); + + addressTableModel = new AddressTableModel(wallet, this); + transactionTableModel = new TransactionTableModel(wallet, this); +} + +qint64 WalletModel::getBalance() const +{ + return wallet->GetBalance(); +} + +qint64 WalletModel::getUnconfirmedBalance() const +{ + return wallet->GetUnconfirmedBalance(); +} + +int WalletModel::getNumTransactions() const +{ + int numTransactions = 0; + CRITICAL_BLOCK(wallet->cs_wallet) + { + numTransactions = wallet->mapWallet.size(); + } + return numTransactions; +} + +void WalletModel::update() +{ + 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; + + addressTableModel->update(); +} + +bool WalletModel::validateAddress(const QString &address) +{ + CBitcoinAddress addressParsed(address.toStdString()); + return addressParsed.IsValid(); +} + +WalletModel::SendCoinsReturn WalletModel::sendCoins(const QList<SendCoinsRecipient> &recipients) +{ + qint64 total = 0; + QSet<QString> setAddress; + QString hex; + + if(recipients.empty()) + { + return OK; + } + + // Pre-check input data for validity + foreach(const SendCoinsRecipient &rcp, recipients) + { + if(!validateAddress(rcp.address)) + { + return InvalidAddress; + } + setAddress.insert(rcp.address); + + if(rcp.amount <= 0) + { + return InvalidAmount; + } + total += rcp.amount; + } + + if(recipients.size() > setAddress.size()) + { + return DuplicateAddress; + } + + if(total > getBalance()) + { + return AmountExceedsBalance; + } + + if((total + nTransactionFee) > getBalance()) + { + return SendCoinsReturn(AmountWithFeeExceedsBalance, nTransactionFee); + } + + CRITICAL_BLOCK(cs_main) + CRITICAL_BLOCK(wallet->cs_wallet) + { + // Sendmany + std::vector<std::pair<CScript, int64> > vecSend; + foreach(const SendCoinsRecipient &rcp, recipients) + { + CScript scriptPubKey; + scriptPubKey.SetBitcoinAddress(rcp.address.toStdString()); + vecSend.push_back(make_pair(scriptPubKey, rcp.amount)); + } + + CWalletTx wtx; + CReserveKey keyChange(wallet); + int64 nFeeRequired = 0; + bool fCreated = wallet->CreateTransaction(vecSend, wtx, keyChange, nFeeRequired); + + if(!fCreated) + { + if((total + nFeeRequired) > wallet->GetBalance()) + { + return SendCoinsReturn(AmountWithFeeExceedsBalance, nFeeRequired); + } + return TransactionCreationFailed; + } + if(!ThreadSafeAskFee(nFeeRequired, tr("Sending...").toStdString(), NULL)) + { + return Aborted; + } + if(!wallet->CommitTransaction(wtx, keyChange)) + { + return TransactionCommitFailed; + } + hex = QString::fromStdString(wtx.GetHash().GetHex()); + } + + // Add addresses that we've sent to to the address book + foreach(const SendCoinsRecipient &rcp, recipients) + { + std::string strAddress = rcp.address.toStdString(); + CRITICAL_BLOCK(wallet->cs_wallet) + { + if (!wallet->mapAddressBook.count(strAddress)) + wallet->SetAddressBookName(strAddress, rcp.label.toStdString()); + } + } + + // Update our model of the address table + addressTableModel->updateList(); + + return SendCoinsReturn(OK, 0, hex); +} + +OptionsModel *WalletModel::getOptionsModel() +{ + return optionsModel; +} + +AddressTableModel *WalletModel::getAddressTableModel() +{ + return addressTableModel; +} + +TransactionTableModel *WalletModel::getTransactionTableModel() +{ + return transactionTableModel; +} + +WalletModel::EncryptionStatus WalletModel::getEncryptionStatus() const +{ + if(!wallet->IsCrypted()) + { + return Unencrypted; + } + else if(wallet->IsLocked()) + { + return Locked; + } + else + { + return Unlocked; + } +} + +bool WalletModel::setWalletEncrypted(bool encrypted, const std::string &passphrase) +{ + if(encrypted) + { + // Encrypt + return wallet->EncryptWallet(passphrase); + } + else + { + // Decrypt -- TODO; not supported yet + return false; + } +} + +bool WalletModel::setWalletLocked(bool locked, const std::string &passPhrase) +{ + if(locked) + { + // Lock + return wallet->Lock(); + } + else + { + // Unlock + return wallet->Unlock(passPhrase); + } +} + +bool WalletModel::changePassphrase(const std::string &oldPass, const std::string &newPass) +{ + bool retval; + CRITICAL_BLOCK(wallet->cs_wallet) + { + wallet->Lock(); // Make sure wallet is locked before attempting pass change + retval = wallet->ChangeWalletPassphrase(oldPass, newPass); + } + return retval; +} + +// WalletModel::UnlockContext implementation +WalletModel::UnlockContext WalletModel::requestUnlock() +{ + bool was_locked = getEncryptionStatus() == Locked; + if(was_locked) + { + // Request UI to unlock wallet + emit requireUnlock(); + } + // If wallet is still locked, unlock was failed or cancelled, mark context as invalid + bool valid = getEncryptionStatus() != Locked; + + return UnlockContext(this, valid, was_locked); +} + +WalletModel::UnlockContext::UnlockContext(WalletModel *wallet, bool valid, bool relock): + wallet(wallet), + valid(valid), + relock(relock) +{ +} + +WalletModel::UnlockContext::~UnlockContext() +{ + if(valid && relock) + { + wallet->setWalletLocked(true); + } +} + +void WalletModel::UnlockContext::CopyFrom(const UnlockContext& rhs) +{ + // Transfer context; old object no longer relocks wallet + *this = rhs; + rhs.relock = false; +} diff --git a/src/qt/walletmodel.h b/src/qt/walletmodel.h new file mode 100644 index 0000000000..b7b6973b3b --- /dev/null +++ b/src/qt/walletmodel.h @@ -0,0 +1,143 @@ +#ifndef WALLETMODEL_H +#define WALLETMODEL_H + +#include <QObject> +#include <string> + +class OptionsModel; +class AddressTableModel; +class TransactionTableModel; +class CWallet; + +struct SendCoinsRecipient +{ + QString address; + QString label; + qint64 amount; +}; + +// Interface to Bitcoin wallet from Qt view code +class WalletModel : public QObject +{ + Q_OBJECT +public: + explicit WalletModel(CWallet *wallet, OptionsModel *optionsModel, QObject *parent = 0); + + enum StatusCode // Returned by sendCoins + { + OK, + InvalidAmount, + InvalidAddress, + AmountExceedsBalance, + AmountWithFeeExceedsBalance, + DuplicateAddress, + TransactionCreationFailed, // Error returned when wallet is still locked + TransactionCommitFailed, + Aborted, + MiscError + }; + + enum EncryptionStatus + { + Unencrypted, // !wallet->IsCrypted() + Locked, // wallet->IsCrypted() && wallet->IsLocked() + Unlocked // wallet->IsCrypted() && !wallet->IsLocked() + }; + + OptionsModel *getOptionsModel(); + AddressTableModel *getAddressTableModel(); + TransactionTableModel *getTransactionTableModel(); + + qint64 getBalance() const; + qint64 getUnconfirmedBalance() const; + int getNumTransactions() const; + EncryptionStatus getEncryptionStatus() const; + + // Check address for validity + bool validateAddress(const QString &address); + + // Return status record for SendCoins, contains error id + information + struct SendCoinsReturn + { + SendCoinsReturn(StatusCode status, + qint64 fee=0, + QString hex=QString()): + status(status), fee(fee), hex(hex) {} + StatusCode status; + qint64 fee; // is used in case status is "AmountWithFeeExceedsBalance" + QString hex; // is filled with the transaction hash if status is "OK" + }; + + // Send coins to a list of recipients + SendCoinsReturn sendCoins(const QList<SendCoinsRecipient> &recipients); + + // Wallet encryption + bool setWalletEncrypted(bool encrypted, const std::string &passphrase); + // Passphrase only needed when unlocking + bool setWalletLocked(bool locked, const std::string &passPhrase=std::string()); + bool changePassphrase(const std::string &oldPass, const std::string &newPass); + + // RAI object for unlocking wallet, returned by requestUnlock() + class UnlockContext + { + public: + UnlockContext(WalletModel *wallet, bool valid, bool relock); + ~UnlockContext(); + + bool isValid() const { return valid; } + + // Copy operator and constructor transfer the context + UnlockContext(const UnlockContext& obj) { CopyFrom(obj); } + UnlockContext& operator=(const UnlockContext& rhs) { CopyFrom(rhs); return *this; } + private: + WalletModel *wallet; + bool valid; + mutable bool relock; // mutable, as it can be set to false by copying + + void CopyFrom(const UnlockContext& rhs); + }; + + UnlockContext requestUnlock(); + +private: + CWallet *wallet; + + // Wallet has an options model for wallet-specific options + // (transaction fee, for example) + OptionsModel *optionsModel; + + AddressTableModel *addressTableModel; + TransactionTableModel *transactionTableModel; + + // Cache some values to be able to detect changes + qint64 cachedBalance; + qint64 cachedUnconfirmedBalance; + qint64 cachedNumTransactions; + EncryptionStatus cachedEncryptionStatus; + +signals: + // Signal that balance in wallet changed + void balanceChanged(qint64 balance, qint64 unconfirmedBalance); + + // Number of transactions in wallet changed + void numTransactionsChanged(int count); + + // Encryption status of wallet changed + void encryptionStatusChanged(int status); + + // Signal emitted when wallet needs to be unlocked + // It is valid behaviour for listeners to keep the wallet locked after this signal; + // this means that the unlocking failed or was cancelled. + void requireUnlock(); + + // Asynchronous error notification + void error(const QString &title, const QString &message); + +public slots: + +private slots: + void update(); +}; + + +#endif // WALLETMODEL_H diff --git a/src/qtui.h b/src/qtui.h new file mode 100644 index 0000000000..17fc44e94b --- /dev/null +++ b/src/qtui.h @@ -0,0 +1,49 @@ +// 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. +#ifndef BITCOIN_EXTERNUI_H +#define BITCOIN_EXTERNUI_H + +#include <string> +#include <boost/function/function0.hpp> +#include "wallet.h" + +typedef void wxWindow; +#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 + +extern int MyMessageBox(const std::string& message, const std::string& caption="Message", int style=wxOK, wxWindow* parent=NULL, int x=-1, int y=-1); +#define wxMessageBox MyMessageBox +extern int ThreadSafeMessageBox(const std::string& message, const std::string& caption, int style=wxOK, wxWindow* parent=NULL, int x=-1, int y=-1); +extern bool ThreadSafeAskFee(int64 nFeeRequired, const std::string& strCaption, wxWindow* parent); +extern void CalledSetStatusBar(const std::string& strText, int nField); +extern void UIThreadCall(boost::function0<void> fn); +extern void MainFrameRepaint(); +extern void InitMessage(const std::string &message); +extern std::string _(const char* psz); + +#endif diff --git a/src/script.cpp b/src/script.cpp index bd1b5b3c5f..12d3f9e83a 100644 --- a/src/script.cpp +++ b/src/script.cpp @@ -1,4 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto +// Copyright (c) 2011 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. #include "headers.h" @@ -580,6 +581,7 @@ bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, co case OP_ABS: if (bn < bnZero) bn = -bn; break; case OP_NOT: bn = (bn == bnZero); break; case OP_0NOTEQUAL: bn = (bn != bnZero); break; + default: assert(!"invalid opcode"); break; } popstack(stack); stack.push_back(bn.getvch()); @@ -659,6 +661,7 @@ bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, co case OP_GREATERTHANOREQUAL: bn = (bn1 >= bn2); break; case OP_MIN: bn = (bn1 < bn2 ? bn1 : bn2); break; case OP_MAX: bn = (bn1 > bn2 ? bn1 : bn2); break; + default: assert(!"invalid opcode"); break; } popstack(stack); popstack(stack); @@ -1030,50 +1033,45 @@ bool Solver(const CKeyStore& keystore, const CScript& scriptPubKey, uint256 hash return false; // Compile solution - CRITICAL_BLOCK(keystore.cs_mapKeys) + BOOST_FOREACH(PAIRTYPE(opcodetype, valtype)& item, vSolution) { - BOOST_FOREACH(PAIRTYPE(opcodetype, valtype)& item, vSolution) + if (item.first == OP_PUBKEY) { - if (item.first == OP_PUBKEY) + // Sign + const valtype& vchPubKey = item.second; + CKey key; + if (!keystore.GetKey(Hash160(vchPubKey), key)) + return false; + if (key.GetPubKey() != vchPubKey) + return false; + if (hash != 0) { - // Sign - const valtype& vchPubKey = item.second; - CPrivKey privkey; - if (!keystore.GetPrivKey(vchPubKey, privkey)) + vector<unsigned char> vchSig; + if (!key.Sign(hash, vchSig)) return false; - if (hash != 0) - { - vector<unsigned char> vchSig; - if (!CKey::Sign(privkey, hash, vchSig)) - return false; - vchSig.push_back((unsigned char)nHashType); - scriptSigRet << vchSig; - } + vchSig.push_back((unsigned char)nHashType); + scriptSigRet << vchSig; } - else if (item.first == OP_PUBKEYHASH) + } + else if (item.first == OP_PUBKEYHASH) + { + // Sign and give pubkey + CKey key; + if (!keystore.GetKey(uint160(item.second), key)) + return false; + if (hash != 0) { - // Sign and give pubkey - map<uint160, valtype>::iterator mi = mapPubKeys.find(uint160(item.second)); - if (mi == mapPubKeys.end()) + vector<unsigned char> vchSig; + if (!key.Sign(hash, vchSig)) return false; - const vector<unsigned char>& vchPubKey = (*mi).second; - CPrivKey privkey; - if (!keystore.GetPrivKey(vchPubKey, privkey)) - return false; - if (hash != 0) - { - vector<unsigned char> vchSig; - if (!CKey::Sign(privkey, hash, vchSig)) - return false; - vchSig.push_back((unsigned char)nHashType); - scriptSigRet << vchSig << vchPubKey; - } - } - else - { - return false; + vchSig.push_back((unsigned char)nHashType); + scriptSigRet << vchSig << key.GetPubKey(); } } + else + { + return false; + } } return true; @@ -1089,62 +1087,62 @@ bool IsStandard(const CScript& scriptPubKey) bool IsMine(const CKeyStore &keystore, const CScript& scriptPubKey) { - CScript scriptSig; - return Solver(keystore, scriptPubKey, 0, 0, scriptSig); -} - - -bool ExtractPubKey(const CScript& scriptPubKey, const CKeyStore* keystore, vector<unsigned char>& vchPubKeyRet) -{ - vchPubKeyRet.clear(); - vector<pair<opcodetype, valtype> > vSolution; if (!Solver(scriptPubKey, vSolution)) return false; - CRITICAL_BLOCK(cs_mapPubKeys) + // Compile solution + BOOST_FOREACH(PAIRTYPE(opcodetype, valtype)& item, vSolution) { - BOOST_FOREACH(PAIRTYPE(opcodetype, valtype)& item, vSolution) + if (item.first == OP_PUBKEY) { - valtype vchPubKey; - if (item.first == OP_PUBKEY) - { - vchPubKey = item.second; - } - else if (item.first == OP_PUBKEYHASH) - { - map<uint160, valtype>::iterator mi = mapPubKeys.find(uint160(item.second)); - if (mi == mapPubKeys.end()) - continue; - vchPubKey = (*mi).second; - } - if (keystore == NULL || keystore->HaveKey(vchPubKey)) - { - vchPubKeyRet = vchPubKey; - return true; - } + const valtype& vchPubKey = item.second; + vector<unsigned char> vchPubKeyFound; + if (!keystore.GetPubKey(Hash160(vchPubKey), vchPubKeyFound)) + return false; + if (vchPubKeyFound != vchPubKey) + return false; + } + else if (item.first == OP_PUBKEYHASH) + { + if (!keystore.HaveKey(uint160(item.second))) + return false; + } + else + { + return false; } } - return false; -} + return true; +} -bool ExtractHash160(const CScript& scriptPubKey, uint160& hash160Ret) +bool static ExtractAddressInner(const CScript& scriptPubKey, const CKeyStore* keystore, CBitcoinAddress& addressRet) { - hash160Ret = 0; - vector<pair<opcodetype, valtype> > vSolution; if (!Solver(scriptPubKey, vSolution)) return false; BOOST_FOREACH(PAIRTYPE(opcodetype, valtype)& item, vSolution) { - if (item.first == OP_PUBKEYHASH) - { - hash160Ret = uint160(item.second); + if (item.first == OP_PUBKEY) + addressRet.SetPubKey(item.second); + else if (item.first == OP_PUBKEYHASH) + addressRet.SetHash160((uint160)item.second); + if (keystore == NULL || keystore->HaveKey(addressRet)) return true; - } } + + return false; +} + + +bool ExtractAddress(const CScript& scriptPubKey, const CKeyStore* keystore, CBitcoinAddress& addressRet) +{ + if (keystore) + return ExtractAddressInner(scriptPubKey, keystore, addressRet); + else + return ExtractAddressInner(scriptPubKey, NULL, addressRet); return false; } diff --git a/src/script.h b/src/script.h index ae9fdfffa2..e61ea2fd7e 100644 --- a/src/script.h +++ b/src/script.h @@ -1,4 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto +// Copyright (c) 2011 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. #ifndef H_BITCOIN_SCRIPT @@ -10,6 +11,8 @@ #include <string> #include <vector> +#include <boost/foreach.hpp> + class CTransaction; enum @@ -486,7 +489,7 @@ public: { // I'm not sure if this should push the script or concatenate scripts. // If there's ever a use for pushing a script onto a script, delete this member fn - assert(("warning: pushing a CScript onto a CScript with << is probably not intended, use + to concatenate", false)); + assert(!"warning: pushing a CScript onto a CScript with << is probably not intended, use + to concatenate"); return *this; } @@ -622,7 +625,7 @@ public: } - uint160 GetBitcoinAddressHash160() const + CBitcoinAddress GetBitcoinAddress() const { opcodetype opcode; std::vector<unsigned char> vch; @@ -634,36 +637,18 @@ public: if (!GetOp(pc, opcode, vch) || opcode != OP_EQUALVERIFY) return 0; if (!GetOp(pc, opcode, vch) || opcode != OP_CHECKSIG) return 0; if (pc != end()) return 0; - return hash160; + return CBitcoinAddress(hash160); } - std::string GetBitcoinAddress() const - { - uint160 hash160 = GetBitcoinAddressHash160(); - if (hash160 == 0) - return ""; - return Hash160ToAddress(hash160); - } - - void SetBitcoinAddress(const uint160& hash160) + void SetBitcoinAddress(const CBitcoinAddress& address) { this->clear(); - *this << OP_DUP << OP_HASH160 << hash160 << OP_EQUALVERIFY << OP_CHECKSIG; + *this << OP_DUP << OP_HASH160 << address.GetHash160() << OP_EQUALVERIFY << OP_CHECKSIG; } void SetBitcoinAddress(const std::vector<unsigned char>& vchPubKey) { - SetBitcoinAddress(Hash160(vchPubKey)); - } - - bool SetBitcoinAddress(const std::string& strAddress) - { - this->clear(); - uint160 hash160; - if (!AddressToHash160(strAddress, hash160)) - return false; - SetBitcoinAddress(hash160); - return true; + SetBitcoinAddress(CBitcoinAddress(vchPubKey)); } @@ -707,11 +692,11 @@ public: +bool EvalScript(std::vector<std::vector<unsigned char> >& stack, const CScript& script, const CTransaction& txTo, unsigned int nIn, int nHashType); bool IsStandard(const CScript& scriptPubKey); bool IsMine(const CKeyStore& keystore, const CScript& scriptPubKey); -bool ExtractPubKey(const CScript& scriptPubKey, const CKeyStore* pkeystore, std::vector<unsigned char>& vchPubKeyRet); -bool ExtractHash160(const CScript& scriptPubKey, uint160& hash160Ret); +bool ExtractAddress(const CScript& scriptPubKey, const CKeyStore* pkeystore, CBitcoinAddress& addressRet); bool SignSignature(const CKeyStore& keystore, const CTransaction& txFrom, CTransaction& txTo, unsigned int nIn, int nHashType=SIGHASH_ALL, CScript scriptPrereq=CScript()); bool VerifySignature(const CTransaction& txFrom, const CTransaction& txTo, unsigned int nIn, int nHashType=0); diff --git a/src/serialize.h b/src/serialize.h index 31862a71a9..6b35773ac3 100644 --- a/src/serialize.h +++ b/src/serialize.h @@ -1,4 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto +// Copyright (c) 2011 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. #ifndef BITCOIN_SERIALIZE_H @@ -28,19 +29,48 @@ typedef unsigned long long uint64; #if defined(_MSC_VER) && _MSC_VER < 1300 #define for if (false) ; else for #endif + +#ifdef __WXMSW__ +#include <windows.h> +// This is used to attempt to keep keying material out of swap +// Note that VirtualLock does not provide this as a guarantee on Windows, +// but, in practice, memory that has been VirtualLock'd almost never gets written to +// the pagefile except in rare circumstances where memory is extremely low. +#include <windows.h> +#define mlock(p, n) VirtualLock((p), (n)); +#define munlock(p, n) VirtualUnlock((p), (n)); +#else +#include <sys/mman.h> +#include <limits.h> +/* This comes from limits.h if it's not defined there set a sane default */ +#ifndef PAGESIZE +#include <unistd.h> +#define PAGESIZE sysconf(_SC_PAGESIZE) +#endif +#define mlock(a,b) \ + mlock(((void *)(((size_t)(a)) & (~((PAGESIZE)-1)))),\ + (((((size_t)(a)) + (b) - 1) | ((PAGESIZE) - 1)) + 1) - (((size_t)(a)) & (~((PAGESIZE) - 1)))) +#define munlock(a,b) \ + munlock(((void *)(((size_t)(a)) & (~((PAGESIZE)-1)))),\ + (((((size_t)(a)) + (b) - 1) | ((PAGESIZE) - 1)) + 1) - (((size_t)(a)) & (~((PAGESIZE) - 1)))) +#endif + class CScript; class CDataStream; class CAutoFile; static const unsigned int MAX_SIZE = 0x02000000; -static const int VERSION = 32400; +static const int VERSION = 40100; static const char* pszSubVer = ""; static const bool VERSION_IS_BETA = true; - - - - +// Used to bypass the rule against non-const reference to temporary +// where it makes sense with wrappers such as CFlatData or CTxDB +template<typename T> +inline T& REF(const T& val) +{ + return const_cast<T&>(val); +} ///////////////////////////////////////////////////////////////// // @@ -755,7 +785,8 @@ struct ser_streamplaceholder // -// Allocator that clears its contents before deletion +// Allocator that locks its contents from being paged +// out of memory and clears its contents before deletion. // template<typename T> struct secure_allocator : public std::allocator<T> @@ -777,10 +808,22 @@ struct secure_allocator : public std::allocator<T> template<typename _Other> struct rebind { typedef secure_allocator<_Other> other; }; + T* allocate(std::size_t n, const void *hint = 0) + { + T *p; + p = std::allocator<T>::allocate(n, hint); + if (p != NULL) + mlock(p, sizeof(T) * n); + return p; + } + void deallocate(T* p, std::size_t n) { if (p != NULL) + { memset(p, 0, sizeof(T) * n); + munlock(p, sizeof(T) * n); + } std::allocator<T>::deallocate(p, n); } }; diff --git a/src/test/DoS_tests.cpp b/src/test/DoS_tests.cpp new file mode 100644 index 0000000000..e60bb742dd --- /dev/null +++ b/src/test/DoS_tests.cpp @@ -0,0 +1,68 @@ +// +// Unit tests for denial-of-service detection/prevention code +// +#include <boost/test/unit_test.hpp> +#include <boost/foreach.hpp> + +#include "../main.h" +#include "../net.h" +#include "../util.h" + +using namespace std; + +BOOST_AUTO_TEST_SUITE(DoS_tests) + +BOOST_AUTO_TEST_CASE(DoS_banning) +{ + CNode::ClearBanned(); + CAddress addr1(0xa0b0c001); + CNode dummyNode1(INVALID_SOCKET, addr1, true); + dummyNode1.Misbehaving(100); // Should get banned + BOOST_CHECK(CNode::IsBanned(addr1.ip)); + BOOST_CHECK(!CNode::IsBanned(addr1.ip|0x0000ff00)); // Different ip, not banned + + CAddress addr2(0xa0b0c002); + CNode dummyNode2(INVALID_SOCKET, addr2, true); + dummyNode2.Misbehaving(50); + BOOST_CHECK(!CNode::IsBanned(addr2.ip)); // 2 not banned yet... + BOOST_CHECK(CNode::IsBanned(addr1.ip)); // ... but 1 still should be + dummyNode2.Misbehaving(50); + BOOST_CHECK(CNode::IsBanned(addr2.ip)); +} + +BOOST_AUTO_TEST_CASE(DoS_banscore) +{ + CNode::ClearBanned(); + mapArgs["-banscore"] = "111"; // because 11 is my favorite number + CAddress addr1(0xa0b0c001); + CNode dummyNode1(INVALID_SOCKET, addr1, true); + dummyNode1.Misbehaving(100); + BOOST_CHECK(!CNode::IsBanned(addr1.ip)); + dummyNode1.Misbehaving(10); + BOOST_CHECK(!CNode::IsBanned(addr1.ip)); + dummyNode1.Misbehaving(1); + BOOST_CHECK(CNode::IsBanned(addr1.ip)); + mapArgs["-banscore"] = "100"; +} + +BOOST_AUTO_TEST_CASE(DoS_bantime) +{ + CNode::ClearBanned(); + int64 nStartTime = GetTime(); + SetMockTime(nStartTime); // Overrides future calls to GetTime() + + CAddress addr(0xa0b0c001); + CNode dummyNode(INVALID_SOCKET, addr, true); + + dummyNode.Misbehaving(100); + BOOST_CHECK(CNode::IsBanned(addr.ip)); + + SetMockTime(nStartTime+60*60); + BOOST_CHECK(CNode::IsBanned(addr.ip)); + + SetMockTime(nStartTime+60*60*24+1); + BOOST_CHECK(!CNode::IsBanned(addr.ip)); +} + + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/base58_tests.cpp b/src/test/base58_tests.cpp new file mode 100644 index 0000000000..c7fa74e96d --- /dev/null +++ b/src/test/base58_tests.cpp @@ -0,0 +1,87 @@ +#include <boost/test/unit_test.hpp> + +#include "../util.h" + +BOOST_AUTO_TEST_SUITE(base58_tests) + +// TODO: +// EncodeBase58Check +// DecodeBase58Check +// CBase58Data +// bool SetString(const char* psz) + // bool SetString(const std::string& str) + // std::string ToString() const + // int CompareTo(const CBase58Data& b58) const + // bool operator==(const CBase58Data& b58) const + // bool operator<=(const CBase58Data& b58) const + // bool operator>=(const CBase58Data& b58) const + // bool operator< (const CBase58Data& b58) const + // bool operator> (const CBase58Data& b58) const + +// CBitcoinAddress + // bool SetHash160(const uint160& hash160) + // bool SetPubKey(const std::vector<unsigned char>& vchPubKey) + // bool IsValid() const + // CBitcoinAddress() + // CBitcoinAddress(uint160 hash160In) + // CBitcoinAddress(const std::vector<unsigned char>& vchPubKey) + // CBitcoinAddress(const std::string& strAddress) + // CBitcoinAddress(const char* pszAddress) + // uint160 GetHash160() const + +#define U(x) (reinterpret_cast<const unsigned char*>(x)) +static struct { + const unsigned char *data; + int size; +} vstrIn[] = { +{U(""), 0}, +{U("\x61"), 1}, +{U("\x62\x62\x62"), 3}, +{U("\x63\x63\x63"), 3}, +{U("\x73\x69\x6d\x70\x6c\x79\x20\x61\x20\x6c\x6f\x6e\x67\x20\x73\x74\x72\x69\x6e\x67"), 20}, +{U("\x00\xeb\x15\x23\x1d\xfc\xeb\x60\x92\x58\x86\xb6\x7d\x06\x52\x99\x92\x59\x15\xae\xb1\x72\xc0\x66\x47"), 25}, +{U("\x51\x6b\x6f\xcd\x0f"), 5}, +{U("\xbf\x4f\x89\x00\x1e\x67\x02\x74\xdd"), 9}, +{U("\x57\x2e\x47\x94"), 4}, +{U("\xec\xac\x89\xca\xd9\x39\x23\xc0\x23\x21"), 10}, +{U("\x10\xc8\x51\x1e"), 4}, +{U("\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"), 10}, +}; + +const char *vstrOut[] = { +"", +"2g", +"a3gV", +"aPEr", +"2cFupjhnEsSn59qHXstmK2ffpLv2", +"1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L", +"ABnLTmg", +"3SEo3LWLoPntC", +"3EFU7m", +"EJDM8drfXA6uyA", +"Rt5zm", +"1111111111" +}; + +BOOST_AUTO_TEST_CASE(base58_EncodeBase58) +{ + for (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]); + } +} + +BOOST_AUTO_TEST_CASE(base58_DecodeBase58) +{ + std::vector<unsigned char> result; + for (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)); + BOOST_CHECK_EQUAL_COLLECTIONS(result.begin(), result.end(), expected.begin(), expected.end()); + } + BOOST_CHECK(!DecodeBase58("invalid", result)); +} + +BOOST_AUTO_TEST_SUITE_END() + diff --git a/src/test/base64_tests.cpp b/src/test/base64_tests.cpp new file mode 100644 index 0000000000..f30f7f8936 --- /dev/null +++ b/src/test/base64_tests.cpp @@ -0,0 +1,20 @@ +#include <boost/test/unit_test.hpp> + +#include "../util.h" + +BOOST_AUTO_TEST_SUITE(base64_tests) + +BOOST_AUTO_TEST_CASE(base64_testvectors) +{ + static const string vstrIn[] = {"","f","fo","foo","foob","fooba","foobar"}; + static const string vstrOut[] = {"","Zg==","Zm8=","Zm9v","Zm9vYg==","Zm9vYmE=","Zm9vYmFy"}; + for (int i=0; i<sizeof(vstrIn)/sizeof(vstrIn[0]); i++) + { + string strEnc = EncodeBase64(vstrIn[i]); + BOOST_CHECK(strEnc == vstrOut[i]); + string strDec = DecodeBase64(strEnc); + BOOST_CHECK(strDec == vstrIn[i]); + } +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/miner_tests.cpp b/src/test/miner_tests.cpp new file mode 100644 index 0000000000..e773542d71 --- /dev/null +++ b/src/test/miner_tests.cpp @@ -0,0 +1,35 @@ +#include <boost/test/unit_test.hpp> + +#include "../uint256.h" + +extern void SHA256Transform(void* pstate, void* pinput, const void* pinit); + +BOOST_AUTO_TEST_SUITE(miner_tests) + +BOOST_AUTO_TEST_CASE(sha256transform_equality) +{ + unsigned int pSHA256InitState[8] = {0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19}; + + + unsigned char pstate[32]; + unsigned char pinput[32]; + + int i; + + for (i = 0; i < 32; i++) { + pinput[i] = i; + pstate[i] = 0; + } + + uint256 hash; + + SHA256Transform(&hash, pinput, pSHA256InitState); + + BOOST_TEST_MESSAGE(hash.GetHex()); + + uint256 hash_reference("0x2df5e1c65ef9f8cde240d23cae2ec036d31a15ec64bc68f64be242b1da6631f3"); + + BOOST_CHECK(hash == hash_reference); +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/script_tests.cpp b/src/test/script_tests.cpp new file mode 100644 index 0000000000..13feb86b97 --- /dev/null +++ b/src/test/script_tests.cpp @@ -0,0 +1,173 @@ +#include <vector> +#include <boost/test/unit_test.hpp> +#include <boost/foreach.hpp> + +#include "../main.h" +#include "../wallet.h" + +using namespace std; +extern uint256 SignatureHash(CScript scriptCode, const CTransaction& txTo, unsigned int nIn, int nHashType); +extern bool VerifyScript(const CScript& scriptSig, const CScript& scriptPubKey, const CTransaction& txTo, unsigned int nIn, int nHashType); +extern bool VerifySignature(const CTransaction& txFrom, const CTransaction& txTo, unsigned int nIn, int nHashType); + +BOOST_AUTO_TEST_SUITE(script_tests) + +BOOST_AUTO_TEST_CASE(script_PushData) +{ + // Check that PUSHDATA1, PUSHDATA2, and PUSHDATA4 create the same value on + // the stack as the 1-75 opcodes do. + static const unsigned char direct[] = { 1, 0x5a }; + static const unsigned char pushdata1[] = { OP_PUSHDATA1, 1, 0x5a }; + static const unsigned char pushdata2[] = { OP_PUSHDATA2, 1, 0, 0x5a }; + static const unsigned char pushdata4[] = { OP_PUSHDATA4, 1, 0, 0, 0, 0x5a }; + + vector<vector<unsigned char> > directStack; + BOOST_CHECK(EvalScript(directStack, CScript(&direct[0], &direct[sizeof(direct)]), CTransaction(), 0, 0)); + + vector<vector<unsigned char> > pushdata1Stack; + BOOST_CHECK(EvalScript(pushdata1Stack, CScript(&pushdata1[0], &pushdata1[sizeof(pushdata1)]), CTransaction(), 0, 0)); + BOOST_CHECK(pushdata1Stack == directStack); + + vector<vector<unsigned char> > pushdata2Stack; + BOOST_CHECK(EvalScript(pushdata2Stack, CScript(&pushdata2[0], &pushdata2[sizeof(pushdata2)]), CTransaction(), 0, 0)); + BOOST_CHECK(pushdata2Stack == directStack); + + vector<vector<unsigned char> > pushdata4Stack; + BOOST_CHECK(EvalScript(pushdata4Stack, CScript(&pushdata4[0], &pushdata4[sizeof(pushdata4)]), CTransaction(), 0, 0)); + BOOST_CHECK(pushdata4Stack == directStack); +} + +CScript +sign_multisig(CScript scriptPubKey, std::vector<CKey> keys, CTransaction transaction) +{ + uint256 hash = SignatureHash(scriptPubKey, transaction, 0, SIGHASH_ALL); + + CScript result; + // + // NOTE: CHECKMULTISIG has an unfortunate bug; it requires + // one extra item on the stack, before the signatures. + // Putting OP_0 on the stack is the workaround; + // fixing the bug would mean splitting the blockchain (old + // clients would not accept new CHECKMULTISIG transactions, + // and vice-versa) + // + result << OP_0; + BOOST_FOREACH(CKey key, keys) + { + vector<unsigned char> vchSig; + BOOST_CHECK(key.Sign(hash, vchSig)); + vchSig.push_back((unsigned char)SIGHASH_ALL); + result << vchSig; + } + return result; +} +CScript +sign_multisig(CScript scriptPubKey, CKey key, CTransaction transaction) +{ + std::vector<CKey> keys; + keys.push_back(key); + return sign_multisig(scriptPubKey, keys, transaction); +} + +BOOST_AUTO_TEST_CASE(script_CHECKMULTISIG12) +{ + CKey key1, key2, key3; + key1.MakeNewKey(); + key2.MakeNewKey(); + key3.MakeNewKey(); + + CScript scriptPubKey12; + scriptPubKey12 << OP_1 << key1.GetPubKey() << key2.GetPubKey() << OP_2 << OP_CHECKMULTISIG; + + CTransaction txFrom12; + txFrom12.vout.resize(1); + txFrom12.vout[0].scriptPubKey = scriptPubKey12; + + CTransaction txTo12; + txTo12.vin.resize(1); + txTo12.vout.resize(1); + txTo12.vin[0].prevout.n = 0; + txTo12.vin[0].prevout.hash = txFrom12.GetHash(); + txTo12.vout[0].nValue = 1; + + CScript goodsig1 = sign_multisig(scriptPubKey12, key1, txTo12); + BOOST_CHECK(VerifyScript(goodsig1, scriptPubKey12, txTo12, 0, 0)); + txTo12.vout[0].nValue = 2; + BOOST_CHECK(!VerifyScript(goodsig1, scriptPubKey12, txTo12, 0, 0)); + + CScript goodsig2 = sign_multisig(scriptPubKey12, key2, txTo12); + BOOST_CHECK(VerifyScript(goodsig2, scriptPubKey12, txTo12, 0, 0)); + + CScript badsig1 = sign_multisig(scriptPubKey12, key3, txTo12); + BOOST_CHECK(!VerifyScript(badsig1, scriptPubKey12, txTo12, 0, 0)); +} + +BOOST_AUTO_TEST_CASE(script_CHECKMULTISIG23) +{ + CKey key1, key2, key3, key4; + key1.MakeNewKey(); + key2.MakeNewKey(); + key3.MakeNewKey(); + key4.MakeNewKey(); + + CScript scriptPubKey23; + scriptPubKey23 << OP_2 << key1.GetPubKey() << key2.GetPubKey() << key3.GetPubKey() << OP_3 << OP_CHECKMULTISIG; + + CTransaction txFrom23; + txFrom23.vout.resize(1); + txFrom23.vout[0].scriptPubKey = scriptPubKey23; + + CTransaction txTo23; + txTo23.vin.resize(1); + txTo23.vout.resize(1); + txTo23.vin[0].prevout.n = 0; + txTo23.vin[0].prevout.hash = txFrom23.GetHash(); + txTo23.vout[0].nValue = 1; + + std::vector<CKey> keys; + keys.push_back(key1); keys.push_back(key2); + CScript goodsig1 = sign_multisig(scriptPubKey23, keys, txTo23); + BOOST_CHECK(VerifyScript(goodsig1, scriptPubKey23, txTo23, 0, 0)); + + keys.clear(); + keys.push_back(key1); keys.push_back(key3); + CScript goodsig2 = sign_multisig(scriptPubKey23, keys, txTo23); + BOOST_CHECK(VerifyScript(goodsig2, scriptPubKey23, txTo23, 0, 0)); + + keys.clear(); + keys.push_back(key2); keys.push_back(key3); + CScript goodsig3 = sign_multisig(scriptPubKey23, keys, txTo23); + BOOST_CHECK(VerifyScript(goodsig3, scriptPubKey23, txTo23, 0, 0)); + + keys.clear(); + keys.push_back(key2); keys.push_back(key2); // Can't re-use sig + CScript badsig1 = sign_multisig(scriptPubKey23, keys, txTo23); + BOOST_CHECK(!VerifyScript(badsig1, scriptPubKey23, txTo23, 0, 0)); + + keys.clear(); + keys.push_back(key2); keys.push_back(key1); // sigs must be in correct order + CScript badsig2 = sign_multisig(scriptPubKey23, keys, txTo23); + BOOST_CHECK(!VerifyScript(badsig2, scriptPubKey23, txTo23, 0, 0)); + + keys.clear(); + keys.push_back(key3); keys.push_back(key2); // sigs must be in correct order + CScript badsig3 = sign_multisig(scriptPubKey23, keys, txTo23); + BOOST_CHECK(!VerifyScript(badsig3, scriptPubKey23, txTo23, 0, 0)); + + keys.clear(); + keys.push_back(key4); keys.push_back(key2); // sigs must match pubkeys + CScript badsig4 = sign_multisig(scriptPubKey23, keys, txTo23); + BOOST_CHECK(!VerifyScript(badsig4, scriptPubKey23, txTo23, 0, 0)); + + keys.clear(); + keys.push_back(key1); keys.push_back(key4); // sigs must match pubkeys + CScript badsig5 = sign_multisig(scriptPubKey23, keys, txTo23); + BOOST_CHECK(!VerifyScript(badsig5, scriptPubKey23, txTo23, 0, 0)); + + keys.clear(); // Must have signatures + CScript badsig6 = sign_multisig(scriptPubKey23, keys, txTo23); + BOOST_CHECK(!VerifyScript(badsig6, scriptPubKey23, txTo23, 0, 0)); +} + + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/test_bitcoin.cpp b/src/test/test_bitcoin.cpp index 3b7d2d2f2c..8863aad478 100644 --- a/src/test/test_bitcoin.cpp +++ b/src/test/test_bitcoin.cpp @@ -1,6 +1,22 @@ -#define BOOST_TEST_MODULE uint160 +#define BOOST_TEST_MODULE Bitcoin Test Suite #include <boost/test/unit_test.hpp> +#include "../main.h" +#include "../wallet.h" + #include "uint160_tests.cpp" #include "uint256_tests.cpp" +#include "script_tests.cpp" +#include "transaction_tests.cpp" +#include "DoS_tests.cpp" +#include "base64_tests.cpp" +#include "util_tests.cpp" +#include "base58_tests.cpp" +#include "miner_tests.cpp" + +CWallet* pwalletMain; +void Shutdown(void* parg) +{ + exit(0); +} diff --git a/src/test/transaction_tests.cpp b/src/test/transaction_tests.cpp new file mode 100644 index 0000000000..e6eb0f054f --- /dev/null +++ b/src/test/transaction_tests.cpp @@ -0,0 +1,25 @@ +#include <boost/test/unit_test.hpp> + +#include "../main.h" +#include "../wallet.h" + +using namespace std; + +BOOST_AUTO_TEST_SUITE(transaction_tests) + +BOOST_AUTO_TEST_CASE(basic_transaction_tests) +{ + // Random real transaction (e2769b09e784f32f62ef849763d4f45b98e07ba658647343b915ff832b110436) + unsigned char ch[] = {0x01, 0x00, 0x00, 0x00, 0x01, 0x6b, 0xff, 0x7f, 0xcd, 0x4f, 0x85, 0x65, 0xef, 0x40, 0x6d, 0xd5, 0xd6, 0x3d, 0x4f, 0xf9, 0x4f, 0x31, 0x8f, 0xe8, 0x20, 0x27, 0xfd, 0x4d, 0xc4, 0x51, 0xb0, 0x44, 0x74, 0x01, 0x9f, 0x74, 0xb4, 0x00, 0x00, 0x00, 0x00, 0x8c, 0x49, 0x30, 0x46, 0x02, 0x21, 0x00, 0xda, 0x0d, 0xc6, 0xae, 0xce, 0xfe, 0x1e, 0x06, 0xef, 0xdf, 0x05, 0x77, 0x37, 0x57, 0xde, 0xb1, 0x68, 0x82, 0x09, 0x30, 0xe3, 0xb0, 0xd0, 0x3f, 0x46, 0xf5, 0xfc, 0xf1, 0x50, 0xbf, 0x99, 0x0c, 0x02, 0x21, 0x00, 0xd2, 0x5b, 0x5c, 0x87, 0x04, 0x00, 0x76, 0xe4, 0xf2, 0x53, 0xf8, 0x26, 0x2e, 0x76, 0x3e, 0x2d, 0xd5, 0x1e, 0x7f, 0xf0, 0xbe, 0x15, 0x77, 0x27, 0xc4, 0xbc, 0x42, 0x80, 0x7f, 0x17, 0xbd, 0x39, 0x01, 0x41, 0x04, 0xe6, 0xc2, 0x6e, 0xf6, 0x7d, 0xc6, 0x10, 0xd2, 0xcd, 0x19, 0x24, 0x84, 0x78, 0x9a, 0x6c, 0xf9, 0xae, 0xa9, 0x93, 0x0b, 0x94, 0x4b, 0x7e, 0x2d, 0xb5, 0x34, 0x2b, 0x9d, 0x9e, 0x5b, 0x9f, 0xf7, 0x9a, 0xff, 0x9a, 0x2e, 0xe1, 0x97, 0x8d, 0xd7, 0xfd, 0x01, 0xdf, 0xc5, 0x22, 0xee, 0x02, 0x28, 0x3d, 0x3b, 0x06, 0xa9, 0xd0, 0x3a, 0xcf, 0x80, 0x96, 0x96, 0x8d, 0x7d, 0xbb, 0x0f, 0x91, 0x78, 0xff, 0xff, 0xff, 0xff, 0x02, 0x8b, 0xa7, 0x94, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x19, 0x76, 0xa9, 0x14, 0xba, 0xde, 0xec, 0xfd, 0xef, 0x05, 0x07, 0x24, 0x7f, 0xc8, 0xf7, 0x42, 0x41, 0xd7, 0x3b, 0xc0, 0x39, 0x97, 0x2d, 0x7b, 0x88, 0xac, 0x40, 0x94, 0xa8, 0x02, 0x00, 0x00, 0x00, 0x00, 0x19, 0x76, 0xa9, 0x14, 0xc1, 0x09, 0x32, 0x48, 0x3f, 0xec, 0x93, 0xed, 0x51, 0xf5, 0xfe, 0x95, 0xe7, 0x25, 0x59, 0xf2, 0xcc, 0x70, 0x43, 0xf9, 0x88, 0xac, 0x00, 0x00, 0x00, 0x00, 0x00}; + vector<unsigned char> vch(ch, ch + sizeof(ch) -1); + CDataStream stream(vch); + CTransaction tx; + stream >> tx; + BOOST_CHECK_MESSAGE(tx.CheckTransaction(), "Simple deserialized transaction should be valid."); + + // Check that duplicate txins fail + tx.vin.push_back(tx.vin[0]); + BOOST_CHECK_MESSAGE(!tx.CheckTransaction(), "Transaction with duplicate txins should be invalid."); +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/uint160_tests.cpp b/src/test/uint160_tests.cpp index 66ffd285b8..42c8275afe 100644 --- a/src/test/uint160_tests.cpp +++ b/src/test/uint160_tests.cpp @@ -1,8 +1,10 @@ +#include <boost/test/unit_test.hpp> + #include "../uint256.h" BOOST_AUTO_TEST_SUITE(uint160_tests) -BOOST_AUTO_TEST_CASE(equality) +BOOST_AUTO_TEST_CASE(uint160_equality) { uint160 num1 = 10; uint160 num2 = 11; diff --git a/src/test/uint256_tests.cpp b/src/test/uint256_tests.cpp index cbae9bf6d2..c5d45e215e 100644 --- a/src/test/uint256_tests.cpp +++ b/src/test/uint256_tests.cpp @@ -1,8 +1,10 @@ +#include <boost/test/unit_test.hpp> + #include "../uint256.h" BOOST_AUTO_TEST_SUITE(uint256_tests) -BOOST_AUTO_TEST_CASE(equality) +BOOST_AUTO_TEST_CASE(uint256_equality) { uint256 num1 = 10; uint256 num2 = 11; diff --git a/src/test/util_tests.cpp b/src/test/util_tests.cpp new file mode 100644 index 0000000000..8afc85c507 --- /dev/null +++ b/src/test/util_tests.cpp @@ -0,0 +1,214 @@ +#include <vector> +#include <boost/test/unit_test.hpp> +#include <boost/foreach.hpp> + +#include "../util.h" + +using namespace std; + +BOOST_AUTO_TEST_SUITE(util_tests) + +BOOST_AUTO_TEST_CASE(util_MedianFilter) +{ + CMedianFilter<int> filter(5, 15); + + BOOST_CHECK_EQUAL(filter.median(), 15); + + filter.input(20); // [15 20] + BOOST_CHECK_EQUAL(filter.median(), 17); + + filter.input(30); // [15 20 30] + BOOST_CHECK_EQUAL(filter.median(), 20); + + filter.input(3); // [3 15 20 30] + BOOST_CHECK_EQUAL(filter.median(), 17); + + filter.input(7); // [3 7 15 20 30] + BOOST_CHECK_EQUAL(filter.median(), 15); + + filter.input(18); // [3 7 18 20 30] + BOOST_CHECK_EQUAL(filter.median(), 18); + + filter.input(0); // [0 3 7 18 30] + BOOST_CHECK_EQUAL(filter.median(), 7); +} + +static const unsigned char ParseHex_expected[65] = { + 0x04, 0x67, 0x8a, 0xfd, 0xb0, 0xfe, 0x55, 0x48, 0x27, 0x19, 0x67, 0xf1, 0xa6, 0x71, 0x30, 0xb7, + 0x10, 0x5c, 0xd6, 0xa8, 0x28, 0xe0, 0x39, 0x09, 0xa6, 0x79, 0x62, 0xe0, 0xea, 0x1f, 0x61, 0xde, + 0xb6, 0x49, 0xf6, 0xbc, 0x3f, 0x4c, 0xef, 0x38, 0xc4, 0xf3, 0x55, 0x04, 0xe5, 0x1e, 0xc1, 0x12, + 0xde, 0x5c, 0x38, 0x4d, 0xf7, 0xba, 0x0b, 0x8d, 0x57, 0x8a, 0x4c, 0x70, 0x2b, 0x6b, 0xf1, 0x1d, + 0x5f +}; +BOOST_AUTO_TEST_CASE(util_ParseHex) +{ + std::vector<unsigned char> result; + std::vector<unsigned char> expected(ParseHex_expected, ParseHex_expected + sizeof(ParseHex_expected)); + // Basic test vector + result = ParseHex("04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f"); + BOOST_CHECK_EQUAL_COLLECTIONS(result.begin(), result.end(), expected.begin(), expected.end()); + + // Spaces between bytes must be supported + result = ParseHex("12 34 56 78"); + BOOST_CHECK(result.size() == 4 && result[0] == 0x12 && result[1] == 0x34 && result[2] == 0x56 && result[3] == 0x78); + + // Stop parsing at invalid value + result = ParseHex("1234 invalid 1234"); + BOOST_CHECK(result.size() == 2 && result[0] == 0x12 && result[1] == 0x34); +} + +BOOST_AUTO_TEST_CASE(util_HexStr) +{ + BOOST_CHECK_EQUAL( + HexStr(ParseHex_expected, ParseHex_expected + sizeof(ParseHex_expected)), + "04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f"); + + BOOST_CHECK_EQUAL( + HexStr(ParseHex_expected, ParseHex_expected + 5, true), + "04 67 8a fd b0"); +} + +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 + 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"); +} + +BOOST_AUTO_TEST_CASE(util_ParseParameters) +{ + const char *argv_test[] = {"-ignored", "-a", "-b", "-ccc=argument", "-ccc=multiple", "f", "-d=e"}; + + ParseParameters(0, (char**)argv_test); + BOOST_CHECK(mapArgs.empty() && mapMultiArgs.empty()); + + ParseParameters(1, (char**)argv_test); + BOOST_CHECK(mapArgs.empty() && mapMultiArgs.empty()); + + ParseParameters(5, (char**)argv_test); + // expectation: -ignored is ignored (program name argument), + // -a, -b and -ccc end up in map, -d ignored because it is after + // a non-option argument (non-GNU option parsing) + BOOST_CHECK(mapArgs.size() == 3 && mapMultiArgs.size() == 3); + BOOST_CHECK(mapArgs.count("-a") && mapArgs.count("-b") && mapArgs.count("-ccc") + && !mapArgs.count("f") && !mapArgs.count("-d")); + BOOST_CHECK(mapMultiArgs.count("-a") && mapMultiArgs.count("-b") && mapMultiArgs.count("-ccc") + && !mapMultiArgs.count("f") && !mapMultiArgs.count("-d")); + + BOOST_CHECK(mapArgs["-a"] == "" && mapArgs["-ccc"] == "multiple"); + BOOST_CHECK(mapMultiArgs["-ccc"].size() == 2); +} + +BOOST_AUTO_TEST_CASE(util_GetArg) +{ + mapArgs.clear(); + mapArgs["strtest1"] = "string..."; + // strtest2 undefined on purpose + mapArgs["inttest1"] = "12345"; + mapArgs["inttest2"] = "81985529216486895"; + // inttest3 undefined on purpose + mapArgs["booltest1"] = ""; + // booltest2 undefined on purpose + mapArgs["booltest3"] = "0"; + mapArgs["booltest4"] = "1"; + + BOOST_CHECK_EQUAL(GetArg("strtest1", "default"), "string..."); + BOOST_CHECK_EQUAL(GetArg("strtest2", "default"), "default"); + BOOST_CHECK_EQUAL(GetArg("inttest1", -1), 12345); + BOOST_CHECK_EQUAL(GetArg("inttest2", -1), 81985529216486895LL); + BOOST_CHECK_EQUAL(GetArg("inttest3", -1), -1); + BOOST_CHECK_EQUAL(GetBoolArg("booltest1"), true); + BOOST_CHECK_EQUAL(GetBoolArg("booltest2"), false); + BOOST_CHECK_EQUAL(GetBoolArg("booltest3"), false); + BOOST_CHECK_EQUAL(GetBoolArg("booltest4"), true); +} + +BOOST_AUTO_TEST_CASE(util_WildcardMatch) +{ + BOOST_CHECK(WildcardMatch("127.0.0.1", "*")); + BOOST_CHECK(WildcardMatch("127.0.0.1", "127.*")); + BOOST_CHECK(WildcardMatch("abcdef", "a?cde?")); + BOOST_CHECK(!WildcardMatch("abcdef", "a?cde??")); + BOOST_CHECK(WildcardMatch("abcdef", "a*f")); + BOOST_CHECK(!WildcardMatch("abcdef", "a*x")); + BOOST_CHECK(WildcardMatch("", "*")); +} + +BOOST_AUTO_TEST_CASE(util_FormatMoney) +{ + BOOST_CHECK_EQUAL(FormatMoney(0, false), "0.00"); + BOOST_CHECK_EQUAL(FormatMoney((COIN/10000)*123456789, false), "12345.6789"); + BOOST_CHECK_EQUAL(FormatMoney(COIN, true), "+1.00"); + BOOST_CHECK_EQUAL(FormatMoney(-COIN, false), "-1.00"); + BOOST_CHECK_EQUAL(FormatMoney(-COIN, true), "-1.00"); + + BOOST_CHECK_EQUAL(FormatMoney(COIN*100000000, false), "100000000.00"); + BOOST_CHECK_EQUAL(FormatMoney(COIN*10000000, false), "10000000.00"); + BOOST_CHECK_EQUAL(FormatMoney(COIN*1000000, false), "1000000.00"); + BOOST_CHECK_EQUAL(FormatMoney(COIN*100000, false), "100000.00"); + BOOST_CHECK_EQUAL(FormatMoney(COIN*10000, false), "10000.00"); + BOOST_CHECK_EQUAL(FormatMoney(COIN*1000, false), "1000.00"); + BOOST_CHECK_EQUAL(FormatMoney(COIN*100, false), "100.00"); + BOOST_CHECK_EQUAL(FormatMoney(COIN*10, false), "10.00"); + BOOST_CHECK_EQUAL(FormatMoney(COIN, false), "1.00"); + BOOST_CHECK_EQUAL(FormatMoney(COIN/10, false), "0.10"); + BOOST_CHECK_EQUAL(FormatMoney(COIN/100, false), "0.01"); + BOOST_CHECK_EQUAL(FormatMoney(COIN/1000, false), "0.001"); + BOOST_CHECK_EQUAL(FormatMoney(COIN/10000, false), "0.0001"); + BOOST_CHECK_EQUAL(FormatMoney(COIN/100000, false), "0.00001"); + BOOST_CHECK_EQUAL(FormatMoney(COIN/1000000, false), "0.000001"); + BOOST_CHECK_EQUAL(FormatMoney(COIN/10000000, false), "0.0000001"); + BOOST_CHECK_EQUAL(FormatMoney(COIN/100000000, false), "0.00000001"); +} + +BOOST_AUTO_TEST_CASE(util_ParseMoney) +{ + int64 ret = 0; + BOOST_CHECK(ParseMoney("0.0", ret)); + BOOST_CHECK_EQUAL(ret, 0); + + BOOST_CHECK(ParseMoney("12345.6789", ret)); + BOOST_CHECK_EQUAL(ret, (COIN/10000)*123456789); + + BOOST_CHECK(ParseMoney("100000000.00", ret)); + BOOST_CHECK_EQUAL(ret, COIN*100000000); + BOOST_CHECK(ParseMoney("10000000.00", ret)); + BOOST_CHECK_EQUAL(ret, COIN*10000000); + BOOST_CHECK(ParseMoney("1000000.00", ret)); + BOOST_CHECK_EQUAL(ret, COIN*1000000); + BOOST_CHECK(ParseMoney("100000.00", ret)); + BOOST_CHECK_EQUAL(ret, COIN*100000); + BOOST_CHECK(ParseMoney("10000.00", ret)); + BOOST_CHECK_EQUAL(ret, COIN*10000); + BOOST_CHECK(ParseMoney("1000.00", ret)); + BOOST_CHECK_EQUAL(ret, COIN*1000); + BOOST_CHECK(ParseMoney("100.00", ret)); + BOOST_CHECK_EQUAL(ret, COIN*100); + BOOST_CHECK(ParseMoney("10.00", ret)); + BOOST_CHECK_EQUAL(ret, COIN*10); + BOOST_CHECK(ParseMoney("1.00", ret)); + BOOST_CHECK_EQUAL(ret, COIN); + BOOST_CHECK(ParseMoney("0.1", ret)); + BOOST_CHECK_EQUAL(ret, COIN/10); + BOOST_CHECK(ParseMoney("0.01", ret)); + BOOST_CHECK_EQUAL(ret, COIN/100); + BOOST_CHECK(ParseMoney("0.001", ret)); + BOOST_CHECK_EQUAL(ret, COIN/1000); + BOOST_CHECK(ParseMoney("0.0001", ret)); + BOOST_CHECK_EQUAL(ret, COIN/10000); + BOOST_CHECK(ParseMoney("0.00001", ret)); + BOOST_CHECK_EQUAL(ret, COIN/100000); + BOOST_CHECK(ParseMoney("0.000001", ret)); + BOOST_CHECK_EQUAL(ret, COIN/1000000); + BOOST_CHECK(ParseMoney("0.0000001", ret)); + BOOST_CHECK_EQUAL(ret, COIN/10000000); + BOOST_CHECK(ParseMoney("0.00000001", ret)); + BOOST_CHECK_EQUAL(ret, COIN/100000000); + + // Attempted 63 bit overflow should fail + BOOST_CHECK(!ParseMoney("92233720368.54775808", ret)); +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/ui.cpp b/src/ui.cpp deleted file mode 100644 index 9b84fb9e6b..0000000000 --- a/src/ui.cpp +++ /dev/null @@ -1,2964 +0,0 @@ -// Copyright (c) 2009-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. - -#include "headers.h" -#include "db.h" -#include "init.h" -#include "strlcpy.h" -#include <boost/filesystem/fstream.hpp> -#include <boost/filesystem/convenience.hpp> -#ifdef _MSC_VER -#include <crtdbg.h> -#endif - -using namespace std; -using namespace boost; - - -DEFINE_EVENT_TYPE(wxEVT_UITHREADCALL) - -CMainFrame* pframeMain = NULL; -CMyTaskBarIcon* ptaskbaricon = NULL; -bool fClosedToTray = false; -wxLocale g_locale; - -#ifdef __WXMSW__ -double nScaleX = 1.0; -double nScaleY = 1.0; -#else -static const double nScaleX = 1.0; -static const double nScaleY = 1.0; -#endif - - - - - - - - -////////////////////////////////////////////////////////////////////////////// -// -// Util -// - -void HandleCtrlA(wxKeyEvent& event) -{ - // Ctrl-a select all - event.Skip(); - wxTextCtrl* textCtrl = (wxTextCtrl*)event.GetEventObject(); - if (event.GetModifiers() == wxMOD_CONTROL && event.GetKeyCode() == 'A') - textCtrl->SetSelection(-1, -1); -} - -bool Is24HourTime() -{ - //char pszHourFormat[256]; - //pszHourFormat[0] = '\0'; - //GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_ITIME, pszHourFormat, 256); - //return (pszHourFormat[0] != '0'); - return true; -} - -string DateStr(int64 nTime) -{ - // Can only be used safely here in the UI - return (string)wxDateTime((time_t)nTime).FormatDate(); -} - -string DateTimeStr(int64 nTime) -{ - // Can only be used safely here in the UI - wxDateTime datetime((time_t)nTime); - if (Is24HourTime()) - return (string)datetime.Format("%x %H:%M"); - else - return (string)datetime.Format("%x ") + itostr((datetime.GetHour() + 11) % 12 + 1) + (string)datetime.Format(":%M %p"); -} - -wxString GetItemText(wxListCtrl* listCtrl, int nIndex, int nColumn) -{ - // Helper to simplify access to listctrl - wxListItem item; - item.m_itemId = nIndex; - item.m_col = nColumn; - item.m_mask = wxLIST_MASK_TEXT; - if (!listCtrl->GetItem(item)) - return ""; - return item.GetText(); -} - -int InsertLine(wxListCtrl* listCtrl, const wxString& str0, const wxString& str1) -{ - int nIndex = listCtrl->InsertItem(listCtrl->GetItemCount(), str0); - listCtrl->SetItem(nIndex, 1, str1); - return nIndex; -} - -int InsertLine(wxListCtrl* listCtrl, const wxString& str0, const wxString& str1, const wxString& str2, const wxString& str3, const wxString& str4) -{ - int nIndex = listCtrl->InsertItem(listCtrl->GetItemCount(), str0); - listCtrl->SetItem(nIndex, 1, str1); - listCtrl->SetItem(nIndex, 2, str2); - listCtrl->SetItem(nIndex, 3, str3); - listCtrl->SetItem(nIndex, 4, str4); - return nIndex; -} - -int InsertLine(wxListCtrl* listCtrl, void* pdata, const wxString& str0, const wxString& str1, const wxString& str2, const wxString& str3, const wxString& str4) -{ - int nIndex = listCtrl->InsertItem(listCtrl->GetItemCount(), str0); - listCtrl->SetItemPtrData(nIndex, (wxUIntPtr)pdata); - listCtrl->SetItem(nIndex, 1, str1); - listCtrl->SetItem(nIndex, 2, str2); - listCtrl->SetItem(nIndex, 3, str3); - listCtrl->SetItem(nIndex, 4, str4); - return nIndex; -} - -void SetItemTextColour(wxListCtrl* listCtrl, int nIndex, const wxColour& colour) -{ - // Repaint on Windows is more flickery if the colour has ever been set, - // so don't want to set it unless it's different. Default colour has - // alpha 0 transparent, so our colours don't match using operator==. - wxColour c1 = listCtrl->GetItemTextColour(nIndex); - if (!c1.IsOk()) - c1 = wxColour(0,0,0); - if (colour.Red() != c1.Red() || colour.Green() != c1.Green() || colour.Blue() != c1.Blue()) - listCtrl->SetItemTextColour(nIndex, colour); -} - -void SetSelection(wxListCtrl* listCtrl, int nIndex) -{ - int nSize = listCtrl->GetItemCount(); - long nState = (wxLIST_STATE_SELECTED|wxLIST_STATE_FOCUSED); - for (int i = 0; i < nSize; i++) - listCtrl->SetItemState(i, (i == nIndex ? nState : 0), nState); -} - -int GetSelection(wxListCtrl* listCtrl) -{ - int nSize = listCtrl->GetItemCount(); - for (int i = 0; i < nSize; i++) - if (listCtrl->GetItemState(i, wxLIST_STATE_FOCUSED)) - return i; - return -1; -} - -string HtmlEscape(const char* psz, bool fMultiLine=false) -{ - int len = 0; - for (const char* p = psz; *p; p++) - { - if (*p == '<') len += 4; - else if (*p == '>') len += 4; - else if (*p == '&') len += 5; - else if (*p == '"') len += 6; - else if (*p == ' ' && p > psz && p[-1] == ' ' && p[1] == ' ') len += 6; - else if (*p == '\n' && fMultiLine) len += 5; - else - len++; - } - string str; - str.reserve(len); - for (const char* p = psz; *p; p++) - { - if (*p == '<') str += "<"; - else if (*p == '>') str += ">"; - else if (*p == '&') str += "&"; - else if (*p == '"') str += """; - else if (*p == ' ' && p > psz && p[-1] == ' ' && p[1] == ' ') str += " "; - else if (*p == '\n' && fMultiLine) str += "<br>\n"; - else - str += *p; - } - return str; -} - -string HtmlEscape(const string& str, bool fMultiLine=false) -{ - return HtmlEscape(str.c_str(), fMultiLine); -} - -void CalledMessageBox(const string& message, const string& caption, int style, wxWindow* parent, int x, int y, int* pnRet, bool* pfDone) -{ - *pnRet = wxMessageBox(message, caption, style, parent, x, y); - *pfDone = true; -} - -int ThreadSafeMessageBox(const string& message, const string& caption, int style, wxWindow* parent, int x, int y) -{ -#ifdef __WXMSW__ - return wxMessageBox(message, caption, style, parent, x, y); -#else - if (wxThread::IsMain() || fDaemon) - { - return wxMessageBox(message, caption, style, parent, x, y); - } - else - { - int nRet = 0; - bool fDone = false; - UIThreadCall(bind(CalledMessageBox, message, caption, style, parent, x, y, &nRet, &fDone)); - while (!fDone) - Sleep(100); - return nRet; - } -#endif -} - -bool ThreadSafeAskFee(int64 nFeeRequired, const string& strCaption, wxWindow* parent) -{ - if (nFeeRequired < MIN_TX_FEE || nFeeRequired <= nTransactionFee || fDaemon) - return true; - string strMessage = strprintf( - _("This transaction is over the size limit. You can still send it for a fee of %s, " - "which goes to the nodes that process your transaction and helps to support the network. " - "Do you want to pay the fee?"), - FormatMoney(nFeeRequired).c_str()); - return (ThreadSafeMessageBox(strMessage, strCaption, wxYES_NO, parent) == wxYES); -} - -void CalledSetStatusBar(const string& strText, int nField) -{ - if (nField == 0 && GetWarnings("statusbar") != "") - return; - if (pframeMain && pframeMain->m_statusBar) - pframeMain->m_statusBar->SetStatusText(strText, nField); -} - -void SetDefaultReceivingAddress(const string& strAddress) -{ - // Update main window address and database - if (pframeMain == NULL) - return; - if (strAddress != pframeMain->m_textCtrlAddress->GetValue()) - { - uint160 hash160; - if (!AddressToHash160(strAddress, hash160)) - return; - if (!mapPubKeys.count(hash160)) - return; - pwalletMain->SetDefaultKey(mapPubKeys[hash160]); - pframeMain->m_textCtrlAddress->SetValue(strAddress); - } -} - - - - - - - - - - -////////////////////////////////////////////////////////////////////////////// -// -// CMainFrame -// - -CMainFrame::CMainFrame(wxWindow* parent) : CMainFrameBase(parent) -{ - Connect(wxEVT_UITHREADCALL, wxCommandEventHandler(CMainFrame::OnUIThreadCall), NULL, this); - - // Set initially selected page - wxNotebookEvent event; - event.SetSelection(0); - OnNotebookPageChanged(event); - m_notebook->ChangeSelection(0); - - // Init - fRefreshListCtrl = false; - fRefreshListCtrlRunning = false; - fOnSetFocusAddress = false; - fRefresh = false; - m_choiceFilter->SetSelection(0); - double dResize = nScaleX; -#ifdef __WXMSW__ - SetIcon(wxICON(bitcoin)); - SetSize(dResize * GetSize().GetWidth(), nScaleY * GetSize().GetHeight()); -#else - SetIcon(bitcoin80_xpm); - SetBackgroundColour(m_toolBar->GetBackgroundColour()); - wxFont fontTmp = m_staticText41->GetFont(); - fontTmp.SetFamily(wxFONTFAMILY_TELETYPE); - m_staticTextBalance->SetFont(fontTmp); - m_staticTextBalance->SetSize(140, 17); - // resize to fit ubuntu's huge default font - dResize = 1.22; - SetSize(dResize * GetSize().GetWidth(), 1.15 * GetSize().GetHeight()); -#endif - m_staticTextBalance->SetLabel(FormatMoney(pwalletMain->GetBalance()) + " "); - m_listCtrl->SetFocus(); - ptaskbaricon = new CMyTaskBarIcon(); -#ifdef __WXMAC_OSX__ - // Mac automatically moves wxID_EXIT, wxID_PREFERENCES and wxID_ABOUT - // to their standard places, leaving these menus empty. - GetMenuBar()->Remove(2); // remove Help menu - GetMenuBar()->Remove(0); // remove File menu -#endif - - // Init column headers - int nDateWidth = DateTimeStr(1229413914).size() * 6 + 8; - if (!strstr(DateTimeStr(1229413914).c_str(), "2008")) - nDateWidth += 12; -#ifdef __WXMAC_OSX__ - nDateWidth += 5; - dResize -= 0.01; -#endif - wxListCtrl* pplistCtrl[] = {m_listCtrlAll, m_listCtrlSentReceived, m_listCtrlSent, m_listCtrlReceived}; - BOOST_FOREACH(wxListCtrl* p, pplistCtrl) - { - p->InsertColumn(0, "", wxLIST_FORMAT_LEFT, dResize * 0); - p->InsertColumn(1, "", wxLIST_FORMAT_LEFT, dResize * 0); - p->InsertColumn(2, _("Status"), wxLIST_FORMAT_LEFT, dResize * 112); - p->InsertColumn(3, _("Date"), wxLIST_FORMAT_LEFT, dResize * nDateWidth); - p->InsertColumn(4, _("Description"), wxLIST_FORMAT_LEFT, dResize * 409 - nDateWidth); - p->InsertColumn(5, _("Debit"), wxLIST_FORMAT_RIGHT, dResize * 79); - p->InsertColumn(6, _("Credit"), wxLIST_FORMAT_RIGHT, dResize * 79); - } - - // Init status bar - int pnWidths[3] = { -100, 88, 300 }; -#ifndef __WXMSW__ - pnWidths[1] = pnWidths[1] * 1.1 * dResize; - pnWidths[2] = pnWidths[2] * 1.1 * dResize; -#endif - m_statusBar->SetFieldsCount(3, pnWidths); - - // Fill your address text box - vector<unsigned char> vchPubKey; - if (CWalletDB(pwalletMain->strWalletFile,"r").ReadDefaultKey(vchPubKey)) - m_textCtrlAddress->SetValue(PubKeyToAddress(vchPubKey)); - - // Fill listctrl with wallet transactions - RefreshListCtrl(); -} - -CMainFrame::~CMainFrame() -{ - pframeMain = NULL; - delete ptaskbaricon; - ptaskbaricon = NULL; -} - -void CMainFrame::OnNotebookPageChanged(wxNotebookEvent& event) -{ - event.Skip(); - nPage = event.GetSelection(); - if (nPage == ALL) - { - m_listCtrl = m_listCtrlAll; - fShowGenerated = true; - fShowSent = true; - fShowReceived = true; - } - else if (nPage == SENTRECEIVED) - { - m_listCtrl = m_listCtrlSentReceived; - fShowGenerated = false; - fShowSent = true; - fShowReceived = true; - } - else if (nPage == SENT) - { - m_listCtrl = m_listCtrlSent; - fShowGenerated = false; - fShowSent = true; - fShowReceived = false; - } - else if (nPage == RECEIVED) - { - m_listCtrl = m_listCtrlReceived; - fShowGenerated = false; - fShowSent = false; - fShowReceived = true; - } - RefreshListCtrl(); - m_listCtrl->SetFocus(); -} - -void CMainFrame::OnClose(wxCloseEvent& event) -{ - if (fMinimizeOnClose && event.CanVeto() && !IsIconized()) - { - // Divert close to minimize - event.Veto(); - fClosedToTray = true; - Iconize(true); - } - else - { - Destroy(); - CreateThread(Shutdown, NULL); - } -} - -void CMainFrame::OnIconize(wxIconizeEvent& event) -{ - event.Skip(); - // Hide the task bar button when minimized. - // Event is sent when the frame is minimized or restored. - // wxWidgets 2.8.9 doesn't have IsIconized() so there's no way - // to get rid of the deprecated warning. Just ignore it. - if (!event.Iconized()) - fClosedToTray = false; -#if defined(__WXGTK__) || defined(__WXMAC_OSX__) - if (GetBoolArg("-minimizetotray")) { -#endif - // The tray icon sometimes disappears on ubuntu karmic - // Hiding the taskbar button doesn't work cleanly on ubuntu lucid - // Reports of CPU peg on 64-bit linux - if (fMinimizeToTray && event.Iconized()) - fClosedToTray = true; - Show(!fClosedToTray); - ptaskbaricon->Show(fMinimizeToTray || fClosedToTray); -#if defined(__WXGTK__) || defined(__WXMAC_OSX__) - } -#endif -} - -void CMainFrame::OnMouseEvents(wxMouseEvent& event) -{ - event.Skip(); - RandAddSeed(); - RAND_add(&event.m_x, sizeof(event.m_x), 0.25); - RAND_add(&event.m_y, sizeof(event.m_y), 0.25); -} - -void CMainFrame::OnListColBeginDrag(wxListEvent& event) -{ - // Hidden columns not resizeable - if (event.GetColumn() <= 1 && !fDebug) - event.Veto(); - else - event.Skip(); -} - -int CMainFrame::GetSortIndex(const string& strSort) -{ -#ifdef __WXMSW__ - return 0; -#else - // The wx generic listctrl implementation used on GTK doesn't sort, - // so we have to do it ourselves. Remember, we sort in reverse order. - // In the wx generic implementation, they store the list of items - // in a vector, so indexed lookups are fast, but inserts are slower - // the closer they are to the top. - int low = 0; - int high = m_listCtrl->GetItemCount(); - while (low < high) - { - int mid = low + ((high - low) / 2); - if (strSort.compare(m_listCtrl->GetItemText(mid).c_str()) >= 0) - high = mid; - else - low = mid + 1; - } - return low; -#endif -} - -void CMainFrame::InsertLine(bool fNew, int nIndex, uint256 hashKey, string strSort, const wxColour& colour, const wxString& str2, const wxString& str3, const wxString& str4, const wxString& str5, const wxString& str6) -{ - strSort = " " + strSort; // leading space to workaround wx2.9.0 ubuntu 9.10 bug - long nData = *(long*)&hashKey; // where first char of hidden column is displayed - - // Find item - if (!fNew && nIndex == -1) - { - string strHash = " " + hashKey.ToString(); - while ((nIndex = m_listCtrl->FindItem(nIndex, nData)) != -1) - if (GetItemText(m_listCtrl, nIndex, 1) == strHash) - break; - } - - // fNew is for blind insert, only use if you're sure it's new - if (fNew || nIndex == -1) - { - nIndex = m_listCtrl->InsertItem(GetSortIndex(strSort), strSort); - } - else - { - // If sort key changed, must delete and reinsert to make it relocate - if (GetItemText(m_listCtrl, nIndex, 0) != strSort) - { - m_listCtrl->DeleteItem(nIndex); - nIndex = m_listCtrl->InsertItem(GetSortIndex(strSort), strSort); - } - } - - m_listCtrl->SetItem(nIndex, 1, " " + hashKey.ToString()); - m_listCtrl->SetItem(nIndex, 2, str2); - m_listCtrl->SetItem(nIndex, 3, str3); - m_listCtrl->SetItem(nIndex, 4, str4); - m_listCtrl->SetItem(nIndex, 5, str5); - m_listCtrl->SetItem(nIndex, 6, str6); - m_listCtrl->SetItemData(nIndex, nData); - SetItemTextColour(m_listCtrl, nIndex, colour); -} - -bool CMainFrame::DeleteLine(uint256 hashKey) -{ - long nData = *(long*)&hashKey; - - // Find item - int nIndex = -1; - string strHash = " " + hashKey.ToString(); - while ((nIndex = m_listCtrl->FindItem(nIndex, nData)) != -1) - if (GetItemText(m_listCtrl, nIndex, 1) == strHash) - break; - - if (nIndex != -1) - m_listCtrl->DeleteItem(nIndex); - - return nIndex != -1; -} - -string FormatTxStatus(const CWalletTx& wtx) -{ - // Status - if (!wtx.IsFinal()) - { - if (wtx.nLockTime < 500000000) - return strprintf(_("Open for %d blocks"), nBestHeight - wtx.nLockTime); - else - return strprintf(_("Open until %s"), DateTimeStr(wtx.nLockTime).c_str()); - } - else - { - int nDepth = wtx.GetDepthInMainChain(); - if (GetAdjustedTime() - wtx.nTimeReceived > 2 * 60 && wtx.GetRequestCount() == 0) - return strprintf(_("%d/offline?"), nDepth); - else if (nDepth < 6) - return strprintf(_("%d/unconfirmed"), nDepth); - else - return strprintf(_("%d confirmations"), nDepth); - } -} - -string SingleLine(const string& strIn) -{ - string strOut; - bool fOneSpace = false; - BOOST_FOREACH(unsigned char c, strIn) - { - if (isspace(c)) - { - fOneSpace = true; - } - else if (c > ' ') - { - if (fOneSpace && !strOut.empty()) - strOut += ' '; - strOut += c; - fOneSpace = false; - } - } - return strOut; -} - -bool CMainFrame::InsertTransaction(const CWalletTx& wtx, bool fNew, int nIndex) -{ - int64 nTime = wtx.nTimeDisplayed = wtx.GetTxTime(); - int64 nCredit = wtx.GetCredit(true); - int64 nDebit = wtx.GetDebit(); - int64 nNet = nCredit - nDebit; - uint256 hash = wtx.GetHash(); - string strStatus = FormatTxStatus(wtx); - bool fConfirmed = wtx.fConfirmedDisplayed = wtx.IsConfirmed(); - wxColour colour = (fConfirmed ? wxColour(0,0,0) : wxColour(128,128,128)); - map<string, string> mapValue = wtx.mapValue; - wtx.nLinesDisplayed = 1; - nListViewUpdated++; - - // Filter - if (wtx.IsCoinBase()) - { - // Don't show generated coin until confirmed by at least one block after it - // so we don't get the user's hopes up until it looks like it's probably accepted. - // - // It is not an error when generated blocks are not accepted. By design, - // some percentage of blocks, like 10% or more, will end up not accepted. - // This is the normal mechanism by which the network copes with latency. - // - // We display regular transactions right away before any confirmation - // because they can always get into some block eventually. Generated coins - // are special because if their block is not accepted, they are not valid. - // - if (wtx.GetDepthInMainChain() < 2) - { - wtx.nLinesDisplayed = 0; - return false; - } - - if (!fShowGenerated) - return false; - } - - // Find the block the tx is in - CBlockIndex* pindex = NULL; - map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(wtx.hashBlock); - if (mi != mapBlockIndex.end()) - pindex = (*mi).second; - - // Sort order, unrecorded transactions sort to the top - string strSort = strprintf("%010d-%01d-%010u", - (pindex ? pindex->nHeight : INT_MAX), - (wtx.IsCoinBase() ? 1 : 0), - wtx.nTimeReceived); - - // Insert line - if (nNet > 0 || wtx.IsCoinBase()) - { - // - // Credit - // - string strDescription; - if (wtx.IsCoinBase()) - { - // Generated - strDescription = _("Generated"); - if (nCredit == 0) - { - int64 nUnmatured = 0; - BOOST_FOREACH(const CTxOut& txout, wtx.vout) - nUnmatured += pwalletMain->GetCredit(txout); - if (wtx.IsInMainChain()) - { - strDescription = strprintf(_("Generated (%s matures in %d more blocks)"), FormatMoney(nUnmatured).c_str(), wtx.GetBlocksToMaturity()); - - // Check if the block was requested by anyone - if (GetAdjustedTime() - wtx.nTimeReceived > 2 * 60 && wtx.GetRequestCount() == 0) - strDescription = _("Generated - Warning: This block was not received by any other nodes and will probably not be accepted!"); - } - else - { - strDescription = _("Generated (not accepted)"); - } - } - } - else if (!mapValue["from"].empty() || !mapValue["message"].empty()) - { - // Received by IP connection - if (!fShowReceived) - return false; - if (!mapValue["from"].empty()) - strDescription += _("From: ") + mapValue["from"]; - if (!mapValue["message"].empty()) - { - if (!strDescription.empty()) - strDescription += " - "; - strDescription += mapValue["message"]; - } - } - else - { - // Received by Bitcoin Address - if (!fShowReceived) - return false; - BOOST_FOREACH(const CTxOut& txout, wtx.vout) - { - if (pwalletMain->IsMine(txout)) - { - vector<unsigned char> vchPubKey; - if (ExtractPubKey(txout.scriptPubKey, pwalletMain, vchPubKey)) - { - CRITICAL_BLOCK(pwalletMain->cs_mapAddressBook) - { - //strDescription += _("Received payment to "); - //strDescription += _("Received with address "); - strDescription += _("Received with: "); - string strAddress = PubKeyToAddress(vchPubKey); - map<string, string>::iterator mi = pwalletMain->mapAddressBook.find(strAddress); - if (mi != pwalletMain->mapAddressBook.end() && !(*mi).second.empty()) - { - string strLabel = (*mi).second; - strDescription += strAddress.substr(0,12) + "... "; - strDescription += "(" + strLabel + ")"; - } - else - strDescription += strAddress; - } - } - break; - } - } - } - - string strCredit = FormatMoney(nNet, true); - if (!fConfirmed) - strCredit = "[" + strCredit + "]"; - - InsertLine(fNew, nIndex, hash, strSort, colour, - strStatus, - nTime ? DateTimeStr(nTime) : "", - SingleLine(strDescription), - "", - strCredit); - } - else - { - bool fAllFromMe = true; - BOOST_FOREACH(const CTxIn& txin, wtx.vin) - fAllFromMe = fAllFromMe && pwalletMain->IsMine(txin); - - bool fAllToMe = true; - BOOST_FOREACH(const CTxOut& txout, wtx.vout) - fAllToMe = fAllToMe && pwalletMain->IsMine(txout); - - if (fAllFromMe && fAllToMe) - { - // Payment to self - int64 nChange = wtx.GetChange(); - InsertLine(fNew, nIndex, hash, strSort, colour, - strStatus, - nTime ? DateTimeStr(nTime) : "", - _("Payment to yourself"), - FormatMoney(-(nDebit - nChange), true), - FormatMoney(nCredit - nChange, true)); - } - else if (fAllFromMe) - { - // - // Debit - // - if (!fShowSent) - return false; - - int64 nTxFee = nDebit - wtx.GetValueOut(); - wtx.nLinesDisplayed = 0; - for (int nOut = 0; nOut < wtx.vout.size(); nOut++) - { - const CTxOut& txout = wtx.vout[nOut]; - if (pwalletMain->IsMine(txout)) - continue; - - string strAddress; - if (!mapValue["to"].empty()) - { - // Sent to IP - strAddress = mapValue["to"]; - } - else - { - // Sent to Bitcoin Address - uint160 hash160; - if (ExtractHash160(txout.scriptPubKey, hash160)) - strAddress = Hash160ToAddress(hash160); - } - - string strDescription = _("To: "); - CRITICAL_BLOCK(pwalletMain->cs_mapAddressBook) - if (pwalletMain->mapAddressBook.count(strAddress) && !pwalletMain->mapAddressBook[strAddress].empty()) - strDescription += pwalletMain->mapAddressBook[strAddress] + " "; - strDescription += strAddress; - if (!mapValue["message"].empty()) - { - if (!strDescription.empty()) - strDescription += " - "; - strDescription += mapValue["message"]; - } - else if (!mapValue["comment"].empty()) - { - if (!strDescription.empty()) - strDescription += " - "; - strDescription += mapValue["comment"]; - } - - int64 nValue = txout.nValue; - if (nTxFee > 0) - { - nValue += nTxFee; - nTxFee = 0; - } - - InsertLine(fNew, nIndex, hash, strprintf("%s-%d", strSort.c_str(), nOut), colour, - strStatus, - nTime ? DateTimeStr(nTime) : "", - SingleLine(strDescription), - FormatMoney(-nValue, true), - ""); - nIndex = -1; - wtx.nLinesDisplayed++; - } - } - else - { - // - // Mixed debit transaction, can't break down payees - // - bool fAllMine = true; - BOOST_FOREACH(const CTxOut& txout, wtx.vout) - fAllMine = fAllMine && pwalletMain->IsMine(txout); - BOOST_FOREACH(const CTxIn& txin, wtx.vin) - fAllMine = fAllMine && pwalletMain->IsMine(txin); - - InsertLine(fNew, nIndex, hash, strSort, colour, - strStatus, - nTime ? DateTimeStr(nTime) : "", - "", - FormatMoney(nNet, true), - ""); - } - } - - return true; -} - -void CMainFrame::RefreshListCtrl() -{ - fRefreshListCtrl = true; - ::wxWakeUpIdle(); -} - -void CMainFrame::OnIdle(wxIdleEvent& event) -{ - if (fRefreshListCtrl) - { - // Collect list of wallet transactions and sort newest first - bool fEntered = false; - vector<pair<unsigned int, uint256> > vSorted; - TRY_CRITICAL_BLOCK(pwalletMain->cs_mapWallet) - { - printf("RefreshListCtrl starting\n"); - fEntered = true; - fRefreshListCtrl = false; - pwalletMain->vWalletUpdated.clear(); - - // Do the newest transactions first - vSorted.reserve(pwalletMain->mapWallet.size()); - for (map<uint256, CWalletTx>::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); ++it) - { - const CWalletTx& wtx = (*it).second; - unsigned int nTime = UINT_MAX - wtx.GetTxTime(); - vSorted.push_back(make_pair(nTime, (*it).first)); - } - m_listCtrl->DeleteAllItems(); - } - if (!fEntered) - return; - - sort(vSorted.begin(), vSorted.end()); - - // Fill list control - for (int i = 0; i < vSorted.size();) - { - if (fShutdown) - return; - bool fEntered = false; - TRY_CRITICAL_BLOCK(pwalletMain->cs_mapWallet) - { - fEntered = true; - uint256& hash = vSorted[i++].second; - map<uint256, CWalletTx>::iterator mi = pwalletMain->mapWallet.find(hash); - if (mi != pwalletMain->mapWallet.end()) - InsertTransaction((*mi).second, true); - } - if (!fEntered || i == 100 || i % 500 == 0) - wxYield(); - } - - printf("RefreshListCtrl done\n"); - - // Update transaction total display - MainFrameRepaint(); - } - else - { - // Check for time updates - static int64 nLastTime; - if (GetTime() > nLastTime + 30) - { - TRY_CRITICAL_BLOCK(pwalletMain->cs_mapWallet) - { - nLastTime = GetTime(); - for (map<uint256, CWalletTx>::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); ++it) - { - CWalletTx& wtx = (*it).second; - if (wtx.nTimeDisplayed && wtx.nTimeDisplayed != wtx.GetTxTime()) - InsertTransaction(wtx, false); - } - } - } - } -} - -void CMainFrame::RefreshStatusColumn() -{ - static int nLastTop; - static CBlockIndex* pindexLastBest; - static unsigned int nLastRefreshed; - - int nTop = max((int)m_listCtrl->GetTopItem(), 0); - if (nTop == nLastTop && pindexLastBest == pindexBest) - return; - - TRY_CRITICAL_BLOCK(pwalletMain->cs_mapWallet) - { - int nStart = nTop; - int nEnd = min(nStart + 100, m_listCtrl->GetItemCount()); - - if (pindexLastBest == pindexBest && nLastRefreshed == nListViewUpdated) - { - // If no updates, only need to do the part that moved onto the screen - if (nStart >= nLastTop && nStart < nLastTop + 100) - nStart = nLastTop + 100; - if (nEnd >= nLastTop && nEnd < nLastTop + 100) - nEnd = nLastTop; - } - nLastTop = nTop; - pindexLastBest = pindexBest; - nLastRefreshed = nListViewUpdated; - - for (int nIndex = nStart; nIndex < min(nEnd, m_listCtrl->GetItemCount()); nIndex++) - { - uint256 hash((string)GetItemText(m_listCtrl, nIndex, 1)); - map<uint256, CWalletTx>::iterator mi = pwalletMain->mapWallet.find(hash); - if (mi == pwalletMain->mapWallet.end()) - { - printf("CMainFrame::RefreshStatusColumn() : tx not found in mapWallet\n"); - continue; - } - CWalletTx& wtx = (*mi).second; - if (wtx.IsCoinBase() || - wtx.GetTxTime() != wtx.nTimeDisplayed || - wtx.IsConfirmed() != wtx.fConfirmedDisplayed) - { - if (!InsertTransaction(wtx, false, nIndex)) - m_listCtrl->DeleteItem(nIndex--); - } - else - { - m_listCtrl->SetItem(nIndex, 2, FormatTxStatus(wtx)); - } - } - } -} - -void CMainFrame::OnPaint(wxPaintEvent& event) -{ - event.Skip(); - if (fRefresh) - { - fRefresh = false; - Refresh(); - } -} - - -unsigned int nNeedRepaint = 0; -unsigned int nLastRepaint = 0; -int64 nLastRepaintTime = 0; -int64 nRepaintInterval = 500; - -void ThreadDelayedRepaint(void* parg) -{ - while (!fShutdown) - { - if (nLastRepaint != nNeedRepaint && GetTimeMillis() - nLastRepaintTime >= nRepaintInterval) - { - nLastRepaint = nNeedRepaint; - if (pframeMain) - { - printf("DelayedRepaint\n"); - wxPaintEvent event; - pframeMain->fRefresh = true; - pframeMain->GetEventHandler()->AddPendingEvent(event); - } - } - Sleep(nRepaintInterval); - } -} - -void MainFrameRepaint() -{ - // This is called by network code that shouldn't access pframeMain - // directly because it could still be running after the UI is closed. - if (pframeMain) - { - // Don't repaint too often - static int64 nLastRepaintRequest; - if (GetTimeMillis() - nLastRepaintRequest < 100) - { - nNeedRepaint++; - return; - } - nLastRepaintRequest = GetTimeMillis(); - - printf("MainFrameRepaint\n"); - wxPaintEvent event; - pframeMain->fRefresh = true; - pframeMain->GetEventHandler()->AddPendingEvent(event); - } -} - -void CMainFrame::OnPaintListCtrl(wxPaintEvent& event) -{ - // Skip lets the listctrl do the paint, we're just hooking the message - event.Skip(); - - if (ptaskbaricon) - ptaskbaricon->UpdateTooltip(); - - // - // Slower stuff - // - static int nTransactionCount; - bool fPaintedBalance = false; - if (GetTimeMillis() - nLastRepaintTime >= nRepaintInterval) - { - nLastRepaint = nNeedRepaint; - nLastRepaintTime = GetTimeMillis(); - - // Update listctrl contents - if (!pwalletMain->vWalletUpdated.empty()) - { - TRY_CRITICAL_BLOCK(pwalletMain->cs_mapWallet) - { - string strTop; - if (m_listCtrl->GetItemCount()) - strTop = (string)m_listCtrl->GetItemText(0); - BOOST_FOREACH(uint256 hash, pwalletMain->vWalletUpdated) - { - map<uint256, CWalletTx>::iterator mi = pwalletMain->mapWallet.find(hash); - if (mi != pwalletMain->mapWallet.end()) - InsertTransaction((*mi).second, false); - } - pwalletMain->vWalletUpdated.clear(); - if (m_listCtrl->GetItemCount() && strTop != (string)m_listCtrl->GetItemText(0)) - m_listCtrl->ScrollList(0, INT_MIN/2); - } - } - - // Balance total - TRY_CRITICAL_BLOCK(pwalletMain->cs_mapWallet) - { - fPaintedBalance = true; - m_staticTextBalance->SetLabel(FormatMoney(pwalletMain->GetBalance()) + " "); - - // Count hidden and multi-line transactions - nTransactionCount = 0; - for (map<uint256, CWalletTx>::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); ++it) - { - CWalletTx& wtx = (*it).second; - nTransactionCount += wtx.nLinesDisplayed; - } - } - } - if (!pwalletMain->vWalletUpdated.empty() || !fPaintedBalance) - nNeedRepaint++; - - // Update status column of visible items only - RefreshStatusColumn(); - - // Update status bar - static string strPrevWarning; - string strWarning = GetWarnings("statusbar"); - if (strWarning != "") - m_statusBar->SetStatusText(string(" ") + _(strWarning), 0); - else if (strPrevWarning != "") - m_statusBar->SetStatusText("", 0); - strPrevWarning = strWarning; - - string strGen = ""; - if (fGenerateBitcoins) - strGen = _(" Generating"); - if (fGenerateBitcoins && vNodes.empty()) - strGen = _("(not connected)"); - m_statusBar->SetStatusText(strGen, 1); - - string strStatus = strprintf(_(" %d connections %d blocks %d transactions"), vNodes.size(), nBestHeight, nTransactionCount); - m_statusBar->SetStatusText(strStatus, 2); - - // Update receiving address - string strDefaultAddress = PubKeyToAddress(pwalletMain->vchDefaultKey); - if (m_textCtrlAddress->GetValue() != strDefaultAddress) - m_textCtrlAddress->SetValue(strDefaultAddress); -} - - -void UIThreadCall(boost::function0<void> fn) -{ - // Call this with a function object created with bind. - // bind needs all parameters to match the function's expected types - // and all default parameters specified. Some examples: - // UIThreadCall(bind(wxBell)); - // UIThreadCall(bind(wxMessageBox, wxT("Message"), wxT("Title"), wxOK, (wxWindow*)NULL, -1, -1)); - // UIThreadCall(bind(&CMainFrame::OnMenuHelpAbout, pframeMain, event)); - if (pframeMain) - { - wxCommandEvent event(wxEVT_UITHREADCALL); - event.SetClientData((void*)new boost::function0<void>(fn)); - pframeMain->GetEventHandler()->AddPendingEvent(event); - } -} - -void CMainFrame::OnUIThreadCall(wxCommandEvent& event) -{ - boost::function0<void>* pfn = (boost::function0<void>*)event.GetClientData(); - (*pfn)(); - delete pfn; -} - -void CMainFrame::OnMenuFileExit(wxCommandEvent& event) -{ - // File->Exit - Close(true); -} - -void CMainFrame::OnUpdateUIOptionsGenerate(wxUpdateUIEvent& event) -{ - event.Check(fGenerateBitcoins); -} - -void CMainFrame::OnMenuOptionsChangeYourAddress(wxCommandEvent& event) -{ - // Options->Your Receiving Addresses - CAddressBookDialog dialog(this, "", CAddressBookDialog::RECEIVING, false); - if (!dialog.ShowModal()) - return; -} - -void CMainFrame::OnMenuOptionsOptions(wxCommandEvent& event) -{ - // Options->Options - COptionsDialog dialog(this); - dialog.ShowModal(); -} - -void CMainFrame::OnMenuHelpAbout(wxCommandEvent& event) -{ - // Help->About - CAboutDialog dialog(this); - dialog.ShowModal(); -} - -void CMainFrame::OnButtonSend(wxCommandEvent& event) -{ - // Toolbar: Send - CSendDialog dialog(this); - dialog.ShowModal(); -} - -void CMainFrame::OnButtonAddressBook(wxCommandEvent& event) -{ - // Toolbar: Address Book - CAddressBookDialog dialogAddr(this, "", CAddressBookDialog::SENDING, false); - if (dialogAddr.ShowModal() == 2) - { - // Send - CSendDialog dialogSend(this, dialogAddr.GetSelectedAddress()); - dialogSend.ShowModal(); - } -} - -void CMainFrame::OnSetFocusAddress(wxFocusEvent& event) -{ - // Automatically select-all when entering window - event.Skip(); - m_textCtrlAddress->SetSelection(-1, -1); - fOnSetFocusAddress = true; -} - -void CMainFrame::OnMouseEventsAddress(wxMouseEvent& event) -{ - event.Skip(); - if (fOnSetFocusAddress) - m_textCtrlAddress->SetSelection(-1, -1); - fOnSetFocusAddress = false; -} - -void CMainFrame::OnButtonNew(wxCommandEvent& event) -{ - // Ask name - CGetTextFromUserDialog dialog(this, - _("New Receiving Address"), - _("You should use a new address for each payment you receive.\n\nLabel"), - ""); - if (!dialog.ShowModal()) - return; - string strName = dialog.GetValue(); - - // Generate new key - string strAddress = PubKeyToAddress(pwalletMain->GetKeyFromKeyPool()); - - // Save - CRITICAL_BLOCK(pwalletMain->cs_mapAddressBook) - pwalletMain->SetAddressBookName(strAddress, strName); - SetDefaultReceivingAddress(strAddress); -} - -void CMainFrame::OnButtonCopy(wxCommandEvent& event) -{ - // Copy address box to clipboard - if (wxTheClipboard->Open()) - { - wxTheClipboard->SetData(new wxTextDataObject(m_textCtrlAddress->GetValue())); - wxTheClipboard->Close(); - } -} - -void CMainFrame::OnListItemActivated(wxListEvent& event) -{ - uint256 hash((string)GetItemText(m_listCtrl, event.GetIndex(), 1)); - CWalletTx wtx; - CRITICAL_BLOCK(pwalletMain->cs_mapWallet) - { - map<uint256, CWalletTx>::iterator mi = pwalletMain->mapWallet.find(hash); - if (mi == pwalletMain->mapWallet.end()) - { - printf("CMainFrame::OnListItemActivated() : tx not found in mapWallet\n"); - return; - } - wtx = (*mi).second; - } - CTxDetailsDialog dialog(this, wtx); - dialog.ShowModal(); - //CTxDetailsDialog* pdialog = new CTxDetailsDialog(this, wtx); - //pdialog->Show(); -} - - - - - - -////////////////////////////////////////////////////////////////////////////// -// -// CTxDetailsDialog -// - -CTxDetailsDialog::CTxDetailsDialog(wxWindow* parent, CWalletTx wtx) : CTxDetailsDialogBase(parent) -{ -#ifdef __WXMSW__ - SetSize(nScaleX * GetSize().GetWidth(), nScaleY * GetSize().GetHeight()); -#endif - CRITICAL_BLOCK(pwalletMain->cs_mapAddressBook) - { - string strHTML; - strHTML.reserve(4000); - strHTML += "<html><font face='verdana, arial, helvetica, sans-serif'>"; - - int64 nTime = wtx.GetTxTime(); - int64 nCredit = wtx.GetCredit(); - int64 nDebit = wtx.GetDebit(); - int64 nNet = nCredit - nDebit; - - - - strHTML += _("<b>Status:</b> ") + FormatTxStatus(wtx); - int nRequests = wtx.GetRequestCount(); - if (nRequests != -1) - { - if (nRequests == 0) - strHTML += _(", has not been successfully broadcast yet"); - else if (nRequests == 1) - strHTML += strprintf(_(", broadcast through %d node"), nRequests); - else - strHTML += strprintf(_(", broadcast through %d nodes"), nRequests); - } - strHTML += "<br>"; - - strHTML += _("<b>Date:</b> ") + (nTime ? DateTimeStr(nTime) : "") + "<br>"; - - - // - // From - // - if (wtx.IsCoinBase()) - { - strHTML += _("<b>Source:</b> Generated<br>"); - } - else if (!wtx.mapValue["from"].empty()) - { - // Online transaction - if (!wtx.mapValue["from"].empty()) - strHTML += _("<b>From:</b> ") + HtmlEscape(wtx.mapValue["from"]) + "<br>"; - } - else - { - // Offline transaction - if (nNet > 0) - { - // Credit - BOOST_FOREACH(const CTxOut& txout, wtx.vout) - { - if (pwalletMain->IsMine(txout)) - { - vector<unsigned char> vchPubKey; - if (ExtractPubKey(txout.scriptPubKey, pwalletMain, vchPubKey)) - { - string strAddress = PubKeyToAddress(vchPubKey); - if (pwalletMain->mapAddressBook.count(strAddress)) - { - strHTML += string() + _("<b>From:</b> ") + _("unknown") + "<br>"; - strHTML += _("<b>To:</b> "); - strHTML += HtmlEscape(strAddress); - if (!pwalletMain->mapAddressBook[strAddress].empty()) - strHTML += _(" (yours, label: ") + pwalletMain->mapAddressBook[strAddress] + ")"; - else - strHTML += _(" (yours)"); - strHTML += "<br>"; - } - } - break; - } - } - } - } - - - // - // To - // - string strAddress; - if (!wtx.mapValue["to"].empty()) - { - // Online transaction - strAddress = wtx.mapValue["to"]; - strHTML += _("<b>To:</b> "); - if (pwalletMain->mapAddressBook.count(strAddress) && !pwalletMain->mapAddressBook[strAddress].empty()) - strHTML += pwalletMain->mapAddressBook[strAddress] + " "; - strHTML += HtmlEscape(strAddress) + "<br>"; - } - - - // - // Amount - // - if (wtx.IsCoinBase() && nCredit == 0) - { - // - // Coinbase - // - int64 nUnmatured = 0; - BOOST_FOREACH(const CTxOut& txout, wtx.vout) - nUnmatured += pwalletMain->GetCredit(txout); - strHTML += _("<b>Credit:</b> "); - if (wtx.IsInMainChain()) - strHTML += strprintf(_("(%s matures in %d more blocks)"), FormatMoney(nUnmatured).c_str(), wtx.GetBlocksToMaturity()); - else - strHTML += _("(not accepted)"); - strHTML += "<br>"; - } - else if (nNet > 0) - { - // - // Credit - // - strHTML += _("<b>Credit:</b> ") + FormatMoney(nNet) + "<br>"; - } - else - { - bool fAllFromMe = true; - BOOST_FOREACH(const CTxIn& txin, wtx.vin) - fAllFromMe = fAllFromMe && pwalletMain->IsMine(txin); - - bool fAllToMe = true; - BOOST_FOREACH(const CTxOut& txout, wtx.vout) - fAllToMe = fAllToMe && pwalletMain->IsMine(txout); - - if (fAllFromMe) - { - // - // Debit - // - BOOST_FOREACH(const CTxOut& txout, wtx.vout) - { - if (pwalletMain->IsMine(txout)) - continue; - - if (wtx.mapValue["to"].empty()) - { - // Offline transaction - uint160 hash160; - if (ExtractHash160(txout.scriptPubKey, hash160)) - { - string strAddress = Hash160ToAddress(hash160); - strHTML += _("<b>To:</b> "); - if (pwalletMain->mapAddressBook.count(strAddress) && !pwalletMain->mapAddressBook[strAddress].empty()) - strHTML += pwalletMain->mapAddressBook[strAddress] + " "; - strHTML += strAddress; - strHTML += "<br>"; - } - } - - strHTML += _("<b>Debit:</b> ") + FormatMoney(-txout.nValue) + "<br>"; - } - - if (fAllToMe) - { - // Payment to self - int64 nChange = wtx.GetChange(); - int64 nValue = nCredit - nChange; - strHTML += _("<b>Debit:</b> ") + FormatMoney(-nValue) + "<br>"; - strHTML += _("<b>Credit:</b> ") + FormatMoney(nValue) + "<br>"; - } - - int64 nTxFee = nDebit - wtx.GetValueOut(); - if (nTxFee > 0) - strHTML += _("<b>Transaction fee:</b> ") + FormatMoney(-nTxFee) + "<br>"; - } - else - { - // - // Mixed debit transaction - // - BOOST_FOREACH(const CTxIn& txin, wtx.vin) - if (pwalletMain->IsMine(txin)) - strHTML += _("<b>Debit:</b> ") + FormatMoney(-pwalletMain->GetDebit(txin)) + "<br>"; - BOOST_FOREACH(const CTxOut& txout, wtx.vout) - if (pwalletMain->IsMine(txout)) - strHTML += _("<b>Credit:</b> ") + FormatMoney(pwalletMain->GetCredit(txout)) + "<br>"; - } - } - - strHTML += _("<b>Net amount:</b> ") + FormatMoney(nNet, true) + "<br>"; - - - // - // Message - // - if (!wtx.mapValue["message"].empty()) - strHTML += string() + "<br><b>" + _("Message:") + "</b><br>" + HtmlEscape(wtx.mapValue["message"], true) + "<br>"; - if (!wtx.mapValue["comment"].empty()) - strHTML += string() + "<br><b>" + _("Comment:") + "</b><br>" + HtmlEscape(wtx.mapValue["comment"], true) + "<br>"; - - if (wtx.IsCoinBase()) - strHTML += string() + "<br>" + _("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 \"not accepted\" and not be spendable. This may occasionally happen if another node generates a block within a few seconds of yours.") + "<br>"; - - - // - // Debug view - // - if (fDebug) - { - strHTML += "<hr><br>debug print<br><br>"; - BOOST_FOREACH(const CTxIn& txin, wtx.vin) - if (pwalletMain->IsMine(txin)) - strHTML += "<b>Debit:</b> " + FormatMoney(-pwalletMain->GetDebit(txin)) + "<br>"; - BOOST_FOREACH(const CTxOut& txout, wtx.vout) - if (pwalletMain->IsMine(txout)) - strHTML += "<b>Credit:</b> " + FormatMoney(pwalletMain->GetCredit(txout)) + "<br>"; - - strHTML += "<br><b>Transaction:</b><br>"; - strHTML += HtmlEscape(wtx.ToString(), true); - - strHTML += "<br><b>Inputs:</b><br>"; - CRITICAL_BLOCK(pwalletMain->cs_mapWallet) - { - BOOST_FOREACH(const CTxIn& txin, wtx.vin) - { - COutPoint prevout = txin.prevout; - map<uint256, CWalletTx>::iterator mi = pwalletMain->mapWallet.find(prevout.hash); - if (mi != pwalletMain->mapWallet.end()) - { - const CWalletTx& prev = (*mi).second; - if (prevout.n < prev.vout.size()) - { - strHTML += HtmlEscape(prev.ToString(), true); - strHTML += " " + FormatTxStatus(prev) + ", "; - strHTML = strHTML + "IsMine=" + (pwalletMain->IsMine(prev.vout[prevout.n]) ? "true" : "false") + "<br>"; - } - } - } - } - } - - - - strHTML += "</font></html>"; - string(strHTML.begin(), strHTML.end()).swap(strHTML); - m_htmlWin->SetPage(strHTML); - m_buttonOK->SetFocus(); - } -} - -void CTxDetailsDialog::OnButtonOK(wxCommandEvent& event) -{ - EndModal(false); -} - - - - - - -////////////////////////////////////////////////////////////////////////////// -// -// Startup folder -// - -#ifdef __WXMSW__ -string StartupShortcutPath() -{ - return MyGetSpecialFolderPath(CSIDL_STARTUP, true) + "\\Bitcoin.lnk"; -} - -bool GetStartOnSystemStartup() -{ - return filesystem::exists(StartupShortcutPath().c_str()); -} - -void SetStartOnSystemStartup(bool fAutoStart) -{ - // If the shortcut exists already, remove it for updating - remove(StartupShortcutPath().c_str()); - - 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)); - - // Set the path to the shortcut target - psl->SetPath(pszExePath); - PathRemoveFileSpec(pszExePath); - psl->SetWorkingDirectory(pszExePath); - psl->SetShowCmd(SW_SHOWMINNOACTIVE); - - // 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().c_str(), -1, pwsz, MAX_PATH); - // Save the link by calling IPersistFile::Save. - hres = ppf->Save(pwsz, TRUE); - ppf->Release(); - } - psl->Release(); - } - CoUninitialize(); - } -} - -#elif defined(__WXGTK__) - -// Follow the Desktop Application Autostart Spec: -// http://standards.freedesktop.org/autostart-spec/autostart-spec-latest.html - -boost::filesystem::path GetAutostartDir() -{ - namespace fs = boost::filesystem; - - char* pszConfigHome = getenv("XDG_CONFIG_HOME"); - if (pszConfigHome) return fs::path(pszConfigHome) / fs::path("autostart"); - char* pszHome = getenv("HOME"); - if (pszHome) return fs::path(pszHome) / fs::path(".config/autostart"); - return fs::path(); -} - -boost::filesystem::path GetAutostartFilePath() -{ - return GetAutostartDir() / boost::filesystem::path("bitcoin.desktop"); -} - -bool GetStartOnSystemStartup() -{ - boost::filesystem::ifstream optionFile(GetAutostartFilePath()); - if (!optionFile.good()) - return false; - // Scan through file for "Hidden=true": - string line; - while (!optionFile.eof()) - { - getline(optionFile, line); - if (line.find("Hidden") != string::npos && - line.find("true") != string::npos) - return false; - } - optionFile.close(); - - return true; -} - -void SetStartOnSystemStartup(bool fAutoStart) -{ - if (!fAutoStart) - { - unlink(GetAutostartFilePath().native_file_string().c_str()); - } - else - { - char pszExePath[MAX_PATH+1]; - memset(pszExePath, 0, sizeof(pszExePath)); - if (readlink("/proc/self/exe", pszExePath, sizeof(pszExePath)-1) == -1) - return; - - boost::filesystem::create_directories(GetAutostartDir()); - - boost::filesystem::ofstream optionFile(GetAutostartFilePath(), ios_base::out|ios_base::trunc); - if (!optionFile.good()) - { - wxMessageBox(_("Cannot write autostart/bitcoin.desktop file"), "Bitcoin"); - return; - } - // Write a bitcoin.desktop file to the autostart directory: - optionFile << "[Desktop Entry]\n"; - optionFile << "Type=Application\n"; - optionFile << "Name=Bitcoin\n"; - optionFile << "Exec=" << pszExePath << "\n"; - optionFile << "Terminal=false\n"; - optionFile << "Hidden=false\n"; - optionFile.close(); - } -} -#else - -// TODO: OSX startup stuff; see: -// http://developer.apple.com/mac/library/documentation/MacOSX/Conceptual/BPSystemStartup/Articles/CustomLogin.html - -bool GetStartOnSystemStartup() { return false; } -void SetStartOnSystemStartup(bool fAutoStart) { } - -#endif - - - - - - -////////////////////////////////////////////////////////////////////////////// -// -// COptionsDialog -// - -COptionsDialog::COptionsDialog(wxWindow* parent) : COptionsDialogBase(parent) -{ - // Set up list box of page choices - m_listBox->Append(_("Main")); - //m_listBox->Append(_("Test 2")); - m_listBox->SetSelection(0); - SelectPage(0); -#ifndef __WXMSW__ - SetSize(1.0 * GetSize().GetWidth(), 1.2 * GetSize().GetHeight()); -#else - SetSize(nScaleX * GetSize().GetWidth(), nScaleY * GetSize().GetHeight()); -#endif -#if defined(__WXGTK__) || defined(__WXMAC_OSX__) - m_checkBoxStartOnSystemStartup->SetLabel(_("&Start Bitcoin on window system startup")); - if (!GetBoolArg("-minimizetotray")) - { - // Minimize to tray is just too buggy on Linux - fMinimizeToTray = false; - m_checkBoxMinimizeToTray->SetValue(false); - m_checkBoxMinimizeToTray->Enable(false); - m_checkBoxMinimizeOnClose->SetLabel(_("&Minimize on close")); - } -#endif -#ifdef __WXMAC_OSX__ - m_checkBoxStartOnSystemStartup->Enable(false); // not implemented yet -#endif - - // Init values - m_textCtrlTransactionFee->SetValue(FormatMoney(nTransactionFee)); - m_checkBoxStartOnSystemStartup->SetValue(fTmpStartOnSystemStartup = GetStartOnSystemStartup()); - m_checkBoxMinimizeToTray->SetValue(fMinimizeToTray); - m_checkBoxMinimizeOnClose->SetValue(fMinimizeOnClose); - if (fHaveUPnP) - m_checkBoxUseUPnP->SetValue(fUseUPnP); - else - m_checkBoxUseUPnP->Enable(false); - m_checkBoxUseProxy->SetValue(fUseProxy); - m_textCtrlProxyIP->Enable(fUseProxy); - m_textCtrlProxyPort->Enable(fUseProxy); - m_staticTextProxyIP->Enable(fUseProxy); - m_staticTextProxyPort->Enable(fUseProxy); - m_textCtrlProxyIP->SetValue(addrProxy.ToStringIP()); - m_textCtrlProxyPort->SetValue(addrProxy.ToStringPort()); - - m_buttonOK->SetFocus(); -} - -void COptionsDialog::SelectPage(int nPage) -{ - m_panelMain->Show(nPage == 0); - m_panelTest2->Show(nPage == 1); - - m_scrolledWindow->Layout(); - m_scrolledWindow->SetScrollbars(0, 0, 0, 0, 0, 0); -} - -void COptionsDialog::OnListBox(wxCommandEvent& event) -{ - SelectPage(event.GetSelection()); -} - -void COptionsDialog::OnKillFocusTransactionFee(wxFocusEvent& event) -{ - event.Skip(); - int64 nTmp = nTransactionFee; - ParseMoney(m_textCtrlTransactionFee->GetValue(), nTmp); - m_textCtrlTransactionFee->SetValue(FormatMoney(nTmp)); -} - -void COptionsDialog::OnCheckBoxUseProxy(wxCommandEvent& event) -{ - m_textCtrlProxyIP->Enable(event.IsChecked()); - m_textCtrlProxyPort->Enable(event.IsChecked()); - m_staticTextProxyIP->Enable(event.IsChecked()); - m_staticTextProxyPort->Enable(event.IsChecked()); -} - -CAddress COptionsDialog::GetProxyAddr() -{ - // Be careful about byte order, addr.ip and addr.port are big endian - CAddress addr(m_textCtrlProxyIP->GetValue() + ":" + m_textCtrlProxyPort->GetValue()); - if (addr.ip == INADDR_NONE) - addr.ip = addrProxy.ip; - int nPort = atoi(m_textCtrlProxyPort->GetValue()); - addr.port = htons(nPort); - if (nPort <= 0 || nPort > USHRT_MAX) - addr.port = addrProxy.port; - return addr; -} - -void COptionsDialog::OnKillFocusProxy(wxFocusEvent& event) -{ - event.Skip(); - m_textCtrlProxyIP->SetValue(GetProxyAddr().ToStringIP()); - m_textCtrlProxyPort->SetValue(GetProxyAddr().ToStringPort()); -} - - -void COptionsDialog::OnButtonOK(wxCommandEvent& event) -{ - OnButtonApply(event); - EndModal(false); -} - -void COptionsDialog::OnButtonCancel(wxCommandEvent& event) -{ - EndModal(false); -} - -void COptionsDialog::OnButtonApply(wxCommandEvent& event) -{ - CWalletDB walletdb(pwalletMain->strWalletFile); - - int64 nPrevTransactionFee = nTransactionFee; - if (ParseMoney(m_textCtrlTransactionFee->GetValue(), nTransactionFee) && nTransactionFee != nPrevTransactionFee) - walletdb.WriteSetting("nTransactionFee", nTransactionFee); - - if (fTmpStartOnSystemStartup != m_checkBoxStartOnSystemStartup->GetValue()) - { - fTmpStartOnSystemStartup = m_checkBoxStartOnSystemStartup->GetValue(); - SetStartOnSystemStartup(fTmpStartOnSystemStartup); - } - - if (fMinimizeToTray != m_checkBoxMinimizeToTray->GetValue()) - { - fMinimizeToTray = m_checkBoxMinimizeToTray->GetValue(); - walletdb.WriteSetting("fMinimizeToTray", fMinimizeToTray); - ptaskbaricon->Show(fMinimizeToTray || fClosedToTray); - } - - if (fMinimizeOnClose != m_checkBoxMinimizeOnClose->GetValue()) - { - fMinimizeOnClose = m_checkBoxMinimizeOnClose->GetValue(); - walletdb.WriteSetting("fMinimizeOnClose", fMinimizeOnClose); - } - - if (fHaveUPnP && fUseUPnP != m_checkBoxUseUPnP->GetValue()) - { - fUseUPnP = m_checkBoxUseUPnP->GetValue(); - walletdb.WriteSetting("fUseUPnP", fUseUPnP); - MapPort(fUseUPnP); - } - - fUseProxy = m_checkBoxUseProxy->GetValue(); - walletdb.WriteSetting("fUseProxy", fUseProxy); - - addrProxy = GetProxyAddr(); - walletdb.WriteSetting("addrProxy", addrProxy); -} - - - - - - -////////////////////////////////////////////////////////////////////////////// -// -// CAboutDialog -// - -CAboutDialog::CAboutDialog(wxWindow* parent) : CAboutDialogBase(parent) -{ - m_staticTextVersion->SetLabel(strprintf(_("version %s"), FormatFullVersion().c_str())); - - // Change (c) into UTF-8 or ANSI copyright symbol - wxString str = m_staticTextMain->GetLabel(); -#if wxUSE_UNICODE - str.Replace("(c)", wxString::FromUTF8("\xC2\xA9")); -#else - str.Replace("(c)", "\xA9"); -#endif - m_staticTextMain->SetLabel(str); -#ifndef __WXMSW__ - // Resize on Linux to make the window fit the text. - // The text was wrapped manually rather than using the Wrap setting because - // the wrap would be too small on Linux and it can't be changed at this point. - wxFont fontTmp = m_staticTextMain->GetFont(); - if (fontTmp.GetPointSize() > 8); - fontTmp.SetPointSize(8); - m_staticTextMain->SetFont(fontTmp); - SetSize(GetSize().GetWidth() + 44, GetSize().GetHeight() + 10); -#else - SetSize(nScaleX * GetSize().GetWidth(), nScaleY * GetSize().GetHeight()); -#endif -} - -void CAboutDialog::OnButtonOK(wxCommandEvent& event) -{ - EndModal(false); -} - - - - - - -////////////////////////////////////////////////////////////////////////////// -// -// CSendDialog -// - -CSendDialog::CSendDialog(wxWindow* parent, const wxString& strAddress) : CSendDialogBase(parent) -{ - // Init - m_textCtrlAddress->SetValue(strAddress); - m_choiceTransferType->SetSelection(0); - m_bitmapCheckMark->Show(false); - fEnabledPrev = true; - m_textCtrlAddress->SetFocus(); - - //// todo: should add a display of your balance for convenience -#ifndef __WXMSW__ - wxFont fontTmp = m_staticTextInstructions->GetFont(); - if (fontTmp.GetPointSize() > 9); - fontTmp.SetPointSize(9); - m_staticTextInstructions->SetFont(fontTmp); - SetSize(725, 180); -#else - SetSize(nScaleX * GetSize().GetWidth(), nScaleY * GetSize().GetHeight()); -#endif - - // Set Icon - if (nScaleX == 1.0 && nScaleY == 1.0) // We don't have icons of the proper size otherwise - { - wxIcon iconSend; - iconSend.CopyFromBitmap(wxBitmap(send16noshadow_xpm)); - SetIcon(iconSend); - } -#ifdef __WXMSW__ - else - SetIcon(wxICON(bitcoin)); -#endif - - // Fixup the tab order - m_buttonPaste->MoveAfterInTabOrder(m_buttonCancel); - m_buttonAddress->MoveAfterInTabOrder(m_buttonPaste); - this->Layout(); -} - -void CSendDialog::OnKillFocusAmount(wxFocusEvent& event) -{ - // Reformat the amount - event.Skip(); - if (m_textCtrlAmount->GetValue().Trim().empty()) - return; - int64 nTmp; - if (ParseMoney(m_textCtrlAmount->GetValue(), nTmp)) - m_textCtrlAmount->SetValue(FormatMoney(nTmp)); -} - -void CSendDialog::OnButtonAddressBook(wxCommandEvent& event) -{ - // Open address book - CAddressBookDialog dialog(this, m_textCtrlAddress->GetValue(), CAddressBookDialog::SENDING, true); - if (dialog.ShowModal()) - m_textCtrlAddress->SetValue(dialog.GetSelectedAddress()); -} - -void CSendDialog::OnButtonPaste(wxCommandEvent& event) -{ - // Copy clipboard to address box - if (wxTheClipboard->Open()) - { - if (wxTheClipboard->IsSupported(wxDF_TEXT)) - { - wxTextDataObject data; - wxTheClipboard->GetData(data); - m_textCtrlAddress->SetValue(data.GetText()); - } - wxTheClipboard->Close(); - } -} - -void CSendDialog::OnButtonSend(wxCommandEvent& event) -{ - static CCriticalSection cs_sendlock; - TRY_CRITICAL_BLOCK(cs_sendlock) - { - CWalletTx wtx; - string strAddress = (string)m_textCtrlAddress->GetValue(); - - // Parse amount - int64 nValue = 0; - if (!ParseMoney(m_textCtrlAmount->GetValue(), nValue) || nValue <= 0) - { - wxMessageBox(_("Error in amount "), _("Send Coins")); - return; - } - if (nValue > pwalletMain->GetBalance()) - { - wxMessageBox(_("Amount exceeds your balance "), _("Send Coins")); - return; - } - if (nValue + nTransactionFee > pwalletMain->GetBalance()) - { - wxMessageBox(string(_("Total exceeds your balance when the ")) + FormatMoney(nTransactionFee) + _(" transaction fee is included "), _("Send Coins")); - return; - } - - // Parse bitcoin address - uint160 hash160; - bool fBitcoinAddress = AddressToHash160(strAddress, hash160); - - if (fBitcoinAddress) - { - CRITICAL_BLOCK(cs_main) - { - // Send to bitcoin address - CScript scriptPubKey; - scriptPubKey << OP_DUP << OP_HASH160 << hash160 << OP_EQUALVERIFY << OP_CHECKSIG; - - string strError = pwalletMain->SendMoney(scriptPubKey, nValue, wtx, true); - if (strError == "") - wxMessageBox(_("Payment sent "), _("Sending...")); - else if (strError == "ABORTED") - return; // leave send dialog open - else - { - wxMessageBox(strError + " ", _("Sending...")); - EndModal(false); - return; - } - } - } - else - { - // Parse IP address - CAddress addr(strAddress); - if (!addr.IsValid()) - { - wxMessageBox(_("Invalid address "), _("Send Coins")); - return; - } - - // Message - wtx.mapValue["to"] = strAddress; - - // Send to IP address - CSendingDialog* pdialog = new CSendingDialog(this, addr, nValue, wtx); - if (!pdialog->ShowModal()) - return; - } - - CRITICAL_BLOCK(pwalletMain->cs_mapAddressBook) - if (!pwalletMain->mapAddressBook.count(strAddress)) - pwalletMain->SetAddressBookName(strAddress, ""); - - EndModal(true); - } -} - -void CSendDialog::OnButtonCancel(wxCommandEvent& event) -{ - // Cancel - EndModal(false); -} - - - - - - -////////////////////////////////////////////////////////////////////////////// -// -// CSendingDialog -// - -CSendingDialog::CSendingDialog(wxWindow* parent, const CAddress& addrIn, int64 nPriceIn, const CWalletTx& wtxIn) : CSendingDialogBase(NULL) // we have to give null so parent can't destroy us -{ - addr = addrIn; - nPrice = nPriceIn; - wtx = wtxIn; - start = wxDateTime::UNow(); - memset(pszStatus, 0, sizeof(pszStatus)); - fCanCancel = true; - fAbort = false; - fSuccess = false; - fUIDone = false; - fWorkDone = false; -#ifndef __WXMSW__ - SetSize(1.2 * GetSize().GetWidth(), 1.08 * GetSize().GetHeight()); -#else - SetSize(nScaleX * GetSize().GetWidth(), nScaleY * GetSize().GetHeight()); -#endif - - SetTitle(strprintf(_("Sending %s to %s"), FormatMoney(nPrice).c_str(), wtx.mapValue["to"].c_str())); - m_textCtrlStatus->SetValue(""); - - CreateThread(SendingDialogStartTransfer, this); -} - -CSendingDialog::~CSendingDialog() -{ - printf("~CSendingDialog()\n"); -} - -void CSendingDialog::Close() -{ - // Last one out turn out the lights. - // fWorkDone signals that work side is done and UI thread should call destroy. - // fUIDone signals that UI window has closed and work thread should call destroy. - // This allows the window to disappear and end modality when cancelled - // without making the user wait for ConnectNode to return. The dialog object - // hangs around in the background until the work thread exits. - if (IsModal()) - EndModal(fSuccess); - else - Show(false); - if (fWorkDone) - Destroy(); - else - fUIDone = true; -} - -void CSendingDialog::OnClose(wxCloseEvent& event) -{ - if (!event.CanVeto() || fWorkDone || fAbort || !fCanCancel) - { - Close(); - } - else - { - event.Veto(); - wxCommandEvent cmdevent; - OnButtonCancel(cmdevent); - } -} - -void CSendingDialog::OnButtonOK(wxCommandEvent& event) -{ - if (fWorkDone) - Close(); -} - -void CSendingDialog::OnButtonCancel(wxCommandEvent& event) -{ - if (fCanCancel) - fAbort = true; -} - -void CSendingDialog::OnPaint(wxPaintEvent& event) -{ - event.Skip(); - if (strlen(pszStatus) > 130) - m_textCtrlStatus->SetValue(string("\n") + pszStatus); - else - m_textCtrlStatus->SetValue(string("\n\n") + pszStatus); - m_staticTextSending->SetFocus(); - if (!fCanCancel) - m_buttonCancel->Enable(false); - if (fWorkDone) - { - m_buttonOK->Enable(true); - m_buttonOK->SetFocus(); - m_buttonCancel->Enable(false); - } - if (fAbort && fCanCancel && IsShown()) - { - strcpy(pszStatus, _("CANCELLED")); - m_buttonOK->Enable(true); - m_buttonOK->SetFocus(); - m_buttonCancel->Enable(false); - m_buttonCancel->SetLabel(_("Cancelled")); - Close(); - wxMessageBox(_("Transfer cancelled "), _("Sending..."), wxOK, this); - } -} - - -// -// Everything from here on is not in the UI thread and must only communicate -// with the rest of the dialog through variables and calling repaint. -// - -void CSendingDialog::Repaint() -{ - Refresh(); - wxPaintEvent event; - GetEventHandler()->AddPendingEvent(event); -} - -bool CSendingDialog::Status() -{ - if (fUIDone) - { - Destroy(); - return false; - } - if (fAbort && fCanCancel) - { - memset(pszStatus, 0, 10); - strcpy(pszStatus, _("CANCELLED")); - Repaint(); - fWorkDone = true; - return false; - } - return true; -} - -bool CSendingDialog::Status(const string& str) -{ - if (!Status()) - return false; - - // This can be read by the UI thread at any time, - // so copy in a way that can be read cleanly at all times. - memset(pszStatus, 0, min(str.size()+1, sizeof(pszStatus))); - strlcpy(pszStatus, str.c_str(), sizeof(pszStatus)); - - Repaint(); - return true; -} - -bool CSendingDialog::Error(const string& str) -{ - fCanCancel = false; - fWorkDone = true; - Status(string(_("Error: ")) + str); - return false; -} - -void SendingDialogStartTransfer(void* parg) -{ - ((CSendingDialog*)parg)->StartTransfer(); -} - -void CSendingDialog::StartTransfer() -{ - // Make sure we have enough money - if (nPrice + nTransactionFee > pwalletMain->GetBalance()) - { - Error(_("Insufficient funds")); - return; - } - - // We may have connected already for product details - if (!Status(_("Connecting..."))) - return; - CNode* pnode = ConnectNode(addr, 15 * 60); - if (!pnode) - { - Error(_("Unable to connect")); - return; - } - - // Send order to seller, with response going to OnReply2 via event handler - if (!Status(_("Requesting public key..."))) - return; - pnode->PushRequest("checkorder", wtx, SendingDialogOnReply2, this); -} - -void SendingDialogOnReply2(void* parg, CDataStream& vRecv) -{ - ((CSendingDialog*)parg)->OnReply2(vRecv); -} - -void CSendingDialog::OnReply2(CDataStream& vRecv) -{ - if (!Status(_("Received public key..."))) - return; - - CScript scriptPubKey; - int nRet; - try - { - vRecv >> nRet; - if (nRet > 0) - { - string strMessage; - if (!vRecv.empty()) - vRecv >> strMessage; - if (nRet == 2) - Error(_("Recipient is not accepting transactions sent by IP address")); - else - Error(_("Transfer was not accepted")); - //// todo: enlarge the window and enable a hidden white box to put seller's message - return; - } - vRecv >> scriptPubKey; - } - catch (...) - { - //// what do we want to do about this? - Error(_("Invalid response received")); - return; - } - - // Pause to give the user a chance to cancel - while (wxDateTime::UNow() < start + wxTimeSpan(0, 0, 0, 2 * 1000)) - { - Sleep(200); - if (!Status()) - return; - } - - CRITICAL_BLOCK(cs_main) - { - // Pay - if (!Status(_("Creating transaction..."))) - return; - if (nPrice + nTransactionFee > pwalletMain->GetBalance()) - { - Error(_("Insufficient funds")); - return; - } - CReserveKey reservekey(pwalletMain); - int64 nFeeRequired; - if (!pwalletMain->CreateTransaction(scriptPubKey, nPrice, wtx, reservekey, nFeeRequired)) - { - if (nPrice + nFeeRequired > pwalletMain->GetBalance()) - Error(strprintf(_("This transaction requires a transaction fee of at least %s because of its amount, complexity, or use of recently received funds"), FormatMoney(nFeeRequired).c_str())); - else - Error(_("Transaction creation failed")); - return; - } - - // Transaction fee - if (!ThreadSafeAskFee(nFeeRequired, _("Sending..."), this)) - { - Error(_("Transaction aborted")); - return; - } - - // Make sure we're still connected - CNode* pnode = ConnectNode(addr, 2 * 60 * 60); - if (!pnode) - { - Error(_("Lost connection, transaction cancelled")); - return; - } - - // Last chance to cancel - Sleep(50); - if (!Status()) - return; - fCanCancel = false; - if (fAbort) - { - fCanCancel = true; - if (!Status()) - return; - fCanCancel = false; - } - if (!Status(_("Sending payment..."))) - return; - - // Commit - if (!pwalletMain->CommitTransaction(wtx, reservekey)) - { - 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.")); - return; - } - - // Send payment tx to seller, with response going to OnReply3 via event handler - CWalletTx wtxSend = wtx; - wtxSend.fFromMe = false; - pnode->PushRequest("submitorder", wtxSend, SendingDialogOnReply3, this); - - Status(_("Waiting for confirmation...")); - MainFrameRepaint(); - } -} - -void SendingDialogOnReply3(void* parg, CDataStream& vRecv) -{ - ((CSendingDialog*)parg)->OnReply3(vRecv); -} - -void CSendingDialog::OnReply3(CDataStream& vRecv) -{ - int nRet; - try - { - vRecv >> nRet; - if (nRet > 0) - { - Error(_("The payment was sent, but the recipient was unable to verify it.\n" - "The transaction is recorded and will credit to the recipient,\n" - "but the comment information will be blank.")); - return; - } - } - catch (...) - { - //// what do we want to do about this? - Error(_("Payment was sent, but an invalid response was received")); - return; - } - - fSuccess = true; - fWorkDone = true; - Status(_("Payment completed")); -} - - - - - - -////////////////////////////////////////////////////////////////////////////// -// -// CAddressBookDialog -// - -CAddressBookDialog::CAddressBookDialog(wxWindow* parent, const wxString& strInitSelected, int nPageIn, bool fDuringSendIn) : CAddressBookDialogBase(parent) -{ -#ifdef __WXMSW__ - SetSize(nScaleX * GetSize().GetWidth(), nScaleY * GetSize().GetHeight()); -#endif - - // Set initially selected page - wxNotebookEvent event; - event.SetSelection(nPageIn); - OnNotebookPageChanged(event); - m_notebook->ChangeSelection(nPageIn); - - fDuringSend = fDuringSendIn; - if (!fDuringSend) - m_buttonCancel->Show(false); - - // Set Icon - if (nScaleX == 1.0 && nScaleY == 1.0) // We don't have icons of the proper size otherwise - { - wxIcon iconAddressBook; - iconAddressBook.CopyFromBitmap(wxBitmap(addressbook16_xpm)); - SetIcon(iconAddressBook); - } -#ifdef __WXMSW__ - else - SetIcon(wxICON(bitcoin)); -#endif - - // Init column headers - m_listCtrlSending->InsertColumn(0, _("Name"), wxLIST_FORMAT_LEFT, 200); - m_listCtrlSending->InsertColumn(1, _("Address"), wxLIST_FORMAT_LEFT, 350); - m_listCtrlSending->SetFocus(); - m_listCtrlReceiving->InsertColumn(0, _("Label"), wxLIST_FORMAT_LEFT, 200); - m_listCtrlReceiving->InsertColumn(1, _("Bitcoin Address"), wxLIST_FORMAT_LEFT, 350); - m_listCtrlReceiving->SetFocus(); - - // Fill listctrl with address book data - CRITICAL_BLOCK(pwalletMain->cs_mapKeys) - CRITICAL_BLOCK(pwalletMain->cs_mapAddressBook) - { - string strDefaultReceiving = (string)pframeMain->m_textCtrlAddress->GetValue(); - BOOST_FOREACH(const PAIRTYPE(string, string)& item, pwalletMain->mapAddressBook) - { - string strAddress = item.first; - string strName = item.second; - uint160 hash160; - bool fMine = (AddressToHash160(strAddress, hash160) && mapPubKeys.count(hash160)); - wxListCtrl* plistCtrl = fMine ? m_listCtrlReceiving : m_listCtrlSending; - int nIndex = InsertLine(plistCtrl, strName, strAddress); - if (strAddress == (fMine ? strDefaultReceiving : string(strInitSelected))) - plistCtrl->SetItemState(nIndex, wxLIST_STATE_SELECTED|wxLIST_STATE_FOCUSED, wxLIST_STATE_SELECTED|wxLIST_STATE_FOCUSED); - } - } -} - -wxString CAddressBookDialog::GetSelectedAddress() -{ - int nIndex = GetSelection(m_listCtrl); - if (nIndex == -1) - return ""; - return GetItemText(m_listCtrl, nIndex, 1); -} - -wxString CAddressBookDialog::GetSelectedSendingAddress() -{ - int nIndex = GetSelection(m_listCtrlSending); - if (nIndex == -1) - return ""; - return GetItemText(m_listCtrlSending, nIndex, 1); -} - -wxString CAddressBookDialog::GetSelectedReceivingAddress() -{ - int nIndex = GetSelection(m_listCtrlReceiving); - if (nIndex == -1) - return ""; - return GetItemText(m_listCtrlReceiving, nIndex, 1); -} - -void CAddressBookDialog::OnNotebookPageChanged(wxNotebookEvent& event) -{ - event.Skip(); - nPage = event.GetSelection(); - if (nPage == SENDING) - m_listCtrl = m_listCtrlSending; - else if (nPage == RECEIVING) - m_listCtrl = m_listCtrlReceiving; - m_buttonDelete->Show(nPage == SENDING); - m_buttonCopy->Show(nPage == RECEIVING); - this->Layout(); - m_listCtrl->SetFocus(); -} - -void CAddressBookDialog::OnListEndLabelEdit(wxListEvent& event) -{ - // Update address book with edited name - event.Skip(); - if (event.IsEditCancelled()) - return; - string strAddress = (string)GetItemText(m_listCtrl, event.GetIndex(), 1); - CRITICAL_BLOCK(pwalletMain->cs_mapAddressBook) - pwalletMain->SetAddressBookName(strAddress, string(event.GetText())); - pframeMain->RefreshListCtrl(); -} - -void CAddressBookDialog::OnListItemSelected(wxListEvent& event) -{ - event.Skip(); - if (nPage == RECEIVING) - SetDefaultReceivingAddress((string)GetSelectedReceivingAddress()); -} - -void CAddressBookDialog::OnListItemActivated(wxListEvent& event) -{ - event.Skip(); - if (fDuringSend) - { - // Doubleclick returns selection - EndModal(GetSelectedAddress() != "" ? 2 : 0); - return; - } - - // Doubleclick edits item - wxCommandEvent event2; - OnButtonEdit(event2); -} - -void CAddressBookDialog::OnButtonDelete(wxCommandEvent& event) -{ - if (nPage != SENDING) - return; - for (int nIndex = m_listCtrl->GetItemCount()-1; nIndex >= 0; nIndex--) - { - if (m_listCtrl->GetItemState(nIndex, wxLIST_STATE_SELECTED)) - { - string strAddress = (string)GetItemText(m_listCtrl, nIndex, 1); - CRITICAL_BLOCK(pwalletMain->cs_mapAddressBook) - pwalletMain->DelAddressBookName(strAddress); - m_listCtrl->DeleteItem(nIndex); - } - } - pframeMain->RefreshListCtrl(); -} - -void CAddressBookDialog::OnButtonCopy(wxCommandEvent& event) -{ - // Copy address box to clipboard - if (wxTheClipboard->Open()) - { - wxTheClipboard->SetData(new wxTextDataObject(GetSelectedAddress())); - wxTheClipboard->Close(); - } -} - -bool CAddressBookDialog::CheckIfMine(const string& strAddress, const string& strTitle) -{ - uint160 hash160; - bool fMine = (AddressToHash160(strAddress, hash160) && mapPubKeys.count(hash160)); - if (fMine) - wxMessageBox(_("This is one of your own addresses for receiving payments and cannot be entered in the address book. "), strTitle); - return fMine; -} - -void CAddressBookDialog::OnButtonEdit(wxCommandEvent& event) -{ - int nIndex = GetSelection(m_listCtrl); - if (nIndex == -1) - return; - string strName = (string)m_listCtrl->GetItemText(nIndex); - string strAddress = (string)GetItemText(m_listCtrl, nIndex, 1); - string strAddressOrg = strAddress; - - if (nPage == SENDING) - { - // Ask name and address - do - { - CGetTextFromUserDialog dialog(this, _("Edit Address"), _("Name"), strName, _("Address"), strAddress); - if (!dialog.ShowModal()) - return; - strName = dialog.GetValue1(); - strAddress = dialog.GetValue2(); - } - while (CheckIfMine(strAddress, _("Edit Address"))); - - } - else if (nPage == RECEIVING) - { - // Ask name - CGetTextFromUserDialog dialog(this, _("Edit Address Label"), _("Label"), strName); - if (!dialog.ShowModal()) - return; - strName = dialog.GetValue(); - } - - // Write back - CRITICAL_BLOCK(pwalletMain->cs_mapAddressBook) - { - if (strAddress != strAddressOrg) - pwalletMain->DelAddressBookName(strAddressOrg); - pwalletMain->SetAddressBookName(strAddress, strName); - } - m_listCtrl->SetItem(nIndex, 1, strAddress); - m_listCtrl->SetItemText(nIndex, strName); - pframeMain->RefreshListCtrl(); -} - -void CAddressBookDialog::OnButtonNew(wxCommandEvent& event) -{ - string strName; - string strAddress; - - if (nPage == SENDING) - { - // Ask name and address - do - { - CGetTextFromUserDialog dialog(this, _("Add Address"), _("Name"), strName, _("Address"), strAddress); - if (!dialog.ShowModal()) - return; - strName = dialog.GetValue1(); - strAddress = dialog.GetValue2(); - } - while (CheckIfMine(strAddress, _("Add Address"))); - } - else if (nPage == RECEIVING) - { - // Ask name - CGetTextFromUserDialog dialog(this, - _("New Receiving Address"), - _("You should use a new address for each payment you receive.\n\nLabel"), - ""); - if (!dialog.ShowModal()) - return; - strName = dialog.GetValue(); - - // Generate new key - strAddress = PubKeyToAddress(pwalletMain->GetKeyFromKeyPool()); - } - - // Add to list and select it - CRITICAL_BLOCK(pwalletMain->cs_mapAddressBook) - pwalletMain->SetAddressBookName(strAddress, strName); - int nIndex = InsertLine(m_listCtrl, strName, strAddress); - SetSelection(m_listCtrl, nIndex); - m_listCtrl->SetFocus(); - if (nPage == SENDING) - pframeMain->RefreshListCtrl(); -} - -void CAddressBookDialog::OnButtonOK(wxCommandEvent& event) -{ - // OK - EndModal(GetSelectedAddress() != "" ? 1 : 0); -} - -void CAddressBookDialog::OnButtonCancel(wxCommandEvent& event) -{ - // Cancel - EndModal(0); -} - -void CAddressBookDialog::OnClose(wxCloseEvent& event) -{ - // Close - EndModal(0); -} - - - - - - -////////////////////////////////////////////////////////////////////////////// -// -// CMyTaskBarIcon -// - -enum -{ - ID_TASKBAR_RESTORE = 10001, - ID_TASKBAR_SEND, - ID_TASKBAR_OPTIONS, - ID_TASKBAR_GENERATE, - ID_TASKBAR_EXIT, -}; - -BEGIN_EVENT_TABLE(CMyTaskBarIcon, wxTaskBarIcon) - EVT_TASKBAR_LEFT_DCLICK(CMyTaskBarIcon::OnLeftButtonDClick) - EVT_MENU(ID_TASKBAR_RESTORE, CMyTaskBarIcon::OnMenuRestore) - EVT_MENU(ID_TASKBAR_SEND, CMyTaskBarIcon::OnMenuSend) - EVT_MENU(ID_TASKBAR_OPTIONS, CMyTaskBarIcon::OnMenuOptions) - EVT_UPDATE_UI(ID_TASKBAR_GENERATE, CMyTaskBarIcon::OnUpdateUIGenerate) - EVT_MENU(ID_TASKBAR_EXIT, CMyTaskBarIcon::OnMenuExit) -END_EVENT_TABLE() - -void CMyTaskBarIcon::Show(bool fShow) -{ - static char pszPrevTip[200]; - if (fShow) - { - string strTooltip = _("Bitcoin"); - if (fGenerateBitcoins) - strTooltip = _("Bitcoin - Generating"); - if (fGenerateBitcoins && vNodes.empty()) - strTooltip = _("Bitcoin - (not connected)"); - - // Optimization, only update when changed, using char array to be reentrant - if (strncmp(pszPrevTip, strTooltip.c_str(), sizeof(pszPrevTip)-1) != 0) - { - strlcpy(pszPrevTip, strTooltip.c_str(), sizeof(pszPrevTip)); -#ifdef __WXMSW__ - // somehow it'll choose the wrong size and scale it down if - // we use the main icon, so we hand it one with only 16x16 - SetIcon(wxICON(favicon), strTooltip); -#else - SetIcon(bitcoin80_xpm, strTooltip); -#endif - } - } - else - { - strlcpy(pszPrevTip, "", sizeof(pszPrevTip)); - RemoveIcon(); - } -} - -void CMyTaskBarIcon::Hide() -{ - Show(false); -} - -void CMyTaskBarIcon::OnLeftButtonDClick(wxTaskBarIconEvent& event) -{ - Restore(); -} - -void CMyTaskBarIcon::OnMenuRestore(wxCommandEvent& event) -{ - Restore(); -} - -void CMyTaskBarIcon::OnMenuSend(wxCommandEvent& event) -{ - // Taskbar: Send - CSendDialog dialog(pframeMain); - dialog.ShowModal(); -} - -void CMyTaskBarIcon::OnMenuOptions(wxCommandEvent& event) -{ - // Since it's modal, get the main window to do it - wxCommandEvent event2(wxEVT_COMMAND_MENU_SELECTED, wxID_PREFERENCES); - pframeMain->GetEventHandler()->AddPendingEvent(event2); -} - -void CMyTaskBarIcon::Restore() -{ - pframeMain->Show(); - wxIconizeEvent event(0, false); - pframeMain->GetEventHandler()->AddPendingEvent(event); - pframeMain->Iconize(false); - pframeMain->Raise(); -} - -void CMyTaskBarIcon::OnUpdateUIGenerate(wxUpdateUIEvent& event) -{ - event.Check(fGenerateBitcoins); -} - -void CMyTaskBarIcon::OnMenuExit(wxCommandEvent& event) -{ - pframeMain->Close(true); -} - -void CMyTaskBarIcon::UpdateTooltip() -{ - if (IsIconInstalled()) - Show(true); -} - -wxMenu* CMyTaskBarIcon::CreatePopupMenu() -{ - wxMenu* pmenu = new wxMenu; - pmenu->Append(ID_TASKBAR_RESTORE, _("&Open Bitcoin")); - pmenu->Append(ID_TASKBAR_SEND, _("&Send Bitcoins")); - pmenu->Append(ID_TASKBAR_OPTIONS, _("O&ptions...")); -#ifndef __WXMAC_OSX__ // Mac has built-in quit menu - pmenu->AppendSeparator(); - pmenu->Append(ID_TASKBAR_EXIT, _("E&xit")); -#endif - return pmenu; -} - - - - - - -////////////////////////////////////////////////////////////////////////////// -// -// CMyApp -// - -void CreateMainWindow() -{ - pframeMain = new CMainFrame(NULL); - if (GetBoolArg("-min")) - pframeMain->Iconize(true); -#if defined(__WXGTK__) || defined(__WXMAC_OSX__) - if (!GetBoolArg("-minimizetotray")) - fMinimizeToTray = false; -#endif - pframeMain->Show(true); // have to show first to get taskbar button to hide - if (fMinimizeToTray && pframeMain->IsIconized()) - fClosedToTray = true; - pframeMain->Show(!fClosedToTray); - ptaskbaricon->Show(fMinimizeToTray || fClosedToTray); - CreateThread(ThreadDelayedRepaint, NULL); -} - - -// Define a new application -class CMyApp : public wxApp -{ -public: - CMyApp(){}; - ~CMyApp(){}; - bool OnInit(); - bool OnInit2(); - int OnExit(); - - // Hook Initialize so we can start without GUI - virtual bool Initialize(int& argc, wxChar** argv); - - // 2nd-level exception handling: we get all the exceptions occurring in any - // event handler here - virtual bool OnExceptionInMainLoop(); - - // 3rd, and final, level exception handling: whenever an unhandled - // exception is caught, this function is called - virtual void OnUnhandledException(); - - // and now for something different: this function is called in case of a - // crash (e.g. dereferencing null pointer, division by 0, ...) - virtual void OnFatalException(); -}; - -IMPLEMENT_APP(CMyApp) - -bool CMyApp::Initialize(int& argc, wxChar** argv) -{ - for (int i = 1; i < argc; i++) - if (!IsSwitchChar(argv[i][0])) - fCommandLine = true; - - if (!fCommandLine) - { - // wxApp::Initialize will remove environment-specific parameters, - // so it's too early to call ParseParameters yet - for (int i = 1; i < argc; i++) - { - wxString str = argv[i]; - #ifdef __WXMSW__ - if (str.size() >= 1 && str[0] == '/') - str[0] = '-'; - char pszLower[MAX_PATH]; - strlcpy(pszLower, str.c_str(), sizeof(pszLower)); - strlwr(pszLower); - str = pszLower; - #endif - if (str == "-daemon") - fDaemon = true; - } - } - -#ifdef __WXGTK__ - if (fDaemon || fCommandLine) - { - // Call the original Initialize while suppressing error messages - // and ignoring failure. If unable to initialize GTK, it fails - // near the end so hopefully the last few things don't matter. - { - wxLogNull logNo; - wxApp::Initialize(argc, argv); - } - - if (fDaemon) - { - // Daemonize - pid_t pid = fork(); - if (pid < 0) - { - fprintf(stderr, "Error: fork() returned %d errno %d\n", pid, errno); - return false; - } - if (pid > 0) - pthread_exit((void*)0); - - pid_t sid = setsid(); - if (sid < 0) - fprintf(stderr, "Error: setsid() returned %d errno %d\n", sid, errno); - } - - return true; - } -#endif - - return wxApp::Initialize(argc, argv); -} - -bool CMyApp::OnInit() -{ -#if defined(__WXMSW__) && defined(__WXDEBUG__) && defined(GUI) - // Disable malfunctioning wxWidgets debug assertion - extern int g_isPainting; - g_isPainting = 10000; -#endif -#if defined(__WXMSW__ ) || defined(__WXMAC_OSX__) - SetAppName("Bitcoin"); -#else - SetAppName("bitcoin"); -#endif -#ifdef __WXMSW__ -#if wxUSE_UNICODE - // Hack to set wxConvLibc codepage to UTF-8 on Windows, - // may break if wxMBConv_win32 implementation in strconv.cpp changes. - class wxMBConv_win32 : public wxMBConv - { - public: - long m_CodePage; - size_t m_minMBCharWidth; - }; - if (((wxMBConv_win32*)&wxConvLibc)->m_CodePage == CP_ACP) - ((wxMBConv_win32*)&wxConvLibc)->m_CodePage = CP_UTF8; -#endif -#endif - - // Load locale/<lang>/LC_MESSAGES/bitcoin.mo language file - g_locale.Init(wxLANGUAGE_DEFAULT, 0); - g_locale.AddCatalogLookupPathPrefix("locale"); -#ifndef __WXMSW__ - g_locale.AddCatalogLookupPathPrefix("/usr/share/locale"); - g_locale.AddCatalogLookupPathPrefix("/usr/local/share/locale"); -#endif - g_locale.AddCatalog("wxstd"); // wxWidgets standard translations, if any - g_locale.AddCatalog("bitcoin"); - -#ifdef __WXMSW__ - HDC hdc = GetDC(NULL); - if (hdc) - { - nScaleX = GetDeviceCaps(hdc, LOGPIXELSX) / 96.0; - nScaleY = GetDeviceCaps(hdc, LOGPIXELSY) / 96.0; - ReleaseDC(NULL, hdc); - } -#endif - - return AppInit(argc, argv); -} - -int CMyApp::OnExit() -{ - Shutdown(NULL); - return wxApp::OnExit(); -} - -bool CMyApp::OnExceptionInMainLoop() -{ - try - { - throw; - } - catch (std::exception& e) - { - PrintException(&e, "CMyApp::OnExceptionInMainLoop()"); - wxLogWarning("Exception %s %s", typeid(e).name(), e.what()); - Sleep(1000); - throw; - } - catch (...) - { - PrintException(NULL, "CMyApp::OnExceptionInMainLoop()"); - wxLogWarning("Unknown exception"); - Sleep(1000); - throw; - } - return true; -} - -void CMyApp::OnUnhandledException() -{ - // this shows how we may let some exception propagate uncaught - try - { - throw; - } - catch (std::exception& e) - { - PrintException(&e, "CMyApp::OnUnhandledException()"); - wxLogWarning("Exception %s %s", typeid(e).name(), e.what()); - Sleep(1000); - throw; - } - catch (...) - { - PrintException(NULL, "CMyApp::OnUnhandledException()"); - wxLogWarning("Unknown exception"); - Sleep(1000); - throw; - } -} - -void CMyApp::OnFatalException() -{ - wxMessageBox(_("Program has crashed and will terminate. "), "Bitcoin", wxOK | wxICON_ERROR); -} diff --git a/src/ui.h b/src/ui.h deleted file mode 100644 index 3f06ad90cb..0000000000 --- a/src/ui.h +++ /dev/null @@ -1,350 +0,0 @@ -// Copyright (c) 2009-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. -#ifndef BITCOIN_UI_H -#define BITCOIN_UI_H - -#include <boost/function.hpp> -#include "wallet.h" - -DECLARE_EVENT_TYPE(wxEVT_UITHREADCALL, -1) - - - -extern wxLocale g_locale; - - - -void HandleCtrlA(wxKeyEvent& event); -void UIThreadCall(boost::function0<void>); -int ThreadSafeMessageBox(const std::string& message, const std::string& caption="Message", int style=wxOK, wxWindow* parent=NULL, int x=-1, int y=-1); -bool ThreadSafeAskFee(int64 nFeeRequired, const std::string& strCaption, wxWindow* parent); -void CalledSetStatusBar(const std::string& strText, int nField); -void MainFrameRepaint(); -void CreateMainWindow(); -void SetStartOnSystemStartup(bool fAutoStart); - - - - -inline int MyMessageBox(const wxString& message, const wxString& caption="Message", int style=wxOK, wxWindow* parent=NULL, int x=-1, int y=-1) -{ -#ifdef GUI - if (!fDaemon) - return wxMessageBox(message, caption, style, parent, x, y); -#endif - printf("wxMessageBox %s: %s\n", std::string(caption).c_str(), std::string(message).c_str()); - fprintf(stderr, "%s: %s\n", std::string(caption).c_str(), std::string(message).c_str()); - return wxOK; -} -#define wxMessageBox MyMessageBox - - - - - - -class CMainFrame : public CMainFrameBase -{ -protected: - // Event handlers - void OnNotebookPageChanged(wxNotebookEvent& event); - void OnClose(wxCloseEvent& event); - void OnIconize(wxIconizeEvent& event); - void OnMouseEvents(wxMouseEvent& event); - void OnKeyDown(wxKeyEvent& event) { HandleCtrlA(event); } - void OnIdle(wxIdleEvent& event); - void OnPaint(wxPaintEvent& event); - void OnPaintListCtrl(wxPaintEvent& event); - void OnMenuFileExit(wxCommandEvent& event); - void OnUpdateUIOptionsGenerate(wxUpdateUIEvent& event); - void OnMenuOptionsChangeYourAddress(wxCommandEvent& event); - void OnMenuOptionsOptions(wxCommandEvent& event); - void OnMenuHelpAbout(wxCommandEvent& event); - void OnButtonSend(wxCommandEvent& event); - void OnButtonAddressBook(wxCommandEvent& event); - void OnSetFocusAddress(wxFocusEvent& event); - void OnMouseEventsAddress(wxMouseEvent& event); - void OnButtonNew(wxCommandEvent& event); - void OnButtonCopy(wxCommandEvent& event); - void OnListColBeginDrag(wxListEvent& event); - void OnListItemActivated(wxListEvent& event); - void OnListItemActivatedProductsSent(wxListEvent& event); - void OnListItemActivatedOrdersSent(wxListEvent& event); - void OnListItemActivatedOrdersReceived(wxListEvent& event); - -public: - /** Constructor */ - CMainFrame(wxWindow* parent); - ~CMainFrame(); - - // Custom - enum - { - ALL = 0, - SENTRECEIVED = 1, - SENT = 2, - RECEIVED = 3, - }; - int nPage; - wxListCtrl* m_listCtrl; - bool fShowGenerated; - bool fShowSent; - bool fShowReceived; - bool fRefreshListCtrl; - bool fRefreshListCtrlRunning; - bool fOnSetFocusAddress; - unsigned int nListViewUpdated; - bool fRefresh; - - void OnUIThreadCall(wxCommandEvent& event); - int GetSortIndex(const std::string& strSort); - void InsertLine(bool fNew, int nIndex, uint256 hashKey, std::string strSort, const wxColour& colour, const wxString& str1, const wxString& str2, const wxString& str3, const wxString& str4, const wxString& str5); - bool DeleteLine(uint256 hashKey); - bool InsertTransaction(const CWalletTx& wtx, bool fNew, int nIndex=-1); - void RefreshListCtrl(); - void RefreshStatusColumn(); -}; - - - - -class CTxDetailsDialog : public CTxDetailsDialogBase -{ -protected: - // Event handlers - void OnButtonOK(wxCommandEvent& event); - -public: - /** Constructor */ - CTxDetailsDialog(wxWindow* parent, CWalletTx wtx); - - // State - CWalletTx wtx; -}; - - - -class COptionsDialog : public COptionsDialogBase -{ -protected: - // Event handlers - void OnListBox(wxCommandEvent& event); - void OnKillFocusTransactionFee(wxFocusEvent& event); - void OnCheckBoxUseProxy(wxCommandEvent& event); - void OnKillFocusProxy(wxFocusEvent& event); - - void OnButtonOK(wxCommandEvent& event); - void OnButtonCancel(wxCommandEvent& event); - void OnButtonApply(wxCommandEvent& event); - -public: - /** Constructor */ - COptionsDialog(wxWindow* parent); - - // Custom - bool fTmpStartOnSystemStartup; - bool fTmpMinimizeOnClose; - void SelectPage(int nPage); - CAddress GetProxyAddr(); -}; - - - -class CAboutDialog : public CAboutDialogBase -{ -protected: - // Event handlers - void OnButtonOK(wxCommandEvent& event); - -public: - /** Constructor */ - CAboutDialog(wxWindow* parent); -}; - - - -class CSendDialog : public CSendDialogBase -{ -protected: - // Event handlers - void OnKeyDown(wxKeyEvent& event) { HandleCtrlA(event); } - void OnKillFocusAmount(wxFocusEvent& event); - void OnButtonAddressBook(wxCommandEvent& event); - void OnButtonPaste(wxCommandEvent& event); - void OnButtonSend(wxCommandEvent& event); - void OnButtonCancel(wxCommandEvent& event); - -public: - /** Constructor */ - CSendDialog(wxWindow* parent, const wxString& strAddress=""); - - // Custom - bool fEnabledPrev; - std::string strFromSave; - std::string strMessageSave; -}; - - - -class CSendingDialog : public CSendingDialogBase -{ -public: - // Event handlers - void OnClose(wxCloseEvent& event); - void OnButtonOK(wxCommandEvent& event); - void OnButtonCancel(wxCommandEvent& event); - void OnPaint(wxPaintEvent& event); - -public: - /** Constructor */ - CSendingDialog(wxWindow* parent, const CAddress& addrIn, int64 nPriceIn, const CWalletTx& wtxIn); - ~CSendingDialog(); - - // State - CAddress addr; - int64 nPrice; - CWalletTx wtx; - wxDateTime start; - char pszStatus[10000]; - bool fCanCancel; - bool fAbort; - bool fSuccess; - bool fUIDone; - bool fWorkDone; - - void Close(); - void Repaint(); - bool Status(); - bool Status(const std::string& str); - bool Error(const std::string& str); - void StartTransfer(); - void OnReply2(CDataStream& vRecv); - void OnReply3(CDataStream& vRecv); -}; - -void SendingDialogStartTransfer(void* parg); -void SendingDialogOnReply2(void* parg, CDataStream& vRecv); -void SendingDialogOnReply3(void* parg, CDataStream& vRecv); - - - -class CAddressBookDialog : public CAddressBookDialogBase -{ -protected: - // Event handlers - void OnNotebookPageChanged(wxNotebookEvent& event); - void OnListEndLabelEdit(wxListEvent& event); - void OnListItemSelected(wxListEvent& event); - void OnListItemActivated(wxListEvent& event); - void OnButtonDelete(wxCommandEvent& event); - void OnButtonCopy(wxCommandEvent& event); - void OnButtonEdit(wxCommandEvent& event); - void OnButtonNew(wxCommandEvent& event); - void OnButtonOK(wxCommandEvent& event); - void OnButtonCancel(wxCommandEvent& event); - void OnClose(wxCloseEvent& event); - -public: - /** Constructor */ - CAddressBookDialog(wxWindow* parent, const wxString& strInitSelected, int nPageIn, bool fDuringSendIn); - - // Custom - enum - { - SENDING = 0, - RECEIVING = 1, - }; - int nPage; - wxListCtrl* m_listCtrl; - bool fDuringSend; - wxString GetAddress(); - wxString GetSelectedAddress(); - wxString GetSelectedSendingAddress(); - wxString GetSelectedReceivingAddress(); - bool CheckIfMine(const std::string& strAddress, const std::string& strTitle); -}; - - - -class CGetTextFromUserDialog : public CGetTextFromUserDialogBase -{ -protected: - // Event handlers - void OnButtonOK(wxCommandEvent& event) { EndModal(true); } - void OnButtonCancel(wxCommandEvent& event) { EndModal(false); } - void OnClose(wxCloseEvent& event) { EndModal(false); } - - void OnKeyDown(wxKeyEvent& event) - { - if (event.GetKeyCode() == '\r' || event.GetKeyCode() == WXK_NUMPAD_ENTER) - EndModal(true); - else - HandleCtrlA(event); - } - -public: - /** Constructor */ - CGetTextFromUserDialog(wxWindow* parent, - const std::string& strCaption, - const std::string& strMessage1, - const std::string& strValue1="", - const std::string& strMessage2="", - const std::string& strValue2="") : CGetTextFromUserDialogBase(parent, wxID_ANY, strCaption) - { - int x = GetSize().GetWidth(); - int y = GetSize().GetHeight(); - m_staticTextMessage1->SetLabel(strMessage1); - m_textCtrl1->SetValue(strValue1); - y += wxString(strMessage1).Freq('\n') * 14; - if (!strMessage2.empty()) - { - m_staticTextMessage2->Show(true); - m_staticTextMessage2->SetLabel(strMessage2); - m_textCtrl2->Show(true); - m_textCtrl2->SetValue(strValue2); - y += 46 + wxString(strMessage2).Freq('\n') * 14; - } -#ifndef __WXMSW__ - x = x * 114 / 100; - y = y * 114 / 100; -#endif - SetSize(x, y); - } - - // Custom - std::string GetValue() { return (std::string)m_textCtrl1->GetValue(); } - std::string GetValue1() { return (std::string)m_textCtrl1->GetValue(); } - std::string GetValue2() { return (std::string)m_textCtrl2->GetValue(); } -}; - - - -class CMyTaskBarIcon : public wxTaskBarIcon -{ -protected: - // Event handlers - void OnLeftButtonDClick(wxTaskBarIconEvent& event); - void OnMenuRestore(wxCommandEvent& event); - void OnMenuSend(wxCommandEvent& event); - void OnMenuOptions(wxCommandEvent& event); - void OnUpdateUIGenerate(wxUpdateUIEvent& event); - void OnMenuGenerate(wxCommandEvent& event); - void OnMenuExit(wxCommandEvent& event); - -public: - CMyTaskBarIcon() : wxTaskBarIcon() - { - Show(true); - } - - void Show(bool fShow=true); - void Hide(); - void Restore(); - void UpdateTooltip(); - virtual wxMenu* CreatePopupMenu(); - -DECLARE_EVENT_TABLE() -}; - -#endif diff --git a/src/uibase.cpp b/src/uibase.cpp deleted file mode 100644 index 1b901a1edb..0000000000 --- a/src/uibase.cpp +++ /dev/null @@ -1,1008 +0,0 @@ -/////////////////////////////////////////////////////////////////////////// -// C++ code generated with wxFormBuilder (version Dec 21 2009) -// http://www.wxformbuilder.org/ -// -// PLEASE DO "NOT" EDIT THIS FILE! -/////////////////////////////////////////////////////////////////////////// - -#include "uibase.h" - -#include "xpm/about.xpm" -#include "xpm/addressbook20.xpm" -#include "xpm/check.xpm" -#include "xpm/send20.xpm" - -/////////////////////////////////////////////////////////////////////////// - -CMainFrameBase::CMainFrameBase( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : wxFrame( parent, id, title, pos, size, style ) -{ - this->SetSizeHints( wxDefaultSize, wxDefaultSize ); - this->SetBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_BTNFACE ) ); - - m_menubar = new wxMenuBar( 0 ); - m_menuFile = new wxMenu(); - wxMenuItem* m_menuFileExit; - m_menuFileExit = new wxMenuItem( m_menuFile, wxID_EXIT, wxString( _("E&xit") ) , wxEmptyString, wxITEM_NORMAL ); - m_menuFile->Append( m_menuFileExit ); - - m_menubar->Append( m_menuFile, _("&File") ); - - m_menuOptions = new wxMenu(); - wxMenuItem* m_menuOptionsChangeYourAddress; - m_menuOptionsChangeYourAddress = new wxMenuItem( m_menuOptions, wxID_ANY, wxString( _("&Your Receiving Addresses...") ) , wxEmptyString, wxITEM_NORMAL ); - m_menuOptions->Append( m_menuOptionsChangeYourAddress ); - - wxMenuItem* m_menuOptionsOptions; - m_menuOptionsOptions = new wxMenuItem( m_menuOptions, wxID_PREFERENCES, wxString( _("&Options...") ) , wxEmptyString, wxITEM_NORMAL ); - m_menuOptions->Append( m_menuOptionsOptions ); - - m_menubar->Append( m_menuOptions, _("&Settings") ); - - m_menuHelp = new wxMenu(); - wxMenuItem* m_menuHelpAbout; - m_menuHelpAbout = new wxMenuItem( m_menuHelp, wxID_ABOUT, wxString( _("&About...") ) , wxEmptyString, wxITEM_NORMAL ); - m_menuHelp->Append( m_menuHelpAbout ); - - m_menubar->Append( m_menuHelp, _("&Help") ); - - this->SetMenuBar( m_menubar ); - - m_toolBar = this->CreateToolBar( wxTB_FLAT|wxTB_HORZ_TEXT, wxID_ANY ); - m_toolBar->SetToolBitmapSize( wxSize( 20,20 ) ); - m_toolBar->SetToolSeparation( 1 ); - m_toolBar->SetFont( wxFont( wxNORMAL_FONT->GetPointSize(), 70, 90, 90, false, wxEmptyString ) ); - - m_toolBar->AddTool( wxID_BUTTONSEND, _("Send Coins"), wxBitmap( send20_xpm ), wxNullBitmap, wxITEM_NORMAL, wxEmptyString, wxEmptyString ); - m_toolBar->AddTool( wxID_BUTTONRECEIVE, _("Address Book"), wxBitmap( addressbook20_xpm ), wxNullBitmap, wxITEM_NORMAL, wxEmptyString, wxEmptyString ); - m_toolBar->Realize(); - - m_statusBar = this->CreateStatusBar( 1, wxST_SIZEGRIP, wxID_ANY ); - wxBoxSizer* bSizer2; - bSizer2 = new wxBoxSizer( wxVERTICAL ); - - - bSizer2->Add( 0, 2, 0, wxEXPAND, 5 ); - - wxBoxSizer* bSizer85; - bSizer85 = new wxBoxSizer( wxHORIZONTAL ); - - m_staticText32 = new wxStaticText( this, wxID_ANY, _("Your Bitcoin Address:"), wxDefaultPosition, wxDefaultSize, 0 ); - m_staticText32->Wrap( -1 ); - bSizer85->Add( m_staticText32, 0, wxALIGN_CENTER_VERTICAL|wxLEFT, 5 ); - - m_textCtrlAddress = new wxTextCtrl( this, wxID_TEXTCTRLADDRESS, wxEmptyString, wxDefaultPosition, wxSize( 340,-1 ), wxTE_READONLY ); - bSizer85->Add( m_textCtrlAddress, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 ); - - m_buttonNew = new wxButton( this, wxID_BUTTONNEW, _(" &New... "), wxDefaultPosition, wxSize( -1,-1 ), wxBU_EXACTFIT ); - bSizer85->Add( m_buttonNew, 0, wxRIGHT|wxALIGN_CENTER_VERTICAL, 5 ); - - m_buttonCopy = new wxButton( this, wxID_BUTTONCOPY, _(" &Copy to Clipboard "), wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT ); - bSizer85->Add( m_buttonCopy, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 5 ); - - - bSizer85->Add( 0, 0, 0, wxEXPAND, 5 ); - - bSizer2->Add( bSizer85, 0, wxEXPAND|wxRIGHT|wxLEFT, 5 ); - - wxBoxSizer* bSizer3; - bSizer3 = new wxBoxSizer( wxHORIZONTAL ); - - wxBoxSizer* bSizer66; - bSizer66 = new wxBoxSizer( wxHORIZONTAL ); - - m_staticText41 = new wxStaticText( this, wxID_ANY, _("Balance:"), wxDefaultPosition, wxSize( -1,15 ), 0 ); - m_staticText41->Wrap( -1 ); - bSizer66->Add( m_staticText41, 0, wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxLEFT, 5 ); - - m_staticTextBalance = new wxStaticText( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize( 120,15 ), wxALIGN_RIGHT|wxST_NO_AUTORESIZE ); - m_staticTextBalance->Wrap( -1 ); - m_staticTextBalance->SetFont( wxFont( 8, 70, 90, 90, false, wxEmptyString ) ); - m_staticTextBalance->SetBackgroundColour( wxColour( 255, 255, 255 ) ); - - bSizer66->Add( m_staticTextBalance, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 ); - - bSizer3->Add( bSizer66, 1, wxEXPAND|wxALL, 5 ); - - - bSizer3->Add( 0, 0, 0, wxEXPAND, 5 ); - - wxString m_choiceFilterChoices[] = { _(" All"), _(" Sent"), _(" Received"), _(" In Progress") }; - int m_choiceFilterNChoices = sizeof( m_choiceFilterChoices ) / sizeof( wxString ); - m_choiceFilter = new wxChoice( this, wxID_ANY, wxDefaultPosition, wxSize( 110,-1 ), m_choiceFilterNChoices, m_choiceFilterChoices, 0 ); - m_choiceFilter->SetSelection( 0 ); - m_choiceFilter->Hide(); - - bSizer3->Add( m_choiceFilter, 0, wxALIGN_BOTTOM|wxTOP|wxRIGHT|wxLEFT, 5 ); - - bSizer2->Add( bSizer3, 0, wxEXPAND, 5 ); - - m_notebook = new wxNotebook( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 ); - m_panel9 = new wxPanel( m_notebook, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL ); - wxBoxSizer* bSizer11; - bSizer11 = new wxBoxSizer( wxVERTICAL ); - - m_listCtrlAll = new wxListCtrl( m_panel9, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_NO_SORT_HEADER|wxLC_REPORT|wxLC_SORT_DESCENDING ); - bSizer11->Add( m_listCtrlAll, 1, wxEXPAND, 5 ); - - m_panel9->SetSizer( bSizer11 ); - m_panel9->Layout(); - bSizer11->Fit( m_panel9 ); - m_notebook->AddPage( m_panel9, _("All Transactions"), true ); - m_panel91 = new wxPanel( m_notebook, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL ); - wxBoxSizer* bSizer111; - bSizer111 = new wxBoxSizer( wxVERTICAL ); - - m_listCtrlSentReceived = new wxListCtrl( m_panel91, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_NO_SORT_HEADER|wxLC_REPORT|wxLC_SORT_DESCENDING ); - bSizer111->Add( m_listCtrlSentReceived, 1, wxEXPAND, 5 ); - - m_panel91->SetSizer( bSizer111 ); - m_panel91->Layout(); - bSizer111->Fit( m_panel91 ); - m_notebook->AddPage( m_panel91, _("Sent/Received"), false ); - m_panel92 = new wxPanel( m_notebook, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL ); - wxBoxSizer* bSizer112; - bSizer112 = new wxBoxSizer( wxVERTICAL ); - - m_listCtrlSent = new wxListCtrl( m_panel92, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_NO_SORT_HEADER|wxLC_REPORT|wxLC_SORT_DESCENDING ); - bSizer112->Add( m_listCtrlSent, 1, wxEXPAND, 5 ); - - m_panel92->SetSizer( bSizer112 ); - m_panel92->Layout(); - bSizer112->Fit( m_panel92 ); - m_notebook->AddPage( m_panel92, _("Sent"), false ); - m_panel93 = new wxPanel( m_notebook, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL ); - wxBoxSizer* bSizer113; - bSizer113 = new wxBoxSizer( wxVERTICAL ); - - m_listCtrlReceived = new wxListCtrl( m_panel93, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_NO_SORT_HEADER|wxLC_REPORT|wxLC_SORT_DESCENDING ); - bSizer113->Add( m_listCtrlReceived, 1, wxEXPAND, 5 ); - - m_panel93->SetSizer( bSizer113 ); - m_panel93->Layout(); - bSizer113->Fit( m_panel93 ); - m_notebook->AddPage( m_panel93, _("Received"), false ); - - bSizer2->Add( m_notebook, 1, wxEXPAND, 5 ); - - this->SetSizer( bSizer2 ); - this->Layout(); - - // Connect Events - this->Connect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( CMainFrameBase::OnClose ) ); - this->Connect( wxEVT_ICONIZE, wxIconizeEventHandler( CMainFrameBase::OnIconize ) ); - this->Connect( wxEVT_IDLE, wxIdleEventHandler( CMainFrameBase::OnIdle ) ); - this->Connect( wxEVT_LEFT_DOWN, wxMouseEventHandler( CMainFrameBase::OnMouseEvents ) ); - this->Connect( wxEVT_LEFT_UP, wxMouseEventHandler( CMainFrameBase::OnMouseEvents ) ); - this->Connect( wxEVT_MIDDLE_DOWN, wxMouseEventHandler( CMainFrameBase::OnMouseEvents ) ); - this->Connect( wxEVT_MIDDLE_UP, wxMouseEventHandler( CMainFrameBase::OnMouseEvents ) ); - this->Connect( wxEVT_RIGHT_DOWN, wxMouseEventHandler( CMainFrameBase::OnMouseEvents ) ); - this->Connect( wxEVT_RIGHT_UP, wxMouseEventHandler( CMainFrameBase::OnMouseEvents ) ); - this->Connect( wxEVT_MOTION, wxMouseEventHandler( CMainFrameBase::OnMouseEvents ) ); - this->Connect( wxEVT_LEFT_DCLICK, wxMouseEventHandler( CMainFrameBase::OnMouseEvents ) ); - this->Connect( wxEVT_MIDDLE_DCLICK, wxMouseEventHandler( CMainFrameBase::OnMouseEvents ) ); - this->Connect( wxEVT_RIGHT_DCLICK, wxMouseEventHandler( CMainFrameBase::OnMouseEvents ) ); - this->Connect( wxEVT_LEAVE_WINDOW, wxMouseEventHandler( CMainFrameBase::OnMouseEvents ) ); - this->Connect( wxEVT_ENTER_WINDOW, wxMouseEventHandler( CMainFrameBase::OnMouseEvents ) ); - this->Connect( wxEVT_MOUSEWHEEL, wxMouseEventHandler( CMainFrameBase::OnMouseEvents ) ); - this->Connect( wxEVT_PAINT, wxPaintEventHandler( CMainFrameBase::OnPaint ) ); - this->Connect( m_menuFileExit->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( CMainFrameBase::OnMenuFileExit ) ); - this->Connect( m_menuOptionsChangeYourAddress->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( CMainFrameBase::OnMenuOptionsChangeYourAddress ) ); - this->Connect( m_menuOptionsOptions->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( CMainFrameBase::OnMenuOptionsOptions ) ); - this->Connect( m_menuHelpAbout->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( CMainFrameBase::OnMenuHelpAbout ) ); - this->Connect( wxID_BUTTONSEND, wxEVT_COMMAND_TOOL_CLICKED, wxCommandEventHandler( CMainFrameBase::OnButtonSend ) ); - this->Connect( wxID_BUTTONRECEIVE, wxEVT_COMMAND_TOOL_CLICKED, wxCommandEventHandler( CMainFrameBase::OnButtonAddressBook ) ); - m_textCtrlAddress->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CMainFrameBase::OnKeyDown ), NULL, this ); - m_textCtrlAddress->Connect( wxEVT_LEFT_DOWN, wxMouseEventHandler( CMainFrameBase::OnMouseEventsAddress ), NULL, this ); - m_textCtrlAddress->Connect( wxEVT_LEFT_UP, wxMouseEventHandler( CMainFrameBase::OnMouseEventsAddress ), NULL, this ); - m_textCtrlAddress->Connect( wxEVT_MIDDLE_DOWN, wxMouseEventHandler( CMainFrameBase::OnMouseEventsAddress ), NULL, this ); - m_textCtrlAddress->Connect( wxEVT_MIDDLE_UP, wxMouseEventHandler( CMainFrameBase::OnMouseEventsAddress ), NULL, this ); - m_textCtrlAddress->Connect( wxEVT_RIGHT_DOWN, wxMouseEventHandler( CMainFrameBase::OnMouseEventsAddress ), NULL, this ); - m_textCtrlAddress->Connect( wxEVT_RIGHT_UP, wxMouseEventHandler( CMainFrameBase::OnMouseEventsAddress ), NULL, this ); - m_textCtrlAddress->Connect( wxEVT_MOTION, wxMouseEventHandler( CMainFrameBase::OnMouseEventsAddress ), NULL, this ); - m_textCtrlAddress->Connect( wxEVT_LEFT_DCLICK, wxMouseEventHandler( CMainFrameBase::OnMouseEventsAddress ), NULL, this ); - m_textCtrlAddress->Connect( wxEVT_MIDDLE_DCLICK, wxMouseEventHandler( CMainFrameBase::OnMouseEventsAddress ), NULL, this ); - m_textCtrlAddress->Connect( wxEVT_RIGHT_DCLICK, wxMouseEventHandler( CMainFrameBase::OnMouseEventsAddress ), NULL, this ); - m_textCtrlAddress->Connect( wxEVT_LEAVE_WINDOW, wxMouseEventHandler( CMainFrameBase::OnMouseEventsAddress ), NULL, this ); - m_textCtrlAddress->Connect( wxEVT_ENTER_WINDOW, wxMouseEventHandler( CMainFrameBase::OnMouseEventsAddress ), NULL, this ); - m_textCtrlAddress->Connect( wxEVT_MOUSEWHEEL, wxMouseEventHandler( CMainFrameBase::OnMouseEventsAddress ), NULL, this ); - m_textCtrlAddress->Connect( wxEVT_SET_FOCUS, wxFocusEventHandler( CMainFrameBase::OnSetFocusAddress ), NULL, this ); - m_buttonNew->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CMainFrameBase::OnButtonNew ), NULL, this ); - m_buttonCopy->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CMainFrameBase::OnButtonCopy ), NULL, this ); - m_notebook->Connect( wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGED, wxNotebookEventHandler( CMainFrameBase::OnNotebookPageChanged ), NULL, this ); - m_listCtrlAll->Connect( wxEVT_COMMAND_LIST_COL_BEGIN_DRAG, wxListEventHandler( CMainFrameBase::OnListColBeginDrag ), NULL, this ); - m_listCtrlAll->Connect( wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler( CMainFrameBase::OnListItemActivated ), NULL, this ); - m_listCtrlAll->Connect( wxEVT_PAINT, wxPaintEventHandler( CMainFrameBase::OnPaintListCtrl ), NULL, this ); - m_listCtrlSentReceived->Connect( wxEVT_COMMAND_LIST_COL_BEGIN_DRAG, wxListEventHandler( CMainFrameBase::OnListColBeginDrag ), NULL, this ); - m_listCtrlSentReceived->Connect( wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler( CMainFrameBase::OnListItemActivated ), NULL, this ); - m_listCtrlSentReceived->Connect( wxEVT_PAINT, wxPaintEventHandler( CMainFrameBase::OnPaintListCtrl ), NULL, this ); - m_listCtrlSent->Connect( wxEVT_COMMAND_LIST_COL_BEGIN_DRAG, wxListEventHandler( CMainFrameBase::OnListColBeginDrag ), NULL, this ); - m_listCtrlSent->Connect( wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler( CMainFrameBase::OnListItemActivated ), NULL, this ); - m_listCtrlSent->Connect( wxEVT_PAINT, wxPaintEventHandler( CMainFrameBase::OnPaintListCtrl ), NULL, this ); - m_listCtrlReceived->Connect( wxEVT_COMMAND_LIST_COL_BEGIN_DRAG, wxListEventHandler( CMainFrameBase::OnListColBeginDrag ), NULL, this ); - m_listCtrlReceived->Connect( wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler( CMainFrameBase::OnListItemActivated ), NULL, this ); - m_listCtrlReceived->Connect( wxEVT_PAINT, wxPaintEventHandler( CMainFrameBase::OnPaintListCtrl ), NULL, this ); -} - -CMainFrameBase::~CMainFrameBase() -{ - // Disconnect Events - this->Disconnect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( CMainFrameBase::OnClose ) ); - this->Disconnect( wxEVT_ICONIZE, wxIconizeEventHandler( CMainFrameBase::OnIconize ) ); - this->Disconnect( wxEVT_IDLE, wxIdleEventHandler( CMainFrameBase::OnIdle ) ); - this->Disconnect( wxEVT_LEFT_DOWN, wxMouseEventHandler( CMainFrameBase::OnMouseEvents ) ); - this->Disconnect( wxEVT_LEFT_UP, wxMouseEventHandler( CMainFrameBase::OnMouseEvents ) ); - this->Disconnect( wxEVT_MIDDLE_DOWN, wxMouseEventHandler( CMainFrameBase::OnMouseEvents ) ); - this->Disconnect( wxEVT_MIDDLE_UP, wxMouseEventHandler( CMainFrameBase::OnMouseEvents ) ); - this->Disconnect( wxEVT_RIGHT_DOWN, wxMouseEventHandler( CMainFrameBase::OnMouseEvents ) ); - this->Disconnect( wxEVT_RIGHT_UP, wxMouseEventHandler( CMainFrameBase::OnMouseEvents ) ); - this->Disconnect( wxEVT_MOTION, wxMouseEventHandler( CMainFrameBase::OnMouseEvents ) ); - this->Disconnect( wxEVT_LEFT_DCLICK, wxMouseEventHandler( CMainFrameBase::OnMouseEvents ) ); - this->Disconnect( wxEVT_MIDDLE_DCLICK, wxMouseEventHandler( CMainFrameBase::OnMouseEvents ) ); - this->Disconnect( wxEVT_RIGHT_DCLICK, wxMouseEventHandler( CMainFrameBase::OnMouseEvents ) ); - this->Disconnect( wxEVT_LEAVE_WINDOW, wxMouseEventHandler( CMainFrameBase::OnMouseEvents ) ); - this->Disconnect( wxEVT_ENTER_WINDOW, wxMouseEventHandler( CMainFrameBase::OnMouseEvents ) ); - this->Disconnect( wxEVT_MOUSEWHEEL, wxMouseEventHandler( CMainFrameBase::OnMouseEvents ) ); - this->Disconnect( wxEVT_PAINT, wxPaintEventHandler( CMainFrameBase::OnPaint ) ); - this->Disconnect( wxID_ANY, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( CMainFrameBase::OnMenuFileExit ) ); - this->Disconnect( wxID_ANY, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( CMainFrameBase::OnMenuOptionsChangeYourAddress ) ); - this->Disconnect( wxID_ANY, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( CMainFrameBase::OnMenuOptionsOptions ) ); - this->Disconnect( wxID_ANY, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( CMainFrameBase::OnMenuHelpAbout ) ); - this->Disconnect( wxID_BUTTONSEND, wxEVT_COMMAND_TOOL_CLICKED, wxCommandEventHandler( CMainFrameBase::OnButtonSend ) ); - this->Disconnect( wxID_BUTTONRECEIVE, wxEVT_COMMAND_TOOL_CLICKED, wxCommandEventHandler( CMainFrameBase::OnButtonAddressBook ) ); - m_textCtrlAddress->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CMainFrameBase::OnKeyDown ), NULL, this ); - m_textCtrlAddress->Disconnect( wxEVT_LEFT_DOWN, wxMouseEventHandler( CMainFrameBase::OnMouseEventsAddress ), NULL, this ); - m_textCtrlAddress->Disconnect( wxEVT_LEFT_UP, wxMouseEventHandler( CMainFrameBase::OnMouseEventsAddress ), NULL, this ); - m_textCtrlAddress->Disconnect( wxEVT_MIDDLE_DOWN, wxMouseEventHandler( CMainFrameBase::OnMouseEventsAddress ), NULL, this ); - m_textCtrlAddress->Disconnect( wxEVT_MIDDLE_UP, wxMouseEventHandler( CMainFrameBase::OnMouseEventsAddress ), NULL, this ); - m_textCtrlAddress->Disconnect( wxEVT_RIGHT_DOWN, wxMouseEventHandler( CMainFrameBase::OnMouseEventsAddress ), NULL, this ); - m_textCtrlAddress->Disconnect( wxEVT_RIGHT_UP, wxMouseEventHandler( CMainFrameBase::OnMouseEventsAddress ), NULL, this ); - m_textCtrlAddress->Disconnect( wxEVT_MOTION, wxMouseEventHandler( CMainFrameBase::OnMouseEventsAddress ), NULL, this ); - m_textCtrlAddress->Disconnect( wxEVT_LEFT_DCLICK, wxMouseEventHandler( CMainFrameBase::OnMouseEventsAddress ), NULL, this ); - m_textCtrlAddress->Disconnect( wxEVT_MIDDLE_DCLICK, wxMouseEventHandler( CMainFrameBase::OnMouseEventsAddress ), NULL, this ); - m_textCtrlAddress->Disconnect( wxEVT_RIGHT_DCLICK, wxMouseEventHandler( CMainFrameBase::OnMouseEventsAddress ), NULL, this ); - m_textCtrlAddress->Disconnect( wxEVT_LEAVE_WINDOW, wxMouseEventHandler( CMainFrameBase::OnMouseEventsAddress ), NULL, this ); - m_textCtrlAddress->Disconnect( wxEVT_ENTER_WINDOW, wxMouseEventHandler( CMainFrameBase::OnMouseEventsAddress ), NULL, this ); - m_textCtrlAddress->Disconnect( wxEVT_MOUSEWHEEL, wxMouseEventHandler( CMainFrameBase::OnMouseEventsAddress ), NULL, this ); - m_textCtrlAddress->Disconnect( wxEVT_SET_FOCUS, wxFocusEventHandler( CMainFrameBase::OnSetFocusAddress ), NULL, this ); - m_buttonNew->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CMainFrameBase::OnButtonNew ), NULL, this ); - m_buttonCopy->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CMainFrameBase::OnButtonCopy ), NULL, this ); - m_notebook->Disconnect( wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGED, wxNotebookEventHandler( CMainFrameBase::OnNotebookPageChanged ), NULL, this ); - m_listCtrlAll->Disconnect( wxEVT_COMMAND_LIST_COL_BEGIN_DRAG, wxListEventHandler( CMainFrameBase::OnListColBeginDrag ), NULL, this ); - m_listCtrlAll->Disconnect( wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler( CMainFrameBase::OnListItemActivated ), NULL, this ); - m_listCtrlAll->Disconnect( wxEVT_PAINT, wxPaintEventHandler( CMainFrameBase::OnPaintListCtrl ), NULL, this ); - m_listCtrlSentReceived->Disconnect( wxEVT_COMMAND_LIST_COL_BEGIN_DRAG, wxListEventHandler( CMainFrameBase::OnListColBeginDrag ), NULL, this ); - m_listCtrlSentReceived->Disconnect( wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler( CMainFrameBase::OnListItemActivated ), NULL, this ); - m_listCtrlSentReceived->Disconnect( wxEVT_PAINT, wxPaintEventHandler( CMainFrameBase::OnPaintListCtrl ), NULL, this ); - m_listCtrlSent->Disconnect( wxEVT_COMMAND_LIST_COL_BEGIN_DRAG, wxListEventHandler( CMainFrameBase::OnListColBeginDrag ), NULL, this ); - m_listCtrlSent->Disconnect( wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler( CMainFrameBase::OnListItemActivated ), NULL, this ); - m_listCtrlSent->Disconnect( wxEVT_PAINT, wxPaintEventHandler( CMainFrameBase::OnPaintListCtrl ), NULL, this ); - m_listCtrlReceived->Disconnect( wxEVT_COMMAND_LIST_COL_BEGIN_DRAG, wxListEventHandler( CMainFrameBase::OnListColBeginDrag ), NULL, this ); - m_listCtrlReceived->Disconnect( wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler( CMainFrameBase::OnListItemActivated ), NULL, this ); - m_listCtrlReceived->Disconnect( wxEVT_PAINT, wxPaintEventHandler( CMainFrameBase::OnPaintListCtrl ), NULL, this ); -} - -CTxDetailsDialogBase::CTxDetailsDialogBase( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : wxDialog( parent, id, title, pos, size, style ) -{ - this->SetSizeHints( wxDefaultSize, wxDefaultSize ); - - wxBoxSizer* bSizer64; - bSizer64 = new wxBoxSizer( wxVERTICAL ); - - wxBoxSizer* bSizer66; - bSizer66 = new wxBoxSizer( wxVERTICAL ); - - m_htmlWin = new wxHtmlWindow( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxHW_SCROLLBAR_AUTO ); - bSizer66->Add( m_htmlWin, 1, wxALL|wxEXPAND, 5 ); - - bSizer64->Add( bSizer66, 1, wxEXPAND, 5 ); - - wxBoxSizer* bSizer65; - bSizer65 = new wxBoxSizer( wxHORIZONTAL ); - - m_buttonOK = new wxButton( this, wxID_OK, _("OK"), wxDefaultPosition, wxSize( -1,-1 ), 0 ); - bSizer65->Add( m_buttonOK, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); - - bSizer64->Add( bSizer65, 0, wxALIGN_RIGHT, 5 ); - - this->SetSizer( bSizer64 ); - this->Layout(); - - // Connect Events - m_buttonOK->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CTxDetailsDialogBase::OnButtonOK ), NULL, this ); -} - -CTxDetailsDialogBase::~CTxDetailsDialogBase() -{ - // Disconnect Events - m_buttonOK->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CTxDetailsDialogBase::OnButtonOK ), NULL, this ); -} - -COptionsDialogBase::COptionsDialogBase( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : wxDialog( parent, id, title, pos, size, style ) -{ - this->SetSizeHints( wxDefaultSize, wxDefaultSize ); - - wxBoxSizer* bSizer55; - bSizer55 = new wxBoxSizer( wxVERTICAL ); - - wxBoxSizer* bSizer66; - bSizer66 = new wxBoxSizer( wxHORIZONTAL ); - - m_listBox = new wxListBox( this, wxID_ANY, wxDefaultPosition, wxSize( 110,-1 ), 0, NULL, wxLB_NEEDED_SB|wxLB_SINGLE ); - bSizer66->Add( m_listBox, 0, wxEXPAND|wxRIGHT, 5 ); - - m_scrolledWindow = new wxScrolledWindow( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 ); - m_scrolledWindow->SetScrollRate( 5, 5 ); - wxBoxSizer* bSizer63; - bSizer63 = new wxBoxSizer( wxVERTICAL ); - - m_panelMain = new wxPanel( m_scrolledWindow, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL ); - wxBoxSizer* bSizer69; - bSizer69 = new wxBoxSizer( wxVERTICAL ); - - - bSizer69->Add( 0, 16, 0, wxEXPAND, 5 ); - - m_checkBoxStartOnSystemStartup = new wxCheckBox( m_panelMain, wxID_ANY, _("&Start Bitcoin on system startup"), wxDefaultPosition, wxDefaultSize, 0 ); - bSizer69->Add( m_checkBoxStartOnSystemStartup, 0, wxALL, 5 ); - - m_checkBoxMinimizeToTray = new wxCheckBox( m_panelMain, wxID_ANY, _("&Minimize to the tray instead of the taskbar"), wxDefaultPosition, wxDefaultSize, 0 ); - bSizer69->Add( m_checkBoxMinimizeToTray, 0, wxALL, 5 ); - - m_checkBoxUseUPnP = new wxCheckBox( m_panelMain, wxID_ANY, _("Map port using &UPnP"), wxDefaultPosition, wxDefaultSize, 0 ); - bSizer69->Add( m_checkBoxUseUPnP, 0, wxALL, 5 ); - - m_checkBoxMinimizeOnClose = new wxCheckBox( m_panelMain, wxID_ANY, _("M&inimize to the tray on close"), wxDefaultPosition, wxDefaultSize, 0 ); - bSizer69->Add( m_checkBoxMinimizeOnClose, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); - - wxBoxSizer* bSizer102; - bSizer102 = new wxBoxSizer( wxHORIZONTAL ); - - m_checkBoxUseProxy = new wxCheckBox( m_panelMain, wxID_ANY, _("&Connect through socks4 proxy: "), wxDefaultPosition, wxDefaultSize, 0 ); - bSizer102->Add( m_checkBoxUseProxy, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); - - bSizer69->Add( bSizer102, 1, wxEXPAND, 5 ); - - wxBoxSizer* bSizer103; - bSizer103 = new wxBoxSizer( wxHORIZONTAL ); - - - bSizer103->Add( 18, 0, 0, 0, 5 ); - - m_staticTextProxyIP = new wxStaticText( m_panelMain, wxID_ANY, _("Proxy &IP:"), wxDefaultPosition, wxDefaultSize, 0 ); - m_staticTextProxyIP->Wrap( -1 ); - bSizer103->Add( m_staticTextProxyIP, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); - - m_textCtrlProxyIP = new wxTextCtrl( m_panelMain, wxID_PROXYIP, wxEmptyString, wxDefaultPosition, wxSize( 140,-1 ), 0 ); - m_textCtrlProxyIP->SetMaxLength( 15 ); - bSizer103->Add( m_textCtrlProxyIP, 0, wxALIGN_CENTER_VERTICAL, 5 ); - - m_staticTextProxyPort = new wxStaticText( m_panelMain, wxID_ANY, _(" &Port:"), wxDefaultPosition, wxDefaultSize, 0 ); - m_staticTextProxyPort->Wrap( -1 ); - bSizer103->Add( m_staticTextProxyPort, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); - - m_textCtrlProxyPort = new wxTextCtrl( m_panelMain, wxID_PROXYPORT, wxEmptyString, wxDefaultPosition, wxSize( 55,-1 ), 0 ); - m_textCtrlProxyPort->SetMaxLength( 5 ); - bSizer103->Add( m_textCtrlProxyPort, 0, wxALIGN_CENTER_VERTICAL, 5 ); - - bSizer69->Add( bSizer103, 1, wxEXPAND, 5 ); - - - bSizer69->Add( 0, 1, 0, 0, 5 ); - - m_staticText32 = new wxStaticText( m_panelMain, wxID_ANY, _("Optional transaction fee per KB that helps make sure your transactions are processed quickly. Most transactions are 1KB. Fee 0.01 recommended."), wxDefaultPosition, wxDefaultSize, 0 ); - m_staticText32->Wrap( 365 ); - bSizer69->Add( m_staticText32, 0, wxALIGN_CENTER_VERTICAL|wxTOP|wxRIGHT|wxLEFT, 5 ); - - wxBoxSizer* bSizer56; - bSizer56 = new wxBoxSizer( wxHORIZONTAL ); - - m_staticText31 = new wxStaticText( m_panelMain, wxID_ANY, _("Pay transaction fee:"), wxDefaultPosition, wxDefaultSize, 0 ); - m_staticText31->Wrap( -1 ); - bSizer56->Add( m_staticText31, 0, wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxLEFT, 5 ); - - m_textCtrlTransactionFee = new wxTextCtrl( m_panelMain, wxID_TRANSACTIONFEE, wxEmptyString, wxDefaultPosition, wxSize( 70,-1 ), 0 ); - bSizer56->Add( m_textCtrlTransactionFee, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 ); - - bSizer69->Add( bSizer56, 0, wxEXPAND, 5 ); - - m_panelMain->SetSizer( bSizer69 ); - m_panelMain->Layout(); - bSizer69->Fit( m_panelMain ); - bSizer63->Add( m_panelMain, 0, wxEXPAND, 5 ); - - m_panelTest2 = new wxPanel( m_scrolledWindow, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL ); - wxBoxSizer* bSizer64; - bSizer64 = new wxBoxSizer( wxVERTICAL ); - - - bSizer64->Add( 0, 16, 0, wxEXPAND, 5 ); - - m_staticText321 = new wxStaticText( m_panelTest2, wxID_ANY, _("// [don't translate] Test panel 2 for future expansion"), wxDefaultPosition, wxDefaultSize, 0 ); - m_staticText321->Wrap( -1 ); - bSizer64->Add( m_staticText321, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 ); - - m_staticText69 = new wxStaticText( m_panelTest2, wxID_ANY, _("// [don't translate] Let's not start multiple pages until the first page is filled up"), wxDefaultPosition, wxDefaultSize, 0 ); - m_staticText69->Wrap( -1 ); - bSizer64->Add( m_staticText69, 0, wxALL, 5 ); - - m_panelTest2->SetSizer( bSizer64 ); - m_panelTest2->Layout(); - bSizer64->Fit( m_panelTest2 ); - bSizer63->Add( m_panelTest2, 0, wxEXPAND, 5 ); - - m_scrolledWindow->SetSizer( bSizer63 ); - m_scrolledWindow->Layout(); - bSizer63->Fit( m_scrolledWindow ); - bSizer66->Add( m_scrolledWindow, 1, wxEXPAND|wxLEFT, 5 ); - - bSizer55->Add( bSizer66, 1, wxEXPAND|wxALL, 9 ); - - wxBoxSizer* bSizer58; - bSizer58 = new wxBoxSizer( wxHORIZONTAL ); - - m_buttonOK = new wxButton( this, wxID_OK, _("OK"), wxDefaultPosition, wxSize( -1,-1 ), 0 ); - bSizer58->Add( m_buttonOK, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); - - m_buttonCancel = new wxButton( this, wxID_CANCEL, _("Cancel"), wxDefaultPosition, wxSize( -1,-1 ), 0 ); - bSizer58->Add( m_buttonCancel, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); - - m_buttonApply = new wxButton( this, wxID_APPLY, _("&Apply"), wxDefaultPosition, wxSize( -1,-1 ), 0 ); - bSizer58->Add( m_buttonApply, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); - - bSizer55->Add( bSizer58, 0, wxALIGN_RIGHT, 5 ); - - this->SetSizer( bSizer55 ); - this->Layout(); - - // Connect Events - m_listBox->Connect( wxEVT_COMMAND_LISTBOX_SELECTED, wxCommandEventHandler( COptionsDialogBase::OnListBox ), NULL, this ); - m_checkBoxMinimizeToTray->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( COptionsDialogBase::OnCheckBoxMinimizeToTray ), NULL, this ); - m_checkBoxUseProxy->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( COptionsDialogBase::OnCheckBoxUseProxy ), NULL, this ); - m_textCtrlProxyIP->Connect( wxEVT_KILL_FOCUS, wxFocusEventHandler( COptionsDialogBase::OnKillFocusProxy ), NULL, this ); - m_textCtrlProxyPort->Connect( wxEVT_KILL_FOCUS, wxFocusEventHandler( COptionsDialogBase::OnKillFocusProxy ), NULL, this ); - m_textCtrlTransactionFee->Connect( wxEVT_KILL_FOCUS, wxFocusEventHandler( COptionsDialogBase::OnKillFocusTransactionFee ), NULL, this ); - m_buttonOK->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( COptionsDialogBase::OnButtonOK ), NULL, this ); - m_buttonCancel->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( COptionsDialogBase::OnButtonCancel ), NULL, this ); - m_buttonApply->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( COptionsDialogBase::OnButtonApply ), NULL, this ); -} - -COptionsDialogBase::~COptionsDialogBase() -{ - // Disconnect Events - m_listBox->Disconnect( wxEVT_COMMAND_LISTBOX_SELECTED, wxCommandEventHandler( COptionsDialogBase::OnListBox ), NULL, this ); - m_checkBoxMinimizeToTray->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( COptionsDialogBase::OnCheckBoxMinimizeToTray ), NULL, this ); - m_checkBoxUseProxy->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( COptionsDialogBase::OnCheckBoxUseProxy ), NULL, this ); - m_textCtrlProxyIP->Disconnect( wxEVT_KILL_FOCUS, wxFocusEventHandler( COptionsDialogBase::OnKillFocusProxy ), NULL, this ); - m_textCtrlProxyPort->Disconnect( wxEVT_KILL_FOCUS, wxFocusEventHandler( COptionsDialogBase::OnKillFocusProxy ), NULL, this ); - m_textCtrlTransactionFee->Disconnect( wxEVT_KILL_FOCUS, wxFocusEventHandler( COptionsDialogBase::OnKillFocusTransactionFee ), NULL, this ); - m_buttonOK->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( COptionsDialogBase::OnButtonOK ), NULL, this ); - m_buttonCancel->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( COptionsDialogBase::OnButtonCancel ), NULL, this ); - m_buttonApply->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( COptionsDialogBase::OnButtonApply ), NULL, this ); -} - -CAboutDialogBase::CAboutDialogBase( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : wxDialog( parent, id, title, pos, size, style ) -{ - this->SetSizeHints( wxDefaultSize, wxDefaultSize ); - - wxBoxSizer* bSizer63; - bSizer63 = new wxBoxSizer( wxHORIZONTAL ); - - m_bitmap = new wxStaticBitmap( this, wxID_ANY, wxBitmap( about_xpm ), wxDefaultPosition, wxDefaultSize, 0 ); - bSizer63->Add( m_bitmap, 0, 0, 5 ); - - wxBoxSizer* bSizer60; - bSizer60 = new wxBoxSizer( wxVERTICAL ); - - wxBoxSizer* bSizer62; - bSizer62 = new wxBoxSizer( wxHORIZONTAL ); - - wxBoxSizer* bSizer631; - bSizer631 = new wxBoxSizer( wxVERTICAL ); - - - bSizer631->Add( 0, 65, 0, wxEXPAND, 5 ); - - wxBoxSizer* bSizer64; - bSizer64 = new wxBoxSizer( wxHORIZONTAL ); - - m_staticText40 = new wxStaticText( this, wxID_ANY, _("Bitcoin "), wxDefaultPosition, wxDefaultSize, 0 ); - m_staticText40->Wrap( -1 ); - m_staticText40->SetFont( wxFont( 10, 74, 90, 92, false, wxT("Tahoma") ) ); - - bSizer64->Add( m_staticText40, 0, wxALIGN_BOTTOM|wxTOP|wxBOTTOM|wxLEFT, 5 ); - - m_staticTextVersion = new wxStaticText( this, wxID_ANY, _("version"), wxDefaultPosition, wxDefaultSize, 0 ); - m_staticTextVersion->Wrap( -1 ); - m_staticTextVersion->SetFont( wxFont( 10, 74, 90, 90, false, wxT("Tahoma") ) ); - - bSizer64->Add( m_staticTextVersion, 0, wxALIGN_BOTTOM|wxTOP|wxBOTTOM|wxRIGHT, 5 ); - - bSizer631->Add( bSizer64, 0, wxEXPAND, 5 ); - - - bSizer631->Add( 0, 4, 0, wxEXPAND, 5 ); - - m_staticTextMain = new wxStaticText( this, wxID_ANY, _("Copyright (c) 2009-2011 Bitcoin Developers\n\nThis is experimental software.\n\nDistributed under the MIT/X11 software license, see the accompanying file \nlicense.txt or http://www.opensource.org/licenses/mit-license.php.\n\nThis product includes software developed by the OpenSSL Project for use in the \nOpenSSL Toolkit (http://www.openssl.org/) and cryptographic software written by \nEric Young (eay@cryptsoft.com) and UPnP software written by Thomas Bernard."), wxDefaultPosition, wxDefaultSize, 0 ); - m_staticTextMain->Wrap( -1 ); - bSizer631->Add( m_staticTextMain, 0, wxALL, 5 ); - - - bSizer631->Add( 0, 0, 0, wxEXPAND, 5 ); - - bSizer62->Add( bSizer631, 1, wxEXPAND, 5 ); - - bSizer60->Add( bSizer62, 1, wxEXPAND, 5 ); - - wxBoxSizer* bSizer61; - bSizer61 = new wxBoxSizer( wxHORIZONTAL ); - - - bSizer61->Add( 0, 0, 1, wxEXPAND, 5 ); - - m_buttonOK = new wxButton( this, wxID_OK, _("OK"), wxDefaultPosition, wxSize( -1,-1 ), 0 ); - bSizer61->Add( m_buttonOK, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 6 ); - - bSizer60->Add( bSizer61, 0, wxALIGN_RIGHT|wxEXPAND|wxRIGHT, 2 ); - - bSizer63->Add( bSizer60, 1, wxEXPAND|wxLEFT, 5 ); - - this->SetSizer( bSizer63 ); - this->Layout(); - - // Connect Events - m_buttonOK->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CAboutDialogBase::OnButtonOK ), NULL, this ); -} - -CAboutDialogBase::~CAboutDialogBase() -{ - // Disconnect Events - m_buttonOK->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CAboutDialogBase::OnButtonOK ), NULL, this ); -} - -CSendDialogBase::CSendDialogBase( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : wxDialog( parent, id, title, pos, size, style ) -{ - this->SetSizeHints( wxDefaultSize, wxDefaultSize ); - - wxBoxSizer* bSizer21; - bSizer21 = new wxBoxSizer( wxVERTICAL ); - - - bSizer21->Add( 0, 5, 0, wxEXPAND, 5 ); - - wxFlexGridSizer* fgSizer1; - fgSizer1 = new wxFlexGridSizer( 0, 2, 0, 0 ); - fgSizer1->AddGrowableCol( 1 ); - fgSizer1->SetFlexibleDirection( wxBOTH ); - fgSizer1->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED ); - - - fgSizer1->Add( 0, 0, 0, wxEXPAND, 5 ); - - m_staticTextInstructions = new wxStaticText( this, wxID_ANY, _("Enter a Bitcoin address (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L)"), wxDefaultPosition, wxDefaultSize, 0 ); - m_staticTextInstructions->Wrap( -1 ); - fgSizer1->Add( m_staticTextInstructions, 0, wxTOP|wxRIGHT|wxLEFT, 5 ); - - wxBoxSizer* bSizer47; - bSizer47 = new wxBoxSizer( wxHORIZONTAL ); - - bSizer47->SetMinSize( wxSize( 70,-1 ) ); - - bSizer47->Add( 0, 0, 1, wxEXPAND, 5 ); - - m_bitmapCheckMark = new wxStaticBitmap( this, wxID_ANY, wxBitmap( check_xpm ), wxDefaultPosition, wxSize( 16,16 ), 0 ); - bSizer47->Add( m_bitmapCheckMark, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); - - m_staticText36 = new wxStaticText( this, wxID_ANY, _("Pay &To:"), wxDefaultPosition, wxSize( -1,-1 ), wxALIGN_RIGHT ); - m_staticText36->Wrap( -1 ); - bSizer47->Add( m_staticText36, 0, wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxLEFT, 5 ); - - fgSizer1->Add( bSizer47, 1, wxEXPAND|wxLEFT, 5 ); - - wxBoxSizer* bSizer19; - bSizer19 = new wxBoxSizer( wxHORIZONTAL ); - - m_textCtrlAddress = new wxTextCtrl( this, wxID_TEXTCTRLPAYTO, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); - bSizer19->Add( m_textCtrlAddress, 1, wxALIGN_CENTER_VERTICAL|wxALL, 5 ); - - wxBoxSizer* bSizer66; - bSizer66 = new wxBoxSizer( wxHORIZONTAL ); - - m_buttonPaste = new wxButton( this, wxID_BUTTONPASTE, _("&Paste"), wxDefaultPosition, wxSize( -1,-1 ), wxBU_EXACTFIT ); - bSizer66->Add( m_buttonPaste, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxEXPAND, 5 ); - - m_buttonAddress = new wxButton( this, wxID_BUTTONADDRESSBOOK, _(" Address &Book..."), wxDefaultPosition, wxDefaultSize, 0 ); - bSizer66->Add( m_buttonAddress, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxEXPAND, 5 ); - - bSizer19->Add( bSizer66, 0, wxALIGN_CENTER_VERTICAL, 5 ); - - fgSizer1->Add( bSizer19, 1, wxEXPAND|wxRIGHT, 5 ); - - m_staticText19 = new wxStaticText( this, wxID_ANY, _("&Amount:"), wxDefaultPosition, wxSize( -1,-1 ), wxALIGN_RIGHT ); - m_staticText19->Wrap( -1 ); - fgSizer1->Add( m_staticText19, 0, wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxLEFT|wxALIGN_RIGHT, 5 ); - - m_textCtrlAmount = new wxTextCtrl( this, wxID_TEXTCTRLAMOUNT, wxEmptyString, wxDefaultPosition, wxSize( 145,-1 ), 0 ); - m_textCtrlAmount->SetMaxLength( 20 ); - m_textCtrlAmount->SetFont( wxFont( wxNORMAL_FONT->GetPointSize(), 70, 90, 90, false, wxEmptyString ) ); - - fgSizer1->Add( m_textCtrlAmount, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 ); - - m_staticText20 = new wxStaticText( this, wxID_ANY, _("T&ransfer:"), wxDefaultPosition, wxSize( -1,-1 ), wxALIGN_RIGHT ); - m_staticText20->Wrap( -1 ); - m_staticText20->Hide(); - - fgSizer1->Add( m_staticText20, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxTOP|wxBOTTOM|wxLEFT, 5 ); - - wxString m_choiceTransferTypeChoices[] = { _(" Standard") }; - int m_choiceTransferTypeNChoices = sizeof( m_choiceTransferTypeChoices ) / sizeof( wxString ); - m_choiceTransferType = new wxChoice( this, wxID_CHOICETRANSFERTYPE, wxDefaultPosition, wxDefaultSize, m_choiceTransferTypeNChoices, m_choiceTransferTypeChoices, 0 ); - m_choiceTransferType->SetSelection( 0 ); - m_choiceTransferType->Hide(); - - fgSizer1->Add( m_choiceTransferType, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 ); - - - fgSizer1->Add( 0, 3, 0, wxEXPAND, 5 ); - - - fgSizer1->Add( 0, 0, 0, wxEXPAND, 5 ); - - bSizer21->Add( fgSizer1, 0, wxEXPAND|wxLEFT, 5 ); - - wxBoxSizer* bSizer672; - bSizer672 = new wxBoxSizer( wxHORIZONTAL ); - - bSizer21->Add( bSizer672, 0, wxEXPAND, 5 ); - - wxBoxSizer* bSizer23; - bSizer23 = new wxBoxSizer( wxHORIZONTAL ); - - - bSizer23->Add( 0, 0, 1, wxEXPAND, 5 ); - - m_buttonSend = new wxButton( this, wxID_BUTTONSEND, _("&Send"), wxDefaultPosition, wxSize( -1,-1 ), 0 ); - m_buttonSend->SetFont( wxFont( wxNORMAL_FONT->GetPointSize(), 70, 90, 90, false, wxEmptyString ) ); - - bSizer23->Add( m_buttonSend, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); - - m_buttonCancel = new wxButton( this, wxID_CANCEL, _("Cancel"), wxDefaultPosition, wxSize( -1,-1 ), 0 ); - bSizer23->Add( m_buttonCancel, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); - - bSizer21->Add( bSizer23, 0, wxEXPAND, 5 ); - - this->SetSizer( bSizer21 ); - this->Layout(); - - // Connect Events - m_textCtrlAddress->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CSendDialogBase::OnKeyDown ), NULL, this ); - m_textCtrlAddress->Connect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( CSendDialogBase::OnTextAddress ), NULL, this ); - m_buttonPaste->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CSendDialogBase::OnButtonPaste ), NULL, this ); - m_buttonAddress->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CSendDialogBase::OnButtonAddressBook ), NULL, this ); - m_textCtrlAmount->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CSendDialogBase::OnKeyDown ), NULL, this ); - m_textCtrlAmount->Connect( wxEVT_KILL_FOCUS, wxFocusEventHandler( CSendDialogBase::OnKillFocusAmount ), NULL, this ); - m_buttonSend->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CSendDialogBase::OnButtonSend ), NULL, this ); - m_buttonCancel->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CSendDialogBase::OnButtonCancel ), NULL, this ); -} - -CSendDialogBase::~CSendDialogBase() -{ - // Disconnect Events - m_textCtrlAddress->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CSendDialogBase::OnKeyDown ), NULL, this ); - m_textCtrlAddress->Disconnect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( CSendDialogBase::OnTextAddress ), NULL, this ); - m_buttonPaste->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CSendDialogBase::OnButtonPaste ), NULL, this ); - m_buttonAddress->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CSendDialogBase::OnButtonAddressBook ), NULL, this ); - m_textCtrlAmount->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CSendDialogBase::OnKeyDown ), NULL, this ); - m_textCtrlAmount->Disconnect( wxEVT_KILL_FOCUS, wxFocusEventHandler( CSendDialogBase::OnKillFocusAmount ), NULL, this ); - m_buttonSend->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CSendDialogBase::OnButtonSend ), NULL, this ); - m_buttonCancel->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CSendDialogBase::OnButtonCancel ), NULL, this ); -} - -CSendingDialogBase::CSendingDialogBase( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : wxDialog( parent, id, title, pos, size, style ) -{ - this->SetSizeHints( wxDefaultSize, wxDefaultSize ); - - wxBoxSizer* bSizer68; - bSizer68 = new wxBoxSizer( wxVERTICAL ); - - m_staticTextSending = new wxStaticText( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize( -1,14 ), 0 ); - m_staticTextSending->Wrap( -1 ); - bSizer68->Add( m_staticTextSending, 0, wxALIGN_CENTER_VERTICAL|wxEXPAND|wxTOP|wxRIGHT|wxLEFT, 8 ); - - m_textCtrlStatus = new wxTextCtrl( this, wxID_ANY, _("\n\nConnecting..."), wxDefaultPosition, wxDefaultSize, wxTE_CENTRE|wxTE_MULTILINE|wxTE_NO_VSCROLL|wxTE_READONLY|wxNO_BORDER ); - m_textCtrlStatus->SetBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_BTNFACE ) ); - - bSizer68->Add( m_textCtrlStatus, 1, wxEXPAND|wxRIGHT|wxLEFT, 10 ); - - wxBoxSizer* bSizer69; - bSizer69 = new wxBoxSizer( wxHORIZONTAL ); - - - bSizer69->Add( 0, 0, 1, wxEXPAND, 5 ); - - m_buttonOK = new wxButton( this, wxID_ANY, _("OK"), wxDefaultPosition, wxDefaultSize, 0 ); - m_buttonOK->Enable( false ); - - bSizer69->Add( m_buttonOK, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); - - m_buttonCancel = new wxButton( this, wxID_CANCEL, _("Cancel"), wxDefaultPosition, wxSize( -1,-1 ), 0 ); - bSizer69->Add( m_buttonCancel, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); - - bSizer68->Add( bSizer69, 0, wxEXPAND, 5 ); - - this->SetSizer( bSizer68 ); - this->Layout(); - - // Connect Events - this->Connect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( CSendingDialogBase::OnClose ) ); - this->Connect( wxEVT_PAINT, wxPaintEventHandler( CSendingDialogBase::OnPaint ) ); - m_buttonOK->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CSendingDialogBase::OnButtonOK ), NULL, this ); - m_buttonCancel->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CSendingDialogBase::OnButtonCancel ), NULL, this ); -} - -CSendingDialogBase::~CSendingDialogBase() -{ - // Disconnect Events - this->Disconnect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( CSendingDialogBase::OnClose ) ); - this->Disconnect( wxEVT_PAINT, wxPaintEventHandler( CSendingDialogBase::OnPaint ) ); - m_buttonOK->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CSendingDialogBase::OnButtonOK ), NULL, this ); - m_buttonCancel->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CSendingDialogBase::OnButtonCancel ), NULL, this ); -} - -CYourAddressDialogBase::CYourAddressDialogBase( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : wxDialog( parent, id, title, pos, size, style ) -{ - this->SetSizeHints( wxDefaultSize, wxDefaultSize ); - - wxBoxSizer* bSizer68; - bSizer68 = new wxBoxSizer( wxVERTICAL ); - - - bSizer68->Add( 0, 5, 0, wxEXPAND, 5 ); - - m_staticText45 = new wxStaticText( this, wxID_ANY, _("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. The highlighted address is displayed in the main window."), wxDefaultPosition, wxDefaultSize, 0 ); - m_staticText45->Wrap( 590 ); - bSizer68->Add( m_staticText45, 0, wxALL, 5 ); - - m_listCtrl = new wxListCtrl( this, wxID_LISTCTRL, wxDefaultPosition, wxDefaultSize, wxLC_NO_SORT_HEADER|wxLC_REPORT|wxLC_SORT_ASCENDING ); - bSizer68->Add( m_listCtrl, 1, wxALL|wxEXPAND, 5 ); - - wxBoxSizer* bSizer69; - bSizer69 = new wxBoxSizer( wxHORIZONTAL ); - - - bSizer69->Add( 0, 0, 1, wxEXPAND, 5 ); - - m_buttonRename = new wxButton( this, wxID_BUTTONRENAME, _("&Edit..."), wxDefaultPosition, wxDefaultSize, 0 ); - bSizer69->Add( m_buttonRename, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); - - m_buttonNew = new wxButton( this, wxID_BUTTONNEW, _(" &New Address... "), wxDefaultPosition, wxSize( -1,-1 ), 0 ); - bSizer69->Add( m_buttonNew, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); - - m_buttonCopy = new wxButton( this, wxID_BUTTONCOPY, _(" &Copy to Clipboard "), wxDefaultPosition, wxSize( -1,-1 ), 0 ); - bSizer69->Add( m_buttonCopy, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); - - m_buttonOK = new wxButton( this, wxID_OK, _("OK"), wxDefaultPosition, wxDefaultSize, 0 ); - bSizer69->Add( m_buttonOK, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); - - m_buttonCancel = new wxButton( this, wxID_CANCEL, _("Cancel"), wxDefaultPosition, wxSize( -1,-1 ), 0 ); - m_buttonCancel->Hide(); - - bSizer69->Add( m_buttonCancel, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); - - bSizer68->Add( bSizer69, 0, wxEXPAND, 5 ); - - this->SetSizer( bSizer68 ); - this->Layout(); - - // Connect Events - this->Connect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( CYourAddressDialogBase::OnClose ) ); - m_listCtrl->Connect( wxEVT_COMMAND_LIST_END_LABEL_EDIT, wxListEventHandler( CYourAddressDialogBase::OnListEndLabelEdit ), NULL, this ); - m_listCtrl->Connect( wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler( CYourAddressDialogBase::OnListItemActivated ), NULL, this ); - m_listCtrl->Connect( wxEVT_COMMAND_LIST_ITEM_SELECTED, wxListEventHandler( CYourAddressDialogBase::OnListItemSelected ), NULL, this ); - m_buttonRename->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CYourAddressDialogBase::OnButtonRename ), NULL, this ); - m_buttonNew->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CYourAddressDialogBase::OnButtonNew ), NULL, this ); - m_buttonCopy->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CYourAddressDialogBase::OnButtonCopy ), NULL, this ); - m_buttonOK->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CYourAddressDialogBase::OnButtonOK ), NULL, this ); - m_buttonCancel->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CYourAddressDialogBase::OnButtonCancel ), NULL, this ); -} - -CYourAddressDialogBase::~CYourAddressDialogBase() -{ - // Disconnect Events - this->Disconnect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( CYourAddressDialogBase::OnClose ) ); - m_listCtrl->Disconnect( wxEVT_COMMAND_LIST_END_LABEL_EDIT, wxListEventHandler( CYourAddressDialogBase::OnListEndLabelEdit ), NULL, this ); - m_listCtrl->Disconnect( wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler( CYourAddressDialogBase::OnListItemActivated ), NULL, this ); - m_listCtrl->Disconnect( wxEVT_COMMAND_LIST_ITEM_SELECTED, wxListEventHandler( CYourAddressDialogBase::OnListItemSelected ), NULL, this ); - m_buttonRename->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CYourAddressDialogBase::OnButtonRename ), NULL, this ); - m_buttonNew->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CYourAddressDialogBase::OnButtonNew ), NULL, this ); - m_buttonCopy->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CYourAddressDialogBase::OnButtonCopy ), NULL, this ); - m_buttonOK->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CYourAddressDialogBase::OnButtonOK ), NULL, this ); - m_buttonCancel->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CYourAddressDialogBase::OnButtonCancel ), NULL, this ); -} - -CAddressBookDialogBase::CAddressBookDialogBase( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : wxDialog( parent, id, title, pos, size, style ) -{ - this->SetSizeHints( wxDefaultSize, wxDefaultSize ); - - wxBoxSizer* bSizer58; - bSizer58 = new wxBoxSizer( wxVERTICAL ); - - m_notebook = new wxNotebook( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 ); - m_panelSending = new wxPanel( m_notebook, wxID_PANELSENDING, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL ); - wxBoxSizer* bSizer68; - bSizer68 = new wxBoxSizer( wxVERTICAL ); - - - bSizer68->Add( 0, 0, 0, wxEXPAND, 5 ); - - m_staticText55 = new wxStaticText( m_panelSending, wxID_ANY, _("Bitcoin Address"), wxDefaultPosition, wxDefaultSize, 0 ); - m_staticText55->Wrap( -1 ); - m_staticText55->Hide(); - - bSizer68->Add( m_staticText55, 0, wxTOP|wxRIGHT|wxLEFT, 5 ); - - m_listCtrlSending = new wxListCtrl( m_panelSending, wxID_LISTCTRLSENDING, wxDefaultPosition, wxDefaultSize, wxLC_NO_SORT_HEADER|wxLC_REPORT|wxLC_SORT_ASCENDING ); - bSizer68->Add( m_listCtrlSending, 1, wxALL|wxEXPAND, 5 ); - - m_panelSending->SetSizer( bSizer68 ); - m_panelSending->Layout(); - bSizer68->Fit( m_panelSending ); - m_notebook->AddPage( m_panelSending, _("Sending"), false ); - m_panelReceiving = new wxPanel( m_notebook, wxID_PANELRECEIVING, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL ); - wxBoxSizer* bSizer681; - bSizer681 = new wxBoxSizer( wxVERTICAL ); - - - bSizer681->Add( 0, 0, 0, wxEXPAND, 5 ); - - m_staticText45 = new wxStaticText( m_panelReceiving, wxID_ANY, _("These are your Bitcoin addresses for receiving payments. You can give a different one to each sender to keep track of who is paying you. The highlighted address will be displayed in the main window."), wxDefaultPosition, wxDefaultSize, 0 ); - m_staticText45->Wrap( 570 ); - bSizer681->Add( m_staticText45, 0, wxTOP|wxRIGHT|wxLEFT, 6 ); - - - bSizer681->Add( 0, 2, 0, wxEXPAND, 5 ); - - m_listCtrlReceiving = new wxListCtrl( m_panelReceiving, wxID_LISTCTRLRECEIVING, wxDefaultPosition, wxDefaultSize, wxLC_NO_SORT_HEADER|wxLC_REPORT|wxLC_SORT_ASCENDING ); - bSizer681->Add( m_listCtrlReceiving, 1, wxALL|wxEXPAND, 5 ); - - m_panelReceiving->SetSizer( bSizer681 ); - m_panelReceiving->Layout(); - bSizer681->Fit( m_panelReceiving ); - m_notebook->AddPage( m_panelReceiving, _("Receiving"), true ); - - bSizer58->Add( m_notebook, 1, wxEXPAND|wxTOP|wxRIGHT|wxLEFT, 5 ); - - wxBoxSizer* bSizer69; - bSizer69 = new wxBoxSizer( wxHORIZONTAL ); - - - bSizer69->Add( 0, 0, 1, wxEXPAND, 5 ); - - m_buttonDelete = new wxButton( this, wxID_BUTTONDELETE, _("&Delete"), wxDefaultPosition, wxDefaultSize, 0 ); - bSizer69->Add( m_buttonDelete, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); - - m_buttonCopy = new wxButton( this, wxID_BUTTONCOPY, _(" &Copy to Clipboard "), wxDefaultPosition, wxSize( -1,-1 ), 0 ); - bSizer69->Add( m_buttonCopy, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); - - m_buttonEdit = new wxButton( this, wxID_BUTTONEDIT, _("&Edit..."), wxDefaultPosition, wxDefaultSize, 0 ); - bSizer69->Add( m_buttonEdit, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); - - m_buttonNew = new wxButton( this, wxID_BUTTONNEW, _(" &New Address... "), wxDefaultPosition, wxDefaultSize, 0 ); - bSizer69->Add( m_buttonNew, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); - - m_buttonOK = new wxButton( this, wxID_OK, _("OK"), wxDefaultPosition, wxSize( -1,-1 ), 0 ); - bSizer69->Add( m_buttonOK, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); - - m_buttonCancel = new wxButton( this, wxID_CANCEL, _("Cancel"), wxDefaultPosition, wxSize( -1,-1 ), 0 ); - bSizer69->Add( m_buttonCancel, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); - - bSizer58->Add( bSizer69, 0, wxEXPAND, 5 ); - - this->SetSizer( bSizer58 ); - this->Layout(); - - // Connect Events - this->Connect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( CAddressBookDialogBase::OnClose ) ); - m_notebook->Connect( wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGED, wxNotebookEventHandler( CAddressBookDialogBase::OnNotebookPageChanged ), NULL, this ); - m_listCtrlSending->Connect( wxEVT_COMMAND_LIST_END_LABEL_EDIT, wxListEventHandler( CAddressBookDialogBase::OnListEndLabelEdit ), NULL, this ); - m_listCtrlSending->Connect( wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler( CAddressBookDialogBase::OnListItemActivated ), NULL, this ); - m_listCtrlSending->Connect( wxEVT_COMMAND_LIST_ITEM_SELECTED, wxListEventHandler( CAddressBookDialogBase::OnListItemSelected ), NULL, this ); - m_listCtrlReceiving->Connect( wxEVT_COMMAND_LIST_END_LABEL_EDIT, wxListEventHandler( CAddressBookDialogBase::OnListEndLabelEdit ), NULL, this ); - m_listCtrlReceiving->Connect( wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler( CAddressBookDialogBase::OnListItemActivated ), NULL, this ); - m_listCtrlReceiving->Connect( wxEVT_COMMAND_LIST_ITEM_SELECTED, wxListEventHandler( CAddressBookDialogBase::OnListItemSelected ), NULL, this ); - m_buttonDelete->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CAddressBookDialogBase::OnButtonDelete ), NULL, this ); - m_buttonCopy->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CAddressBookDialogBase::OnButtonCopy ), NULL, this ); - m_buttonEdit->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CAddressBookDialogBase::OnButtonEdit ), NULL, this ); - m_buttonNew->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CAddressBookDialogBase::OnButtonNew ), NULL, this ); - m_buttonOK->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CAddressBookDialogBase::OnButtonOK ), NULL, this ); - m_buttonCancel->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CAddressBookDialogBase::OnButtonCancel ), NULL, this ); -} - -CAddressBookDialogBase::~CAddressBookDialogBase() -{ - // Disconnect Events - this->Disconnect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( CAddressBookDialogBase::OnClose ) ); - m_notebook->Disconnect( wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGED, wxNotebookEventHandler( CAddressBookDialogBase::OnNotebookPageChanged ), NULL, this ); - m_listCtrlSending->Disconnect( wxEVT_COMMAND_LIST_END_LABEL_EDIT, wxListEventHandler( CAddressBookDialogBase::OnListEndLabelEdit ), NULL, this ); - m_listCtrlSending->Disconnect( wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler( CAddressBookDialogBase::OnListItemActivated ), NULL, this ); - m_listCtrlSending->Disconnect( wxEVT_COMMAND_LIST_ITEM_SELECTED, wxListEventHandler( CAddressBookDialogBase::OnListItemSelected ), NULL, this ); - m_listCtrlReceiving->Disconnect( wxEVT_COMMAND_LIST_END_LABEL_EDIT, wxListEventHandler( CAddressBookDialogBase::OnListEndLabelEdit ), NULL, this ); - m_listCtrlReceiving->Disconnect( wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler( CAddressBookDialogBase::OnListItemActivated ), NULL, this ); - m_listCtrlReceiving->Disconnect( wxEVT_COMMAND_LIST_ITEM_SELECTED, wxListEventHandler( CAddressBookDialogBase::OnListItemSelected ), NULL, this ); - m_buttonDelete->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CAddressBookDialogBase::OnButtonDelete ), NULL, this ); - m_buttonCopy->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CAddressBookDialogBase::OnButtonCopy ), NULL, this ); - m_buttonEdit->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CAddressBookDialogBase::OnButtonEdit ), NULL, this ); - m_buttonNew->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CAddressBookDialogBase::OnButtonNew ), NULL, this ); - m_buttonOK->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CAddressBookDialogBase::OnButtonOK ), NULL, this ); - m_buttonCancel->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CAddressBookDialogBase::OnButtonCancel ), NULL, this ); -} - -CGetTextFromUserDialogBase::CGetTextFromUserDialogBase( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : wxDialog( parent, id, title, pos, size, style ) -{ - this->SetSizeHints( wxDefaultSize, wxDefaultSize ); - - wxBoxSizer* bSizer79; - bSizer79 = new wxBoxSizer( wxVERTICAL ); - - wxBoxSizer* bSizer81; - bSizer81 = new wxBoxSizer( wxVERTICAL ); - - - bSizer81->Add( 0, 0, 1, wxEXPAND, 5 ); - - m_staticTextMessage1 = new wxStaticText( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); - m_staticTextMessage1->Wrap( -1 ); - bSizer81->Add( m_staticTextMessage1, 0, wxTOP|wxRIGHT|wxLEFT, 5 ); - - m_textCtrl1 = new wxTextCtrl( this, wxID_TEXTCTRL, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_PROCESS_ENTER ); - bSizer81->Add( m_textCtrl1, 0, wxALL|wxEXPAND|wxALIGN_CENTER_HORIZONTAL, 5 ); - - m_staticTextMessage2 = new wxStaticText( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); - m_staticTextMessage2->Wrap( -1 ); - m_staticTextMessage2->Hide(); - - bSizer81->Add( m_staticTextMessage2, 0, wxTOP|wxRIGHT|wxLEFT, 5 ); - - m_textCtrl2 = new wxTextCtrl( this, wxID_TEXTCTRL, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_PROCESS_ENTER ); - m_textCtrl2->Hide(); - - bSizer81->Add( m_textCtrl2, 0, wxALL|wxEXPAND|wxALIGN_CENTER_HORIZONTAL, 5 ); - - - bSizer81->Add( 0, 0, 1, wxEXPAND, 5 ); - - bSizer79->Add( bSizer81, 1, wxEXPAND|wxALL, 10 ); - - wxBoxSizer* bSizer80; - bSizer80 = new wxBoxSizer( wxHORIZONTAL ); - - - bSizer80->Add( 0, 0, 1, wxEXPAND, 5 ); - - m_buttonOK = new wxButton( this, wxID_OK, _("OK"), wxDefaultPosition, wxSize( -1,-1 ), 0 ); - bSizer80->Add( m_buttonOK, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); - - m_buttonCancel = new wxButton( this, wxID_CANCEL, _("Cancel"), wxDefaultPosition, wxDefaultSize, 0 ); - bSizer80->Add( m_buttonCancel, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); - - bSizer79->Add( bSizer80, 0, wxEXPAND, 5 ); - - this->SetSizer( bSizer79 ); - this->Layout(); - - // Connect Events - this->Connect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( CGetTextFromUserDialogBase::OnClose ) ); - m_textCtrl1->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CGetTextFromUserDialogBase::OnKeyDown ), NULL, this ); - m_textCtrl2->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CGetTextFromUserDialogBase::OnKeyDown ), NULL, this ); - m_buttonOK->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CGetTextFromUserDialogBase::OnButtonOK ), NULL, this ); - m_buttonCancel->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CGetTextFromUserDialogBase::OnButtonCancel ), NULL, this ); -} - -CGetTextFromUserDialogBase::~CGetTextFromUserDialogBase() -{ - // Disconnect Events - this->Disconnect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( CGetTextFromUserDialogBase::OnClose ) ); - m_textCtrl1->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CGetTextFromUserDialogBase::OnKeyDown ), NULL, this ); - m_textCtrl2->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CGetTextFromUserDialogBase::OnKeyDown ), NULL, this ); - m_buttonOK->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CGetTextFromUserDialogBase::OnButtonOK ), NULL, this ); - m_buttonCancel->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CGetTextFromUserDialogBase::OnButtonCancel ), NULL, this ); -} diff --git a/src/uibase.h b/src/uibase.h deleted file mode 100644 index 78f3d1b385..0000000000 --- a/src/uibase.h +++ /dev/null @@ -1,421 +0,0 @@ -/////////////////////////////////////////////////////////////////////////// -// C++ code generated with wxFormBuilder (version Dec 21 2009) -// http://www.wxformbuilder.org/ -// -// PLEASE DO "NOT" EDIT THIS FILE! -/////////////////////////////////////////////////////////////////////////// - -#ifndef __uibase__ -#define __uibase__ - -#include <wx/intl.h> - -#include <wx/string.h> -#include <wx/bitmap.h> -#include <wx/image.h> -#include <wx/icon.h> -#include <wx/menu.h> -#include <wx/gdicmn.h> -#include <wx/font.h> -#include <wx/colour.h> -#include <wx/settings.h> -#include <wx/toolbar.h> -#include <wx/statusbr.h> -#include <wx/stattext.h> -#include <wx/textctrl.h> -#include <wx/button.h> -#include <wx/sizer.h> -#include <wx/choice.h> -#include <wx/listctrl.h> -#include <wx/panel.h> -#include <wx/notebook.h> -#include <wx/frame.h> -#include <wx/html/htmlwin.h> -#include <wx/dialog.h> -#include <wx/listbox.h> -#include <wx/checkbox.h> -#include <wx/scrolwin.h> -#include <wx/statbmp.h> - -/////////////////////////////////////////////////////////////////////////// - -#define wxID_MAINFRAME 1000 -#define wxID_BUTTONSEND 1001 -#define wxID_BUTTONRECEIVE 1002 -#define wxID_TEXTCTRLADDRESS 1003 -#define wxID_BUTTONNEW 1004 -#define wxID_BUTTONCOPY 1005 -#define wxID_PROXYIP 1006 -#define wxID_PROXYPORT 1007 -#define wxID_TRANSACTIONFEE 1008 -#define wxID_TEXTCTRLPAYTO 1009 -#define wxID_BUTTONPASTE 1010 -#define wxID_BUTTONADDRESSBOOK 1011 -#define wxID_TEXTCTRLAMOUNT 1012 -#define wxID_CHOICETRANSFERTYPE 1013 -#define wxID_LISTCTRL 1014 -#define wxID_BUTTONRENAME 1015 -#define wxID_PANELSENDING 1016 -#define wxID_LISTCTRLSENDING 1017 -#define wxID_PANELRECEIVING 1018 -#define wxID_LISTCTRLRECEIVING 1019 -#define wxID_BUTTONDELETE 1020 -#define wxID_BUTTONEDIT 1021 -#define wxID_TEXTCTRL 1022 - -/////////////////////////////////////////////////////////////////////////////// -/// Class CMainFrameBase -/////////////////////////////////////////////////////////////////////////////// -class CMainFrameBase : public wxFrame -{ - private: - - protected: - wxMenuBar* m_menubar; - wxMenu* m_menuFile; - wxMenu* m_menuHelp; - wxToolBar* m_toolBar; - - wxStaticText* m_staticText32; - wxButton* m_buttonNew; - wxButton* m_buttonCopy; - - wxStaticText* m_staticText41; - wxStaticText* m_staticTextBalance; - - wxChoice* m_choiceFilter; - wxNotebook* m_notebook; - wxPanel* m_panel9; - wxPanel* m_panel91; - wxPanel* m_panel92; - wxPanel* m_panel93; - - // Virtual event handlers, overide them in your derived class - virtual void OnClose( wxCloseEvent& event ) { event.Skip(); } - virtual void OnIconize( wxIconizeEvent& event ) { event.Skip(); } - virtual void OnIdle( wxIdleEvent& event ) { event.Skip(); } - virtual void OnMouseEvents( wxMouseEvent& event ) { event.Skip(); } - virtual void OnPaint( wxPaintEvent& event ) { event.Skip(); } - virtual void OnMenuFileExit( wxCommandEvent& event ) { event.Skip(); } - virtual void OnMenuOptionsChangeYourAddress( wxCommandEvent& event ) { event.Skip(); } - virtual void OnMenuOptionsOptions( wxCommandEvent& event ) { event.Skip(); } - virtual void OnMenuHelpAbout( wxCommandEvent& event ) { event.Skip(); } - virtual void OnButtonSend( wxCommandEvent& event ) { event.Skip(); } - virtual void OnButtonAddressBook( wxCommandEvent& event ) { event.Skip(); } - virtual void OnKeyDown( wxKeyEvent& event ) { event.Skip(); } - virtual void OnMouseEventsAddress( wxMouseEvent& event ) { event.Skip(); } - virtual void OnSetFocusAddress( wxFocusEvent& event ) { event.Skip(); } - virtual void OnButtonNew( wxCommandEvent& event ) { event.Skip(); } - virtual void OnButtonCopy( wxCommandEvent& event ) { event.Skip(); } - virtual void OnNotebookPageChanged( wxNotebookEvent& event ) { event.Skip(); } - virtual void OnListColBeginDrag( wxListEvent& event ) { event.Skip(); } - virtual void OnListItemActivated( wxListEvent& event ) { event.Skip(); } - virtual void OnPaintListCtrl( wxPaintEvent& event ) { event.Skip(); } - - - public: - wxMenu* m_menuOptions; - wxStatusBar* m_statusBar; - wxTextCtrl* m_textCtrlAddress; - wxListCtrl* m_listCtrlAll; - wxListCtrl* m_listCtrlSentReceived; - wxListCtrl* m_listCtrlSent; - wxListCtrl* m_listCtrlReceived; - - CMainFrameBase( wxWindow* parent, wxWindowID id = wxID_MAINFRAME, const wxString& title = _("Bitcoin"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 723,484 ), long style = wxDEFAULT_FRAME_STYLE|wxRESIZE_BORDER|wxTAB_TRAVERSAL ); - ~CMainFrameBase(); - -}; - -/////////////////////////////////////////////////////////////////////////////// -/// Class CTxDetailsDialogBase -/////////////////////////////////////////////////////////////////////////////// -class CTxDetailsDialogBase : public wxDialog -{ - private: - - protected: - wxHtmlWindow* m_htmlWin; - wxButton* m_buttonOK; - - // Virtual event handlers, overide them in your derived class - virtual void OnButtonOK( wxCommandEvent& event ) { event.Skip(); } - - - public: - - CTxDetailsDialogBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Transaction Details"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 620,450 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER ); - ~CTxDetailsDialogBase(); - -}; - -/////////////////////////////////////////////////////////////////////////////// -/// Class COptionsDialogBase -/////////////////////////////////////////////////////////////////////////////// -class COptionsDialogBase : public wxDialog -{ - private: - - protected: - wxListBox* m_listBox; - wxScrolledWindow* m_scrolledWindow; - wxPanel* m_panelMain; - - wxCheckBox* m_checkBoxStartOnSystemStartup; - wxCheckBox* m_checkBoxMinimizeToTray; - wxCheckBox* m_checkBoxUseUPnP; - wxCheckBox* m_checkBoxMinimizeOnClose; - wxCheckBox* m_checkBoxUseProxy; - - wxStaticText* m_staticTextProxyIP; - wxTextCtrl* m_textCtrlProxyIP; - wxStaticText* m_staticTextProxyPort; - wxTextCtrl* m_textCtrlProxyPort; - - wxStaticText* m_staticText32; - wxStaticText* m_staticText31; - wxTextCtrl* m_textCtrlTransactionFee; - wxPanel* m_panelTest2; - - wxStaticText* m_staticText321; - wxStaticText* m_staticText69; - wxButton* m_buttonOK; - wxButton* m_buttonCancel; - wxButton* m_buttonApply; - - // Virtual event handlers, overide them in your derived class - virtual void OnListBox( wxCommandEvent& event ) { event.Skip(); } - virtual void OnCheckBoxMinimizeToTray( wxCommandEvent& event ) { event.Skip(); } - virtual void OnCheckBoxUseProxy( wxCommandEvent& event ) { event.Skip(); } - virtual void OnKillFocusProxy( wxFocusEvent& event ) { event.Skip(); } - virtual void OnKillFocusTransactionFee( wxFocusEvent& event ) { event.Skip(); } - virtual void OnButtonOK( wxCommandEvent& event ) { event.Skip(); } - virtual void OnButtonCancel( wxCommandEvent& event ) { event.Skip(); } - virtual void OnButtonApply( wxCommandEvent& event ) { event.Skip(); } - - - public: - - COptionsDialogBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Options"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 540,360 ), long style = wxDEFAULT_DIALOG_STYLE ); - ~COptionsDialogBase(); - -}; - -/////////////////////////////////////////////////////////////////////////////// -/// Class CAboutDialogBase -/////////////////////////////////////////////////////////////////////////////// -class CAboutDialogBase : public wxDialog -{ - private: - - protected: - wxStaticBitmap* m_bitmap; - - wxStaticText* m_staticText40; - - wxStaticText* m_staticTextMain; - - - wxButton* m_buttonOK; - - // Virtual event handlers, overide them in your derived class - virtual void OnButtonOK( wxCommandEvent& event ) { event.Skip(); } - - - public: - wxStaticText* m_staticTextVersion; - - CAboutDialogBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("About Bitcoin"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 532,333 ), long style = wxDEFAULT_DIALOG_STYLE ); - ~CAboutDialogBase(); - -}; - -/////////////////////////////////////////////////////////////////////////////// -/// Class CSendDialogBase -/////////////////////////////////////////////////////////////////////////////// -class CSendDialogBase : public wxDialog -{ - private: - - protected: - - - wxStaticText* m_staticTextInstructions; - - wxStaticBitmap* m_bitmapCheckMark; - wxStaticText* m_staticText36; - wxTextCtrl* m_textCtrlAddress; - wxButton* m_buttonPaste; - wxButton* m_buttonAddress; - wxStaticText* m_staticText19; - wxTextCtrl* m_textCtrlAmount; - wxStaticText* m_staticText20; - wxChoice* m_choiceTransferType; - - - - wxButton* m_buttonSend; - wxButton* m_buttonCancel; - - // Virtual event handlers, overide them in your derived class - virtual void OnKeyDown( wxKeyEvent& event ) { event.Skip(); } - virtual void OnTextAddress( wxCommandEvent& event ) { event.Skip(); } - virtual void OnButtonPaste( wxCommandEvent& event ) { event.Skip(); } - virtual void OnButtonAddressBook( wxCommandEvent& event ) { event.Skip(); } - virtual void OnKillFocusAmount( wxFocusEvent& event ) { event.Skip(); } - virtual void OnButtonSend( wxCommandEvent& event ) { event.Skip(); } - virtual void OnButtonCancel( wxCommandEvent& event ) { event.Skip(); } - - - public: - - CSendDialogBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Send Coins"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 498,157 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER ); - ~CSendDialogBase(); - -}; - -/////////////////////////////////////////////////////////////////////////////// -/// Class CSendingDialogBase -/////////////////////////////////////////////////////////////////////////////// -class CSendingDialogBase : public wxDialog -{ - private: - - protected: - wxStaticText* m_staticTextSending; - wxTextCtrl* m_textCtrlStatus; - - wxButton* m_buttonOK; - wxButton* m_buttonCancel; - - // Virtual event handlers, overide them in your derived class - virtual void OnClose( wxCloseEvent& event ) { event.Skip(); } - virtual void OnPaint( wxPaintEvent& event ) { event.Skip(); } - virtual void OnButtonOK( wxCommandEvent& event ) { event.Skip(); } - virtual void OnButtonCancel( wxCommandEvent& event ) { event.Skip(); } - - - public: - - CSendingDialogBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Sending..."), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 442,151 ), long style = wxDEFAULT_DIALOG_STYLE ); - ~CSendingDialogBase(); - -}; - -/////////////////////////////////////////////////////////////////////////////// -/// Class CYourAddressDialogBase -/////////////////////////////////////////////////////////////////////////////// -class CYourAddressDialogBase : public wxDialog -{ - private: - - protected: - - wxStaticText* m_staticText45; - wxListCtrl* m_listCtrl; - - wxButton* m_buttonRename; - wxButton* m_buttonNew; - wxButton* m_buttonCopy; - wxButton* m_buttonOK; - wxButton* m_buttonCancel; - - // Virtual event handlers, overide them in your derived class - virtual void OnClose( wxCloseEvent& event ) { event.Skip(); } - virtual void OnListEndLabelEdit( wxListEvent& event ) { event.Skip(); } - virtual void OnListItemActivated( wxListEvent& event ) { event.Skip(); } - virtual void OnListItemSelected( wxListEvent& event ) { event.Skip(); } - virtual void OnButtonRename( wxCommandEvent& event ) { event.Skip(); } - virtual void OnButtonNew( wxCommandEvent& event ) { event.Skip(); } - virtual void OnButtonCopy( wxCommandEvent& event ) { event.Skip(); } - virtual void OnButtonOK( wxCommandEvent& event ) { event.Skip(); } - virtual void OnButtonCancel( wxCommandEvent& event ) { event.Skip(); } - - - public: - - CYourAddressDialogBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Your Bitcoin Addresses"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 610,390 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER ); - ~CYourAddressDialogBase(); - -}; - -/////////////////////////////////////////////////////////////////////////////// -/// Class CAddressBookDialogBase -/////////////////////////////////////////////////////////////////////////////// -class CAddressBookDialogBase : public wxDialog -{ - private: - - protected: - wxNotebook* m_notebook; - wxPanel* m_panelSending; - - wxStaticText* m_staticText55; - wxListCtrl* m_listCtrlSending; - wxPanel* m_panelReceiving; - - wxStaticText* m_staticText45; - - wxListCtrl* m_listCtrlReceiving; - - wxButton* m_buttonDelete; - wxButton* m_buttonCopy; - wxButton* m_buttonEdit; - wxButton* m_buttonNew; - wxButton* m_buttonOK; - - // Virtual event handlers, overide them in your derived class - virtual void OnClose( wxCloseEvent& event ) { event.Skip(); } - virtual void OnNotebookPageChanged( wxNotebookEvent& event ) { event.Skip(); } - virtual void OnListEndLabelEdit( wxListEvent& event ) { event.Skip(); } - virtual void OnListItemActivated( wxListEvent& event ) { event.Skip(); } - virtual void OnListItemSelected( wxListEvent& event ) { event.Skip(); } - virtual void OnButtonDelete( wxCommandEvent& event ) { event.Skip(); } - virtual void OnButtonCopy( wxCommandEvent& event ) { event.Skip(); } - virtual void OnButtonEdit( wxCommandEvent& event ) { event.Skip(); } - virtual void OnButtonNew( wxCommandEvent& event ) { event.Skip(); } - virtual void OnButtonOK( wxCommandEvent& event ) { event.Skip(); } - virtual void OnButtonCancel( wxCommandEvent& event ) { event.Skip(); } - - - public: - wxButton* m_buttonCancel; - - CAddressBookDialogBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Address Book"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 610,390 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER ); - ~CAddressBookDialogBase(); - -}; - -/////////////////////////////////////////////////////////////////////////////// -/// Class CGetTextFromUserDialogBase -/////////////////////////////////////////////////////////////////////////////// -class CGetTextFromUserDialogBase : public wxDialog -{ - private: - - protected: - - wxStaticText* m_staticTextMessage1; - wxTextCtrl* m_textCtrl1; - wxStaticText* m_staticTextMessage2; - wxTextCtrl* m_textCtrl2; - - - wxButton* m_buttonOK; - wxButton* m_buttonCancel; - - // Virtual event handlers, overide them in your derived class - virtual void OnClose( wxCloseEvent& event ) { event.Skip(); } - virtual void OnKeyDown( wxKeyEvent& event ) { event.Skip(); } - virtual void OnButtonOK( wxCommandEvent& event ) { event.Skip(); } - virtual void OnButtonCancel( wxCommandEvent& event ) { event.Skip(); } - - - public: - - CGetTextFromUserDialogBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxEmptyString, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 440,138 ), long style = wxDEFAULT_DIALOG_STYLE ); - ~CGetTextFromUserDialogBase(); - -}; - -#endif //__uibase__ diff --git a/src/uint256.h b/src/uint256.h index 14feb1683d..3e20201387 100644 --- a/src/uint256.h +++ b/src/uint256.h @@ -1,4 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto +// Copyright (c) 2011 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. #ifndef BITCOIN_UINT256_H diff --git a/src/util.cpp b/src/util.cpp index 479c601ee5..02e2d21491 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -1,4 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto +// Copyright (c) 2011 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. #include "headers.h" @@ -263,8 +264,7 @@ int my_snprintf(char* buffer, size_t limit, const char* format, ...) return ret; } - -string strprintf(const char* format, ...) +string strprintf(const std::string &format, ...) { char buffer[50000]; char* p = buffer; @@ -274,7 +274,7 @@ string strprintf(const char* format, ...) { va_list arg_ptr; va_start(arg_ptr, format); - ret = _vsnprintf(p, limit, format, arg_ptr); + ret = _vsnprintf(p, limit, format.c_str(), arg_ptr); va_end(arg_ptr); if (ret >= 0 && ret < limit) break; @@ -291,14 +291,13 @@ string strprintf(const char* format, ...) return str; } - -bool error(const char* format, ...) +bool error(const std::string &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); + int ret = _vsnprintf(buffer, limit, format.c_str(), arg_ptr); va_end(arg_ptr); if (ret < 0 || ret >= limit) { @@ -388,7 +387,7 @@ bool ParseMoney(const char* pszIn, int64& nRet) for (; *p; p++) if (!isspace(*p)) return false; - if (strWhole.size() > 14) + if (strWhole.size() > 10) // guard against 63 bit overflow return false; if (nUnits < 0 || nUnits > COIN) return false; @@ -444,7 +443,6 @@ vector<unsigned char> ParseHex(const string& str) return ParseHex(str.c_str()); } - void ParseParameters(int argc, char* argv[]) { mapArgs.clear(); @@ -471,39 +469,144 @@ void ParseParameters(int argc, char* argv[]) } } - -const char* wxGetTranslation(const char* pszEnglish) +string EncodeBase64(const unsigned char* pch, size_t len) { -#ifdef GUI - // Wrapper of wxGetTranslation returning the same const char* type as was passed in - static CCriticalSection cs; - CRITICAL_BLOCK(cs) + static const char *pbase64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + + string strRet=""; + strRet.reserve((len+2)/3*4); + + int mode=0, left=0; + const unsigned char *pchEnd = pch+len; + + while (pch<pchEnd) + { + int enc = *(pch++); + switch (mode) + { + case 0: // we have no bits + strRet += pbase64[enc >> 2]; + left = (enc & 3) << 4; + mode = 1; + break; + + case 1: // we have two bits + strRet += pbase64[left | (enc >> 4)]; + left = (enc & 15) << 2; + mode = 2; + break; + + case 2: // we have four bits + strRet += pbase64[left | (enc >> 6)]; + strRet += pbase64[enc & 63]; + mode = 0; + break; + } + } + + if (mode) { - // Look in cache - static map<string, char*> mapCache; - map<string, char*>::iterator mi = mapCache.find(pszEnglish); - if (mi != mapCache.end()) - return (*mi).second; + strRet += pbase64[left]; + strRet += '='; + if (mode == 1) + strRet += '='; + } - // wxWidgets translation - wxString strTranslated = wxGetTranslation(wxString(pszEnglish, wxConvUTF8)); + return strRet; +} - // We don't cache unknown strings because caller might be passing in a - // dynamic string and we would keep allocating memory for each variation. - if (strcmp(pszEnglish, strTranslated.utf8_str()) == 0) - return pszEnglish; +string EncodeBase64(const string& str) +{ + return EncodeBase64((const unsigned char*)str.c_str(), str.size()); +} - // Add to cache, memory doesn't need to be freed. We only cache because - // we must pass back a pointer to permanently allocated memory. - char* pszCached = new char[strlen(strTranslated.utf8_str())+1]; - strcpy(pszCached, strTranslated.utf8_str()); - mapCache[pszEnglish] = pszCached; - return pszCached; +vector<unsigned char> DecodeBase64(const char* p, bool* pfInvalid) +{ + static const int decode64_table[256] = + { + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 62, -1, -1, -1, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, + -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, -1, 26, 27, 28, + 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, + 49, 50, 51, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 + }; + + if (pfInvalid) + *pfInvalid = false; + + vector<unsigned char> vchRet; + vchRet.reserve(strlen(p)*3/4); + + int mode = 0; + int left = 0; + + while (1) + { + int dec = decode64_table[*p]; + if (dec == -1) break; + p++; + switch (mode) + { + case 0: // we have no bits and get 6 + left = dec; + mode = 1; + break; + + case 1: // we have 6 bits and keep 4 + vchRet.push_back((left<<2) | (dec>>4)); + left = dec & 15; + mode = 2; + break; + + case 2: // we have 4 bits and get 6, we keep 2 + vchRet.push_back((left<<4) | (dec>>2)); + left = dec & 3; + mode = 3; + break; + + case 3: // we have 2 bits and get 6 + vchRet.push_back((left<<6) | dec); + mode = 0; + break; + } } - return NULL; -#else - return pszEnglish; -#endif + + if (pfInvalid) + switch (mode) + { + case 0: // 4n base64 characters processed: ok + break; + + case 1: // 4n+1 base64 character processed: impossible + *pfInvalid = true; + break; + + case 2: // 4n+2 base64 characters processed: require '==' + if (left || p[0] != '=' || p[1] != '=' || decode64_table[p[2]] != -1) + *pfInvalid = true; + break; + + case 3: // 4n+3 base64 characters processed: require '=' + if (left || p[0] != '=' || decode64_table[p[1]] != -1) + *pfInvalid = true; + break; + } + + return vchRet; +} + +string DecodeBase64(const string& str) +{ + vector<unsigned char> vchRet = DecodeBase64(str.c_str()); + return string((const char*)&vchRet[0], vchRet.size()); } @@ -574,10 +677,6 @@ void PrintException(std::exception* pex, const char* pszThread) printf("\n\n************************\n%s\n", pszMessage); fprintf(stderr, "\n\n************************\n%s\n", pszMessage); strMiscWarning = pszMessage; -#ifdef GUI - if (wxTheApp && !fDaemon) - MyMessageBox(pszMessage, "Bitcoin", wxOK | wxICON_ERROR); -#endif throw; } @@ -599,10 +698,6 @@ void PrintExceptionContinue(std::exception* pex, const char* pszThread) printf("\n\n************************\n%s\n", pszMessage); fprintf(stderr, "\n\n************************\n%s\n", pszMessage); strMiscWarning = pszMessage; -#ifdef GUI - if (wxTheApp && !fDaemon) - boost::thread(boost::bind(ThreadOneMessageBox, string(pszMessage))); -#endif } @@ -760,8 +855,8 @@ string GetPidFile() void CreatePidFile(string pidFile, pid_t pid) { - FILE* file; - if (file = fopen(pidFile.c_str(), "w")) + FILE* file = fopen(pidFile.c_str(), "w"); + if (file) { fprintf(file, "%d\n", pid); fclose(file); @@ -790,7 +885,9 @@ void ShrinkDebugFile() fseek(file, -sizeof(pch), SEEK_END); int nBytes = fread(pch, 1, sizeof(pch), file); fclose(file); - if (file = fopen(strFile.c_str(), "w")) + + file = fopen(strFile.c_str(), "w"); + if (file) { fwrite(pch, 1, nBytes, file); fclose(file); @@ -812,11 +909,20 @@ void ShrinkDebugFile() // - Median of other nodes's clocks // - The user (asking the user to fix the system clock if the first two disagree) // +static int64 nMockTime = 0; // For unit testing + int64 GetTime() { + if (nMockTime) return nMockTime; + return time(NULL); } +void SetMockTime(int64 nMockTimeIn) +{ + nMockTime = nMockTimeIn; +} + static int64 nTimeOffset = 0; int64 GetAdjustedTime() @@ -906,4 +1012,140 @@ string FormatFullVersion() +#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<CCriticalSection*, CLockLocation> > LockStack; + +static boost::interprocess::interprocess_mutex dd_mutex; +static std::map<std::pair<CCriticalSection*, CCriticalSection*>, LockStack> lockorders; +static boost::thread_specific_ptr<LockStack> lockstack; + + +static void potential_deadlock_detected(const std::pair<CCriticalSection*, CCriticalSection*>& mismatch, const LockStack& s1, const LockStack& s2) +{ + printf("POTENTIAL DEADLOCK DETECTED\n"); + printf("Previous lock order was:\n"); + BOOST_FOREACH(const PAIRTYPE(CCriticalSection*, 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(CCriticalSection*, 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(CCriticalSection* c, const CLockLocation& locklocation) +{ + 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)); + + BOOST_FOREACH(const PAIRTYPE(CCriticalSection*, CLockLocation)& i, (*lockstack)) + { + if (i.first == c) break; + + std::pair<CCriticalSection*, CCriticalSection*> p1 = std::make_pair(i.first, c); + if (lockorders.count(p1)) + continue; + lockorders[p1] = (*lockstack); + + std::pair<CCriticalSection*, CCriticalSection*> 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 CCriticalSection::Enter(const char* pszName, const char* pszFile, int nLine) +{ + push_lock(this, CLockLocation(pszName, pszFile, nLine)); + mutex.lock(); +} +void CCriticalSection::Leave() +{ + mutex.unlock(); + pop_lock(); +} +bool CCriticalSection::TryEnter(const char* pszName, const char* pszFile, int nLine) +{ + push_lock(this, CLockLocation(pszName, pszFile, nLine)); + bool result = mutex.try_lock(); + if (!result) pop_lock(); + return result; +} + +#else + +void CCriticalSection::Enter(const char*, const char*, int) +{ + mutex.lock(); +} + +void CCriticalSection::Leave() +{ + mutex.unlock(); +} + +bool CCriticalSection::TryEnter(const char*, const char*, int) +{ + bool result = mutex.try_lock(); + return result; +} +#endif /* DEBUG_LOCKORDER */ diff --git a/src/util.h b/src/util.h index e7110570c6..c05143bece 100644 --- a/src/util.h +++ b/src/util.h @@ -1,4 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto +// Copyright (c) 2011 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. #ifndef BITCOIN_UTIL_H @@ -64,15 +65,7 @@ typedef unsigned long long uint64; #endif // This is needed because the foreach macro can't get over the comma in pair<t1, t2> -#define PAIRTYPE(t1, t2) pair<t1, t2> - -// Used to bypass the rule against non-const reference to temporary -// where it makes sense with wrappers such as CFlatData or CTxDB -template<typename T> -inline T& REF(const T& val) -{ - return (T&)val; -} +#define PAIRTYPE(t1, t2) std::pair<t1, t2> // Align by increasing pointer, must have extra space at end of buffer template <size_t nBytes, typename T> @@ -139,8 +132,7 @@ inline int myclosesocket(SOCKET& hSocket) return ret; } #define closesocket(s) myclosesocket(s) - -#ifndef GUI +#if !defined(QT_GUI) inline const char* _(const char* psz) { return psz; @@ -155,7 +147,6 @@ inline const char* _(const char* psz) - extern std::map<std::string, std::string> mapArgs; extern std::map<std::string, std::vector<std::string> > mapMultiArgs; extern bool fDebug; @@ -176,8 +167,8 @@ void RandAddSeed(); void RandAddSeedPerfmon(); int OutputDebugStringF(const char* pszFormat, ...); int my_snprintf(char* buffer, size_t limit, const char* format, ...); -std::string strprintf(const char* format, ...); -bool error(const char* format, ...); +std::string strprintf(const std::string &format, ...); +bool error(const std::string &format, ...); void LogException(std::exception* pex, const char* pszThread); void PrintException(std::exception* pex, const char* pszThread); void PrintExceptionContinue(std::exception* pex, const char* pszThread); @@ -187,6 +178,10 @@ bool ParseMoney(const std::string& str, int64& nRet); bool ParseMoney(const char* pszIn, int64& nRet); std::vector<unsigned char> ParseHex(const char* psz); std::vector<unsigned char> ParseHex(const std::string& str); +std::vector<unsigned char> DecodeBase64(const char* p, bool* pfInvalid = NULL); +std::string DecodeBase64(const std::string& str); +std::string EncodeBase64(const unsigned char* pch, size_t len); +std::string EncodeBase64(const std::string& str); void ParseParameters(int argc, char* argv[]); const char* wxGetTranslation(const char* psz); bool WildcardMatch(const char* psz, const char* mask); @@ -206,6 +201,7 @@ void ShrinkDebugFile(); int GetRandInt(int nMax); uint64 GetRand(uint64 nMax); int64 GetTime(); +void SetMockTime(int64 nMockTimeIn); int64 GetAdjustedTime(); void AddTimeData(unsigned int ip, int64 nTime); std::string FormatFullVersion(); @@ -222,31 +218,17 @@ std::string FormatFullVersion(); -// Wrapper to automatically initialize critical sections +// Wrapper to automatically initialize mutex class CCriticalSection { -#ifdef __WXMSW__ -protected: - CRITICAL_SECTION cs; -public: - explicit CCriticalSection() { InitializeCriticalSection(&cs); } - ~CCriticalSection() { DeleteCriticalSection(&cs); } - void Enter() { EnterCriticalSection(&cs); } - void Leave() { LeaveCriticalSection(&cs); } - bool TryEnter() { return TryEnterCriticalSection(&cs); } -#else protected: boost::interprocess::interprocess_recursive_mutex mutex; public: explicit CCriticalSection() { } ~CCriticalSection() { } - void Enter() { mutex.lock(); } - void Leave() { mutex.unlock(); } - bool TryEnter() { return mutex.try_lock(); } -#endif -public: - const char* pszFile; - int nLine; + void Enter(const char* pszName, const char* pszFile, int nLine); + void Leave(); + bool TryEnter(const char* pszName, const char* pszFile, int nLine); }; // Automatically leave critical section when leaving block, needed for exception safety @@ -254,9 +236,17 @@ class CCriticalBlock { protected: CCriticalSection* pcs; + public: - CCriticalBlock(CCriticalSection& csIn) { pcs = &csIn; pcs->Enter(); } - ~CCriticalBlock() { pcs->Leave(); } + CCriticalBlock(CCriticalSection& csIn, const char* pszName, const char* pszFile, int nLine) + { + pcs = &csIn; + pcs->Enter(pszName, pszFile, nLine); + } + ~CCriticalBlock() + { + pcs->Leave(); + } }; // WARNING: This will catch continue and break! @@ -264,22 +254,32 @@ public: // I'd rather be careful than suffer the other more error prone syntax. // The compiler will optimise away all this loop junk. #define CRITICAL_BLOCK(cs) \ - for (bool fcriticalblockonce=true; fcriticalblockonce; assert(("break caught by CRITICAL_BLOCK!", !fcriticalblockonce)), fcriticalblockonce=false) \ - for (CCriticalBlock criticalblock(cs); fcriticalblockonce && (cs.pszFile=__FILE__, cs.nLine=__LINE__, true); fcriticalblockonce=false, cs.pszFile=NULL, cs.nLine=0) + for (bool fcriticalblockonce=true; fcriticalblockonce; assert(("break caught by CRITICAL_BLOCK!" && !fcriticalblockonce)), fcriticalblockonce=false) \ + for (CCriticalBlock criticalblock(cs, #cs, __FILE__, __LINE__); fcriticalblockonce; fcriticalblockonce=false) class CTryCriticalBlock { protected: CCriticalSection* pcs; + public: - CTryCriticalBlock(CCriticalSection& csIn) { pcs = (csIn.TryEnter() ? &csIn : NULL); } - ~CTryCriticalBlock() { if (pcs) pcs->Leave(); } + CTryCriticalBlock(CCriticalSection& csIn, const char* pszName, const char* pszFile, int nLine) + { + pcs = (csIn.TryEnter(pszName, pszFile, nLine) ? &csIn : NULL); + } + ~CTryCriticalBlock() + { + if (pcs) + { + pcs->Leave(); + } + } bool Entered() { return pcs != NULL; } }; #define TRY_CRITICAL_BLOCK(cs) \ - for (bool fcriticalblockonce=true; fcriticalblockonce; assert(("break caught by TRY_CRITICAL_BLOCK!", !fcriticalblockonce)), fcriticalblockonce=false) \ - for (CTryCriticalBlock criticalblock(cs); fcriticalblockonce && (fcriticalblockonce = criticalblock.Entered()) && (cs.pszFile=__FILE__, cs.nLine=__LINE__, true); fcriticalblockonce=false, cs.pszFile=NULL, cs.nLine=0) + for (bool fcriticalblockonce=true; fcriticalblockonce; assert(("break caught by TRY_CRITICAL_BLOCK!" && !fcriticalblockonce)), fcriticalblockonce=false) \ + for (CTryCriticalBlock criticalblock(cs, #cs, __FILE__, __LINE__); fcriticalblockonce && (fcriticalblockonce = criticalblock.Entered()); fcriticalblockonce=false) @@ -570,6 +570,51 @@ inline uint160 Hash160(const std::vector<unsigned char>& vch) } +// Median filter over a stream of values +// Returns the median of the last N numbers +template <typename T> class CMedianFilter +{ +private: + std::vector<T> vValues; + std::vector<T> vSorted; + int nSize; +public: + CMedianFilter(int size, T initial_value): + nSize(size) + { + vValues.reserve(size); + vValues.push_back(initial_value); + vSorted = vValues; + } + + void input(T value) + { + if(vValues.size() == nSize) + { + vValues.erase(vValues.begin()); + } + vValues.push_back(value); + + vSorted.resize(vValues.size()); + std::copy(vValues.begin(), vValues.end(), vSorted.begin()); + std::sort(vSorted.begin(), vSorted.end()); + } + + T median() const + { + int size = vSorted.size(); + assert(size>0); + if(size & 1) // Odd number of elements + { + return vSorted[size/2]; + } + else // Even number of elements + { + return (vSorted[size/2-1] + vSorted[size/2]) / 2; + } + } +}; + @@ -623,7 +668,10 @@ inline pthread_t CreateThread(void(*pfn)(void*), void* parg, bool fWantHandle=fa return (pthread_t)0; } if (!fWantHandle) + { + pthread_detach(hthread); return (pthread_t)-1; + } return hthread; } @@ -648,7 +696,7 @@ inline bool TerminateThread(pthread_t hthread, unsigned int nExitCode) return (pthread_cancel(hthread) == 0); } -inline void ExitThread(unsigned int nExitCode) +inline void ExitThread(size_t nExitCode) { pthread_exit((void*)nExitCode); } @@ -678,4 +726,10 @@ inline bool AffinityBugWorkaround(void(*pfn)(void*)) return false; } +inline uint32_t ByteReverse(uint32_t value) +{ + value = ((value & 0xFF00FF00) >> 8) | ((value & 0x00FF00FF) << 8); + return (value<<16) | (value>>16); +} + #endif diff --git a/src/wallet.cpp b/src/wallet.cpp index 6ef75ef27f..30a561dcb4 100644 --- a/src/wallet.cpp +++ b/src/wallet.cpp @@ -1,15 +1,15 @@ -// Copyright (c) 2009-2011 Satoshi Nakamoto & Bitcoin developers +// Copyright (c) 2009-2010 Satoshi Nakamoto +// Copyright (c) 2011 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. #include "headers.h" #include "db.h" -#include "cryptopp/sha.h" +#include "crypter.h" using namespace std; - ////////////////////////////////////////////////////////////////////////////// // // mapWallet @@ -17,10 +17,178 @@ using namespace std; bool CWallet::AddKey(const CKey& key) { - this->CKeyStore::AddKey(key); + if (!CCryptoKeyStore::AddKey(key)) + return false; + if (!fFileBacked) + return true; + if (!IsCrypted()) + return CWalletDB(strWalletFile).WriteKey(key.GetPubKey(), key.GetPrivKey()); + return true; +} + +bool CWallet::AddCryptedKey(const vector<unsigned char> &vchPubKey, const vector<unsigned char> &vchCryptedSecret) +{ + if (!CCryptoKeyStore::AddCryptedKey(vchPubKey, vchCryptedSecret)) + return false; if (!fFileBacked) return true; - return CWalletDB(strWalletFile).WriteKey(key.GetPubKey(), key.GetPrivKey()); + CRITICAL_BLOCK(cs_wallet) + { + if (pwalletdbEncryption) + return pwalletdbEncryption->WriteCryptedKey(vchPubKey, vchCryptedSecret); + else + return CWalletDB(strWalletFile).WriteCryptedKey(vchPubKey, vchCryptedSecret); + } +} + +bool CWallet::Unlock(const string& strWalletPassphrase) +{ + if (!IsLocked()) + return false; + + CCrypter crypter; + CKeyingMaterial vMasterKey; + + CRITICAL_BLOCK(cs_wallet) + BOOST_FOREACH(const MasterKeyMap::value_type& pMasterKey, mapMasterKeys) + { + if(!crypter.SetKeyFromPassphrase(strWalletPassphrase, pMasterKey.second.vchSalt, pMasterKey.second.nDeriveIterations, pMasterKey.second.nDerivationMethod)) + return false; + if (!crypter.Decrypt(pMasterKey.second.vchCryptedKey, vMasterKey)) + return false; + if (CCryptoKeyStore::Unlock(vMasterKey)) + return true; + } + return false; +} + +bool CWallet::ChangeWalletPassphrase(const string& strOldWalletPassphrase, const string& strNewWalletPassphrase) +{ + bool fWasLocked = IsLocked(); + + CRITICAL_BLOCK(cs_wallet) + { + Lock(); + + CCrypter crypter; + CKeyingMaterial vMasterKey; + BOOST_FOREACH(MasterKeyMap::value_type& pMasterKey, mapMasterKeys) + { + if(!crypter.SetKeyFromPassphrase(strOldWalletPassphrase, pMasterKey.second.vchSalt, pMasterKey.second.nDeriveIterations, pMasterKey.second.nDerivationMethod)) + return false; + if (!crypter.Decrypt(pMasterKey.second.vchCryptedKey, vMasterKey)) + return false; + if (CCryptoKeyStore::Unlock(vMasterKey)) + { + int64 nStartTime = GetTimeMillis(); + crypter.SetKeyFromPassphrase(strNewWalletPassphrase, pMasterKey.second.vchSalt, pMasterKey.second.nDeriveIterations, pMasterKey.second.nDerivationMethod); + pMasterKey.second.nDeriveIterations = pMasterKey.second.nDeriveIterations * (100 / ((double)(GetTimeMillis() - nStartTime))); + + nStartTime = GetTimeMillis(); + crypter.SetKeyFromPassphrase(strNewWalletPassphrase, pMasterKey.second.vchSalt, pMasterKey.second.nDeriveIterations, pMasterKey.second.nDerivationMethod); + pMasterKey.second.nDeriveIterations = (pMasterKey.second.nDeriveIterations + pMasterKey.second.nDeriveIterations * 100 / ((double)(GetTimeMillis() - nStartTime))) / 2; + + if (pMasterKey.second.nDeriveIterations < 25000) + pMasterKey.second.nDeriveIterations = 25000; + + printf("Wallet passphrase changed to an nDeriveIterations of %i\n", pMasterKey.second.nDeriveIterations); + + if (!crypter.SetKeyFromPassphrase(strNewWalletPassphrase, pMasterKey.second.vchSalt, pMasterKey.second.nDeriveIterations, pMasterKey.second.nDerivationMethod)) + return false; + if (!crypter.Encrypt(vMasterKey, pMasterKey.second.vchCryptedKey)) + return false; + CWalletDB(strWalletFile).WriteMasterKey(pMasterKey.first, pMasterKey.second); + if (fWasLocked) + Lock(); + return true; + } + } + } + + return false; +} + + +// This class implements an addrIncoming entry that causes pre-0.4 +// clients to crash on startup if reading a private-key-encrypted wallet. +class CCorruptAddress +{ +public: + IMPLEMENT_SERIALIZE + ( + if (nType & SER_DISK) + READWRITE(nVersion); + ) +}; + +bool CWallet::EncryptWallet(const string& strWalletPassphrase) +{ + if (IsCrypted()) + return false; + + CKeyingMaterial vMasterKey; + RandAddSeedPerfmon(); + + vMasterKey.resize(WALLET_CRYPTO_KEY_SIZE); + RAND_bytes(&vMasterKey[0], WALLET_CRYPTO_KEY_SIZE); + + CMasterKey kMasterKey; + + RandAddSeedPerfmon(); + kMasterKey.vchSalt.resize(WALLET_CRYPTO_SALT_SIZE); + RAND_bytes(&kMasterKey.vchSalt[0], WALLET_CRYPTO_SALT_SIZE); + + CCrypter crypter; + int64 nStartTime = GetTimeMillis(); + crypter.SetKeyFromPassphrase(strWalletPassphrase, kMasterKey.vchSalt, 25000, kMasterKey.nDerivationMethod); + kMasterKey.nDeriveIterations = 2500000 / ((double)(GetTimeMillis() - nStartTime)); + + nStartTime = GetTimeMillis(); + crypter.SetKeyFromPassphrase(strWalletPassphrase, kMasterKey.vchSalt, kMasterKey.nDeriveIterations, kMasterKey.nDerivationMethod); + kMasterKey.nDeriveIterations = (kMasterKey.nDeriveIterations + kMasterKey.nDeriveIterations * 100 / ((double)(GetTimeMillis() - nStartTime))) / 2; + + if (kMasterKey.nDeriveIterations < 25000) + kMasterKey.nDeriveIterations = 25000; + + printf("Encrypting Wallet with an nDeriveIterations of %i\n", kMasterKey.nDeriveIterations); + + if (!crypter.SetKeyFromPassphrase(strWalletPassphrase, kMasterKey.vchSalt, kMasterKey.nDeriveIterations, kMasterKey.nDerivationMethod)) + return false; + if (!crypter.Encrypt(vMasterKey, kMasterKey.vchCryptedKey)) + return false; + + CRITICAL_BLOCK(cs_wallet) + { + mapMasterKeys[++nMasterKeyMaxID] = kMasterKey; + if (fFileBacked) + { + pwalletdbEncryption = new CWalletDB(strWalletFile); + pwalletdbEncryption->TxnBegin(); + pwalletdbEncryption->WriteMasterKey(nMasterKeyMaxID, kMasterKey); + } + + if (!EncryptKeys(vMasterKey)) + { + if (fFileBacked) + pwalletdbEncryption->TxnAbort(); + exit(1); //We now probably have half of our keys encrypted in memory, and half not...die and let the user reload their unencrypted wallet. + } + + if (fFileBacked) + { + CCorruptAddress corruptAddress; + pwalletdbEncryption->WriteSetting("addrIncoming", corruptAddress); + if (!pwalletdbEncryption->TxnCommit()) + exit(1); //We now have keys encrypted in memory, but no on disk...die to avoid confusion and let the user reload their unencrypted wallet. + + pwalletdbEncryption->Close(); + pwalletdbEncryption = NULL; + } + + Lock(); + } + + return true; } void CWallet::WalletUpdateSpent(const CTransaction &tx) @@ -28,7 +196,7 @@ void CWallet::WalletUpdateSpent(const CTransaction &tx) // Anytime a signature is successfully verified, it's proof the outpoint is spent. // Update the wallet spent flag if it doesn't know due to wallet.dat being // restored from backup or the user making copies of wallet.dat. - CRITICAL_BLOCK(cs_mapWallet) + CRITICAL_BLOCK(cs_wallet) { BOOST_FOREACH(const CTxIn& txin, tx.vin) { @@ -51,7 +219,7 @@ void CWallet::WalletUpdateSpent(const CTransaction &tx) bool CWallet::AddToWallet(const CWalletTx& wtxIn) { uint256 hash = wtxIn.GetHash(); - CRITICAL_BLOCK(cs_mapWallet) + CRITICAL_BLOCK(cs_wallet) { // Inserts only if not already there, returns tx inserted or tx found pair<map<uint256, CWalletTx>::iterator, bool> ret = mapWallet.insert(make_pair(hash, wtxIn)); @@ -91,16 +259,23 @@ bool CWallet::AddToWallet(const CWalletTx& wtxIn) if (fInsertedNew || fUpdated) if (!wtx.WriteToDisk()) return false; - +#ifndef QT_GUI // If default receiving address gets used, replace it with a new one CScript scriptDefaultKey; scriptDefaultKey.SetBitcoinAddress(vchDefaultKey); BOOST_FOREACH(const CTxOut& txout, wtx.vout) { if (txout.scriptPubKey == scriptDefaultKey) - SetDefaultKey(GetKeyFromKeyPool()); + { + std::vector<unsigned char> newDefaultKey; + if (GetKeyFromPool(newDefaultKey, false)) + { + SetDefaultKey(newDefaultKey); + SetAddressBookName(CBitcoinAddress(vchDefaultKey), ""); + } + } } - +#endif // Notify UI vWalletUpdated.push_back(hash); @@ -116,18 +291,21 @@ bool CWallet::AddToWallet(const CWalletTx& wtxIn) bool CWallet::AddToWalletIfInvolvingMe(const CTransaction& tx, const CBlock* pblock, bool fUpdate) { uint256 hash = tx.GetHash(); - bool fExisted = mapWallet.count(hash); - if (fExisted && !fUpdate) return false; - if (fExisted || IsMine(tx) || IsFromMe(tx)) + CRITICAL_BLOCK(cs_wallet) { - CWalletTx wtx(this,tx); - // Get merkle branch if transaction was found in a block - if (pblock) - wtx.SetMerkleBranch(pblock); - return AddToWallet(wtx); + bool fExisted = mapWallet.count(hash); + if (fExisted && !fUpdate) return false; + if (fExisted || IsMine(tx) || IsFromMe(tx)) + { + CWalletTx wtx(this,tx); + // Get merkle branch if transaction was found in a block + if (pblock) + wtx.SetMerkleBranch(pblock); + return AddToWallet(wtx); + } + else + WalletUpdateSpent(tx); } - else - WalletUpdateSpent(tx); return false; } @@ -135,7 +313,7 @@ bool CWallet::EraseFromWallet(uint256 hash) { if (!fFileBacked) return false; - CRITICAL_BLOCK(cs_mapWallet) + CRITICAL_BLOCK(cs_wallet) { if (mapWallet.erase(hash)) CWalletDB(strWalletFile).EraseTx(hash); @@ -146,7 +324,7 @@ bool CWallet::EraseFromWallet(uint256 hash) bool CWallet::IsMine(const CTxIn &txin) const { - CRITICAL_BLOCK(cs_mapWallet) + CRITICAL_BLOCK(cs_wallet) { map<uint256, CWalletTx>::const_iterator mi = mapWallet.find(txin.prevout.hash); if (mi != mapWallet.end()) @@ -162,7 +340,7 @@ bool CWallet::IsMine(const CTxIn &txin) const int64 CWallet::GetDebit(const CTxIn &txin) const { - CRITICAL_BLOCK(cs_mapWallet) + CRITICAL_BLOCK(cs_wallet) { map<uint256, CWalletTx>::const_iterator mi = mapWallet.find(txin.prevout.hash); if (mi != mapWallet.end()) @@ -178,19 +356,6 @@ int64 CWallet::GetDebit(const CTxIn &txin) const int64 CWalletTx::GetTxTime() const { - if (!fTimeReceivedIsTxTime && hashBlock != 0) - { - // If we did not receive the transaction directly, we rely on the block's - // time to figure out when it happened. We use the median over a range - // of blocks to try to filter out inaccurate block times. - map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hashBlock); - if (mi != mapBlockIndex.end()) - { - CBlockIndex* pindex = (*mi).second; - if (pindex) - return pindex->GetMedianTime(); - } - } return nTimeReceived; } @@ -198,7 +363,7 @@ int CWalletTx::GetRequestCount() const { // Returns -1 if it wasn't being tracked int nRequests = -1; - CRITICAL_BLOCK(pwallet->cs_mapRequestCount) + CRITICAL_BLOCK(pwallet->cs_wallet) { if (IsCoinBase()) { @@ -233,8 +398,8 @@ int CWalletTx::GetRequestCount() const return nRequests; } -void CWalletTx::GetAmounts(int64& nGeneratedImmature, int64& nGeneratedMature, list<pair<string, int64> >& listReceived, - list<pair<string, int64> >& listSent, int64& nFee, string& strSentAccount) const +void CWalletTx::GetAmounts(int64& nGeneratedImmature, int64& nGeneratedMature, list<pair<CBitcoinAddress, int64> >& listReceived, + list<pair<CBitcoinAddress, int64> >& listSent, int64& nFee, string& strSentAccount) const { nGeneratedImmature = nGeneratedMature = nFee = 0; listReceived.clear(); @@ -262,14 +427,9 @@ void CWalletTx::GetAmounts(int64& nGeneratedImmature, int64& nGeneratedMature, l // but non-standard clients might (so return a list of address/amount pairs) BOOST_FOREACH(const CTxOut& txout, vout) { - string address; - uint160 hash160; + CBitcoinAddress address; vector<unsigned char> vchPubKey; - if (ExtractHash160(txout.scriptPubKey, hash160)) - address = Hash160ToAddress(hash160); - else if (ExtractPubKey(txout.scriptPubKey, NULL, vchPubKey)) - address = PubKeyToAddress(vchPubKey); - else + if (!ExtractAddress(txout.scriptPubKey, NULL, address)) { printf("CWalletTx::GetAmounts: Unknown transaction type found, txid %s\n", this->GetHash().ToString().c_str()); @@ -297,25 +457,25 @@ void CWalletTx::GetAccountAmounts(const string& strAccount, int64& nGenerated, i int64 allGeneratedImmature, allGeneratedMature, allFee; allGeneratedImmature = allGeneratedMature = allFee = 0; string strSentAccount; - list<pair<string, int64> > listReceived; - list<pair<string, int64> > listSent; + list<pair<CBitcoinAddress, int64> > listReceived; + list<pair<CBitcoinAddress, int64> > listSent; GetAmounts(allGeneratedImmature, allGeneratedMature, listReceived, listSent, allFee, strSentAccount); if (strAccount == "") nGenerated = allGeneratedMature; if (strAccount == strSentAccount) { - BOOST_FOREACH(const PAIRTYPE(string,int64)& s, listSent) + BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress,int64)& s, listSent) nSent += s.second; nFee = allFee; } - CRITICAL_BLOCK(pwallet->cs_mapAddressBook) + CRITICAL_BLOCK(pwallet->cs_wallet) { - BOOST_FOREACH(const PAIRTYPE(string,int64)& r, listReceived) + BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress,int64)& r, listReceived) { if (pwallet->mapAddressBook.count(r.first)) { - map<string, string>::const_iterator mi = pwallet->mapAddressBook.find(r.first); + map<CBitcoinAddress, string>::const_iterator mi = pwallet->mapAddressBook.find(r.first); if (mi != pwallet->mapAddressBook.end() && (*mi).second == strAccount) nReceived += r.second; } @@ -339,7 +499,7 @@ void CWalletTx::AddSupportingTransactions(CTxDB& txdb) vWorkQueue.push_back(txin.prevout.hash); // This critsect is OK because txdb is already open - CRITICAL_BLOCK(pwallet->cs_mapWallet) + CRITICAL_BLOCK(pwallet->cs_wallet) { map<uint256, const CMerkleTx*> mapWalletPrev; set<uint256> setAlreadyDone; @@ -395,7 +555,7 @@ int CWallet::ScanForWalletTransactions(CBlockIndex* pindexStart, bool fUpdate) int ret = 0; CBlockIndex* pindex = pindexStart; - CRITICAL_BLOCK(cs_mapWallet) + CRITICAL_BLOCK(cs_wallet) { while (pindex) { @@ -416,7 +576,7 @@ void CWallet::ReacceptWalletTransactions() { CTxDB txdb("r"); bool fRepeat = true; - while (fRepeat) CRITICAL_BLOCK(cs_mapWallet) + while (fRepeat) CRITICAL_BLOCK(cs_wallet) { fRepeat = false; vector<CDiskTxPos> vMissingTx; @@ -519,7 +679,7 @@ void CWallet::ResendWalletTransactions() // Rebroadcast any of our txes that aren't in a block yet printf("ResendWalletTransactions()\n"); CTxDB txdb("r"); - CRITICAL_BLOCK(cs_mapWallet) + CRITICAL_BLOCK(cs_wallet) { // Sort them in chronological order multimap<unsigned int, CWalletTx*> mapSorted; @@ -552,10 +712,8 @@ void CWallet::ResendWalletTransactions() int64 CWallet::GetBalance() const { - int64 nStart = GetTimeMillis(); - int64 nTotal = 0; - CRITICAL_BLOCK(cs_mapWallet) + CRITICAL_BLOCK(cs_wallet) { for (map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it) { @@ -566,10 +724,24 @@ int64 CWallet::GetBalance() const } } - //printf("GetBalance() %"PRI64d"ms\n", GetTimeMillis() - nStart); return nTotal; } +int64 CWallet::GetUnconfirmedBalance() const +{ + int64 nTotal = 0; + CRITICAL_BLOCK(cs_wallet) + { + for (map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it) + { + const CWalletTx* pcoin = &(*it).second; + if (pcoin->IsFinal() && pcoin->IsConfirmed()) + continue; + nTotal += pcoin->GetAvailableCredit(); + } + } + return nTotal; +} bool CWallet::SelectCoinsMinConf(int64 nTargetValue, int nConfMine, int nConfTheirs, set<pair<const CWalletTx*,unsigned int> >& setCoinsRet, int64& nValueRet) const { @@ -583,7 +755,7 @@ bool CWallet::SelectCoinsMinConf(int64 nTargetValue, int nConfMine, int nConfThe vector<pair<int64, pair<const CWalletTx*,unsigned int> > > vValue; int64 nTotalLower = 0; - CRITICAL_BLOCK(cs_mapWallet) + CRITICAL_BLOCK(cs_wallet) { vector<const CWalletTx*> vCoins; vCoins.reserve(mapWallet.size()); @@ -741,10 +913,10 @@ bool CWallet::CreateTransaction(const vector<pair<CScript, int64> >& vecSend, CW wtxNew.pwallet = this; CRITICAL_BLOCK(cs_main) + CRITICAL_BLOCK(cs_wallet) { // txdb must be opened before the mapWallet lock CTxDB txdb("r"); - CRITICAL_BLOCK(cs_mapWallet) { nFeeRet = nTransactionFee; loop @@ -770,9 +942,17 @@ bool CWallet::CreateTransaction(const vector<pair<CScript, int64> >& vecSend, CW dPriority += (double)nCredit * pcoin.first->GetDepthInMainChain(); } - // Fill a vout back to self with any change - int64 nChange = nValueIn - nTotalValue; - if (nChange >= CENT) + int64 nChange = nValueIn - nValue - nFeeRet; + // if sub-cent change is required, the fee must be raised to at least MIN_TX_FEE + // or until nChange becomes zero + if (nFeeRet < MIN_TX_FEE && nChange > 0 && nChange < CENT) + { + int64 nMoveToFee = min(nChange, MIN_TX_FEE - nFeeRet); + nChange -= nMoveToFee; + nFeeRet += nMoveToFee; + } + + if (nChange > 0) { // Note: We use a new key here to keep it from being obvious which side is the change. // The drawback is that by not reusing a previous key, the change may be lost if a @@ -783,11 +963,11 @@ bool CWallet::CreateTransaction(const vector<pair<CScript, int64> >& vecSend, CW // Reserve a new key pair from key pool vector<unsigned char> vchPubKey = reservekey.GetReservedKey(); - assert(mapKeys.count(vchPubKey)); + // assert(mapKeys.count(vchPubKey)); // Fill a vout to ourself, using same address type as the payment CScript scriptChange; - if (vecSend[0].first.GetBitcoinAddressHash160() != 0) + if (vecSend[0].first.GetBitcoinAddress().IsValid()) scriptChange.SetBitcoinAddress(vchPubKey); else scriptChange << vchPubKey << OP_CHECKSIG; @@ -847,9 +1027,9 @@ bool CWallet::CreateTransaction(CScript scriptPubKey, int64 nValue, CWalletTx& w bool CWallet::CommitTransaction(CWalletTx& wtxNew, CReserveKey& reservekey) { CRITICAL_BLOCK(cs_main) + CRITICAL_BLOCK(cs_wallet) { printf("CommitTransaction:\n%s", wtxNew.ToString().c_str()); - CRITICAL_BLOCK(cs_mapWallet) { // This is only to keep the database open to defeat the auto-flush for the // duration of this scope. This is the only place where this optimization @@ -879,8 +1059,7 @@ bool CWallet::CommitTransaction(CWalletTx& wtxNew, CReserveKey& reservekey) } // Track how many getdata requests our transaction gets - CRITICAL_BLOCK(cs_mapRequestCount) - mapRequestCount[wtxNew.GetHash()] = 0; + mapRequestCount[wtxNew.GetHash()] = 0; // Broadcast if (!wtxNew.AcceptToMemoryPool()) @@ -898,11 +1077,17 @@ bool CWallet::CommitTransaction(CWalletTx& wtxNew, CReserveKey& reservekey) -// requires cs_main lock string CWallet::SendMoney(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew, bool fAskFee) { CReserveKey reservekey(this); int64 nFeeRequired; + + if (IsLocked()) + { + string strError = _("Error: Wallet locked, unable to create transaction "); + printf("SendMoney() : %s", strError.c_str()); + return strError; + } if (!CreateTransaction(scriptPubKey, nValue, wtxNew, reservekey, nFeeRequired)) { string strError; @@ -926,8 +1111,7 @@ string CWallet::SendMoney(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew, -// requires cs_main lock -string CWallet::SendMoneyToBitcoinAddress(string strAddress, int64 nValue, CWalletTx& wtxNew, bool fAskFee) +string CWallet::SendMoneyToBitcoinAddress(const CBitcoinAddress& address, int64 nValue, CWalletTx& wtxNew, bool fAskFee) { // Check amount if (nValue <= 0) @@ -937,8 +1121,7 @@ string CWallet::SendMoneyToBitcoinAddress(string strAddress, int64 nValue, CWall // Parse bitcoin address CScript scriptPubKey; - if (!scriptPubKey.SetBitcoinAddress(strAddress)) - return _("Invalid bitcoin address"); + scriptPubKey.SetBitcoinAddress(address); return SendMoney(scriptPubKey, nValue, wtxNew, fAskFee); } @@ -946,50 +1129,54 @@ string CWallet::SendMoneyToBitcoinAddress(string strAddress, int64 nValue, CWall -bool CWallet::LoadWallet(bool& fFirstRunRet) +int CWallet::LoadWallet(bool& fFirstRunRet) { if (!fFileBacked) return false; fFirstRunRet = false; - if (!CWalletDB(strWalletFile,"cr+").LoadWallet(this)) - return false; + int nLoadWalletRet = CWalletDB(strWalletFile,"cr+").LoadWallet(this); + if (nLoadWalletRet != DB_LOAD_OK) + return nLoadWalletRet; fFirstRunRet = vchDefaultKey.empty(); - if (!mapKeys.count(vchDefaultKey)) + if (!HaveKey(Hash160(vchDefaultKey))) { - // Create new default key + // Create new keyUser and set as default key RandAddSeedPerfmon(); - SetDefaultKey(GetKeyFromKeyPool()); - if (!SetAddressBookName(PubKeyToAddress(vchDefaultKey), "")) - return false; + std::vector<unsigned char> newDefaultKey; + if (!GetKeyFromPool(newDefaultKey, false)) + return DB_LOAD_FAIL; + SetDefaultKey(newDefaultKey); + if (!SetAddressBookName(CBitcoinAddress(vchDefaultKey), "")) + return DB_LOAD_FAIL; } CreateThread(ThreadFlushWalletDB, &strWalletFile); - return true; + return DB_LOAD_OK; } -bool CWallet::SetAddressBookName(const string& strAddress, const string& strName) +bool CWallet::SetAddressBookName(const CBitcoinAddress& address, const string& strName) { - mapAddressBook[strAddress] = strName; + mapAddressBook[address] = strName; if (!fFileBacked) return false; - return CWalletDB(strWalletFile).WriteName(strAddress, strName); + return CWalletDB(strWalletFile).WriteName(address.ToString(), strName); } -bool CWallet::DelAddressBookName(const string& strAddress) +bool CWallet::DelAddressBookName(const CBitcoinAddress& address) { - mapAddressBook.erase(strAddress); + mapAddressBook.erase(address); if (!fFileBacked) return false; - return CWalletDB(strWalletFile).EraseName(strAddress); + return CWalletDB(strWalletFile).EraseName(address.ToString()); } void CWallet::PrintWallet(const CBlock& block) { - CRITICAL_BLOCK(cs_mapWallet) + CRITICAL_BLOCK(cs_wallet) { if (mapWallet.count(block.vtx[0].GetHash())) { @@ -1002,7 +1189,7 @@ void CWallet::PrintWallet(const CBlock& block) bool CWallet::GetTransaction(const uint256 &hashTx, CWalletTx& wtx) { - CRITICAL_BLOCK(cs_mapWallet) + CRITICAL_BLOCK(cs_wallet) { map<uint256, CWalletTx>::iterator mi = mapWallet.find(hashTx); if (mi != mapWallet.end()) @@ -1033,14 +1220,13 @@ bool GetWalletFile(CWallet* pwallet, string &strWalletFileOut) return true; } -void CWallet::ReserveKeyFromKeyPool(int64& nIndex, CKeyPool& keypool) +bool CWallet::TopUpKeyPool() { - nIndex = -1; - keypool.vchPubKey.clear(); - CRITICAL_BLOCK(cs_main) - CRITICAL_BLOCK(cs_mapWallet) - CRITICAL_BLOCK(cs_setKeyPool) + CRITICAL_BLOCK(cs_wallet) { + if (IsLocked()) + return false; + CWalletDB walletdb(strWalletFile); // Top up key pool @@ -1051,18 +1237,34 @@ void CWallet::ReserveKeyFromKeyPool(int64& nIndex, CKeyPool& keypool) if (!setKeyPool.empty()) nEnd = *(--setKeyPool.end()) + 1; if (!walletdb.WritePool(nEnd, CKeyPool(GenerateNewKey()))) - throw runtime_error("ReserveKeyFromKeyPool() : writing generated key failed"); + throw runtime_error("TopUpKeyPool() : writing generated key failed"); setKeyPool.insert(nEnd); printf("keypool added key %"PRI64d", size=%d\n", nEnd, setKeyPool.size()); } + } + return true; +} + +void CWallet::ReserveKeyFromKeyPool(int64& nIndex, CKeyPool& keypool) +{ + nIndex = -1; + keypool.vchPubKey.clear(); + CRITICAL_BLOCK(cs_wallet) + { + if (!IsLocked()) + TopUpKeyPool(); // Get the oldest key - assert(!setKeyPool.empty()); + if(setKeyPool.empty()) + return; + + CWalletDB walletdb(strWalletFile); + nIndex = *(setKeyPool.begin()); setKeyPool.erase(setKeyPool.begin()); if (!walletdb.ReadPool(nIndex, keypool)) throw runtime_error("ReserveKeyFromKeyPool() : read failed"); - if (!mapKeys.count(keypool.vchPubKey)) + if (!HaveKey(Hash160(keypool.vchPubKey))) throw runtime_error("ReserveKeyFromKeyPool() : unknown key in key pool"); assert(!keypool.vchPubKey.empty()); printf("keypool reserve %"PRI64d"\n", nIndex); @@ -1075,10 +1277,7 @@ void CWallet::KeepKey(int64 nIndex) if (fFileBacked) { CWalletDB walletdb(strWalletFile); - CRITICAL_BLOCK(cs_main) - { - walletdb.ErasePool(nIndex); - } + walletdb.ErasePool(nIndex); } printf("keypool keep %"PRI64d"\n", nIndex); } @@ -1086,18 +1285,33 @@ void CWallet::KeepKey(int64 nIndex) void CWallet::ReturnKey(int64 nIndex) { // Return to key pool - CRITICAL_BLOCK(cs_setKeyPool) + CRITICAL_BLOCK(cs_wallet) setKeyPool.insert(nIndex); printf("keypool return %"PRI64d"\n", nIndex); } -vector<unsigned char> CWallet::GetKeyFromKeyPool() +bool CWallet::GetKeyFromPool(vector<unsigned char>& result, bool fAllowReuse) { int64 nIndex = 0; CKeyPool keypool; - ReserveKeyFromKeyPool(nIndex, keypool); - KeepKey(nIndex); - return keypool.vchPubKey; + CRITICAL_BLOCK(cs_wallet) + { + ReserveKeyFromKeyPool(nIndex, keypool); + if (nIndex == -1) + { + if (fAllowReuse && !vchDefaultKey.empty()) + { + result = vchDefaultKey; + return true; + } + if (IsLocked()) return false; + result = GenerateNewKey(); + return true; + } + KeepKey(nIndex); + result = keypool.vchPubKey; + } + return true; } int64 CWallet::GetOldestKeyPoolTime() @@ -1105,6 +1319,8 @@ int64 CWallet::GetOldestKeyPoolTime() int64 nIndex = 0; CKeyPool keypool; ReserveKeyFromKeyPool(nIndex, keypool); + if (nIndex == -1) + return GetTime(); ReturnKey(nIndex); return keypool.nTime; } @@ -1115,7 +1331,13 @@ vector<unsigned char> CReserveKey::GetReservedKey() { CKeyPool keypool; pwallet->ReserveKeyFromKeyPool(nIndex, keypool); - vchPubKey = keypool.vchPubKey; + if (nIndex != -1) + vchPubKey = keypool.vchPubKey; + else + { + printf("CReserveKey::GetReservedKey(): Warning: using default key instead of a new key, top up your keypool."); + vchPubKey = pwallet->vchDefaultKey; + } } assert(!vchPubKey.empty()); return vchPubKey; diff --git a/src/wallet.h b/src/wallet.h index 7d9db97267..b6df1aa0e1 100644 --- a/src/wallet.h +++ b/src/wallet.h @@ -1,4 +1,5 @@ -// Copyright (c) 2009-2011 Satoshi Nakamoto & Bitcoin developers +// Copyright (c) 2009-2010 Satoshi Nakamoto +// Copyright (c) 2011 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. #ifndef BITCOIN_WALLET_H @@ -12,43 +13,59 @@ class CWalletTx; class CReserveKey; class CWalletDB; -class CWallet : public CKeyStore +class CWallet : public CCryptoKeyStore { private: bool SelectCoinsMinConf(int64 nTargetValue, int nConfMine, int nConfTheirs, std::set<std::pair<const CWalletTx*,unsigned int> >& setCoinsRet, int64& nValueRet) const; bool SelectCoins(int64 nTargetValue, std::set<std::pair<const CWalletTx*,unsigned int> >& setCoinsRet, int64& nValueRet) const; + CWalletDB *pwalletdbEncryption; public: + mutable CCriticalSection cs_wallet; + bool fFileBacked; std::string strWalletFile; std::set<int64> setKeyPool; - CCriticalSection cs_setKeyPool; + + typedef std::map<unsigned int, CMasterKey> MasterKeyMap; + MasterKeyMap mapMasterKeys; + unsigned int nMasterKeyMaxID; CWallet() { fFileBacked = false; + nMasterKeyMaxID = 0; + pwalletdbEncryption = NULL; } CWallet(std::string strWalletFileIn) { strWalletFile = strWalletFileIn; fFileBacked = true; + nMasterKeyMaxID = 0; + pwalletdbEncryption = NULL; } - mutable CCriticalSection cs_mapWallet; std::map<uint256, CWalletTx> mapWallet; std::vector<uint256> vWalletUpdated; std::map<uint256, int> mapRequestCount; - mutable CCriticalSection cs_mapRequestCount; - std::map<std::string, std::string> mapAddressBook; - mutable CCriticalSection cs_mapAddressBook; + std::map<CBitcoinAddress, std::string> mapAddressBook; std::vector<unsigned char> vchDefaultKey; + // keystore implementation bool AddKey(const CKey& key); + bool LoadKey(const CKey& key) { return CCryptoKeyStore::AddKey(key); } + bool AddCryptedKey(const std::vector<unsigned char> &vchPubKey, const std::vector<unsigned char> &vchCryptedSecret); + bool LoadCryptedKey(const std::vector<unsigned char> &vchPubKey, const std::vector<unsigned char> &vchCryptedSecret) { return CCryptoKeyStore::AddCryptedKey(vchPubKey, vchCryptedSecret); } + + bool Unlock(const std::string& strWalletPassphrase); + bool ChangeWalletPassphrase(const std::string& strOldWalletPassphrase, const std::string& strNewWalletPassphrase); + bool EncryptWallet(const std::string& strWalletPassphrase); + bool AddToWallet(const CWalletTx& wtxIn); bool AddToWalletIfInvolvingMe(const CTransaction& tx, const CBlock* pblock, bool fUpdate = false); bool EraseFromWallet(uint256 hash); @@ -57,17 +74,19 @@ public: void ReacceptWalletTransactions(); void ResendWalletTransactions(); int64 GetBalance() const; + int64 GetUnconfirmedBalance() const; bool CreateTransaction(const std::vector<std::pair<CScript, int64> >& vecSend, CWalletTx& wtxNew, CReserveKey& reservekey, int64& nFeeRet); bool CreateTransaction(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew, CReserveKey& reservekey, int64& nFeeRet); bool CommitTransaction(CWalletTx& wtxNew, CReserveKey& reservekey); bool BroadcastTransaction(CWalletTx& wtxNew); std::string SendMoney(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew, bool fAskFee=false); - std::string SendMoneyToBitcoinAddress(std::string strAddress, int64 nValue, CWalletTx& wtxNew, bool fAskFee=false); + std::string SendMoneyToBitcoinAddress(const CBitcoinAddress& address, int64 nValue, CWalletTx& wtxNew, bool fAskFee=false); + bool TopUpKeyPool(); void ReserveKeyFromKeyPool(int64& nIndex, CKeyPool& keypool); void KeepKey(int64 nIndex); void ReturnKey(int64 nIndex); - std::vector<unsigned char> GetKeyFromKeyPool(); + bool GetKeyFromPool(std::vector<unsigned char> &key, bool fAllowReuse=true); int64 GetOldestKeyPoolTime(); bool IsMine(const CTxIn& txin) const; @@ -84,10 +103,10 @@ public: } bool IsChange(const CTxOut& txout) const { - std::vector<unsigned char> vchPubKey; - if (ExtractPubKey(txout.scriptPubKey, this, vchPubKey)) - CRITICAL_BLOCK(cs_mapAddressBook) - if (!mapAddressBook.count(PubKeyToAddress(vchPubKey))) + CBitcoinAddress address; + if (ExtractAddress(txout.scriptPubKey, this, address)) + CRITICAL_BLOCK(cs_wallet) + if (!mapAddressBook.count(address)) return true; return false; } @@ -147,18 +166,16 @@ public: walletdb.WriteBestBlock(loc); } - bool LoadWallet(bool& fFirstRunRet); + int LoadWallet(bool& fFirstRunRet); // bool BackupWallet(const std::string& strDest); - // requires cs_mapAddressBook lock - bool SetAddressBookName(const std::string& strAddress, const std::string& strName); + bool SetAddressBookName(const CBitcoinAddress& address, const std::string& strName); - // requires cs_mapAddressBook lock - bool DelAddressBookName(const std::string& strAddress); + bool DelAddressBookName(const CBitcoinAddress& address); void UpdatedTransaction(const uint256 &hashTx) { - CRITICAL_BLOCK(cs_mapWallet) + CRITICAL_BLOCK(cs_wallet) vWalletUpdated.push_back(hashTx); } @@ -166,7 +183,7 @@ public: void Inventory(const uint256 &hash) { - CRITICAL_BLOCK(cs_mapRequestCount) + CRITICAL_BLOCK(cs_wallet) { std::map<uint256, int>::iterator mi = mapRequestCount.find(hash); if (mi != mapRequestCount.end()) @@ -174,6 +191,11 @@ public: } } + int GetKeyPoolSize() + { + return setKeyPool.size(); + } + bool GetTransaction(const uint256 &hashTx, CWalletTx& wtx); bool SetDefaultKey(const std::vector<unsigned char> &vchPubKey); @@ -439,8 +461,8 @@ public: return nChangeCached; } - void GetAmounts(int64& nGeneratedImmature, int64& nGeneratedMature, std::list<std::pair<std::string /* address */, int64> >& listReceived, - std::list<std::pair<std::string /* address */, int64> >& listSent, int64& nFee, std::string& strSentAccount) const; + void GetAmounts(int64& nGeneratedImmature, int64& nGeneratedMature, std::list<std::pair<CBitcoinAddress, int64> >& listReceived, + std::list<std::pair<CBitcoinAddress, int64> >& listSent, int64& nFee, std::string& strSentAccount) const; void GetAccountAmounts(const std::string& strAccount, int64& nGenerated, int64& nReceived, int64& nSent, int64& nFee) const; diff --git a/src/xpm/about.xpm b/src/xpm/about.xpm deleted file mode 100644 index 3fa868ca76..0000000000 --- a/src/xpm/about.xpm +++ /dev/null @@ -1,665 +0,0 @@ -// Copyright (c) 2009-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. -/* XPM */ -static const char * about_xpm[] = { -/* columns rows colors chars-per-pixel */ -"96 564 92 1", -" c #001269", -". c #000C72", -"X c #00057F", -"o c #001175", -"O c #000B6A", -"+ c #000E84", -"@ c #000489", -"# c #001583", -"$ c #001B89", -"% c #001B99", -"& c #000B92", -"* c #00208B", -"= c #002B97", -"- c #0004A6", -"; c #001DA7", -": c #0014BC", -"> c #0019BB", -", c #0017B4", -"< c #0023A3", -"1 c #002CAA", -"2 c #0030A4", -"3 c #003BA3", -"4 c #0033AB", -"5 c #003FA8", -"6 c #0027B8", -"7 c #0035BB", -"8 c #003CBA", -"9 c #004ABD", -"0 c #001DC4", -"q c #0017CC", -"w c #000CD0", -"e c #0026C7", -"r c #0035C4", -"t c #003DC5", -"y c #0032CB", -"u c #003BCC", -"i c #002BD3", -"p c #0021DC", -"a c #0025D5", -"s c #0034D5", -"d c #003ADB", -"f c #0016F6", -"g c #0008F9", -"h c #0027E3", -"j c #003CE9", -"k c #002BF5", -"l c #0024F9", -"z c #0033F4", -"x c #0035F8", -"c c #0048CA", -"v c #0055C5", -"b c #0059C3", -"n c #0053CB", -"m c #005ACC", -"M c #004FD4", -"N c #004CDC", -"B c #0047D0", -"V c #005BD6", -"C c #0049E5", -"Z c #0042EA", -"A c #0052E4", -"S c #005CE4", -"D c #0054EC", -"F c #005EEB", -"G c #004AF5", -"H c #0051F2", -"J c #005CFA", -"K c #0058F9", -"L c #0066E4", -"P c #006BE3", -"I c #0064EC", -"U c #006DEF", -"Y c #0074EB", -"T c #0078EC", -"R c #0073E7", -"E c #0065F4", -"W c #006BF5", -"Q c #006BFB", -"! c #0066FD", -"~ c #0073F5", -"^ c #007CF3", -"/ c #0075FB", -"( c #007DFC", -") c #0084FF", -"_ c #008AFF", -"` c #0092FF", -"' c #339CFF", -"] c #33A3FF", -"[ c #33AAFF", -"{ c #66B5FF", -"} c #66BBFF", -"| c #66C0FF", -/* pixels */ -"kkkkkkkkkkkk<<<<<<<<<<<<DDDDDDDDDDDDvvvvvvvvvvvv////////////))))))))))))]]]]]]]]]]]]}}}}}}}}}}}}", -"kkkkkkkkkkkk<<<<<<<<<<<<DDDDDDDDDDDDvvvvvvvvvvvv////////////))))))))))))]]]]]]]]]]]]}}}}}}}}}}}}", -"kkkkkkkkkkkk<<<<<<<<<<<<DDDDDDDDDDDDvvvvvvvvvvvv////////////))))))))))))]]]]]]]]]]]]}}}}}}}}}}}}", -"kkkkkkkkkkkk<<<<<<<<<<<<DDDDDDDDDDDDvvvvvvvvvvvv////////////))))))))))))]]]]]]]]]]]]}}}}}}}}}}}}", -"kkkkkkkkkkkk<<<<<<<<<<<<DDDDDDDDDDDDvvvvvvvvvvvv////////////))))))))))))]]]]]]]]]]]]}}}}}}}}}}}}", -"kkkkkkkkkkkk<<<<<<<<<<<<DDDDDDDDDDDDvvvvvvvvvvvv////////////))))))))))))]]]]]]]]]]]]}}}}}}}}}}}}", -"kkkkkkkkkkkk<<<<<<<<<<<<DDDDDDDDDDDDvvvvvvvvvvvv////////////))))))))))))]]]]]]]]]]]]}}}}}}}}}}}}", -"kkkkkkkkkkkk<<<<<<<<<<<<DDDDDDDDDDDDvvvvvvvvvvvv////////////))))))))))))]]]]]]]]]]]]}}}}}}}}}}}}", -"kkkkkkkkkkkk<<<<<<<<<<<<DDDDDDDDDDDDvvvvvvvvvvvv////////////))))))))))))]]]]]]]]]]]]}}}}}}}}}}}}", -"kkkkkkkkkkkk<<<<<<<<<<<<DDDDDDDDDDDDvvvvvvvvvvvv////////////))))))))))))]]]]]]]]]]]]}}}}}}}}}}}}", -"kkkkkkkkkkkk<<<<<<<<<<<<DDDDDDDDDDDDvvvvvvvvvvvv////////////))))))))))))]]]]]]]]]]]]}}}}}}}}}}}}", -"kkkkkkkkkkkk<<<<<<<<<<<<DDDDDDDDDDDDvvvvvvvvvvvv////////////))))))))))))]]]]]]]]]]]]}}}}}}}}}}}}", -"XXXXXXXXXXXXrrrrrrrrrrrr777777777777MMMMMMMMMMMM(((((((((((())))))))))))[[[[[[[[[[[[}}}}}}}}}}}}", -"XXXXXXXXXXXXrrrrrrrrrrrr777777777777MMMMMMMMMMMM(((((((((((())))))))))))[[[[[[[[[[[[}}}}}}}}}}}}", -"XXXXXXXXXXXXrrrrrrrrrrrr777777777777MMMMMMMMMMMM(((((((((((())))))))))))[[[[[[[[[[[[}}}}}}}}}}}}", -"XXXXXXXXXXXXrrrrrrrrrrrr777777777777MMMMMMMMMMMM(((((((((((())))))))))))[[[[[[[[[[[[}}}}}}}}}}}}", -"XXXXXXXXXXXXrrrrrrrrrrrr777777777777MMMMMMMMMMMM(((((((((((())))))))))))[[[[[[[[[[[[}}}}}}}}}}}}", -"XXXXXXXXXXXXrrrrrrrrrrrr777777777777MMMMMMMMMMMM(((((((((((())))))))))))[[[[[[[[[[[[}}}}}}}}}}}}", -"XXXXXXXXXXXXrrrrrrrrrrrr777777777777MMMMMMMMMMMM(((((((((((())))))))))))[[[[[[[[[[[[}}}}}}}}}}}}", -"XXXXXXXXXXXXrrrrrrrrrrrr777777777777MMMMMMMMMMMM(((((((((((())))))))))))[[[[[[[[[[[[}}}}}}}}}}}}", -"XXXXXXXXXXXXrrrrrrrrrrrr777777777777MMMMMMMMMMMM(((((((((((())))))))))))[[[[[[[[[[[[}}}}}}}}}}}}", -"XXXXXXXXXXXXrrrrrrrrrrrr777777777777MMMMMMMMMMMM(((((((((((())))))))))))[[[[[[[[[[[[}}}}}}}}}}}}", -"XXXXXXXXXXXXrrrrrrrrrrrr777777777777MMMMMMMMMMMM(((((((((((())))))))))))[[[[[[[[[[[[}}}}}}}}}}}}", -"XXXXXXXXXXXXrrrrrrrrrrrr777777777777MMMMMMMMMMMM(((((((((((())))))))))))[[[[[[[[[[[[}}}}}}}}}}}}", -"llllllllllll;;;;;;;;;;;;NNNNNNNNNNNNSSSSSSSSSSSS~~~~~~~~~~~~))))))))))))]]]]]]]]]]]]{{{{{{{{{{{{", -"llllllllllll;;;;;;;;;;;;NNNNNNNNNNNNSSSSSSSSSSSS~~~~~~~~~~~~))))))))))))]]]]]]]]]]]]{{{{{{{{{{{{", -"llllllllllll;;;;;;;;;;;;NNNNNNNNNNNNSSSSSSSSSSSS~~~~~~~~~~~~))))))))))))]]]]]]]]]]]]{{{{{{{{{{{{", -"llllllllllll;;;;;;;;;;;;NNNNNNNNNNNNSSSSSSSSSSSS~~~~~~~~~~~~))))))))))))]]]]]]]]]]]]{{{{{{{{{{{{", -"llllllllllll;;;;;;;;;;;;NNNNNNNNNNNNSSSSSSSSSSSS~~~~~~~~~~~~))))))))))))]]]]]]]]]]]]{{{{{{{{{{{{", -"llllllllllll;;;;;;;;;;;;NNNNNNNNNNNNSSSSSSSSSSSS~~~~~~~~~~~~))))))))))))]]]]]]]]]]]]{{{{{{{{{{{{", -"llllllllllll;;;;;;;;;;;;NNNNNNNNNNNNSSSSSSSSSSSS~~~~~~~~~~~~))))))))))))]]]]]]]]]]]]{{{{{{{{{{{{", -"llllllllllll;;;;;;;;;;;;NNNNNNNNNNNNSSSSSSSSSSSS~~~~~~~~~~~~))))))))))))]]]]]]]]]]]]{{{{{{{{{{{{", -"llllllllllll;;;;;;;;;;;;NNNNNNNNNNNNSSSSSSSSSSSS~~~~~~~~~~~~))))))))))))]]]]]]]]]]]]{{{{{{{{{{{{", -"llllllllllll;;;;;;;;;;;;NNNNNNNNNNNNSSSSSSSSSSSS~~~~~~~~~~~~))))))))))))]]]]]]]]]]]]{{{{{{{{{{{{", -"llllllllllll;;;;;;;;;;;;NNNNNNNNNNNNSSSSSSSSSSSS~~~~~~~~~~~~))))))))))))]]]]]]]]]]]]{{{{{{{{{{{{", -"llllllllllll;;;;;;;;;;;;NNNNNNNNNNNNSSSSSSSSSSSS~~~~~~~~~~~~))))))))))))]]]]]]]]]]]]{{{{{{{{{{{{", -"############666666666666uuuuuuuuuuuuJJJJJJJJJJJJ^^^^^^^^^^^^____________]]]]]]]]]]]]{{{{{{{{{{{{", -"############666666666666uuuuuuuuuuuuJJJJJJJJJJJJ^^^^^^^^^^^^____________]]]]]]]]]]]]{{{{{{{{{{{{", -"############666666666666uuuuuuuuuuuuJJJJJJJJJJJJ^^^^^^^^^^^^____________]]]]]]]]]]]]{{{{{{{{{{{{", -"############666666666666uuuuuuuuuuuuJJJJJJJJJJJJ^^^^^^^^^^^^____________]]]]]]]]]]]]{{{{{{{{{{{{", -"############666666666666uuuuuuuuuuuuJJJJJJJJJJJJ^^^^^^^^^^^^____________]]]]]]]]]]]]{{{{{{{{{{{{", -"############666666666666uuuuuuuuuuuuJJJJJJJJJJJJ^^^^^^^^^^^^____________]]]]]]]]]]]]{{{{{{{{{{{{", -"############666666666666uuuuuuuuuuuuJJJJJJJJJJJJ^^^^^^^^^^^^____________]]]]]]]]]]]]{{{{{{{{{{{{", -"############666666666666uuuuuuuuuuuuJJJJJJJJJJJJ^^^^^^^^^^^^____________]]]]]]]]]]]]{{{{{{{{{{{{", -"############666666666666uuuuuuuuuuuuJJJJJJJJJJJJ^^^^^^^^^^^^____________]]]]]]]]]]]]{{{{{{{{{{{{", -"############666666666666uuuuuuuuuuuuJJJJJJJJJJJJ^^^^^^^^^^^^____________]]]]]]]]]]]]{{{{{{{{{{{{", -"############666666666666uuuuuuuuuuuuJJJJJJJJJJJJ^^^^^^^^^^^^____________]]]]]]]]]]]]{{{{{{{{{{{{", -"############666666666666uuuuuuuuuuuuJJJJJJJJJJJJ^^^^^^^^^^^^____________]]]]]]]]]]]]{{{{{{{{{{{{", -"............yyyyyyyyyyyy333333333333AAAAAAAAAAAAWWWWWWWWWWWW____________[[[[[[[[[[[[{{{{{{{{{{{{", -"............yyyyyyyyyyyy333333333333AAAAAAAAAAAAWWWWWWWWWWWW____________[[[[[[[[[[[[{{{{{{{{{{{{", -"............yyyyyyyyyyyy333333333333AAAAAAAAAAAAWWWWWWWWWWWW____________[[[[[[[[[[[[{{{{{{{{{{{{", -"............yyyyyyyyyyyy333333333333AAAAAAAAAAAAWWWWWWWWWWWW____________[[[[[[[[[[[[{{{{{{{{{{{{", -"............yyyyyyyyyyyy333333333333AAAAAAAAAAAAWWWWWWWWWWWW____________[[[[[[[[[[[[{{{{{{{{{{{{", -"............yyyyyyyyyyyy333333333333AAAAAAAAAAAAWWWWWWWWWWWW____________[[[[[[[[[[[[{{{{{{{{{{{{", -"............yyyyyyyyyyyy333333333333AAAAAAAAAAAAWWWWWWWWWWWW____________[[[[[[[[[[[[{{{{{{{{{{{{", -"............yyyyyyyyyyyy333333333333AAAAAAAAAAAAWWWWWWWWWWWW____________[[[[[[[[[[[[{{{{{{{{{{{{", -"............yyyyyyyyyyyy333333333333AAAAAAAAAAAAWWWWWWWWWWWW____________[[[[[[[[[[[[{{{{{{{{{{{{", -"............yyyyyyyyyyyy333333333333AAAAAAAAAAAAWWWWWWWWWWWW____________[[[[[[[[[[[[{{{{{{{{{{{{", -"............yyyyyyyyyyyy333333333333AAAAAAAAAAAAWWWWWWWWWWWW____________[[[[[[[[[[[[{{{{{{{{{{{{", -"............yyyyyyyyyyyy333333333333AAAAAAAAAAAAWWWWWWWWWWWW____________[[[[[[[[[[[[{{{{{{{{{{{{", -"ffffffffffff============yyyyyyyyyyyyJJJJJJJJJJJJRRRRRRRRRRRR))))))))))))]]]]]]]]]]]]{{{{{{{{{{{{", -"ffffffffffff============yyyyyyyyyyyyJJJJJJJJJJJJRRRRRRRRRRRR))))))))))))]]]]]]]]]]]]{{{{{{{{{{{{", -"ffffffffffff============yyyyyyyyyyyyJJJJJJJJJJJJRRRRRRRRRRRR))))))))))))]]]]]]]]]]]]{{{{{{{{{{{{", -"ffffffffffff============yyyyyyyyyyyyJJJJJJJJJJJJRRRRRRRRRRRR))))))))))))]]]]]]]]]]]]{{{{{{{{{{{{", -"ffffffffffff============yyyyyyyyyyyyJJJJJJJJJJJJRRRRRRRRRRRR))))))))))))]]]]]]]]]]]]{{{{{{{{{{{{", -"ffffffffffff============yyyyyyyyyyyyJJJJJJJJJJJJRRRRRRRRRRRR))))))))))))]]]]]]]]]]]]{{{{{{{{{{{{", -"ffffffffffff============yyyyyyyyyyyyJJJJJJJJJJJJRRRRRRRRRRRR))))))))))))]]]]]]]]]]]]{{{{{{{{{{{{", -"ffffffffffff============yyyyyyyyyyyyJJJJJJJJJJJJRRRRRRRRRRRR))))))))))))]]]]]]]]]]]]{{{{{{{{{{{{", -"ffffffffffff============yyyyyyyyyyyyJJJJJJJJJJJJRRRRRRRRRRRR))))))))))))]]]]]]]]]]]]{{{{{{{{{{{{", -"ffffffffffff============yyyyyyyyyyyyJJJJJJJJJJJJRRRRRRRRRRRR))))))))))))]]]]]]]]]]]]{{{{{{{{{{{{", -"ffffffffffff============yyyyyyyyyyyyJJJJJJJJJJJJRRRRRRRRRRRR))))))))))))]]]]]]]]]]]]{{{{{{{{{{{{", -"ffffffffffff============yyyyyyyyyyyyJJJJJJJJJJJJRRRRRRRRRRRR))))))))))))]]]]]]]]]]]]{{{{{{{{{{{{", -"gggggggggggg$$$$$$$$$$$$uuuuuuuuuuuuNNNNNNNNNNNN~~~~~~~~~~~~))))))))))))]]]]]]]]]]]]}}}}}}}}}}}}", -"gggggggggggg$$$$$$$$$$$$uuuuuuuuuuuuNNNNNNNNNNNN~~~~~~~~~~~~))))))))))))]]]]]]]]]]]]}}}}}}}}}}}}", -"gggggggggggg$$$$$$$$$$$$uuuuuuuuuuuuNNNNNNNNNNNN~~~~~~~~~~~~))))))))))))]]]]]]]]]]]]}}}}}}}}}}}}", -"gggggggggggg$$$$$$$$$$$$uuuuuuuuuuuuNNNNNNNNNNNN~~~~~~~~~~~~))))))))))))]]]]]]]]]]]]}}}}}}}}}}}}", -"gggggggggggg$$$$$$$$$$$$uuuuuuuuuuuuNNNNNNNNNNNN~~~~~~~~~~~~))))))))))))]]]]]]]]]]]]}}}}}}}}}}}}", -"gggggggggggg$$$$$$$$$$$$uuuuuuuuuuuuNNNNNNNNNNNN~~~~~~~~~~~~))))))))))))]]]]]]]]]]]]}}}}}}}}}}}}", -"gggggggggggg$$$$$$$$$$$$uuuuuuuuuuuuNNNNNNNNNNNN~~~~~~~~~~~~))))))))))))]]]]]]]]]]]]}}}}}}}}}}}}", -"gggggggggggg$$$$$$$$$$$$uuuuuuuuuuuuNNNNNNNNNNNN~~~~~~~~~~~~))))))))))))]]]]]]]]]]]]}}}}}}}}}}}}", -"gggggggggggg$$$$$$$$$$$$uuuuuuuuuuuuNNNNNNNNNNNN~~~~~~~~~~~~))))))))))))]]]]]]]]]]]]}}}}}}}}}}}}", -"gggggggggggg$$$$$$$$$$$$uuuuuuuuuuuuNNNNNNNNNNNN~~~~~~~~~~~~))))))))))))]]]]]]]]]]]]}}}}}}}}}}}}", -"gggggggggggg$$$$$$$$$$$$uuuuuuuuuuuuNNNNNNNNNNNN~~~~~~~~~~~~))))))))))))]]]]]]]]]]]]}}}}}}}}}}}}", -"gggggggggggg$$$$$$$$$$$$uuuuuuuuuuuuNNNNNNNNNNNN~~~~~~~~~~~~))))))))))))]]]]]]]]]]]]}}}}}}}}}}}}", -"::::::::::::hhhhhhhhhhhhddddddddddddAAAAAAAAAAAAUUUUUUUUUUUU))))))))))))''''''''''''}}}}}}}}}}}}", -"::::::::::::hhhhhhhhhhhhddddddddddddAAAAAAAAAAAAUUUUUUUUUUUU))))))))))))''''''''''''}}}}}}}}}}}}", -"::::::::::::hhhhhhhhhhhhddddddddddddAAAAAAAAAAAAUUUUUUUUUUUU))))))))))))''''''''''''}}}}}}}}}}}}", -"::::::::::::hhhhhhhhhhhhddddddddddddAAAAAAAAAAAAUUUUUUUUUUUU))))))))))))''''''''''''}}}}}}}}}}}}", -"::::::::::::hhhhhhhhhhhhddddddddddddAAAAAAAAAAAAUUUUUUUUUUUU))))))))))))''''''''''''}}}}}}}}}}}}", -"::::::::::::hhhhhhhhhhhhddddddddddddAAAAAAAAAAAAUUUUUUUUUUUU))))))))))))''''''''''''}}}}}}}}}}}}", -"::::::::::::hhhhhhhhhhhhddddddddddddAAAAAAAAAAAAUUUUUUUUUUUU))))))))))))''''''''''''}}}}}}}}}}}}", -"::::::::::::hhhhhhhhhhhhddddddddddddAAAAAAAAAAAAUUUUUUUUUUUU))))))))))))''''''''''''}}}}}}}}}}}}", -"::::::::::::hhhhhhhhhhhhddddddddddddAAAAAAAAAAAAUUUUUUUUUUUU))))))))))))''''''''''''}}}}}}}}}}}}", -"::::::::::::hhhhhhhhhhhhddddddddddddAAAAAAAAAAAAUUUUUUUUUUUU))))))))))))''''''''''''}}}}}}}}}}}}", -"::::::::::::hhhhhhhhhhhhddddddddddddAAAAAAAAAAAAUUUUUUUUUUUU))))))))))))''''''''''''}}}}}}}}}}}}", -"::::::::::::hhhhhhhhhhhhddddddddddddAAAAAAAAAAAAUUUUUUUUUUUU))))))))))))''''''''''''}}}}}}}}}}}}", -"zzzzzzzzzzzzGGGGGGGGGGGGBBBBBBBBBBBBDDDDDDDDDDDDPPPPPPPPPPPP))))))))))))''''''''''''{{{{{{{{{{{{", -"zzzzzzzzzzzzGGGGGGGGGGGGBBBBBBBBBBBBDDDDDDDDDDDDPPPPPPPPPPPP))))))))))))''''''''''''{{{{{{{{{{{{", -"zzzzzzzzzzzzGGGGGGGGGGGGBBBBBBBBBBBBDDDDDDDDDDDDPPPPPPPPPPPP))))))))))))''''''''''''{{{{{{{{{{{{", -"zzzzzzzzzzzzGGGGGGGGGGGGBBBBBBBBBBBBDDDDDDDDDDDDPPPPPPPPPPPP))))))))))))''''''''''''{{{{{{{{{{{{", -"zzzzzzzzzzzzGGGGGGGGGGGGBBBBBBBBBBBBDDDDDDDDDDDDPPPPPPPPPPPP))))))))))))''''''''''''{{{{{{{{{{{{", -"zzzzzzzzzzzzGGGGGGGGGGGGBBBBBBBBBBBBDDDDDDDDDDDDPPPPPPPPPPPP))))))))))))''''''''''''{{{{{{{{{{{{", -"zzzzzzzzzzzzGGGGGGGGGGGGBBBBBBBBBBBBDDDDDDDDDDDDPPPPPPPPPPPP))))))))))))''''''''''''{{{{{{{{{{{{", -"zzzzzzzzzzzzGGGGGGGGGGGGBBBBBBBBBBBBDDDDDDDDDDDDPPPPPPPPPPPP))))))))))))''''''''''''{{{{{{{{{{{{", -"zzzzzzzzzzzzGGGGGGGGGGGGBBBBBBBBBBBBDDDDDDDDDDDDPPPPPPPPPPPP))))))))))))''''''''''''{{{{{{{{{{{{", -"zzzzzzzzzzzzGGGGGGGGGGGGBBBBBBBBBBBBDDDDDDDDDDDDPPPPPPPPPPPP))))))))))))''''''''''''{{{{{{{{{{{{", -"zzzzzzzzzzzzGGGGGGGGGGGGBBBBBBBBBBBBDDDDDDDDDDDDPPPPPPPPPPPP))))))))))))''''''''''''{{{{{{{{{{{{", -"zzzzzzzzzzzzGGGGGGGGGGGGBBBBBBBBBBBBDDDDDDDDDDDDPPPPPPPPPPPP))))))))))))''''''''''''{{{{{{{{{{{{", -"ffffffffffffssssssssssssjjjjjjjjjjjjnnnnnnnnnnnnLLLLLLLLLLLL))))))))))))''''''''''''{{{{{{{{{{{{", -"ffffffffffffssssssssssssjjjjjjjjjjjjnnnnnnnnnnnnLLLLLLLLLLLL))))))))))))''''''''''''{{{{{{{{{{{{", -"ffffffffffffssssssssssssjjjjjjjjjjjjnnnnnnnnnnnnLLLLLLLLLLLL))))))))))))''''''''''''{{{{{{{{{{{{", -"ffffffffffffssssssssssssjjjjjjjjjjjjnnnnnnnnnnnnLLLLLLLLLLLL))))))))))))''''''''''''{{{{{{{{{{{{", -"ffffffffffffssssssssssssjjjjjjjjjjjjnnnnnnnnnnnnLLLLLLLLLLLL))))))))))))''''''''''''{{{{{{{{{{{{", -"ffffffffffffssssssssssssjjjjjjjjjjjjnnnnnnnnnnnnLLLLLLLLLLLL))))))))))))''''''''''''{{{{{{{{{{{{", -"ffffffffffffssssssssssssjjjjjjjjjjjjnnnnnnnnnnnnLLLLLLLLLLLL))))))))))))''''''''''''{{{{{{{{{{{{", -"ffffffffffffssssssssssssjjjjjjjjjjjjnnnnnnnnnnnnLLLLLLLLLLLL))))))))))))''''''''''''{{{{{{{{{{{{", -"ffffffffffffssssssssssssjjjjjjjjjjjjnnnnnnnnnnnnLLLLLLLLLLLL))))))))))))''''''''''''{{{{{{{{{{{{", -"ffffffffffffssssssssssssjjjjjjjjjjjjnnnnnnnnnnnnLLLLLLLLLLLL))))))))))))''''''''''''{{{{{{{{{{{{", -"ffffffffffffssssssssssssjjjjjjjjjjjjnnnnnnnnnnnnLLLLLLLLLLLL))))))))))))''''''''''''{{{{{{{{{{{{", -"ffffffffffffssssssssssssjjjjjjjjjjjjnnnnnnnnnnnnLLLLLLLLLLLL))))))))))))''''''''''''{{{{{{{{{{{{", -"wwwwwwwwwwww<<<<<<<<<<<<888888888888VVVVVVVVVVVV~~~~~~~~~~~~((((((((((((]]]]]]]]]]]]}}}}}}}}}}}}", -"wwwwwwwwwwww<<<<<<<<<<<<888888888888VVVVVVVVVVVV~~~~~~~~~~~~((((((((((((]]]]]]]]]]]]}}}}}}}}}}}}", -"wwwwwwwwwwww<<<<<<<<<<<<888888888888VVVVVVVVVVVV~~~~~~~~~~~~((((((((((((]]]]]]]]]]]]}}}}}}}}}}}}", -"wwwwwwwwwwww<<<<<<<<<<<<888888888888VVVVVVVVVVVV~~~~~~~~~~~~((((((((((((]]]]]]]]]]]]}}}}}}}}}}}}", -"wwwwwwwwwwww<<<<<<<<<<<<888888888888VVVVVVVVVVVV~~~~~~~~~~~~((((((((((((]]]]]]]]]]]]}}}}}}}}}}}}", -"wwwwwwwwwwww<<<<<<<<<<<<888888888888VVVVVVVVVVVV~~~~~~~~~~~~((((((((((((]]]]]]]]]]]]}}}}}}}}}}}}", -"wwwwwwwwwwww<<<<<<<<<<<<888888888888VVVVVVVVVVVV~~~~~~~~~~~~((((((((((((]]]]]]]]]]]]}}}}}}}}}}}}", -"wwwwwwwwwwww<<<<<<<<<<<<888888888888VVVVVVVVVVVV~~~~~~~~~~~~((((((((((((]]]]]]]]]]]]}}}}}}}}}}}}", -"wwwwwwwwwwww<<<<<<<<<<<<888888888888VVVVVVVVVVVV~~~~~~~~~~~~((((((((((((]]]]]]]]]]]]}}}}}}}}}}}}", -"wwwwwwwwwwww<<<<<<<<<<<<888888888888VVVVVVVVVVVV~~~~~~~~~~~~((((((((((((]]]]]]]]]]]]}}}}}}}}}}}}", -"wwwwwwwwwwww<<<<<<<<<<<<888888888888VVVVVVVVVVVV~~~~~~~~~~~~((((((((((((]]]]]]]]]]]]}}}}}}}}}}}}", -"wwwwwwwwwwww<<<<<<<<<<<<888888888888VVVVVVVVVVVV~~~~~~~~~~~~((((((((((((]]]]]]]]]]]]}}}}}}}}}}}}", -"hhhhhhhhhhhh>>>>>>>>>>>>rrrrrrrrrrrrVVVVVVVVVVVVLLLLLLLLLLLL))))))))))))]]]]]]]]]]]]{{{{{{{{{{{{", -"hhhhhhhhhhhh>>>>>>>>>>>>rrrrrrrrrrrrVVVVVVVVVVVVLLLLLLLLLLLL))))))))))))]]]]]]]]]]]]{{{{{{{{{{{{", -"hhhhhhhhhhhh>>>>>>>>>>>>rrrrrrrrrrrrVVVVVVVVVVVVLLLLLLLLLLLL))))))))))))]]]]]]]]]]]]{{{{{{{{{{{{", -"hhhhhhhhhhhh>>>>>>>>>>>>rrrrrrrrrrrrVVVVVVVVVVVVLLLLLLLLLLLL))))))))))))]]]]]]]]]]]]{{{{{{{{{{{{", -"hhhhhhhhhhhh>>>>>>>>>>>>rrrrrrrrrrrrVVVVVVVVVVVVLLLLLLLLLLLL))))))))))))]]]]]]]]]]]]{{{{{{{{{{{{", -"hhhhhhhhhhhh>>>>>>>>>>>>rrrrrrrrrrrrVVVVVVVVVVVVLLLLLLLLLLLL))))))))))))]]]]]]]]]]]]{{{{{{{{{{{{", -"hhhhhhhhhhhh>>>>>>>>>>>>rrrrrrrrrrrrVVVVVVVVVVVVLLLLLLLLLLLL))))))))))))]]]]]]]]]]]]{{{{{{{{{{{{", -"hhhhhhhhhhhh>>>>>>>>>>>>rrrrrrrrrrrrVVVVVVVVVVVVLLLLLLLLLLLL))))))))))))]]]]]]]]]]]]{{{{{{{{{{{{", -"hhhhhhhhhhhh>>>>>>>>>>>>rrrrrrrrrrrrVVVVVVVVVVVVLLLLLLLLLLLL))))))))))))]]]]]]]]]]]]{{{{{{{{{{{{", -"hhhhhhhhhhhh>>>>>>>>>>>>rrrrrrrrrrrrVVVVVVVVVVVVLLLLLLLLLLLL))))))))))))]]]]]]]]]]]]{{{{{{{{{{{{", -"hhhhhhhhhhhh>>>>>>>>>>>>rrrrrrrrrrrrVVVVVVVVVVVVLLLLLLLLLLLL))))))))))))]]]]]]]]]]]]{{{{{{{{{{{{", -"hhhhhhhhhhhh>>>>>>>>>>>>rrrrrrrrrrrrVVVVVVVVVVVVLLLLLLLLLLLL))))))))))))]]]]]]]]]]]]{{{{{{{{{{{{", -"::::::::::::;;;;;;;;;;;;HHHHHHHHHHHHccccccccccccQQQQQQQQQQQQ))))))))))))''''''''''''}}}}}}}}}}}}", -"::::::::::::;;;;;;;;;;;;HHHHHHHHHHHHccccccccccccQQQQQQQQQQQQ))))))))))))''''''''''''}}}}}}}}}}}}", -"::::::::::::;;;;;;;;;;;;HHHHHHHHHHHHccccccccccccQQQQQQQQQQQQ))))))))))))''''''''''''}}}}}}}}}}}}", -"::::::::::::;;;;;;;;;;;;HHHHHHHHHHHHccccccccccccQQQQQQQQQQQQ))))))))))))''''''''''''}}}}}}}}}}}}", -"::::::::::::;;;;;;;;;;;;HHHHHHHHHHHHccccccccccccQQQQQQQQQQQQ))))))))))))''''''''''''}}}}}}}}}}}}", -"::::::::::::;;;;;;;;;;;;HHHHHHHHHHHHccccccccccccQQQQQQQQQQQQ))))))))))))''''''''''''}}}}}}}}}}}}", -"::::::::::::;;;;;;;;;;;;HHHHHHHHHHHHccccccccccccQQQQQQQQQQQQ))))))))))))''''''''''''}}}}}}}}}}}}", -"::::::::::::;;;;;;;;;;;;HHHHHHHHHHHHccccccccccccQQQQQQQQQQQQ))))))))))))''''''''''''}}}}}}}}}}}}", -"::::::::::::;;;;;;;;;;;;HHHHHHHHHHHHccccccccccccQQQQQQQQQQQQ))))))))))))''''''''''''}}}}}}}}}}}}", -"::::::::::::;;;;;;;;;;;;HHHHHHHHHHHHccccccccccccQQQQQQQQQQQQ))))))))))))''''''''''''}}}}}}}}}}}}", -"::::::::::::;;;;;;;;;;;;HHHHHHHHHHHHccccccccccccQQQQQQQQQQQQ))))))))))))''''''''''''}}}}}}}}}}}}", -"::::::::::::;;;;;;;;;;;;HHHHHHHHHHHHccccccccccccQQQQQQQQQQQQ))))))))))))''''''''''''}}}}}}}}}}}}", -"qqqqqqqqqqqqkkkkkkkkkkkk333333333333AAAAAAAAAAAARRRRRRRRRRRR))))))))))))''''''''''''{{{{{{{{{{{{", -"qqqqqqqqqqqqkkkkkkkkkkkk333333333333AAAAAAAAAAAARRRRRRRRRRRR))))))))))))''''''''''''{{{{{{{{{{{{", -"qqqqqqqqqqqqkkkkkkkkkkkk333333333333AAAAAAAAAAAARRRRRRRRRRRR))))))))))))''''''''''''{{{{{{{{{{{{", -"qqqqqqqqqqqqkkkkkkkkkkkk333333333333AAAAAAAAAAAARRRRRRRRRRRR))))))))))))''''''''''''{{{{{{{{{{{{", -"qqqqqqqqqqqqkkkkkkkkkkkk333333333333AAAAAAAAAAAARRRRRRRRRRRR))))))))))))''''''''''''{{{{{{{{{{{{", -"qqqqqqqqqqqqkkkkkkkkkkkk333333333333AAAAAAAAAAAARRRRRRRRRRRR))))))))))))''''''''''''{{{{{{{{{{{{", -"qqqqqqqqqqqqkkkkkkkkkkkk333333333333AAAAAAAAAAAARRRRRRRRRRRR))))))))))))''''''''''''{{{{{{{{{{{{", -"qqqqqqqqqqqqkkkkkkkkkkkk333333333333AAAAAAAAAAAARRRRRRRRRRRR))))))))))))''''''''''''{{{{{{{{{{{{", -"qqqqqqqqqqqqkkkkkkkkkkkk333333333333AAAAAAAAAAAARRRRRRRRRRRR))))))))))))''''''''''''{{{{{{{{{{{{", -"qqqqqqqqqqqqkkkkkkkkkkkk333333333333AAAAAAAAAAAARRRRRRRRRRRR))))))))))))''''''''''''{{{{{{{{{{{{", -"qqqqqqqqqqqqkkkkkkkkkkkk333333333333AAAAAAAAAAAARRRRRRRRRRRR))))))))))))''''''''''''{{{{{{{{{{{{", -"qqqqqqqqqqqqkkkkkkkkkkkk333333333333AAAAAAAAAAAARRRRRRRRRRRR))))))))))))''''''''''''{{{{{{{{{{{{", -"############ppppppppppppssssssssssssIIIIIIIIIIII^^^^^^^^^^^^____________''''''''''''{{{{{{{{{{{{", -"############ppppppppppppssssssssssssIIIIIIIIIIII^^^^^^^^^^^^____________''''''''''''{{{{{{{{{{{{", -"############ppppppppppppssssssssssssIIIIIIIIIIII^^^^^^^^^^^^____________''''''''''''{{{{{{{{{{{{", -"############ppppppppppppssssssssssssIIIIIIIIIIII^^^^^^^^^^^^____________''''''''''''{{{{{{{{{{{{", -"############ppppppppppppssssssssssssIIIIIIIIIIII^^^^^^^^^^^^____________''''''''''''{{{{{{{{{{{{", -"############ppppppppppppssssssssssssIIIIIIIIIIII^^^^^^^^^^^^____________''''''''''''{{{{{{{{{{{{", -"############ppppppppppppssssssssssssIIIIIIIIIIII^^^^^^^^^^^^____________''''''''''''{{{{{{{{{{{{", -"############ppppppppppppssssssssssssIIIIIIIIIIII^^^^^^^^^^^^____________''''''''''''{{{{{{{{{{{{", -"############ppppppppppppssssssssssssIIIIIIIIIIII^^^^^^^^^^^^____________''''''''''''{{{{{{{{{{{{", -"############ppppppppppppssssssssssssIIIIIIIIIIII^^^^^^^^^^^^____________''''''''''''{{{{{{{{{{{{", -"############ppppppppppppssssssssssssIIIIIIIIIIII^^^^^^^^^^^^____________''''''''''''{{{{{{{{{{{{", -"############ppppppppppppssssssssssssIIIIIIIIIIII^^^^^^^^^^^^____________''''''''''''{{{{{{{{{{{{", -"++++++++++++rrrrrrrrrrrr777777777777MMMMMMMMMMMMIIIIIIIIIIII````````````''''''''''''{{{{{{{{{{{{", -"++++++++++++rrrrrrrrrrrr777777777777MMMMMMMMMMMMIIIIIIIIIIII````````````''''''''''''{{{{{{{{{{{{", -"++++++++++++rrrrrrrrrrrr777777777777MMMMMMMMMMMMIIIIIIIIIIII````````````''''''''''''{{{{{{{{{{{{", -"++++++++++++rrrrrrrrrrrr777777777777MMMMMMMMMMMMIIIIIIIIIIII````````````''''''''''''{{{{{{{{{{{{", -"++++++++++++rrrrrrrrrrrr777777777777MMMMMMMMMMMMIIIIIIIIIIII````````````''''''''''''{{{{{{{{{{{{", -"++++++++++++rrrrrrrrrrrr777777777777MMMMMMMMMMMMIIIIIIIIIIII````````````''''''''''''{{{{{{{{{{{{", -"++++++++++++rrrrrrrrrrrr777777777777MMMMMMMMMMMMIIIIIIIIIIII````````````''''''''''''{{{{{{{{{{{{", -"++++++++++++rrrrrrrrrrrr777777777777MMMMMMMMMMMMIIIIIIIIIIII````````````''''''''''''{{{{{{{{{{{{", -"++++++++++++rrrrrrrrrrrr777777777777MMMMMMMMMMMMIIIIIIIIIIII````````````''''''''''''{{{{{{{{{{{{", -"++++++++++++rrrrrrrrrrrr777777777777MMMMMMMMMMMMIIIIIIIIIIII````````````''''''''''''{{{{{{{{{{{{", -"++++++++++++rrrrrrrrrrrr777777777777MMMMMMMMMMMMIIIIIIIIIIII````````````''''''''''''{{{{{{{{{{{{", -"++++++++++++rrrrrrrrrrrr777777777777MMMMMMMMMMMMIIIIIIIIIIII````````````''''''''''''{{{{{{{{{{{{", -"------------$$$$$$$$$$$$999999999999JJJJJJJJJJJJTTTTTTTTTTTT____________]]]]]]]]]]]]{{{{{{{{{{{{", -"------------$$$$$$$$$$$$999999999999JJJJJJJJJJJJTTTTTTTTTTTT____________]]]]]]]]]]]]{{{{{{{{{{{{", -"------------$$$$$$$$$$$$999999999999JJJJJJJJJJJJTTTTTTTTTTTT____________]]]]]]]]]]]]{{{{{{{{{{{{", -"------------$$$$$$$$$$$$999999999999JJJJJJJJJJJJTTTTTTTTTTTT____________]]]]]]]]]]]]{{{{{{{{{{{{", -"------------$$$$$$$$$$$$999999999999JJJJJJJJJJJJTTTTTTTTTTTT____________]]]]]]]]]]]]{{{{{{{{{{{{", -"------------$$$$$$$$$$$$999999999999JJJJJJJJJJJJTTTTTTTTTTTT____________]]]]]]]]]]]]{{{{{{{{{{{{", -"------------$$$$$$$$$$$$999999999999JJJJJJJJJJJJTTTTTTTTTTTT____________]]]]]]]]]]]]{{{{{{{{{{{{", -"------------$$$$$$$$$$$$999999999999JJJJJJJJJJJJTTTTTTTTTTTT____________]]]]]]]]]]]]{{{{{{{{{{{{", -"------------$$$$$$$$$$$$999999999999JJJJJJJJJJJJTTTTTTTTTTTT____________]]]]]]]]]]]]{{{{{{{{{{{{", -"------------$$$$$$$$$$$$999999999999JJJJJJJJJJJJTTTTTTTTTTTT____________]]]]]]]]]]]]{{{{{{{{{{{{", -"------------$$$$$$$$$$$$999999999999JJJJJJJJJJJJTTTTTTTTTTTT____________]]]]]]]]]]]]{{{{{{{{{{{{", -"------------$$$$$$$$$$$$999999999999JJJJJJJJJJJJTTTTTTTTTTTT____________]]]]]]]]]]]]{{{{{{{{{{{{", -"@@@@@@@@@@@@666666666666ttttttttttttWWWWWWWWWWWWPPPPPPPPPPPP))))))))))))''''''''''''{{{{{{{{{{{{", -"@@@@@@@@@@@@666666666666ttttttttttttWWWWWWWWWWWWPPPPPPPPPPPP))))))))))))''''''''''''{{{{{{{{{{{{", -"@@@@@@@@@@@@666666666666ttttttttttttWWWWWWWWWWWWPPPPPPPPPPPP))))))))))))''''''''''''{{{{{{{{{{{{", -"@@@@@@@@@@@@666666666666ttttttttttttWWWWWWWWWWWWPPPPPPPPPPPP))))))))))))''''''''''''{{{{{{{{{{{{", -"@@@@@@@@@@@@666666666666ttttttttttttWWWWWWWWWWWWPPPPPPPPPPPP))))))))))))''''''''''''{{{{{{{{{{{{", -"@@@@@@@@@@@@666666666666ttttttttttttWWWWWWWWWWWWPPPPPPPPPPPP))))))))))))''''''''''''{{{{{{{{{{{{", -"@@@@@@@@@@@@666666666666ttttttttttttWWWWWWWWWWWWPPPPPPPPPPPP))))))))))))''''''''''''{{{{{{{{{{{{", -"@@@@@@@@@@@@666666666666ttttttttttttWWWWWWWWWWWWPPPPPPPPPPPP))))))))))))''''''''''''{{{{{{{{{{{{", -"@@@@@@@@@@@@666666666666ttttttttttttWWWWWWWWWWWWPPPPPPPPPPPP))))))))))))''''''''''''{{{{{{{{{{{{", -"@@@@@@@@@@@@666666666666ttttttttttttWWWWWWWWWWWWPPPPPPPPPPPP))))))))))))''''''''''''{{{{{{{{{{{{", -"@@@@@@@@@@@@666666666666ttttttttttttWWWWWWWWWWWWPPPPPPPPPPPP))))))))))))''''''''''''{{{{{{{{{{{{", -"@@@@@@@@@@@@666666666666ttttttttttttWWWWWWWWWWWWPPPPPPPPPPPP))))))))))))''''''''''''{{{{{{{{{{{{", -"aaaaaaaaaaaazzzzzzzzzzzzBBBBBBBBBBBBbbbbbbbbbbbbPPPPPPPPPPPP____________''''''''''''{{{{{{{{{{{{", -"aaaaaaaaaaaazzzzzzzzzzzzBBBBBBBBBBBBbbbbbbbbbbbbPPPPPPPPPPPP____________''''''''''''{{{{{{{{{{{{", -"aaaaaaaaaaaazzzzzzzzzzzzBBBBBBBBBBBBbbbbbbbbbbbbPPPPPPPPPPPP____________''''''''''''{{{{{{{{{{{{", -"aaaaaaaaaaaazzzzzzzzzzzzBBBBBBBBBBBBbbbbbbbbbbbbPPPPPPPPPPPP____________''''''''''''{{{{{{{{{{{{", -"aaaaaaaaaaaazzzzzzzzzzzzBBBBBBBBBBBBbbbbbbbbbbbbPPPPPPPPPPPP____________''''''''''''{{{{{{{{{{{{", -"aaaaaaaaaaaazzzzzzzzzzzzBBBBBBBBBBBBbbbbbbbbbbbbPPPPPPPPPPPP____________''''''''''''{{{{{{{{{{{{", -"aaaaaaaaaaaazzzzzzzzzzzzBBBBBBBBBBBBbbbbbbbbbbbbPPPPPPPPPPPP____________''''''''''''{{{{{{{{{{{{", -"aaaaaaaaaaaazzzzzzzzzzzzBBBBBBBBBBBBbbbbbbbbbbbbPPPPPPPPPPPP____________''''''''''''{{{{{{{{{{{{", -"aaaaaaaaaaaazzzzzzzzzzzzBBBBBBBBBBBBbbbbbbbbbbbbPPPPPPPPPPPP____________''''''''''''{{{{{{{{{{{{", -"aaaaaaaaaaaazzzzzzzzzzzzBBBBBBBBBBBBbbbbbbbbbbbbPPPPPPPPPPPP____________''''''''''''{{{{{{{{{{{{", -"aaaaaaaaaaaazzzzzzzzzzzzBBBBBBBBBBBBbbbbbbbbbbbbPPPPPPPPPPPP____________''''''''''''{{{{{{{{{{{{", -"aaaaaaaaaaaazzzzzzzzzzzzBBBBBBBBBBBBbbbbbbbbbbbbPPPPPPPPPPPP____________''''''''''''{{{{{{{{{{{{", -"------------%%%%%%%%%%%%ttttttttttttNNNNNNNNNNNN^^^^^^^^^^^^))))))))))))''''''''''''}}}}}}}}}}}}", -"------------%%%%%%%%%%%%ttttttttttttNNNNNNNNNNNN^^^^^^^^^^^^))))))))))))''''''''''''}}}}}}}}}}}}", -"------------%%%%%%%%%%%%ttttttttttttNNNNNNNNNNNN^^^^^^^^^^^^))))))))))))''''''''''''}}}}}}}}}}}}", -"------------%%%%%%%%%%%%ttttttttttttNNNNNNNNNNNN^^^^^^^^^^^^))))))))))))''''''''''''}}}}}}}}}}}}", -"------------%%%%%%%%%%%%ttttttttttttNNNNNNNNNNNN^^^^^^^^^^^^))))))))))))''''''''''''}}}}}}}}}}}}", -"------------%%%%%%%%%%%%ttttttttttttNNNNNNNNNNNN^^^^^^^^^^^^))))))))))))''''''''''''}}}}}}}}}}}}", -"------------%%%%%%%%%%%%ttttttttttttNNNNNNNNNNNN^^^^^^^^^^^^))))))))))))''''''''''''}}}}}}}}}}}}", -"------------%%%%%%%%%%%%ttttttttttttNNNNNNNNNNNN^^^^^^^^^^^^))))))))))))''''''''''''}}}}}}}}}}}}", -"------------%%%%%%%%%%%%ttttttttttttNNNNNNNNNNNN^^^^^^^^^^^^))))))))))))''''''''''''}}}}}}}}}}}}", -"------------%%%%%%%%%%%%ttttttttttttNNNNNNNNNNNN^^^^^^^^^^^^))))))))))))''''''''''''}}}}}}}}}}}}", -"------------%%%%%%%%%%%%ttttttttttttNNNNNNNNNNNN^^^^^^^^^^^^))))))))))))''''''''''''}}}}}}}}}}}}", -"------------%%%%%%%%%%%%ttttttttttttNNNNNNNNNNNN^^^^^^^^^^^^))))))))))))''''''''''''}}}}}}}}}}}}", -" 000000000000888888888888FFFFFFFFFFFF~~~~~~~~~~~~))))))))))))''''''''''''}}}}}}}}}}}}", -" 000000000000888888888888FFFFFFFFFFFF~~~~~~~~~~~~))))))))))))''''''''''''}}}}}}}}}}}}", -" 000000000000888888888888FFFFFFFFFFFF~~~~~~~~~~~~))))))))))))''''''''''''}}}}}}}}}}}}", -" 000000000000888888888888FFFFFFFFFFFF~~~~~~~~~~~~))))))))))))''''''''''''}}}}}}}}}}}}", -" 000000000000888888888888FFFFFFFFFFFF~~~~~~~~~~~~))))))))))))''''''''''''}}}}}}}}}}}}", -" 000000000000888888888888FFFFFFFFFFFF~~~~~~~~~~~~))))))))))))''''''''''''}}}}}}}}}}}}", -" 000000000000888888888888FFFFFFFFFFFF~~~~~~~~~~~~))))))))))))''''''''''''}}}}}}}}}}}}", -" 000000000000888888888888FFFFFFFFFFFF~~~~~~~~~~~~))))))))))))''''''''''''}}}}}}}}}}}}", -" 000000000000888888888888FFFFFFFFFFFF~~~~~~~~~~~~))))))))))))''''''''''''}}}}}}}}}}}}", -" 000000000000888888888888FFFFFFFFFFFF~~~~~~~~~~~~))))))))))))''''''''''''}}}}}}}}}}}}", -" 000000000000888888888888FFFFFFFFFFFF~~~~~~~~~~~~))))))))))))''''''''''''}}}}}}}}}}}}", -" 000000000000888888888888FFFFFFFFFFFF~~~~~~~~~~~~))))))))))))''''''''''''}}}}}}}}}}}}", -"++++++++++++222222222222xxxxxxxxxxxxNNNNNNNNNNNNEEEEEEEEEEEE))))))))))))''''''''''''}}}}}}}}}}}}", -"++++++++++++222222222222xxxxxxxxxxxxNNNNNNNNNNNNEEEEEEEEEEEE))))))))))))''''''''''''}}}}}}}}}}}}", -"++++++++++++222222222222xxxxxxxxxxxxNNNNNNNNNNNNEEEEEEEEEEEE))))))))))))''''''''''''}}}}}}}}}}}}", -"++++++++++++222222222222xxxxxxxxxxxxNNNNNNNNNNNNEEEEEEEEEEEE))))))))))))''''''''''''}}}}}}}}}}}}", -"++++++++++++222222222222xxxxxxxxxxxxNNNNNNNNNNNNEEEEEEEEEEEE))))))))))))''''''''''''}}}}}}}}}}}}", -"++++++++++++222222222222xxxxxxxxxxxxNNNNNNNNNNNNEEEEEEEEEEEE))))))))))))''''''''''''}}}}}}}}}}}}", -"++++++++++++222222222222xxxxxxxxxxxxNNNNNNNNNNNNEEEEEEEEEEEE))))))))))))''''''''''''}}}}}}}}}}}}", -"++++++++++++222222222222xxxxxxxxxxxxNNNNNNNNNNNNEEEEEEEEEEEE))))))))))))''''''''''''}}}}}}}}}}}}", -"++++++++++++222222222222xxxxxxxxxxxxNNNNNNNNNNNNEEEEEEEEEEEE))))))))))))''''''''''''}}}}}}}}}}}}", -"++++++++++++222222222222xxxxxxxxxxxxNNNNNNNNNNNNEEEEEEEEEEEE))))))))))))''''''''''''}}}}}}}}}}}}", -"++++++++++++222222222222xxxxxxxxxxxxNNNNNNNNNNNNEEEEEEEEEEEE))))))))))))''''''''''''}}}}}}}}}}}}", -"++++++++++++222222222222xxxxxxxxxxxxNNNNNNNNNNNNEEEEEEEEEEEE))))))))))))''''''''''''}}}}}}}}}}}}", -"$$$$$$$$$$$$000000000000GGGGGGGGGGGGnnnnnnnnnnnnLLLLLLLLLLLL))))))))))))]]]]]]]]]]]]{{{{{{{{{{{{", -"$$$$$$$$$$$$000000000000GGGGGGGGGGGGnnnnnnnnnnnnLLLLLLLLLLLL))))))))))))]]]]]]]]]]]]{{{{{{{{{{{{", -"$$$$$$$$$$$$000000000000GGGGGGGGGGGGnnnnnnnnnnnnLLLLLLLLLLLL))))))))))))]]]]]]]]]]]]{{{{{{{{{{{{", -"$$$$$$$$$$$$000000000000GGGGGGGGGGGGnnnnnnnnnnnnLLLLLLLLLLLL))))))))))))]]]]]]]]]]]]{{{{{{{{{{{{", -"$$$$$$$$$$$$000000000000GGGGGGGGGGGGnnnnnnnnnnnnLLLLLLLLLLLL))))))))))))]]]]]]]]]]]]{{{{{{{{{{{{", -"$$$$$$$$$$$$000000000000GGGGGGGGGGGGnnnnnnnnnnnnLLLLLLLLLLLL))))))))))))]]]]]]]]]]]]{{{{{{{{{{{{", -"$$$$$$$$$$$$000000000000GGGGGGGGGGGGnnnnnnnnnnnnLLLLLLLLLLLL))))))))))))]]]]]]]]]]]]{{{{{{{{{{{{", -"$$$$$$$$$$$$000000000000GGGGGGGGGGGGnnnnnnnnnnnnLLLLLLLLLLLL))))))))))))]]]]]]]]]]]]{{{{{{{{{{{{", -"$$$$$$$$$$$$000000000000GGGGGGGGGGGGnnnnnnnnnnnnLLLLLLLLLLLL))))))))))))]]]]]]]]]]]]{{{{{{{{{{{{", -"$$$$$$$$$$$$000000000000GGGGGGGGGGGGnnnnnnnnnnnnLLLLLLLLLLLL))))))))))))]]]]]]]]]]]]{{{{{{{{{{{{", -"$$$$$$$$$$$$000000000000GGGGGGGGGGGGnnnnnnnnnnnnLLLLLLLLLLLL))))))))))))]]]]]]]]]]]]{{{{{{{{{{{{", -"$$$$$$$$$$$$000000000000GGGGGGGGGGGGnnnnnnnnnnnnLLLLLLLLLLLL))))))))))))]]]]]]]]]]]]{{{{{{{{{{{{", -"ooooooooooooffffffffffffccccccccccccbbbbbbbbbbbbRRRRRRRRRRRR____________''''''''''''{{{{{{{{{{{{", -"ooooooooooooffffffffffffccccccccccccbbbbbbbbbbbbRRRRRRRRRRRR____________''''''''''''{{{{{{{{{{{{", -"ooooooooooooffffffffffffccccccccccccbbbbbbbbbbbbRRRRRRRRRRRR____________''''''''''''{{{{{{{{{{{{", -"ooooooooooooffffffffffffccccccccccccbbbbbbbbbbbbRRRRRRRRRRRR____________''''''''''''{{{{{{{{{{{{", -"ooooooooooooffffffffffffccccccccccccbbbbbbbbbbbbRRRRRRRRRRRR____________''''''''''''{{{{{{{{{{{{", -"ooooooooooooffffffffffffccccccccccccbbbbbbbbbbbbRRRRRRRRRRRR____________''''''''''''{{{{{{{{{{{{", -"ooooooooooooffffffffffffccccccccccccbbbbbbbbbbbbRRRRRRRRRRRR____________''''''''''''{{{{{{{{{{{{", -"ooooooooooooffffffffffffccccccccccccbbbbbbbbbbbbRRRRRRRRRRRR____________''''''''''''{{{{{{{{{{{{", -"ooooooooooooffffffffffffccccccccccccbbbbbbbbbbbbRRRRRRRRRRRR____________''''''''''''{{{{{{{{{{{{", -"ooooooooooooffffffffffffccccccccccccbbbbbbbbbbbbRRRRRRRRRRRR____________''''''''''''{{{{{{{{{{{{", -"ooooooooooooffffffffffffccccccccccccbbbbbbbbbbbbRRRRRRRRRRRR____________''''''''''''{{{{{{{{{{{{", -"ooooooooooooffffffffffffccccccccccccbbbbbbbbbbbbRRRRRRRRRRRR____________''''''''''''{{{{{{{{{{{{", -"@@@@@@@@@@@@111111111111777777777777JJJJJJJJJJJJPPPPPPPPPPPP((((((((((((''''''''''''{{{{{{{{{{{{", -"@@@@@@@@@@@@111111111111777777777777JJJJJJJJJJJJPPPPPPPPPPPP((((((((((((''''''''''''{{{{{{{{{{{{", -"@@@@@@@@@@@@111111111111777777777777JJJJJJJJJJJJPPPPPPPPPPPP((((((((((((''''''''''''{{{{{{{{{{{{", -"@@@@@@@@@@@@111111111111777777777777JJJJJJJJJJJJPPPPPPPPPPPP((((((((((((''''''''''''{{{{{{{{{{{{", -"@@@@@@@@@@@@111111111111777777777777JJJJJJJJJJJJPPPPPPPPPPPP((((((((((((''''''''''''{{{{{{{{{{{{", -"@@@@@@@@@@@@111111111111777777777777JJJJJJJJJJJJPPPPPPPPPPPP((((((((((((''''''''''''{{{{{{{{{{{{", -"@@@@@@@@@@@@111111111111777777777777JJJJJJJJJJJJPPPPPPPPPPPP((((((((((((''''''''''''{{{{{{{{{{{{", -"@@@@@@@@@@@@111111111111777777777777JJJJJJJJJJJJPPPPPPPPPPPP((((((((((((''''''''''''{{{{{{{{{{{{", -"@@@@@@@@@@@@111111111111777777777777JJJJJJJJJJJJPPPPPPPPPPPP((((((((((((''''''''''''{{{{{{{{{{{{", -"@@@@@@@@@@@@111111111111777777777777JJJJJJJJJJJJPPPPPPPPPPPP((((((((((((''''''''''''{{{{{{{{{{{{", -"@@@@@@@@@@@@111111111111777777777777JJJJJJJJJJJJPPPPPPPPPPPP((((((((((((''''''''''''{{{{{{{{{{{{", -"@@@@@@@@@@@@111111111111777777777777JJJJJJJJJJJJPPPPPPPPPPPP((((((((((((''''''''''''{{{{{{{{{{{{", -" iiiiiiiiiiiiGGGGGGGGGGGGVVVVVVVVVVVV~~~~~~~~~~~~____________''''''''''''}}}}}}}}}}}}", -" iiiiiiiiiiiiGGGGGGGGGGGGVVVVVVVVVVVV~~~~~~~~~~~~____________''''''''''''}}}}}}}}}}}}", -" iiiiiiiiiiiiGGGGGGGGGGGGVVVVVVVVVVVV~~~~~~~~~~~~____________''''''''''''}}}}}}}}}}}}", -" iiiiiiiiiiiiGGGGGGGGGGGGVVVVVVVVVVVV~~~~~~~~~~~~____________''''''''''''}}}}}}}}}}}}", -" iiiiiiiiiiiiGGGGGGGGGGGGVVVVVVVVVVVV~~~~~~~~~~~~____________''''''''''''}}}}}}}}}}}}", -" iiiiiiiiiiiiGGGGGGGGGGGGVVVVVVVVVVVV~~~~~~~~~~~~____________''''''''''''}}}}}}}}}}}}", -" iiiiiiiiiiiiGGGGGGGGGGGGVVVVVVVVVVVV~~~~~~~~~~~~____________''''''''''''}}}}}}}}}}}}", -" iiiiiiiiiiiiGGGGGGGGGGGGVVVVVVVVVVVV~~~~~~~~~~~~____________''''''''''''}}}}}}}}}}}}", -" iiiiiiiiiiiiGGGGGGGGGGGGVVVVVVVVVVVV~~~~~~~~~~~~____________''''''''''''}}}}}}}}}}}}", -" iiiiiiiiiiiiGGGGGGGGGGGGVVVVVVVVVVVV~~~~~~~~~~~~____________''''''''''''}}}}}}}}}}}}", -" iiiiiiiiiiiiGGGGGGGGGGGGVVVVVVVVVVVV~~~~~~~~~~~~____________''''''''''''}}}}}}}}}}}}", -" iiiiiiiiiiiiGGGGGGGGGGGGVVVVVVVVVVVV~~~~~~~~~~~~____________''''''''''''}}}}}}}}}}}}", -"------------222222222222KKKKKKKKKKKKIIIIIIIIIIIIQQQQQQQQQQQQ____________''''''''''''{{{{{{{{{{{{", -"------------222222222222KKKKKKKKKKKKIIIIIIIIIIIIQQQQQQQQQQQQ____________''''''''''''{{{{{{{{{{{{", -"------------222222222222KKKKKKKKKKKKIIIIIIIIIIIIQQQQQQQQQQQQ____________''''''''''''{{{{{{{{{{{{", -"------------222222222222KKKKKKKKKKKKIIIIIIIIIIIIQQQQQQQQQQQQ____________''''''''''''{{{{{{{{{{{{", -"------------222222222222KKKKKKKKKKKKIIIIIIIIIIIIQQQQQQQQQQQQ____________''''''''''''{{{{{{{{{{{{", -"------------222222222222KKKKKKKKKKKKIIIIIIIIIIIIQQQQQQQQQQQQ____________''''''''''''{{{{{{{{{{{{", -"------------222222222222KKKKKKKKKKKKIIIIIIIIIIIIQQQQQQQQQQQQ____________''''''''''''{{{{{{{{{{{{", -"------------222222222222KKKKKKKKKKKKIIIIIIIIIIIIQQQQQQQQQQQQ____________''''''''''''{{{{{{{{{{{{", -"------------222222222222KKKKKKKKKKKKIIIIIIIIIIIIQQQQQQQQQQQQ____________''''''''''''{{{{{{{{{{{{", -"------------222222222222KKKKKKKKKKKKIIIIIIIIIIIIQQQQQQQQQQQQ____________''''''''''''{{{{{{{{{{{{", -"------------222222222222KKKKKKKKKKKKIIIIIIIIIIIIQQQQQQQQQQQQ____________''''''''''''{{{{{{{{{{{{", -"------------222222222222KKKKKKKKKKKKIIIIIIIIIIIIQQQQQQQQQQQQ____________''''''''''''{{{{{{{{{{{{", -"&&&&&&&&&&&&222222222222333333333333WWWWWWWWWWWW~~~~~~~~~~~~____________''''''''''''{{{{{{{{{{{{", -"&&&&&&&&&&&&222222222222333333333333WWWWWWWWWWWW~~~~~~~~~~~~____________''''''''''''{{{{{{{{{{{{", -"&&&&&&&&&&&&222222222222333333333333WWWWWWWWWWWW~~~~~~~~~~~~____________''''''''''''{{{{{{{{{{{{", -"&&&&&&&&&&&&222222222222333333333333WWWWWWWWWWWW~~~~~~~~~~~~____________''''''''''''{{{{{{{{{{{{", -"&&&&&&&&&&&&222222222222333333333333WWWWWWWWWWWW~~~~~~~~~~~~____________''''''''''''{{{{{{{{{{{{", -"&&&&&&&&&&&&222222222222333333333333WWWWWWWWWWWW~~~~~~~~~~~~____________''''''''''''{{{{{{{{{{{{", -"&&&&&&&&&&&&222222222222333333333333WWWWWWWWWWWW~~~~~~~~~~~~____________''''''''''''{{{{{{{{{{{{", -"&&&&&&&&&&&&222222222222333333333333WWWWWWWWWWWW~~~~~~~~~~~~____________''''''''''''{{{{{{{{{{{{", -"&&&&&&&&&&&&222222222222333333333333WWWWWWWWWWWW~~~~~~~~~~~~____________''''''''''''{{{{{{{{{{{{", -"&&&&&&&&&&&&222222222222333333333333WWWWWWWWWWWW~~~~~~~~~~~~____________''''''''''''{{{{{{{{{{{{", -"&&&&&&&&&&&&222222222222333333333333WWWWWWWWWWWW~~~~~~~~~~~~____________''''''''''''{{{{{{{{{{{{", -"&&&&&&&&&&&&222222222222333333333333WWWWWWWWWWWW~~~~~~~~~~~~____________''''''''''''{{{{{{{{{{{{", -"wwwwwwwwwwww============555555555555EEEEEEEEEEEEEEEEEEEEEEEE____________''''''''''''||||||||||||", -"wwwwwwwwwwww============555555555555EEEEEEEEEEEEEEEEEEEEEEEE____________''''''''''''||||||||||||", -"wwwwwwwwwwww============555555555555EEEEEEEEEEEEEEEEEEEEEEEE____________''''''''''''||||||||||||", -"wwwwwwwwwwww============555555555555EEEEEEEEEEEEEEEEEEEEEEEE____________''''''''''''||||||||||||", -"wwwwwwwwwwww============555555555555EEEEEEEEEEEEEEEEEEEEEEEE____________''''''''''''||||||||||||", -"wwwwwwwwwwww============555555555555EEEEEEEEEEEEEEEEEEEEEEEE____________''''''''''''||||||||||||", -"wwwwwwwwwwww============555555555555EEEEEEEEEEEEEEEEEEEEEEEE____________''''''''''''||||||||||||", -"wwwwwwwwwwww============555555555555EEEEEEEEEEEEEEEEEEEEEEEE____________''''''''''''||||||||||||", -"wwwwwwwwwwww============555555555555EEEEEEEEEEEEEEEEEEEEEEEE____________''''''''''''||||||||||||", -"wwwwwwwwwwww============555555555555EEEEEEEEEEEEEEEEEEEEEEEE____________''''''''''''||||||||||||", -"wwwwwwwwwwww============555555555555EEEEEEEEEEEEEEEEEEEEEEEE____________''''''''''''||||||||||||", -"wwwwwwwwwwww============555555555555EEEEEEEEEEEEEEEEEEEEEEEE____________''''''''''''||||||||||||", -"ffffffffffff>>>>>>>>>>>>rrrrrrrrrrrrnnnnnnnnnnnn~~~~~~~~~~~~____________]]]]]]]]]]]]{{{{{{{{{{{{", -"ffffffffffff>>>>>>>>>>>>rrrrrrrrrrrrnnnnnnnnnnnn~~~~~~~~~~~~____________]]]]]]]]]]]]{{{{{{{{{{{{", -"ffffffffffff>>>>>>>>>>>>rrrrrrrrrrrrnnnnnnnnnnnn~~~~~~~~~~~~____________]]]]]]]]]]]]{{{{{{{{{{{{", -"ffffffffffff>>>>>>>>>>>>rrrrrrrrrrrrnnnnnnnnnnnn~~~~~~~~~~~~____________]]]]]]]]]]]]{{{{{{{{{{{{", -"ffffffffffff>>>>>>>>>>>>rrrrrrrrrrrrnnnnnnnnnnnn~~~~~~~~~~~~____________]]]]]]]]]]]]{{{{{{{{{{{{", -"ffffffffffff>>>>>>>>>>>>rrrrrrrrrrrrnnnnnnnnnnnn~~~~~~~~~~~~____________]]]]]]]]]]]]{{{{{{{{{{{{", -"ffffffffffff>>>>>>>>>>>>rrrrrrrrrrrrnnnnnnnnnnnn~~~~~~~~~~~~____________]]]]]]]]]]]]{{{{{{{{{{{{", -"ffffffffffff>>>>>>>>>>>>rrrrrrrrrrrrnnnnnnnnnnnn~~~~~~~~~~~~____________]]]]]]]]]]]]{{{{{{{{{{{{", -"ffffffffffff>>>>>>>>>>>>rrrrrrrrrrrrnnnnnnnnnnnn~~~~~~~~~~~~____________]]]]]]]]]]]]{{{{{{{{{{{{", -"ffffffffffff>>>>>>>>>>>>rrrrrrrrrrrrnnnnnnnnnnnn~~~~~~~~~~~~____________]]]]]]]]]]]]{{{{{{{{{{{{", -"ffffffffffff>>>>>>>>>>>>rrrrrrrrrrrrnnnnnnnnnnnn~~~~~~~~~~~~____________]]]]]]]]]]]]{{{{{{{{{{{{", -"ffffffffffff>>>>>>>>>>>>rrrrrrrrrrrrnnnnnnnnnnnn~~~~~~~~~~~~____________]]]]]]]]]]]]{{{{{{{{{{{{", -"############$$$$$$$$$$$$CCCCCCCCCCCCEEEEEEEEEEEE(((((((((((())))))))))))''''''''''''}}}}}}}}}}}}", -"############$$$$$$$$$$$$CCCCCCCCCCCCEEEEEEEEEEEE(((((((((((())))))))))))''''''''''''}}}}}}}}}}}}", -"############$$$$$$$$$$$$CCCCCCCCCCCCEEEEEEEEEEEE(((((((((((())))))))))))''''''''''''}}}}}}}}}}}}", -"############$$$$$$$$$$$$CCCCCCCCCCCCEEEEEEEEEEEE(((((((((((())))))))))))''''''''''''}}}}}}}}}}}}", -"############$$$$$$$$$$$$CCCCCCCCCCCCEEEEEEEEEEEE(((((((((((())))))))))))''''''''''''}}}}}}}}}}}}", -"############$$$$$$$$$$$$CCCCCCCCCCCCEEEEEEEEEEEE(((((((((((())))))))))))''''''''''''}}}}}}}}}}}}", -"############$$$$$$$$$$$$CCCCCCCCCCCCEEEEEEEEEEEE(((((((((((())))))))))))''''''''''''}}}}}}}}}}}}", -"############$$$$$$$$$$$$CCCCCCCCCCCCEEEEEEEEEEEE(((((((((((())))))))))))''''''''''''}}}}}}}}}}}}", -"############$$$$$$$$$$$$CCCCCCCCCCCCEEEEEEEEEEEE(((((((((((())))))))))))''''''''''''}}}}}}}}}}}}", -"############$$$$$$$$$$$$CCCCCCCCCCCCEEEEEEEEEEEE(((((((((((())))))))))))''''''''''''}}}}}}}}}}}}", -"############$$$$$$$$$$$$CCCCCCCCCCCCEEEEEEEEEEEE(((((((((((())))))))))))''''''''''''}}}}}}}}}}}}", -"############$$$$$$$$$$$$CCCCCCCCCCCCEEEEEEEEEEEE(((((((((((())))))))))))''''''''''''}}}}}}}}}}}}", -",,,,,,,,,,,,666666666666ddddddddddddHHHHHHHHHHHHEEEEEEEEEEEE____________]]]]]]]]]]]]{{{{{{{{{{{{", -",,,,,,,,,,,,666666666666ddddddddddddHHHHHHHHHHHHEEEEEEEEEEEE____________]]]]]]]]]]]]{{{{{{{{{{{{", -",,,,,,,,,,,,666666666666ddddddddddddHHHHHHHHHHHHEEEEEEEEEEEE____________]]]]]]]]]]]]{{{{{{{{{{{{", -",,,,,,,,,,,,666666666666ddddddddddddHHHHHHHHHHHHEEEEEEEEEEEE____________]]]]]]]]]]]]{{{{{{{{{{{{", -",,,,,,,,,,,,666666666666ddddddddddddHHHHHHHHHHHHEEEEEEEEEEEE____________]]]]]]]]]]]]{{{{{{{{{{{{", -",,,,,,,,,,,,666666666666ddddddddddddHHHHHHHHHHHHEEEEEEEEEEEE____________]]]]]]]]]]]]{{{{{{{{{{{{", -",,,,,,,,,,,,666666666666ddddddddddddHHHHHHHHHHHHEEEEEEEEEEEE____________]]]]]]]]]]]]{{{{{{{{{{{{", -",,,,,,,,,,,,666666666666ddddddddddddHHHHHHHHHHHHEEEEEEEEEEEE____________]]]]]]]]]]]]{{{{{{{{{{{{", -",,,,,,,,,,,,666666666666ddddddddddddHHHHHHHHHHHHEEEEEEEEEEEE____________]]]]]]]]]]]]{{{{{{{{{{{{", -",,,,,,,,,,,,666666666666ddddddddddddHHHHHHHHHHHHEEEEEEEEEEEE____________]]]]]]]]]]]]{{{{{{{{{{{{", -",,,,,,,,,,,,666666666666ddddddddddddHHHHHHHHHHHHEEEEEEEEEEEE____________]]]]]]]]]]]]{{{{{{{{{{{{", -",,,,,,,,,,,,666666666666ddddddddddddHHHHHHHHHHHHEEEEEEEEEEEE____________]]]]]]]]]]]]{{{{{{{{{{{{", -"xxxxxxxxxxxxjjjjjjjjjjjjccccccccccccSSSSSSSSSSSSPPPPPPPPPPPP))))))))))))]]]]]]]]]]]]}}}}}}}}}}}}", -"xxxxxxxxxxxxjjjjjjjjjjjjccccccccccccSSSSSSSSSSSSPPPPPPPPPPPP))))))))))))]]]]]]]]]]]]}}}}}}}}}}}}", -"xxxxxxxxxxxxjjjjjjjjjjjjccccccccccccSSSSSSSSSSSSPPPPPPPPPPPP))))))))))))]]]]]]]]]]]]}}}}}}}}}}}}", -"xxxxxxxxxxxxjjjjjjjjjjjjccccccccccccSSSSSSSSSSSSPPPPPPPPPPPP))))))))))))]]]]]]]]]]]]}}}}}}}}}}}}", -"xxxxxxxxxxxxjjjjjjjjjjjjccccccccccccSSSSSSSSSSSSPPPPPPPPPPPP))))))))))))]]]]]]]]]]]]}}}}}}}}}}}}", -"xxxxxxxxxxxxjjjjjjjjjjjjccccccccccccSSSSSSSSSSSSPPPPPPPPPPPP))))))))))))]]]]]]]]]]]]}}}}}}}}}}}}", -"xxxxxxxxxxxxjjjjjjjjjjjjccccccccccccSSSSSSSSSSSSPPPPPPPPPPPP))))))))))))]]]]]]]]]]]]}}}}}}}}}}}}", -"xxxxxxxxxxxxjjjjjjjjjjjjccccccccccccSSSSSSSSSSSSPPPPPPPPPPPP))))))))))))]]]]]]]]]]]]}}}}}}}}}}}}", -"xxxxxxxxxxxxjjjjjjjjjjjjccccccccccccSSSSSSSSSSSSPPPPPPPPPPPP))))))))))))]]]]]]]]]]]]}}}}}}}}}}}}", -"xxxxxxxxxxxxjjjjjjjjjjjjccccccccccccSSSSSSSSSSSSPPPPPPPPPPPP))))))))))))]]]]]]]]]]]]}}}}}}}}}}}}", -"xxxxxxxxxxxxjjjjjjjjjjjjccccccccccccSSSSSSSSSSSSPPPPPPPPPPPP))))))))))))]]]]]]]]]]]]}}}}}}}}}}}}", -"xxxxxxxxxxxxjjjjjjjjjjjjccccccccccccSSSSSSSSSSSSPPPPPPPPPPPP))))))))))))]]]]]]]]]]]]}}}}}}}}}}}}", -"000000000000%%%%%%%%%%%%ttttttttttttmmmmmmmmmmmm////////////````````````''''''''''''{{{{{{{{{{{{", -"000000000000%%%%%%%%%%%%ttttttttttttmmmmmmmmmmmm////////////````````````''''''''''''{{{{{{{{{{{{", -"000000000000%%%%%%%%%%%%ttttttttttttmmmmmmmmmmmm////////////````````````''''''''''''{{{{{{{{{{{{", -"000000000000%%%%%%%%%%%%ttttttttttttmmmmmmmmmmmm////////////````````````''''''''''''{{{{{{{{{{{{", -"000000000000%%%%%%%%%%%%ttttttttttttmmmmmmmmmmmm////////////````````````''''''''''''{{{{{{{{{{{{", -"000000000000%%%%%%%%%%%%ttttttttttttmmmmmmmmmmmm////////////````````````''''''''''''{{{{{{{{{{{{", -"000000000000%%%%%%%%%%%%ttttttttttttmmmmmmmmmmmm////////////````````````''''''''''''{{{{{{{{{{{{", -"000000000000%%%%%%%%%%%%ttttttttttttmmmmmmmmmmmm////////////````````````''''''''''''{{{{{{{{{{{{", -"000000000000%%%%%%%%%%%%ttttttttttttmmmmmmmmmmmm////////////````````````''''''''''''{{{{{{{{{{{{", -"000000000000%%%%%%%%%%%%ttttttttttttmmmmmmmmmmmm////////////````````````''''''''''''{{{{{{{{{{{{", -"000000000000%%%%%%%%%%%%ttttttttttttmmmmmmmmmmmm////////////````````````''''''''''''{{{{{{{{{{{{", -"000000000000%%%%%%%%%%%%ttttttttttttmmmmmmmmmmmm////////////````````````''''''''''''{{{{{{{{{{{{", -">>>>>>>>>>>>uuuuuuuuuuuuZZZZZZZZZZZZmmmmmmmmmmmmLLLLLLLLLLLL))))))))))))''''''''''''{{{{{{{{{{{{", -">>>>>>>>>>>>uuuuuuuuuuuuZZZZZZZZZZZZmmmmmmmmmmmmLLLLLLLLLLLL))))))))))))''''''''''''{{{{{{{{{{{{", -">>>>>>>>>>>>uuuuuuuuuuuuZZZZZZZZZZZZmmmmmmmmmmmmLLLLLLLLLLLL))))))))))))''''''''''''{{{{{{{{{{{{", -">>>>>>>>>>>>uuuuuuuuuuuuZZZZZZZZZZZZmmmmmmmmmmmmLLLLLLLLLLLL))))))))))))''''''''''''{{{{{{{{{{{{", -">>>>>>>>>>>>uuuuuuuuuuuuZZZZZZZZZZZZmmmmmmmmmmmmLLLLLLLLLLLL))))))))))))''''''''''''{{{{{{{{{{{{", -">>>>>>>>>>>>uuuuuuuuuuuuZZZZZZZZZZZZmmmmmmmmmmmmLLLLLLLLLLLL))))))))))))''''''''''''{{{{{{{{{{{{", -">>>>>>>>>>>>uuuuuuuuuuuuZZZZZZZZZZZZmmmmmmmmmmmmLLLLLLLLLLLL))))))))))))''''''''''''{{{{{{{{{{{{", -">>>>>>>>>>>>uuuuuuuuuuuuZZZZZZZZZZZZmmmmmmmmmmmmLLLLLLLLLLLL))))))))))))''''''''''''{{{{{{{{{{{{", -">>>>>>>>>>>>uuuuuuuuuuuuZZZZZZZZZZZZmmmmmmmmmmmmLLLLLLLLLLLL))))))))))))''''''''''''{{{{{{{{{{{{", -">>>>>>>>>>>>uuuuuuuuuuuuZZZZZZZZZZZZmmmmmmmmmmmmLLLLLLLLLLLL))))))))))))''''''''''''{{{{{{{{{{{{", -">>>>>>>>>>>>uuuuuuuuuuuuZZZZZZZZZZZZmmmmmmmmmmmmLLLLLLLLLLLL))))))))))))''''''''''''{{{{{{{{{{{{", -">>>>>>>>>>>>uuuuuuuuuuuuZZZZZZZZZZZZmmmmmmmmmmmmLLLLLLLLLLLL))))))))))))''''''''''''{{{{{{{{{{{{", -"OOOOOOOOOOOO444444444444888888888888KKKKKKKKKKKKTTTTTTTTTTTT))))))))))))''''''''''''{{{{{{{{{{{{", -"OOOOOOOOOOOO444444444444888888888888KKKKKKKKKKKKTTTTTTTTTTTT))))))))))))''''''''''''{{{{{{{{{{{{", -"OOOOOOOOOOOO444444444444888888888888KKKKKKKKKKKKTTTTTTTTTTTT))))))))))))''''''''''''{{{{{{{{{{{{", -"OOOOOOOOOOOO444444444444888888888888KKKKKKKKKKKKTTTTTTTTTTTT))))))))))))''''''''''''{{{{{{{{{{{{", -"OOOOOOOOOOOO444444444444888888888888KKKKKKKKKKKKTTTTTTTTTTTT))))))))))))''''''''''''{{{{{{{{{{{{", -"OOOOOOOOOOOO444444444444888888888888KKKKKKKKKKKKTTTTTTTTTTTT))))))))))))''''''''''''{{{{{{{{{{{{", -"OOOOOOOOOOOO444444444444888888888888KKKKKKKKKKKKTTTTTTTTTTTT))))))))))))''''''''''''{{{{{{{{{{{{", -"OOOOOOOOOOOO444444444444888888888888KKKKKKKKKKKKTTTTTTTTTTTT))))))))))))''''''''''''{{{{{{{{{{{{", -"OOOOOOOOOOOO444444444444888888888888KKKKKKKKKKKKTTTTTTTTTTTT))))))))))))''''''''''''{{{{{{{{{{{{", -"OOOOOOOOOOOO444444444444888888888888KKKKKKKKKKKKTTTTTTTTTTTT))))))))))))''''''''''''{{{{{{{{{{{{", -"OOOOOOOOOOOO444444444444888888888888KKKKKKKKKKKKTTTTTTTTTTTT))))))))))))''''''''''''{{{{{{{{{{{{", -"OOOOOOOOOOOO444444444444888888888888KKKKKKKKKKKKTTTTTTTTTTTT))))))))))))''''''''''''{{{{{{{{{{{{", -"++++++++++++666666666666CCCCCCCCCCCCQQQQQQQQQQQQYYYYYYYYYYYY____________''''''''''''}}}}}}}}}}}}", -"++++++++++++666666666666CCCCCCCCCCCCQQQQQQQQQQQQYYYYYYYYYYYY____________''''''''''''}}}}}}}}}}}}", -"++++++++++++666666666666CCCCCCCCCCCCQQQQQQQQQQQQYYYYYYYYYYYY____________''''''''''''}}}}}}}}}}}}", -"++++++++++++666666666666CCCCCCCCCCCCQQQQQQQQQQQQYYYYYYYYYYYY____________''''''''''''}}}}}}}}}}}}", -"++++++++++++666666666666CCCCCCCCCCCCQQQQQQQQQQQQYYYYYYYYYYYY____________''''''''''''}}}}}}}}}}}}", -"++++++++++++666666666666CCCCCCCCCCCCQQQQQQQQQQQQYYYYYYYYYYYY____________''''''''''''}}}}}}}}}}}}", -"++++++++++++666666666666CCCCCCCCCCCCQQQQQQQQQQQQYYYYYYYYYYYY____________''''''''''''}}}}}}}}}}}}", -"++++++++++++666666666666CCCCCCCCCCCCQQQQQQQQQQQQYYYYYYYYYYYY____________''''''''''''}}}}}}}}}}}}", -"++++++++++++666666666666CCCCCCCCCCCCQQQQQQQQQQQQYYYYYYYYYYYY____________''''''''''''}}}}}}}}}}}}", -"++++++++++++666666666666CCCCCCCCCCCCQQQQQQQQQQQQYYYYYYYYYYYY____________''''''''''''}}}}}}}}}}}}", -"++++++++++++666666666666CCCCCCCCCCCCQQQQQQQQQQQQYYYYYYYYYYYY____________''''''''''''}}}}}}}}}}}}", -"++++++++++++666666666666CCCCCCCCCCCCQQQQQQQQQQQQYYYYYYYYYYYY____________''''''''''''}}}}}}}}}}}}", -"oooooooooooo,,,,,,,,,,,,DDDDDDDDDDDDmmmmmmmmmmmmLLLLLLLLLLLL))))))))))))''''''''''''}}}}}}}}}}}}", -"oooooooooooo,,,,,,,,,,,,DDDDDDDDDDDDmmmmmmmmmmmmLLLLLLLLLLLL))))))))))))''''''''''''}}}}}}}}}}}}", -"oooooooooooo,,,,,,,,,,,,DDDDDDDDDDDDmmmmmmmmmmmmLLLLLLLLLLLL))))))))))))''''''''''''}}}}}}}}}}}}", -"oooooooooooo,,,,,,,,,,,,DDDDDDDDDDDDmmmmmmmmmmmmLLLLLLLLLLLL))))))))))))''''''''''''}}}}}}}}}}}}", -"oooooooooooo,,,,,,,,,,,,DDDDDDDDDDDDmmmmmmmmmmmmLLLLLLLLLLLL))))))))))))''''''''''''}}}}}}}}}}}}", -"oooooooooooo,,,,,,,,,,,,DDDDDDDDDDDDmmmmmmmmmmmmLLLLLLLLLLLL))))))))))))''''''''''''}}}}}}}}}}}}", -"oooooooooooo,,,,,,,,,,,,DDDDDDDDDDDDmmmmmmmmmmmmLLLLLLLLLLLL))))))))))))''''''''''''}}}}}}}}}}}}", -"oooooooooooo,,,,,,,,,,,,DDDDDDDDDDDDmmmmmmmmmmmmLLLLLLLLLLLL))))))))))))''''''''''''}}}}}}}}}}}}", -"oooooooooooo,,,,,,,,,,,,DDDDDDDDDDDDmmmmmmmmmmmmLLLLLLLLLLLL))))))))))))''''''''''''}}}}}}}}}}}}", -"oooooooooooo,,,,,,,,,,,,DDDDDDDDDDDDmmmmmmmmmmmmLLLLLLLLLLLL))))))))))))''''''''''''}}}}}}}}}}}}", -"oooooooooooo,,,,,,,,,,,,DDDDDDDDDDDDmmmmmmmmmmmmLLLLLLLLLLLL))))))))))))''''''''''''}}}}}}}}}}}}", -"oooooooooooo,,,,,,,,,,,,DDDDDDDDDDDDmmmmmmmmmmmmLLLLLLLLLLLL))))))))))))''''''''''''}}}}}}}}}}}}", -"::::::::::::eeeeeeeeeeee444444444444mmmmmmmmmmmm^^^^^^^^^^^^____________''''''''''''{{{{{{{{{{{{", -"::::::::::::eeeeeeeeeeee444444444444mmmmmmmmmmmm^^^^^^^^^^^^____________''''''''''''{{{{{{{{{{{{", -"::::::::::::eeeeeeeeeeee444444444444mmmmmmmmmmmm^^^^^^^^^^^^____________''''''''''''{{{{{{{{{{{{", -"::::::::::::eeeeeeeeeeee444444444444mmmmmmmmmmmm^^^^^^^^^^^^____________''''''''''''{{{{{{{{{{{{", -"::::::::::::eeeeeeeeeeee444444444444mmmmmmmmmmmm^^^^^^^^^^^^____________''''''''''''{{{{{{{{{{{{", -"::::::::::::eeeeeeeeeeee444444444444mmmmmmmmmmmm^^^^^^^^^^^^____________''''''''''''{{{{{{{{{{{{", -"::::::::::::eeeeeeeeeeee444444444444mmmmmmmmmmmm^^^^^^^^^^^^____________''''''''''''{{{{{{{{{{{{", -"::::::::::::eeeeeeeeeeee444444444444mmmmmmmmmmmm^^^^^^^^^^^^____________''''''''''''{{{{{{{{{{{{", -"::::::::::::eeeeeeeeeeee444444444444mmmmmmmmmmmm^^^^^^^^^^^^____________''''''''''''{{{{{{{{{{{{", -"::::::::::::eeeeeeeeeeee444444444444mmmmmmmmmmmm^^^^^^^^^^^^____________''''''''''''{{{{{{{{{{{{", -"::::::::::::eeeeeeeeeeee444444444444mmmmmmmmmmmm^^^^^^^^^^^^____________''''''''''''{{{{{{{{{{{{", -"::::::::::::eeeeeeeeeeee444444444444mmmmmmmmmmmm^^^^^^^^^^^^____________''''''''''''{{{{{{{{{{{{", -"............666666666666ZZZZZZZZZZZZbbbbbbbbbbbbPPPPPPPPPPPP````````````''''''''''''{{{{{{{{{{{{", -"............666666666666ZZZZZZZZZZZZbbbbbbbbbbbbPPPPPPPPPPPP````````````''''''''''''{{{{{{{{{{{{", -"............666666666666ZZZZZZZZZZZZbbbbbbbbbbbbPPPPPPPPPPPP````````````''''''''''''{{{{{{{{{{{{", -"............666666666666ZZZZZZZZZZZZbbbbbbbbbbbbPPPPPPPPPPPP````````````''''''''''''{{{{{{{{{{{{", -"............666666666666ZZZZZZZZZZZZbbbbbbbbbbbbPPPPPPPPPPPP````````````''''''''''''{{{{{{{{{{{{", -"............666666666666ZZZZZZZZZZZZbbbbbbbbbbbbPPPPPPPPPPPP````````````''''''''''''{{{{{{{{{{{{", -"............666666666666ZZZZZZZZZZZZbbbbbbbbbbbbPPPPPPPPPPPP````````````''''''''''''{{{{{{{{{{{{", -"............666666666666ZZZZZZZZZZZZbbbbbbbbbbbbPPPPPPPPPPPP````````````''''''''''''{{{{{{{{{{{{", -"............666666666666ZZZZZZZZZZZZbbbbbbbbbbbbPPPPPPPPPPPP````````````''''''''''''{{{{{{{{{{{{", -"............666666666666ZZZZZZZZZZZZbbbbbbbbbbbbPPPPPPPPPPPP````````````''''''''''''{{{{{{{{{{{{", -"............666666666666ZZZZZZZZZZZZbbbbbbbbbbbbPPPPPPPPPPPP````````````''''''''''''{{{{{{{{{{{{", -"............666666666666ZZZZZZZZZZZZbbbbbbbbbbbbPPPPPPPPPPPP````````````''''''''''''{{{{{{{{{{{{", -"aaaaaaaaaaaaiiiiiiiiiiiizzzzzzzzzzzzJJJJJJJJJJJJPPPPPPPPPPPP))))))))))))''''''''''''{{{{{{{{{{{{", -"aaaaaaaaaaaaiiiiiiiiiiiizzzzzzzzzzzzJJJJJJJJJJJJPPPPPPPPPPPP))))))))))))''''''''''''{{{{{{{{{{{{", -"aaaaaaaaaaaaiiiiiiiiiiiizzzzzzzzzzzzJJJJJJJJJJJJPPPPPPPPPPPP))))))))))))''''''''''''{{{{{{{{{{{{", -"aaaaaaaaaaaaiiiiiiiiiiiizzzzzzzzzzzzJJJJJJJJJJJJPPPPPPPPPPPP))))))))))))''''''''''''{{{{{{{{{{{{", -"aaaaaaaaaaaaiiiiiiiiiiiizzzzzzzzzzzzJJJJJJJJJJJJPPPPPPPPPPPP))))))))))))''''''''''''{{{{{{{{{{{{", -"aaaaaaaaaaaaiiiiiiiiiiiizzzzzzzzzzzzJJJJJJJJJJJJPPPPPPPPPPPP))))))))))))''''''''''''{{{{{{{{{{{{", -"aaaaaaaaaaaaiiiiiiiiiiiizzzzzzzzzzzzJJJJJJJJJJJJPPPPPPPPPPPP))))))))))))''''''''''''{{{{{{{{{{{{", -"aaaaaaaaaaaaiiiiiiiiiiiizzzzzzzzzzzzJJJJJJJJJJJJPPPPPPPPPPPP))))))))))))''''''''''''{{{{{{{{{{{{", -"aaaaaaaaaaaaiiiiiiiiiiiizzzzzzzzzzzzJJJJJJJJJJJJPPPPPPPPPPPP))))))))))))''''''''''''{{{{{{{{{{{{", -"aaaaaaaaaaaaiiiiiiiiiiiizzzzzzzzzzzzJJJJJJJJJJJJPPPPPPPPPPPP))))))))))))''''''''''''{{{{{{{{{{{{", -"aaaaaaaaaaaaiiiiiiiiiiiizzzzzzzzzzzzJJJJJJJJJJJJPPPPPPPPPPPP))))))))))))''''''''''''{{{{{{{{{{{{", -"aaaaaaaaaaaaiiiiiiiiiiiizzzzzzzzzzzzJJJJJJJJJJJJPPPPPPPPPPPP))))))))))))''''''''''''{{{{{{{{{{{{", -"............eeeeeeeeeeee444444444444IIIIIIIIIIIIWWWWWWWWWWWW))))))))))))''''''''''''}}}}}}}}}}}}", -"............eeeeeeeeeeee444444444444IIIIIIIIIIIIWWWWWWWWWWWW))))))))))))''''''''''''}}}}}}}}}}}}", -"............eeeeeeeeeeee444444444444IIIIIIIIIIIIWWWWWWWWWWWW))))))))))))''''''''''''}}}}}}}}}}}}", -"............eeeeeeeeeeee444444444444IIIIIIIIIIIIWWWWWWWWWWWW))))))))))))''''''''''''}}}}}}}}}}}}", -"............eeeeeeeeeeee444444444444IIIIIIIIIIIIWWWWWWWWWWWW))))))))))))''''''''''''}}}}}}}}}}}}", -"............eeeeeeeeeeee444444444444IIIIIIIIIIIIWWWWWWWWWWWW))))))))))))''''''''''''}}}}}}}}}}}}", -"............eeeeeeeeeeee444444444444IIIIIIIIIIIIWWWWWWWWWWWW))))))))))))''''''''''''}}}}}}}}}}}}", -"............eeeeeeeeeeee444444444444IIIIIIIIIIIIWWWWWWWWWWWW))))))))))))''''''''''''}}}}}}}}}}}}", -"............eeeeeeeeeeee444444444444IIIIIIIIIIIIWWWWWWWWWWWW))))))))))))''''''''''''}}}}}}}}}}}}", -"............eeeeeeeeeeee444444444444IIIIIIIIIIIIWWWWWWWWWWWW))))))))))))''''''''''''}}}}}}}}}}}}", -"............eeeeeeeeeeee444444444444IIIIIIIIIIIIWWWWWWWWWWWW))))))))))))''''''''''''}}}}}}}}}}}}", -"............eeeeeeeeeeee444444444444IIIIIIIIIIIIWWWWWWWWWWWW))))))))))))''''''''''''}}}}}}}}}}}}", -"llllllllllll444444444444HHHHHHHHHHHHvvvvvvvvvvvv((((((((((((____________]]]]]]]]]]]]}}}}}}}}}}}}", -"llllllllllll444444444444HHHHHHHHHHHHvvvvvvvvvvvv((((((((((((____________]]]]]]]]]]]]}}}}}}}}}}}}", -"llllllllllll444444444444HHHHHHHHHHHHvvvvvvvvvvvv((((((((((((____________]]]]]]]]]]]]}}}}}}}}}}}}", -"llllllllllll444444444444HHHHHHHHHHHHvvvvvvvvvvvv((((((((((((____________]]]]]]]]]]]]}}}}}}}}}}}}", -"llllllllllll444444444444HHHHHHHHHHHHvvvvvvvvvvvv((((((((((((____________]]]]]]]]]]]]}}}}}}}}}}}}", -"llllllllllll444444444444HHHHHHHHHHHHvvvvvvvvvvvv((((((((((((____________]]]]]]]]]]]]}}}}}}}}}}}}", -"llllllllllll444444444444HHHHHHHHHHHHvvvvvvvvvvvv((((((((((((____________]]]]]]]]]]]]}}}}}}}}}}}}", -"llllllllllll444444444444HHHHHHHHHHHHvvvvvvvvvvvv((((((((((((____________]]]]]]]]]]]]}}}}}}}}}}}}", -"llllllllllll444444444444HHHHHHHHHHHHvvvvvvvvvvvv((((((((((((____________]]]]]]]]]]]]}}}}}}}}}}}}", -"llllllllllll444444444444HHHHHHHHHHHHvvvvvvvvvvvv((((((((((((____________]]]]]]]]]]]]}}}}}}}}}}}}", -"llllllllllll444444444444HHHHHHHHHHHHvvvvvvvvvvvv((((((((((((____________]]]]]]]]]]]]}}}}}}}}}}}}", -"llllllllllll444444444444HHHHHHHHHHHHvvvvvvvvvvvv((((((((((((____________]]]]]]]]]]]]}}}}}}}}}}}}", -"qqqqqqqqqqqq111111111111ssssssssssssGGGGGGGGGGGGQQQQQQQQQQQQ____________[[[[[[[[[[[[{{{{{{{{{{{{", -"qqqqqqqqqqqq111111111111ssssssssssssGGGGGGGGGGGGQQQQQQQQQQQQ____________[[[[[[[[[[[[{{{{{{{{{{{{", -"qqqqqqqqqqqq111111111111ssssssssssssGGGGGGGGGGGGQQQQQQQQQQQQ____________[[[[[[[[[[[[{{{{{{{{{{{{", -"qqqqqqqqqqqq111111111111ssssssssssssGGGGGGGGGGGGQQQQQQQQQQQQ____________[[[[[[[[[[[[{{{{{{{{{{{{", -"qqqqqqqqqqqq111111111111ssssssssssssGGGGGGGGGGGGQQQQQQQQQQQQ____________[[[[[[[[[[[[{{{{{{{{{{{{", -"qqqqqqqqqqqq111111111111ssssssssssssGGGGGGGGGGGGQQQQQQQQQQQQ____________[[[[[[[[[[[[{{{{{{{{{{{{", -"qqqqqqqqqqqq111111111111ssssssssssssGGGGGGGGGGGGQQQQQQQQQQQQ____________[[[[[[[[[[[[{{{{{{{{{{{{", -"qqqqqqqqqqqq111111111111ssssssssssssGGGGGGGGGGGGQQQQQQQQQQQQ____________[[[[[[[[[[[[{{{{{{{{{{{{", -"qqqqqqqqqqqq111111111111ssssssssssssGGGGGGGGGGGGQQQQQQQQQQQQ____________[[[[[[[[[[[[{{{{{{{{{{{{", -"qqqqqqqqqqqq111111111111ssssssssssssGGGGGGGGGGGGQQQQQQQQQQQQ____________[[[[[[[[[[[[{{{{{{{{{{{{", -"qqqqqqqqqqqq111111111111ssssssssssssGGGGGGGGGGGGQQQQQQQQQQQQ____________[[[[[[[[[[[[{{{{{{{{{{{{", -"qqqqqqqqqqqq111111111111ssssssssssssGGGGGGGGGGGGQQQQQQQQQQQQ____________[[[[[[[[[[[[{{{{{{{{{{{{", -"ppppppppppppkkkkkkkkkkkkttttttttttttSSSSSSSSSSSS!!!!!!!!!!!!))))))))))))]]]]]]]]]]]]{{{{{{{{{{{{", -"ppppppppppppkkkkkkkkkkkkttttttttttttSSSSSSSSSSSS!!!!!!!!!!!!))))))))))))]]]]]]]]]]]]{{{{{{{{{{{{", -"ppppppppppppkkkkkkkkkkkkttttttttttttSSSSSSSSSSSS!!!!!!!!!!!!))))))))))))]]]]]]]]]]]]{{{{{{{{{{{{", -"ppppppppppppkkkkkkkkkkkkttttttttttttSSSSSSSSSSSS!!!!!!!!!!!!))))))))))))]]]]]]]]]]]]{{{{{{{{{{{{", -"ppppppppppppkkkkkkkkkkkkttttttttttttSSSSSSSSSSSS!!!!!!!!!!!!))))))))))))]]]]]]]]]]]]{{{{{{{{{{{{", -"ppppppppppppkkkkkkkkkkkkttttttttttttSSSSSSSSSSSS!!!!!!!!!!!!))))))))))))]]]]]]]]]]]]{{{{{{{{{{{{", -"ppppppppppppkkkkkkkkkkkkttttttttttttSSSSSSSSSSSS!!!!!!!!!!!!))))))))))))]]]]]]]]]]]]{{{{{{{{{{{{", -"ppppppppppppkkkkkkkkkkkkttttttttttttSSSSSSSSSSSS!!!!!!!!!!!!))))))))))))]]]]]]]]]]]]{{{{{{{{{{{{", -"ppppppppppppkkkkkkkkkkkkttttttttttttSSSSSSSSSSSS!!!!!!!!!!!!))))))))))))]]]]]]]]]]]]{{{{{{{{{{{{", -"ppppppppppppkkkkkkkkkkkkttttttttttttSSSSSSSSSSSS!!!!!!!!!!!!))))))))))))]]]]]]]]]]]]{{{{{{{{{{{{", -"ppppppppppppkkkkkkkkkkkkttttttttttttSSSSSSSSSSSS!!!!!!!!!!!!))))))))))))]]]]]]]]]]]]{{{{{{{{{{{{", -"ppppppppppppkkkkkkkkkkkkttttttttttttSSSSSSSSSSSS!!!!!!!!!!!!))))))))))))]]]]]]]]]]]]{{{{{{{{{{{{", -"ppppppppppppzzzzzzzzzzzzddddddddddddFFFFFFFFFFFFLLLLLLLLLLLL````````````''''''''''''{{{{{{{{{{{{", -"ppppppppppppzzzzzzzzzzzzddddddddddddFFFFFFFFFFFFLLLLLLLLLLLL````````````''''''''''''{{{{{{{{{{{{", -"ppppppppppppzzzzzzzzzzzzddddddddddddFFFFFFFFFFFFLLLLLLLLLLLL````````````''''''''''''{{{{{{{{{{{{", -"ppppppppppppzzzzzzzzzzzzddddddddddddFFFFFFFFFFFFLLLLLLLLLLLL````````````''''''''''''{{{{{{{{{{{{", -"ppppppppppppzzzzzzzzzzzzddddddddddddFFFFFFFFFFFFLLLLLLLLLLLL````````````''''''''''''{{{{{{{{{{{{", -"ppppppppppppzzzzzzzzzzzzddddddddddddFFFFFFFFFFFFLLLLLLLLLLLL````````````''''''''''''{{{{{{{{{{{{", -"ppppppppppppzzzzzzzzzzzzddddddddddddFFFFFFFFFFFFLLLLLLLLLLLL````````````''''''''''''{{{{{{{{{{{{", -"ppppppppppppzzzzzzzzzzzzddddddddddddFFFFFFFFFFFFLLLLLLLLLLLL````````````''''''''''''{{{{{{{{{{{{", -"ppppppppppppzzzzzzzzzzzzddddddddddddFFFFFFFFFFFFLLLLLLLLLLLL````````````''''''''''''{{{{{{{{{{{{", -"ppppppppppppzzzzzzzzzzzzddddddddddddFFFFFFFFFFFFLLLLLLLLLLLL````````````''''''''''''{{{{{{{{{{{{", -"ppppppppppppzzzzzzzzzzzzddddddddddddFFFFFFFFFFFFLLLLLLLLLLLL````````````''''''''''''{{{{{{{{{{{{", -"ppppppppppppzzzzzzzzzzzzddddddddddddFFFFFFFFFFFFLLLLLLLLLLLL````````````''''''''''''{{{{{{{{{{{{", -"666666666666************777777777777MMMMMMMMMMMMLLLLLLLLLLLL````````````''''''''''''{{{{{{{{{{{{", -"666666666666************777777777777MMMMMMMMMMMMLLLLLLLLLLLL````````````''''''''''''{{{{{{{{{{{{", -"666666666666************777777777777MMMMMMMMMMMMLLLLLLLLLLLL````````````''''''''''''{{{{{{{{{{{{", -"666666666666************777777777777MMMMMMMMMMMMLLLLLLLLLLLL````````````''''''''''''{{{{{{{{{{{{", -"666666666666************777777777777MMMMMMMMMMMMLLLLLLLLLLLL````````````''''''''''''{{{{{{{{{{{{", -"666666666666************777777777777MMMMMMMMMMMMLLLLLLLLLLLL````````````''''''''''''{{{{{{{{{{{{", -"666666666666************777777777777MMMMMMMMMMMMLLLLLLLLLLLL````````````''''''''''''{{{{{{{{{{{{", -"666666666666************777777777777MMMMMMMMMMMMLLLLLLLLLLLL````````````''''''''''''{{{{{{{{{{{{", -"666666666666************777777777777MMMMMMMMMMMMLLLLLLLLLLLL````````````''''''''''''{{{{{{{{{{{{", -"666666666666************777777777777MMMMMMMMMMMMLLLLLLLLLLLL````````````''''''''''''{{{{{{{{{{{{", -"666666666666************777777777777MMMMMMMMMMMMLLLLLLLLLLLL````````````''''''''''''{{{{{{{{{{{{", -"666666666666************777777777777MMMMMMMMMMMMLLLLLLLLLLLL````````````''''''''''''{{{{{{{{{{{{" -}; diff --git a/src/xpm/addressbook16.xpm b/src/xpm/addressbook16.xpm deleted file mode 100644 index e00944ef7a..0000000000 --- a/src/xpm/addressbook16.xpm +++ /dev/null @@ -1,278 +0,0 @@ -/* XPM */
-static const char * addressbook16_xpm[] = {
-/* columns rows colors chars-per-pixel */
-"16 16 256 2",
-" c #FFFFFF",
-". c #F7FFFF",
-"X c #F7F7FF",
-"o c #EFF7FF",
-"O c #E6EFF7",
-"+ c #E6E6F7",
-"@ c #CEE6F7",
-"# c #DEDEEF",
-"$ c #D6DEEF",
-"% c #D6DEE6",
-"& c #CEDEF7",
-"* c #CEDEEF",
-"= c #EFF708",
-"- c #C5DEF7",
-"; c #CED6EF",
-": c None",
-"> c #C5D6E6",
-", c #BDD6F7",
-"< c #BDD6EF",
-"1 c #D6CECE",
-"2 c #BDCEE6",
-"3 c #BDC5E6",
-"4 c #B5C5DE",
-"5 c #BDD631",
-"6 c #ADBDDE",
-"7 c #B5B5BD",
-"8 c #A5B5D6",
-"9 c #00FFFF",
-"0 c #9CB5CE",
-"q c #9CADD6",
-"w c #94A5D6",
-"e c #8CA5D6",
-"r c #8CA5CE",
-"t c #8CA5C5",
-"y c #849CC5",
-"u c #7B9CD6",
-"i c #7B9CCE",
-"p c #31BDCE",
-"a c #6B9CD6",
-"s c #00F708",
-"d c #8494AD",
-"f c #7B94B5",
-"g c #6B94D6",
-"h c #6B9C84",
-"j c #7B8CAD",
-"k c #738CAD",
-"l c #638CC5",
-"z c #10CE42",
-"x c #638CBD",
-"c c #7B849C",
-"v c #73849C",
-"b c #6B84A5",
-"n c #7B7BA5",
-"m c #6B849C",
-"M c #7B8C42",
-"N c #5A84C5",
-"B c #29AD6B",
-"V c #F74A4A",
-"C c #6384A5",
-"Z c #5284C5",
-"A c #637BA5",
-"S c #637B9C",
-"D c #9C637B",
-"F c #6B7B5A",
-"G c #637394",
-"H c #52739C",
-"J c #5A7384",
-"K c #526B94",
-"L c #426B94",
-"P c #52638C",
-"I c #426B7B",
-"U c #5A5A8C",
-"Y c #524A7B",
-"T c #425273",
-"R c #21636B",
-"E c #106394",
-"W c #106B52",
-"Q c #3A4273",
-"! c #31426B",
-"~ c #523163",
-"^ c #29426B",
-"/ c #293A63",
-"( c #213A63",
-") c #193A63",
-"_ c #193163",
-"` c #19315A",
-"' c #212963",
-"] c #10315A",
-"[ c #082952",
-"{ c #FFCC33",
-"} c #33FF33",
-"| c #66FF33",
-" . c #99FF33",
-".. c #CCFF33",
-"X. c #FFFF33",
-"o. c #000066",
-"O. c #330066",
-"+. c #660066",
-"@. c #990066",
-"#. c #CC0066",
-"$. c #FF0066",
-"%. c #003366",
-"&. c #333366",
-"*. c #663366",
-"=. c #993366",
-"-. c #CC3366",
-";. c #FF3366",
-":. c #006666",
-">. c #336666",
-",. c #666666",
-"<. c #996666",
-"1. c #CC6666",
-"2. c #009966",
-"3. c #339966",
-"4. c #669966",
-"5. c #999966",
-"6. c #CC9966",
-"7. c #FF9966",
-"8. c #00CC66",
-"9. c #33CC66",
-"0. c #99CC66",
-"q. c #CCCC66",
-"w. c #FFCC66",
-"e. c #00FF66",
-"r. c #33FF66",
-"t. c #99FF66",
-"y. c #CCFF66",
-"u. c #FF00CC",
-"i. c #CC00FF",
-"p. c #009999",
-"a. c #993399",
-"s. c #990099",
-"d. c #CC0099",
-"f. c #000099",
-"g. c #333399",
-"h. c #660099",
-"j. c #CC3399",
-"k. c #FF0099",
-"l. c #006699",
-"z. c #336699",
-"x. c #663399",
-"c. c #996699",
-"v. c #CC6699",
-"b. c #FF3399",
-"n. c #339999",
-"m. c #669999",
-"M. c #999999",
-"N. c #CC9999",
-"B. c #FF9999",
-"V. c #00CC99",
-"C. c #33CC99",
-"Z. c #66CC66",
-"A. c #99CC99",
-"S. c #CCCC99",
-"D. c #FFCC99",
-"F. c #00FF99",
-"G. c #33FF99",
-"H. c #66CC99",
-"J. c #99FF99",
-"K. c #CCFF99",
-"L. c #FFFF99",
-"P. c #0000CC",
-"I. c #330099",
-"U. c #6600CC",
-"Y. c #9900CC",
-"T. c #CC00CC",
-"R. c #003399",
-"E. c #3333CC",
-"W. c #6633CC",
-"Q. c #9933CC",
-"!. c #CC33CC",
-"~. c #FF33CC",
-"^. c #0066CC",
-"/. c #3366CC",
-"(. c #666699",
-"). c #9966CC",
-"_. c #CC66CC",
-"`. c #FF6699",
-"'. c #0099CC",
-"]. c #3399CC",
-"[. c #6699CC",
-"{. c #9999CC",
-"}. c #CC99CC",
-"|. c #FF99CC",
-" X c #00CCCC",
-".X c #33CCCC",
-"XX c #66CCCC",
-"oX c #99CCCC",
-"OX c #CCCCCC",
-"+X c #FFCCCC",
-"@X c #00FFCC",
-"#X c #33FFCC",
-"$X c #66FF99",
-"%X c #99FFCC",
-"&X c #CCFFCC",
-"*X c #FFFFCC",
-"=X c #3300CC",
-"-X c #6600FF",
-";X c #9900FF",
-":X c #0033CC",
-">X c #3333FF",
-",X c #6633FF",
-"<X c #9933FF",
-"1X c #CC33FF",
-"2X c #FF33FF",
-"3X c #0066FF",
-"4X c #3366FF",
-"5X c #6666CC",
-"6X c #9966FF",
-"7X c #CC66FF",
-"8X c #FF66CC",
-"9X c #0099FF",
-"0X c #3399FF",
-"qX c #6699FF",
-"wX c #9999FF",
-"eX c #CC99FF",
-"rX c #FF99FF",
-"tX c #00CCFF",
-"yX c #33CCFF",
-"uX c #66CCFF",
-"iX c #99CCFF",
-"pX c #CCCCFF",
-"aX c #FFCCFF",
-"sX c #33FFFF",
-"dX c #66FFCC",
-"fX c #99FFFF",
-"gX c #CCFFFF",
-"hX c #FF6666",
-"jX c #66FF66",
-"kX c #FFFF66",
-"lX c #6666FF",
-"zX c #FF66FF",
-"xX c #66FFFF",
-"cX c #A50021",
-"vX c #5F5F5F",
-"bX c #777777",
-"nX c #868686",
-"mX c #969696",
-"MX c #CBCBCB",
-"NX c #B2B2B2",
-"BX c #D7D7D7",
-"VX c #DDDDDD",
-"CX c #E3E3E3",
-"ZX c #EAEAEA",
-"AX c #F1F1F1",
-"SX c #F8F8F8",
-"DX c #FFFBF0",
-"FX c #A0A0A4",
-"GX c #808080",
-"HX c #FF0000",
-"JX c #00FF00",
-"KX c #FFFF00",
-"LX c #0000FF",
-"PX c #FF00FF",
-"IX c #00FFFF",
-"UX c #FFFFFF",
-/* pixels */
-": : : : : : : : : : : : : : : : ",
-": : H H H A d : 7 G K H H : : : ",
-"n n c X 4 k j X b n n : ",
-"n 2 c $ 8 6 4 x < + 4 4 C V ~ : ",
-"n * c X o $ y N u 6 $ + b D Y : ",
-"n * c X > g , S z R : ",
-"n * c * r r y g , 6 r q S s W : ",
-"n * c X 4 N u + m B I : ",
-"n * c X ; a - S 5 F : ",
-"n * c * r r r g - S = M : ",
-"n * c X 4 N - m h J : ",
-"n * c X ; a - A 9 E : ",
-"n * ( ] ` ^ P l y T / / ( p L : ",
-"n O > 0 f ) ! t 8 % n : ",
-"U U U U U U U ' Q U U U U U U : ",
-": : : : : : : : : : : : : : : : "
-};
diff --git a/src/xpm/addressbook20.xpm b/src/xpm/addressbook20.xpm deleted file mode 100644 index 7ebd73fb2f..0000000000 --- a/src/xpm/addressbook20.xpm +++ /dev/null @@ -1,282 +0,0 @@ -/* XPM */
-static const char * addressbook20_xpm[] = {
-/* columns rows colors chars-per-pixel */
-"20 20 256 2",
-" c #FFFFFF",
-". c #F7FFFF",
-"X c #F7F7FF",
-"o c #EFF7FF",
-"O c #EFF7F7",
-"+ c #E6EFFF",
-"@ c #E6EFF7",
-"# c #DEEFFF",
-"$ c #DEE6F7",
-"% c #DEE6EF",
-"& c #D6E6F7",
-"* c #FFFF00",
-"= c #DEDEE6",
-"- c #D6DEE6",
-"; c #D6D6DE",
-": c #CED6E6",
-"> c None",
-", c #C5D6E6",
-"< c #C5CEE6",
-"1 c #B5CEEF",
-"2 c #C5C5C5",
-"3 c #C5DE31",
-"4 c #B5C5DE",
-"5 c #BDC5C5",
-"6 c #ADC5EF",
-"7 c #B5C5CE",
-"8 c #BDBDBD",
-"9 c #B5BDCE",
-"0 c #ADBDDE",
-"q c #ADBDD6",
-"w c #B5CE52",
-"e c #ADB5C5",
-"r c #00FFFF",
-"t c #A5B5C5",
-"y c #9CB5CE",
-"u c #94B5DE",
-"i c #9CADD6",
-"p c #A5ADB5",
-"a c #94ADDE",
-"s c #94ADD6",
-"d c #9CADBD",
-"f c #8CADDE",
-"g c #BD9CA5",
-"h c #9CA5BD",
-"j c #9CA5B5",
-"k c #29D6E6",
-"l c #8CA5CE",
-"z c #849CCE",
-"x c #6BA5C5",
-"c c #739CDE",
-"v c #00FF00",
-"b c #739CD6",
-"n c #7B94CE",
-"m c #8494AD",
-"M c #7394CE",
-"N c #7B94B5",
-"B c #4AB584",
-"V c #848CB5",
-"C c #6B94CE",
-"Z c #6394D6",
-"A c #6394CE",
-"S c #7B8CAD",
-"D c #6B8CC5",
-"F c #738CAD",
-"G c #5294B5",
-"H c #6B84C5",
-"J c #7384A5",
-"K c #73849C",
-"L c #738494",
-"P c #FF4A4A",
-"I c #FF4A42",
-"U c #737B8C",
-"Y c #637BAD",
-"T c #527BBD",
-"R c #637394",
-"E c #637352",
-"W c #5A6B8C",
-"Q c #526B9C",
-"! c #63638C",
-"~ c #5A734A",
-"^ c #4A6B9C",
-"/ c #526B63",
-"( c #0884A5",
-") c #526384",
-"_ c #52637B",
-"` c #4A6B5A",
-"' c #52636B",
-"] c #525A8C",
-"[ c #525A7B",
-"{ c #426363",
-"} c #4A5A7B",
-"| c #425A8C",
-" . c #196B94",
-".. c #3A5A8C",
-"X. c #3A5A84",
-"o. c #087B4A",
-"O. c #21636B",
-"+. c #634263",
-"@. c #3A527B",
-"#. c #424A84",
-"$. c #315284",
-"%. c #295284",
-"&. c #3A4A6B",
-"*. c #42427B",
-"=. c #424273",
-"-. c #294A84",
-";. c #3A3A73",
-":. c #194284",
-">. c #104A63",
-",. c #213A6B",
-"<. c #31316B",
-"1. c #21315A",
-"2. c #212163",
-"3. c #08295A",
-"4. c #082152",
-"5. c #101952",
-"6. c #CC9966",
-"7. c #FF9966",
-"8. c #00CC66",
-"9. c #33CC66",
-"0. c #99CC66",
-"q. c #CCCC66",
-"w. c #FFCC66",
-"e. c #00FF66",
-"r. c #33FF66",
-"t. c #99FF66",
-"y. c #CCFF66",
-"u. c #FF00CC",
-"i. c #CC00FF",
-"p. c #009999",
-"a. c #993399",
-"s. c #990099",
-"d. c #CC0099",
-"f. c #000099",
-"g. c #333399",
-"h. c #660099",
-"j. c #CC3399",
-"k. c #FF0099",
-"l. c #006699",
-"z. c #336699",
-"x. c #663399",
-"c. c #996699",
-"v. c #CC6699",
-"b. c #FF3399",
-"n. c #339999",
-"m. c #669999",
-"M. c #999999",
-"N. c #CC9999",
-"B. c #FF9999",
-"V. c #00CC99",
-"C. c #33CC99",
-"Z. c #66CC66",
-"A. c #99CC99",
-"S. c #CCCC99",
-"D. c #FFCC99",
-"F. c #00FF99",
-"G. c #33FF99",
-"H. c #66CC99",
-"J. c #99FF99",
-"K. c #CCFF99",
-"L. c #FFFF99",
-"P. c #0000CC",
-"I. c #330099",
-"U. c #6600CC",
-"Y. c #9900CC",
-"T. c #CC00CC",
-"R. c #003399",
-"E. c #3333CC",
-"W. c #6633CC",
-"Q. c #9933CC",
-"!. c #CC33CC",
-"~. c #FF33CC",
-"^. c #0066CC",
-"/. c #3366CC",
-"(. c #666699",
-"). c #9966CC",
-"_. c #CC66CC",
-"`. c #FF6699",
-"'. c #0099CC",
-"]. c #3399CC",
-"[. c #6699CC",
-"{. c #9999CC",
-"}. c #CC99CC",
-"|. c #FF99CC",
-" X c #00CCCC",
-".X c #33CCCC",
-"XX c #66CCCC",
-"oX c #99CCCC",
-"OX c #CCCCCC",
-"+X c #FFCCCC",
-"@X c #00FFCC",
-"#X c #33FFCC",
-"$X c #66FF99",
-"%X c #99FFCC",
-"&X c #CCFFCC",
-"*X c #FFFFCC",
-"=X c #3300CC",
-"-X c #6600FF",
-";X c #9900FF",
-":X c #0033CC",
-">X c #3333FF",
-",X c #6633FF",
-"<X c #9933FF",
-"1X c #CC33FF",
-"2X c #FF33FF",
-"3X c #0066FF",
-"4X c #3366FF",
-"5X c #6666CC",
-"6X c #9966FF",
-"7X c #CC66FF",
-"8X c #FF66CC",
-"9X c #0099FF",
-"0X c #3399FF",
-"qX c #6699FF",
-"wX c #9999FF",
-"eX c #CC99FF",
-"rX c #FF99FF",
-"tX c #00CCFF",
-"yX c #33CCFF",
-"uX c #66CCFF",
-"iX c #99CCFF",
-"pX c #CCCCFF",
-"aX c #FFCCFF",
-"sX c #33FFFF",
-"dX c #66FFCC",
-"fX c #99FFFF",
-"gX c #CCFFFF",
-"hX c #FF6666",
-"jX c #66FF66",
-"kX c #FFFF66",
-"lX c #6666FF",
-"zX c #FF66FF",
-"xX c #66FFFF",
-"cX c #A50021",
-"vX c #5F5F5F",
-"bX c #777777",
-"nX c #868686",
-"mX c #969696",
-"MX c #CBCBCB",
-"NX c #B2B2B2",
-"BX c #D7D7D7",
-"VX c #DDDDDD",
-"CX c #E3E3E3",
-"ZX c #EAEAEA",
-"AX c #F1F1F1",
-"SX c #F8F8F8",
-"DX c #FFFBF0",
-"FX c #A0A0A4",
-"GX c #808080",
-"HX c #FF0000",
-"JX c #00FF00",
-"KX c #FFFF00",
-"LX c #0000FF",
-"PX c #FF00FF",
-"IX c #00FFFF",
-"UX c #FFFFFF",
-/* pixels */
-"> > > > > > > > > > > > > > > > > > > > ",
-"> > > > > > > > > > > > > > > > > > > > ",
-"> > U $.| | ^ S 2 > p W | | @.L > > > > ",
-"8 5 R - < Y j S O - ) g e > > ",
-"! V K - % a Q # - +.P <.> > ",
-"! & K - 0 z n D C b f n n z q +.P <.> > ",
-"! & K - % M A 1 - %.G #.> > ",
-"! & K - % u b # - o.v >.> > ",
-"! & K - 0 z n H M b 6 z n z q o.v >.> > ",
-"! & K - X - M A a - O.B @.> > ",
-"! & K - X % u b # - ` 3 / > > ",
-"! & K - 0 l i 4 u b # - ~ * E > > ",
-"! & K - X o $ s T b # - { w ' > > ",
-"! & K - % f b # - .k -.> > ",
-"! & K m d t 7 , u b # ; 9 9 h ( r :.> > ",
-"! & h _ _ [ &.4.$.A ,.1.} _ _ F x ] > > ",
-"! @ , y N _ 3._ N y , @ ! > > ",
-"*.*.*.*.*.*.*.*.;.5.*.*.*.*.*.*.*.2.> > ",
-"> > > > > > > > > > > > > > > > > > > > ",
-"> > > > > > > > > > > > > > > > > > > > "
-};
diff --git a/src/xpm/bitcoin16.xpm b/src/xpm/bitcoin16.xpm deleted file mode 100644 index f70fef026a..0000000000 --- a/src/xpm/bitcoin16.xpm +++ /dev/null @@ -1,219 +0,0 @@ -/* XPM */ -static const char * bitcoin16_xpm[] = { -/* columns rows colors chars-per-pixel */ -"16 16 197 2", -" c #755507", -". c #775606", -"X c #795707", -"o c #7D5A07", -"O c #765608", -"+ c #74550A", -"@ c #75550A", -"# c #75560A", -"$ c #785708", -"% c #78580B", -"& c #7D5C0B", -"* c #78590E", -"= c #7E5F14", -"- c #8A6711", -"; c #8D6B15", -": c #8A691A", -"> c #93711C", -", c #9D7A23", -"< c #9F7B22", -"1 c #9C7B2A", -"2 c #9E7C28", -"3 c #A37F26", -"4 c #B4831B", -"5 c #A68126", -"6 c #A5852E", -"7 c #A9872E", -"8 c #AC862D", -"9 c #AC872F", -"0 c #AF8B30", -"q c #AC8932", -"w c #AF8A34", -"e c #B08E36", -"r c #B98F33", -"t c #B18E3A", -"y c #B39036", -"u c #B69237", -"i c #B3913B", -"p c #B6923C", -"a c #BD9338", -"s c #B9993F", -"d c #BA993F", -"f c #C2932D", -"g c #C09437", -"h c #C59832", -"j c #C39836", -"k c #C89835", -"l c #C59C3D", -"z c #CF9E3E", -"x c #CFA23F", -"c c #D0A13A", -"v c #D3A23A", -"b c #D4A338", -"n c #D6A33F", -"m c #B19345", -"M c #BF9940", -"N c #BF9D43", -"B c #B3954B", -"V c #BD9A48", -"C c #BC9C4B", -"Z c #BD9F51", -"A c #CAA244", -"S c #C2A14B", -"D c #C4A44B", -"F c #C1A24C", -"G c #C7A64C", -"H c #C5A64E", -"J c #C9A94F", -"K c #D1A343", -"L c #D7A644", -"P c #D5A547", -"I c #D6A547", -"U c #DCAD42", -"Y c #DDAB45", -"T c #C3A151", -"R c #C9A551", -"E c #CAAA50", -"W c #CBAD53", -"Q c #CDAC52", -"! c #CEA855", -"~ c #CEB15A", -"^ c #DEB154", -"/ c #D1B35A", -"( c #D7B35A", -") c #D8B45D", -"_ c #E3B34A", -"` c #E2B34E", -"' c #E6B54F", -"] c #E2B350", -"[ c #E3B352", -"{ c #E4B451", -"} c #E2B355", -"| c #E7B853", -" . c #E9BC51", -".. c #ECBC53", -"X. c #E7BE5A", -"o. c #E2BA5C", -"O. c #E2BC5C", -"+. c #E9BB59", -"@. c #EBBE59", -"#. c #EABD5B", -"$. c #E8BF5C", -"%. c #E9BE5E", -"&. c #C8AC63", -"*. c #D0B162", -"=. c #D5B567", -"-. c #DABC62", -";. c #D2B66B", -":. c #D0B56D", -">. c #DCBC6E", -",. c #D2B972", -"<. c #D7BE78", -"1. c #E9BE62", -"2. c #EEC05A", -"3. c #F0C25F", -"4. c #DEC26B", -"5. c #DDC27A", -"6. c #E0C167", -"7. c #E5C067", -"8. c #EBC463", -"9. c #EEC460", -"0. c #ECC364", -"q. c #E4C16B", -"w. c #E7C46B", -"e. c #E9C56C", -"r. c #E0C172", -"t. c #E5C575", -"y. c #E4C870", -"u. c #E6CA72", -"i. c #E6CA74", -"p. c #E8CB73", -"a. c #E9CE76", -"s. c #EBD07B", -"d. c #EED179", -"f. c #F5D478", -"g. c #F5D57C", -"h. c #F4D67C", -"j. c #F4D77E", -"k. c #DEC781", -"l. c #E0C883", -"z. c #E3CA89", -"x. c #E4CB8B", -"c. c #E3CD8A", -"v. c #E5CE8B", -"b. c #E3CC8E", -"n. c #E8D18D", -"m. c #F6D980", -"M. c #F7DB83", -"N. c #F3DA86", -"B. c #F7DA84", -"V. c #F6DB84", -"C. c #F7DB84", -"Z. c #F7DA86", -"A. c #F6DC85", -"S. c #F7DC85", -"D. c #F8DB85", -"F. c #FADD85", -"G. c #FBDE86", -"H. c #F5DE8B", -"J. c #FADD88", -"K. c #F9DF8B", -"L. c #E4CF93", -"P. c #E6CF92", -"I. c #E6D094", -"U. c #EAD597", -"Y. c #EBD698", -"T. c #EFDA99", -"R. c #F0DC9C", -"E. c #FCE089", -"W. c #FCE28B", -"Q. c #FDE28B", -"!. c #FCE38C", -"~. c #FCE28D", -"^. c #FCE38D", -"/. c #FDE38D", -"(. c #FEE38D", -"). c #FDE38E", -"_. c #FEE48D", -"`. c #FEE58F", -"'. c #FCE490", -"]. c #FDE490", -"[. c #FFE590", -"{. c #FFE690", -"}. c #FFE691", -"|. c #FEE791", -" X c #FFE692", -".X c #FFE792", -"XX c #FEE693", -"oX c #FFE693", -"OX c #FFE793", -"+X c #FEE897", -"@X c #F6E2A2", -"#X c #F7E3A2", -"$X c #FAE6A8", -"%X c #FBE7A9", -"&X c #FCE9AB", -"*X c #FDEAAC", -"=X c None", -/* pixels */ -"=X=X=X=X=X0 S G D i =X=X=X=X=X=X", -"=X=X=X9 6.).).).).).d.e =X=X=X=X", -"=X=Xu C.J.O.( h ( o.D.).J & =X=X", -"=X0 S.j.f 4 b.e P.K @.j.'.d % =X", -"=X4.).k a T Y.&.Y.R 2.2.F.S.- =X", -"e '.e.z ! v.&X,.k.*X:. .%.`.d # ", -"H +X^ I P =.*X9 j T.k.U ' F.-.% ", -"W '.` { } >.*X<.n.*XC b Y g.u.X ", -"W |.` { 3.t.&Xm C c.%Xa n m.u.. ", -"N '.9...@.r.&Xi A 5.*XM L W.~ . ", -"5 m.f._ *.#X&XR.#X%X:.v 0.'.7 # ", -"=XQ `.@.l t P.B I.u v { G.a.o =X", -"=X3 u.W.0.A z.V b.+.1.J.E., # =X", -"=X=X3 u.oXF.e.7.q.C.+XH.6 # =X=X", -"=X=X=X=XS s.'.'.'.C.~ ; * =X=X=X", -"=X=X=X=X=X=X1 1 > : = =X=X=X=X=X" -}; diff --git a/src/xpm/bitcoin20.xpm b/src/xpm/bitcoin20.xpm deleted file mode 100644 index 3cc29ac14b..0000000000 --- a/src/xpm/bitcoin20.xpm +++ /dev/null @@ -1,160 +0,0 @@ -/* XPM */ -static const char * bitcoin20_xpm[] = { -/* columns rows colors chars-per-pixel */ -"20 20 134 2", -" c #735305", -". c #785706", -"X c #7E5C07", -"o c #755509", -"O c #76580D", -"+ c #7F6015", -"@ c #85620D", -"# c #89650D", -"$ c #836215", -"% c #886510", -"& c #8E6B11", -"* c #81641F", -"= c #906D19", -"- c #977116", -"; c #96741E", -": c #9B761E", -"> c #947424", -", c #9B7722", -"< c #9D7824", -"1 c #A47F23", -"2 c #A17D2A", -"3 c #A58125", -"4 c #AA8327", -"5 c #A4832F", -"6 c #AD862B", -"7 c #B28B2E", -"8 c #A58433", -"9 c #A88637", -"0 c #AD8932", -"q c #A78639", -"w c #A8893C", -"e c #B28C34", -"r c #B88E33", -"t c #B28E3A", -"y c #B79136", -"u c #BB9235", -"i c #BB9639", -"p c #C19836", -"a c #C29539", -"s c #C59C3C", -"d c #A88B41", -"f c #AF9045", -"g c #B49342", -"h c #BE9641", -"j c #BD9B44", -"k c #B29448", -"l c #B7994B", -"z c #B8994C", -"x c #C09946", -"c c #CB9E46", -"v c #C59D4C", -"b c #CFA246", -"n c #CBAB47", -"m c #CEA74A", -"M c #D4A749", -"N c #D6A94D", -"B c #C7A754", -"V c #CEA453", -"C c #C6AA56", -"Z c #CDA955", -"A c #CBAB5B", -"S c #D2AB54", -"D c #D2AE5E", -"F c #D9AE5A", -"G c #D7B356", -"H c #DDB35F", -"J c #DFB95A", -"K c #E1B554", -"L c #E4BA56", -"P c #E6BC5A", -"I c #E9BE5E", -"U c #C7AC64", -"Y c #CBAF64", -"T c #CDB166", -"R c #D4B364", -"E c #DBB463", -"W c #DFB867", -"Q c #D5B76B", -"! c #DFBA6F", -"~ c #D5BB76", -"^ c #D7BE79", -"/ c #E3BC64", -"( c #E8BF64", -") c #E0BB68", -"_ c #DECA7A", -"` c #EBC265", -"' c #EBC36B", -"] c #EFC96B", -"[ c #F1C564", -"{ c #F3CB6A", -"} c #F9CD6C", -"| c #FAD16C", -" . c #E5C770", -".. c #EEC774", -"X. c #E6CE7E", -"o. c #EFCE7A", -"O. c #F1CB73", -"+. c #F4CE7A", -"@. c #F3D273", -"#. c #FCD574", -"$. c #FEDA76", -"%. c #F5D47D", -"&. c #FAD47B", -"*. c #F2D97D", -"=. c #FCDA7A", -"-. c #DDC784", -";. c #E1CA86", -":. c #E4CE8B", -">. c #ECD985", -",. c #E7D18E", -"<. c #F4DC84", -"1. c #FCDC81", -"2. c #F4DB8B", -"3. c #FBDF8B", -"4. c #EBD592", -"5. c #EFDA99", -"6. c #F1DD9C", -"7. c #F6E081", -"8. c #FDE484", -"9. c #FFEA87", -"0. c #F9E488", -"q. c #FEE88D", -"w. c #F9E394", -"e. c #FFEB93", -"r. c #FEE698", -"t. c #FEEA9B", -"y. c #FFF49A", -"u. c #F7E4A4", -"i. c #F9E5A5", -"p. c #FCE9AA", -"a. c #F7F0AA", -"s. c #FEF1AE", -"d. c #FEF6B3", -"f. c None", -/* pixels */ -"f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.", -"f.f.f.f.f.f.f.0 y i i 0 , f.f.f.f.f.f.f.", -"f.f.f.f.3 p P | $.| } { I p ; f.f.f.f.f.", -"f.f.f.4 L | $.{ L K L ` =.#.` 3 $ f.f.f.", -"f.f.6 [ $.{ M a Q 0 Q S ' %.q.*.6 o f.f.", -"f.3 ' $.P i u r ,.< :.S +.%.0.y.*.& f.f.", -"f.C e.%.c x T Y 6.U 5.T R @.#.0.9.n . f.", -"f.>.t.W F A ^ p.u.~ -.p.i.C { { =.@.# f.", -"e e.3.E H / j p.6.0 V ~ p.Y ( ` #.$.3 o ", -"j p.2.( ( ! Z p.6.l R 6.6.t I I { #.y o ", -"j e.1.( ! +.H i.i.-.:.i.u.R N K ` #.u ", -"i 9.&.( ..1.) p.6.8 j w p.p.h N ' #.7 ", -"4 =.7.` ....Z p.6.g D T p.i.t M [ } - o ", -"f.J =.{ ` E i.p.p.i.p.p.6.k u M } K @ o ", -"f.7 @.@./ S z f 4.d ,.q 2 r a ( { 6 f.", -"f.f.m @.O.( / V 4.q :.v V V O.&.G X O f.", -"f.f.: G 1.0.+.W R D R ! 4.d.d._ # f.f.", -"f.f.f.2 C a.i.r.w.w.i.s.d.p.Y @ f.f.f.", -"f.f.f.f.f.5 Z .<.3.2.X.A > . f.f.f.f.", -"f.f.f.f.f.f.f.> > = # $ + f.f.f.f.f.f.f." -}; diff --git a/src/xpm/bitcoin32.xpm b/src/xpm/bitcoin32.xpm deleted file mode 100644 index f538a44d2d..0000000000 --- a/src/xpm/bitcoin32.xpm +++ /dev/null @@ -1,232 +0,0 @@ -/* XPM */ -static const char * bitcoin32_xpm[] = { -/* columns rows colors chars-per-pixel */ -"32 32 194 2", -" c #745305", -". c #785704", -"X c #7C5903", -"o c #75560B", -"O c #77590F", -"+ c #7C5C0B", -"@ c #795B12", -"# c #7F631D", -"$ c #825E07", -"% c #825F0B", -"& c #85610A", -"* c #8C660C", -"= c #8E680E", -"- c #916B0F", -"; c #856515", -": c #8B6714", -"> c #8F6A16", -", c #816218", -"< c #88691C", -"1 c #926D12", -"2 c #936F1C", -"3 c #997417", -"4 c #94721E", -"5 c #9B761C", -"6 c #9F781C", -"7 c #A17B1E", -"8 c #826622", -"9 c #916E20", -"0 c #967425", -"q c #9D7420", -"w c #9C7923", -"e c #997728", -"r c #99792C", -"t c #A37D23", -"y c #A37F2C", -"u c #A68125", -"i c #AB8225", -"p c #A5832B", -"a c #AA852C", -"s c #B28A2C", -"d c #A58233", -"f c #AC8734", -"g c #AE8C33", -"h c #AC8C3C", -"j c #B28C33", -"k c #B98E34", -"l c #B28D3D", -"z c #B59136", -"x c #BC9335", -"c c #B3913E", -"v c #BC933A", -"b c #BF9A3D", -"n c #C19235", -"m c #C2953C", -"M c #C39B3C", -"N c #CA9C3D", -"B c #B59343", -"V c #BE9642", -"C c #B69A44", -"Z c #BD9A45", -"A c #B49649", -"S c #BB9A49", -"D c #BB9F52", -"F c #BFA256", -"G c #C49C43", -"H c #CA9D41", -"J c #C59D4A", -"K c #C99E4D", -"L c #C3A144", -"P c #CDA244", -"I c #CFAA47", -"U c #C3A14D", -"Y c #CDA24A", -"T c #CCAB49", -"R c #D2A644", -"E c #D2A54B", -"W c #D6AA4C", -"Q c #DAAE4E", -"! c #DAB04F", -"~ c #C7A656", -"^ c #CDA452", -"/ c #CFAC52", -"( c #C0A65E", -") c #CEA75A", -"_ c #CCAC59", -"` c #D2AB53", -"' c #DCAF52", -"] c #D6AD5A", -"[ c #D9AE5B", -"{ c #DCB556", -"} c #DFB855", -"| c #D6B25F", -" . c #DCB35C", -".. c #DEBE5E", -"X. c #E2B656", -"o. c #E1B55A", -"O. c #E6BC5D", -"+. c #E9BD5E", -"@. c #C3AA63", -"#. c #CCAD62", -"$. c #D4AF62", -"%. c #CDB565", -"&. c #CEB46D", -"*. c #D7B164", -"=. c #DBB362", -"-. c #D6BD64", -";. c #DDBA64", -":. c #D3B66C", -">. c #DFB86B", -",. c #CEB772", -"<. c #D0B771", -"1. c #D4BA73", -"2. c #D9BE77", -"3. c #D6BE79", -"4. c #D8BF7A", -"5. c #E4BB62", -"6. c #E9BF64", -"7. c #E4BC69", -"8. c #E9BF69", -"9. c #E0BB71", -"0. c #E9C05E", -"q. c #D2C279", -"w. c #DBC27C", -"e. c #E2C667", -"r. c #EDC364", -"t. c #E3C16E", -"y. c #ECC46C", -"u. c #EDCC6C", -"i. c #F1C764", -"p. c #F5CA66", -"a. c #F9CD67", -"s. c #F5CC6A", -"d. c #F9CD6B", -"f. c #FBD36F", -"g. c #EDC572", -"h. c #E5CF77", -"j. c #ECCA74", -"k. c #E0C67E", -"l. c #EFCE78", -"z. c #F6CE72", -"x. c #FBCF71", -"c. c #F4CE79", -"v. c #F4D273", -"b. c #FCD473", -"n. c #F4DC75", -"m. c #FEDA74", -"M. c #F6D77C", -"N. c #FBD47A", -"B. c #F1DA7B", -"V. c #FDDA7C", -"C. c #FEE27D", -"Z. c #DDC683", -"A. c #DFC884", -"S. c #E4CA84", -"D. c #E3CC89", -"F. c #E7D183", -"G. c #EFD280", -"H. c #EFDC82", -"J. c #ECD48D", -"K. c #EFDA8C", -"L. c #F9D783", -"P. c #F2DF83", -"I. c #FCDB83", -"U. c #F5DC8F", -"Y. c #FADD8B", -"T. c #EBD593", -"R. c #EFDA99", -"E. c #F3DD93", -"W. c #F3DF9F", -"Q. c #FFE385", -"!. c #FEE986", -"~. c #FDE48C", -"^. c #FEEC8E", -"/. c #ECE199", -"(. c #F6E591", -"). c #FEE494", -"_. c #FEEB93", -"`. c #FEE69A", -"'. c #FFEB9B", -"]. c #FFF197", -"[. c #FFF39B", -"{. c #FEF99B", -"}. c #F6E2A2", -"|. c #F9E5A5", -" X c #F7E9A5", -".X c #FEECA4", -"XX c #FBE7A8", -"oX c #FDEAAB", -"OX c #F7F2AA", -"+X c #FEF2AC", -"@X c #FDF4B4", -"#X c #FFFABA", -"$X c #FFFEC2", -"%X c None", -/* pixels */ -"%X%X%X%X%X%X%X%X%X%X%X%Xp t 6 5 w t w %X%X%X%X%X%X%X%X%X%X%X%X%X", -"%X%X%X%X%X%X%X%X%Xu u x I X.0.s.u.0.W x 7 4 %X%X%X%X%X%X%X%X%X%X", -"%X%X%X%X%X%X%Xy i I i.a.f.m.m.b.f.s.a.s.i.W 7 > %X%X%X%X%X%X%X%X", -"%X%X%X%X%X%Xt M 0.a.m.m.m.m.f.d.p.p.p.f.d.f.i.b 1 < %X%X%X%X%X%X", -"%X%X%X%X%X7 ! d.f.f.m.f.+.W P R I Q 5.v.V.V.z.f.{ 5 + %X%X%X%X%X", -"%X%X%X%Xu X.f.m.m.f.' H s ~ V y _ Z J o.g.L.L.Q.!.e.5 X %X%X%X%X", -"%X%X%Xu X.b.C.m.+.N m n t }.3.> }.w.V 5.y.y.Y.[.^.^.-.1 + %X%X%X", -"%X%Xt P m.N.m.X.v v v k 6 }.1.: /.4.c 7.N.N.v.!.{.{.^.L & %X%X%X", -"%X%Xg Y.Y.V.+.m k a t t : }.1.% }.1.r | l.B.M.b.!.{.^.n.7 X %X%X", -"%Xp -._.'.Y.' Y n D.}.}.|.oXXX|.oX XT.w.F _ j.v.v._.^.C.T & @ %X", -"%Xa (.'.'.9.[ [ K S.}.oXoXoXoXXXoXoXoXoX XD / s.d.v.!.C.v.3 o %X", -"%XU '.'.Y.[ [ [ [ J f <.oXoX( 2 f S J.oXoXT.j r.s.i.C.C.C.z X %X", -"p e.'.'.F. .=.=.=.=.) 1.oXoX@.f . .F oXoX}.a +.i.i.b.C.m.I X O ", -"u w.'.[.j.5.8.7.7.7.] 2.oXoX@.y W c &.oXoXZ.k r.s.i.s.V.m.} = o ", -"u H.[.{.y.8.y.g.8.g.7.2.oXoXA.@.&.D.oXoXT.e G +.O.O.5.V.m.0.- o ", -"u !.].[.r.8.y.g.g.g.7.4.oXoXoXoXoXoXoXoXoX<.y W X.o.o.m.m.0.- o ", -"u B._._.5.5.8.y.g.c.g.w.oXoX,.h A F <..XoXoX1.k ' ' ' V.N.r.- ", -"u u.Q.~.r.6.z.N.V.I.v.k.oXoX@.B | _ c 1.oXoX}.a ' ' O.I.b.O.= o ", -"u ..Q.Q.v.i.s.c.N.L.l.Z.oXoX@.B t.=.S &.oXoXXXy Y R +.N.b.Q % o ", -"t T C.I.I.6.u.z.z.5.S 1.oXoX@.e B h D |.oXoXS.f Y Y 6.d.d.n X O ", -"%Xs m.V.Q.r.r.z.5.<.}.oXoXoXXXW.}.oXoXoXoXW.h G H R a.p.s.7 %X", -"%X7 O.V.V.v.+.r.` 4.oXoXoXoXoXoXoXoXXXR.<.h v N N o.a.p.Q = %X", -"%Xw x v.v.v.r.+. .Z l d e }.Z.r }.3.d l V G n n R a.s.a.s X O %X", -"%X%X6 { v.l.v.+.O.5.=.^ d }.4.9 }.1.f J G m m G d.d.x.Q = %X%X", -"%X%X%Xs u.v.v.v.r.6.o. .l }.4.9 W.4.l ^ ^ J ) c.N.N.y.7 X O %X%X", -"%X%X%X5 z v.v.M.I.g.;. .J 1.#.B 1.#.) 7.$.S..X'.W.Y.j $ %X%X%X", -"%X%X%X%X5 b N.Y.~.).Y.j.5.$.=.=.$.*.2.J.@X$X#X#XoXC $ %X%X%X%X", -"%X%X%X%X%X3 z U.@X+X`.`.`.(.E.E.E.|.@X@X#X#X#X/.j % %X%X%X%X%X", -"%X%X%X%X%X%Xw a q.OX|.).`._.'.'.XX.X.X+X+X X%.w X o %X%X%X%X%X%X", -"%X%X%X%X%X%X%X%Xw a _ j.~.~.).).`.`.`.F._ t & . # %X%X%X%X%X%X%X", -"%X%X%X%X%X%X%X%X%X%X4 3 t z L U Z z t 1 $ . 8 %X%X%X%X%X%X%X%X%X", -"%X%X%X%X%X%X%X%X%X%X%X%X%X< ; & + + , 8 %X%X%X%X%X%X%X%X%X%X%X%X" -}; diff --git a/src/xpm/bitcoin48.xpm b/src/xpm/bitcoin48.xpm deleted file mode 100644 index 85a7711940..0000000000 --- a/src/xpm/bitcoin48.xpm +++ /dev/null @@ -1,277 +0,0 @@ -/* XPM */ -static const char * bitcoin48_xpm[] = { -/* columns rows colors chars-per-pixel */ -"48 48 223 2", -" c #765404", -". c #795704", -"X c #7C5904", -"o c #7C5A0A", -"O c #825E05", -"+ c #815F0E", -"@ c #815F11", -"# c #866107", -"$ c #866208", -"% c #8A650A", -"& c #8E680D", -"* c #916B0E", -"= c #866414", -"- c #8C6715", -"; c #8F6A10", -": c #8A691B", -"> c #956E12", -", c #906D1D", -"< c #967013", -"1 c #997215", -"2 c #94711F", -"3 c #9C751A", -"4 c #9E781C", -"5 c #A27B1D", -"6 c #947324", -"7 c #997625", -"8 c #9D7926", -"9 c #97792B", -"0 c #9D7B28", -"q c #9C7F34", -"w c #A47E22", -"e c #A87F21", -"r c #A37E2A", -"t c #A8801F", -"y c #A58025", -"u c #AB8425", -"i c #A5812C", -"p c #AB842A", -"a c #AB892D", -"s c #B0862C", -"d c #B48C2D", -"f c #B88F2F", -"g c #B9912E", -"h c #A68432", -"j c #AB8531", -"k c #AD8A33", -"l c #A68638", -"z c #AD8B3B", -"x c #B38C32", -"c c #BA8E35", -"v c #B28D3B", -"b c #B59234", -"n c #BD9235", -"m c #B5903E", -"M c #BC943B", -"N c #BA9A3B", -"B c #C29536", -"V c #C59937", -"C c #C2953B", -"Z c #C49C3C", -"A c #CA9E3D", -"S c #AC8E43", -"D c #AD9045", -"F c #AE9248", -"G c #B49444", -"H c #B99542", -"J c #B49842", -"K c #BD9C44", -"L c #B3954A", -"P c #B7994D", -"I c #BD9A4A", -"U c #B69A52", -"Y c #BB9E54", -"T c #BEA04A", -"R c #BFA354", -"E c #BEA35A", -"W c #C19742", -"Q c #C49B43", -"! c #CA9D41", -"~ c #C39C4B", -"^ c #C99E4A", -"/ c #C7A444", -"( c #CDA244", -") c #CAA945", -"_ c #C5A44C", -"` c #CCA44B", -"' c #C6A94C", -"] c #CFAC4D", -"[ c #D2A647", -"{ c #D2A54B", -"} c #D4AA4C", -"| c #D9AC4D", -" . c #D4B04E", -".. c #DCB14D", -"X. c #C4A151", -"o. c #CAA454", -"O. c #C6AB56", -"+. c #CCA955", -"@. c #C1A45A", -"#. c #C6AA5A", -"$. c #CDAB5D", -"%. c #D1A652", -"&. c #D4AB53", -"*. c #DDAF52", -"=. c #D3AC5B", -"-. c #D9AF5C", -";. c #D5B154", -":. c #DDB253", -">. c #D5B25B", -",. c #DCB45D", -"<. c #DDBB5E", -"1. c #E1B354", -"2. c #E4B955", -"3. c #E3B65B", -"4. c #E5BA5C", -"5. c #EABE5E", -"6. c #C6AB63", -"7. c #CCAD63", -"8. c #C6AE68", -"9. c #C9AF69", -"0. c #D4AC60", -"q. c #CDB067", -"w. c #CDB36C", -"e. c #D6B162", -"r. c #DDB463", -"t. c #D7B964", -"y. c #DBB965", -"u. c #D1B66F", -"i. c #DDB66A", -"p. c #D0BC6C", -"a. c #DFBE6B", -"s. c #CEB772", -"d. c #D1B771", -"f. c #D4BC74", -"g. c #DBBD75", -"h. c #DABF78", -"j. c #E2B764", -"k. c #E4BA64", -"l. c #E9BD62", -"z. c #E2BB6A", -"x. c #E8BF69", -"c. c #EBC15F", -"v. c #F1C25E", -"b. c #DFC266", -"n. c #DBC26C", -"m. c #DCC676", -"M. c #DEC973", -"N. c #D7C07A", -"B. c #D9C27E", -"V. c #E4C162", -"C. c #EDC363", -"Z. c #E3C36F", -"A. c #EBC26C", -"S. c #E5CA6B", -"D. c #EECA6D", -"F. c #F1C565", -"G. c #F5CB66", -"H. c #F9CA66", -"J. c #F2C76A", -"K. c #F5CC6A", -"L. c #F9CD6C", -"P. c #EDD26C", -"I. c #FBD26E", -"U. c #E5C374", -"Y. c #EDC573", -"T. c #E6CB74", -"R. c #EECC73", -"E. c #EBCA78", -"W. c #F5CD74", -"Q. c #F9CE72", -"!. c #EED77F", -"~. c #F4D274", -"^. c #FDD473", -"/. c #F2D870", -"(. c #FED975", -"). c #F5D37C", -"_. c #FCD57A", -"`. c #F7D87A", -"'. c #FEDC7C", -"]. c #FFE37D", -"[. c #DCC682", -"{. c #E1C984", -"}. c #E4CD8A", -"|. c #EFD182", -" X c #E5D48D", -".X c #EAD28D", -"XX c #E8DB8D", -"oX c #F1D581", -"OX c #FDD581", -"+X c #F5DB84", -"@X c #FDDC84", -"#X c #FEDE89", -"$X c #EAD594", -"%X c #E1D894", -"&X c #ECDA94", -"*X c #EFDA99", -"=X c #F2DD9C", -"-X c #F6E284", -";X c #FEE385", -":X c #FFE883", -">X c #FEE38C", -",X c #FEEA8C", -"<X c #F6E196", -"1X c #FEE594", -"2X c #FEEC93", -"3X c #F6E39C", -"4X c #FEE599", -"5X c #FFEB9B", -"6X c #FFF195", -"7X c #FEF39B", -"8X c #FEF99C", -"9X c #F5E2A2", -"0X c #F9E5A5", -"qX c #F6EAA6", -"wX c #FFECA3", -"eX c #FDEAAB", -"rX c #FFF5A0", -"tX c #FFF2AB", -"yX c #FEF5B3", -"uX c #FFF9B3", -"iX c #FFFBBB", -"pX c #FFFDC1", -"aX c None", -/* pixels */ -"aXaXaXaXaXaXaXaXaXaXaXaXaXaXaXaXaXaXaX* < * < < < < * * & aXaXaXaXaXaXaXaXaXaXaXaXaXaXaXaXaXaXaX", -"aXaXaXaXaXaXaXaXaXaXaXaXaXaXaX* 1 3 5 u u d g Z Z N d u 5 3 * % aXaXaXaXaXaXaXaXaXaXaXaXaXaXaXaX", -"aXaXaXaXaXaXaXaXaXaXaXaXaX< 3 t u A ..c.K.I.I.(.(.'.(.G.2.( d 5 1 & aXaXaXaXaXaXaXaXaXaXaXaXaXaX", -"aXaXaXaXaXaXaXaXaXaXaX< 5 t g 1.G.H.H.I.(.'.(.I.I.I.K.K.G.I.K.2.V u 1 % aXaXaXaXaXaXaXaXaXaXaXaX", -"aXaXaXaXaXaXaXaXaXaX4 t g c.G.H.I.I.I.].(.(.(.I.G.H.K.G.K.I.G.K.Q.C.C 5 & % aXaXaXaXaXaXaXaXaXaX", -"aXaXaXaXaXaXaXaXaX4 u } v.G.G.I.(.].(.(.(.I.G.G.G.G.G.L.G.K.I.^.^.L.L.:.u < # aXaXaXaXaXaXaXaXaX", -"aXaXaXaXaXaXaXaXt d c.G.I.I.I.I.].(.I.G.c.........:.4.C.W.~.`.'._.^.K.K.J.N 4 # aXaXaXaXaXaXaXaX", -"aXaXaXaXaXaXaX5 g v.H.I.I.(.(.(.H.c.[ V V V V A A A ! ( } l.).>X@X_.`._.'.'./ 4 O aXaXaXaXaXaXaX", -"aXaXaXaXaXaXt g C.I.(.(.^.(.^.1.( ! C d p u s d d d x M &.3.3.A.).+XOX>X;X;X;X) 3 O aXaXaXaXaXaX", -"aXaXaXaXaX5 d G.I.'.].(.^.l.( C A C s H =X=XI 7 N.*X$Xk o.j.z.J.l.W.1X7X6X,X,X,XK 1 X aXaXaXaXaX", -"aXaXaXaX3 p C.(.(.'.'.^.*.C C C C B r G eXeXL - [.eX3Xr ~ r.W._.W.J.D.6X8X6X6X6X-Xd & X aXaXaXaX", -"aXaXaXaXu ;.'.'.(.^.^.| C c B B B c w z eXeXF = [.eX*X8 K r.@X#X;X`.~.D.7X8X8X6X,XS.y O aXaXaXaX", -"aXaXaXw N #X#X'.'.^.*.C c c s r e r 2 r eXeXD $ B.eX=X: z z.oX>X,X,X;X~.D.8X8X6X,X:X) < X aXaXaX", -"aXaX3 a T.1X1X>X#XA.! C B s $.6.6.@.@.w.eXeXd.U $XeX9XF z G O.n.!.-X;X'.D./.8X6X,X:X/.u # aXaXaX", -"aXaXy K 5X5X5X2X>X-.} ^ C r 0XeXeXeXeXeXeXeXeXeXeXeXeXeXeX9XN.L O.T.`.]./.F.-X6X:X].].) < . aXaX", -"aXaXa M.7X5X5X5XU.&.-.&.^ j 0XeXeXeXeXeXeXeXeXeXeXeXeXeXeXeXeX9XL X.~.'.'.K.c.6X:X].].P.t O aXaX", -"aX5 k 2X5X5X5X<X-.-.-.-.=.W q.6.9.=XeXeXeXeXs.9.d.B.*XeXeXeXeXeX&Xh <.(.(.Q.F.~.;X].].].b & . aX", -"aXy O.5X5X5X5XE.-.-.-.-.-.%.Q z 6 6.eXeXeXeX: , w r 7 R eXeXeXeX0XG ' ~.^.^.F.l.;X].].]. .1 . aX", -"aXp n.2X5X5X5Xj.-.-.-.r.r.r.-.=.G 9.eXeXeXeX6 j ( &.} i [.eXeXeXeXY Q J.I.I.L.5.(.;X].(.c.5 X aX", -"3 a !.7X5X7X<X-.r.r.r.r.j.r.r.r.W w.eXeXeXeX6 v ,.Q.k.m s.eXeXeXeXL K C.L.L.L.F.D.'.'.(.I.u # ", -"5 a ,X5XrXwX+X3.j.j.j.z.z.z.z.r.~ w.eXeXeXeX6 l ;.<._ 0 *XeXeXeX0X0 ( G.L.Q.L.5.C.].'.^.^.g $ ", -"4 b 2X7X7XrX!.l.x.x.x.x.U.x.z.z.~ w.eXeXeXeX: , k z Y XeXeXeXeXY r } C.5.5.5.3.4.'.(.^.^.V % . ", -"4 N 6X7X7XrXOXx.x.x.W.x.Y.Y.Y.Y.o.d.eXeXeXeX=X=X9XeXeXeXeXeXeX8.+ r [ 3.5.5.3.3.1.'._.(.^.A & . ", -"5 N 2X6X5X5XW.x.x.x.x.W.Y.Y.Y.Y.o.d.eXeXeXeXeXeXeXeXeXeXeXeXeXeX[.r C | 1.3.3.3.:._._.^.I./ % ", -"5 N ,X2X2X6XD.l.l.x.x.x.Y.Y.Y.R.=.f.eXeXeXeX[.[.[.[.*XeXeXeXeXeXeX*Xj ! *.1.1.1.1._._.^.^./ % ", -"5 b ;X,X,X2XU.3.j.x.Y.W.).OX#X@Xt.f.eXeXeXeX: : 7 7 : 6 6.eXeXeXeXeXd.k { *.*.*.1.OX_.(.^.V % ", -"4 a ].;X;X>X`.C.L.^._._.OX@X#X#Xt.f.eXeXeXeX6 z #.o.I z 6 w.eXeXeXeX*Xr ! { %.%.,.OX_.(.^.n % ", -"4 u /.;X;X;X@XF.Q.Q._._._.@X#X#Xa.f.eXeXeXeX9 I a.Z.y.+.k F eXeXeXeX0Xr Q { { { 4.'.(.^.^.u O ", -"aXu V.;X;X;X>XF.K.Q.Q._._.OX#X@Xt.f.eXeXeXeX9 I Z.U.z.=.z 8.eXeXeXeX=X7 Q { { ( A._.^.^.F.5 O ", -"aXu ] '.'.;X>XK.J.Q.Q.^._._.~.Z.R w.eXeXeXeX6 S =.>.+.G S 9XeXeXeXeXh.r ! ( ( [ L.L.L.L.:.1 . aX", -"aX5 b '.'.'.@X`.F.K.Q.Q.~.A.e.$.P }.eXeXeXeXF L E #.9.[.eXeXeXeXeXeXS k ! ( ! *.H.K.H.L.Z % aX", -"aX1 u J.(.'.'.;XC.F.W.Q.K.&.h.eXeXeXeXeXeXeXeXeXeXeXeXeXeXeXeXeXeX@.2 c ! ! ! F.H.L.H.F.w O aX", -"aXaXw ( (.(.`.`.`.C.F.K.A.~ [.eXeXeXeXeXeXeXeXeXeXeXeXeXeXeXeX*XF 7 r C B A | H.H.H.H.| 1 X aXaX", -"aXaX3 u D.~.~.~.`.D.C.J.V.` .X=X=X3X9X9XeXeX9X=XeXeXeX$X{.9.S 2 r r B B B V 5.H.H.H.H.s + . aXaX", -"aXaXaXt / ~.W.~.`.`.5.V.C.>.M i 6 - = q eXeXS o B.eX*Xo 7 r r r B C B r B 1.H.H.L.L.*.5 X . aXaX", -"aXaXaX1 u 4.~.~.~.~.~.c.V.l.4.,.~ H i S eXeXF : [.eX=X, r W ^ W W C C W *.Q.Q.Q.Q.J.e % aXaXaX", -"aXaXaXaX5 b K.~.~.R.~.`.l.C.J.A.,.=.H P eXeXU , [.eX=X7 v ^ %.^ W ^ ^ -.^.^.W._.W.Z > . aXaXaX", -"aXaXaXaX1 5 / ~.~.~.~.~.`.F.F.<.r.,.~ R eXeXY 7 [.eX=Xq ~ 0.r.0.%.o.g.#XOXOXOXOX,.4 O aXaXaXaX", -"aXaXaXaXaX1 y } ~.`.`.`.'.#XR.,.r.,.+.X.9.7.I G 9.7.7.X.0.i.i.j.i.9XeX0X=X4X1XT.r # aXaXaXaXaX", -"aXaXaXaXaXaX1 u :.'.'.OX#X#X1X+XA.3.r.-.=.=.>.e.i.$.0.0.i.j.g.0XpXpXpXyXuXyXXXk % aXaXaXaXaXaX", -"aXaXaXaXaXaXaX1 p >.>X#X>X1X1X1X1X1X|.U.z.3.j.z.y.i.i.U..XqXpXiXpXpXpXiXiX Xh % . . aXaXaXaXaXaX", -"aXaXaXaXaXaXaXaX< y _ 3XtXuXtXwX=X4X4X4X5X<X>X=X3X0XeXtXyXuXiXiXiXiXiXuXp.y # . . aXaXaXaXaXaXaX", -"aXaXaXaXaXaXaXaXaX* y J %XpXiXwX4X4X4X5X4X5X5XwXwXwXeXtXeXtXtXyXyXyX&XJ 3 # aXaXaXaXaXaXaXaXaX", -"aXaXaXaXaXaXaXaXaXaX* 3 k R XwX4X1X1X1X1X5X4X5X5XwX5XwXwXtXtXtX&X@.y & X aXaXaXaXaXaXaXaXaXaX", -"aXaXaXaXaXaXaXaXaXaXaXaX& 3 a J t.|.>X,X>X>X2X1X1X1X5X4X0X<Xm.T i > O o aXaXaXaXaXaXaXaXaXaXaX", -"aXaXaXaXaXaXaXaXaXaXaXaXaXaX% > w p b _ >.b.S.T.T.U.t.O.N p 4 & O . o aXaXaXaXaXaXaXaXaXaXaXaXaX", -"aXaXaXaXaXaXaXaXaXaXaXaXaXaXaXaX$ $ ; 1 4 5 5 w w 5 3 > % O . . o aXaXaXaXaXaXaXaXaXaXaXaXaXaXaX", -"aXaXaXaXaXaXaXaXaXaXaXaXaXaXaXaXaXaXaXaXO X X X o X X X o aXaXaXaXaXaXaXaXaXaXaXaXaXaXaXaXaXaXaX" -}; diff --git a/src/xpm/bitcoin80.xpm b/src/xpm/bitcoin80.xpm deleted file mode 100644 index c3c816e92d..0000000000 --- a/src/xpm/bitcoin80.xpm +++ /dev/null @@ -1,292 +0,0 @@ -/* XPM */ -static const char * bitcoin80_xpm[] = { -/* columns rows colors chars-per-pixel */ -"80 80 206 2", -" c #725203", -". c #785706", -"X c #7B5907", -"o c #7C5A09", -"O c #7F5F10", -"+ c #815E0B", -"@ c #85620C", -"# c #89650F", -"$ c #856313", -"% c #896614", -"& c #8D6913", -"* c #886718", -"= c #8D6B1B", -"- c #926D14", -"; c #926E1B", -": c #967116", -"> c #997317", -", c #95711E", -"< c #9B7419", -"1 c #9F781B", -"2 c #A27B1D", -"3 c #8F6F22", -"4 c #926F21", -"5 c #947323", -"6 c #9A7623", -"7 c #9D7925", -"8 c #957628", -"9 c #9A7729", -"0 c #9D7B2B", -"q c #9D7F33", -"w c #A47D23", -"e c #A97F27", -"r c #A37E2B", -"t c #9F8030", -"y c #A78021", -"u c #AC8425", -"i c #A5802D", -"p c #AC842B", -"a c #AF8829", -"s c #B2872C", -"d c #B28B2D", -"f c #A68333", -"g c #AA8633", -"h c #AD8A36", -"j c #A4863A", -"k c #A88638", -"l c #A7893B", -"z c #AC8B3B", -"x c #B28732", -"c c #B48C32", -"v c #B98E34", -"b c #B28D3B", -"n c #B88F3C", -"m c #B69033", -"M c #BD9235", -"N c #B4913D", -"B c #BC943A", -"V c #BE993C", -"C c #C19336", -"Z c #C1953B", -"A c #C49A3C", -"S c #C99C3D", -"D c #CDA13F", -"F c #D0A33F", -"G c #A88B40", -"H c #B08F40", -"J c #AE9142", -"K c #AE944C", -"L c #B49443", -"P c #BB9542", -"I c #B49946", -"U c #BD9846", -"Y c #B3964C", -"T c #BB974A", -"R c #B6994A", -"E c #BF9C4A", -"W c #B69B53", -"Q c #B99D53", -"! c #BCA055", -"~ c #BDA25A", -"^ c #C49742", -"/ c #C49C43", -"( c #CB9E42", -") c #C49D4B", -"_ c #C99E4C", -"` c #C29F52", -"' c #C5A244", -"] c #CDA245", -"[ c #C5A34C", -"{ c #CCA34B", -"} c #CCA94D", -"| c #D2A445", -" . c #D1A54B", -".. c #D5AA4E", -"X. c #DBAF4F", -"o. c #C6A352", -"O. c #CBA554", -"+. c #C5AA57", -"@. c #CEAC54", -"#. c #C4A65A", -"$. c #CDA458", -"%. c #C2A85F", -"&. c #CEAA5B", -"*. c #D0A550", -"=. c #D4AB53", -"-. c #DBAE53", -";. c #D0A75B", -":. c #D4AC5A", -">. c #D9AE5C", -",. c #CEB25E", -"<. c #D4B156", -"1. c #DDB156", -"2. c #D4B25C", -"3. c #DCB35D", -"4. c #D7B85C", -"5. c #DCBA5E", -"6. c #E2B355", -"7. c #E2B65B", -"8. c #E4BA5D", -"9. c #EABD5E", -"0. c #C5AA62", -"q. c #CCAE63", -"w. c #C6AE69", -"e. c #D5AF62", -"r. c #CEB167", -"t. c #CCB36C", -"y. c #D5B162", -"u. c #DCB462", -"i. c #D7B964", -"p. c #DCBC64", -"a. c #D2B66B", -"s. c #DCB669", -"d. c #D7BE69", -"f. c #DFB86A", -"g. c #D0B771", -"h. c #D2BA74", -"j. c #D5BE78", -"k. c #E1B766", -"l. c #E4BB63", -"z. c #E9BE63", -"x. c #E3BB6A", -"c. c #E9BF6A", -"v. c #E1BE72", -"b. c #DDC16B", -"n. c #DAC27E", -"m. c #E4C164", -"M. c #ECC264", -"N. c #E4C36B", -"B. c #EBC36C", -"V. c #E7C96F", -"C. c #EECA6E", -"Z. c #F1C564", -"A. c #F1C76A", -"S. c #F5CB6C", -"D. c #FACE6D", -"F. c #F4D06F", -"G. c #FCD06E", -"H. c #E5C371", -"J. c #EDC573", -"K. c #E4CA73", -"L. c #ECCC74", -"P. c #E7CF7A", -"I. c #EBCD7A", -"U. c #F3CD73", -"Y. c #F8CE71", -"T. c #F3CD7A", -"R. c #EDD076", -"E. c #EDD17B", -"W. c #F4D274", -"Q. c #FBD274", -"!. c #FED977", -"~. c #F3D47B", -"^. c #FDD47A", -"/. c #F5DA7C", -"(. c #FDDA7C", -"). c #FFE07F", -"_. c #DBC481", -"`. c #DFC885", -"'. c #E1CA86", -"]. c #EACC80", -"[. c #E4CD8A", -"{. c #EED383", -"}. c #E7D18F", -"|. c #EAD38C", -" X c #F4D680", -".X c #FDD780", -"XX c #F5DA83", -"oX c #FCDC84", -"OX c #F5DB8A", -"+X c #FADE89", -"@X c #EAD492", -"#X c #EED896", -"$X c #EFDA9A", -"%X c #F1DD9D", -"&X c #FDE283", -"*X c #F6E18D", -"=X c #FEE48D", -"-X c #FFE692", -";X c #FFE894", -":X c #FBE799", -">X c #FFEA98", -",X c #F6E2A3", -"<X c #FAE6A6", -"1X c #FAE7A8", -"2X c #FDEAAB", -"3X c None", -/* pixels */ -"3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X", -"3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X", -"3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X", -"3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X", -"3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X", -"3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3Xu u u u u u u y y u y 3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X", -"3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3Xu u u u u u u u u a u u u u u u a u u 2 3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X", -"3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3Xu u u u u u u u s m V D ' { ' D M d u u a u u u u 2 3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X", -"3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3Xu u u u u u M } m.~.oX=X=X=X=X=X-X-X=X&X/.m.=.V u u a u u w 3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X", -"3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3Xu u u u u M 4.~.=X=X=X=X=X=X=X=X=X=X=X=X=X=X=X=X=X=X/.5.Z u u u u u 3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X", -"3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3Xu u u u ] V.&X=X=X&X=X=X=X=X=X=X=X=X=X&X=X=X=X=X=X=X=X=X=X=XW.} a u u u 2 3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X", -"3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3Xu a u u ' W.=X=X=X=X=X=X=X=X=X=X=X=X=X=X=X=X=X=X=X=X+X=X=X=X&X=X=X=X~.} a u u u < 3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X", -"3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3Xu u u M N.=X&X=X=X=X=X=X=X=X-X=X=X=X=X&X=X=X=XoX=X=X=X=X&X+X=X=X=X=X=X=X=XL.M u u u < 3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X", -"3X3X3X3X3X3X3X3X3X3X3X3X3X3X3Xu u u u } XX=X=X=X&X=X=X=X=X=X=X=X=X=X=X=X=X=X=X=X*X=X=X=X=X=X=X=X=X=X=X=X=X=X=XoX<.a u u 2 3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X", -"3X3X3X3X3X3X3X3X3X3X3X3X3X3Xu u u s m.&X=X=X=X=X=X=X=X=X=X=X=X=X=X/.L.M.m.9.m.9.m.C.~.&X*X=X=X=X=X=X=X=X=X=X=X=X=XV.m u u 2 o 3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X", -"3X3X3X3X3X3X3X3X3X3X3X3X3Xu u u c R.=X=X=X=X=X=X=X=X=X=X=XoXC.1.| S S A S D D D D ] ] ..<.N./.=X-X=X-X=X=X=X=X=X=X=XXXZ u a 2 o 3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X", -"3X3X3X3X3X3X3X3X3X3X3X3Xu u u m XX=X=X=X=X=X=X=X=X=X=XW.3.| ^ A C M M M C S S A A A / ( { =.<.l.I.=X-X-X=X=X=X=X=X=X=X=XV a u 2 . 3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X", -"3X3X3X3X3X3X3X3X3X3X3X3Xu u m /.=X=X=X-X=X=X=X=X=X~.1.D ] S Z v x p s u s d d v c c v V { =.7.8.7.l.T.=X-X=X-X-X-X-X-X=X=XV u a 1 3X3X3X3X3X3X3X3X3X3X3X3X3X3X", -"3X3X3X3X3X3X3X3X3X3X3Xu u d /.=X=X=X=X=X=X=X=X&X8.^ A ( S M v e $.r.e.r.u w i a.a.a.&.b ^ =.l.l.l.c.z.z.XX-X-X-X-X=X-X-X;X&XV u u : 3X3X3X3X3X3X3X3X3X3X3X3X3X", -"3X3X3X3X3X3X3X3X3X3Xu u s R.=X=X=X=X=X=X=X=XU.{ ^ Z C ( A M u w [.2X2X2X0 - 7 2X2X1X@Xi P *.l.x.B.U.C.z.z.W.-X-X-X-X-X-X=X-X*Xd a u # . 3X3X3X3X3X3X3X3X3X3X3X3X", -"3X3X3X3X3X3X3X3X3Xu u u l.=X=X=X=X-X=X=X=Xm.Z Z Z Z n Z Z v e , '.2X2X2X5 & ; 2X2X2X}.7 b { 3.x.^.^.^.Y.A.z.R.-X;X;X;X;X-X;X-XP.a u y . 3X3X3X3X3X3X3X3X3X3X3X3X", -"3X3X3X3X3X3X3X3X3Xu u } -X-X=X-X=X=X=X=Xl.M M Z C C C C C x e ; '.2X2X2X, $ = 2X2X2X}.6 h ) >.J..X.X.X.X(.W.Z.C.&X;X;X;X;X-X-X-X<.u u < 3X3X3X3X3X3X3X3X3X3X3X", -"3X3X3X3X3X3X3X3Xu u c oX=X=X=X=X=X=X=Xl.Z C M M C C v v v s w = '.2X2X2X5 $ = 2X2X2X}.5 g ) u./.+X+X=X=X=X&XW.Z.F.=X;X;X;X;X-X-X*XV u y @ X 3X3X3X3X3X3X3X3X3X3X", -"3X3X3X3X3X3X3Xu u u N.-X-X-X-X=X=X=XB.Z M C v v s e e e e w > % `.2X2X2X= + % 2X2X2X}.= r L 4.E.OX+X-X=X=X&X).W.M.R.;X;X;X-X-X-X;XR.u u y 3X3X3X3X3X3X3X3X3X3X", -"3X3X3X3X3X3X3Xu u U -X-X-X-X-X-X=XW.^ C C C x e e r 6 5 4 ; = $ `.2X2X2X= O = 2X2X2X}.O = t Q ,.b.P./.*X=X&X&X).F.M.W.;X;X;X;X&X-X&X} u u O 3X3X3X3X3X3X3X3X3X", -"3X3X3X3X3X3Xu u u R.-X-X-X-X-X-X=X=.{ ^ Z C x n 2X2X<X<X1X2X<X<X2X2X2X2X1X1X<X2X2X2X<X$X[.b.~ J I ~ b.P.&X&X&X).!.F.m.).;X;X;X;X;X&X).u y y 3X3X3X3X3X3X3X3X3X", -"3X3X3X3X3X3Xu u U -X-X-X-X-X-X-Xc.=.=. ._ ^ x z 2X2X1X2X2X2X2X2X2X2X2X2X2X2X2X2X2X2X2X2X2X2X2X<Xn.l I ,.K./.).).).F.Z.Z.&X;X;X=X-X-X&X} u u O 3X3X3X3X3X3X3X3X", -"3X3X3X3X3X3Xu u V.-X;X-X-X-X-XOX>.>.>.=.=._ n b 2X2X2X2X2X2X2X2X2X2X2X2X2X2X2X2X2X2X2X2X2X2X2X2X2X:XI N +.V./.).).F.F.9.W.;X=X;X-X-X-XR.u u > 3X3X3X3X3X3X3X3X", -"3X3X3X3X3Xu u d =X;X-X-X-X-X-Xx.>.>.>.>.>...^ P 2X2X2X2X2X2X2X2X2X2X2X2X2X2X2X2X2X2X2X2X2X2X2X2X2X2X,Xl N 4.R.!.!.!.G.Z.M.&X;X=X=X-X-X-XB a u 3X3X3X3X3X3X3X", -"3X3X3X3X3Xu u @.;X;X-X;X;X;XXX>.:.>.>.>.>.>._ P ` Y Y W _.2X2X2X2X2X2X@XW W ~ 0.t.'.<X2X2X2X2X2X2X2X2X'.0 ' m./.!.!.Q.S.9.F.=X;X-X=X-X&X4.u u @ 3X3X3X3X3X3X3X", -"3X3X3X3X3Xu u P.;X;X;X;X-X:XN.>.>.>.>.>.>.>.=._ P z r 4 8 2X2X2X2X2X2X_.. $ , 6 1 3 t ~ 1X2X2X2X2X2X2X2Xt B 5.G.!.!.G.G.M.9.&X;X=X-X-X=X/.u u > 3X3X3X3X3X3X3X", -"3X3X3X3Xu u d =X;X;X=X;X;X=X3.>.>.>.e.>.3.3.>.:.*._ P r 9 2X2X2X2X2X1Xn.@ , c B N m h 8 ~ 2X2X2X2X2X2X2XI h <.F.!.G.G.F.M.9.W.;X=X-X-X=X=Xm u y . 3X3X3X3X3X3X", -"3X3X3X3Xu u ' -X-X>X-X-X-X X>.>.>.>.>.>.>.u.u.u.u.3.$.P f 2X2X2X2X2X2X_.$ i / -.<.8.} h 8 1X2X2X2X2X2X2X! i <.S.G.G.G.G.Z.9.Z.=X-X=X-X&X-X} u u X 3X3X3X3X3X3X", -"3X3X3X3Xu u 4.-X-X-X-X-X-XJ.3.>.>.k.k.k.k.k.u.k.u.u.:.U k 2X2X2X2X2X1X_.% f } 8.Z.F.8.U 8 ,X2X2X2X2X2X2XI g } Z.D.G.D.G.D.Z.9.&X-X=X=X=X-Xm.u u @ 3X3X3X3X3X3X", -"3X3X3X3Xu u K.;X-X;X-X>X-Xk.3.k.k.k.k.k.k.k.k.k.k.u.e.U k 2X2X2X2X2X2X_.% f [ 8.F.M.<.b i 2X2X2X2X2X2X2Xt a X.Z.D.D.D.G.G.Z.9./.=X-X=X=X=XR.u u & 3X3X3X3X3X3X", -"3X3X3X3Xu u E.;X-X;X-X-X=Xl.l.x.c.k.x.k.k.x.x.v.x.x.u.) z 2X2X2X2X2X2X_.$ 7 L <.<.} N 6 h.2X2X2X2X2X2X_.: V 1.S.D.D.G.D.S.M.6.W.-X=X-X=X=X&Xu u > X 3X3X3X3X3X", -"3X3X3Xu a u =X;X;X;X;X;XoX7.z.c.c.c.c.c.c.c.c.c.x.k.u.) z 2X2X2X2X2X2Xn.o = i N h i l n.2X2X2X2X2X2X<Xt t D 7.M.Z.z.z.9.9.9.6.M.-X=X=X=X;X=Xm u 1 3X3X3X3X3X", -"3X3X3Xy u a =X;X;X;X;X;XXXl.z.c.c.c.c.T.J.J.T.v.J.J.s.` z 2X2X2X2X2X2X#XW ~ ~ t.n.$X2X2X2X2X2X2X2X,Xt % t V X.8.9.8.9.9.9.6.6.M.-X=X=X=X=X&XM u 2 3X3X3X3X3X", -"3X3X3Xu u m -X-X-X;X;X;X~.z.z.c.c.c.c..XJ.J.J.J.J.J.x.O.b 2X2X2X2X2X2X2X2X2X2X2X2X2X2X2X2X2X2X2X2Xw.$ * y V X.7.8.8.9.7.8.7.6.8.=X=X-X-X=X-XV a y 3X3X3X3X3X", -"3X3X3Xu a m -X-X-X;X;X;X~.7.z.c.c.c.c.c.c.J.T.J.T.J.B.O.b 2X2X2X2X2X2X2X2X2X2X2X2X2X2X2X2X2X2X2X2X2X,X~ , c ' X.6.6.7.6.6.6.6.8.=X=X=X-X&X-XV u y 3X3X3X3X3X", -"3X3X3Xu u m -X-X-X-X-X-X/.8.l.z.c.T.c.J.c.J.T.v.J.J.x.O.G 2X2X2X2X2X2X2X2X2X2X2X2X2X2X2X2X2X2X2X2X2X2X2Xn.r v { 6.6.6.6.6.6.-.7.&X-X=X=X=X-XD u y 3X3X3X3X3X", -"3X3X3Xu u d =X-X-X-X-X-X~.7.z.z.c.c.c.c.c.J.c.T.T.^.T.y.R 2X2X2X2X2X2X@XK K W W W ~ h.#X1X2X2X2X2X2X2X2X2Xa.i Z ..X.6.6.-.-.6.7.-X-X-X-X-X-XD u 2 3X3X3X3X3X", -"3X3X3Xw u a =X-X-X-X-X-X~.7.7.8.c.c.c.c.T..X.X+X+X+XXXi.R 2X2X2X2X2X2Xn.. * 5 8 5 3 = * q `.2X2X2X2X2X2X2X<Xk c | X.6.-.-.-.-.z.&X;X=X;X-X;XV u w 3X3X3X3X3X", -"3X3X3Xu u u =X-X=X-X-X-X/.8.M.B.Y.T.^.^.^..X.XoXoX+XXXi.R 2X2X2X2X2X2X_.$ 0 b U U N l t 5 $ `.2X2X2X2X2X2X2X0.e Z .....-.-.6.c.;X=X;X=X;X-Xd u 1 3X3X3X3X3X", -"3X3X3X3Xu a E.-X-X-X-X-X=Xz.S.D.Y.^.Q.^.^.^..XoX+X+XXXi.R 2X2X2X2X2X2X_.= l +.u.i.,.O.E h 5 G 2X2X2X2X2X2X2X_.0 n | . .*. .*.T.-X;X;X;X-X=Xa u : 3X3X3X3X3X", -"3X3X3X3Xu u N.-X-X-X=X-X-XA.Z.S.Y.Q.Q.^.^..X.XoXoX&X.Xi.R 2X2X2X2X2X2X_.= N y.H.H.m.i.y.E f 8 2X2X2X2X2X2X2X'.6 n | . . . . ..X;X;X;X;X-X~.u u & 3X3X3X3X3X", -"3X3X3X3Xu u <.-X-X=X=X-X-XW.Z.S.Y.Y.Q.^.^.^.(..XoX=XXXi.R 2X2X2X2X2X2X_.= L 4.H.J.H.x.i.o.k j 2X2X2X2X2X2X2X_.6 B . . . .{ =.-X;X-X;X-X-Xb.a u @ 3X3X3X3X3X", -"3X3X3X3Xy a V =X=X-X-X=X-XXXZ.S.Y.Y.Y.Q.!.^..X.XoXoXE.y.I 2X2X2X2X2X2X_.= J y.b.H.N.p.&.P 0 g.2X2X2X2X2X2X2Xr.r B _ { .| ] l.-X;X;X-X-X;X..u u . . 3X3X3X3X3X", -"3X3X3X3Xy u a =X=X=X=X-X=X-XM.Z.S.Y.Y.Q.Q.^.^.^.U.J.u.E l 2X2X2X2X2X2X_.* k o.e.e.$.` P q W 1X2X2X2X2X2X2X2XG i B ] | ] ] ( ~.=X;X;X;X;X;XM u y 3X3X3X3X3X3X", -"3X3X3X3X3Xu u V.-X=X-X=X-X-XF.M.A.D.Y.Q.Y.Q.Y.B.2.[ N 0 j 2X2X2X2X2X2X_.O 5 l G z H H Q _.2X2X2X2X2X2X2X2X#X, g ^ ] ] | ] ..-X-X-X-X&X;X).u u : 3X3X3X3X3X3X", -"3X3X3X3X3Xu u } =X=X=X=X-X=X&XM.Z.S.D.W.Q.Y.B.*.a.#X@X|.,X2X2X2X2X2X2X,X[.[.}.}.%X<X2X2X2X2X2X2X2X2X2X2X<Xj 6 b / ] ] ] ] M.-X-X-X-X-X-X4.u u O 3X3X3X3X3X3X", -"3X3X3X3X3Xy u d =X=X=X=X=X=X-XS.M.A.S.S.U.A.u.) n.2X2X2X2X2X2X2X2X2X2X2X2X1X2X2X2X2X2X2X2X2X2X2X2X2X2X2XW ; i M ( S S S ] &X-X-X-X-X=X-Xm u y . X 3X3X3X3X3X3X", -"3X3X3X3X3X3Xu u p.=X=X=X=X=X-X&X9.Z.C.S.S.M.:.b [.2X2X2X2X2X2X2X2X2X2X2X2X2X2X2X2X2X2X2X2X2X2X2X2X2X%XG = r x v C D D D m.-X-X-X-X-X-XR.u u : 3X3X3X3X3X3X3X", -"3X3X3X3X3X3Xy u B =X=X=X=X=X=X=XF.9.M.A.C.M.=.h %X2X2X2X2X2X2X2X2X2X2X2X2X2X2X2X2X2X2X2X2X2X2X1X#X~ 4 ; r p v v M C A | &X-X-X-X-X-X-X] u u X 3X3X3X3X3X3X3X", -"3X3X3X3X3X3Xy u u N.=X=X-X=X-X=X=XM.z.M.M.M.1.V #X%X%X%X%X$X%X%X<X2X2X2X%X$X%X2X2X2X<X[.n.t.W q = , r i x v C C C M C W.-X-X-X-X-X-X/.u u 1 X 3X3X3X3X3X3X3X", -"3X3X3X3X3X3X3Xu u V *X=X=X*X=X=X=XoX8.M.M.M.5.{ m r , ; $ $ o o `.2X2X2X3 o $ 2X2X2X[.o $ 4 9 0 r g x v m C M C C C 8.&X-X-X-X-X-X-X[ u u @ 3X3X3X3X3X3X3X3X", -"3X3X3X3X3X3X3X2 u u 5.=X=X=X=X=X=X=XI.8.M.M.z.3.O.) P b r 0 4 % `.2X2X2X3 $ * 2X2X2X[.$ 4 r e ^ n n Z Z Z C C C M | =X=X-X-X-X-X-XR.u u < 3X3X3X3X3X3X3X3X", -"3X3X3X3X3X3X3X3Xy u d XX=X=X=X=X-X=X=XS.8.8.M.M.z.z.7.{ _ U g 5 `.2X2X2X8 = 3 2X2X2X}.3 0 x ^ _ ^ ^ ^ Z ^ B ^ C .&X-X-X-X-X-X-X=XB u u o 3X3X3X3X3X3X3X3X3X", -"3X3X3X3X3X3X3X3X1 u u ' =X=X*X=X=X*X=X=XW.8.M.M.A.S.l.u.>.o.L r [.2X2X2X9 = 8 2X2X2X}.4 r ^ _ *.*._ ) ) ^ ^ ^ O.oX=X-X-X-X-X-X-X<.u u : . 3X3X3X3X3X3X3X3X3X", -"3X3X3X3X3X3X3X3X3Xy u u i.=X=X=X=X=X-X*X=XW.9.M.A.B.3.5.5.;.U f [.2X2X2Xq 4 8 2X2X2X}.r q _ _ ;.;.*._ _ ` _ e.+X-X-X-X-X-X-X-XR.a u 2 3X3X3X3X3X3X3X3X3X3X", -"3X3X3X3X3X3X3X3X3X3Xu u u K.=X=X=X-X=X=X=X=XXXz.M.8.5.8.u.:.) h }.2X2X2Xj r f 2X2X2X@Xq T _ e.e.u.e.;.$.$.b.-X-X-X=X;X=X;X-X&Xa a u + 3X3X3X3X3X3X3X3X3X3X3X", -"3X3X3X3X3X3X3X3X3X3X3Xu u d ~.=X=X=X=X=X-X=X-X+XC.3.5.7.7.2.@.) q.r.q.q.H H L g.r.w.q.T ` e.k.v.k.k.s.s.{.-X-X;X-X;X;X;X;X*XV u u & . 3X3X3X3X3X3X3X3X3X3X3X", -"3X3X3X3X3X3X3X3X3X3X3X2 u u c XX-X=X=X=X=X-X=X-X-X Xl.7.7.u.2.$.o.[ [ o.O.$.&.&.` ` ` q.s.k.v.k.k.x.{.%X>X>X>X;X>X;X>X>X*XV u u > 3X3X3X3X3X3X3X3X3X3X3X3X", -"3X3X3X3X3X3X3X3X3X3X3X3X2 u u m ~.=X-X-X-X=X-X-X-X-X-X Xc.7.5.u.3.e.y.u.s.f.k.s.e.e.s.s.k.k.k.v. X:X>X>X>X>X>X>X;X>X>X*XV u u < 3X3X3X3X3X3X3X3X3X3X3X3X3X", -"3X3X3X3X3X3X3X3X3X3X3X3X3X2 u u d R.-X=X-X=X-X-X-X-X-X-X-X+XI.v.u.s.l.k.k.x.x.x.s.s.s.s.j.].+X>X>X>X>X>X:X>X>X>X>X>XOXV u u 1 3X3X3X3X3X3X3X3X3X3X3X3X3X3X", -"3X3X3X3X3X3X3X3X3X3X3X3X3X3X2 u u a p.-X-X-X;X;X;X-X-X-X:X-X-X-X-XOX XL.J.J.J.L.I.].OX:X>X-X>X>X-X>X>X>X>X>X>X>X>XK.a a u < 3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X", -"3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X2 u u u @.=X;X;X>X;X-X-X>X-X-X-X-X;X-X-X-X-X-X>X>X-X>X-X>X>X>X>X;X>X>X>X-X>X-X-X:X<.u u u > 3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X", -"3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X1 u u u m n.>X;X>X>X-X-X-X-X>X-X-X-X;X;X;X-X-X-X-X-X>X-X-X>X-X>X>X-X>X>X>X>XK.B u u u & 3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X", -"3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3Xw u u u / {.>X>X-X-X-X-X-X-X-X-X-X-X;X-X-X;X:X-X-X>X-X:X>X;X;X>X;X;X{.[ u u u w + 3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X", -"3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X2 u u u u ) K.-X-X-X-X:X-X-X-X-X-X-X-X-X-X-X-X-X>X-X-X-X-X-X-XE.[ u u u u - . 3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X", -"3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X1 u u u u m 2.E.-X+X:X-X-X-X-X-X-X-X-X-X:X-X-X-X;X-XOXi.B u u u u 1 o 3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X", -"3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X> u u u u u v [ l.I.OX-X-X-X-X-X-X-X-X+XI.f.@.m u u u u u 1 + o 3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X", -"3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X& 2 u u u u u u u d B V V V V B d u u u u u u u y - . o 3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X", -"3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X+ - 1 u u u u u u u a u u u u u u u u 2 - o o 3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X", -"3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3Xo . X # - > 1 2 2 2 1 2 > - # o . o 3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X", -"3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3Xo o . o 3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X", -"3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X", -"3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X", -"3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X", -"3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X3X" -}; diff --git a/src/xpm/check.xpm b/src/xpm/check.xpm deleted file mode 100644 index e62b656961..0000000000 --- a/src/xpm/check.xpm +++ /dev/null @@ -1,41 +0,0 @@ -/* XPM */
-static const char * check_xpm[] = {
-/* columns rows colors chars-per-pixel */
-"32 32 3 1",
-" c #008000",
-". c #00FF00",
-"X c None",
-/* pixels */
-"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
-"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
-"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
-"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
-"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
-"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
-"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
-"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
-"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
-"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
-"XXXXXXXXXXXXXXXXX XXXXXXXXXXXX",
-"XXXXXXXXXXXXXXXXX . XXXXXXXXXXX",
-"XXXXXXXXXXXXXXXX .. XXXXXXXXXXXX",
-"XXXXXXXXXXXXXXXX . XXXXXXXXXXXX",
-"XXXXXXXXXXXXXXX .. XXXXXXXXXXXXX",
-"XXXXXXXXXXX XX . XXXXXXXXXXXXX",
-"XXXXXXXXXXX . .. XXXXXXXXXXXXXX",
-"XXXXXXXXXXX .. . XXXXXXXXXXXXXX",
-"XXXXXXXXXXXX ... XXXXXXXXXXXXXXX",
-"XXXXXXXXXXXXX . XXXXXXXXXXXXXXX",
-"XXXXXXXXXXXXXX XXXXXXXXXXXXXXXX",
-"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
-"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
-"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
-"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
-"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
-"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
-"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
-"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
-"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
-"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
-"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
-};
diff --git a/src/xpm/send16.xpm b/src/xpm/send16.xpm deleted file mode 100644 index 7da44d9c56..0000000000 --- a/src/xpm/send16.xpm +++ /dev/null @@ -1,278 +0,0 @@ -/* XPM */
-static const char * send16_xpm[] = {
-/* columns rows colors chars-per-pixel */
-"16 16 256 2",
-" c #ADF7AD",
-". c #9CFF9C",
-"X c None",
-"o c #ADEFAD",
-"O c #94FF94",
-"+ c #D6CECE",
-"@ c #8CFF8C",
-"# c #CECECE",
-"$ c #CECEC5",
-"% c #84FF84",
-"& c #CEC5C5",
-"* c #73FF73",
-"= c #C5C5C5",
-"- c #6BFF6B",
-"; c #73F773",
-": c #C5BDBD",
-"> c #6BF76B",
-", c #BDBDBD",
-"< c #63F763",
-"1 c #B5B5B5",
-"2 c #52F752",
-"3 c #42FF42",
-"4 c #3AFF3A",
-"5 c #ADADAD",
-"6 c #ADADA5",
-"7 c #4AEF4A",
-"8 c #29FF29",
-"9 c #A5A5A5",
-"0 c #42E642",
-"q c #9CA59C",
-"w c #3AE63A",
-"e c #10FF10",
-"r c #08FF08",
-"t c #949C94",
-"y c #00FF00",
-"u c #00F700",
-"i c #8C948C",
-"p c #00EF00",
-"a c #08E608",
-"s c #10DE10",
-"d c #00E600",
-"f c #00DE00",
-"g c #19C519",
-"h c #00CE00",
-"j c #00C500",
-"k c #008C00",
-"l c #008400",
-"z c #669900",
-"x c #999900",
-"c c #CC9900",
-"v c #FF9900",
-"b c #00CC00",
-"n c #33CC00",
-"m c #66CC00",
-"M c #99CC00",
-"N c #CCCC00",
-"B c #FFCC00",
-"V c #66FF00",
-"C c #99FF00",
-"Z c #CCFF00",
-"A c #000033",
-"S c #330033",
-"D c #660033",
-"F c #990033",
-"G c #CC0033",
-"H c #FF0033",
-"J c #003333",
-"K c #333333",
-"L c #663333",
-"P c #993333",
-"I c #CC3333",
-"U c #FF3333",
-"Y c #006633",
-"T c #336633",
-"R c #666633",
-"E c #996633",
-"W c #CC6633",
-"Q c #FF6633",
-"! c #009933",
-"~ c #339933",
-"^ c #669933",
-"/ c #999933",
-"( c #CC9933",
-") c #FF9933",
-"_ c #00CC33",
-"` c #33CC33",
-"' c #66CC33",
-"] c #99CC33",
-"[ c #CCCC33",
-"{ c #FFCC33",
-"} c #33FF33",
-"| c #66FF33",
-" . c #99FF33",
-".. c #CCFF33",
-"X. c #FFFF33",
-"o. c #000066",
-"O. c #330066",
-"+. c #660066",
-"@. c #990066",
-"#. c #CC0066",
-"$. c #FF0066",
-"%. c #003366",
-"&. c #333366",
-"*. c #663366",
-"=. c #993366",
-"-. c #CC3366",
-";. c #FF3366",
-":. c #006666",
-">. c #336666",
-",. c #666666",
-"<. c #996666",
-"1. c #CC6666",
-"2. c #009966",
-"3. c #339966",
-"4. c #669966",
-"5. c #999966",
-"6. c #CC9966",
-"7. c #FF9966",
-"8. c #00CC66",
-"9. c #33CC66",
-"0. c #99CC66",
-"q. c #CCCC66",
-"w. c #FFCC66",
-"e. c #00FF66",
-"r. c #33FF66",
-"t. c #99FF66",
-"y. c #CCFF66",
-"u. c #FF00CC",
-"i. c #CC00FF",
-"p. c #009999",
-"a. c #993399",
-"s. c #990099",
-"d. c #CC0099",
-"f. c #000099",
-"g. c #333399",
-"h. c #660099",
-"j. c #CC3399",
-"k. c #FF0099",
-"l. c #006699",
-"z. c #336699",
-"x. c #663399",
-"c. c #996699",
-"v. c #CC6699",
-"b. c #FF3399",
-"n. c #339999",
-"m. c #669999",
-"M. c #999999",
-"N. c #CC9999",
-"B. c #FF9999",
-"V. c #00CC99",
-"C. c #33CC99",
-"Z. c #66CC66",
-"A. c #99CC99",
-"S. c #CCCC99",
-"D. c #FFCC99",
-"F. c #00FF99",
-"G. c #33FF99",
-"H. c #66CC99",
-"J. c #99FF99",
-"K. c #CCFF99",
-"L. c #FFFF99",
-"P. c #0000CC",
-"I. c #330099",
-"U. c #6600CC",
-"Y. c #9900CC",
-"T. c #CC00CC",
-"R. c #003399",
-"E. c #3333CC",
-"W. c #6633CC",
-"Q. c #9933CC",
-"!. c #CC33CC",
-"~. c #FF33CC",
-"^. c #0066CC",
-"/. c #3366CC",
-"(. c #666699",
-"). c #9966CC",
-"_. c #CC66CC",
-"`. c #FF6699",
-"'. c #0099CC",
-"]. c #3399CC",
-"[. c #6699CC",
-"{. c #9999CC",
-"}. c #CC99CC",
-"|. c #FF99CC",
-" X c #00CCCC",
-".X c #33CCCC",
-"XX c #66CCCC",
-"oX c #99CCCC",
-"OX c #CCCCCC",
-"+X c #FFCCCC",
-"@X c #00FFCC",
-"#X c #33FFCC",
-"$X c #66FF99",
-"%X c #99FFCC",
-"&X c #CCFFCC",
-"*X c #FFFFCC",
-"=X c #3300CC",
-"-X c #6600FF",
-";X c #9900FF",
-":X c #0033CC",
-">X c #3333FF",
-",X c #6633FF",
-"<X c #9933FF",
-"1X c #CC33FF",
-"2X c #FF33FF",
-"3X c #0066FF",
-"4X c #3366FF",
-"5X c #6666CC",
-"6X c #9966FF",
-"7X c #CC66FF",
-"8X c #FF66CC",
-"9X c #0099FF",
-"0X c #3399FF",
-"qX c #6699FF",
-"wX c #9999FF",
-"eX c #CC99FF",
-"rX c #FF99FF",
-"tX c #00CCFF",
-"yX c #33CCFF",
-"uX c #66CCFF",
-"iX c #99CCFF",
-"pX c #CCCCFF",
-"aX c #FFCCFF",
-"sX c #33FFFF",
-"dX c #66FFCC",
-"fX c #99FFFF",
-"gX c #CCFFFF",
-"hX c #FF6666",
-"jX c #66FF66",
-"kX c #FFFF66",
-"lX c #6666FF",
-"zX c #FF66FF",
-"xX c #66FFFF",
-"cX c #A50021",
-"vX c #5F5F5F",
-"bX c #777777",
-"nX c #868686",
-"mX c #969696",
-"MX c #CBCBCB",
-"NX c #B2B2B2",
-"BX c #D7D7D7",
-"VX c #DDDDDD",
-"CX c #E3E3E3",
-"ZX c #EAEAEA",
-"AX c #F1F1F1",
-"SX c #F8F8F8",
-"DX c #FFFBF0",
-"FX c #A0A0A4",
-"GX c #808080",
-"HX c #FF0000",
-"JX c #00FF00",
-"KX c #FFFF00",
-"LX c #0000FF",
-"PX c #FF00FF",
-"IX c #00FFFF",
-"UX c #FFFFFF",
-/* pixels */
-"X X X X X X X k k X X X X X X X ",
-"X X X X X X X k j k X X X X X X ",
-"X X X X X X X k o j k X X X X X ",
-"X X X X X X X k * o j k X X X X ",
-"l k k k k k k k * * . j k X X X ",
-"l @ @ @ @ @ @ @ 4 e e % j k X X ",
-"l O 3 8 e r r r r r r e ; j k X ",
-"l @ e e r r r r r u p a f < j k ",
-"l @ r u p a a a a a f f w j k i ",
-"l O ; ; ; ; ; < a f b 0 j k t : ",
-"l k k k k k k k s j 7 j k q = X ",
-"X $ = = = = = k g 7 j k 9 & X X ",
-"X X X X X X X k 2 j k 6 $ X X X ",
-"X X X X X X X k j k 5 + X X X X ",
-"X X X X X X X k k 1 + X X X X X ",
-"X X X X X X X = , X X X X X X X "
-};
diff --git a/src/xpm/send16noshadow.xpm b/src/xpm/send16noshadow.xpm deleted file mode 100644 index f6cef45e0d..0000000000 --- a/src/xpm/send16noshadow.xpm +++ /dev/null @@ -1,278 +0,0 @@ -/* XPM */
-static const char * send16noshadow_xpm[] = {
-/* columns rows colors chars-per-pixel */
-"16 16 256 2",
-" c #ADF7AD",
-". c #9CFF9C",
-"X c None",
-"o c #ADEFAD",
-"O c #94FF94",
-"+ c #D6CECE",
-"@ c #8CFF8C",
-"# c #CECECE",
-"$ c #CECEC5",
-"% c #84FF84",
-"& c #CEC5C5",
-"* c #73FF73",
-"= c #C5C5C5",
-"- c #6BFF6B",
-"; c #73F773",
-": c #C5BDBD",
-"> c #6BF76B",
-", c #BDBDBD",
-"< c #63F763",
-"1 c #B5B5B5",
-"2 c #52F752",
-"3 c #42FF42",
-"4 c #3AFF3A",
-"5 c #ADADAD",
-"6 c #ADADA5",
-"7 c #4AEF4A",
-"8 c #29FF29",
-"9 c #A5A5A5",
-"0 c #42E642",
-"q c #9CA59C",
-"w c #3AE63A",
-"e c #10FF10",
-"r c #08FF08",
-"t c #949C94",
-"y c #00FF00",
-"u c #00F700",
-"i c #8C948C",
-"p c #00EF00",
-"a c #08E608",
-"s c #10DE10",
-"d c #00E600",
-"f c #00DE00",
-"g c #19C519",
-"h c #00CE00",
-"j c #00C500",
-"k c #008C00",
-"l c #008400",
-"z c #669900",
-"x c #999900",
-"c c #CC9900",
-"v c #FF9900",
-"b c #00CC00",
-"n c #33CC00",
-"m c #66CC00",
-"M c #99CC00",
-"N c #CCCC00",
-"B c #FFCC00",
-"V c #66FF00",
-"C c #99FF00",
-"Z c #CCFF00",
-"A c #000033",
-"S c #330033",
-"D c #660033",
-"F c #990033",
-"G c #CC0033",
-"H c #FF0033",
-"J c #003333",
-"K c #333333",
-"L c #663333",
-"P c #993333",
-"I c #CC3333",
-"U c #FF3333",
-"Y c #006633",
-"T c #336633",
-"R c #666633",
-"E c #996633",
-"W c #CC6633",
-"Q c #FF6633",
-"! c #009933",
-"~ c #339933",
-"^ c #669933",
-"/ c #999933",
-"( c #CC9933",
-") c #FF9933",
-"_ c #00CC33",
-"` c #33CC33",
-"' c #66CC33",
-"] c #99CC33",
-"[ c #CCCC33",
-"{ c #FFCC33",
-"} c #33FF33",
-"| c #66FF33",
-" . c #99FF33",
-".. c #CCFF33",
-"X. c #FFFF33",
-"o. c #000066",
-"O. c #330066",
-"+. c #660066",
-"@. c #990066",
-"#. c #CC0066",
-"$. c #FF0066",
-"%. c #003366",
-"&. c #333366",
-"*. c #663366",
-"=. c #993366",
-"-. c #CC3366",
-";. c #FF3366",
-":. c #006666",
-">. c #336666",
-",. c #666666",
-"<. c #996666",
-"1. c #CC6666",
-"2. c #009966",
-"3. c #339966",
-"4. c #669966",
-"5. c #999966",
-"6. c #CC9966",
-"7. c #FF9966",
-"8. c #00CC66",
-"9. c #33CC66",
-"0. c #99CC66",
-"q. c #CCCC66",
-"w. c #FFCC66",
-"e. c #00FF66",
-"r. c #33FF66",
-"t. c #99FF66",
-"y. c #CCFF66",
-"u. c #FF00CC",
-"i. c #CC00FF",
-"p. c #009999",
-"a. c #993399",
-"s. c #990099",
-"d. c #CC0099",
-"f. c #000099",
-"g. c #333399",
-"h. c #660099",
-"j. c #CC3399",
-"k. c #FF0099",
-"l. c #006699",
-"z. c #336699",
-"x. c #663399",
-"c. c #996699",
-"v. c #CC6699",
-"b. c #FF3399",
-"n. c #339999",
-"m. c #669999",
-"M. c #999999",
-"N. c #CC9999",
-"B. c #FF9999",
-"V. c #00CC99",
-"C. c #33CC99",
-"Z. c #66CC66",
-"A. c #99CC99",
-"S. c #CCCC99",
-"D. c #FFCC99",
-"F. c #00FF99",
-"G. c #33FF99",
-"H. c #66CC99",
-"J. c #99FF99",
-"K. c #CCFF99",
-"L. c #FFFF99",
-"P. c #0000CC",
-"I. c #330099",
-"U. c #6600CC",
-"Y. c #9900CC",
-"T. c #CC00CC",
-"R. c #003399",
-"E. c #3333CC",
-"W. c #6633CC",
-"Q. c #9933CC",
-"!. c #CC33CC",
-"~. c #FF33CC",
-"^. c #0066CC",
-"/. c #3366CC",
-"(. c #666699",
-"). c #9966CC",
-"_. c #CC66CC",
-"`. c #FF6699",
-"'. c #0099CC",
-"]. c #3399CC",
-"[. c #6699CC",
-"{. c #9999CC",
-"}. c #CC99CC",
-"|. c #FF99CC",
-" X c #00CCCC",
-".X c #33CCCC",
-"XX c #66CCCC",
-"oX c #99CCCC",
-"OX c #CCCCCC",
-"+X c #FFCCCC",
-"@X c #00FFCC",
-"#X c #33FFCC",
-"$X c #66FF99",
-"%X c #99FFCC",
-"&X c #CCFFCC",
-"*X c #FFFFCC",
-"=X c #3300CC",
-"-X c #6600FF",
-";X c #9900FF",
-":X c #0033CC",
-">X c #3333FF",
-",X c #6633FF",
-"<X c #9933FF",
-"1X c #CC33FF",
-"2X c #FF33FF",
-"3X c #0066FF",
-"4X c #3366FF",
-"5X c #6666CC",
-"6X c #9966FF",
-"7X c #CC66FF",
-"8X c #FF66CC",
-"9X c #0099FF",
-"0X c #3399FF",
-"qX c #6699FF",
-"wX c #9999FF",
-"eX c #CC99FF",
-"rX c #FF99FF",
-"tX c #00CCFF",
-"yX c #33CCFF",
-"uX c #66CCFF",
-"iX c #99CCFF",
-"pX c #CCCCFF",
-"aX c #FFCCFF",
-"sX c #33FFFF",
-"dX c #66FFCC",
-"fX c #99FFFF",
-"gX c #CCFFFF",
-"hX c #FF6666",
-"jX c #66FF66",
-"kX c #FFFF66",
-"lX c #6666FF",
-"zX c #FF66FF",
-"xX c #66FFFF",
-"cX c #A50021",
-"vX c #5F5F5F",
-"bX c #777777",
-"nX c #868686",
-"mX c #969696",
-"MX c #CBCBCB",
-"NX c #B2B2B2",
-"BX c #D7D7D7",
-"VX c #DDDDDD",
-"CX c #E3E3E3",
-"ZX c #EAEAEA",
-"AX c #F1F1F1",
-"SX c #F8F8F8",
-"DX c #FFFBF0",
-"FX c #A0A0A4",
-"GX c #808080",
-"HX c #FF0000",
-"JX c #00FF00",
-"KX c #FFFF00",
-"LX c #0000FF",
-"PX c #FF00FF",
-"IX c #00FFFF",
-"UX c #FFFFFF",
-/* pixels */
-"X X X X X X X k k X X X X X X X ",
-"X X X X X X X k j k X X X X X X ",
-"X X X X X X X k o j k X X X X X ",
-"X X X X X X X k * o j k X X X X ",
-"l k k k k k k k * * . j k X X X ",
-"l @ @ @ @ @ @ @ 4 e e % j k X X ",
-"l O 3 8 e r r r r r r e ; j k X ",
-"l @ e e r r r r r u p a f < j k ",
-"l @ r u p a a a a a f f w j k X ",
-"l O ; ; ; ; ; < a f b 0 j k X X ",
-"l k k k k k k k s j 7 j k X X X ",
-"X X X X X X X k g 7 j k X X X X ",
-"X X X X X X X k 2 j k X X X X X ",
-"X X X X X X X k j k X X X X X X ",
-"X X X X X X X k k X X X X X X X ",
-"X X X X X X X X X X X X X X X X "
-};
diff --git a/src/xpm/send20.xpm b/src/xpm/send20.xpm deleted file mode 100644 index 68e7b1379a..0000000000 --- a/src/xpm/send20.xpm +++ /dev/null @@ -1,282 +0,0 @@ -/* XPM */
-static const char * send20_xpm[] = {
-/* columns rows colors chars-per-pixel */
-"20 20 256 2",
-" c #CEFFCE",
-". c #BDFFBD",
-"X c #C5F7C5",
-"o c #B5FFB5",
-"O c #ADFFAD",
-"+ c #A5FFA5",
-"@ c #9CFF9C",
-"# c None",
-"$ c #94FF94",
-"% c #D6CECE",
-"& c #8CFF8C",
-"* c #CECEC5",
-"= c #84FF84",
-"- c #94EF94",
-"; c #7BFF7B",
-": c #CEC5C5",
-"> c #73FF73",
-", c #C5C5C5",
-"< c #C5C5BD",
-"1 c #6BFF6B",
-"2 c #BDC5B5",
-"3 c #63FF63",
-"4 c #6BF76B",
-"5 c #BDBDBD",
-"6 c #BDBDB5",
-"7 c #5AFF5A",
-"8 c #63F763",
-"9 c #B5BDB5",
-"0 c #B5BDAD",
-"q c #52FF52",
-"w c #BDB5B5",
-"e c #5AF75A",
-"r c #B5B5B5",
-"t c #B5B5AD",
-"y c #52F752",
-"u c #42FF42",
-"i c #52EF52",
-"p c #ADADAD",
-"a c #ADADA5",
-"s c #4AEF4A",
-"d c #31FF31",
-"f c #29FF29",
-"g c #A5A5A5",
-"h c #21FF21",
-"j c #5AD65A",
-"k c #42E642",
-"l c #94AD94",
-"z c #4ADE4A",
-"x c #3AE63A",
-"c c #5ACE5A",
-"v c #10FF10",
-"b c #9C9C9C",
-"n c #31E631",
-"m c #08FF08",
-"M c #949C94",
-"N c #84A584",
-"B c #00FF00",
-"V c #3AD63A",
-"C c #52C552",
-"Z c #00F700",
-"A c #8C948C",
-"S c #849484",
-"D c #00EF00",
-"F c #739C73",
-"G c #08E608",
-"H c #4AB54A",
-"J c #31C531",
-"K c #00E600",
-"L c #739473",
-"P c #00DE00",
-"I c #63945A",
-"U c #6B8C6B",
-"Y c #00D600",
-"T c #42A542",
-"R c #638C63",
-"E c #00CE00",
-"W c #21B521",
-"Q c #5A8C5A",
-"! c #00C500",
-"~ c #528C52",
-"^ c #3A9C3A",
-"/ c #4A8C4A",
-"( c #00BD00",
-") c #319431",
-"_ c #219C21",
-"` c #318C31",
-"' c #3A843A",
-"] c #219421",
-"[ c #298C29",
-"{ c #318431",
-"} c #218C21",
-"| c #218C19",
-" . c #198C19",
-".. c #218421",
-"X. c #297B29",
-"o. c #198419",
-"O. c #217B21",
-"+. c #108410",
-"@. c #197B19",
-"#. c #CC0066",
-"$. c #FF0066",
-"%. c #003366",
-"&. c #333366",
-"*. c #663366",
-"=. c #993366",
-"-. c #CC3366",
-";. c #FF3366",
-":. c #006666",
-">. c #336666",
-",. c #666666",
-"<. c #996666",
-"1. c #CC6666",
-"2. c #009966",
-"3. c #339966",
-"4. c #669966",
-"5. c #999966",
-"6. c #CC9966",
-"7. c #FF9966",
-"8. c #00CC66",
-"9. c #33CC66",
-"0. c #99CC66",
-"q. c #CCCC66",
-"w. c #FFCC66",
-"e. c #00FF66",
-"r. c #33FF66",
-"t. c #99FF66",
-"y. c #CCFF66",
-"u. c #FF00CC",
-"i. c #CC00FF",
-"p. c #009999",
-"a. c #993399",
-"s. c #990099",
-"d. c #CC0099",
-"f. c #000099",
-"g. c #333399",
-"h. c #660099",
-"j. c #CC3399",
-"k. c #FF0099",
-"l. c #006699",
-"z. c #336699",
-"x. c #663399",
-"c. c #996699",
-"v. c #CC6699",
-"b. c #FF3399",
-"n. c #339999",
-"m. c #669999",
-"M. c #999999",
-"N. c #CC9999",
-"B. c #FF9999",
-"V. c #00CC99",
-"C. c #33CC99",
-"Z. c #66CC66",
-"A. c #99CC99",
-"S. c #CCCC99",
-"D. c #FFCC99",
-"F. c #00FF99",
-"G. c #33FF99",
-"H. c #66CC99",
-"J. c #99FF99",
-"K. c #CCFF99",
-"L. c #FFFF99",
-"P. c #0000CC",
-"I. c #330099",
-"U. c #6600CC",
-"Y. c #9900CC",
-"T. c #CC00CC",
-"R. c #003399",
-"E. c #3333CC",
-"W. c #6633CC",
-"Q. c #9933CC",
-"!. c #CC33CC",
-"~. c #FF33CC",
-"^. c #0066CC",
-"/. c #3366CC",
-"(. c #666699",
-"). c #9966CC",
-"_. c #CC66CC",
-"`. c #FF6699",
-"'. c #0099CC",
-"]. c #3399CC",
-"[. c #6699CC",
-"{. c #9999CC",
-"}. c #CC99CC",
-"|. c #FF99CC",
-" X c #00CCCC",
-".X c #33CCCC",
-"XX c #66CCCC",
-"oX c #99CCCC",
-"OX c #CCCCCC",
-"+X c #FFCCCC",
-"@X c #00FFCC",
-"#X c #33FFCC",
-"$X c #66FF99",
-"%X c #99FFCC",
-"&X c #CCFFCC",
-"*X c #FFFFCC",
-"=X c #3300CC",
-"-X c #6600FF",
-";X c #9900FF",
-":X c #0033CC",
-">X c #3333FF",
-",X c #6633FF",
-"<X c #9933FF",
-"1X c #CC33FF",
-"2X c #FF33FF",
-"3X c #0066FF",
-"4X c #3366FF",
-"5X c #6666CC",
-"6X c #9966FF",
-"7X c #CC66FF",
-"8X c #FF66CC",
-"9X c #0099FF",
-"0X c #3399FF",
-"qX c #6699FF",
-"wX c #9999FF",
-"eX c #CC99FF",
-"rX c #FF99FF",
-"tX c #00CCFF",
-"yX c #33CCFF",
-"uX c #66CCFF",
-"iX c #99CCFF",
-"pX c #CCCCFF",
-"aX c #FFCCFF",
-"sX c #33FFFF",
-"dX c #66FFCC",
-"fX c #99FFFF",
-"gX c #CCFFFF",
-"hX c #FF6666",
-"jX c #66FF66",
-"kX c #FFFF66",
-"lX c #6666FF",
-"zX c #FF66FF",
-"xX c #66FFFF",
-"cX c #A50021",
-"vX c #5F5F5F",
-"bX c #777777",
-"nX c #868686",
-"mX c #969696",
-"MX c #CBCBCB",
-"NX c #B2B2B2",
-"BX c #D7D7D7",
-"VX c #DDDDDD",
-"CX c #E3E3E3",
-"ZX c #EAEAEA",
-"AX c #F1F1F1",
-"SX c #F8F8F8",
-"DX c #FFFBF0",
-"FX c #A0A0A4",
-"GX c #808080",
-"HX c #FF0000",
-"JX c #00FF00",
-"KX c #FFFF00",
-"LX c #0000FF",
-"PX c #FF00FF",
-"IX c #00FFFF",
-"UX c #FFFFFF",
-/* pixels */
-"# # # # # # # # # # # # # # # # # # # # ",
-"# # # # # # # ` 0 # # # # # # # # # # # ",
-"# # # # # # # ..` l # # # # # # # # # # ",
-"# # # # # # # [ X ) N # # # # # # # # # ",
-"# # # # # # # [ &X. ^ F # # # # # # # # ",
-"# # # # # # # } o & o T I : # # # # # # ",
-"` ` ` ` ` ` ` ` + 7 ; + H ~ < # # # # # ",
-"` = = = = = = - @ d v h $ C ' 5 # # # # ",
-"` = = 3 u h v v v m m m v ; c { 6 # # # ",
-"` = f v v m m m m m m Z G G 4 j ..t # # ",
-"` = v m m m Z Z D D G G G P n ; _ R 5 # ",
-"` = m Z G G G G G G G P Y x 4 _ Q g # # ",
-"` = $ $ $ $ $ & e P P E k 8 .U g # # # ",
-"..[ ......[ [ ] e Y ! s i o.L p # # # # ",
-"# # 5 6 6 6 9 ..i ( i z o.S t # # # # # ",
-"# # # # # # # } i i V O.A r # # # # # # ",
-"# # # # # # # } 7 J X.M 6 # # # # # # # ",
-"# # # # # # # | W ' b < # # # # # # # # ",
-"# # # # # # # @.~ g , # # # # # # # # # ",
-"# # # # # # # 6 < , # # # # # # # # # # "
-};
|