From 4405b78d6059e536c36974088a8ed4d9f0f29898 Mon Sep 17 00:00:00 2001 From: sirius-m Date: Sun, 30 Aug 2009 03:46:39 +0000 Subject: First commit --- base58.h | 201 + bignum.h | 498 ++ db.cpp | 614 +++ db.h | 420 ++ headers.h | 71 + irc.cpp | 314 ++ irc.h | 10 + key.h | 156 + libeay32.dll | Bin 0 -> 1306630 bytes license.txt | 19 + main.cpp | 2692 ++++++++++ main.h | 1329 +++++ makefile | 83 + makefile.vc | 77 + market.cpp | 264 + market.h | 182 + mingwm10.dll | Bin 0 -> 11673 bytes net.cpp | 1100 ++++ net.h | 856 ++++ rc/addressbook16.bmp | Bin 0 -> 1334 bytes rc/addressbook16mask.bmp | Bin 0 -> 126 bytes rc/addressbook20.bmp | Bin 0 -> 1478 bytes rc/addressbook20mask.bmp | Bin 0 -> 142 bytes rc/bitcoin.ico | Bin 0 -> 22486 bytes rc/check.ico | Bin 0 -> 766 bytes rc/send16.bmp | Bin 0 -> 1334 bytes rc/send16mask.bmp | Bin 0 -> 126 bytes rc/send16masknoshadow.bmp | Bin 0 -> 126 bytes rc/send20.bmp | Bin 0 -> 1478 bytes rc/send20mask.bmp | Bin 0 -> 142 bytes readme.txt | 76 + script.cpp | 1127 +++++ script.h | 597 +++ serialize.h | 1158 +++++ sha.cpp | 554 +++ sha.h | 177 + ui.cpp | 3290 ++++++++++++ ui.h | 420 ++ ui.rc | 14 + uibase.cpp | 1825 +++++++ uibase.h | 723 +++ uint256.h | 750 +++ uiproject.fbp | 11860 ++++++++++++++++++++++++++++++++++++++++++++ util.cpp | 383 ++ util.h | 399 ++ 45 files changed, 32239 insertions(+) create mode 100644 base58.h create mode 100644 bignum.h create mode 100644 db.cpp create mode 100644 db.h create mode 100644 headers.h create mode 100644 irc.cpp create mode 100644 irc.h create mode 100644 key.h create mode 100644 libeay32.dll create mode 100644 license.txt create mode 100644 main.cpp create mode 100644 main.h create mode 100644 makefile create mode 100644 makefile.vc create mode 100644 market.cpp create mode 100644 market.h create mode 100644 mingwm10.dll create mode 100644 net.cpp create mode 100644 net.h create mode 100644 rc/addressbook16.bmp create mode 100644 rc/addressbook16mask.bmp create mode 100644 rc/addressbook20.bmp create mode 100644 rc/addressbook20mask.bmp create mode 100644 rc/bitcoin.ico create mode 100644 rc/check.ico create mode 100644 rc/send16.bmp create mode 100644 rc/send16mask.bmp create mode 100644 rc/send16masknoshadow.bmp create mode 100644 rc/send20.bmp create mode 100644 rc/send20mask.bmp create mode 100644 readme.txt create mode 100644 script.cpp create mode 100644 script.h create mode 100644 serialize.h create mode 100644 sha.cpp create mode 100644 sha.h create mode 100644 ui.cpp create mode 100644 ui.h create mode 100644 ui.rc create mode 100644 uibase.cpp create mode 100644 uibase.h create mode 100644 uint256.h create mode 100644 uiproject.fbp create mode 100644 util.cpp create mode 100644 util.h diff --git a/base58.h b/base58.h new file mode 100644 index 0000000000..69f40bd208 --- /dev/null +++ b/base58.h @@ -0,0 +1,201 @@ +// Copyright (c) 2009 Satoshi Nakamoto +// Distributed under the MIT/X11 software license, see the accompanying +// file license.txt or http://www.opensource.org/licenses/mit-license.php. + + +// +// Why base-58 instead of standard base-64 encoding? +// - Don't want 0OIl characters that look the same in some fonts and +// could be used to create visually identical looking account numbers. +// - A string with non-alphanumeric characters is not as easily accepted as an account number. +// - E-mail usually won't line-break if there's no punctuation to break at. +// - Doubleclicking selects the whole number as one word if it's all alphanumeric. +// + + +static const char* pszBase58 = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"; + + +inline string EncodeBase58(const unsigned char* pbegin, const unsigned char* pend) +{ + CAutoBN_CTX pctx; + CBigNum bn58 = 58; + CBigNum bn0 = 0; + + // Convert big endian data to little endian + // Extra zero at the end make sure bignum will interpret as a positive number + vector vchTmp(pend-pbegin+1, 0); + reverse_copy(pbegin, pend, vchTmp.begin()); + + // Convert little endian data to bignum + CBigNum bn; + bn.setvch(vchTmp); + + // Convert bignum to string + string str; + str.reserve((pend - pbegin) * 138 / 100 + 1); + CBigNum dv; + CBigNum rem; + while (bn > bn0) + { + if (!BN_div(&dv, &rem, &bn, &bn58, pctx)) + throw bignum_error("EncodeBase58 : BN_div failed"); + bn = dv; + unsigned int c = rem.getulong(); + str += pszBase58[c]; + } + + // Leading zeroes encoded as base58 zeros + for (const unsigned char* p = pbegin; p < pend && *p == 0; p++) + str += pszBase58[0]; + + // Convert little endian string to big endian + reverse(str.begin(), str.end()); + return str; +} + +inline string EncodeBase58(const vector& vch) +{ + return EncodeBase58(&vch[0], &vch[0] + vch.size()); +} + +inline bool DecodeBase58(const char* psz, vector& vchRet) +{ + CAutoBN_CTX pctx; + vchRet.clear(); + CBigNum bn58 = 58; + CBigNum bn = 0; + CBigNum bnChar; + while (isspace(*psz)) + psz++; + + // Convert big endian string to bignum + for (const char* p = psz; *p; p++) + { + const char* p1 = strchr(pszBase58, *p); + if (p1 == NULL) + { + while (isspace(*p)) + p++; + if (*p != '\0') + return false; + break; + } + bnChar.setulong(p1 - pszBase58); + if (!BN_mul(&bn, &bn, &bn58, pctx)) + throw bignum_error("DecodeBase58 : BN_mul failed"); + bn += bnChar; + } + + // Get bignum as little endian data + vector vchTmp = bn.getvch(); + + // Trim off sign byte if present + if (vchTmp.size() >= 2 && vchTmp.end()[-1] == 0 && vchTmp.end()[-2] >= 0x80) + vchTmp.erase(vchTmp.end()-1); + + // Restore leading zeros + int nLeadingZeros = 0; + for (const char* p = psz; *p == pszBase58[0]; p++) + nLeadingZeros++; + vchRet.assign(nLeadingZeros + vchTmp.size(), 0); + + // Convert little endian data to big endian + reverse_copy(vchTmp.begin(), vchTmp.end(), vchRet.end() - vchTmp.size()); + return true; +} + +inline bool DecodeBase58(const string& str, vector& vchRet) +{ + return DecodeBase58(str.c_str(), vchRet); +} + + + + + +inline string EncodeBase58Check(const vector& vchIn) +{ + // add 4-byte hash check to the end + vector vch(vchIn); + uint256 hash = Hash(vch.begin(), vch.end()); + vch.insert(vch.end(), (unsigned char*)&hash, (unsigned char*)&hash + 4); + return EncodeBase58(vch); +} + +inline bool DecodeBase58Check(const char* psz, vector& vchRet) +{ + if (!DecodeBase58(psz, vchRet)) + return false; + if (vchRet.size() < 4) + { + vchRet.clear(); + return false; + } + uint256 hash = Hash(vchRet.begin(), vchRet.end()-4); + if (memcmp(&hash, &vchRet.end()[-4], 4) != 0) + { + vchRet.clear(); + return false; + } + vchRet.resize(vchRet.size()-4); + return true; +} + +inline bool DecodeBase58Check(const string& str, vector& vchRet) +{ + return DecodeBase58Check(str.c_str(), vchRet); +} + + + + + + +static const unsigned char ADDRESSVERSION = 0; + +inline string Hash160ToAddress(uint160 hash160) +{ + // add 1-byte version number to the front + vector vch(1, ADDRESSVERSION); + vch.insert(vch.end(), UBEGIN(hash160), UEND(hash160)); + return EncodeBase58Check(vch); +} + +inline bool AddressToHash160(const char* psz, uint160& hash160Ret) +{ + vector 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); +} + +inline bool AddressToHash160(const string& str, uint160& hash160Ret) +{ + return AddressToHash160(str.c_str(), hash160Ret); +} + +inline bool IsValidBitcoinAddress(const char* psz) +{ + uint160 hash160; + return AddressToHash160(psz, hash160); +} + +inline bool IsValidBitcoinAddress(const string& str) +{ + return IsValidBitcoinAddress(str.c_str()); +} + + + + +inline string PubKeyToAddress(const vector& vchPubKey) +{ + return Hash160ToAddress(Hash160(vchPubKey)); +} diff --git a/bignum.h b/bignum.h new file mode 100644 index 0000000000..8aa4e9c4ff --- /dev/null +++ b/bignum.h @@ -0,0 +1,498 @@ +// Copyright (c) 2009 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 +#include +#include + + + + + +class bignum_error : public std::runtime_error +{ +public: + explicit bignum_error(const std::string& str) : std::runtime_error(str) {} +}; + + + +class CAutoBN_CTX +{ +protected: + BN_CTX* pctx; + BN_CTX* operator=(BN_CTX* pnew) { return pctx = pnew; } + +public: + CAutoBN_CTX() + { + pctx = BN_CTX_new(); + if (pctx == NULL) + throw bignum_error("CAutoBN_CTX : BN_CTX_new() returned NULL"); + } + + ~CAutoBN_CTX() + { + if (pctx != NULL) + BN_CTX_free(pctx); + } + + operator BN_CTX*() { return pctx; } + BN_CTX& operator*() { return *pctx; } + BN_CTX** operator&() { return &pctx; } + bool operator!() { return (pctx == NULL); } +}; + + + +class CBigNum : public BIGNUM +{ +public: + CBigNum() + { + BN_init(this); + } + + CBigNum(const CBigNum& b) + { + BN_init(this); + if (!BN_copy(this, &b)) + { + BN_clear_free(this); + throw bignum_error("CBigNum::CBigNum(const CBigNum&) : BN_copy failed"); + } + } + + explicit CBigNum(const std::string& str) + { + BN_init(this); + SetHex(str); + } + + CBigNum& operator=(const CBigNum& b) + { + if (!BN_copy(this, &b)) + throw bignum_error("CBigNum::operator= : BN_copy failed"); + return (*this); + } + + ~CBigNum() + { + BN_clear_free(this); + } + + CBigNum(char n) { BN_init(this); if (n >= 0) setulong(n); else setint64(n); } + CBigNum(short n) { BN_init(this); if (n >= 0) setulong(n); else setint64(n); } + CBigNum(int n) { BN_init(this); if (n >= 0) setulong(n); else setint64(n); } + CBigNum(long n) { BN_init(this); if (n >= 0) setulong(n); else setint64(n); } + CBigNum(int64 n) { BN_init(this); setint64(n); } + CBigNum(unsigned char n) { BN_init(this); setulong(n); } + CBigNum(unsigned short n) { BN_init(this); setulong(n); } + CBigNum(unsigned int n) { BN_init(this); setulong(n); } + CBigNum(unsigned long n) { BN_init(this); setulong(n); } + CBigNum(uint64 n) { BN_init(this); setuint64(n); } + explicit CBigNum(uint256 n) { BN_init(this); setuint256(n); } + + explicit CBigNum(const std::vector& vch) + { + BN_init(this); + setvch(vch); + } + + void setulong(unsigned long n) + { + if (!BN_set_word(this, n)) + throw bignum_error("CBigNum conversion from unsigned long : BN_set_word failed"); + } + + unsigned long getulong() const + { + return BN_get_word(this); + } + + unsigned int getuint() const + { + return BN_get_word(this); + } + + int getint() const + { + unsigned long n = BN_get_word(this); + if (!BN_is_negative(this)) + return (n > INT_MAX ? INT_MAX : n); + else + return (n > INT_MAX ? INT_MIN : -(int)n); + } + + void setint64(int64 n) + { + unsigned char pch[sizeof(n) + 6]; + unsigned char* p = pch + 4; + bool fNegative = false; + if (n < (int64)0) + { + n = -n; + fNegative = true; + } + bool fLeadingZeroes = true; + for (int i = 0; i < 8; i++) + { + unsigned char c = (n >> 56) & 0xff; + n <<= 8; + if (fLeadingZeroes) + { + if (c == 0) + continue; + if (c & 0x80) + *p++ = (fNegative ? 0x80 : 0); + else if (fNegative) + c |= 0x80; + fLeadingZeroes = false; + } + *p++ = c; + } + unsigned int nSize = p - (pch + 4); + pch[0] = (nSize >> 24) & 0xff; + pch[1] = (nSize >> 16) & 0xff; + pch[2] = (nSize >> 8) & 0xff; + pch[3] = (nSize) & 0xff; + BN_mpi2bn(pch, p - pch, this); + } + + void setuint64(uint64 n) + { + unsigned char pch[sizeof(n) + 6]; + unsigned char* p = pch + 4; + bool fLeadingZeroes = true; + for (int i = 0; i < 8; i++) + { + unsigned char c = (n >> 56) & 0xff; + n <<= 8; + if (fLeadingZeroes) + { + if (c == 0) + continue; + if (c & 0x80) + *p++ = 0; + fLeadingZeroes = false; + } + *p++ = c; + } + unsigned int nSize = p - (pch + 4); + pch[0] = (nSize >> 24) & 0xff; + pch[1] = (nSize >> 16) & 0xff; + pch[2] = (nSize >> 8) & 0xff; + pch[3] = (nSize) & 0xff; + BN_mpi2bn(pch, p - pch, this); + } + + void setuint256(uint256 n) + { + unsigned char pch[sizeof(n) + 6]; + unsigned char* p = pch + 4; + bool fLeadingZeroes = true; + unsigned char* pbegin = (unsigned char*)&n; + unsigned char* psrc = pbegin + sizeof(n); + while (psrc != pbegin) + { + unsigned char c = *(--psrc); + if (fLeadingZeroes) + { + if (c == 0) + continue; + if (c & 0x80) + *p++ = 0; + fLeadingZeroes = false; + } + *p++ = c; + } + unsigned int nSize = p - (pch + 4); + pch[0] = (nSize >> 24) & 0xff; + pch[1] = (nSize >> 16) & 0xff; + pch[2] = (nSize >> 8) & 0xff; + pch[3] = (nSize >> 0) & 0xff; + BN_mpi2bn(pch, p - pch, this); + } + + uint256 getuint256() + { + unsigned int nSize = BN_bn2mpi(this, NULL); + if (nSize < 4) + return 0; + std::vector vch(nSize); + BN_bn2mpi(this, &vch[0]); + if (vch.size() > 4) + vch[4] &= 0x7f; + uint256 n = 0; + for (int i = 0, j = vch.size()-1; i < sizeof(n) && j >= 4; i++, j--) + ((unsigned char*)&n)[i] = vch[j]; + return n; + } + + void setvch(const std::vector& vch) + { + std::vector vch2(vch.size() + 4); + unsigned int nSize = vch.size(); + vch2[0] = (nSize >> 24) & 0xff; + vch2[1] = (nSize >> 16) & 0xff; + vch2[2] = (nSize >> 8) & 0xff; + vch2[3] = (nSize >> 0) & 0xff; + reverse_copy(vch.begin(), vch.end(), vch2.begin() + 4); + BN_mpi2bn(&vch2[0], vch2.size(), this); + } + + std::vector getvch() const + { + unsigned int nSize = BN_bn2mpi(this, NULL); + if (nSize < 4) + return std::vector(); + std::vector vch(nSize); + BN_bn2mpi(this, &vch[0]); + vch.erase(vch.begin(), vch.begin() + 4); + reverse(vch.begin(), vch.end()); + return vch; + } + + CBigNum& SetCompact(unsigned int nCompact) + { + unsigned int nSize = nCompact >> 24; + std::vector vch(4 + nSize); + vch[3] = nSize; + if (nSize >= 1) vch[4] = (nCompact >> 16) & 0xff; + if (nSize >= 2) vch[5] = (nCompact >> 8) & 0xff; + if (nSize >= 3) vch[6] = (nCompact >> 0) & 0xff; + BN_mpi2bn(&vch[0], vch.size(), this); + return *this; + } + + unsigned int GetCompact() const + { + unsigned int nSize = BN_bn2mpi(this, NULL); + std::vector vch(nSize); + nSize -= 4; + BN_bn2mpi(this, &vch[0]); + unsigned int nCompact = nSize << 24; + if (nSize >= 1) nCompact |= (vch[4] << 16); + if (nSize >= 2) nCompact |= (vch[5] << 8); + if (nSize >= 3) nCompact |= (vch[6] << 0); + return nCompact; + } + + void SetHex(const std::string& str) + { + // skip 0x + const char* psz = str.c_str(); + while (isspace(*psz)) + psz++; + bool fNegative = false; + if (*psz == '-') + { + fNegative = true; + psz++; + } + if (psz[0] == '0' && tolower(psz[1]) == 'x') + psz += 2; + while (isspace(*psz)) + psz++; + + // hex string to bignum + static char phexdigit[256] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,1,2,3,4,5,6,7,8,9,0,0,0,0,0,0, 0,0xa,0xb,0xc,0xd,0xe,0xf,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0xa,0xb,0xc,0xd,0xe,0xf,0,0,0,0,0,0,0,0,0 }; + *this = 0; + while (isxdigit(*psz)) + { + *this <<= 4; + int n = phexdigit[*psz++]; + *this += n; + } + if (fNegative) + *this = 0 - *this; + } + + unsigned int GetSerializeSize(int nType=0, int nVersion=VERSION) const + { + return ::GetSerializeSize(getvch(), nType, nVersion); + } + + template + void Serialize(Stream& s, int nType=0, int nVersion=VERSION) const + { + ::Serialize(s, getvch(), nType, nVersion); + } + + template + void Unserialize(Stream& s, int nType=0, int nVersion=VERSION) + { + vector vch; + ::Unserialize(s, vch, nType, nVersion); + setvch(vch); + } + + + bool operator!() const + { + return BN_is_zero(this); + } + + CBigNum& operator+=(const CBigNum& b) + { + if (!BN_add(this, this, &b)) + throw bignum_error("CBigNum::operator+= : BN_add failed"); + return *this; + } + + CBigNum& operator-=(const CBigNum& b) + { + *this = *this - b; + return *this; + } + + CBigNum& operator*=(const CBigNum& b) + { + CAutoBN_CTX pctx; + if (!BN_mul(this, this, &b, pctx)) + throw bignum_error("CBigNum::operator*= : BN_mul failed"); + return *this; + } + + CBigNum& operator/=(const CBigNum& b) + { + *this = *this / b; + return *this; + } + + CBigNum& operator%=(const CBigNum& b) + { + *this = *this % b; + return *this; + } + + CBigNum& operator<<=(unsigned int shift) + { + if (!BN_lshift(this, this, shift)) + throw bignum_error("CBigNum:operator<<= : BN_lshift failed"); + return *this; + } + + CBigNum& operator>>=(unsigned int shift) + { + if (!BN_rshift(this, this, shift)) + throw bignum_error("CBigNum:operator>>= : BN_rshift failed"); + return *this; + } + + + CBigNum& operator++() + { + // prefix operator + if (!BN_add(this, this, BN_value_one())) + throw bignum_error("CBigNum::operator++ : BN_add failed"); + return *this; + } + + const CBigNum operator++(int) + { + // postfix operator + const CBigNum ret = *this; + ++(*this); + return ret; + } + + CBigNum& operator--() + { + // prefix operator + CBigNum r; + if (!BN_sub(&r, this, BN_value_one())) + throw bignum_error("CBigNum::operator-- : BN_sub failed"); + *this = r; + return *this; + } + + const CBigNum operator--(int) + { + // postfix operator + const CBigNum ret = *this; + --(*this); + return ret; + } + + + friend inline const CBigNum operator-(const CBigNum& a, const CBigNum& b); + friend inline const CBigNum operator/(const CBigNum& a, const CBigNum& b); + friend inline const CBigNum operator%(const CBigNum& a, const CBigNum& b); +}; + + + +inline const CBigNum operator+(const CBigNum& a, const CBigNum& b) +{ + CBigNum r; + if (!BN_add(&r, &a, &b)) + throw bignum_error("CBigNum::operator+ : BN_add failed"); + return r; +} + +inline const CBigNum operator-(const CBigNum& a, const CBigNum& b) +{ + CBigNum r; + if (!BN_sub(&r, &a, &b)) + throw bignum_error("CBigNum::operator- : BN_sub failed"); + return r; +} + +inline const CBigNum operator-(const CBigNum& a) +{ + CBigNum r(a); + BN_set_negative(&r, !BN_is_negative(&r)); + return r; +} + +inline const CBigNum operator*(const CBigNum& a, const CBigNum& b) +{ + CAutoBN_CTX pctx; + CBigNum r; + if (!BN_mul(&r, &a, &b, pctx)) + throw bignum_error("CBigNum::operator* : BN_mul failed"); + return r; +} + +inline const CBigNum operator/(const CBigNum& a, const CBigNum& b) +{ + CAutoBN_CTX pctx; + CBigNum r; + if (!BN_div(&r, NULL, &a, &b, pctx)) + throw bignum_error("CBigNum::operator/ : BN_div failed"); + return r; +} + +inline const CBigNum operator%(const CBigNum& a, const CBigNum& b) +{ + CAutoBN_CTX pctx; + CBigNum r; + if (!BN_mod(&r, &a, &b, pctx)) + throw bignum_error("CBigNum::operator% : BN_div failed"); + return r; +} + +inline const CBigNum operator<<(const CBigNum& a, unsigned int shift) +{ + CBigNum r; + if (!BN_lshift(&r, &a, shift)) + throw bignum_error("CBigNum:operator<< : BN_lshift failed"); + return r; +} + +inline const CBigNum operator>>(const CBigNum& a, unsigned int shift) +{ + CBigNum r; + if (!BN_rshift(&r, &a, shift)) + throw bignum_error("CBigNum:operator>> : BN_rshift failed"); + return r; +} + +inline bool operator==(const CBigNum& a, const CBigNum& b) { return (BN_cmp(&a, &b) == 0); } +inline bool operator!=(const CBigNum& a, const CBigNum& b) { return (BN_cmp(&a, &b) != 0); } +inline bool operator<=(const CBigNum& a, const CBigNum& b) { return (BN_cmp(&a, &b) <= 0); } +inline bool operator>=(const CBigNum& a, const CBigNum& b) { return (BN_cmp(&a, &b) >= 0); } +inline bool operator<(const CBigNum& a, const CBigNum& b) { return (BN_cmp(&a, &b) < 0); } +inline bool operator>(const CBigNum& a, const CBigNum& b) { return (BN_cmp(&a, &b) > 0); } diff --git a/db.cpp b/db.cpp new file mode 100644 index 0000000000..f38f3ffad8 --- /dev/null +++ b/db.cpp @@ -0,0 +1,614 @@ +// Copyright (c) 2009 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" + + + + + + +// +// CDB +// + +static CCriticalSection cs_db; +static bool fDbEnvInit = false; +DbEnv dbenv(0); +static map mapFileUseCount; + +class CDBInit +{ +public: + CDBInit() + { + } + ~CDBInit() + { + if (fDbEnvInit) + { + dbenv.close(0); + fDbEnvInit = false; + } + } +} +instance_of_cdbinit; + + +CDB::CDB(const char* pszFile, const char* pszMode, bool fTxn) : pdb(NULL) +{ + int ret; + if (pszFile == NULL) + return; + + bool fCreate = strchr(pszMode, 'c'); + bool fReadOnly = (!strchr(pszMode, '+') && !strchr(pszMode, 'w')); + unsigned int nFlags = DB_THREAD; + if (fCreate) + nFlags |= DB_CREATE; + else if (fReadOnly) + nFlags |= DB_RDONLY; + if (!fReadOnly || fTxn) + nFlags |= DB_AUTO_COMMIT; + + CRITICAL_BLOCK(cs_db) + { + if (!fDbEnvInit) + { + string strAppDir = GetAppDir(); + string strLogDir = strAppDir + "\\database"; + _mkdir(strLogDir.c_str()); + printf("dbenv.open strAppDir=%s\n", strAppDir.c_str()); + + dbenv.set_lg_dir(strLogDir.c_str()); + dbenv.set_lg_max(10000000); + dbenv.set_lk_max_locks(10000); + dbenv.set_lk_max_objects(10000); + dbenv.set_errfile(fopen("db.log", "a")); /// debug + ///dbenv.log_set_config(DB_LOG_AUTO_REMOVE, 1); /// causes corruption + ret = dbenv.open(strAppDir.c_str(), + DB_CREATE | + DB_INIT_LOCK | + DB_INIT_LOG | + DB_INIT_MPOOL | + DB_INIT_TXN | + DB_THREAD | + DB_PRIVATE | + DB_RECOVER, + 0); + if (ret > 0) + throw runtime_error(strprintf("CDB() : error %d opening database environment\n", ret)); + fDbEnvInit = true; + } + + strFile = pszFile; + ++mapFileUseCount[strFile]; + } + + pdb = new Db(&dbenv, 0); + + ret = pdb->open(NULL, // Txn pointer + pszFile, // Filename + "main", // Logical db name + DB_BTREE, // Database type + nFlags, // Flags + 0); + + if (ret > 0) + { + delete pdb; + pdb = NULL; + CRITICAL_BLOCK(cs_db) + --mapFileUseCount[strFile]; + strFile = ""; + throw runtime_error(strprintf("CDB() : can't open database file %s, error %d\n", pszFile, ret)); + } + + if (fCreate && !Exists(string("version"))) + WriteVersion(VERSION); + + RandAddSeed(); +} + +void CDB::Close() +{ + if (!pdb) + return; + if (!vTxn.empty()) + vTxn.front()->abort(); + vTxn.clear(); + pdb->close(0); + delete pdb; + pdb = NULL; + dbenv.txn_checkpoint(0, 0, 0); + + CRITICAL_BLOCK(cs_db) + --mapFileUseCount[strFile]; + + RandAddSeed(); +} + +void DBFlush(bool fShutdown) +{ + // Flush log data to the actual data file + // on all files that are not in use + printf("DBFlush(%s)\n", fShutdown ? "true" : "false"); + CRITICAL_BLOCK(cs_db) + { + dbenv.txn_checkpoint(0, 0, 0); + map::iterator mi = mapFileUseCount.begin(); + while (mi != mapFileUseCount.end()) + { + string strFile = (*mi).first; + int nRefCount = (*mi).second; + if (nRefCount == 0) + { + dbenv.lsn_reset(strFile.c_str(), 0); + mapFileUseCount.erase(mi++); + } + else + mi++; + } + if (fShutdown) + { + char** listp; + if (mapFileUseCount.empty()) + dbenv.log_archive(&listp, DB_ARCH_REMOVE); + dbenv.close(0); + fDbEnvInit = false; + } + } +} + + + + + + +// +// CTxDB +// + +bool CTxDB::ReadTxIndex(uint256 hash, CTxIndex& txindex) +{ + assert(!fClient); + txindex.SetNull(); + return Read(make_pair(string("tx"), hash), txindex); +} + +bool CTxDB::UpdateTxIndex(uint256 hash, const CTxIndex& txindex) +{ + assert(!fClient); + return Write(make_pair(string("tx"), hash), txindex); +} + +bool CTxDB::AddTxIndex(const CTransaction& tx, const CDiskTxPos& pos, int nHeight) +{ + assert(!fClient); + + // Add to tx index + uint256 hash = tx.GetHash(); + CTxIndex txindex(pos, tx.vout.size()); + return Write(make_pair(string("tx"), hash), txindex); +} + +bool CTxDB::EraseTxIndex(const CTransaction& tx) +{ + assert(!fClient); + uint256 hash = tx.GetHash(); + + return Erase(make_pair(string("tx"), hash)); +} + +bool CTxDB::ContainsTx(uint256 hash) +{ + assert(!fClient); + return Exists(make_pair(string("tx"), hash)); +} + +bool CTxDB::ReadOwnerTxes(uint160 hash160, int nMinHeight, vector& vtx) +{ + assert(!fClient); + vtx.clear(); + + // Get cursor + Dbc* pcursor = GetCursor(); + if (!pcursor) + return false; + + unsigned int fFlags = DB_SET_RANGE; + loop + { + // Read next record + CDataStream ssKey; + if (fFlags == DB_SET_RANGE) + ssKey << string("owner") << hash160 << CDiskTxPos(0, 0, 0); + CDataStream ssValue; + int ret = ReadAtCursor(pcursor, ssKey, ssValue, fFlags); + fFlags = DB_NEXT; + if (ret == DB_NOTFOUND) + break; + else if (ret != 0) + return false; + + // Unserialize + string strType; + uint160 hashItem; + CDiskTxPos pos; + ssKey >> strType >> hashItem >> pos; + int nItemHeight; + ssValue >> nItemHeight; + + // Read transaction + if (strType != "owner" || hashItem != hash160) + break; + if (nItemHeight >= nMinHeight) + { + vtx.resize(vtx.size()+1); + if (!vtx.back().ReadFromDisk(pos)) + return false; + } + } + return true; +} + +bool CTxDB::ReadDiskTx(uint256 hash, CTransaction& tx, CTxIndex& txindex) +{ + assert(!fClient); + tx.SetNull(); + if (!ReadTxIndex(hash, txindex)) + return false; + return (tx.ReadFromDisk(txindex.pos)); +} + +bool CTxDB::ReadDiskTx(uint256 hash, CTransaction& tx) +{ + CTxIndex txindex; + return ReadDiskTx(hash, tx, txindex); +} + +bool CTxDB::ReadDiskTx(COutPoint outpoint, CTransaction& tx, CTxIndex& txindex) +{ + return ReadDiskTx(outpoint.hash, tx, txindex); +} + +bool CTxDB::ReadDiskTx(COutPoint outpoint, CTransaction& tx) +{ + CTxIndex txindex; + return ReadDiskTx(outpoint.hash, tx, txindex); +} + +bool CTxDB::WriteBlockIndex(const CDiskBlockIndex& blockindex) +{ + return Write(make_pair(string("blockindex"), blockindex.GetBlockHash()), blockindex); +} + +bool CTxDB::EraseBlockIndex(uint256 hash) +{ + return Erase(make_pair(string("blockindex"), hash)); +} + +bool CTxDB::ReadHashBestChain(uint256& hashBestChain) +{ + return Read(string("hashBestChain"), hashBestChain); +} + +bool CTxDB::WriteHashBestChain(uint256 hashBestChain) +{ + return Write(string("hashBestChain"), hashBestChain); +} + +CBlockIndex* InsertBlockIndex(uint256 hash) +{ + if (hash == 0) + return NULL; + + // Return existing + map::iterator mi = mapBlockIndex.find(hash); + if (mi != mapBlockIndex.end()) + return (*mi).second; + + // Create new + CBlockIndex* pindexNew = new CBlockIndex(); + if (!pindexNew) + throw runtime_error("LoadBlockIndex() : new CBlockIndex failed"); + mi = mapBlockIndex.insert(make_pair(hash, pindexNew)).first; + pindexNew->phashBlock = &((*mi).first); + + return pindexNew; +} + +bool CTxDB::LoadBlockIndex() +{ + // Get cursor + Dbc* pcursor = GetCursor(); + if (!pcursor) + return false; + + unsigned int fFlags = DB_SET_RANGE; + loop + { + // Read next record + CDataStream ssKey; + if (fFlags == DB_SET_RANGE) + ssKey << make_pair(string("blockindex"), uint256(0)); + CDataStream ssValue; + int ret = ReadAtCursor(pcursor, ssKey, ssValue, fFlags); + fFlags = DB_NEXT; + if (ret == DB_NOTFOUND) + break; + else if (ret != 0) + return false; + + // Unserialize + string strType; + ssKey >> strType; + if (strType == "blockindex") + { + CDiskBlockIndex diskindex; + ssValue >> diskindex; + + // Construct block index object + CBlockIndex* pindexNew = InsertBlockIndex(diskindex.GetBlockHash()); + pindexNew->pprev = InsertBlockIndex(diskindex.hashPrev); + pindexNew->pnext = InsertBlockIndex(diskindex.hashNext); + pindexNew->nFile = diskindex.nFile; + pindexNew->nBlockPos = diskindex.nBlockPos; + pindexNew->nHeight = diskindex.nHeight; + pindexNew->nVersion = diskindex.nVersion; + pindexNew->hashMerkleRoot = diskindex.hashMerkleRoot; + pindexNew->nTime = diskindex.nTime; + pindexNew->nBits = diskindex.nBits; + pindexNew->nNonce = diskindex.nNonce; + + // Watch for genesis block and best block + if (pindexGenesisBlock == NULL && diskindex.GetBlockHash() == hashGenesisBlock) + pindexGenesisBlock = pindexNew; + } + else + { + break; + } + } + + if (!ReadHashBestChain(hashBestChain)) + { + if (pindexGenesisBlock == NULL) + return true; + return error("CTxDB::LoadBlockIndex() : hashBestChain not found\n"); + } + + if (!mapBlockIndex.count(hashBestChain)) + return error("CTxDB::LoadBlockIndex() : blockindex for hashBestChain not found\n"); + pindexBest = mapBlockIndex[hashBestChain]; + nBestHeight = pindexBest->nHeight; + printf("LoadBlockIndex(): hashBestChain=%s height=%d\n", hashBestChain.ToString().substr(0,14).c_str(), nBestHeight); + + return true; +} + + + + + +// +// CAddrDB +// + +bool CAddrDB::WriteAddress(const CAddress& addr) +{ + return Write(make_pair(string("addr"), addr.GetKey()), addr); +} + +bool CAddrDB::LoadAddresses() +{ + CRITICAL_BLOCK(cs_mapIRCAddresses) + CRITICAL_BLOCK(cs_mapAddresses) + { + // Load user provided addresses + CAutoFile filein = fopen("addr.txt", "rt"); + if (filein) + { + try + { + char psz[1000]; + while (fgets(psz, sizeof(psz), filein)) + { + CAddress addr(psz, NODE_NETWORK); + if (addr.ip != 0) + { + AddAddress(*this, addr); + mapIRCAddresses.insert(make_pair(addr.GetKey(), addr)); + } + } + } + catch (...) { } + } + + // Get cursor + Dbc* pcursor = GetCursor(); + if (!pcursor) + return false; + + loop + { + // Read next record + CDataStream ssKey; + CDataStream ssValue; + int ret = ReadAtCursor(pcursor, ssKey, ssValue); + if (ret == DB_NOTFOUND) + break; + else if (ret != 0) + return false; + + // Unserialize + string strType; + ssKey >> strType; + if (strType == "addr") + { + CAddress addr; + ssValue >> addr; + mapAddresses.insert(make_pair(addr.GetKey(), addr)); + } + } + + //// debug print + printf("mapAddresses:\n"); + foreach(const PAIRTYPE(vector, CAddress)& item, mapAddresses) + item.second.print(); + printf("-----\n"); + + // Fix for possible bug that manifests in mapAddresses.count in irc.cpp, + // just need to call count here and it doesn't happen there. The bug was the + // pack pragma in irc.cpp and has been fixed, but I'm not in a hurry to delete this. + mapAddresses.count(vector(18)); + } + + return true; +} + +bool LoadAddresses() +{ + return CAddrDB("cr+").LoadAddresses(); +} + + + + +// +// CReviewDB +// + +bool CReviewDB::ReadReviews(uint256 hash, vector& vReviews) +{ + vReviews.size(); // msvc workaround, just need to do anything with vReviews + return Read(make_pair(string("reviews"), hash), vReviews); +} + +bool CReviewDB::WriteReviews(uint256 hash, const vector& vReviews) +{ + return Write(make_pair(string("reviews"), hash), vReviews); +} + + + + + + + +// +// CWalletDB +// + +bool CWalletDB::LoadWallet(vector& vchDefaultKeyRet) +{ + vchDefaultKeyRet.clear(); + + //// todo: shouldn't we catch exceptions and try to recover and continue? + CRITICAL_BLOCK(cs_mapKeys) + CRITICAL_BLOCK(cs_mapWallet) + { + // Get cursor + Dbc* pcursor = GetCursor(); + if (!pcursor) + return false; + + loop + { + // Read next record + CDataStream ssKey; + CDataStream ssValue; + int ret = ReadAtCursor(pcursor, ssKey, ssValue); + if (ret == DB_NOTFOUND) + break; + else if (ret != 0) + return false; + + // Unserialize + // Taking advantage of the fact that pair serialization + // is just the two items serialized one after the other + string strType; + ssKey >> strType; + if (strType == "name") + { + string strAddress; + ssKey >> strAddress; + ssValue >> mapAddressBook[strAddress]; + } + else if (strType == "tx") + { + uint256 hash; + ssKey >> hash; + CWalletTx& wtx = mapWallet[hash]; + ssValue >> wtx; + + if (wtx.GetHash() != hash) + printf("Error in wallet.dat, hash mismatch\n"); + + //// debug print + //printf("LoadWallet %s\n", wtx.GetHash().ToString().c_str()); + //printf(" %12I64d %s %s %s\n", + // wtx.vout[0].nValue, + // DateTimeStr(wtx.nTime).c_str(), + // wtx.hashBlock.ToString().substr(0,14).c_str(), + // wtx.mapValue["message"].c_str()); + } + else if (strType == "key") + { + vector vchPubKey; + ssKey >> vchPubKey; + CPrivKey vchPrivKey; + ssValue >> vchPrivKey; + + mapKeys[vchPubKey] = vchPrivKey; + mapPubKeys[Hash160(vchPubKey)] = vchPubKey; + } + else if (strType == "defaultkey") + { + ssValue >> vchDefaultKeyRet; + } + else if (strType == "setting") /// or settings or option or options or config? + { + string strKey; + ssKey >> strKey; + if (strKey == "fGenerateBitcoins") ssValue >> fGenerateBitcoins; + if (strKey == "nTransactionFee") ssValue >> nTransactionFee; + if (strKey == "addrIncoming") ssValue >> addrIncoming; + } + } + } + + printf("fGenerateBitcoins = %d\n", fGenerateBitcoins); + printf("nTransactionFee = %I64d\n", nTransactionFee); + printf("addrIncoming = %s\n", addrIncoming.ToString().c_str()); + + return true; +} + +bool LoadWallet() +{ + vector vchDefaultKey; + if (!CWalletDB("cr").LoadWallet(vchDefaultKey)) + return false; + + if (mapKeys.count(vchDefaultKey)) + { + // Set keyUser + keyUser.SetPubKey(vchDefaultKey); + keyUser.SetPrivKey(mapKeys[vchDefaultKey]); + } + else + { + // Create new keyUser and set as default key + RandAddSeed(true); + keyUser.MakeNewKey(); + if (!AddKey(keyUser)) + return false; + if (!SetAddressBookName(PubKeyToAddress(keyUser.GetPubKey()), "Your Address")) + return false; + CWalletDB().WriteDefaultKey(keyUser.GetPubKey()); + } + + return true; +} diff --git a/db.h b/db.h new file mode 100644 index 0000000000..1139f7686c --- /dev/null +++ b/db.h @@ -0,0 +1,420 @@ +// Copyright (c) 2009 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 +class CTransaction; +class CTxIndex; +class CDiskBlockIndex; +class CDiskTxPos; +class COutPoint; +class CUser; +class CReview; +class CAddress; +class CWalletTx; + +extern map mapAddressBook; +extern bool fClient; + + +extern DbEnv dbenv; +extern void DBFlush(bool fShutdown); + + + + +class CDB +{ +protected: + Db* pdb; + string strFile; + vector vTxn; + + explicit CDB(const char* pszFile, const char* pszMode="r+", bool fTxn=false); + ~CDB() { Close(); } +public: + void Close(); +private: + CDB(const CDB&); + void operator=(const CDB&); + +protected: + template + bool Read(const K& key, T& value) + { + if (!pdb) + return false; + + // Key + CDataStream ssKey(SER_DISK); + ssKey.reserve(1000); + ssKey << key; + Dbt datKey(&ssKey[0], ssKey.size()); + + // Read + Dbt datValue; + datValue.set_flags(DB_DBT_MALLOC); + int ret = pdb->get(GetTxn(), &datKey, &datValue, 0); + memset(datKey.get_data(), 0, datKey.get_size()); + if (datValue.get_data() == NULL) + return false; + + // Unserialize value + CDataStream ssValue((char*)datValue.get_data(), (char*)datValue.get_data() + datValue.get_size(), SER_DISK); + ssValue >> value; + + // Clear and free memory + memset(datValue.get_data(), 0, datValue.get_size()); + free(datValue.get_data()); + return (ret == 0); + } + + template + bool Write(const K& key, const T& value, bool fOverwrite=true) + { + if (!pdb) + return false; + + // Key + CDataStream ssKey(SER_DISK); + ssKey.reserve(1000); + ssKey << key; + Dbt datKey(&ssKey[0], ssKey.size()); + + // Value + CDataStream ssValue(SER_DISK); + ssValue.reserve(10000); + ssValue << value; + Dbt datValue(&ssValue[0], ssValue.size()); + + // Write + int ret = pdb->put(GetTxn(), &datKey, &datValue, (fOverwrite ? 0 : DB_NOOVERWRITE)); + + // Clear memory in case it was a private key + memset(datKey.get_data(), 0, datKey.get_size()); + memset(datValue.get_data(), 0, datValue.get_size()); + return (ret == 0); + } + + template + bool Erase(const K& key) + { + if (!pdb) + return false; + + // Key + CDataStream ssKey(SER_DISK); + ssKey.reserve(1000); + ssKey << key; + Dbt datKey(&ssKey[0], ssKey.size()); + + // Erase + int ret = pdb->del(GetTxn(), &datKey, 0); + + // Clear memory + memset(datKey.get_data(), 0, datKey.get_size()); + return (ret == 0 || ret == DB_NOTFOUND); + } + + template + bool Exists(const K& key) + { + if (!pdb) + return false; + + // Key + CDataStream ssKey(SER_DISK); + ssKey.reserve(1000); + ssKey << key; + Dbt datKey(&ssKey[0], ssKey.size()); + + // Exists + int ret = pdb->exists(GetTxn(), &datKey, 0); + + // Clear memory + memset(datKey.get_data(), 0, datKey.get_size()); + return (ret == 0); + } + + Dbc* GetCursor() + { + if (!pdb) + return NULL; + Dbc* pcursor = NULL; + int ret = pdb->cursor(NULL, &pcursor, 0); + if (ret != 0) + return NULL; + return pcursor; + } + + int ReadAtCursor(Dbc* pcursor, CDataStream& ssKey, CDataStream& ssValue, unsigned int fFlags=DB_NEXT) + { + // Read at cursor + Dbt datKey; + if (fFlags == DB_SET || fFlags == DB_SET_RANGE || fFlags == DB_GET_BOTH || fFlags == DB_GET_BOTH_RANGE) + { + datKey.set_data(&ssKey[0]); + datKey.set_size(ssKey.size()); + } + Dbt datValue; + if (fFlags == DB_GET_BOTH || fFlags == DB_GET_BOTH_RANGE) + { + datValue.set_data(&ssValue[0]); + datValue.set_size(ssValue.size()); + } + datKey.set_flags(DB_DBT_MALLOC); + datValue.set_flags(DB_DBT_MALLOC); + int ret = pcursor->get(&datKey, &datValue, fFlags); + if (ret != 0) + return ret; + else if (datKey.get_data() == NULL || datValue.get_data() == NULL) + return 99999; + + // Convert to streams + ssKey.SetType(SER_DISK); + ssKey.clear(); + ssKey.write((char*)datKey.get_data(), datKey.get_size()); + ssValue.SetType(SER_DISK); + ssValue.clear(); + ssValue.write((char*)datValue.get_data(), datValue.get_size()); + + // Clear and free memory + memset(datKey.get_data(), 0, datKey.get_size()); + memset(datValue.get_data(), 0, datValue.get_size()); + free(datKey.get_data()); + free(datValue.get_data()); + return 0; + } + + DbTxn* GetTxn() + { + if (!vTxn.empty()) + return vTxn.back(); + else + return NULL; + } + +public: + bool TxnBegin() + { + if (!pdb) + return false; + DbTxn* ptxn = NULL; + int ret = dbenv.txn_begin(GetTxn(), &ptxn, 0); + if (!ptxn || ret != 0) + return false; + vTxn.push_back(ptxn); + return true; + } + + bool TxnCommit() + { + if (!pdb) + return false; + if (vTxn.empty()) + return false; + int ret = vTxn.back()->commit(0); + vTxn.pop_back(); + return (ret == 0); + } + + bool TxnAbort() + { + if (!pdb) + return false; + if (vTxn.empty()) + return false; + int ret = vTxn.back()->abort(); + vTxn.pop_back(); + return (ret == 0); + } + + bool ReadVersion(int& nVersion) + { + nVersion = 0; + return Read(string("version"), nVersion); + } + + bool WriteVersion(int nVersion) + { + return Write(string("version"), nVersion); + } +}; + + + + + + + + +class CTxDB : public CDB +{ +public: + CTxDB(const char* pszMode="r+", bool fTxn=false) : CDB(!fClient ? "blkindex.dat" : NULL, pszMode, fTxn) { } +private: + CTxDB(const CTxDB&); + void operator=(const CTxDB&); +public: + bool ReadTxIndex(uint256 hash, CTxIndex& txindex); + bool UpdateTxIndex(uint256 hash, const CTxIndex& txindex); + bool AddTxIndex(const CTransaction& tx, const CDiskTxPos& pos, int nHeight); + bool EraseTxIndex(const CTransaction& tx); + bool ContainsTx(uint256 hash); + bool ReadOwnerTxes(uint160 hash160, int nHeight, vector& vtx); + bool ReadDiskTx(uint256 hash, CTransaction& tx, CTxIndex& txindex); + bool ReadDiskTx(uint256 hash, CTransaction& tx); + bool ReadDiskTx(COutPoint outpoint, CTransaction& tx, CTxIndex& txindex); + bool ReadDiskTx(COutPoint outpoint, CTransaction& tx); + bool WriteBlockIndex(const CDiskBlockIndex& blockindex); + bool EraseBlockIndex(uint256 hash); + bool ReadHashBestChain(uint256& hashBestChain); + bool WriteHashBestChain(uint256 hashBestChain); + bool LoadBlockIndex(); +}; + + + + + +class CReviewDB : public CDB +{ +public: + CReviewDB(const char* pszMode="r+", bool fTxn=false) : CDB("reviews.dat", pszMode, fTxn) { } +private: + CReviewDB(const CReviewDB&); + void operator=(const CReviewDB&); +public: + bool ReadUser(uint256 hash, CUser& user) + { + return Read(make_pair(string("user"), hash), user); + } + + bool WriteUser(uint256 hash, const CUser& user) + { + return Write(make_pair(string("user"), hash), user); + } + + bool ReadReviews(uint256 hash, vector& vReviews); + bool WriteReviews(uint256 hash, const vector& vReviews); +}; + + + + + +class CMarketDB : public CDB +{ +public: + CMarketDB(const char* pszMode="r+", bool fTxn=false) : CDB("market.dat", pszMode, fTxn) { } +private: + CMarketDB(const CMarketDB&); + void operator=(const CMarketDB&); +}; + + + + + +class CAddrDB : public CDB +{ +public: + CAddrDB(const char* pszMode="r+", bool fTxn=false) : CDB("addr.dat", pszMode, fTxn) { } +private: + CAddrDB(const CAddrDB&); + void operator=(const CAddrDB&); +public: + bool WriteAddress(const CAddress& addr); + bool LoadAddresses(); +}; + +bool LoadAddresses(); + + + + + +class CWalletDB : public CDB +{ +public: + CWalletDB(const char* pszMode="r+", bool fTxn=false) : CDB("wallet.dat", pszMode, fTxn) { } +private: + CWalletDB(const CWalletDB&); + void operator=(const CWalletDB&); +public: + bool ReadName(const string& strAddress, string& strName) + { + strName = ""; + return Read(make_pair(string("name"), strAddress), strName); + } + + bool WriteName(const string& strAddress, const string& strName) + { + mapAddressBook[strAddress] = strName; + return Write(make_pair(string("name"), strAddress), strName); + } + + bool EraseName(const string& strAddress) + { + mapAddressBook.erase(strAddress); + return Erase(make_pair(string("name"), strAddress)); + } + + bool ReadTx(uint256 hash, CWalletTx& wtx) + { + return Read(make_pair(string("tx"), hash), wtx); + } + + bool WriteTx(uint256 hash, const CWalletTx& wtx) + { + return Write(make_pair(string("tx"), hash), wtx); + } + + bool EraseTx(uint256 hash) + { + return Erase(make_pair(string("tx"), hash)); + } + + bool ReadKey(const vector& vchPubKey, CPrivKey& vchPrivKey) + { + vchPrivKey.clear(); + return Read(make_pair(string("key"), vchPubKey), vchPrivKey); + } + + bool WriteKey(const vector& vchPubKey, const CPrivKey& vchPrivKey) + { + return Write(make_pair(string("key"), vchPubKey), vchPrivKey, false); + } + + bool ReadDefaultKey(vector& vchPubKey) + { + vchPubKey.clear(); + return Read(string("defaultkey"), vchPubKey); + } + + bool WriteDefaultKey(const vector& vchPubKey) + { + return Write(string("defaultkey"), vchPubKey); + } + + template + bool ReadSetting(const string& strKey, T& value) + { + return Read(make_pair(string("setting"), strKey), value); + } + + template + bool WriteSetting(const string& strKey, const T& value) + { + return Write(make_pair(string("setting"), strKey), value); + } + + bool LoadWallet(vector& vchDefaultKeyRet); +}; + +bool LoadWallet(); + +inline bool SetAddressBookName(const string& strAddress, const string& strName) +{ + return CWalletDB().WriteName(strAddress, strName); +} diff --git a/headers.h b/headers.h new file mode 100644 index 0000000000..7bd68a1994 --- /dev/null +++ b/headers.h @@ -0,0 +1,71 @@ +// Copyright (c) 2009 Satoshi Nakamoto +// Distributed under the MIT/X11 software license, see the accompanying +// file license.txt or http://www.opensource.org/licenses/mit-license.php. + +#ifdef _MSC_VER +#pragma warning(disable:4786) +#pragma warning(disable:4804) +#pragma warning(disable:4717) +#endif +#ifdef _WIN32_WINNT +#undef _WIN32_WINNT +#endif +#define _WIN32_WINNT 0x0400 +#define WIN32_LEAN_AND_MEAN 1 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#define BOUNDSCHECK 1 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#pragma hdrstop +using namespace std; +using namespace boost; + + + +#include "serialize.h" +#include "uint256.h" +#include "util.h" +#include "key.h" +#include "bignum.h" +#include "base58.h" +#include "script.h" +#include "db.h" +#include "net.h" +#include "irc.h" +#include "main.h" +#include "market.h" +#include "uibase.h" +#include "ui.h" diff --git a/irc.cpp b/irc.cpp new file mode 100644 index 0000000000..3518df2491 --- /dev/null +++ b/irc.cpp @@ -0,0 +1,314 @@ +// Copyright (c) 2009 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" + + +map, CAddress> mapIRCAddresses; +CCriticalSection cs_mapIRCAddresses; + + + + +#pragma pack(push, 1) +struct ircaddr +{ + int ip; + short port; +}; +#pragma pack(pop) + +string EncodeAddress(const CAddress& addr) +{ + struct ircaddr tmp; + tmp.ip = addr.ip; + tmp.port = addr.port; + + vector vch(UBEGIN(tmp), UEND(tmp)); + return string("u") + EncodeBase58Check(vch); +} + +bool DecodeAddress(string str, CAddress& addr) +{ + vector vch; + if (!DecodeBase58Check(str.substr(1), vch)) + return false; + + struct ircaddr tmp; + if (vch.size() != sizeof(tmp)) + return false; + memcpy(&tmp, &vch[0], sizeof(tmp)); + + addr = CAddress(tmp.ip, tmp.port); + return true; +} + + + + + + +static bool Send(SOCKET hSocket, const char* pszSend) +{ + if (strstr(pszSend, "PONG") != pszSend) + printf("SENDING: %s\n", pszSend); + const char* psz = pszSend; + const char* pszEnd = psz + strlen(psz); + while (psz < pszEnd) + { + int ret = send(hSocket, psz, pszEnd - psz, 0); + if (ret < 0) + return false; + psz += ret; + } + return true; +} + +bool RecvLine(SOCKET hSocket, string& strLine) +{ + strLine = ""; + loop + { + char c; + int nBytes = recv(hSocket, &c, 1, 0); + if (nBytes > 0) + { + if (c == '\n') + continue; + if (c == '\r') + return true; + strLine += c; + } + else if (nBytes <= 0) + { + if (!strLine.empty()) + return true; + // socket closed + printf("IRC socket closed\n"); + return false; + } + else + { + // socket error + int nErr = WSAGetLastError(); + if (nErr != WSAEMSGSIZE && nErr != WSAEINTR && nErr != WSAEINPROGRESS) + { + printf("IRC recv failed: %d\n", nErr); + return false; + } + } + } +} + +bool RecvLineIRC(SOCKET hSocket, string& strLine) +{ + loop + { + bool fRet = RecvLine(hSocket, strLine); + if (fRet) + { + if (fShutdown) + return false; + vector vWords; + ParseString(strLine, ' ', vWords); + if (vWords[0] == "PING") + { + strLine[1] = 'O'; + strLine += '\r'; + Send(hSocket, strLine.c_str()); + continue; + } + } + return fRet; + } +} + +bool RecvUntil(SOCKET hSocket, const char* psz1, const char* psz2=NULL, const char* psz3=NULL) +{ + loop + { + string strLine; + if (!RecvLineIRC(hSocket, strLine)) + return false; + printf("IRC %s\n", strLine.c_str()); + if (psz1 && strLine.find(psz1) != -1) + return true; + if (psz2 && strLine.find(psz2) != -1) + return true; + if (psz3 && strLine.find(psz3) != -1) + return true; + } +} + +bool Wait(int nSeconds) +{ + if (fShutdown) + return false; + printf("Waiting %d seconds to reconnect to IRC\n", nSeconds); + for (int i = 0; i < nSeconds; i++) + { + if (fShutdown) + return false; + Sleep(1000); + } + return true; +} + + + +void ThreadIRCSeed(void* parg) +{ + SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_NORMAL); + int nErrorWait = 10; + int nRetryWait = 10; + + while (!fShutdown) + { + CAddress addrConnect("216.155.130.130:6667"); + struct hostent* phostent = gethostbyname("chat.freenode.net"); + if (phostent && phostent->h_addr_list && phostent->h_addr_list[0]) + addrConnect = CAddress(*(u_long*)phostent->h_addr_list[0], htons(6667)); + + SOCKET hSocket; + if (!ConnectSocket(addrConnect, hSocket)) + { + printf("IRC connect failed\n"); + nErrorWait = nErrorWait * 11 / 10; + if (Wait(nErrorWait += 60)) + continue; + else + return; + } + + if (!RecvUntil(hSocket, "Found your hostname", "using your IP address instead", "Couldn't look up your hostname")) + { + closesocket(hSocket); + nErrorWait = nErrorWait * 11 / 10; + if (Wait(nErrorWait += 60)) + continue; + else + return; + } + + string strMyName = EncodeAddress(addrLocalHost); + + if (!addrLocalHost.IsRoutable()) + strMyName = strprintf("x%u", GetRand(1000000000)); + + + Send(hSocket, strprintf("NICK %s\r", strMyName.c_str()).c_str()); + Send(hSocket, strprintf("USER %s 8 * : %s\r", strMyName.c_str(), strMyName.c_str()).c_str()); + + if (!RecvUntil(hSocket, " 004 ")) + { + closesocket(hSocket); + nErrorWait = nErrorWait * 11 / 10; + if (Wait(nErrorWait += 60)) + continue; + else + return; + } + Sleep(500); + + Send(hSocket, "JOIN #bitcoin\r"); + Send(hSocket, "WHO #bitcoin\r"); + + int64 nStart = GetTime(); + string strLine; + while (!fShutdown && RecvLineIRC(hSocket, strLine)) + { + if (strLine.empty() || strLine.size() > 900 || strLine[0] != ':') + continue; + printf("IRC %s\n", strLine.c_str()); + + vector vWords; + ParseString(strLine, ' ', vWords); + if (vWords.size() < 2) + continue; + + char pszName[10000]; + pszName[0] = '\0'; + + if (vWords[1] == "352" && vWords.size() >= 8) + { + // index 7 is limited to 16 characters + // could get full length name at index 10, but would be different from join messages + strcpy(pszName, vWords[7].c_str()); + printf("GOT WHO: [%s] ", pszName); + } + + if (vWords[1] == "JOIN" && vWords[0].size() > 1) + { + // :username!username@50000007.F000000B.90000002.IP JOIN :#channelname + strcpy(pszName, vWords[0].c_str() + 1); + if (strchr(pszName, '!')) + *strchr(pszName, '!') = '\0'; + printf("GOT JOIN: [%s] ", pszName); + } + + if (pszName[0] == 'u') + { + CAddress addr; + if (DecodeAddress(pszName, addr)) + { + CAddrDB addrdb; + if (AddAddress(addrdb, addr)) + printf("new "); + else + { + // make it try connecting again + CRITICAL_BLOCK(cs_mapAddresses) + if (mapAddresses.count(addr.GetKey())) + mapAddresses[addr.GetKey()].nLastFailed = 0; + } + addr.print(); + + CRITICAL_BLOCK(cs_mapIRCAddresses) + mapIRCAddresses.insert(make_pair(addr.GetKey(), addr)); + } + else + { + printf("decode failed\n"); + } + } + } + closesocket(hSocket); + + if (GetTime() - nStart > 20 * 60) + { + nErrorWait /= 3; + nRetryWait /= 3; + } + + nRetryWait = nRetryWait * 11 / 10; + if (!Wait(nRetryWait += 60)) + return; + } +} + + + + + + + + + + +#ifdef TEST +int main(int argc, char *argv[]) +{ + WSADATA wsadata; + if (WSAStartup(MAKEWORD(2,2), &wsadata) != NO_ERROR) + { + printf("Error at WSAStartup()\n"); + return false; + } + + ThreadIRCSeed(NULL); + + WSACleanup(); + return 0; +} +#endif diff --git a/irc.h b/irc.h new file mode 100644 index 0000000000..91c3ffe686 --- /dev/null +++ b/irc.h @@ -0,0 +1,10 @@ +// Copyright (c) 2009 Satoshi Nakamoto +// Distributed under the MIT/X11 software license, see the accompanying +// file license.txt or http://www.opensource.org/licenses/mit-license.php. + +extern bool RecvLine(SOCKET hSocket, string& strLine); +extern void ThreadIRCSeed(void* parg); +extern bool fRestartIRCSeed; + +extern map, CAddress> mapIRCAddresses; +extern CCriticalSection cs_mapIRCAddresses; diff --git a/key.h b/key.h new file mode 100644 index 0000000000..8b0b54e4b3 --- /dev/null +++ b/key.h @@ -0,0 +1,156 @@ +// Copyright (c) 2009 Satoshi Nakamoto +// Distributed under the MIT/X11 software license, see the accompanying +// file license.txt or http://www.opensource.org/licenses/mit-license.php. + + +// secp160k1 +// const unsigned int PRIVATE_KEY_SIZE = 192; +// const unsigned int PUBLIC_KEY_SIZE = 41; +// const unsigned int SIGNATURE_SIZE = 48; +// +// secp192k1 +// const unsigned int PRIVATE_KEY_SIZE = 222; +// const unsigned int PUBLIC_KEY_SIZE = 49; +// const unsigned int SIGNATURE_SIZE = 57; +// +// secp224k1 +// const unsigned int PRIVATE_KEY_SIZE = 250; +// const unsigned int PUBLIC_KEY_SIZE = 57; +// const unsigned int SIGNATURE_SIZE = 66; +// +// secp256k1: +// const unsigned int PRIVATE_KEY_SIZE = 279; +// const unsigned int PUBLIC_KEY_SIZE = 65; +// const unsigned int SIGNATURE_SIZE = 72; +// +// see www.keylength.com +// script supports up to 75 for single byte push + + + +class key_error : public std::runtime_error +{ +public: + explicit key_error(const std::string& str) : std::runtime_error(str) {} +}; + + +// secure_allocator is defined is serialize.h +typedef vector > CPrivKey; + + + +class CKey +{ +protected: + EC_KEY* pkey; + +public: + CKey() + { + pkey = EC_KEY_new_by_curve_name(NID_secp256k1); + if (pkey == NULL) + throw key_error("CKey::CKey() : EC_KEY_new_by_curve_name failed"); + } + + CKey(const CKey& b) + { + pkey = EC_KEY_dup(b.pkey); + if (pkey == NULL) + throw key_error("CKey::CKey(const CKey&) : EC_KEY_dup failed"); + } + + CKey& operator=(const CKey& b) + { + if (!EC_KEY_copy(pkey, b.pkey)) + throw key_error("CKey::operator=(const CKey&) : EC_KEY_copy failed"); + return (*this); + } + + ~CKey() + { + EC_KEY_free(pkey); + } + + void MakeNewKey() + { + if (!EC_KEY_generate_key(pkey)) + throw key_error("CKey::MakeNewKey() : EC_KEY_generate_key failed"); + } + + bool SetPrivKey(const CPrivKey& vchPrivKey) + { + const unsigned char* pbegin = &vchPrivKey[0]; + if (!d2i_ECPrivateKey(&pkey, &pbegin, vchPrivKey.size())) + return false; + return true; + } + + CPrivKey GetPrivKey() const + { + unsigned int nSize = i2d_ECPrivateKey(pkey, NULL); + if (!nSize) + throw key_error("CKey::GetPrivKey() : i2d_ECPrivateKey failed"); + CPrivKey vchPrivKey(nSize, 0); + unsigned char* pbegin = &vchPrivKey[0]; + if (i2d_ECPrivateKey(pkey, &pbegin) != nSize) + throw key_error("CKey::GetPrivKey() : i2d_ECPrivateKey returned unexpected size"); + return vchPrivKey; + } + + bool SetPubKey(const vector& vchPubKey) + { + const unsigned char* pbegin = &vchPubKey[0]; + if (!o2i_ECPublicKey(&pkey, &pbegin, vchPubKey.size())) + return false; + return true; + } + + vector GetPubKey() const + { + unsigned int nSize = i2o_ECPublicKey(pkey, NULL); + if (!nSize) + throw key_error("CKey::GetPubKey() : i2o_ECPublicKey failed"); + vector vchPubKey(nSize, 0); + unsigned char* pbegin = &vchPubKey[0]; + if (i2o_ECPublicKey(pkey, &pbegin) != nSize) + throw key_error("CKey::GetPubKey() : i2o_ECPublicKey returned unexpected size"); + return vchPubKey; + } + + bool Sign(uint256 hash, vector& vchSig) + { + vchSig.clear(); + unsigned char pchSig[10000]; + unsigned int nSize = 0; + if (!ECDSA_sign(0, (unsigned char*)&hash, sizeof(hash), pchSig, &nSize, pkey)) + return false; + vchSig.resize(nSize); + memcpy(&vchSig[0], pchSig, nSize); + return true; + } + + bool Verify(uint256 hash, const vector& vchSig) + { + // -1 = error, 0 = bad sig, 1 = good + if (ECDSA_verify(0, (unsigned char*)&hash, sizeof(hash), &vchSig[0], vchSig.size(), pkey) != 1) + return false; + return true; + } + + static bool Sign(const CPrivKey& vchPrivKey, uint256 hash, vector& vchSig) + { + CKey key; + if (!key.SetPrivKey(vchPrivKey)) + return false; + return key.Sign(hash, vchSig); + } + + static bool Verify(const vector& vchPubKey, uint256 hash, const vector& vchSig) + { + CKey key; + if (!key.SetPubKey(vchPubKey)) + return false; + return key.Verify(hash, vchSig); + } +}; diff --git a/libeay32.dll b/libeay32.dll new file mode 100644 index 0000000000..3bc745c4c0 Binary files /dev/null and b/libeay32.dll differ diff --git a/license.txt b/license.txt new file mode 100644 index 0000000000..3844dfb429 --- /dev/null +++ b/license.txt @@ -0,0 +1,19 @@ +Copyright (c) 2009 Satoshi Nakamoto + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/main.cpp b/main.cpp new file mode 100644 index 0000000000..97000db381 --- /dev/null +++ b/main.cpp @@ -0,0 +1,2692 @@ +// Copyright (c) 2009 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 "sha.h" + + + + + +// +// Global state +// + +CCriticalSection cs_main; + +map mapTransactions; +CCriticalSection cs_mapTransactions; +unsigned int nTransactionsUpdated = 0; +map mapNextTx; + +map mapBlockIndex; +const uint256 hashGenesisBlock("0x000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f"); +CBlockIndex* pindexGenesisBlock = NULL; +int nBestHeight = -1; +uint256 hashBestChain = 0; +CBlockIndex* pindexBest = NULL; + +map mapOrphanBlocks; +multimap mapOrphanBlocksByPrev; + +map mapOrphanTransactions; +multimap mapOrphanTransactionsByPrev; + +map mapWallet; +vector > vWalletUpdated; +CCriticalSection cs_mapWallet; + +map, CPrivKey> mapKeys; +map > mapPubKeys; +CCriticalSection cs_mapKeys; +CKey keyUser; + +string strSetDataDir; +int nDropMessagesTest = 0; + +// Settings +int fGenerateBitcoins; +int64 nTransactionFee = 0; +CAddress addrIncoming; + + + + + + + + +////////////////////////////////////////////////////////////////////////////// +// +// mapKeys +// + +bool AddKey(const CKey& key) +{ + CRITICAL_BLOCK(cs_mapKeys) + { + mapKeys[key.GetPubKey()] = key.GetPrivKey(); + mapPubKeys[Hash160(key.GetPubKey())] = key.GetPubKey(); + } + return CWalletDB().WriteKey(key.GetPubKey(), key.GetPrivKey()); +} + +vector GenerateNewKey() +{ + CKey key; + key.MakeNewKey(); + if (!AddKey(key)) + throw runtime_error("GenerateNewKey() : AddKey failed\n"); + return key.GetPubKey(); +} + + + + +////////////////////////////////////////////////////////////////////////////// +// +// mapWallet +// + +bool AddToWallet(const CWalletTx& wtxIn) +{ + uint256 hash = wtxIn.GetHash(); + CRITICAL_BLOCK(cs_mapWallet) + { + // Inserts only if not already there, returns tx inserted or tx found + pair::iterator, bool> ret = mapWallet.insert(make_pair(hash, wtxIn)); + CWalletTx& wtx = (*ret.first).second; + bool fInsertedNew = ret.second; + if (fInsertedNew) + wtx.nTimeReceived = GetAdjustedTime(); + + //// debug print + printf("AddToWallet %s %s\n", wtxIn.GetHash().ToString().substr(0,6).c_str(), fInsertedNew ? "new" : "update"); + + if (!fInsertedNew) + { + // Merge + bool fUpdated = false; + if (wtxIn.hashBlock != 0 && wtxIn.hashBlock != wtx.hashBlock) + { + wtx.hashBlock = wtxIn.hashBlock; + fUpdated = true; + } + if (wtxIn.nIndex != -1 && (wtxIn.vMerkleBranch != wtx.vMerkleBranch || wtxIn.nIndex != wtx.nIndex)) + { + wtx.vMerkleBranch = wtxIn.vMerkleBranch; + wtx.nIndex = wtxIn.nIndex; + fUpdated = true; + } + if (wtxIn.fFromMe && wtxIn.fFromMe != wtx.fFromMe) + { + wtx.fFromMe = wtxIn.fFromMe; + fUpdated = true; + } + if (wtxIn.fSpent && wtxIn.fSpent != wtx.fSpent) + { + wtx.fSpent = wtxIn.fSpent; + fUpdated = true; + } + if (!fUpdated) + return true; + } + + // Write to disk + if (!wtx.WriteToDisk()) + return false; + + // Notify UI + vWalletUpdated.push_back(make_pair(hash, fInsertedNew)); + } + + // Refresh UI + MainFrameRepaint(); + return true; +} + +bool AddToWalletIfMine(const CTransaction& tx, const CBlock* pblock) +{ + if (tx.IsMine() || mapWallet.count(tx.GetHash())) + { + CWalletTx wtx(tx); + // Get merkle branch if transaction was found in a block + if (pblock) + wtx.SetMerkleBranch(pblock); + return AddToWallet(wtx); + } + return true; +} + +bool EraseFromWallet(uint256 hash) +{ + CRITICAL_BLOCK(cs_mapWallet) + { + if (mapWallet.erase(hash)) + CWalletDB().EraseTx(hash); + } + return true; +} + + + + + + + + + +////////////////////////////////////////////////////////////////////////////// +// +// mapOrphanTransactions +// + +void AddOrphanTx(const CDataStream& vMsg) +{ + CTransaction tx; + CDataStream(vMsg) >> tx; + uint256 hash = tx.GetHash(); + if (mapOrphanTransactions.count(hash)) + return; + CDataStream* pvMsg = mapOrphanTransactions[hash] = new CDataStream(vMsg); + foreach(const CTxIn& txin, tx.vin) + mapOrphanTransactionsByPrev.insert(make_pair(txin.prevout.hash, pvMsg)); +} + +void EraseOrphanTx(uint256 hash) +{ + if (!mapOrphanTransactions.count(hash)) + return; + const CDataStream* pvMsg = mapOrphanTransactions[hash]; + CTransaction tx; + CDataStream(*pvMsg) >> tx; + foreach(const CTxIn& txin, tx.vin) + { + for (multimap::iterator mi = mapOrphanTransactionsByPrev.lower_bound(txin.prevout.hash); + mi != mapOrphanTransactionsByPrev.upper_bound(txin.prevout.hash);) + { + if ((*mi).second == pvMsg) + mapOrphanTransactionsByPrev.erase(mi++); + else + mi++; + } + } + delete pvMsg; + mapOrphanTransactions.erase(hash); +} + + + + + + + + +////////////////////////////////////////////////////////////////////////////// +// +// CTransaction +// + +bool CTxIn::IsMine() const +{ + CRITICAL_BLOCK(cs_mapWallet) + { + map::iterator mi = mapWallet.find(prevout.hash); + if (mi != mapWallet.end()) + { + const CWalletTx& prev = (*mi).second; + if (prevout.n < prev.vout.size()) + if (prev.vout[prevout.n].IsMine()) + return true; + } + } + return false; +} + +int64 CTxIn::GetDebit() const +{ + CRITICAL_BLOCK(cs_mapWallet) + { + map::iterator mi = mapWallet.find(prevout.hash); + if (mi != mapWallet.end()) + { + const CWalletTx& prev = (*mi).second; + if (prevout.n < prev.vout.size()) + if (prev.vout[prevout.n].IsMine()) + return prev.vout[prevout.n].nValue; + } + } + return 0; +} + +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::iterator mi = mapBlockIndex.find(hashBlock); + if (mi != mapBlockIndex.end()) + { + CBlockIndex* pindex = (*mi).second; + if (pindex) + return pindex->GetMedianTime(); + } + } + return nTimeReceived; +} + + + + + + +int CMerkleTx::SetMerkleBranch(const CBlock* pblock) +{ + if (fClient) + { + if (hashBlock == 0) + return 0; + } + else + { + CBlock blockTmp; + if (pblock == NULL) + { + // Load the block this tx is in + CTxIndex txindex; + if (!CTxDB("r").ReadTxIndex(GetHash(), txindex)) + return 0; + if (!blockTmp.ReadFromDisk(txindex.pos.nFile, txindex.pos.nBlockPos, true)) + return 0; + pblock = &blockTmp; + } + + // Update the tx's hashBlock + hashBlock = pblock->GetHash(); + + // Locate the transaction + for (nIndex = 0; nIndex < pblock->vtx.size(); nIndex++) + if (pblock->vtx[nIndex] == *(CTransaction*)this) + break; + if (nIndex == pblock->vtx.size()) + { + vMerkleBranch.clear(); + nIndex = -1; + printf("ERROR: SetMerkleBranch() : couldn't find tx in block\n"); + return 0; + } + + // Fill in merkle branch + vMerkleBranch = pblock->GetMerkleBranch(nIndex); + } + + // Is the tx in a block that's in the main chain + map::iterator mi = mapBlockIndex.find(hashBlock); + if (mi == mapBlockIndex.end()) + return 0; + CBlockIndex* pindex = (*mi).second; + if (!pindex || !pindex->IsInMainChain()) + return 0; + + return pindexBest->nHeight - pindex->nHeight + 1; +} + + + +void CWalletTx::AddSupportingTransactions(CTxDB& txdb) +{ + vtxPrev.clear(); + + const int COPY_DEPTH = 3; + if (SetMerkleBranch() < COPY_DEPTH) + { + vector vWorkQueue; + foreach(const CTxIn& txin, vin) + vWorkQueue.push_back(txin.prevout.hash); + + // This critsect is OK because txdb is already open + CRITICAL_BLOCK(cs_mapWallet) + { + map mapWalletPrev; + set setAlreadyDone; + for (int i = 0; i < vWorkQueue.size(); i++) + { + uint256 hash = vWorkQueue[i]; + if (setAlreadyDone.count(hash)) + continue; + setAlreadyDone.insert(hash); + + CMerkleTx tx; + if (mapWallet.count(hash)) + { + tx = mapWallet[hash]; + foreach(const CMerkleTx& txWalletPrev, mapWallet[hash].vtxPrev) + mapWalletPrev[txWalletPrev.GetHash()] = &txWalletPrev; + } + else if (mapWalletPrev.count(hash)) + { + tx = *mapWalletPrev[hash]; + } + else if (!fClient && txdb.ReadDiskTx(hash, tx)) + { + ; + } + else + { + printf("ERROR: AddSupportingTransactions() : unsupported transaction\n"); + continue; + } + + int nDepth = tx.SetMerkleBranch(); + vtxPrev.push_back(tx); + + if (nDepth < COPY_DEPTH) + foreach(const CTxIn& txin, tx.vin) + vWorkQueue.push_back(txin.prevout.hash); + } + } + } + + reverse(vtxPrev.begin(), vtxPrev.end()); +} + + + + + + + + + + + +bool CTransaction::AcceptTransaction(CTxDB& txdb, bool fCheckInputs, bool* pfMissingInputs) +{ + if (pfMissingInputs) + *pfMissingInputs = false; + + // Coinbase is only valid in a block, not as a loose transaction + if (IsCoinBase()) + return error("AcceptTransaction() : coinbase as individual tx"); + + if (!CheckTransaction()) + return error("AcceptTransaction() : CheckTransaction failed"); + + // Do we already have it? + uint256 hash = GetHash(); + CRITICAL_BLOCK(cs_mapTransactions) + if (mapTransactions.count(hash)) + return false; + if (fCheckInputs) + if (txdb.ContainsTx(hash)) + return false; + + // Check for conflicts with in-memory transactions + CTransaction* ptxOld = NULL; + for (int i = 0; i < vin.size(); i++) + { + COutPoint outpoint = vin[i].prevout; + if (mapNextTx.count(outpoint)) + { + // Allow replacing with a newer version of the same transaction + if (i != 0) + return false; + ptxOld = mapNextTx[outpoint].ptx; + if (!IsNewerThan(*ptxOld)) + return false; + for (int i = 0; i < vin.size(); i++) + { + COutPoint outpoint = vin[i].prevout; + if (!mapNextTx.count(outpoint) || mapNextTx[outpoint].ptx != ptxOld) + return false; + } + break; + } + } + + // Check against previous transactions + map mapUnused; + int64 nFees = 0; + if (fCheckInputs && !ConnectInputs(txdb, mapUnused, CDiskTxPos(1,1,1), 0, nFees, false, false)) + { + if (pfMissingInputs) + *pfMissingInputs = true; + return error("AcceptTransaction() : ConnectInputs failed %s", hash.ToString().substr(0,6).c_str()); + } + + // Store transaction in memory + CRITICAL_BLOCK(cs_mapTransactions) + { + if (ptxOld) + { + printf("mapTransaction.erase(%s) replacing with new version\n", ptxOld->GetHash().ToString().c_str()); + mapTransactions.erase(ptxOld->GetHash()); + } + AddToMemoryPool(); + } + + ///// are we sure this is ok when loading transactions or restoring block txes + // If updated, erase old tx from wallet + if (ptxOld) + EraseFromWallet(ptxOld->GetHash()); + + printf("AcceptTransaction(): accepted %s\n", hash.ToString().substr(0,6).c_str()); + return true; +} + + +bool CTransaction::AddToMemoryPool() +{ + // Add to memory pool without checking anything. Don't call this directly, + // call AcceptTransaction to properly check the transaction first. + CRITICAL_BLOCK(cs_mapTransactions) + { + uint256 hash = GetHash(); + mapTransactions[hash] = *this; + for (int i = 0; i < vin.size(); i++) + mapNextTx[vin[i].prevout] = CInPoint(&mapTransactions[hash], i); + nTransactionsUpdated++; + } + return true; +} + + +bool CTransaction::RemoveFromMemoryPool() +{ + // Remove transaction from memory pool + CRITICAL_BLOCK(cs_mapTransactions) + { + foreach(const CTxIn& txin, vin) + mapNextTx.erase(txin.prevout); + mapTransactions.erase(GetHash()); + nTransactionsUpdated++; + } + return true; +} + + + + + + +int CMerkleTx::GetDepthInMainChain() const +{ + if (hashBlock == 0 || nIndex == -1) + return 0; + + // Find the block it claims to be in + map::iterator mi = mapBlockIndex.find(hashBlock); + if (mi == mapBlockIndex.end()) + return 0; + CBlockIndex* pindex = (*mi).second; + if (!pindex || !pindex->IsInMainChain()) + return 0; + + // Make sure the merkle branch connects to this block + if (!fMerkleVerified) + { + if (CBlock::CheckMerkleBranch(GetHash(), vMerkleBranch, nIndex) != pindex->hashMerkleRoot) + return 0; + fMerkleVerified = true; + } + + return pindexBest->nHeight - pindex->nHeight + 1; +} + + +int CMerkleTx::GetBlocksToMaturity() const +{ + if (!IsCoinBase()) + return 0; + return max(0, (COINBASE_MATURITY+20) - GetDepthInMainChain()); +} + + +bool CMerkleTx::AcceptTransaction(CTxDB& txdb, bool fCheckInputs) +{ + if (fClient) + { + if (!IsInMainChain() && !ClientConnectInputs()) + return false; + return CTransaction::AcceptTransaction(txdb, false); + } + else + { + return CTransaction::AcceptTransaction(txdb, fCheckInputs); + } +} + + + +bool CWalletTx::AcceptWalletTransaction(CTxDB& txdb, bool fCheckInputs) +{ + CRITICAL_BLOCK(cs_mapTransactions) + { + foreach(CMerkleTx& tx, vtxPrev) + { + if (!tx.IsCoinBase()) + { + uint256 hash = tx.GetHash(); + if (!mapTransactions.count(hash) && !txdb.ContainsTx(hash)) + tx.AcceptTransaction(txdb, fCheckInputs); + } + } + if (!IsCoinBase()) + return AcceptTransaction(txdb, fCheckInputs); + } + return true; +} + +void ReacceptWalletTransactions() +{ + // Reaccept any txes of ours that aren't already in a block + CTxDB txdb("r"); + CRITICAL_BLOCK(cs_mapWallet) + { + foreach(PAIRTYPE(const uint256, CWalletTx)& item, mapWallet) + { + CWalletTx& wtx = item.second; + if (!wtx.IsCoinBase() && !txdb.ContainsTx(wtx.GetHash())) + wtx.AcceptWalletTransaction(txdb, false); + } + } +} + + +void CWalletTx::RelayWalletTransaction(CTxDB& txdb) +{ + foreach(const CMerkleTx& tx, vtxPrev) + { + if (!tx.IsCoinBase()) + { + uint256 hash = tx.GetHash(); + if (!txdb.ContainsTx(hash)) + RelayMessage(CInv(MSG_TX, hash), (CTransaction)tx); + } + } + if (!IsCoinBase()) + { + uint256 hash = GetHash(); + if (!txdb.ContainsTx(hash)) + { + printf("Relaying wtx %s\n", hash.ToString().substr(0,6).c_str()); + RelayMessage(CInv(MSG_TX, hash), (CTransaction)*this); + } + } +} + +void RelayWalletTransactions() +{ + static int64 nLastTime; + if (GetTime() - nLastTime < 10 * 60) + return; + nLastTime = GetTime(); + + // Rebroadcast any of our txes that aren't in a block yet + printf("RelayWalletTransactions()\n"); + CTxDB txdb("r"); + CRITICAL_BLOCK(cs_mapWallet) + { + // Sort them in chronological order + multimap mapSorted; + foreach(PAIRTYPE(const uint256, CWalletTx)& item, mapWallet) + { + CWalletTx& wtx = item.second; + mapSorted.insert(make_pair(wtx.nTimeReceived, &wtx)); + } + foreach(PAIRTYPE(const unsigned int, CWalletTx*)& item, mapSorted) + { + CWalletTx& wtx = *item.second; + wtx.RelayWalletTransaction(txdb); + } + } +} + + + + + + + + + + +////////////////////////////////////////////////////////////////////////////// +// +// CBlock and CBlockIndex +// + +bool CBlock::ReadFromDisk(const CBlockIndex* pblockindex, bool fReadTransactions) +{ + return ReadFromDisk(pblockindex->nFile, pblockindex->nBlockPos, fReadTransactions); +} + +uint256 GetOrphanRoot(const CBlock* pblock) +{ + // Work back to the first block in the orphan chain + while (mapOrphanBlocks.count(pblock->hashPrevBlock)) + pblock = mapOrphanBlocks[pblock->hashPrevBlock]; + return pblock->GetHash(); +} + +int64 CBlock::GetBlockValue(int64 nFees) const +{ + int64 nSubsidy = 50 * COIN; + + // Subsidy is cut in half every 4 years + nSubsidy >>= (nBestHeight / 210000); + + return nSubsidy + nFees; +} + +unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast) +{ + const unsigned int nTargetTimespan = 14 * 24 * 60 * 60; // two weeks + const unsigned int nTargetSpacing = 10 * 60; + const unsigned int nInterval = nTargetTimespan / nTargetSpacing; + + // Genesis block + if (pindexLast == NULL) + return bnProofOfWorkLimit.GetCompact(); + + // Only change once per interval + if ((pindexLast->nHeight+1) % nInterval != 0) + return pindexLast->nBits; + + // Go back by what we want to be 14 days worth of blocks + const CBlockIndex* pindexFirst = pindexLast; + for (int i = 0; pindexFirst && i < nInterval-1; i++) + pindexFirst = pindexFirst->pprev; + assert(pindexFirst); + + // Limit adjustment step + unsigned int nActualTimespan = pindexLast->nTime - pindexFirst->nTime; + printf(" nActualTimespan = %d before bounds\n", nActualTimespan); + if (nActualTimespan < nTargetTimespan/4) + nActualTimespan = nTargetTimespan/4; + if (nActualTimespan > nTargetTimespan*4) + nActualTimespan = nTargetTimespan*4; + + // Retarget + CBigNum bnNew; + bnNew.SetCompact(pindexLast->nBits); + bnNew *= nActualTimespan; + bnNew /= nTargetTimespan; + + if (bnNew > bnProofOfWorkLimit) + bnNew = bnProofOfWorkLimit; + + /// debug print + printf("\n\n\nGetNextWorkRequired RETARGET *****\n"); + printf("nTargetTimespan = %d nActualTimespan = %d\n", nTargetTimespan, nActualTimespan); + printf("Before: %08x %s\n", pindexLast->nBits, CBigNum().SetCompact(pindexLast->nBits).getuint256().ToString().c_str()); + printf("After: %08x %s\n", bnNew.GetCompact(), bnNew.getuint256().ToString().c_str()); + + return bnNew.GetCompact(); +} + + + + + + + + + +bool CTransaction::DisconnectInputs(CTxDB& txdb) +{ + // Relinquish previous transactions' spent pointers + if (!IsCoinBase()) + { + foreach(const CTxIn& txin, vin) + { + COutPoint prevout = txin.prevout; + + // Get prev txindex from disk + CTxIndex txindex; + if (!txdb.ReadTxIndex(prevout.hash, txindex)) + return error("DisconnectInputs() : ReadTxIndex failed"); + + if (prevout.n >= txindex.vSpent.size()) + return error("DisconnectInputs() : prevout.n out of range"); + + // Mark outpoint as not spent + txindex.vSpent[prevout.n].SetNull(); + + // Write back + txdb.UpdateTxIndex(prevout.hash, txindex); + } + } + + // Remove transaction from index + if (!txdb.EraseTxIndex(*this)) + return error("DisconnectInputs() : EraseTxPos failed"); + + return true; +} + + +bool CTransaction::ConnectInputs(CTxDB& txdb, map& mapTestPool, CDiskTxPos posThisTx, int nHeight, int64& nFees, bool fBlock, bool fMiner, int64 nMinFee) +{ + // Take over previous transactions' spent pointers + if (!IsCoinBase()) + { + int64 nValueIn = 0; + for (int i = 0; i < vin.size(); i++) + { + COutPoint prevout = vin[i].prevout; + + // Read txindex + CTxIndex txindex; + bool fFound = true; + if (fMiner && mapTestPool.count(prevout.hash)) + { + // Get txindex from current proposed changes + txindex = mapTestPool[prevout.hash]; + } + else + { + // Read txindex from txdb + fFound = txdb.ReadTxIndex(prevout.hash, txindex); + } + if (!fFound && (fBlock || fMiner)) + return fMiner ? false : error("ConnectInputs() : %s prev tx %s index entry not found", GetHash().ToString().substr(0,6).c_str(), prevout.hash.ToString().substr(0,6).c_str()); + + // Read txPrev + CTransaction txPrev; + if (!fFound || txindex.pos == CDiskTxPos(1,1,1)) + { + // Get prev tx from single transactions in memory + CRITICAL_BLOCK(cs_mapTransactions) + { + if (!mapTransactions.count(prevout.hash)) + return error("ConnectInputs() : %s mapTransactions prev not found %s", GetHash().ToString().substr(0,6).c_str(), prevout.hash.ToString().substr(0,6).c_str()); + txPrev = mapTransactions[prevout.hash]; + } + if (!fFound) + txindex.vSpent.resize(txPrev.vout.size()); + } + else + { + // Get prev tx from disk + if (!txPrev.ReadFromDisk(txindex.pos)) + return error("ConnectInputs() : %s ReadFromDisk prev tx %s failed", GetHash().ToString().substr(0,6).c_str(), prevout.hash.ToString().substr(0,6).c_str()); + } + + if (prevout.n >= txPrev.vout.size() || prevout.n >= txindex.vSpent.size()) + return error("ConnectInputs() : %s prevout.n out of range %d %d %d", GetHash().ToString().substr(0,6).c_str(), prevout.n, txPrev.vout.size(), txindex.vSpent.size()); + + // If prev is coinbase, check that it's matured + if (txPrev.IsCoinBase()) + for (CBlockIndex* pindex = pindexBest; pindex && nBestHeight - pindex->nHeight < COINBASE_MATURITY-1; pindex = pindex->pprev) + if (pindex->nBlockPos == txindex.pos.nBlockPos && pindex->nFile == txindex.pos.nFile) + return error("ConnectInputs() : tried to spend coinbase at depth %d", nBestHeight - pindex->nHeight); + + // Verify signature + if (!VerifySignature(txPrev, *this, i)) + return error("ConnectInputs() : %s VerifySignature failed", GetHash().ToString().substr(0,6).c_str()); + + // Check for conflicts + if (!txindex.vSpent[prevout.n].IsNull()) + return fMiner ? false : error("ConnectInputs() : %s prev tx already used at %s", GetHash().ToString().substr(0,6).c_str(), txindex.vSpent[prevout.n].ToString().c_str()); + + // Mark outpoints as spent + txindex.vSpent[prevout.n] = posThisTx; + + // Write back + if (fBlock) + txdb.UpdateTxIndex(prevout.hash, txindex); + else if (fMiner) + mapTestPool[prevout.hash] = txindex; + + nValueIn += txPrev.vout[prevout.n].nValue; + } + + // Tally transaction fees + int64 nTxFee = nValueIn - GetValueOut(); + if (nTxFee < 0) + return error("ConnectInputs() : %s nTxFee < 0", GetHash().ToString().substr(0,6).c_str()); + if (nTxFee < nMinFee) + return false; + nFees += nTxFee; + } + + if (fBlock) + { + // Add transaction to disk index + if (!txdb.AddTxIndex(*this, posThisTx, nHeight)) + return error("ConnectInputs() : AddTxPos failed"); + } + else if (fMiner) + { + // Add transaction to test pool + mapTestPool[GetHash()] = CTxIndex(CDiskTxPos(1,1,1), vout.size()); + } + + return true; +} + + +bool CTransaction::ClientConnectInputs() +{ + if (IsCoinBase()) + return false; + + // Take over previous transactions' spent pointers + CRITICAL_BLOCK(cs_mapTransactions) + { + int64 nValueIn = 0; + for (int i = 0; i < vin.size(); i++) + { + // Get prev tx from single transactions in memory + COutPoint prevout = vin[i].prevout; + if (!mapTransactions.count(prevout.hash)) + return false; + CTransaction& txPrev = mapTransactions[prevout.hash]; + + if (prevout.n >= txPrev.vout.size()) + return false; + + // Verify signature + if (!VerifySignature(txPrev, *this, i)) + return error("ConnectInputs() : VerifySignature failed"); + + ///// this is redundant with the mapNextTx stuff, not sure which I want to get rid of + ///// this has to go away now that posNext is gone + // // Check for conflicts + // if (!txPrev.vout[prevout.n].posNext.IsNull()) + // return error("ConnectInputs() : prev tx already used"); + // + // // Flag outpoints as used + // txPrev.vout[prevout.n].posNext = posThisTx; + + nValueIn += txPrev.vout[prevout.n].nValue; + } + if (GetValueOut() > nValueIn) + return false; + } + + return true; +} + + + + +bool CBlock::DisconnectBlock(CTxDB& txdb, CBlockIndex* pindex) +{ + // Disconnect in reverse order + for (int i = vtx.size()-1; i >= 0; i--) + if (!vtx[i].DisconnectInputs(txdb)) + return false; + + // Update block index on disk without changing it in memory. + // The memory index structure will be changed after the db commits. + if (pindex->pprev) + { + CDiskBlockIndex blockindexPrev(pindex->pprev); + blockindexPrev.hashNext = 0; + txdb.WriteBlockIndex(blockindexPrev); + } + + return true; +} + +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 mapUnused; + int64 nFees = 0; + foreach(CTransaction& tx, vtx) + { + CDiskTxPos posThisTx(pindex->nFile, pindex->nBlockPos, nTxPos); + nTxPos += ::GetSerializeSize(tx, SER_DISK); + + if (!tx.ConnectInputs(txdb, mapUnused, posThisTx, pindex->nHeight, nFees, true, false)) + return false; + } + + if (vtx[0].GetValueOut() > GetBlockValue(nFees)) + return false; + + // Update block index on disk without changing it in memory. + // The memory index structure will be changed after the db commits. + if (pindex->pprev) + { + CDiskBlockIndex blockindexPrev(pindex->pprev); + blockindexPrev.hashNext = pindex->GetBlockHash(); + txdb.WriteBlockIndex(blockindexPrev); + } + + // Watch for transactions paying to me + foreach(CTransaction& tx, vtx) + AddToWalletIfMine(tx, this); + + return true; +} + + + +bool Reorganize(CTxDB& txdb, CBlockIndex* pindexNew) +{ + printf("*** REORGANIZE ***\n"); + + // Find the fork + CBlockIndex* pfork = pindexBest; + CBlockIndex* plonger = pindexNew; + while (pfork != plonger) + { + if (!(pfork = pfork->pprev)) + return error("Reorganize() : pfork->pprev is null"); + while (plonger->nHeight > pfork->nHeight) + if (!(plonger = plonger->pprev)) + return error("Reorganize() : plonger->pprev is null"); + } + + // List of what to disconnect + vector vDisconnect; + for (CBlockIndex* pindex = pindexBest; pindex != pfork; pindex = pindex->pprev) + vDisconnect.push_back(pindex); + + // List of what to connect + vector vConnect; + for (CBlockIndex* pindex = pindexNew; pindex != pfork; pindex = pindex->pprev) + vConnect.push_back(pindex); + reverse(vConnect.begin(), vConnect.end()); + + // Disconnect shorter branch + vector vResurrect; + foreach(CBlockIndex* pindex, vDisconnect) + { + CBlock block; + if (!block.ReadFromDisk(pindex->nFile, pindex->nBlockPos, true)) + return error("Reorganize() : ReadFromDisk for disconnect failed"); + if (!block.DisconnectBlock(txdb, pindex)) + return error("Reorganize() : DisconnectBlock failed"); + + // Queue memory transactions to resurrect + foreach(const CTransaction& tx, block.vtx) + if (!tx.IsCoinBase()) + vResurrect.push_back(tx); + } + + // Connect longer branch + vector vDelete; + for (int i = 0; i < vConnect.size(); i++) + { + CBlockIndex* pindex = vConnect[i]; + CBlock block; + if (!block.ReadFromDisk(pindex->nFile, pindex->nBlockPos, true)) + return error("Reorganize() : ReadFromDisk for connect failed"); + if (!block.ConnectBlock(txdb, pindex)) + { + // Invalid block, delete the rest of this branch + txdb.TxnAbort(); + for (int j = i; j < vConnect.size(); j++) + { + CBlockIndex* pindex = vConnect[j]; + pindex->EraseBlockFromDisk(); + txdb.EraseBlockIndex(pindex->GetBlockHash()); + mapBlockIndex.erase(pindex->GetBlockHash()); + delete pindex; + } + return error("Reorganize() : ConnectBlock failed"); + } + + // Queue memory transactions to delete + foreach(const CTransaction& tx, block.vtx) + vDelete.push_back(tx); + } + if (!txdb.WriteHashBestChain(pindexNew->GetBlockHash())) + return error("Reorganize() : WriteHashBestChain failed"); + + // Commit now because resurrecting could take some time + txdb.TxnCommit(); + + // Disconnect shorter branch + foreach(CBlockIndex* pindex, vDisconnect) + if (pindex->pprev) + pindex->pprev->pnext = NULL; + + // Connect longer branch + foreach(CBlockIndex* pindex, vConnect) + if (pindex->pprev) + pindex->pprev->pnext = pindex; + + // Resurrect memory transactions that were in the disconnected branch + foreach(CTransaction& tx, vResurrect) + tx.AcceptTransaction(txdb, false); + + // Delete redundant memory transactions that are in the connected branch + foreach(CTransaction& tx, vDelete) + tx.RemoveFromMemoryPool(); + + return true; +} + + +bool CBlock::AddToBlockIndex(unsigned int nFile, unsigned int nBlockPos) +{ + // Check for duplicate + uint256 hash = GetHash(); + if (mapBlockIndex.count(hash)) + return error("AddToBlockIndex() : %s already exists", hash.ToString().substr(0,14).c_str()); + + // Construct new block index object + CBlockIndex* pindexNew = new CBlockIndex(nFile, nBlockPos, *this); + if (!pindexNew) + return error("AddToBlockIndex() : new CBlockIndex failed"); + map::iterator mi = mapBlockIndex.insert(make_pair(hash, pindexNew)).first; + pindexNew->phashBlock = &((*mi).first); + map::iterator miPrev = mapBlockIndex.find(hashPrevBlock); + if (miPrev != mapBlockIndex.end()) + { + pindexNew->pprev = (*miPrev).second; + pindexNew->nHeight = pindexNew->pprev->nHeight + 1; + } + + CTxDB txdb; + txdb.TxnBegin(); + txdb.WriteBlockIndex(CDiskBlockIndex(pindexNew)); + + // New best + if (pindexNew->nHeight > nBestHeight) + { + if (pindexGenesisBlock == NULL && hash == hashGenesisBlock) + { + pindexGenesisBlock = pindexNew; + txdb.WriteHashBestChain(hash); + } + else if (hashPrevBlock == hashBestChain) + { + // Adding to current best branch + if (!ConnectBlock(txdb, pindexNew) || !txdb.WriteHashBestChain(hash)) + { + txdb.TxnAbort(); + pindexNew->EraseBlockFromDisk(); + mapBlockIndex.erase(pindexNew->GetBlockHash()); + delete pindexNew; + return error("AddToBlockIndex() : ConnectBlock failed"); + } + txdb.TxnCommit(); + pindexNew->pprev->pnext = pindexNew; + + // Delete redundant memory transactions + foreach(CTransaction& tx, vtx) + tx.RemoveFromMemoryPool(); + } + else + { + // New best branch + if (!Reorganize(txdb, pindexNew)) + { + txdb.TxnAbort(); + return error("AddToBlockIndex() : Reorganize failed"); + } + } + + // New best link + hashBestChain = hash; + pindexBest = pindexNew; + nBestHeight = pindexBest->nHeight; + nTransactionsUpdated++; + printf("AddToBlockIndex: new best=%s height=%d\n", hashBestChain.ToString().substr(0,14).c_str(), nBestHeight); + } + + txdb.TxnCommit(); + txdb.Close(); + + // Relay wallet transactions that haven't gotten in yet + if (pindexNew == pindexBest) + RelayWalletTransactions(); + + MainFrameRepaint(); + return true; +} + + + + +bool CBlock::CheckBlock() const +{ + // These are checks that are independent of context + // that can be verified before saving an orphan block. + + // Size limits + if (vtx.empty() || vtx.size() > MAX_SIZE || ::GetSerializeSize(*this, SER_DISK) > MAX_SIZE) + return error("CheckBlock() : size limits failed"); + + // Check timestamp + if (nTime > GetAdjustedTime() + 2 * 60 * 60) + return error("CheckBlock() : block timestamp too far in the future"); + + // First transaction must be coinbase, the rest must not be + if (vtx.empty() || !vtx[0].IsCoinBase()) + return 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"); + + // Check transactions + foreach(const CTransaction& tx, vtx) + if (!tx.CheckTransaction()) + return error("CheckBlock() : CheckTransaction failed"); + + // Check proof of work matches claimed amount + if (CBigNum().SetCompact(nBits) > bnProofOfWorkLimit) + return error("CheckBlock() : nBits below minimum work"); + if (GetHash() > CBigNum().SetCompact(nBits).getuint256()) + return error("CheckBlock() : hash doesn't match nBits"); + + // Check merkleroot + if (hashMerkleRoot != BuildMerkleTree()) + return error("CheckBlock() : hashMerkleRoot mismatch"); + + return true; +} + +bool CBlock::AcceptBlock() +{ + // Check for duplicate + uint256 hash = GetHash(); + if (mapBlockIndex.count(hash)) + return error("AcceptBlock() : block already in mapBlockIndex"); + + // Get prev block index + map::iterator mi = mapBlockIndex.find(hashPrevBlock); + if (mi == mapBlockIndex.end()) + return error("AcceptBlock() : prev block not found"); + CBlockIndex* pindexPrev = (*mi).second; + + // Check timestamp against prev + if (nTime <= pindexPrev->GetMedianTimePast()) + return error("AcceptBlock() : block's timestamp is too early"); + + // Check proof of work + if (nBits != GetNextWorkRequired(pindexPrev)) + return error("AcceptBlock() : incorrect proof of work"); + + // Write block to history file + if (!CheckDiskSpace(::GetSerializeSize(*this, SER_DISK))) + return error("AcceptBlock() : out of disk space"); + unsigned int nFile; + unsigned int nBlockPos; + if (!WriteToDisk(!fClient, nFile, nBlockPos)) + return error("AcceptBlock() : WriteToDisk failed"); + if (!AddToBlockIndex(nFile, nBlockPos)) + return error("AcceptBlock() : AddToBlockIndex failed"); + + if (hashBestChain == hash) + RelayInventory(CInv(MSG_BLOCK, hash)); + + // // Add atoms to user reviews for coins created + // vector vchPubKey; + // if (ExtractPubKey(vtx[0].vout[0].scriptPubKey, false, vchPubKey)) + // { + // unsigned short nAtom = GetRand(USHRT_MAX - 100) + 100; + // vector vAtoms(1, nAtom); + // AddAtomsAndPropagate(Hash(vchPubKey.begin(), vchPubKey.end()), vAtoms, true); + // } + + return true; +} + +bool ProcessBlock(CNode* pfrom, CBlock* pblock) +{ + // Check for duplicate + uint256 hash = pblock->GetHash(); + if (mapBlockIndex.count(hash)) + return error("ProcessBlock() : already have block %d %s", mapBlockIndex[hash]->nHeight, hash.ToString().substr(0,14).c_str()); + if (mapOrphanBlocks.count(hash)) + return error("ProcessBlock() : already have block (orphan) %s", hash.ToString().substr(0,14).c_str()); + + // Preliminary checks + if (!pblock->CheckBlock()) + { + delete pblock; + return error("ProcessBlock() : CheckBlock FAILED"); + } + + // If don't already have its previous block, shunt it off to holding area until we get it + if (!mapBlockIndex.count(pblock->hashPrevBlock)) + { + printf("ProcessBlock: ORPHAN BLOCK, prev=%s\n", pblock->hashPrevBlock.ToString().substr(0,14).c_str()); + mapOrphanBlocks.insert(make_pair(hash, pblock)); + mapOrphanBlocksByPrev.insert(make_pair(pblock->hashPrevBlock, pblock)); + + // Ask this guy to fill in what we're missing + if (pfrom) + pfrom->PushMessage("getblocks", CBlockLocator(pindexBest), GetOrphanRoot(pblock)); + return true; + } + + // Store to disk + if (!pblock->AcceptBlock()) + { + delete pblock; + return error("ProcessBlock() : AcceptBlock FAILED"); + } + delete pblock; + + // Recursively process any orphan blocks that depended on this one + vector vWorkQueue; + vWorkQueue.push_back(hash); + for (int i = 0; i < vWorkQueue.size(); i++) + { + uint256 hashPrev = vWorkQueue[i]; + for (multimap::iterator mi = mapOrphanBlocksByPrev.lower_bound(hashPrev); + mi != mapOrphanBlocksByPrev.upper_bound(hashPrev); + ++mi) + { + CBlock* pblockOrphan = (*mi).second; + if (pblockOrphan->AcceptBlock()) + vWorkQueue.push_back(pblockOrphan->GetHash()); + mapOrphanBlocks.erase(pblockOrphan->GetHash()); + delete pblockOrphan; + } + mapOrphanBlocksByPrev.erase(hashPrev); + } + + printf("ProcessBlock: ACCEPTED\n"); + return true; +} + + + + + + + + +template +bool 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; + } +} + +string GetAppDir() +{ + string strDir; + if (!strSetDataDir.empty()) + { + strDir = strSetDataDir; + } + else if (getenv("APPDATA")) + { + strDir = strprintf("%s\\Bitcoin", getenv("APPDATA")); + } + else if (getenv("USERPROFILE")) + { + string strAppData = strprintf("%s\\Application Data", getenv("USERPROFILE")); + static bool fMkdirDone; + if (!fMkdirDone) + { + fMkdirDone = true; + _mkdir(strAppData.c_str()); + } + strDir = strprintf("%s\\Bitcoin", strAppData.c_str()); + } + else + { + return "."; + } + static bool fMkdirDone; + if (!fMkdirDone) + { + fMkdirDone = true; + _mkdir(strDir.c_str()); + } + return strDir; +} + +bool CheckDiskSpace(int64 nAdditionalBytes) +{ + uint64 nFreeBytesAvailable = 0; // bytes available to caller + uint64 nTotalNumberOfBytes = 0; // bytes on disk + uint64 nTotalNumberOfFreeBytes = 0; // free bytes on disk + + if (!GetDiskFreeSpaceEx(GetAppDir().c_str(), + (PULARGE_INTEGER)&nFreeBytesAvailable, + (PULARGE_INTEGER)&nTotalNumberOfBytes, + (PULARGE_INTEGER)&nTotalNumberOfFreeBytes)) + { + printf("ERROR: GetDiskFreeSpaceEx() failed\n"); + return true; + } + + // Check for 15MB because database could create another 10MB log file at any time + if ((int64)nFreeBytesAvailable < 15000000 + nAdditionalBytes) + { + fShutdown = true; + wxMessageBox("Warning: Your disk space is low ", "Bitcoin", wxICON_EXCLAMATION); + _beginthread(Shutdown, 0, NULL); + return false; + } + return true; +} + +FILE* OpenBlockFile(unsigned int nFile, unsigned int nBlockPos, const char* pszMode) +{ + if (nFile == -1) + return NULL; + FILE* file = fopen(strprintf("%s\\blk%04d.dat", GetAppDir().c_str(), nFile).c_str(), pszMode); + if (!file) + return NULL; + if (nBlockPos != 0 && !strchr(pszMode, 'a') && !strchr(pszMode, 'w')) + { + if (fseek(file, nBlockPos, SEEK_SET) != 0) + { + fclose(file); + return NULL; + } + } + return file; +} + +static unsigned int nCurrentBlockFile = 1; + +FILE* AppendBlockFile(unsigned int& nFileRet) +{ + nFileRet = 0; + loop + { + FILE* file = OpenBlockFile(nCurrentBlockFile, 0, "ab"); + if (!file) + return NULL; + if (fseek(file, 0, SEEK_END) != 0) + return NULL; + // FAT32 filesize max 4GB, fseek and ftell max 2GB, so we must stay under 2GB + if (ftell(file) < 0x7F000000 - MAX_SIZE) + { + nFileRet = nCurrentBlockFile; + return file; + } + fclose(file); + nCurrentBlockFile++; + } +} + +bool LoadBlockIndex(bool fAllowNew) +{ + // + // Load block index + // + CTxDB txdb("cr"); + if (!txdb.LoadBlockIndex()) + return false; + txdb.Close(); + + // + // Init with genesis block + // + if (mapBlockIndex.empty()) + { + if (!fAllowNew) + return false; + + + // Genesis Block: + // GetHash() = 0x000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f + // hashMerkleRoot = 0x4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b + // txNew.vin[0].scriptSig = 486604799 4 0x736B6E616220726F662074756F6C69616220646E6F63657320666F206B6E697262206E6F20726F6C6C65636E61684320393030322F6E614A2F33302073656D695420656854 + // txNew.vout[0].nValue = 5000000000 + // txNew.vout[0].scriptPubKey = 0x5F1DF16B2B704C8A578D0BBAF74D385CDE12C11EE50455F3C438EF4C3FBCF649B6DE611FEAE06279A60939E028A8D65C10B73071A6F16719274855FEB0FD8A6704 OP_CHECKSIG + // block.nVersion = 1 + // block.nTime = 1231006505 + // block.nBits = 0x1d00ffff + // block.nNonce = 2083236893 + // CBlock(hash=000000000019d6, ver=1, hashPrevBlock=00000000000000, hashMerkleRoot=4a5e1e, nTime=1231006505, nBits=1d00ffff, nNonce=2083236893, vtx=1) + // CTransaction(hash=4a5e1e, ver=1, vin.size=1, vout.size=1, nLockTime=0) + // CTxIn(COutPoint(000000, -1), coinbase 04ffff001d0104455468652054696d65732030332f4a616e2f32303039204368616e63656c6c6f72206f6e206272696e6b206f66207365636f6e64206261696c6f757420666f722062616e6b73) + // CTxOut(nValue=50.00000000, scriptPubKey=0x5F1DF16B2B704C8A578D0B) + // vMerkleTree: 4a5e1e + + // Genesis block + char* pszTimestamp = "The Times 03/Jan/2009 Chancellor on brink of second bailout for banks"; + CTransaction txNew; + txNew.vin.resize(1); + txNew.vout.resize(1); + txNew.vin[0].scriptSig = CScript() << 486604799 << CBigNum(4) << vector((unsigned char*)pszTimestamp, (unsigned char*)pszTimestamp + strlen(pszTimestamp)); + txNew.vout[0].nValue = 50 * COIN; + txNew.vout[0].scriptPubKey = CScript() << CBigNum("0x5F1DF16B2B704C8A578D0BBAF74D385CDE12C11EE50455F3C438EF4C3FBCF649B6DE611FEAE06279A60939E028A8D65C10B73071A6F16719274855FEB0FD8A6704") << OP_CHECKSIG; + CBlock block; + block.vtx.push_back(txNew); + block.hashPrevBlock = 0; + block.hashMerkleRoot = block.BuildMerkleTree(); + block.nVersion = 1; + block.nTime = 1231006505; + block.nBits = 0x1d00ffff; + block.nNonce = 2083236893; + + //// debug print, delete this later + printf("%s\n", block.GetHash().ToString().c_str()); + printf("%s\n", block.hashMerkleRoot.ToString().c_str()); + printf("%s\n", hashGenesisBlock.ToString().c_str()); + txNew.vout[0].scriptPubKey.print(); + block.print(); + assert(block.hashMerkleRoot == uint256("0x4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b")); + + assert(block.GetHash() == hashGenesisBlock); + + // Start new block file + unsigned int nFile; + unsigned int nBlockPos; + if (!block.WriteToDisk(!fClient, nFile, nBlockPos)) + return error("LoadBlockIndex() : writing genesis block to disk failed"); + if (!block.AddToBlockIndex(nFile, nBlockPos)) + return error("LoadBlockIndex() : genesis block not accepted"); + } + + return true; +} + + + +void PrintBlockTree() +{ + // precompute tree structure + map > mapNext; + for (map::iterator mi = mapBlockIndex.begin(); mi != mapBlockIndex.end(); ++mi) + { + CBlockIndex* pindex = (*mi).second; + mapNext[pindex->pprev].push_back(pindex); + // test + //while (rand() % 3 == 0) + // mapNext[pindex->pprev].push_back(pindex); + } + + vector > vStack; + vStack.push_back(make_pair(0, pindexGenesisBlock)); + + int nPrevCol = 0; + while (!vStack.empty()) + { + int nCol = vStack.back().first; + CBlockIndex* pindex = vStack.back().second; + vStack.pop_back(); + + // print split or gap + if (nCol > nPrevCol) + { + for (int i = 0; i < nCol-1; i++) + printf("| "); + printf("|\\\n"); + } + else if (nCol < nPrevCol) + { + for (int i = 0; i < nCol; i++) + printf("| "); + printf("|\n"); + } + nPrevCol = nCol; + + // print columns + for (int i = 0; i < nCol; i++) + printf("| "); + + // print item + CBlock block; + block.ReadFromDisk(pindex, true); + printf("%d (%u,%u) %s %s tx %d", + pindex->nHeight, + pindex->nFile, + pindex->nBlockPos, + block.GetHash().ToString().substr(0,14).c_str(), + DateTimeStr(block.nTime).c_str(), + block.vtx.size()); + + CRITICAL_BLOCK(cs_mapWallet) + { + if (mapWallet.count(block.vtx[0].GetHash())) + { + CWalletTx& wtx = mapWallet[block.vtx[0].GetHash()]; + printf(" mine: %d %d %d", wtx.GetDepthInMainChain(), wtx.GetBlocksToMaturity(), wtx.GetCredit()); + } + } + printf("\n"); + + + // put the main timechain first + vector& vNext = mapNext[pindex]; + for (int i = 0; i < vNext.size(); i++) + { + if (vNext[i]->pnext) + { + swap(vNext[0], vNext[i]); + break; + } + } + + // iterate children + for (int i = 0; i < vNext.size(); i++) + vStack.push_back(make_pair(nCol+i, vNext[i])); + } +} + + + + + + + + + + +////////////////////////////////////////////////////////////////////////////// +// +// Messages +// + + +bool AlreadyHave(CTxDB& txdb, const CInv& inv) +{ + switch (inv.type) + { + case MSG_TX: return mapTransactions.count(inv.hash) || txdb.ContainsTx(inv.hash); + case MSG_BLOCK: return mapBlockIndex.count(inv.hash) || mapOrphanBlocks.count(inv.hash); + case MSG_REVIEW: return true; + case MSG_PRODUCT: return mapProducts.count(inv.hash); + } + // Don't know what it is, just say we already got one + return true; +} + + + + + + + +bool ProcessMessages(CNode* pfrom) +{ + CDataStream& vRecv = pfrom->vRecv; + if (vRecv.empty()) + return true; + printf("ProcessMessages(%d bytes)\n", vRecv.size()); + + // + // Message format + // (4) message start + // (12) command + // (4) size + // (x) data + // + + loop + { + // Scan for message start + CDataStream::iterator pstart = search(vRecv.begin(), vRecv.end(), BEGIN(pchMessageStart), END(pchMessageStart)); + if (vRecv.end() - pstart < sizeof(CMessageHeader)) + { + if (vRecv.size() > sizeof(CMessageHeader)) + { + printf("\n\nPROCESSMESSAGE MESSAGESTART NOT FOUND\n\n"); + vRecv.erase(vRecv.begin(), vRecv.end() - sizeof(CMessageHeader)); + } + break; + } + if (pstart - vRecv.begin() > 0) + printf("\n\nPROCESSMESSAGE SKIPPED %d BYTES\n\n", pstart - vRecv.begin()); + vRecv.erase(vRecv.begin(), pstart); + + // Read header + CMessageHeader hdr; + vRecv >> hdr; + if (!hdr.IsValid()) + { + printf("\n\nPROCESSMESSAGE: ERRORS IN HEADER %s\n\n\n", hdr.GetCommand().c_str()); + continue; + } + string strCommand = hdr.GetCommand(); + + // Message size + unsigned int nMessageSize = hdr.nMessageSize; + if (nMessageSize > vRecv.size()) + { + // Rewind and wait for rest of message + ///// need a mechanism to give up waiting for overlong message size error + printf("MESSAGE-BREAK\n"); + vRecv.insert(vRecv.begin(), BEGIN(hdr), END(hdr)); + Sleep(100); + break; + } + + // Copy message to its own buffer + CDataStream vMsg(vRecv.begin(), vRecv.begin() + nMessageSize, vRecv.nType, vRecv.nVersion); + vRecv.ignore(nMessageSize); + + // Process message + bool fRet = false; + try + { + CheckForShutdown(2); + CRITICAL_BLOCK(cs_main) + fRet = ProcessMessage(pfrom, strCommand, vMsg); + CheckForShutdown(2); + } + CATCH_PRINT_EXCEPTION("ProcessMessage()") + if (!fRet) + printf("ProcessMessage(%s, %d bytes) from %s to %s FAILED\n", strCommand.c_str(), nMessageSize, pfrom->addr.ToString().c_str(), addrLocalHost.ToString().c_str()); + } + + vRecv.Compact(); + return true; +} + + + + +bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) +{ + static map > mapReuseKey; + printf("received: %-12s (%d bytes) ", strCommand.c_str(), vRecv.size()); + for (int i = 0; i < min(vRecv.size(), (unsigned int)20); i++) + printf("%02x ", vRecv[i] & 0xff); + printf("\n"); + if (nDropMessagesTest > 0 && GetRand(nDropMessagesTest) == 0) + { + printf("dropmessages DROPPING RECV MESSAGE\n"); + return true; + } + + + + if (strCommand == "version") + { + // Can only do this once + if (pfrom->nVersion != 0) + return false; + + int64 nTime; + CAddress addrMe; + vRecv >> pfrom->nVersion >> pfrom->nServices >> nTime >> addrMe; + if (pfrom->nVersion == 0) + return false; + + pfrom->vSend.SetVersion(min(pfrom->nVersion, VERSION)); + pfrom->vRecv.SetVersion(min(pfrom->nVersion, VERSION)); + + pfrom->fClient = !(pfrom->nServices & NODE_NETWORK); + if (pfrom->fClient) + { + pfrom->vSend.nType |= SER_BLOCKHEADERONLY; + pfrom->vRecv.nType |= SER_BLOCKHEADERONLY; + } + + AddTimeData(pfrom->addr.ip, nTime); + + // Ask the first connected node for block updates + static bool fAskedForBlocks; + if (!fAskedForBlocks && !pfrom->fClient) + { + fAskedForBlocks = true; + pfrom->PushMessage("getblocks", CBlockLocator(pindexBest), uint256(0)); + } + + printf("version message: %s has version %d, addrMe=%s\n", pfrom->addr.ToString().c_str(), pfrom->nVersion, addrMe.ToString().c_str()); + } + + + else if (pfrom->nVersion == 0) + { + // Must have a version message before anything else + return false; + } + + + else if (strCommand == "addr") + { + vector vAddr; + vRecv >> vAddr; + + // Store the new addresses + CAddrDB addrdb; + foreach(const CAddress& addr, vAddr) + { + if (fShutdown) + return true; + if (AddAddress(addrdb, addr)) + { + // Put on lists to send to other nodes + pfrom->setAddrKnown.insert(addr); + CRITICAL_BLOCK(cs_vNodes) + foreach(CNode* pnode, vNodes) + if (!pnode->setAddrKnown.count(addr)) + pnode->vAddrToSend.push_back(addr); + } + } + } + + + else if (strCommand == "inv") + { + vector vInv; + vRecv >> vInv; + + CTxDB txdb("r"); + foreach(const CInv& inv, vInv) + { + if (fShutdown) + return true; + pfrom->AddInventoryKnown(inv); + + bool fAlreadyHave = AlreadyHave(txdb, inv); + printf(" got inventory: %s %s\n", inv.ToString().c_str(), fAlreadyHave ? "have" : "new"); + + if (!fAlreadyHave) + pfrom->AskFor(inv); + else if (inv.type == MSG_BLOCK && mapOrphanBlocks.count(inv.hash)) + pfrom->PushMessage("getblocks", CBlockLocator(pindexBest), GetOrphanRoot(mapOrphanBlocks[inv.hash])); + } + } + + + else if (strCommand == "getdata") + { + vector vInv; + vRecv >> vInv; + + foreach(const CInv& inv, vInv) + { + if (fShutdown) + return true; + printf("received getdata for: %s\n", inv.ToString().c_str()); + + if (inv.type == MSG_BLOCK) + { + // Send block from disk + map::iterator mi = mapBlockIndex.find(inv.hash); + if (mi != mapBlockIndex.end()) + { + //// could optimize this to send header straight from blockindex for client + CBlock block; + block.ReadFromDisk((*mi).second, !pfrom->fClient); + pfrom->PushMessage("block", block); + } + } + else if (inv.IsKnownType()) + { + // Send stream from relay memory + CRITICAL_BLOCK(cs_mapRelay) + { + map::iterator mi = mapRelay.find(inv); + if (mi != mapRelay.end()) + pfrom->PushMessage(inv.GetCommand(), (*mi).second); + } + } + } + } + + + else if (strCommand == "getblocks") + { + CBlockLocator locator; + uint256 hashStop; + vRecv >> locator >> hashStop; + + // Find the first block the caller has in the main chain + CBlockIndex* pindex = locator.GetBlockIndex(); + + // Send the rest of the chain + if (pindex) + pindex = pindex->pnext; + printf("getblocks %d to %s\n", (pindex ? pindex->nHeight : -1), hashStop.ToString().substr(0,14).c_str()); + for (; pindex; pindex = pindex->pnext) + { + if (pindex->GetBlockHash() == hashStop) + { + printf(" getblocks stopping at %d %s\n", pindex->nHeight, pindex->GetBlockHash().ToString().substr(0,14).c_str()); + break; + } + + // Bypass setInventoryKnown in case an inventory message got lost + CRITICAL_BLOCK(pfrom->cs_inventory) + { + CInv inv(MSG_BLOCK, pindex->GetBlockHash()); + // returns true if wasn't already contained in the set + if (pfrom->setInventoryKnown2.insert(inv).second) + { + pfrom->setInventoryKnown.erase(inv); + pfrom->vInventoryToSend.push_back(inv); + } + } + } + } + + + else if (strCommand == "tx") + { + vector vWorkQueue; + CDataStream vMsg(vRecv); + CTransaction tx; + vRecv >> tx; + + CInv inv(MSG_TX, tx.GetHash()); + pfrom->AddInventoryKnown(inv); + + bool fMissingInputs = false; + if (tx.AcceptTransaction(true, &fMissingInputs)) + { + AddToWalletIfMine(tx, NULL); + RelayMessage(inv, vMsg); + mapAlreadyAskedFor.erase(inv); + vWorkQueue.push_back(inv.hash); + + // Recursively process any orphan transactions that depended on this one + for (int i = 0; i < vWorkQueue.size(); i++) + { + uint256 hashPrev = vWorkQueue[i]; + for (multimap::iterator mi = mapOrphanTransactionsByPrev.lower_bound(hashPrev); + mi != mapOrphanTransactionsByPrev.upper_bound(hashPrev); + ++mi) + { + const CDataStream& vMsg = *((*mi).second); + CTransaction tx; + CDataStream(vMsg) >> tx; + CInv inv(MSG_TX, tx.GetHash()); + + if (tx.AcceptTransaction(true)) + { + printf(" accepted orphan tx %s\n", inv.hash.ToString().substr(0,6).c_str()); + AddToWalletIfMine(tx, NULL); + RelayMessage(inv, vMsg); + mapAlreadyAskedFor.erase(inv); + vWorkQueue.push_back(inv.hash); + } + } + } + + foreach(uint256 hash, vWorkQueue) + EraseOrphanTx(hash); + } + else if (fMissingInputs) + { + printf("storing orphan tx %s\n", inv.hash.ToString().substr(0,6).c_str()); + AddOrphanTx(vMsg); + } + } + + + else if (strCommand == "review") + { + CDataStream vMsg(vRecv); + CReview review; + vRecv >> review; + + CInv inv(MSG_REVIEW, review.GetHash()); + pfrom->AddInventoryKnown(inv); + + if (review.AcceptReview()) + { + // Relay the original message as-is in case it's a higher version than we know how to parse + RelayMessage(inv, vMsg); + mapAlreadyAskedFor.erase(inv); + } + } + + + else if (strCommand == "block") + { + auto_ptr pblock(new CBlock); + vRecv >> *pblock; + + //// debug print + printf("received block:\n"); pblock->print(); + + CInv inv(MSG_BLOCK, pblock->GetHash()); + pfrom->AddInventoryKnown(inv); + + if (ProcessBlock(pfrom, pblock.release())) + mapAlreadyAskedFor.erase(inv); + } + + + else if (strCommand == "getaddr") + { + pfrom->vAddrToSend.clear(); + int64 nSince = GetAdjustedTime() - 5 * 24 * 60 * 60; // in the last 5 days + CRITICAL_BLOCK(cs_mapAddresses) + { + unsigned int nSize = mapAddresses.size(); + foreach(const PAIRTYPE(vector, CAddress)& item, mapAddresses) + { + if (fShutdown) + return true; + const CAddress& addr = item.second; + //// will need this if we lose IRC + //if (addr.nTime > nSince || (rand() % nSize) < 500) + if (addr.nTime > nSince) + pfrom->vAddrToSend.push_back(addr); + } + } + } + + + else if (strCommand == "checkorder") + { + uint256 hashReply; + CWalletTx order; + vRecv >> hashReply >> order; + + /// we have a chance to check the order here + + // Keep giving the same key to the same ip until they use it + if (!mapReuseKey.count(pfrom->addr.ip)) + mapReuseKey[pfrom->addr.ip] = GenerateNewKey(); + + // Send back approval of order and pubkey to use + CScript scriptPubKey; + scriptPubKey << mapReuseKey[pfrom->addr.ip] << OP_CHECKSIG; + pfrom->PushMessage("reply", hashReply, (int)0, scriptPubKey); + } + + + else if (strCommand == "submitorder") + { + uint256 hashReply; + CWalletTx wtxNew; + vRecv >> hashReply >> wtxNew; + + // Broadcast + if (!wtxNew.AcceptWalletTransaction()) + { + pfrom->PushMessage("reply", hashReply, (int)1); + return error("submitorder AcceptWalletTransaction() failed, returning error 1"); + } + wtxNew.fTimeReceivedIsTxTime = true; + AddToWallet(wtxNew); + wtxNew.RelayWalletTransaction(); + mapReuseKey.erase(pfrom->addr.ip); + + // Send back confirmation + pfrom->PushMessage("reply", hashReply, (int)0); + } + + + else if (strCommand == "reply") + { + uint256 hashReply; + vRecv >> hashReply; + + CRequestTracker tracker; + CRITICAL_BLOCK(pfrom->cs_mapRequests) + { + map::iterator mi = pfrom->mapRequests.find(hashReply); + if (mi != pfrom->mapRequests.end()) + { + tracker = (*mi).second; + pfrom->mapRequests.erase(mi); + } + } + if (!tracker.IsNull()) + tracker.fn(tracker.param1, vRecv); + } + + + else + { + // Ignore unknown commands for extensibility + printf("ProcessMessage(%s) : Ignored unknown message\n", strCommand.c_str()); + } + + + if (!vRecv.empty()) + printf("ProcessMessage(%s) : %d extra bytes\n", strCommand.c_str(), vRecv.size()); + + return true; +} + + + + + + + + + +bool SendMessages(CNode* pto) +{ + CheckForShutdown(2); + CRITICAL_BLOCK(cs_main) + { + // Don't send anything until we get their version message + if (pto->nVersion == 0) + return true; + + + // + // Message: addr + // + vector vAddrToSend; + vAddrToSend.reserve(pto->vAddrToSend.size()); + foreach(const CAddress& addr, pto->vAddrToSend) + if (!pto->setAddrKnown.count(addr)) + vAddrToSend.push_back(addr); + pto->vAddrToSend.clear(); + if (!vAddrToSend.empty()) + pto->PushMessage("addr", vAddrToSend); + + + // + // Message: inventory + // + vector vInventoryToSend; + CRITICAL_BLOCK(pto->cs_inventory) + { + vInventoryToSend.reserve(pto->vInventoryToSend.size()); + foreach(const CInv& inv, pto->vInventoryToSend) + { + // returns true if wasn't already contained in the set + if (pto->setInventoryKnown.insert(inv).second) + vInventoryToSend.push_back(inv); + } + pto->vInventoryToSend.clear(); + pto->setInventoryKnown2.clear(); + } + if (!vInventoryToSend.empty()) + pto->PushMessage("inv", vInventoryToSend); + + + // + // Message: getdata + // + vector vAskFor; + int64 nNow = GetTime() * 1000000; + CTxDB txdb("r"); + while (!pto->mapAskFor.empty() && (*pto->mapAskFor.begin()).first <= nNow) + { + const CInv& inv = (*pto->mapAskFor.begin()).second; + printf("sending getdata: %s\n", inv.ToString().c_str()); + if (!AlreadyHave(txdb, inv)) + vAskFor.push_back(inv); + pto->mapAskFor.erase(pto->mapAskFor.begin()); + } + if (!vAskFor.empty()) + pto->PushMessage("getdata", vAskFor); + + } + return true; +} + + + + + + + + + + + + + + +////////////////////////////////////////////////////////////////////////////// +// +// BitcoinMiner +// + +int FormatHashBlocks(void* pbuffer, unsigned int len) +{ + unsigned char* pdata = (unsigned char*)pbuffer; + unsigned int blocks = 1 + ((len + 8) / 64); + unsigned char* pend = pdata + 64 * blocks; + memset(pdata + len, 0, 64 * blocks - len); + pdata[len] = 0x80; + unsigned int bits = len * 8; + pend[-1] = (bits >> 0) & 0xff; + pend[-2] = (bits >> 8) & 0xff; + pend[-3] = (bits >> 16) & 0xff; + pend[-4] = (bits >> 24) & 0xff; + return blocks; +} + +using CryptoPP::ByteReverse; +static int detectlittleendian = 1; + +void BlockSHA256(const void* pin, unsigned int nBlocks, void* pout) +{ + unsigned int* pinput = (unsigned int*)pin; + unsigned int* pstate = (unsigned int*)pout; + + CryptoPP::SHA256::InitState(pstate); + + if (*(char*)&detectlittleendian != 0) + { + for (int n = 0; n < nBlocks; n++) + { + unsigned int pbuf[16]; + for (int i = 0; i < 16; i++) + pbuf[i] = ByteReverse(pinput[n * 16 + i]); + CryptoPP::SHA256::Transform(pstate, pbuf); + } + for (int i = 0; i < 8; i++) + pstate[i] = ByteReverse(pstate[i]); + } + else + { + for (int n = 0; n < nBlocks; n++) + CryptoPP::SHA256::Transform(pstate, pinput + n * 16); + } +} + + +bool BitcoinMiner() +{ + printf("BitcoinMiner started\n"); + SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_LOWEST); + + CKey key; + key.MakeNewKey(); + CBigNum bnExtraNonce = 0; + while (fGenerateBitcoins) + { + Sleep(50); + CheckForShutdown(3); + while (vNodes.empty()) + { + Sleep(1000); + CheckForShutdown(3); + } + + unsigned int nTransactionsUpdatedLast = nTransactionsUpdated; + CBlockIndex* pindexPrev = pindexBest; + unsigned int nBits = GetNextWorkRequired(pindexPrev); + + + // + // Create coinbase tx + // + CTransaction txNew; + txNew.vin.resize(1); + txNew.vin[0].prevout.SetNull(); + txNew.vin[0].scriptSig << nBits << ++bnExtraNonce; + txNew.vout.resize(1); + txNew.vout[0].scriptPubKey << key.GetPubKey() << OP_CHECKSIG; + + + // + // Create new block + // + auto_ptr pblock(new CBlock()); + if (!pblock.get()) + return false; + + // Add our coinbase tx as first transaction + pblock->vtx.push_back(txNew); + + // Collect the latest transactions into the block + int64 nFees = 0; + CRITICAL_BLOCK(cs_main) + CRITICAL_BLOCK(cs_mapTransactions) + { + CTxDB txdb("r"); + map mapTestPool; + vector vfAlreadyAdded(mapTransactions.size()); + bool fFoundSomething = true; + unsigned int nBlockSize = 0; + while (fFoundSomething && nBlockSize < MAX_SIZE/2) + { + fFoundSomething = false; + unsigned int n = 0; + for (map::iterator mi = mapTransactions.begin(); mi != mapTransactions.end(); ++mi, ++n) + { + if (vfAlreadyAdded[n]) + continue; + CTransaction& tx = (*mi).second; + if (tx.IsCoinBase() || !tx.IsFinal()) + continue; + + // Transaction fee requirements, mainly only needed for flood control + // Under 10K (about 80 inputs) is free for first 100 transactions + // Base rate is 0.01 per KB + int64 nMinFee = tx.GetMinFee(pblock->vtx.size() < 100); + + map mapTestPoolTmp(mapTestPool); + if (!tx.ConnectInputs(txdb, mapTestPoolTmp, CDiskTxPos(1,1,1), 0, nFees, false, true, nMinFee)) + continue; + swap(mapTestPool, mapTestPoolTmp); + + pblock->vtx.push_back(tx); + nBlockSize += ::GetSerializeSize(tx, SER_NETWORK); + vfAlreadyAdded[n] = true; + fFoundSomething = true; + } + } + } + pblock->nBits = nBits; + pblock->vtx[0].vout[0].nValue = pblock->GetBlockValue(nFees); + printf("\n\nRunning BitcoinMiner with %d transactions in block\n", pblock->vtx.size()); + + + // + // Prebuild hash buffer + // + struct unnamed1 + { + struct unnamed2 + { + int nVersion; + uint256 hashPrevBlock; + uint256 hashMerkleRoot; + unsigned int nTime; + unsigned int nBits; + unsigned int nNonce; + } + block; + unsigned char pchPadding0[64]; + uint256 hash1; + unsigned char pchPadding1[64]; + } + tmp; + + tmp.block.nVersion = pblock->nVersion; + tmp.block.hashPrevBlock = pblock->hashPrevBlock = (pindexPrev ? pindexPrev->GetBlockHash() : 0); + tmp.block.hashMerkleRoot = pblock->hashMerkleRoot = pblock->BuildMerkleTree(); + tmp.block.nTime = pblock->nTime = max((pindexPrev ? pindexPrev->GetMedianTimePast()+1 : 0), GetAdjustedTime()); + tmp.block.nBits = pblock->nBits = nBits; + tmp.block.nNonce = pblock->nNonce = 1; + + unsigned int nBlocks0 = FormatHashBlocks(&tmp.block, sizeof(tmp.block)); + unsigned int nBlocks1 = FormatHashBlocks(&tmp.hash1, sizeof(tmp.hash1)); + + + // + // Search + // + unsigned int nStart = GetTime(); + uint256 hashTarget = CBigNum().SetCompact(pblock->nBits).getuint256(); + uint256 hash; + loop + { + BlockSHA256(&tmp.block, nBlocks0, &tmp.hash1); + BlockSHA256(&tmp.hash1, nBlocks1, &hash); + + + if (hash <= hashTarget) + { + pblock->nNonce = tmp.block.nNonce; + assert(hash == pblock->GetHash()); + + //// debug print + printf("BitcoinMiner:\n"); + printf("proof-of-work found \n hash: %s \ntarget: %s\n", hash.GetHex().c_str(), hashTarget.GetHex().c_str()); + pblock->print(); + + SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_NORMAL); + CRITICAL_BLOCK(cs_main) + { + // Save key + if (!AddKey(key)) + return false; + key.MakeNewKey(); + + // Process this block the same as if we had received it from another node + if (!ProcessBlock(NULL, pblock.release())) + printf("ERROR in BitcoinMiner, ProcessBlock, block not accepted\n"); + } + SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_LOWEST); + + Sleep(500); + break; + } + + // Update nTime every few seconds + if ((++tmp.block.nNonce & 0x3ffff) == 0) + { + CheckForShutdown(3); + if (tmp.block.nNonce == 0) + break; + if (pindexPrev != pindexBest) + break; + if (nTransactionsUpdated != nTransactionsUpdatedLast && GetTime() - nStart > 60) + break; + if (!fGenerateBitcoins) + break; + tmp.block.nTime = pblock->nTime = max(pindexPrev->GetMedianTimePast()+1, GetAdjustedTime()); + } + } + } + + return true; +} + + + + + + + + + + + + + + + + + + +////////////////////////////////////////////////////////////////////////////// +// +// Actions +// + + +int64 GetBalance() +{ + int64 nStart, nEnd; + QueryPerformanceCounter((LARGE_INTEGER*)&nStart); + + int64 nTotal = 0; + CRITICAL_BLOCK(cs_mapWallet) + { + for (map::iterator it = mapWallet.begin(); it != mapWallet.end(); ++it) + { + CWalletTx* pcoin = &(*it).second; + if (!pcoin->IsFinal() || pcoin->fSpent) + continue; + nTotal += pcoin->GetCredit(); + } + } + + QueryPerformanceCounter((LARGE_INTEGER*)&nEnd); + ///printf(" GetBalance() time = %16I64d\n", nEnd - nStart); + return nTotal; +} + + + +bool SelectCoins(int64 nTargetValue, set& setCoinsRet) +{ + setCoinsRet.clear(); + + // List of values less than target + int64 nLowestLarger = _I64_MAX; + CWalletTx* pcoinLowestLarger = NULL; + vector > vValue; + int64 nTotalLower = 0; + + CRITICAL_BLOCK(cs_mapWallet) + { + for (map::iterator it = mapWallet.begin(); it != mapWallet.end(); ++it) + { + CWalletTx* pcoin = &(*it).second; + if (!pcoin->IsFinal() || pcoin->fSpent) + continue; + int64 n = pcoin->GetCredit(); + if (n <= 0) + continue; + if (n < nTargetValue) + { + vValue.push_back(make_pair(n, pcoin)); + nTotalLower += n; + } + else if (n == nTargetValue) + { + setCoinsRet.insert(pcoin); + return true; + } + else if (n < nLowestLarger) + { + nLowestLarger = n; + pcoinLowestLarger = pcoin; + } + } + } + + if (nTotalLower < nTargetValue) + { + if (pcoinLowestLarger == NULL) + return false; + setCoinsRet.insert(pcoinLowestLarger); + return true; + } + + // Solve subset sum by stochastic approximation + sort(vValue.rbegin(), vValue.rend()); + vector vfIncluded; + vector vfBest(vValue.size(), true); + int64 nBest = nTotalLower; + + for (int nRep = 0; nRep < 1000 && nBest != nTargetValue; nRep++) + { + vfIncluded.assign(vValue.size(), false); + int64 nTotal = 0; + bool fReachedTarget = false; + for (int nPass = 0; nPass < 2 && !fReachedTarget; nPass++) + { + for (int i = 0; i < vValue.size(); i++) + { + if (nPass == 0 ? rand() % 2 : !vfIncluded[i]) + { + nTotal += vValue[i].first; + vfIncluded[i] = true; + if (nTotal >= nTargetValue) + { + fReachedTarget = true; + if (nTotal < nBest) + { + nBest = nTotal; + vfBest = vfIncluded; + } + nTotal -= vValue[i].first; + vfIncluded[i] = false; + } + } + } + } + } + + // If the next larger is still closer, return it + if (pcoinLowestLarger && nLowestLarger - nTargetValue <= nBest - nTargetValue) + setCoinsRet.insert(pcoinLowestLarger); + else + { + for (int i = 0; i < vValue.size(); i++) + if (vfBest[i]) + setCoinsRet.insert(vValue[i].second); + + //// debug print + printf("SelectCoins() best subset: "); + for (int i = 0; i < vValue.size(); i++) + if (vfBest[i]) + printf("%s ", FormatMoney(vValue[i].first).c_str()); + printf("total %s\n", FormatMoney(nBest).c_str()); + } + + return true; +} + + + + +bool CreateTransaction(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew, int64& nFeeRequiredRet) +{ + nFeeRequiredRet = 0; + CRITICAL_BLOCK(cs_main) + { + // txdb must be opened before the mapWallet lock + CTxDB txdb("r"); + CRITICAL_BLOCK(cs_mapWallet) + { + int64 nFee = nTransactionFee; + loop + { + wtxNew.vin.clear(); + wtxNew.vout.clear(); + if (nValue < 0) + return false; + int64 nValueOut = nValue; + nValue += nFee; + + // Choose coins to use + set setCoins; + if (!SelectCoins(nValue, setCoins)) + return false; + int64 nValueIn = 0; + foreach(CWalletTx* pcoin, setCoins) + nValueIn += pcoin->GetCredit(); + + // Fill vout[0] to the payee + wtxNew.vout.push_back(CTxOut(nValueOut, scriptPubKey)); + + // Fill vout[1] back to self with any change + if (nValueIn > nValue) + { + /// todo: for privacy, should randomize the order of outputs, + // would also have to use a new key for the change. + // Use the same key as one of the coins + vector vchPubKey; + CTransaction& txFirst = *(*setCoins.begin()); + foreach(const CTxOut& txout, txFirst.vout) + if (txout.IsMine()) + if (ExtractPubKey(txout.scriptPubKey, true, vchPubKey)) + break; + if (vchPubKey.empty()) + return false; + + // Fill vout[1] to ourself + CScript scriptPubKey; + scriptPubKey << vchPubKey << OP_CHECKSIG; + wtxNew.vout.push_back(CTxOut(nValueIn - nValue, scriptPubKey)); + } + + // Fill vin + foreach(CWalletTx* pcoin, setCoins) + for (int nOut = 0; nOut < pcoin->vout.size(); nOut++) + if (pcoin->vout[nOut].IsMine()) + wtxNew.vin.push_back(CTxIn(pcoin->GetHash(), nOut)); + + // Sign + int nIn = 0; + foreach(CWalletTx* pcoin, setCoins) + for (int nOut = 0; nOut < pcoin->vout.size(); nOut++) + if (pcoin->vout[nOut].IsMine()) + SignSignature(*pcoin, wtxNew, nIn++); + + // Check that enough fee is included + if (nFee < wtxNew.GetMinFee(true)) + { + nFee = nFeeRequiredRet = wtxNew.GetMinFee(true); + continue; + } + + // Fill vtxPrev by copying from previous transactions vtxPrev + wtxNew.AddSupportingTransactions(txdb); + wtxNew.fTimeReceivedIsTxTime = true; + + break; + } + } + } + return true; +} + +// Call after CreateTransaction unless you want to abort +bool CommitTransactionSpent(const CWalletTx& wtxNew) +{ + CRITICAL_BLOCK(cs_main) + CRITICAL_BLOCK(cs_mapWallet) + { + //// todo: make this transactional, never want to add a transaction + //// without marking spent transactions + + // Add tx to wallet, because if it has change it's also ours, + // otherwise just for transaction history. + AddToWallet(wtxNew); + + // Mark old coins as spent + set setCoins; + foreach(const CTxIn& txin, wtxNew.vin) + setCoins.insert(&mapWallet[txin.prevout.hash]); + foreach(CWalletTx* pcoin, setCoins) + { + pcoin->fSpent = true; + pcoin->WriteToDisk(); + vWalletUpdated.push_back(make_pair(pcoin->GetHash(), false)); + } + } + MainFrameRepaint(); + return true; +} + + + + +bool SendMoney(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew) +{ + CRITICAL_BLOCK(cs_main) + { + int64 nFeeRequired; + if (!CreateTransaction(scriptPubKey, nValue, wtxNew, nFeeRequired)) + { + string strError; + if (nValue + nFeeRequired > GetBalance()) + strError = strprintf("Error: This is an oversized transaction that requires a transaction fee of %s ", FormatMoney(nFeeRequired).c_str()); + else + strError = "Error: Transaction creation failed "; + wxMessageBox(strError, "Sending..."); + return error("SendMoney() : %s\n", strError.c_str()); + } + if (!CommitTransactionSpent(wtxNew)) + { + wxMessageBox("Error finalizing transaction ", "Sending..."); + return error("SendMoney() : Error finalizing transaction"); + } + + printf("SendMoney: %s\n", wtxNew.GetHash().ToString().substr(0,6).c_str()); + + // Broadcast + if (!wtxNew.AcceptTransaction()) + { + // This must not fail. The transaction has already been signed and recorded. + throw runtime_error("SendMoney() : wtxNew.AcceptTransaction() failed\n"); + wxMessageBox("Error: Transaction not valid ", "Sending..."); + return error("SendMoney() : Error: Transaction not valid"); + } + wtxNew.RelayWalletTransaction(); + } + MainFrameRepaint(); + return true; +} diff --git a/main.h b/main.h new file mode 100644 index 0000000000..3432b316e7 --- /dev/null +++ b/main.h @@ -0,0 +1,1329 @@ +// Copyright (c) 2009 Satoshi Nakamoto +// Distributed under the MIT/X11 software license, see the accompanying +// file license.txt or http://www.opensource.org/licenses/mit-license.php. + +class COutPoint; +class CInPoint; +class CDiskTxPos; +class CCoinBase; +class CTxIn; +class CTxOut; +class CTransaction; +class CBlock; +class CBlockIndex; +class CWalletTx; +class CKeyItem; + +static const unsigned int MAX_SIZE = 0x02000000; +static const int64 COIN = 100000000; +static const int64 CENT = 1000000; +static const int COINBASE_MATURITY = 100; + +static const CBigNum bnProofOfWorkLimit(~uint256(0) >> 32); + + + + + + +extern CCriticalSection cs_main; +extern map mapBlockIndex; +extern const uint256 hashGenesisBlock; +extern CBlockIndex* pindexGenesisBlock; +extern int nBestHeight; +extern uint256 hashBestChain; +extern CBlockIndex* pindexBest; +extern unsigned int nTransactionsUpdated; +extern string strSetDataDir; +extern int nDropMessagesTest; + +// Settings +extern int fGenerateBitcoins; +extern int64 nTransactionFee; +extern CAddress addrIncoming; + + + + + + + +string GetAppDir(); +bool CheckDiskSpace(int64 nAdditionalBytes=0); +FILE* OpenBlockFile(unsigned int nFile, unsigned int nBlockPos, const char* pszMode="rb"); +FILE* AppendBlockFile(unsigned int& nFileRet); +bool AddKey(const CKey& key); +vector GenerateNewKey(); +bool AddToWallet(const CWalletTx& wtxIn); +void ReacceptWalletTransactions(); +void RelayWalletTransactions(); +bool LoadBlockIndex(bool fAllowNew=true); +void PrintBlockTree(); +bool BitcoinMiner(); +bool ProcessMessages(CNode* pfrom); +bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv); +bool SendMessages(CNode* pto); +int64 GetBalance(); +bool CreateTransaction(CScript scriptPubKey, int64 nValue, CWalletTx& txNew, int64& nFeeRequiredRet); +bool CommitTransactionSpent(const CWalletTx& wtxNew); +bool SendMoney(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew); + + + + + + + + + + + +class CDiskTxPos +{ +public: + unsigned int nFile; + unsigned int nBlockPos; + unsigned int nTxPos; + + CDiskTxPos() + { + SetNull(); + } + + CDiskTxPos(unsigned int nFileIn, unsigned int nBlockPosIn, unsigned int nTxPosIn) + { + nFile = nFileIn; + nBlockPos = nBlockPosIn; + nTxPos = nTxPosIn; + } + + IMPLEMENT_SERIALIZE( READWRITE(FLATDATA(*this)); ) + void SetNull() { nFile = -1; nBlockPos = 0; nTxPos = 0; } + bool IsNull() const { return (nFile == -1); } + + friend bool operator==(const CDiskTxPos& a, const CDiskTxPos& b) + { + return (a.nFile == b.nFile && + a.nBlockPos == b.nBlockPos && + a.nTxPos == b.nTxPos); + } + + friend bool operator!=(const CDiskTxPos& a, const CDiskTxPos& b) + { + return !(a == b); + } + + string ToString() const + { + if (IsNull()) + return strprintf("null"); + else + return strprintf("(nFile=%d, nBlockPos=%d, nTxPos=%d)", nFile, nBlockPos, nTxPos); + } + + void print() const + { + printf("%s", ToString().c_str()); + } +}; + + + + +class CInPoint +{ +public: + CTransaction* ptx; + unsigned int n; + + CInPoint() { SetNull(); } + CInPoint(CTransaction* ptxIn, unsigned int nIn) { ptx = ptxIn; n = nIn; } + void SetNull() { ptx = NULL; n = -1; } + bool IsNull() const { return (ptx == NULL && n == -1); } +}; + + + + +class COutPoint +{ +public: + uint256 hash; + unsigned int n; + + COutPoint() { SetNull(); } + COutPoint(uint256 hashIn, unsigned int nIn) { hash = hashIn; n = nIn; } + IMPLEMENT_SERIALIZE( READWRITE(FLATDATA(*this)); ) + void SetNull() { hash = 0; n = -1; } + bool IsNull() const { return (hash == 0 && n == -1); } + + friend bool operator<(const COutPoint& a, const COutPoint& b) + { + return (a.hash < b.hash || (a.hash == b.hash && a.n < b.n)); + } + + friend bool operator==(const COutPoint& a, const COutPoint& b) + { + return (a.hash == b.hash && a.n == b.n); + } + + friend bool operator!=(const COutPoint& a, const COutPoint& b) + { + return !(a == b); + } + + string ToString() const + { + return strprintf("COutPoint(%s, %d)", hash.ToString().substr(0,6).c_str(), n); + } + + void print() const + { + printf("%s\n", ToString().c_str()); + } +}; + + + + +// +// An input of a transaction. It contains the location of the previous +// transaction's output that it claims and a signature that matches the +// output's public key. +// +class CTxIn +{ +public: + COutPoint prevout; + CScript scriptSig; + unsigned int nSequence; + + CTxIn() + { + nSequence = UINT_MAX; + } + + explicit CTxIn(COutPoint prevoutIn, CScript scriptSigIn=CScript(), unsigned int nSequenceIn=UINT_MAX) + { + prevout = prevoutIn; + scriptSig = scriptSigIn; + nSequence = nSequenceIn; + } + + CTxIn(uint256 hashPrevTx, unsigned int nOut, CScript scriptSigIn=CScript(), unsigned int nSequenceIn=UINT_MAX) + { + prevout = COutPoint(hashPrevTx, nOut); + scriptSig = scriptSigIn; + nSequence = nSequenceIn; + } + + IMPLEMENT_SERIALIZE + ( + READWRITE(prevout); + READWRITE(scriptSig); + READWRITE(nSequence); + ) + + bool IsFinal() const + { + return (nSequence == UINT_MAX); + } + + friend bool operator==(const CTxIn& a, const CTxIn& b) + { + return (a.prevout == b.prevout && + a.scriptSig == b.scriptSig && + a.nSequence == b.nSequence); + } + + friend bool operator!=(const CTxIn& a, const CTxIn& b) + { + return !(a == b); + } + + string ToString() const + { + string str; + str += strprintf("CTxIn("); + str += prevout.ToString(); + if (prevout.IsNull()) + str += strprintf(", coinbase %s", HexStr(scriptSig.begin(), scriptSig.end(), false).c_str()); + else + str += strprintf(", scriptSig=%s", scriptSig.ToString().substr(0,24).c_str()); + if (nSequence != UINT_MAX) + str += strprintf(", nSequence=%u", nSequence); + str += ")"; + return str; + } + + void print() const + { + printf("%s\n", ToString().c_str()); + } + + bool IsMine() const; + int64 GetDebit() const; +}; + + + + +// +// An output of a transaction. It contains the public key that the next input +// must be able to sign with to claim it. +// +class CTxOut +{ +public: + int64 nValue; + CScript scriptPubKey; + +public: + CTxOut() + { + SetNull(); + } + + CTxOut(int64 nValueIn, CScript scriptPubKeyIn) + { + nValue = nValueIn; + scriptPubKey = scriptPubKeyIn; + } + + IMPLEMENT_SERIALIZE + ( + READWRITE(nValue); + READWRITE(scriptPubKey); + ) + + void SetNull() + { + nValue = -1; + scriptPubKey.clear(); + } + + bool IsNull() + { + return (nValue == -1); + } + + uint256 GetHash() const + { + return SerializeHash(*this); + } + + bool IsMine() const + { + return ::IsMine(scriptPubKey); + } + + int64 GetCredit() const + { + if (IsMine()) + return nValue; + return 0; + } + + friend bool operator==(const CTxOut& a, const CTxOut& b) + { + return (a.nValue == b.nValue && + a.scriptPubKey == b.scriptPubKey); + } + + friend bool operator!=(const CTxOut& a, const CTxOut& b) + { + return !(a == b); + } + + string ToString() const + { + if (scriptPubKey.size() < 6) + return "CTxOut(error)"; + return strprintf("CTxOut(nValue=%I64d.%08I64d, scriptPubKey=%s)", nValue / COIN, nValue % COIN, scriptPubKey.ToString().substr(0,24).c_str()); + } + + void print() const + { + printf("%s\n", ToString().c_str()); + } +}; + + + + +// +// The basic transaction that is broadcasted on the network and contained in +// blocks. A transaction can contain multiple inputs and outputs. +// +class CTransaction +{ +public: + int nVersion; + vector vin; + vector vout; + int nLockTime; + + + CTransaction() + { + SetNull(); + } + + IMPLEMENT_SERIALIZE + ( + READWRITE(this->nVersion); + nVersion = this->nVersion; + READWRITE(vin); + READWRITE(vout); + READWRITE(nLockTime); + ) + + void SetNull() + { + nVersion = 1; + vin.clear(); + vout.clear(); + nLockTime = 0; + } + + bool IsNull() const + { + return (vin.empty() && vout.empty()); + } + + uint256 GetHash() const + { + return SerializeHash(*this); + } + + bool IsFinal() const + { + if (nLockTime == 0 || nLockTime < nBestHeight) + return true; + foreach(const CTxIn& txin, vin) + if (!txin.IsFinal()) + return false; + return true; + } + + bool IsNewerThan(const CTransaction& old) const + { + if (vin.size() != old.vin.size()) + return false; + for (int i = 0; i < vin.size(); i++) + if (vin[i].prevout != old.vin[i].prevout) + return false; + + bool fNewer = false; + unsigned int nLowest = UINT_MAX; + for (int i = 0; i < vin.size(); i++) + { + if (vin[i].nSequence != old.vin[i].nSequence) + { + if (vin[i].nSequence <= nLowest) + { + fNewer = false; + nLowest = vin[i].nSequence; + } + if (old.vin[i].nSequence < nLowest) + { + fNewer = true; + nLowest = old.vin[i].nSequence; + } + } + } + return fNewer; + } + + bool IsCoinBase() const + { + return (vin.size() == 1 && vin[0].prevout.IsNull()); + } + + bool CheckTransaction() const + { + // Basic checks that don't depend on any context + if (vin.empty() || vout.empty()) + return error("CTransaction::CheckTransaction() : vin or vout empty"); + + // Check for negative values + foreach(const CTxOut& txout, vout) + if (txout.nValue < 0) + return error("CTransaction::CheckTransaction() : txout.nValue negative"); + + if (IsCoinBase()) + { + if (vin[0].scriptSig.size() < 2 || vin[0].scriptSig.size() > 100) + return error("CTransaction::CheckTransaction() : coinbase script size"); + } + else + { + foreach(const CTxIn& txin, vin) + if (txin.prevout.IsNull()) + return error("CTransaction::CheckTransaction() : prevout is null"); + } + + return true; + } + + bool IsMine() const + { + foreach(const CTxOut& txout, vout) + if (txout.IsMine()) + return true; + return false; + } + + int64 GetDebit() const + { + int64 nDebit = 0; + foreach(const CTxIn& txin, vin) + nDebit += txin.GetDebit(); + return nDebit; + } + + int64 GetCredit() const + { + int64 nCredit = 0; + foreach(const CTxOut& txout, vout) + nCredit += txout.GetCredit(); + return nCredit; + } + + int64 GetValueOut() const + { + int64 nValueOut = 0; + foreach(const CTxOut& txout, vout) + { + if (txout.nValue < 0) + throw runtime_error("CTransaction::GetValueOut() : negative value"); + nValueOut += txout.nValue; + } + return nValueOut; + } + + int64 GetMinFee(bool fDiscount=false) const + { + // Base fee is 1 cent per kilobyte + unsigned int nBytes = ::GetSerializeSize(*this, SER_NETWORK); + int64 nMinFee = (1 + (int64)nBytes / 1000) * CENT; + + // First 100 transactions in a block are free + if (fDiscount && nBytes < 10000) + nMinFee = 0; + + // To limit dust spam, require a 0.01 fee if any output is less than 0.01 + if (nMinFee < CENT) + foreach(const CTxOut& txout, vout) + if (txout.nValue < CENT) + nMinFee = CENT; + + return nMinFee; + } + + + + bool ReadFromDisk(CDiskTxPos pos, FILE** pfileRet=NULL) + { + CAutoFile filein = OpenBlockFile(pos.nFile, 0, pfileRet ? "rb+" : "rb"); + if (!filein) + return error("CTransaction::ReadFromDisk() : OpenBlockFile failed"); + + // Read transaction + if (fseek(filein, pos.nTxPos, SEEK_SET) != 0) + return error("CTransaction::ReadFromDisk() : fseek failed"); + filein >> *this; + + // Return file pointer + if (pfileRet) + { + if (fseek(filein, pos.nTxPos, SEEK_SET) != 0) + return error("CTransaction::ReadFromDisk() : second fseek failed"); + *pfileRet = filein.release(); + } + return true; + } + + + friend bool operator==(const CTransaction& a, const CTransaction& b) + { + return (a.nVersion == b.nVersion && + a.vin == b.vin && + a.vout == b.vout && + a.nLockTime == b.nLockTime); + } + + friend bool operator!=(const CTransaction& a, const CTransaction& b) + { + return !(a == b); + } + + + string ToString() const + { + string str; + str += strprintf("CTransaction(hash=%s, ver=%d, vin.size=%d, vout.size=%d, nLockTime=%d)\n", + GetHash().ToString().substr(0,6).c_str(), + nVersion, + vin.size(), + vout.size(), + nLockTime); + for (int i = 0; i < vin.size(); i++) + str += " " + vin[i].ToString() + "\n"; + for (int i = 0; i < vout.size(); i++) + str += " " + vout[i].ToString() + "\n"; + return str; + } + + void print() const + { + printf("%s", ToString().c_str()); + } + + + + bool DisconnectInputs(CTxDB& txdb); + bool ConnectInputs(CTxDB& txdb, map& mapTestPool, CDiskTxPos posThisTx, int nHeight, int64& nFees, bool fBlock, bool fMiner, int64 nMinFee=0); + bool ClientConnectInputs(); + + bool AcceptTransaction(CTxDB& txdb, bool fCheckInputs=true, bool* pfMissingInputs=NULL); + + bool AcceptTransaction(bool fCheckInputs=true, bool* pfMissingInputs=NULL) + { + CTxDB txdb("r"); + return AcceptTransaction(txdb, fCheckInputs, pfMissingInputs); + } + +protected: + bool AddToMemoryPool(); +public: + bool RemoveFromMemoryPool(); +}; + + + + + +// +// A transaction with a merkle branch linking it to the block chain +// +class CMerkleTx : public CTransaction +{ +public: + uint256 hashBlock; + vector vMerkleBranch; + int nIndex; + + // memory only + mutable bool fMerkleVerified; + + + CMerkleTx() + { + Init(); + } + + CMerkleTx(const CTransaction& txIn) : CTransaction(txIn) + { + Init(); + } + + void Init() + { + hashBlock = 0; + nIndex = -1; + fMerkleVerified = false; + } + + int64 GetCredit() const + { + // Must wait until coinbase is safely deep enough in the chain before valuing it + if (IsCoinBase() && GetBlocksToMaturity() > 0) + return 0; + return CTransaction::GetCredit(); + } + + IMPLEMENT_SERIALIZE + ( + nSerSize += SerReadWrite(s, *(CTransaction*)this, nType, nVersion, ser_action); + nVersion = this->nVersion; + READWRITE(hashBlock); + READWRITE(vMerkleBranch); + READWRITE(nIndex); + ) + + + int SetMerkleBranch(const CBlock* pblock=NULL); + int GetDepthInMainChain() const; + bool IsInMainChain() const { return GetDepthInMainChain() > 0; } + int GetBlocksToMaturity() const; + bool AcceptTransaction(CTxDB& txdb, bool fCheckInputs=true); + bool AcceptTransaction() { CTxDB txdb("r"); return AcceptTransaction(txdb); } +}; + + + + +// +// A transaction with a bunch of additional info that only the owner cares +// about. It includes any unrecorded transactions needed to link it back +// to the block chain. +// +class CWalletTx : public CMerkleTx +{ +public: + vector vtxPrev; + map mapValue; + vector > vOrderForm; + unsigned int fTimeReceivedIsTxTime; + unsigned int nTimeReceived; // time received by this node + char fFromMe; + char fSpent; + //// probably need to sign the order info so know it came from payer + + // memory only + mutable unsigned int nTimeDisplayed; + + + CWalletTx() + { + Init(); + } + + CWalletTx(const CMerkleTx& txIn) : CMerkleTx(txIn) + { + Init(); + } + + CWalletTx(const CTransaction& txIn) : CMerkleTx(txIn) + { + Init(); + } + + void Init() + { + fTimeReceivedIsTxTime = false; + nTimeReceived = 0; + fFromMe = false; + fSpent = false; + nTimeDisplayed = 0; + } + + IMPLEMENT_SERIALIZE + ( + nSerSize += SerReadWrite(s, *(CMerkleTx*)this, nType, nVersion, ser_action); + nVersion = this->nVersion; + READWRITE(vtxPrev); + READWRITE(mapValue); + READWRITE(vOrderForm); + READWRITE(fTimeReceivedIsTxTime); + READWRITE(nTimeReceived); + READWRITE(fFromMe); + READWRITE(fSpent); + ) + + bool WriteToDisk() + { + return CWalletDB().WriteTx(GetHash(), *this); + } + + + int64 GetTxTime() const; + + void AddSupportingTransactions(CTxDB& txdb); + + bool AcceptWalletTransaction(CTxDB& txdb, bool fCheckInputs=true); + bool AcceptWalletTransaction() { CTxDB txdb("r"); return AcceptWalletTransaction(txdb); } + + void RelayWalletTransaction(CTxDB& txdb); + void RelayWalletTransaction() { CTxDB txdb("r"); RelayWalletTransaction(txdb); } +}; + + + + +// +// A txdb record that contains the disk location of a transaction and the +// locations of transactions that spend its outputs. vSpent is really only +// used as a flag, but having the location is very helpful for debugging. +// +class CTxIndex +{ +public: + CDiskTxPos pos; + vector vSpent; + + CTxIndex() + { + SetNull(); + } + + CTxIndex(const CDiskTxPos& posIn, unsigned int nOutputs) + { + pos = posIn; + vSpent.resize(nOutputs); + } + + IMPLEMENT_SERIALIZE + ( + if (!(nType & SER_GETHASH)) + READWRITE(nVersion); + READWRITE(pos); + READWRITE(vSpent); + ) + + void SetNull() + { + pos.SetNull(); + vSpent.clear(); + } + + bool IsNull() + { + return pos.IsNull(); + } + + friend bool operator==(const CTxIndex& a, const CTxIndex& b) + { + if (a.pos != b.pos || a.vSpent.size() != b.vSpent.size()) + return false; + for (int i = 0; i < a.vSpent.size(); i++) + if (a.vSpent[i] != b.vSpent[i]) + return false; + return true; + } + + friend bool operator!=(const CTxIndex& a, const CTxIndex& b) + { + return !(a == b); + } +}; + + + + + +// +// Nodes collect new transactions into a block, hash them into a hash tree, +// and scan through nonce values to make the block's hash satisfy proof-of-work +// requirements. When they solve the proof-of-work, they broadcast the block +// to everyone and the block is added to the block chain. The first transaction +// in the block is a special one that creates a new coin owned by the creator +// of the block. +// +// Blocks are appended to blk0001.dat files on disk. Their location on disk +// is indexed by CBlockIndex objects in memory. +// +class CBlock +{ +public: + // header + int nVersion; + uint256 hashPrevBlock; + uint256 hashMerkleRoot; + unsigned int nTime; + unsigned int nBits; + unsigned int nNonce; + + // network and disk + vector vtx; + + // memory only + mutable vector vMerkleTree; + + + CBlock() + { + SetNull(); + } + + IMPLEMENT_SERIALIZE + ( + READWRITE(this->nVersion); + nVersion = this->nVersion; + READWRITE(hashPrevBlock); + READWRITE(hashMerkleRoot); + READWRITE(nTime); + READWRITE(nBits); + READWRITE(nNonce); + + // ConnectBlock depends on vtx being last so it can calculate offset + if (!(nType & (SER_GETHASH|SER_BLOCKHEADERONLY))) + READWRITE(vtx); + else if (fRead) + const_cast(this)->vtx.clear(); + ) + + void SetNull() + { + nVersion = 1; + hashPrevBlock = 0; + hashMerkleRoot = 0; + nTime = 0; + nBits = 0; + nNonce = 0; + vtx.clear(); + vMerkleTree.clear(); + } + + bool IsNull() const + { + return (nBits == 0); + } + + uint256 GetHash() const + { + return Hash(BEGIN(nVersion), END(nNonce)); + } + + + uint256 BuildMerkleTree() const + { + vMerkleTree.clear(); + foreach(const CTransaction& tx, vtx) + vMerkleTree.push_back(tx.GetHash()); + int j = 0; + for (int nSize = vtx.size(); nSize > 1; nSize = (nSize + 1) / 2) + { + for (int i = 0; i < nSize; i += 2) + { + int i2 = min(i+1, nSize-1); + vMerkleTree.push_back(Hash(BEGIN(vMerkleTree[j+i]), END(vMerkleTree[j+i]), + BEGIN(vMerkleTree[j+i2]), END(vMerkleTree[j+i2]))); + } + j += nSize; + } + return (vMerkleTree.empty() ? 0 : vMerkleTree.back()); + } + + vector GetMerkleBranch(int nIndex) const + { + if (vMerkleTree.empty()) + BuildMerkleTree(); + vector vMerkleBranch; + int j = 0; + for (int nSize = vtx.size(); nSize > 1; nSize = (nSize + 1) / 2) + { + int i = min(nIndex^1, nSize-1); + vMerkleBranch.push_back(vMerkleTree[j+i]); + nIndex >>= 1; + j += nSize; + } + return vMerkleBranch; + } + + static uint256 CheckMerkleBranch(uint256 hash, const vector& vMerkleBranch, int nIndex) + { + if (nIndex == -1) + return 0; + foreach(const uint256& otherside, vMerkleBranch) + { + if (nIndex & 1) + hash = Hash(BEGIN(otherside), END(otherside), BEGIN(hash), END(hash)); + else + hash = Hash(BEGIN(hash), END(hash), BEGIN(otherside), END(otherside)); + nIndex >>= 1; + } + return hash; + } + + + bool WriteToDisk(bool fWriteTransactions, unsigned int& nFileRet, unsigned int& nBlockPosRet) + { + // Open history file to append + CAutoFile fileout = AppendBlockFile(nFileRet); + if (!fileout) + return error("CBlock::WriteToDisk() : AppendBlockFile failed"); + if (!fWriteTransactions) + fileout.nType |= SER_BLOCKHEADERONLY; + + // Write index header + unsigned int nSize = fileout.GetSerializeSize(*this); + fileout << FLATDATA(pchMessageStart) << nSize; + + // Write block + nBlockPosRet = ftell(fileout); + if (nBlockPosRet == -1) + return error("CBlock::WriteToDisk() : ftell failed"); + fileout << *this; + + return true; + } + + bool ReadFromDisk(unsigned int nFile, unsigned int nBlockPos, bool fReadTransactions) + { + SetNull(); + + // Open history file to read + CAutoFile filein = OpenBlockFile(nFile, nBlockPos, "rb"); + if (!filein) + return error("CBlock::ReadFromDisk() : OpenBlockFile failed"); + if (!fReadTransactions) + filein.nType |= SER_BLOCKHEADERONLY; + + // Read block + filein >> *this; + + // Check the header + if (CBigNum().SetCompact(nBits) > bnProofOfWorkLimit) + return error("CBlock::ReadFromDisk() : nBits errors in block header"); + if (GetHash() > CBigNum().SetCompact(nBits).getuint256()) + return error("CBlock::ReadFromDisk() : GetHash() errors in block header"); + + return true; + } + + + + void print() const + { + printf("CBlock(hash=%s, ver=%d, hashPrevBlock=%s, hashMerkleRoot=%s, nTime=%u, nBits=%08x, nNonce=%u, vtx=%d)\n", + GetHash().ToString().substr(0,14).c_str(), + nVersion, + hashPrevBlock.ToString().substr(0,14).c_str(), + hashMerkleRoot.ToString().substr(0,6).c_str(), + nTime, nBits, nNonce, + vtx.size()); + for (int i = 0; i < vtx.size(); i++) + { + printf(" "); + vtx[i].print(); + } + printf(" vMerkleTree: "); + for (int i = 0; i < vMerkleTree.size(); i++) + printf("%s ", vMerkleTree[i].ToString().substr(0,6).c_str()); + printf("\n"); + } + + + int64 GetBlockValue(int64 nFees) const; + bool DisconnectBlock(CTxDB& txdb, CBlockIndex* pindex); + bool ConnectBlock(CTxDB& txdb, CBlockIndex* pindex); + bool ReadFromDisk(const CBlockIndex* blockindex, bool fReadTransactions); + bool AddToBlockIndex(unsigned int nFile, unsigned int nBlockPos); + bool CheckBlock() const; + bool AcceptBlock(); +}; + + + + + + +// +// The block chain is a tree shaped structure starting with the +// genesis block at the root, with each block potentially having multiple +// candidates to be the next block. pprev and pnext link a path through the +// main/longest chain. A blockindex may have multiple pprev pointing back +// to it, but pnext will only point forward to the longest branch, or will +// be null if the block is not part of the longest chain. +// +class CBlockIndex +{ +public: + const uint256* phashBlock; + CBlockIndex* pprev; + CBlockIndex* pnext; + unsigned int nFile; + unsigned int nBlockPos; + int nHeight; + + // block header + int nVersion; + uint256 hashMerkleRoot; + unsigned int nTime; + unsigned int nBits; + unsigned int nNonce; + + + CBlockIndex() + { + phashBlock = NULL; + pprev = NULL; + pnext = NULL; + nFile = 0; + nBlockPos = 0; + nHeight = 0; + + nVersion = 0; + hashMerkleRoot = 0; + nTime = 0; + nBits = 0; + nNonce = 0; + } + + CBlockIndex(unsigned int nFileIn, unsigned int nBlockPosIn, CBlock& block) + { + phashBlock = NULL; + pprev = NULL; + pnext = NULL; + nFile = nFileIn; + nBlockPos = nBlockPosIn; + nHeight = 0; + + nVersion = block.nVersion; + hashMerkleRoot = block.hashMerkleRoot; + nTime = block.nTime; + nBits = block.nBits; + nNonce = block.nNonce; + } + + uint256 GetBlockHash() const + { + return *phashBlock; + } + + bool IsInMainChain() const + { + return (pnext || this == pindexBest); + } + + bool EraseBlockFromDisk() + { + // Open history file + CAutoFile fileout = OpenBlockFile(nFile, nBlockPos, "rb+"); + if (!fileout) + return false; + + // Overwrite with empty null block + CBlock block; + block.SetNull(); + fileout << block; + + return true; + } + + enum { nMedianTimeSpan=11 }; + + int64 GetMedianTimePast() const + { + unsigned int pmedian[nMedianTimeSpan]; + unsigned int* pbegin = &pmedian[nMedianTimeSpan]; + unsigned int* pend = &pmedian[nMedianTimeSpan]; + + const CBlockIndex* pindex = this; + for (int i = 0; i < nMedianTimeSpan && pindex; i++, pindex = pindex->pprev) + *(--pbegin) = pindex->nTime; + + sort(pbegin, pend); + return pbegin[(pend - pbegin)/2]; + } + + int64 GetMedianTime() const + { + const CBlockIndex* pindex = this; + for (int i = 0; i < nMedianTimeSpan/2; i++) + { + if (!pindex->pnext) + return nTime; + pindex = pindex->pnext; + } + return pindex->GetMedianTimePast(); + } + + + + string ToString() const + { + return strprintf("CBlockIndex(nprev=%08x, pnext=%08x, nFile=%d, nBlockPos=%-6d nHeight=%d, merkle=%s, hashBlock=%s)", + pprev, pnext, nFile, nBlockPos, nHeight, + hashMerkleRoot.ToString().substr(0,6).c_str(), + GetBlockHash().ToString().substr(0,14).c_str()); + } + + void print() const + { + printf("%s\n", ToString().c_str()); + } +}; + + + +// +// Used to marshal pointers into hashes for db storage. +// +class CDiskBlockIndex : public CBlockIndex +{ +public: + uint256 hashPrev; + uint256 hashNext; + + CDiskBlockIndex() + { + hashPrev = 0; + hashNext = 0; + } + + explicit CDiskBlockIndex(CBlockIndex* pindex) : CBlockIndex(*pindex) + { + hashPrev = (pprev ? pprev->GetBlockHash() : 0); + hashNext = (pnext ? pnext->GetBlockHash() : 0); + } + + IMPLEMENT_SERIALIZE + ( + if (!(nType & SER_GETHASH)) + READWRITE(nVersion); + + READWRITE(hashNext); + READWRITE(nFile); + READWRITE(nBlockPos); + READWRITE(nHeight); + + // block header + READWRITE(this->nVersion); + READWRITE(hashPrev); + READWRITE(hashMerkleRoot); + READWRITE(nTime); + READWRITE(nBits); + READWRITE(nNonce); + ) + + uint256 GetBlockHash() const + { + CBlock block; + block.nVersion = nVersion; + block.hashPrevBlock = hashPrev; + block.hashMerkleRoot = hashMerkleRoot; + block.nTime = nTime; + block.nBits = nBits; + block.nNonce = nNonce; + return block.GetHash(); + } + + + string ToString() const + { + string str = "CDiskBlockIndex("; + str += CBlockIndex::ToString(); + str += strprintf("\n hashBlock=%s, hashPrev=%s, hashNext=%s)", + GetBlockHash().ToString().c_str(), + hashPrev.ToString().substr(0,14).c_str(), + hashNext.ToString().substr(0,14).c_str()); + return str; + } + + void print() const + { + printf("%s\n", ToString().c_str()); + } +}; + + + + + + + + +// +// Describes a place in the block chain to another node such that if the +// other node doesn't have the same branch, it can find a recent common trunk. +// The further back it is, the further before the fork it may be. +// +class CBlockLocator +{ +protected: + vector vHave; +public: + + CBlockLocator() + { + } + + explicit CBlockLocator(const CBlockIndex* pindex) + { + Set(pindex); + } + + explicit CBlockLocator(uint256 hashBlock) + { + map::iterator mi = mapBlockIndex.find(hashBlock); + if (mi != mapBlockIndex.end()) + Set((*mi).second); + } + + IMPLEMENT_SERIALIZE + ( + if (!(nType & SER_GETHASH)) + READWRITE(nVersion); + READWRITE(vHave); + ) + + void Set(const CBlockIndex* pindex) + { + vHave.clear(); + int nStep = 1; + while (pindex) + { + vHave.push_back(pindex->GetBlockHash()); + + // Exponentially larger steps back + for (int i = 0; pindex && i < nStep; i++) + pindex = pindex->pprev; + if (vHave.size() > 10) + nStep *= 2; + } + vHave.push_back(hashGenesisBlock); + } + + CBlockIndex* GetBlockIndex() + { + // Find the first block the caller has in the main chain + foreach(const uint256& hash, vHave) + { + map::iterator mi = mapBlockIndex.find(hash); + if (mi != mapBlockIndex.end()) + { + CBlockIndex* pindex = (*mi).second; + if (pindex->IsInMainChain()) + return pindex; + } + } + return pindexGenesisBlock; + } + + uint256 GetBlockHash() + { + // Find the first block the caller has in the main chain + foreach(const uint256& hash, vHave) + { + map::iterator mi = mapBlockIndex.find(hash); + if (mi != mapBlockIndex.end()) + { + CBlockIndex* pindex = (*mi).second; + if (pindex->IsInMainChain()) + return hash; + } + } + return hashGenesisBlock; + } + + int GetHeight() + { + CBlockIndex* pindex = GetBlockIndex(); + if (!pindex) + return 0; + return pindex->nHeight; + } +}; + + + + + + + + + + + + +extern map mapTransactions; +extern map mapWallet; +extern vector > vWalletUpdated; +extern CCriticalSection cs_mapWallet; +extern map, CPrivKey> mapKeys; +extern map > mapPubKeys; +extern CCriticalSection cs_mapKeys; +extern CKey keyUser; diff --git a/makefile b/makefile new file mode 100644 index 0000000000..534eb521e8 --- /dev/null +++ b/makefile @@ -0,0 +1,83 @@ +# Copyright (c) 2009 Satoshi Nakamoto +# Distributed under the MIT/X11 software license, see the accompanying +# file license.txt or http://www.opensource.org/licenses/mit-license.php. + + +ifneq "$(BUILD)" "debug" +ifneq "$(BUILD)" "release" +BUILD=debug +endif +endif +ifeq "$(BUILD)" "debug" +D=d +# note: gcc 3.x profile doesn't work +#DEBUGFLAGS=-O0 -g -pg -D__WXDEBUG__ +DEBUGFLAGS=-g -D__WXDEBUG__ +endif + + + +INCLUDEPATHS=-I"/boost" -I"/DB/build_unix" -I"/OpenSSL/include" -I"/wxWidgets/lib/vc_lib/mswd" -I"/wxWidgets/include" +LIBPATHS=-L"/DB/build_unix" -L"/OpenSSL/out" -L"/wxWidgets/lib/gcc_lib" +LIBS= \ + -l db_cxx \ + -l eay32 \ + -l wxmsw28$(D)_richtext -l wxmsw28$(D)_html -l wxmsw28$(D)_core -l wxbase28$(D) -l wxtiff$(D) -l wxjpeg$(D) -l wxpng$(D) -l wxzlib$(D) -l wxregex$(D) -l wxexpat$(D) \ + -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 +WXDEFS=-DWIN32 -D__WXMSW__ -D_WINDOWS -DNOPCH +CFLAGS=-mthreads -O0 -w -Wno-invalid-offsetof -Wformat $(DEBUGFLAGS) $(WXDEFS) $(INCLUDEPATHS) +HEADERS=headers.h util.h main.h serialize.h uint256.h key.h bignum.h script.h db.h base58.h + + + +all: bitcoin.exe + + +headers.h.gch: headers.h $(HEADERS) net.h irc.h market.h uibase.h ui.h + g++ -c $(CFLAGS) -o $@ $< + +obj/util.o: util.cpp $(HEADERS) + g++ -c $(CFLAGS) -o $@ $< + +obj/script.o: script.cpp $(HEADERS) + g++ -c $(CFLAGS) -o $@ $< + +obj/db.o: db.cpp $(HEADERS) market.h + g++ -c $(CFLAGS) -o $@ $< + +obj/net.o: net.cpp $(HEADERS) net.h + g++ -c $(CFLAGS) -o $@ $< + +obj/main.o: main.cpp $(HEADERS) net.h market.h sha.h + g++ -c $(CFLAGS) -o $@ $< + +obj/market.o: market.cpp $(HEADERS) market.h + g++ -c $(CFLAGS) -o $@ $< + +obj/ui.o: ui.cpp $(HEADERS) net.h uibase.h ui.h market.h + g++ -c $(CFLAGS) -o $@ $< + +obj/uibase.o: uibase.cpp uibase.h + g++ -c $(CFLAGS) -o $@ $< + +obj/sha.o: sha.cpp sha.h + g++ -c $(CFLAGS) -O3 -o $@ $< + +obj/irc.o: irc.cpp $(HEADERS) + g++ -c $(CFLAGS) -o $@ $< + +obj/ui_res.o: ui.rc rc/bitcoin.ico rc/check.ico rc/send16.bmp rc/send16mask.bmp rc/send16masknoshadow.bmp rc/send20.bmp rc/send20mask.bmp rc/addressbook16.bmp rc/addressbook16mask.bmp rc/addressbook20.bmp rc/addressbook20mask.bmp + windres $(WXDEFS) $(INCLUDEPATHS) -o $@ -i $< + + + +OBJS=obj/util.o obj/script.o obj/db.o obj/net.o obj/main.o obj/market.o \ + obj/ui.o obj/uibase.o obj/sha.o obj/irc.o obj/ui_res.o + +bitcoin.exe: headers.h.gch $(OBJS) + -kill /f bitcoin.exe + g++ $(CFLAGS) -mwindows -Wl,--subsystem,windows -o $@ $(LIBPATHS) $(OBJS) $(LIBS) + +clean: + -del /Q obj\* + -del /Q headers.h.gch diff --git a/makefile.vc b/makefile.vc new file mode 100644 index 0000000000..bf7e9bc580 --- /dev/null +++ b/makefile.vc @@ -0,0 +1,77 @@ +# Copyright (c) 2009 Satoshi Nakamoto +# Distributed under the MIT/X11 software license, see the accompanying +# file license.txt or http://www.opensource.org/licenses/mit-license.php. + + +!IF "$(BUILD)" != "debug" && "$(BUILD)" != "release" +BUILD=debug +!ENDIF +!IF "$(BUILD)" == "debug" +D=d +DEBUGFLAGS=/Zi /Od /D__WXDEBUG__ +!ENDIF + + + +INCLUDEPATHS=/I"/boost" /I"/DB/build_windows" /I"/OpenSSL/include" /I"/wxWidgets/lib/vc_lib/mswd" /I"/wxWidgets/include" +LIBPATHS=/LIBPATH:"/DB/build_windows/$(BUILD)" /LIBPATH:"/OpenSSL/out" /LIBPATH:"/wxWidgets/lib/vc_lib" +LIBS= \ + libdb47s$(D).lib \ + libeay32.lib \ + wxmsw28$(D)_richtext.lib wxmsw28$(D)_html.lib wxmsw28$(D)_core.lib wxbase28$(D).lib wxtiff$(D).lib wxjpeg$(D).lib wxpng$(D).lib wxzlib$(D).lib wxregex$(D).lib wxexpat$(D).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 +WXDEFS=/DWIN32 /D__WXMSW__ /D_WINDOWS /DNOPCH +CFLAGS=/c /nologo /Ob0 /MD$(D) /EHsc /GR /Zm300 /YX /Fpobj/headers.pch $(DEBUGFLAGS) $(WXDEFS) $(INCLUDEPATHS) +HEADERS=headers.h util.h main.h serialize.h uint256.h key.h bignum.h script.h db.h base58.h + + + +all: bitcoin.exe + + +obj\util.obj: util.cpp $(HEADERS) + cl $(CFLAGS) /Fo$@ %s + +obj\script.obj: script.cpp $(HEADERS) + cl $(CFLAGS) /Fo$@ %s + +obj\db.obj: db.cpp $(HEADERS) market.h + cl $(CFLAGS) /Fo$@ %s + +obj\net.obj: net.cpp $(HEADERS) net.h + cl $(CFLAGS) /Fo$@ %s + +obj\main.obj: main.cpp $(HEADERS) net.h market.h + cl $(CFLAGS) /Fo$@ %s + +obj\market.obj: market.cpp $(HEADERS) market.h + cl $(CFLAGS) /Fo$@ %s + +obj\ui.obj: ui.cpp $(HEADERS) net.h uibase.h ui.h market.h + cl $(CFLAGS) /Fo$@ %s + +obj\uibase.obj: uibase.cpp uibase.h + cl $(CFLAGS) /Fo$@ %s + +obj\sha.obj: sha.cpp sha.h + cl $(CFLAGS) /O2 /Fo$@ %s + +obj\irc.obj: irc.cpp $(HEADERS) + cl $(CFLAGS) /Fo$@ %s + +obj\ui.res: ui.rc rc/bitcoin.ico rc/check.ico rc/send16.bmp rc/send16mask.bmp rc/send16masknoshadow.bmp rc/send20.bmp rc/send20mask.bmp rc/addressbook16.bmp rc/addressbook16mask.bmp rc/addressbook20.bmp rc/addressbook20mask.bmp + rc $(INCLUDEPATHS) $(WXDEFS) /Fo$@ %s + + + +OBJS=obj\util.obj obj\script.obj obj\db.obj obj\net.obj obj\main.obj obj\market.obj \ + obj\ui.obj obj\uibase.obj obj\sha.obj obj\irc.obj obj\ui.res + +bitcoin.exe: $(OBJS) + -kill /f bitcoin.exe & sleep 1 + link /nologo /DEBUG /SUBSYSTEM:WINDOWS /OUT:$@ $(LIBPATHS) $** $(LIBS) + +clean: + -del /Q obj\* + -del *.ilk + -del *.pdb diff --git a/market.cpp b/market.cpp new file mode 100644 index 0000000000..22b5365fa4 --- /dev/null +++ b/market.cpp @@ -0,0 +1,264 @@ +// Copyright (c) 2009 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" + + + + + + + + + + +// +// Global state variables +// + +//// later figure out how these are persisted +map mapMyProducts; + + + + +map mapProducts; +CCriticalSection cs_mapProducts; + +bool AdvertInsert(const CProduct& product) +{ + uint256 hash = product.GetHash(); + bool fNew = false; + bool fUpdated = false; + + CRITICAL_BLOCK(cs_mapProducts) + { + // Insert or find existing product + pair::iterator, bool> item = mapProducts.insert(make_pair(hash, product)); + CProduct* pproduct = &(*(item.first)).second; + fNew = item.second; + + // Update if newer + if (product.nSequence > pproduct->nSequence) + { + *pproduct = product; + fUpdated = true; + } + } + + //if (fNew) + // NotifyProductAdded(hash); + //else if (fUpdated) + // NotifyProductUpdated(hash); + + return (fNew || fUpdated); +} + +void AdvertErase(const CProduct& product) +{ + uint256 hash = product.GetHash(); + CRITICAL_BLOCK(cs_mapProducts) + mapProducts.erase(hash); + //NotifyProductDeleted(hash); +} + + + + + + + + + + + + + + + + + + + +template +unsigned int Union(T& v1, T& v2) +{ + // v1 = v1 union v2 + // v1 and v2 must be sorted + // returns the number of elements added to v1 + + ///// need to check that this is equivalent, then delete this comment + //vector vUnion(v1.size() + v2.size()); + //vUnion.erase(set_union(v1.begin(), v1.end(), + // v2.begin(), v2.end(), + // vUnion.begin()), + // vUnion.end()); + + T vUnion; + vUnion.reserve(v1.size() + v2.size()); + set_union(v1.begin(), v1.end(), + v2.begin(), v2.end(), + back_inserter(vUnion)); + unsigned int nAdded = vUnion.size() - v1.size(); + if (nAdded > 0) + v1 = vUnion; + return nAdded; +} + +void CUser::AddAtom(unsigned short nAtom, bool fOrigin) +{ + // Ignore duplicates + if (binary_search(vAtomsIn.begin(), vAtomsIn.end(), nAtom) || + find(vAtomsNew.begin(), vAtomsNew.end(), nAtom) != vAtomsNew.end()) + return; + + //// instead of zero atom, should change to free atom that propagates, + //// limited to lower than a certain value like 5 so conflicts quickly + // The zero atom never propagates, + // new atoms always propagate through the user that created them + if (nAtom == 0 || fOrigin) + { + vector vTmp(1, nAtom); + Union(vAtomsIn, vTmp); + if (fOrigin) + vAtomsOut.push_back(nAtom); + return; + } + + vAtomsNew.push_back(nAtom); + + if (vAtomsNew.size() >= nFlowthroughRate || vAtomsOut.empty()) + { + // Select atom to flow through to vAtomsOut + vAtomsOut.push_back(vAtomsNew[GetRand(vAtomsNew.size())]); + + // Merge vAtomsNew into vAtomsIn + sort(vAtomsNew.begin(), vAtomsNew.end()); + Union(vAtomsIn, vAtomsNew); + vAtomsNew.clear(); + } +} + +bool AddAtomsAndPropagate(uint256 hashUserStart, const vector& vAtoms, bool fOrigin) +{ + CReviewDB reviewdb; + map > pmapPropagate[2]; + pmapPropagate[0][hashUserStart] = vAtoms; + + for (int side = 0; !pmapPropagate[side].empty(); side = 1 - side) + { + map >& mapFrom = pmapPropagate[side]; + map >& mapTo = pmapPropagate[1 - side]; + + for (map >::iterator mi = mapFrom.begin(); mi != mapFrom.end(); ++mi) + { + const uint256& hashUser = (*mi).first; + const vector& vReceived = (*mi).second; + + ///// this would be a lot easier on the database if it put the new atom at the beginning of the list, + ///// so the change would be right next to the vector size. + + // Read user + CUser user; + reviewdb.ReadUser(hashUser, user); + unsigned int nIn = user.vAtomsIn.size(); + unsigned int nNew = user.vAtomsNew.size(); + unsigned int nOut = user.vAtomsOut.size(); + + // Add atoms received + foreach(unsigned short nAtom, vReceived) + user.AddAtom(nAtom, fOrigin); + fOrigin = false; + + // Don't bother writing to disk if no changes + if (user.vAtomsIn.size() == nIn && user.vAtomsNew.size() == nNew) + continue; + + // Propagate + if (user.vAtomsOut.size() > nOut) + foreach(const uint256& hash, user.vLinksOut) + mapTo[hash].insert(mapTo[hash].end(), user.vAtomsOut.begin() + nOut, user.vAtomsOut.end()); + + // Write back + if (!reviewdb.WriteUser(hashUser, user)) + return false; + } + mapFrom.clear(); + } + return true; +} + + + + + + +bool CReview::AcceptReview() +{ + // Timestamp + nTime = GetTime(); + + // Check signature + if (!CKey::Verify(vchPubKeyFrom, GetSigHash(), vchSig)) + return false; + + CReviewDB reviewdb; + + // Add review text to recipient + vector vReviews; + reviewdb.ReadReviews(hashTo, vReviews); + vReviews.push_back(*this); + if (!reviewdb.WriteReviews(hashTo, vReviews)) + return false; + + // Add link from sender + CUser user; + uint256 hashFrom = Hash(vchPubKeyFrom.begin(), vchPubKeyFrom.end()); + reviewdb.ReadUser(hashFrom, user); + user.vLinksOut.push_back(hashTo); + if (!reviewdb.WriteUser(hashFrom, user)) + return false; + + reviewdb.Close(); + + // Propagate atoms to recipient + vector vZeroAtom(1, 0); + if (!AddAtomsAndPropagate(hashTo, user.vAtomsOut.size() ? user.vAtomsOut : vZeroAtom, false)) + return false; + + return true; +} + + + + + +bool CProduct::CheckSignature() +{ + return (CKey::Verify(vchPubKeyFrom, GetSigHash(), vchSig)); +} + +bool CProduct::CheckProduct() +{ + if (!CheckSignature()) + return false; + + // Make sure it's a summary product + if (!mapDetails.empty() || !vOrderForm.empty()) + return false; + + // Look up seller's atom count + CReviewDB reviewdb("r"); + CUser user; + reviewdb.ReadUser(GetUserHash(), user); + nAtoms = user.GetAtomCount(); + reviewdb.Close(); + + ////// delme, this is now done by AdvertInsert + //// Store to memory + //CRITICAL_BLOCK(cs_mapProducts) + // mapProducts[GetHash()] = *this; + + return true; +} diff --git a/market.h b/market.h new file mode 100644 index 0000000000..2714787307 --- /dev/null +++ b/market.h @@ -0,0 +1,182 @@ +// Copyright (c) 2009 Satoshi Nakamoto +// Distributed under the MIT/X11 software license, see the accompanying +// file license.txt or http://www.opensource.org/licenses/mit-license.php. + +class CUser; +class CReview; +class CProduct; + +static const unsigned int nFlowthroughRate = 2; + + + + +bool AdvertInsert(const CProduct& product); +void AdvertErase(const CProduct& product); +bool AddAtomsAndPropagate(uint256 hashUserStart, const vector& vAtoms, bool fOrigin); + + + + + + + + +class CUser +{ +public: + vector vAtomsIn; + vector vAtomsNew; + vector vAtomsOut; + vector vLinksOut; + + CUser() + { + } + + IMPLEMENT_SERIALIZE + ( + if (!(nType & SER_GETHASH)) + READWRITE(nVersion); + READWRITE(vAtomsIn); + READWRITE(vAtomsNew); + READWRITE(vAtomsOut); + READWRITE(vLinksOut); + ) + + void SetNull() + { + vAtomsIn.clear(); + vAtomsNew.clear(); + vAtomsOut.clear(); + vLinksOut.clear(); + } + + uint256 GetHash() const { return SerializeHash(*this); } + + + int GetAtomCount() const + { + return (vAtomsIn.size() + vAtomsNew.size()); + } + + void AddAtom(unsigned short nAtom, bool fOrigin); +}; + + + + + + + +class CReview +{ +public: + int nVersion; + uint256 hashTo; + map mapValue; + vector vchPubKeyFrom; + vector vchSig; + + // memory only + unsigned int nTime; + int nAtoms; + + + CReview() + { + nVersion = 1; + hashTo = 0; + nTime = 0; + nAtoms = 0; + } + + IMPLEMENT_SERIALIZE + ( + READWRITE(this->nVersion); + nVersion = this->nVersion; + if (!(nType & SER_DISK)) + READWRITE(hashTo); + READWRITE(mapValue); + READWRITE(vchPubKeyFrom); + if (!(nType & SER_GETHASH)) + READWRITE(vchSig); + ) + + uint256 GetHash() const { return SerializeHash(*this); } + uint256 GetSigHash() const { return SerializeHash(*this, SER_GETHASH|SER_SKIPSIG); } + uint256 GetUserHash() const { return Hash(vchPubKeyFrom.begin(), vchPubKeyFrom.end()); } + + + bool AcceptReview(); +}; + + + + + + + +class CProduct +{ +public: + int nVersion; + CAddress addr; + map mapValue; + map mapDetails; + vector > vOrderForm; + unsigned int nSequence; + vector vchPubKeyFrom; + vector vchSig; + + // disk only + int nAtoms; + + // memory only + set setSources; + + CProduct() + { + nVersion = 1; + nAtoms = 0; + nSequence = 0; + } + + IMPLEMENT_SERIALIZE + ( + READWRITE(this->nVersion); + nVersion = this->nVersion; + READWRITE(addr); + READWRITE(mapValue); + if (!(nType & SER_GETHASH)) + { + READWRITE(mapDetails); + READWRITE(vOrderForm); + READWRITE(nSequence); + } + READWRITE(vchPubKeyFrom); + if (!(nType & SER_GETHASH)) + READWRITE(vchSig); + if (nType & SER_DISK) + READWRITE(nAtoms); + ) + + uint256 GetHash() const { return SerializeHash(*this); } + uint256 GetSigHash() const { return SerializeHash(*this, SER_GETHASH|SER_SKIPSIG); } + uint256 GetUserHash() const { return Hash(vchPubKeyFrom.begin(), vchPubKeyFrom.end()); } + + + bool CheckSignature(); + bool CheckProduct(); +}; + + + + + + + + +extern map mapProducts; +extern CCriticalSection cs_mapProducts; +extern map mapMyProducts; diff --git a/mingwm10.dll b/mingwm10.dll new file mode 100644 index 0000000000..bf8544ce13 Binary files /dev/null and b/mingwm10.dll differ diff --git a/net.cpp b/net.cpp new file mode 100644 index 0000000000..b8d96006fc --- /dev/null +++ b/net.cpp @@ -0,0 +1,1100 @@ +// Copyright (c) 2009 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 + +void ThreadMessageHandler2(void* parg); +void ThreadSocketHandler2(void* parg); +void ThreadOpenConnections2(void* parg); + + + + + + +// +// Global state variables +// +bool fClient = false; +uint64 nLocalServices = (fClient ? 0 : NODE_NETWORK); +CAddress addrLocalHost(0, DEFAULT_PORT, nLocalServices); +CNode nodeLocalHost(INVALID_SOCKET, CAddress("127.0.0.1", nLocalServices)); +CNode* pnodeLocalHost = &nodeLocalHost; +bool fShutdown = false; +array vfThreadRunning; +vector vNodes; +CCriticalSection cs_vNodes; +map, CAddress> mapAddresses; +CCriticalSection cs_mapAddresses; +map mapRelay; +deque > vRelayExpiration; +CCriticalSection cs_mapRelay; +map mapAlreadyAskedFor; + + + +CAddress addrProxy; + +bool ConnectSocket(const CAddress& addrConnect, SOCKET& hSocketRet) +{ + hSocketRet = INVALID_SOCKET; + + SOCKET hSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (hSocket == INVALID_SOCKET) + return false; + + bool fRoutable = !(addrConnect.GetByte(3) == 10 || (addrConnect.GetByte(3) == 192 && addrConnect.GetByte(2) == 168)); + bool fProxy = (addrProxy.ip && fRoutable); + struct sockaddr_in sockaddr = (fProxy ? addrProxy.GetSockAddr() : addrConnect.GetSockAddr()); + + if (connect(hSocket, (struct sockaddr*)&sockaddr, sizeof(sockaddr)) == SOCKET_ERROR) + { + closesocket(hSocket); + return false; + } + + if (fProxy) + { + printf("Proxy connecting to %s\n", addrConnect.ToString().c_str()); + char pszSocks4IP[] = "\4\1\0\0\0\0\0\0user"; + memcpy(pszSocks4IP + 2, &addrConnect.port, 2); + memcpy(pszSocks4IP + 4, &addrConnect.ip, 4); + char* pszSocks4 = pszSocks4IP; + int nSize = sizeof(pszSocks4IP); + + int ret = send(hSocket, pszSocks4, nSize, 0); + if (ret != nSize) + { + closesocket(hSocket); + return error("Error sending to proxy\n"); + } + char pchRet[8]; + if (recv(hSocket, pchRet, 8, 0) != 8) + { + closesocket(hSocket); + return error("Error reading proxy response\n"); + } + if (pchRet[1] != 0x5a) + { + closesocket(hSocket); + return error("Proxy returned error %d\n", pchRet[1]); + } + printf("Proxy connection established %s\n", addrConnect.ToString().c_str()); + } + + hSocketRet = hSocket; + return true; +} + + + +bool GetMyExternalIP2(const CAddress& addrConnect, const char* pszGet, const char* pszKeyword, unsigned int& ipRet) +{ + SOCKET hSocket; + if (!ConnectSocket(addrConnect, hSocket)) + return error("GetMyExternalIP() : connection to %s failed\n", addrConnect.ToString().c_str()); + + send(hSocket, pszGet, strlen(pszGet), 0); + + string strLine; + while (RecvLine(hSocket, strLine)) + { + if (strLine.empty()) + { + loop + { + if (!RecvLine(hSocket, strLine)) + { + closesocket(hSocket); + return false; + } + if (strLine.find(pszKeyword) != -1) + { + strLine = strLine.substr(strLine.find(pszKeyword) + strlen(pszKeyword)); + break; + } + } + closesocket(hSocket); + if (strLine.find("<")) + strLine = strLine.substr(0, strLine.find("<")); + strLine = strLine.substr(strspn(strLine.c_str(), " \t\n\r")); + strLine = wxString(strLine).Trim(); + CAddress addr(strLine.c_str()); + printf("GetMyExternalIP() received [%s] %s\n", strLine.c_str(), addr.ToString().c_str()); + if (addr.ip == 0 || !addr.IsRoutable()) + return false; + ipRet = addr.ip; + return true; + } + } + closesocket(hSocket); + return error("GetMyExternalIP() : connection closed\n"); +} + + +bool GetMyExternalIP(unsigned int& ipRet) +{ + CAddress addrConnect; + char* pszGet; + char* pszKeyword; + + for (int nLookup = 0; nLookup <= 1; nLookup++) + for (int nHost = 1; nHost <= 2; nHost++) + { + if (nHost == 1) + { + addrConnect = CAddress("70.86.96.218:80"); // www.ipaddressworld.com + + if (nLookup == 1) + { + struct hostent* phostent = gethostbyname("www.ipaddressworld.com"); + if (phostent && phostent->h_addr_list && phostent->h_addr_list[0]) + addrConnect = CAddress(*(u_long*)phostent->h_addr_list[0], htons(80)); + } + + pszGet = "GET /ip.php HTTP/1.1\r\n" + "Host: www.ipaddressworld.com\r\n" + "User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)\r\n" + "Connection: close\r\n" + "\r\n"; + + pszKeyword = "IP:"; + } + else if (nHost == 2) + { + addrConnect = CAddress("208.78.68.70:80"); // checkip.dyndns.org + + if (nLookup == 1) + { + struct hostent* phostent = gethostbyname("checkip.dyndns.org"); + if (phostent && phostent->h_addr_list && phostent->h_addr_list[0]) + addrConnect = CAddress(*(u_long*)phostent->h_addr_list[0], htons(80)); + } + + pszGet = "GET / HTTP/1.1\r\n" + "Host: checkip.dyndns.org\r\n" + "User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)\r\n" + "Connection: close\r\n" + "\r\n"; + + pszKeyword = "Address:"; + } + + if (GetMyExternalIP2(addrConnect, pszGet, pszKeyword, ipRet)) + return true; + } + + return false; +} + + + + + +bool AddAddress(CAddrDB& addrdb, const CAddress& addr) +{ + if (!addr.IsRoutable()) + return false; + if (addr.ip == addrLocalHost.ip) + return false; + CRITICAL_BLOCK(cs_mapAddresses) + { + map, CAddress>::iterator it = mapAddresses.find(addr.GetKey()); + if (it == mapAddresses.end()) + { + // New address + mapAddresses.insert(make_pair(addr.GetKey(), addr)); + addrdb.WriteAddress(addr); + return true; + } + else + { + CAddress& addrFound = (*it).second; + if ((addrFound.nServices | addr.nServices) != addrFound.nServices) + { + // Services have been added + addrFound.nServices |= addr.nServices; + addrdb.WriteAddress(addrFound); + return true; + } + } + } + return false; +} + + + + + +void AbandonRequests(void (*fn)(void*, CDataStream&), void* param1) +{ + // If the dialog might get closed before the reply comes back, + // call this in the destructor so it doesn't get called after it's deleted. + CRITICAL_BLOCK(cs_vNodes) + { + foreach(CNode* pnode, vNodes) + { + CRITICAL_BLOCK(pnode->cs_mapRequests) + { + for (map::iterator mi = pnode->mapRequests.begin(); mi != pnode->mapRequests.end();) + { + CRequestTracker& tracker = (*mi).second; + if (tracker.fn == fn && tracker.param1 == param1) + pnode->mapRequests.erase(mi++); + else + mi++; + } + } + } + } +} + + + + + + + +// +// Subscription methods for the broadcast and subscription system. +// Channel numbers are message numbers, i.e. MSG_TABLE and MSG_PRODUCT. +// +// The subscription system uses a meet-in-the-middle strategy. +// With 100,000 nodes, if senders broadcast to 1000 random nodes and receivers +// subscribe to 1000 random nodes, 99.995% (1 - 0.99^1000) of messages will get through. +// + +bool AnySubscribed(unsigned int nChannel) +{ + if (pnodeLocalHost->IsSubscribed(nChannel)) + return true; + CRITICAL_BLOCK(cs_vNodes) + foreach(CNode* pnode, vNodes) + if (pnode->IsSubscribed(nChannel)) + return true; + return false; +} + +bool CNode::IsSubscribed(unsigned int nChannel) +{ + if (nChannel >= vfSubscribe.size()) + return false; + return vfSubscribe[nChannel]; +} + +void CNode::Subscribe(unsigned int nChannel, unsigned int nHops) +{ + if (nChannel >= vfSubscribe.size()) + return; + + if (!AnySubscribed(nChannel)) + { + // Relay subscribe + CRITICAL_BLOCK(cs_vNodes) + foreach(CNode* pnode, vNodes) + if (pnode != this) + pnode->PushMessage("subscribe", nChannel, nHops); + } + + vfSubscribe[nChannel] = true; +} + +void CNode::CancelSubscribe(unsigned int nChannel) +{ + if (nChannel >= vfSubscribe.size()) + return; + + // Prevent from relaying cancel if wasn't subscribed + if (!vfSubscribe[nChannel]) + return; + vfSubscribe[nChannel] = false; + + if (!AnySubscribed(nChannel)) + { + // Relay subscription cancel + CRITICAL_BLOCK(cs_vNodes) + foreach(CNode* pnode, vNodes) + if (pnode != this) + pnode->PushMessage("sub-cancel", nChannel); + + // Clear memory, no longer subscribed + if (nChannel == MSG_PRODUCT) + CRITICAL_BLOCK(cs_mapProducts) + mapProducts.clear(); + } +} + + + + + + + + + +CNode* FindNode(unsigned int ip) +{ + CRITICAL_BLOCK(cs_vNodes) + { + foreach(CNode* pnode, vNodes) + if (pnode->addr.ip == ip) + return (pnode); + } + return NULL; +} + +CNode* FindNode(CAddress addr) +{ + CRITICAL_BLOCK(cs_vNodes) + { + foreach(CNode* pnode, vNodes) + if (pnode->addr == addr) + return (pnode); + } + return NULL; +} + +CNode* ConnectNode(CAddress addrConnect, int64 nTimeout) +{ + if (addrConnect.ip == addrLocalHost.ip) + return NULL; + + // Look for an existing connection + CNode* pnode = FindNode(addrConnect.ip); + if (pnode) + { + if (nTimeout != 0) + pnode->AddRef(nTimeout); + else + pnode->AddRef(); + return pnode; + } + + /// debug print + printf("trying %s\n", addrConnect.ToString().c_str()); + + // Connect + SOCKET hSocket; + if (ConnectSocket(addrConnect, hSocket)) + { + /// debug print + printf("connected %s\n", addrConnect.ToString().c_str()); + + // Set to nonblocking + u_long nOne = 1; + if (ioctlsocket(hSocket, FIONBIO, &nOne) == SOCKET_ERROR) + printf("ConnectSocket() : ioctlsocket nonblocking setting failed, error %d\n", WSAGetLastError()); + + // Add node + CNode* pnode = new CNode(hSocket, addrConnect, false); + if (nTimeout != 0) + pnode->AddRef(nTimeout); + else + pnode->AddRef(); + CRITICAL_BLOCK(cs_vNodes) + vNodes.push_back(pnode); + + CRITICAL_BLOCK(cs_mapAddresses) + mapAddresses[addrConnect.GetKey()].nLastFailed = 0; + return pnode; + } + else + { + CRITICAL_BLOCK(cs_mapAddresses) + mapAddresses[addrConnect.GetKey()].nLastFailed = GetTime(); + return NULL; + } +} + +void CNode::Disconnect() +{ + printf("disconnecting node %s\n", addr.ToString().c_str()); + + closesocket(hSocket); + + // If outbound and never got version message, mark address as failed + if (!fInbound && nVersion == 0) + CRITICAL_BLOCK(cs_mapAddresses) + mapAddresses[addr.GetKey()].nLastFailed = GetTime(); + + // All of a nodes broadcasts and subscriptions are automatically torn down + // when it goes down, so a node has to stay up to keep its broadcast going. + + CRITICAL_BLOCK(cs_mapProducts) + for (map::iterator mi = mapProducts.begin(); mi != mapProducts.end();) + AdvertRemoveSource(this, MSG_PRODUCT, 0, (*(mi++)).second); + + // Cancel subscriptions + for (unsigned int nChannel = 0; nChannel < vfSubscribe.size(); nChannel++) + if (vfSubscribe[nChannel]) + CancelSubscribe(nChannel); +} + + + + + + + + + + + + + +void ThreadSocketHandler(void* parg) +{ + IMPLEMENT_RANDOMIZE_STACK(ThreadSocketHandler(parg)); + + loop + { + vfThreadRunning[0] = true; + CheckForShutdown(0); + try + { + ThreadSocketHandler2(parg); + } + CATCH_PRINT_EXCEPTION("ThreadSocketHandler()") + vfThreadRunning[0] = false; + Sleep(5000); + } +} + +void ThreadSocketHandler2(void* parg) +{ + printf("ThreadSocketHandler started\n"); + SOCKET hListenSocket = *(SOCKET*)parg; + list vNodesDisconnected; + int nPrevNodeCount = 0; + + loop + { + // + // Disconnect nodes + // + CRITICAL_BLOCK(cs_vNodes) + { + // Disconnect unused nodes + vector vNodesCopy = vNodes; + foreach(CNode* pnode, vNodesCopy) + { + if (pnode->ReadyToDisconnect() && pnode->vRecv.empty() && pnode->vSend.empty()) + { + // remove from vNodes + vNodes.erase(remove(vNodes.begin(), vNodes.end(), pnode), vNodes.end()); + pnode->Disconnect(); + + // hold in disconnected pool until all refs are released + pnode->nReleaseTime = max(pnode->nReleaseTime, GetTime() + 5 * 60); + if (pnode->fNetworkNode) + pnode->Release(); + vNodesDisconnected.push_back(pnode); + } + } + + // Delete disconnected nodes + list vNodesDisconnectedCopy = vNodesDisconnected; + foreach(CNode* pnode, vNodesDisconnectedCopy) + { + // wait until threads are done using it + if (pnode->GetRefCount() <= 0) + { + bool fDelete = false; + TRY_CRITICAL_BLOCK(pnode->cs_vSend) + TRY_CRITICAL_BLOCK(pnode->cs_vRecv) + TRY_CRITICAL_BLOCK(pnode->cs_mapRequests) + TRY_CRITICAL_BLOCK(pnode->cs_inventory) + fDelete = true; + if (fDelete) + { + vNodesDisconnected.remove(pnode); + delete pnode; + } + } + } + } + if (vNodes.size() != nPrevNodeCount) + { + nPrevNodeCount = vNodes.size(); + MainFrameRepaint(); + } + + + // + // Find which sockets have data to receive + // + struct timeval timeout; + timeout.tv_sec = 0; + timeout.tv_usec = 50000; // frequency to poll pnode->vSend + + struct fd_set fdsetRecv; + struct fd_set fdsetSend; + FD_ZERO(&fdsetRecv); + FD_ZERO(&fdsetSend); + SOCKET hSocketMax = 0; + FD_SET(hListenSocket, &fdsetRecv); + hSocketMax = max(hSocketMax, hListenSocket); + CRITICAL_BLOCK(cs_vNodes) + { + foreach(CNode* pnode, vNodes) + { + FD_SET(pnode->hSocket, &fdsetRecv); + hSocketMax = max(hSocketMax, pnode->hSocket); + TRY_CRITICAL_BLOCK(pnode->cs_vSend) + if (!pnode->vSend.empty()) + FD_SET(pnode->hSocket, &fdsetSend); + } + } + + vfThreadRunning[0] = false; + int nSelect = select(hSocketMax + 1, &fdsetRecv, &fdsetSend, NULL, &timeout); + vfThreadRunning[0] = true; + CheckForShutdown(0); + if (nSelect == SOCKET_ERROR) + { + int nErr = WSAGetLastError(); + printf("select failed: %d\n", nErr); + for (int i = 0; i <= hSocketMax; i++) + { + FD_SET(i, &fdsetRecv); + FD_SET(i, &fdsetSend); + } + Sleep(timeout.tv_usec/1000); + } + RandAddSeed(); + + //// debug print + //foreach(CNode* pnode, vNodes) + //{ + // printf("vRecv = %-5d ", pnode->vRecv.size()); + // printf("vSend = %-5d ", pnode->vSend.size()); + //} + //printf("\n"); + + + // + // Accept new connections + // + if (FD_ISSET(hListenSocket, &fdsetRecv)) + { + struct sockaddr_in sockaddr; + int len = sizeof(sockaddr); + SOCKET hSocket = accept(hListenSocket, (struct sockaddr*)&sockaddr, &len); + CAddress addr(sockaddr); + if (hSocket == INVALID_SOCKET) + { + if (WSAGetLastError() != WSAEWOULDBLOCK) + printf("ERROR ThreadSocketHandler accept failed: %d\n", WSAGetLastError()); + } + else + { + printf("accepted connection from %s\n", addr.ToString().c_str()); + CNode* pnode = new CNode(hSocket, addr, true); + pnode->AddRef(); + CRITICAL_BLOCK(cs_vNodes) + vNodes.push_back(pnode); + } + } + + + // + // Service each socket + // + vector vNodesCopy; + CRITICAL_BLOCK(cs_vNodes) + vNodesCopy = vNodes; + foreach(CNode* pnode, vNodesCopy) + { + CheckForShutdown(0); + SOCKET hSocket = pnode->hSocket; + + // + // Receive + // + if (FD_ISSET(hSocket, &fdsetRecv)) + { + TRY_CRITICAL_BLOCK(pnode->cs_vRecv) + { + CDataStream& vRecv = pnode->vRecv; + unsigned int nPos = vRecv.size(); + + // typical socket buffer is 8K-64K + const unsigned int nBufSize = 0x10000; + vRecv.resize(nPos + nBufSize); + int nBytes = recv(hSocket, &vRecv[nPos], nBufSize, 0); + vRecv.resize(nPos + max(nBytes, 0)); + if (nBytes == 0) + { + // socket closed gracefully + if (!pnode->fDisconnect) + printf("recv: socket closed\n"); + pnode->fDisconnect = true; + } + else if (nBytes < 0) + { + // socket error + int nErr = WSAGetLastError(); + if (nErr != WSAEWOULDBLOCK && nErr != WSAEMSGSIZE && nErr != WSAEINTR && nErr != WSAEINPROGRESS) + { + if (!pnode->fDisconnect) + printf("recv failed: %d\n", nErr); + pnode->fDisconnect = true; + } + } + } + } + + // + // Send + // + if (FD_ISSET(hSocket, &fdsetSend)) + { + TRY_CRITICAL_BLOCK(pnode->cs_vSend) + { + CDataStream& vSend = pnode->vSend; + if (!vSend.empty()) + { + int nBytes = send(hSocket, &vSend[0], vSend.size(), 0); + if (nBytes > 0) + { + vSend.erase(vSend.begin(), vSend.begin() + nBytes); + } + else if (nBytes == 0) + { + if (pnode->ReadyToDisconnect()) + pnode->vSend.clear(); + } + else + { + printf("send error %d\n", nBytes); + if (pnode->ReadyToDisconnect()) + pnode->vSend.clear(); + } + } + } + } + } + + + Sleep(10); + } +} + + + + + + + + + + +void ThreadOpenConnections(void* parg) +{ + IMPLEMENT_RANDOMIZE_STACK(ThreadOpenConnections(parg)); + + loop + { + vfThreadRunning[1] = true; + CheckForShutdown(1); + try + { + ThreadOpenConnections2(parg); + } + CATCH_PRINT_EXCEPTION("ThreadOpenConnections()") + vfThreadRunning[1] = false; + Sleep(5000); + } +} + +void ThreadOpenConnections2(void* parg) +{ + printf("ThreadOpenConnections started\n"); + + // Initiate network connections + int nTry = 0; + bool fIRCOnly = false; + const int nMaxConnections = 15; + loop + { + // Wait + vfThreadRunning[1] = false; + Sleep(500); + while (vNodes.size() >= nMaxConnections || vNodes.size() >= mapAddresses.size()) + { + CheckForShutdown(1); + Sleep(2000); + } + vfThreadRunning[1] = true; + CheckForShutdown(1); + + + // + // The IP selection process is designed to limit vulnerability to address flooding. + // Any class C (a.b.c.?) has an equal chance of being chosen, then an IP is + // chosen within the class C. An attacker may be able to allocate many IPs, but + // they would normally be concentrated in blocks of class C's. They can hog the + // attention within their class C, but not the whole IP address space overall. + // A lone node in a class C will get as much attention as someone holding all 255 + // IPs in another class C. + // + + // Every other try is with IRC addresses only + fIRCOnly = !fIRCOnly; + if (mapIRCAddresses.empty()) + fIRCOnly = false; + else if (nTry++ < 30 && vNodes.size() < nMaxConnections/2) + fIRCOnly = true; + + // Make a list of unique class C's + unsigned char pchIPCMask[4] = { 0xff, 0xff, 0xff, 0x00 }; + unsigned int nIPCMask = *(unsigned int*)pchIPCMask; + vector vIPC; + CRITICAL_BLOCK(cs_mapIRCAddresses) + CRITICAL_BLOCK(cs_mapAddresses) + { + vIPC.reserve(mapAddresses.size()); + unsigned int nPrev = 0; + foreach(const PAIRTYPE(vector, CAddress)& item, mapAddresses) + { + const CAddress& addr = item.second; + if (!addr.IsIPv4()) + continue; + if (fIRCOnly && !mapIRCAddresses.count(item.first)) + continue; + + // Taking advantage of mapAddresses being in sorted order, + // with IPs of the same class C grouped together. + unsigned int ipC = addr.ip & nIPCMask; + if (ipC != nPrev) + vIPC.push_back(nPrev = ipC); + } + } + if (vIPC.empty()) + continue; + + // Choose a random class C + unsigned int ipC = vIPC[GetRand(vIPC.size())]; + + // Organize all addresses in the class C by IP + map > mapIP; + CRITICAL_BLOCK(cs_mapIRCAddresses) + CRITICAL_BLOCK(cs_mapAddresses) + { + int64 nDelay = ((30 * 60) << vNodes.size()); + if (!fIRCOnly) + { + nDelay *= 2; + if (vNodes.size() >= 3) + nDelay *= 4; + if (!mapIRCAddresses.empty()) + nDelay *= 100; + } + + for (map, CAddress>::iterator mi = mapAddresses.lower_bound(CAddress(ipC, 0).GetKey()); + mi != mapAddresses.upper_bound(CAddress(ipC | ~nIPCMask, 0xffff).GetKey()); + ++mi) + { + const CAddress& addr = (*mi).second; + if (fIRCOnly && !mapIRCAddresses.count((*mi).first)) + continue; + + int64 nRandomizer = (addr.nLastFailed * addr.ip * 7777U) % 20000; + if (GetTime() - addr.nLastFailed > nDelay * nRandomizer / 10000) + mapIP[addr.ip].push_back(addr); + } + } + if (mapIP.empty()) + continue; + + // Choose a random IP in the class C + map >::iterator mi = mapIP.begin(); + advance(mi, GetRand(mapIP.size())); + + // Once we've chosen an IP, we'll try every given port before moving on + foreach(const CAddress& addrConnect, (*mi).second) + { + // + // Initiate outbound network connection + // + CheckForShutdown(1); + if (addrConnect.ip == addrLocalHost.ip || !addrConnect.IsIPv4() || FindNode(addrConnect.ip)) + continue; + + vfThreadRunning[1] = false; + CNode* pnode = ConnectNode(addrConnect); + vfThreadRunning[1] = true; + CheckForShutdown(1); + if (!pnode) + continue; + pnode->fNetworkNode = true; + + if (addrLocalHost.IsRoutable()) + { + // Advertise our address + vector vAddrToSend; + vAddrToSend.push_back(addrLocalHost); + pnode->PushMessage("addr", vAddrToSend); + } + + // Get as many addresses as we can + pnode->PushMessage("getaddr"); + + ////// should the one on the receiving end do this too? + // Subscribe our local subscription list + const unsigned int nHops = 0; + for (unsigned int nChannel = 0; nChannel < pnodeLocalHost->vfSubscribe.size(); nChannel++) + if (pnodeLocalHost->vfSubscribe[nChannel]) + pnode->PushMessage("subscribe", nChannel, nHops); + + break; + } + } +} + + + + + + + + +void ThreadMessageHandler(void* parg) +{ + IMPLEMENT_RANDOMIZE_STACK(ThreadMessageHandler(parg)); + + loop + { + vfThreadRunning[2] = true; + CheckForShutdown(2); + try + { + ThreadMessageHandler2(parg); + } + CATCH_PRINT_EXCEPTION("ThreadMessageHandler()") + vfThreadRunning[2] = false; + Sleep(5000); + } +} + +void ThreadMessageHandler2(void* parg) +{ + printf("ThreadMessageHandler started\n"); + SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_BELOW_NORMAL); + loop + { + // Poll the connected nodes for messages + vector vNodesCopy; + CRITICAL_BLOCK(cs_vNodes) + vNodesCopy = vNodes; + foreach(CNode* pnode, vNodesCopy) + { + pnode->AddRef(); + + // Receive messages + TRY_CRITICAL_BLOCK(pnode->cs_vRecv) + ProcessMessages(pnode); + + // Send messages + TRY_CRITICAL_BLOCK(pnode->cs_vSend) + SendMessages(pnode); + + pnode->Release(); + } + + // Wait and allow messages to bunch up + vfThreadRunning[2] = false; + Sleep(100); + vfThreadRunning[2] = true; + CheckForShutdown(2); + } +} + + + + + + + + + +//// todo: start one thread per processor, use getenv("NUMBER_OF_PROCESSORS") +void ThreadBitcoinMiner(void* parg) +{ + vfThreadRunning[3] = true; + CheckForShutdown(3); + try + { + bool fRet = BitcoinMiner(); + printf("BitcoinMiner returned %s\n\n\n", fRet ? "true" : "false"); + } + CATCH_PRINT_EXCEPTION("BitcoinMiner()") + vfThreadRunning[3] = false; +} + + + + + + + + + + + +bool StartNode(string& strError) +{ + strError = ""; + + // Sockets startup + WSADATA wsadata; + int ret = WSAStartup(MAKEWORD(2,2), &wsadata); + if (ret != NO_ERROR) + { + strError = strprintf("Error: TCP/IP socket library failed to start (WSAStartup returned error %d)", ret); + printf("%s\n", strError.c_str()); + return false; + } + + // Get local host ip + char pszHostName[255]; + if (gethostname(pszHostName, 255) == SOCKET_ERROR) + { + strError = strprintf("Error: Unable to get IP address of this computer (gethostname returned error %d)", WSAGetLastError()); + printf("%s\n", strError.c_str()); + return false; + } + struct hostent* phostent = gethostbyname(pszHostName); + if (!phostent) + { + strError = strprintf("Error: Unable to get IP address of this computer (gethostbyname returned error %d)", WSAGetLastError()); + printf("%s\n", strError.c_str()); + return false; + } + addrLocalHost = CAddress(*(long*)(phostent->h_addr_list[0]), + DEFAULT_PORT, + nLocalServices); + printf("addrLocalHost = %s\n", addrLocalHost.ToString().c_str()); + + // Create socket for listening for incoming connections + SOCKET hListenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (hListenSocket == INVALID_SOCKET) + { + strError = strprintf("Error: Couldn't open socket for incoming connections (socket returned error %d)", WSAGetLastError()); + printf("%s\n", strError.c_str()); + return false; + } + + // Set to nonblocking, incoming connections will also inherit this + u_long nOne = 1; + if (ioctlsocket(hListenSocket, FIONBIO, &nOne) == SOCKET_ERROR) + { + strError = strprintf("Error: Couldn't set properties on socket for incoming connections (ioctlsocket returned error %d)", WSAGetLastError()); + printf("%s\n", strError.c_str()); + return false; + } + + // The sockaddr_in structure specifies the address family, + // IP address, and port for the socket that is being bound + int nRetryLimit = 15; + struct sockaddr_in sockaddr = addrLocalHost.GetSockAddr(); + if (bind(hListenSocket, (struct sockaddr*)&sockaddr, sizeof(sockaddr)) == SOCKET_ERROR) + { + int nErr = WSAGetLastError(); + if (nErr == WSAEADDRINUSE) + strError = strprintf("Error: Unable to bind to port %s on this computer. The program is probably already running.", addrLocalHost.ToString().c_str()); + else + strError = strprintf("Error: Unable to bind to port %s on this computer (bind returned error %d)", addrLocalHost.ToString().c_str(), nErr); + printf("%s\n", strError.c_str()); + return false; + } + printf("bound to addrLocalHost = %s\n\n", addrLocalHost.ToString().c_str()); + + // Listen for incoming connections + if (listen(hListenSocket, SOMAXCONN) == SOCKET_ERROR) + { + strError = strprintf("Error: Listening for incoming connections failed (listen returned error %d)", WSAGetLastError()); + printf("%s\n", strError.c_str()); + return false; + } + + // Get our external IP address for incoming connections + if (addrIncoming.ip) + addrLocalHost.ip = addrIncoming.ip; + + if (GetMyExternalIP(addrLocalHost.ip)) + { + addrIncoming = addrLocalHost; + CWalletDB().WriteSetting("addrIncoming", addrIncoming); + } + + // Get addresses from IRC and advertise ours + if (_beginthread(ThreadIRCSeed, 0, NULL) == -1) + printf("Error: _beginthread(ThreadIRCSeed) failed\n"); + + // + // Start threads + // + if (_beginthread(ThreadSocketHandler, 0, new SOCKET(hListenSocket)) == -1) + { + strError = "Error: _beginthread(ThreadSocketHandler) failed"; + printf("%s\n", strError.c_str()); + return false; + } + + if (_beginthread(ThreadOpenConnections, 0, NULL) == -1) + { + strError = "Error: _beginthread(ThreadOpenConnections) failed"; + printf("%s\n", strError.c_str()); + return false; + } + + if (_beginthread(ThreadMessageHandler, 0, NULL) == -1) + { + strError = "Error: _beginthread(ThreadMessageHandler) failed"; + printf("%s\n", strError.c_str()); + return false; + } + + return true; +} + +bool StopNode() +{ + printf("StopNode()\n"); + fShutdown = true; + nTransactionsUpdated++; + int64 nStart = GetTime(); + while (vfThreadRunning[0] || vfThreadRunning[2] || vfThreadRunning[3]) + { + if (GetTime() - nStart > 15) + break; + Sleep(20); + } + if (vfThreadRunning[0]) printf("ThreadSocketHandler still running\n"); + if (vfThreadRunning[1]) printf("ThreadOpenConnections still running\n"); + if (vfThreadRunning[2]) printf("ThreadMessageHandler still running\n"); + if (vfThreadRunning[3]) printf("ThreadBitcoinMiner still running\n"); + while (vfThreadRunning[2]) + Sleep(20); + Sleep(50); + + // Sockets shutdown + WSACleanup(); + return true; +} + +void CheckForShutdown(int n) +{ + if (fShutdown) + { + if (n != -1) + vfThreadRunning[n] = false; + if (n == 0) + foreach(CNode* pnode, vNodes) + closesocket(pnode->hSocket); + _endthread(); + } +} diff --git a/net.h b/net.h new file mode 100644 index 0000000000..cd311fc502 --- /dev/null +++ b/net.h @@ -0,0 +1,856 @@ +// Copyright (c) 2009 Satoshi Nakamoto +// Distributed under the MIT/X11 software license, see the accompanying +// file license.txt or http://www.opensource.org/licenses/mit-license.php. + +class CMessageHeader; +class CAddress; +class CInv; +class CRequestTracker; +class CNode; + + + +static const unsigned short DEFAULT_PORT = htons(8333); +static const unsigned int PUBLISH_HOPS = 5; +enum +{ + NODE_NETWORK = (1 << 0), +}; + + + + + + +bool ConnectSocket(const CAddress& addrConnect, SOCKET& hSocketRet); +bool GetMyExternalIP(unsigned int& ipRet); +bool AddAddress(CAddrDB& addrdb, const CAddress& addr); +CNode* FindNode(unsigned int ip); +CNode* ConnectNode(CAddress addrConnect, int64 nTimeout=0); +void AbandonRequests(void (*fn)(void*, CDataStream&), void* param1); +bool AnySubscribed(unsigned int nChannel); +void ThreadBitcoinMiner(void* parg); +bool StartNode(string& strError=REF(string())); +bool StopNode(); +void CheckForShutdown(int n); + + + + + + + + + +// +// Message header +// (4) message start +// (12) command +// (4) size + +// 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. +static const char pchMessageStart[4] = { 0xf9, 0xbe, 0xb4, 0xd9 }; + +class CMessageHeader +{ +public: + enum { COMMAND_SIZE=12 }; + char pchMessageStart[sizeof(::pchMessageStart)]; + char pchCommand[COMMAND_SIZE]; + unsigned int nMessageSize; + + CMessageHeader() + { + memcpy(pchMessageStart, ::pchMessageStart, sizeof(pchMessageStart)); + memset(pchCommand, 0, sizeof(pchCommand)); + pchCommand[1] = 1; + nMessageSize = -1; + } + + CMessageHeader(const char* pszCommand, unsigned int nMessageSizeIn) + { + memcpy(pchMessageStart, ::pchMessageStart, sizeof(pchMessageStart)); + strncpy(pchCommand, pszCommand, COMMAND_SIZE); + nMessageSize = nMessageSizeIn; + } + + IMPLEMENT_SERIALIZE + ( + READWRITE(FLATDATA(pchMessageStart)); + READWRITE(FLATDATA(pchCommand)); + READWRITE(nMessageSize); + ) + + string GetCommand() + { + if (pchCommand[COMMAND_SIZE-1] == 0) + return string(pchCommand, pchCommand + strlen(pchCommand)); + else + return 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 > 0x10000000) + { + printf("CMessageHeader::IsValid() : nMessageSize too large %u\n", 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 only + unsigned int nTime; + + // memory only + unsigned int nLastFailed; + + CAddress() + { + nServices = 0; + memcpy(pchReserved, pchIPv4, sizeof(pchReserved)); + ip = 0; + port = DEFAULT_PORT; + nTime = GetAdjustedTime(); + nLastFailed = 0; + } + + CAddress(unsigned int ipIn, unsigned short portIn=DEFAULT_PORT, uint64 nServicesIn=0) + { + nServices = nServicesIn; + memcpy(pchReserved, pchIPv4, sizeof(pchReserved)); + ip = ipIn; + port = portIn; + nTime = GetAdjustedTime(); + nLastFailed = 0; + } + + explicit CAddress(const struct sockaddr_in& sockaddr, uint64 nServicesIn=0) + { + nServices = nServicesIn; + memcpy(pchReserved, pchIPv4, sizeof(pchReserved)); + ip = sockaddr.sin_addr.s_addr; + port = sockaddr.sin_port; + nTime = GetAdjustedTime(); + nLastFailed = 0; + } + + explicit CAddress(const char* pszIn, uint64 nServicesIn=0) + { + nServices = nServicesIn; + memcpy(pchReserved, pchIPv4, sizeof(pchReserved)); + ip = 0; + port = DEFAULT_PORT; + nTime = GetAdjustedTime(); + nLastFailed = 0; + + char psz[100]; + if (strlen(pszIn) > ARRAYLEN(psz)-1) + return; + strcpy(psz, pszIn); + unsigned int a, b, c, d, e; + if (sscanf(psz, "%u.%u.%u.%u:%u", &a, &b, &c, &d, &e) < 4) + return; + char* pszPort = strchr(psz, ':'); + if (pszPort) + { + *pszPort++ = '\0'; + port = htons(atoi(pszPort)); + } + ip = inet_addr(psz); + } + + IMPLEMENT_SERIALIZE + ( + if (nType & SER_DISK) + { + READWRITE(nVersion); + READWRITE(nTime); + } + READWRITE(nServices); + READWRITE(FLATDATA(pchReserved)); + 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) + { + 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; + } + + vector GetKey() const + { + CDataStream ss; + ss.reserve(18); + ss << FLATDATA(pchReserved) << ip << port; + + #if defined(_MSC_VER) && _MSC_VER < 1300 + return vector((unsigned char*)&ss.begin()[0], (unsigned char*)&ss.end()[0]); + #else + return vector(ss.begin(), ss.end()); + #endif + } + + struct sockaddr_in GetSockAddr() const + { + struct sockaddr_in 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 IsRoutable() const + { + return !(GetByte(3) == 10 || (GetByte(3) == 192 && GetByte(2) == 168) || GetByte(3) == 127 || GetByte(3) == 0); + } + + unsigned char GetByte(int n) const + { + return ((unsigned char*)&ip)[3-n]; + } + + string ToStringIPPort() const + { + return strprintf("%u.%u.%u.%u:%u", GetByte(3), GetByte(2), GetByte(1), GetByte(0), ntohs(port)); + } + + string ToStringIP() const + { + return strprintf("%u.%u.%u.%u", GetByte(3), GetByte(2), GetByte(1), GetByte(0)); + } + + string ToString() const + { + return strprintf("%u.%u.%u.%u:%u", GetByte(3), GetByte(2), GetByte(1), GetByte(0), ntohs(port)); + //return strprintf("%u.%u.%u.%u", GetByte(3), GetByte(2), GetByte(1), GetByte(0)); + } + + void print() const + { + printf("CAddress(%s)\n", ToString().c_str()); + } +}; + + + + + + + +enum +{ + MSG_TX = 1, + MSG_BLOCK, + MSG_REVIEW, + MSG_PRODUCT, + MSG_TABLE, +}; + +static const char* ppszTypeName[] = +{ + "ERROR", + "tx", + "block", + "review", + "product", + "table", +}; + +class CInv +{ +public: + int type; + uint256 hash; + + CInv() + { + type = 0; + hash = 0; + } + + CInv(int typeIn, const uint256& hashIn) + { + type = typeIn; + hash = hashIn; + } + + CInv(const 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=% unknown type", type)); + return ppszTypeName[type]; + } + + string ToString() const + { + return strprintf("%s %s", GetCommand(), hash.ToString().substr(0,14).c_str()); + } + + void print() const + { + printf("CInv(%s)\n", ToString().c_str()); + } +}; + + + + + +class CRequestTracker +{ +public: + void (*fn)(void*, CDataStream&); + void* param1; + + explicit CRequestTracker(void (*fnIn)(void*, CDataStream&)=NULL, void* param1In=NULL) + { + fn = fnIn; + param1 = param1In; + } + + bool IsNull() + { + return fn == NULL; + } +}; + + + + + +extern bool fClient; +extern uint64 nLocalServices; +extern CAddress addrLocalHost; +extern CNode* pnodeLocalHost; +extern bool fShutdown; +extern array vfThreadRunning; +extern vector vNodes; +extern CCriticalSection cs_vNodes; +extern map, CAddress> mapAddresses; +extern CCriticalSection cs_mapAddresses; +extern map mapRelay; +extern deque > vRelayExpiration; +extern CCriticalSection cs_mapRelay; +extern map mapAlreadyAskedFor; +extern CAddress addrProxy; + + + + + +class CNode +{ +public: + // socket + uint64 nServices; + SOCKET hSocket; + CDataStream vSend; + CDataStream vRecv; + CCriticalSection cs_vSend; + CCriticalSection cs_vRecv; + unsigned int nPushPos; + CAddress addr; + int nVersion; + bool fClient; + bool fInbound; + bool fNetworkNode; + bool fDisconnect; +protected: + int nRefCount; +public: + int64 nReleaseTime; + map mapRequests; + CCriticalSection cs_mapRequests; + + // flood + vector vAddrToSend; + set setAddrKnown; + + // inventory based relay + set setInventoryKnown; + set setInventoryKnown2; + vector vInventoryToSend; + CCriticalSection cs_inventory; + multimap mapAskFor; + + // publish and subscription + vector vfSubscribe; + + + CNode(SOCKET hSocketIn, CAddress addrIn, bool fInboundIn=false) + { + nServices = 0; + hSocket = hSocketIn; + vSend.SetType(SER_NETWORK); + vRecv.SetType(SER_NETWORK); + nPushPos = -1; + addr = addrIn; + nVersion = 0; + fClient = false; // set by version message + fInbound = fInboundIn; + fNetworkNode = false; + fDisconnect = false; + nRefCount = 0; + nReleaseTime = 0; + vfSubscribe.assign(256, false); + + // Push a version message + /// when NTP implemented, change to just nTime = GetAdjustedTime() + int64 nTime = (fInbound ? GetAdjustedTime() : GetTime()); + PushMessage("version", VERSION, nLocalServices, nTime, addr); + } + + ~CNode() + { + if (hSocket != INVALID_SOCKET) + closesocket(hSocket); + } + +private: + CNode(const CNode&); + void operator=(const CNode&); +public: + + + bool ReadyToDisconnect() + { + return fDisconnect || GetRefCount() <= 0; + } + + int GetRefCount() + { + return max(nRefCount, 0) + (GetTime() < nReleaseTime ? 1 : 0); + } + + void AddRef(int64 nTimeout=0) + { + if (nTimeout != 0) + nReleaseTime = max(nReleaseTime, GetTime() + nTimeout); + else + nRefCount++; + } + + void Release() + { + nRefCount--; + } + + + + void AddInventoryKnown(const CInv& inv) + { + CRITICAL_BLOCK(cs_inventory) + setInventoryKnown.insert(inv); + } + + void PushInventory(const CInv& inv) + { + CRITICAL_BLOCK(cs_inventory) + if (!setInventoryKnown.count(inv)) + vInventoryToSend.push_back(inv); + } + + void AskFor(const CInv& inv) + { + // We're using mapAskFor as a priority queue, + // the key is the earliest time the request can be sent + int64& nRequestTime = mapAlreadyAskedFor[inv]; + printf("askfor %s %I64d\n", inv.ToString().c_str(), nRequestTime); + + // Make sure not to reuse time indexes to keep things in the same order + int64 nNow = (GetTime() - 1) * 1000000; + static int64 nLastTime; + nLastTime = nNow = max(nNow, ++nLastTime); + + // Each retry is 2 minutes after the last + nRequestTime = max(nRequestTime + 2 * 60 * 1000000, nNow); + mapAskFor.insert(make_pair(nRequestTime, inv)); + } + + + + void BeginMessage(const char* pszCommand) + { + EnterCriticalSection(&cs_vSend); + if (nPushPos != -1) + AbortMessage(); + nPushPos = vSend.size(); + vSend << CMessageHeader(pszCommand, 0); + printf("sending: %-12s ", pszCommand); + } + + void AbortMessage() + { + if (nPushPos == -1) + return; + vSend.resize(nPushPos); + nPushPos = -1; + LeaveCriticalSection(&cs_vSend); + printf("(aborted)\n"); + } + + void EndMessage() + { + extern int nDropMessagesTest; + if (nDropMessagesTest > 0 && GetRand(nDropMessagesTest) == 0) + { + printf("dropmessages DROPPING SEND MESSAGE\n"); + AbortMessage(); + return; + } + + if (nPushPos == -1) + return; + + // Patch in the size + unsigned int nSize = vSend.size() - nPushPos - sizeof(CMessageHeader); + memcpy((char*)&vSend[nPushPos] + offsetof(CMessageHeader, nMessageSize), &nSize, sizeof(nSize)); + + printf("(%d bytes) ", nSize); + //for (int i = nPushPos+sizeof(CMessageHeader); i < min(vSend.size(), nPushPos+sizeof(CMessageHeader)+20U); i++) + // printf("%02x ", vSend[i] & 0xff); + printf("\n"); + + nPushPos = -1; + LeaveCriticalSection(&cs_vSend); + } + + void EndMessageAbortIfEmpty() + { + if (nPushPos == -1) + return; + int nSize = vSend.size() - nPushPos - sizeof(CMessageHeader); + if (nSize > 0) + EndMessage(); + else + AbortMessage(); + } + + const char* GetMessageCommand() const + { + if (nPushPos == -1) + return ""; + return &vSend[nPushPos] + offsetof(CMessageHeader, pchCommand); + } + + + + + void PushMessage(const char* pszCommand) + { + try + { + BeginMessage(pszCommand); + EndMessage(); + } + catch (...) + { + AbortMessage(); + throw; + } + } + + template + void PushMessage(const char* pszCommand, const T1& a1) + { + try + { + BeginMessage(pszCommand); + vSend << a1; + EndMessage(); + } + catch (...) + { + AbortMessage(); + throw; + } + } + + template + void PushMessage(const char* pszCommand, const T1& a1, const T2& a2) + { + try + { + BeginMessage(pszCommand); + vSend << a1 << a2; + EndMessage(); + } + catch (...) + { + AbortMessage(); + throw; + } + } + + template + void PushMessage(const char* pszCommand, const T1& a1, const T2& a2, const T3& a3) + { + try + { + BeginMessage(pszCommand); + vSend << a1 << a2 << a3; + EndMessage(); + } + catch (...) + { + AbortMessage(); + throw; + } + } + + template + void PushMessage(const char* pszCommand, const T1& a1, const T2& a2, const T3& a3, const T4& a4) + { + try + { + BeginMessage(pszCommand); + vSend << a1 << a2 << a3 << a4; + EndMessage(); + } + catch (...) + { + AbortMessage(); + throw; + } + } + + + void PushRequest(const char* pszCommand, + void (*fn)(void*, CDataStream&), void* param1) + { + uint256 hashReply; + RAND_bytes((unsigned char*)&hashReply, sizeof(hashReply)); + + CRITICAL_BLOCK(cs_mapRequests) + mapRequests[hashReply] = CRequestTracker(fn, param1); + + PushMessage(pszCommand, hashReply); + } + + template + void PushRequest(const char* pszCommand, const T1& a1, + void (*fn)(void*, CDataStream&), void* param1) + { + uint256 hashReply; + RAND_bytes((unsigned char*)&hashReply, sizeof(hashReply)); + + CRITICAL_BLOCK(cs_mapRequests) + mapRequests[hashReply] = CRequestTracker(fn, param1); + + PushMessage(pszCommand, hashReply, a1); + } + + template + void PushRequest(const char* pszCommand, const T1& a1, const T2& a2, + void (*fn)(void*, CDataStream&), void* param1) + { + uint256 hashReply; + RAND_bytes((unsigned char*)&hashReply, sizeof(hashReply)); + + CRITICAL_BLOCK(cs_mapRequests) + mapRequests[hashReply] = CRequestTracker(fn, param1); + + PushMessage(pszCommand, hashReply, a1, a2); + } + + + + bool IsSubscribed(unsigned int nChannel); + void Subscribe(unsigned int nChannel, unsigned int nHops=0); + void CancelSubscribe(unsigned int nChannel); + void Disconnect(); +}; + + + + + + + + + + +inline void RelayInventory(const CInv& inv) +{ + // Put on lists to offer to the other nodes + CRITICAL_BLOCK(cs_vNodes) + foreach(CNode* pnode, vNodes) + pnode->PushInventory(inv); +} + +template +void RelayMessage(const CInv& inv, const T& a) +{ + CDataStream ss(SER_NETWORK); + ss.reserve(10000); + ss << a; + RelayMessage(inv, ss); +} + +template<> +inline void RelayMessage<>(const CInv& inv, const CDataStream& ss) +{ + CRITICAL_BLOCK(cs_mapRelay) + { + // Expire old relay messages + while (!vRelayExpiration.empty() && vRelayExpiration.front().first < GetTime()) + { + mapRelay.erase(vRelayExpiration.front().second); + vRelayExpiration.pop_front(); + } + + // Save original serialized message so newer versions are preserved + mapRelay[inv] = ss; + vRelayExpiration.push_back(make_pair(GetTime() + 15 * 60, inv)); + } + + RelayInventory(inv); +} + + + + + + + + +// +// Templates for the publish and subscription system. +// The object being published as T& obj needs to have: +// a set setSources member +// specializations of AdvertInsert and AdvertErase +// Currently implemented for CTable and CProduct. +// + +template +void AdvertStartPublish(CNode* pfrom, unsigned int nChannel, unsigned int nHops, T& obj) +{ + // Add to sources + obj.setSources.insert(pfrom->addr.ip); + + if (!AdvertInsert(obj)) + return; + + // Relay + CRITICAL_BLOCK(cs_vNodes) + foreach(CNode* pnode, vNodes) + if (pnode != pfrom && (nHops < PUBLISH_HOPS || pnode->IsSubscribed(nChannel))) + pnode->PushMessage("publish", nChannel, nHops, obj); +} + +template +void AdvertStopPublish(CNode* pfrom, unsigned int nChannel, unsigned int nHops, T& obj) +{ + uint256 hash = obj.GetHash(); + + CRITICAL_BLOCK(cs_vNodes) + foreach(CNode* pnode, vNodes) + if (pnode != pfrom && (nHops < PUBLISH_HOPS || pnode->IsSubscribed(nChannel))) + pnode->PushMessage("pub-cancel", nChannel, nHops, hash); + + AdvertErase(obj); +} + +template +void AdvertRemoveSource(CNode* pfrom, unsigned int nChannel, unsigned int nHops, T& obj) +{ + // Remove a source + obj.setSources.erase(pfrom->addr.ip); + + // If no longer supported by any sources, cancel it + if (obj.setSources.empty()) + AdvertStopPublish(pfrom, nChannel, nHops, obj); +} diff --git a/rc/addressbook16.bmp b/rc/addressbook16.bmp new file mode 100644 index 0000000000..c5576910b1 Binary files /dev/null and b/rc/addressbook16.bmp differ diff --git a/rc/addressbook16mask.bmp b/rc/addressbook16mask.bmp new file mode 100644 index 0000000000..d3a478d1ad Binary files /dev/null and b/rc/addressbook16mask.bmp differ diff --git a/rc/addressbook20.bmp b/rc/addressbook20.bmp new file mode 100644 index 0000000000..2b33b228aa Binary files /dev/null and b/rc/addressbook20.bmp differ diff --git a/rc/addressbook20mask.bmp b/rc/addressbook20mask.bmp new file mode 100644 index 0000000000..56ce6125db Binary files /dev/null and b/rc/addressbook20mask.bmp differ diff --git a/rc/bitcoin.ico b/rc/bitcoin.ico new file mode 100644 index 0000000000..88cc240e2d Binary files /dev/null and b/rc/bitcoin.ico differ diff --git a/rc/check.ico b/rc/check.ico new file mode 100644 index 0000000000..0c4e6e8147 Binary files /dev/null and b/rc/check.ico differ diff --git a/rc/send16.bmp b/rc/send16.bmp new file mode 100644 index 0000000000..676b5c4b49 Binary files /dev/null and b/rc/send16.bmp differ diff --git a/rc/send16mask.bmp b/rc/send16mask.bmp new file mode 100644 index 0000000000..06c747f934 Binary files /dev/null and b/rc/send16mask.bmp differ diff --git a/rc/send16masknoshadow.bmp b/rc/send16masknoshadow.bmp new file mode 100644 index 0000000000..faf24e0d8a Binary files /dev/null and b/rc/send16masknoshadow.bmp differ diff --git a/rc/send20.bmp b/rc/send20.bmp new file mode 100644 index 0000000000..2b90422b38 Binary files /dev/null and b/rc/send20.bmp differ diff --git a/rc/send20mask.bmp b/rc/send20mask.bmp new file mode 100644 index 0000000000..f124d0da08 Binary files /dev/null and b/rc/send20mask.bmp differ diff --git a/readme.txt b/readme.txt new file mode 100644 index 0000000000..7615e6fd83 --- /dev/null +++ b/readme.txt @@ -0,0 +1,76 @@ +BitCoin v0.1.5 ALPHA + +Copyright (c) 2009 Satoshi Nakamoto +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/). This product includes +cryptographic software written by Eric Young (eay@cryptsoft.com). + + +Compilers Supported +------------------- +MinGW GCC (v3.4.5) +Microsoft Visual C++ 6.0 SP6 + + +Dependencies +------------ +Libraries you need to obtain separately to build: + + default path download +wxWidgets \wxWidgets http://www.wxwidgets.org/downloads/ +OpenSSL \OpenSSL http://www.openssl.org/source/ +Berkeley DB \DB http://www.oracle.com/technology/software/products/berkeley-db/index.html +Boost \Boost http://www.boost.org/users/download/ + +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 + + +OpenSSL +------- +Bitcoin does not use any encryption. If you want to do a no-everything +build of OpenSSL to exclude encryption routines, a few patches are required. +(OpenSSL v0.9.8h) + +Edit engines\e_gmp.c and put this #ifndef around #include + #ifndef OPENSSL_NO_RSA + #include + #endif + +Add this to crypto\err\err_all.c before the ERR_load_crypto_strings line: + void ERR_load_RSA_strings(void) { } + +Edit ms\mingw32.bat and replace the Configure line's parameters with this +no-everything list. You have to put this in the batch file because batch +files can't handle more than 9 parameters. + perl Configure mingw threads no-rc2 no-rc4 no-rc5 no-idea no-des no-bf no-cast no-aes no-camellia no-seed no-rsa no-dh + +Also REM out the following line in ms\mingw32.bat. The build fails after it's +already finished building libeay32, which is all we care about, but the +failure aborts the script before it runs dllwrap to generate libeay32.dll. + REM if errorlevel 1 goto end + +Build + ms\mingw32.bat + +If you want to use it with MSVC, generate the .lib file + lib /machine:i386 /def:ms\libeay32.def /out:out\libeay32.lib + + +Berkeley DB +----------- +MinGW with MSYS: +cd \DB\build_unix +sh ../dist/configure --enable-mingw --enable-cxx +make + + +Boost +----- +You may need Boost version 1.35 to build with MSVC 6.0. I couldn't get +version 1.37 to compile with MSVC 6.0. diff --git a/script.cpp b/script.cpp new file mode 100644 index 0000000000..0e95af503c --- /dev/null +++ b/script.cpp @@ -0,0 +1,1127 @@ +// Copyright (c) 2009 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" + +bool CheckSig(vector vchSig, vector vchPubKey, CScript scriptCode, const CTransaction& txTo, unsigned int nIn, int nHashType); + + + +typedef vector valtype; +static const valtype vchFalse(0); +static const valtype vchZero(0); +static const valtype vchTrue(1, 1); +static const CBigNum bnZero(0); +static const CBigNum bnOne(1); +static const CBigNum bnFalse(0); +static const CBigNum bnTrue(1); + + +bool CastToBool(const valtype& vch) +{ + return (CBigNum(vch) != bnZero); +} + +void MakeSameSize(valtype& vch1, valtype& vch2) +{ + // Lengthen the shorter one + if (vch1.size() < vch2.size()) + vch1.resize(vch2.size(), 0); + if (vch2.size() < vch1.size()) + vch2.resize(vch1.size(), 0); +} + + + +// +// Script is a stack machine (like Forth) that evaluates a predicate +// returning a bool indicating valid or not. There are no loops. +// +#define stacktop(i) (stack.at(stack.size()+(i))) +#define altstacktop(i) (altstack.at(altstack.size()+(i))) + +bool EvalScript(const CScript& script, const CTransaction& txTo, unsigned int nIn, int nHashType, + vector >* pvStackRet) +{ + CAutoBN_CTX pctx; + CScript::const_iterator pc = script.begin(); + CScript::const_iterator pend = script.end(); + CScript::const_iterator pbegincodehash = script.begin(); + vector vfExec; + vector stack; + vector altstack; + if (pvStackRet) + pvStackRet->clear(); + + + while (pc < pend) + { + bool fExec = !count(vfExec.begin(), vfExec.end(), false); + + // + // Read instruction + // + opcodetype opcode; + valtype vchPushValue; + if (!script.GetOp(pc, opcode, vchPushValue)) + return false; + + if (fExec && opcode <= OP_PUSHDATA4) + stack.push_back(vchPushValue); + else if (fExec || (OP_IF <= opcode && opcode <= OP_ENDIF)) + switch (opcode) + { + // + // Push value + // + case OP_1NEGATE: + case OP_1: + case OP_2: + case OP_3: + case OP_4: + case OP_5: + case OP_6: + case OP_7: + case OP_8: + case OP_9: + case OP_10: + case OP_11: + case OP_12: + case OP_13: + case OP_14: + case OP_15: + case OP_16: + { + // ( -- value) + CBigNum bn((int)opcode - (int)(OP_1 - 1)); + stack.push_back(bn.getvch()); + } + break; + + + // + // Control + // + case OP_NOP: + break; + + case OP_VER: + { + CBigNum bn(VERSION); + stack.push_back(bn.getvch()); + } + break; + + case OP_IF: + case OP_NOTIF: + case OP_VERIF: + case OP_VERNOTIF: + { + // if [statements] [else [statements]] endif + bool fValue = false; + if (fExec) + { + if (stack.size() < 1) + return false; + valtype& vch = stacktop(-1); + if (opcode == OP_VERIF || opcode == OP_VERNOTIF) + fValue = (CBigNum(VERSION) >= CBigNum(vch)); + else + fValue = CastToBool(vch); + if (opcode == OP_NOTIF || opcode == OP_VERNOTIF) + fValue = !fValue; + stack.pop_back(); + } + vfExec.push_back(fValue); + } + break; + + case OP_ELSE: + { + if (vfExec.empty()) + return false; + vfExec.back() = !vfExec.back(); + } + break; + + case OP_ENDIF: + { + if (vfExec.empty()) + return false; + vfExec.pop_back(); + } + break; + + case OP_VERIFY: + { + // (true -- ) or + // (false -- false) and return + if (stack.size() < 1) + return false; + bool fValue = CastToBool(stacktop(-1)); + if (fValue) + stack.pop_back(); + else + pc = pend; + } + break; + + case OP_RETURN: + { + pc = pend; + } + break; + + + // + // Stack ops + // + case OP_TOALTSTACK: + { + if (stack.size() < 1) + return false; + altstack.push_back(stacktop(-1)); + stack.pop_back(); + } + break; + + case OP_FROMALTSTACK: + { + if (altstack.size() < 1) + return false; + stack.push_back(altstacktop(-1)); + altstack.pop_back(); + } + break; + + case OP_2DROP: + { + // (x1 x2 -- ) + stack.pop_back(); + stack.pop_back(); + } + break; + + case OP_2DUP: + { + // (x1 x2 -- x1 x2 x1 x2) + if (stack.size() < 2) + return false; + valtype vch1 = stacktop(-2); + valtype vch2 = stacktop(-1); + stack.push_back(vch1); + stack.push_back(vch2); + } + break; + + case OP_3DUP: + { + // (x1 x2 x3 -- x1 x2 x3 x1 x2 x3) + if (stack.size() < 3) + return false; + valtype vch1 = stacktop(-3); + valtype vch2 = stacktop(-2); + valtype vch3 = stacktop(-1); + stack.push_back(vch1); + stack.push_back(vch2); + stack.push_back(vch3); + } + break; + + case OP_2OVER: + { + // (x1 x2 x3 x4 -- x1 x2 x3 x4 x1 x2) + if (stack.size() < 4) + return false; + valtype vch1 = stacktop(-4); + valtype vch2 = stacktop(-3); + stack.push_back(vch1); + stack.push_back(vch2); + } + break; + + case OP_2ROT: + { + // (x1 x2 x3 x4 x5 x6 -- x3 x4 x5 x6 x1 x2) + if (stack.size() < 6) + return false; + valtype vch1 = stacktop(-6); + valtype vch2 = stacktop(-5); + stack.erase(stack.end()-6, stack.end()-4); + stack.push_back(vch1); + stack.push_back(vch2); + } + break; + + case OP_2SWAP: + { + // (x1 x2 x3 x4 -- x3 x4 x1 x2) + if (stack.size() < 4) + return false; + swap(stacktop(-4), stacktop(-2)); + swap(stacktop(-3), stacktop(-1)); + } + break; + + case OP_IFDUP: + { + // (x - 0 | x x) + if (stack.size() < 1) + return false; + valtype vch = stacktop(-1); + if (CastToBool(vch)) + stack.push_back(vch); + } + break; + + case OP_DEPTH: + { + // -- stacksize + CBigNum bn(stack.size()); + stack.push_back(bn.getvch()); + } + break; + + case OP_DROP: + { + // (x -- ) + if (stack.size() < 1) + return false; + stack.pop_back(); + } + break; + + case OP_DUP: + { + // (x -- x x) + if (stack.size() < 1) + return false; + valtype vch = stacktop(-1); + stack.push_back(vch); + } + break; + + case OP_NIP: + { + // (x1 x2 -- x2) + if (stack.size() < 2) + return false; + stack.erase(stack.end() - 2); + } + break; + + case OP_OVER: + { + // (x1 x2 -- x1 x2 x1) + if (stack.size() < 2) + return false; + valtype vch = stacktop(-2); + stack.push_back(vch); + } + break; + + case OP_PICK: + case OP_ROLL: + { + // (xn ... x2 x1 x0 n - xn ... x2 x1 x0 xn) + // (xn ... x2 x1 x0 n - ... x2 x1 x0 xn) + if (stack.size() < 2) + return false; + int n = CBigNum(stacktop(-1)).getint(); + stack.pop_back(); + if (n < 0 || n >= stack.size()) + return false; + valtype vch = stacktop(-n-1); + if (opcode == OP_ROLL) + stack.erase(stack.end()-n-1); + stack.push_back(vch); + } + break; + + case OP_ROT: + { + // (x1 x2 x3 -- x2 x3 x1) + // x2 x1 x3 after first swap + // x2 x3 x1 after second swap + if (stack.size() < 3) + return false; + swap(stacktop(-3), stacktop(-2)); + swap(stacktop(-2), stacktop(-1)); + } + break; + + case OP_SWAP: + { + // (x1 x2 -- x2 x1) + if (stack.size() < 2) + return false; + swap(stacktop(-2), stacktop(-1)); + } + break; + + case OP_TUCK: + { + // (x1 x2 -- x2 x1 x2) + if (stack.size() < 2) + return false; + valtype vch = stacktop(-1); + stack.insert(stack.end()-2, vch); + } + break; + + + // + // Splice ops + // + case OP_CAT: + { + // (x1 x2 -- out) + if (stack.size() < 2) + return false; + valtype& vch1 = stacktop(-2); + valtype& vch2 = stacktop(-1); + vch1.insert(vch1.end(), vch2.begin(), vch2.end()); + stack.pop_back(); + } + break; + + case OP_SUBSTR: + { + // (in begin size -- out) + if (stack.size() < 3) + return false; + valtype& vch = stacktop(-3); + int nBegin = CBigNum(stacktop(-2)).getint(); + int nEnd = nBegin + CBigNum(stacktop(-1)).getint(); + if (nBegin < 0 || nEnd < nBegin) + return false; + if (nBegin > vch.size()) + nBegin = vch.size(); + if (nEnd > vch.size()) + nEnd = vch.size(); + vch.erase(vch.begin() + nEnd, vch.end()); + vch.erase(vch.begin(), vch.begin() + nBegin); + stack.pop_back(); + stack.pop_back(); + } + break; + + case OP_LEFT: + case OP_RIGHT: + { + // (in size -- out) + if (stack.size() < 2) + return false; + valtype& vch = stacktop(-2); + int nSize = CBigNum(stacktop(-1)).getint(); + if (nSize < 0) + return false; + if (nSize > vch.size()) + nSize = vch.size(); + if (opcode == OP_LEFT) + vch.erase(vch.begin() + nSize, vch.end()); + else + vch.erase(vch.begin(), vch.end() - nSize); + stack.pop_back(); + } + break; + + case OP_SIZE: + { + // (in -- in size) + if (stack.size() < 1) + return false; + CBigNum bn(stacktop(-1).size()); + stack.push_back(bn.getvch()); + } + break; + + + // + // Bitwise logic + // + case OP_INVERT: + { + // (in - out) + if (stack.size() < 1) + return false; + valtype& vch = stacktop(-1); + for (int i = 0; i < vch.size(); i++) + vch[i] = ~vch[i]; + } + break; + + case OP_AND: + case OP_OR: + case OP_XOR: + { + // (x1 x2 - out) + if (stack.size() < 2) + return false; + valtype& vch1 = stacktop(-2); + valtype& vch2 = stacktop(-1); + MakeSameSize(vch1, vch2); + if (opcode == OP_AND) + { + for (int i = 0; i < vch1.size(); i++) + vch1[i] &= vch2[i]; + } + else if (opcode == OP_OR) + { + for (int i = 0; i < vch1.size(); i++) + vch1[i] |= vch2[i]; + } + else if (opcode == OP_XOR) + { + for (int i = 0; i < vch1.size(); i++) + vch1[i] ^= vch2[i]; + } + stack.pop_back(); + } + break; + + case OP_EQUAL: + case OP_EQUALVERIFY: + //case OP_NOTEQUAL: // use OP_NUMNOTEQUAL + { + // (x1 x2 - bool) + if (stack.size() < 2) + return false; + valtype& vch1 = stacktop(-2); + valtype& vch2 = stacktop(-1); + bool fEqual = (vch1 == vch2); + // OP_NOTEQUAL is disabled because it would be too easy to say + // something like n != 1 and have some wiseguy pass in 1 with extra + // zero bytes after it (numerically, 0x01 == 0x0001 == 0x000001) + //if (opcode == OP_NOTEQUAL) + // fEqual = !fEqual; + stack.pop_back(); + stack.pop_back(); + stack.push_back(fEqual ? vchTrue : vchFalse); + if (opcode == OP_EQUALVERIFY) + { + if (fEqual) + stack.pop_back(); + else + pc = pend; + } + } + break; + + + // + // Numeric + // + case OP_1ADD: + case OP_1SUB: + case OP_2MUL: + case OP_2DIV: + case OP_NEGATE: + case OP_ABS: + case OP_NOT: + case OP_0NOTEQUAL: + { + // (in -- out) + if (stack.size() < 1) + return false; + CBigNum bn(stacktop(-1)); + switch (opcode) + { + case OP_1ADD: bn += bnOne; break; + case OP_1SUB: bn -= bnOne; break; + case OP_2MUL: bn <<= 1; break; + case OP_2DIV: bn >>= 1; break; + case OP_NEGATE: bn = -bn; break; + case OP_ABS: if (bn < bnZero) bn = -bn; break; + case OP_NOT: bn = (bn == bnZero); break; + case OP_0NOTEQUAL: bn = (bn != bnZero); break; + } + stack.pop_back(); + stack.push_back(bn.getvch()); + } + break; + + case OP_ADD: + case OP_SUB: + case OP_MUL: + case OP_DIV: + case OP_MOD: + case OP_LSHIFT: + case OP_RSHIFT: + case OP_BOOLAND: + case OP_BOOLOR: + case OP_NUMEQUAL: + case OP_NUMEQUALVERIFY: + case OP_NUMNOTEQUAL: + case OP_LESSTHAN: + case OP_GREATERTHAN: + case OP_LESSTHANOREQUAL: + case OP_GREATERTHANOREQUAL: + case OP_MIN: + case OP_MAX: + { + // (x1 x2 -- out) + if (stack.size() < 2) + return false; + CBigNum bn1(stacktop(-2)); + CBigNum bn2(stacktop(-1)); + CBigNum bn; + switch (opcode) + { + case OP_ADD: + bn = bn1 + bn2; + break; + + case OP_SUB: + bn = bn1 - bn2; + break; + + case OP_MUL: + if (!BN_mul(&bn, &bn1, &bn2, pctx)) + return false; + break; + + case OP_DIV: + if (!BN_div(&bn, NULL, &bn1, &bn2, pctx)) + return false; + break; + + case OP_MOD: + if (!BN_mod(&bn, &bn1, &bn2, pctx)) + return false; + break; + + case OP_LSHIFT: + if (bn2 < bnZero) + return false; + bn = bn1 << bn2.getulong(); + break; + + case OP_RSHIFT: + if (bn2 < bnZero) + return false; + bn = bn1 >> bn2.getulong(); + break; + + case OP_BOOLAND: bn = (bn1 != bnZero && bn2 != bnZero); break; + case OP_BOOLOR: bn = (bn1 != bnZero || bn2 != bnZero); break; + case OP_NUMEQUAL: bn = (bn1 == bn2); break; + case OP_NUMEQUALVERIFY: bn = (bn1 == bn2); break; + case OP_NUMNOTEQUAL: bn = (bn1 != bn2); break; + case OP_LESSTHAN: bn = (bn1 < bn2); break; + case OP_GREATERTHAN: bn = (bn1 > bn2); break; + case OP_LESSTHANOREQUAL: bn = (bn1 <= bn2); break; + 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; + } + stack.pop_back(); + stack.pop_back(); + stack.push_back(bn.getvch()); + + if (opcode == OP_NUMEQUALVERIFY) + { + if (CastToBool(stacktop(-1))) + stack.pop_back(); + else + pc = pend; + } + } + break; + + case OP_WITHIN: + { + // (x min max -- out) + if (stack.size() < 3) + return false; + CBigNum bn1(stacktop(-3)); + CBigNum bn2(stacktop(-2)); + CBigNum bn3(stacktop(-1)); + bool fValue = (bn2 <= bn1 && bn1 < bn3); + stack.pop_back(); + stack.pop_back(); + stack.pop_back(); + stack.push_back(fValue ? vchTrue : vchFalse); + } + break; + + + // + // Crypto + // + case OP_RIPEMD160: + case OP_SHA1: + case OP_SHA256: + case OP_HASH160: + case OP_HASH256: + { + // (in -- hash) + if (stack.size() < 1) + return false; + valtype& vch = stacktop(-1); + valtype vchHash(opcode == OP_RIPEMD160 || opcode == OP_SHA1 || opcode == OP_HASH160 ? 20 : 32); + if (opcode == OP_RIPEMD160) + RIPEMD160(&vch[0], vch.size(), &vchHash[0]); + else if (opcode == OP_SHA1) + SHA1(&vch[0], vch.size(), &vchHash[0]); + else if (opcode == OP_SHA256) + SHA256(&vch[0], vch.size(), &vchHash[0]); + else if (opcode == OP_HASH160) + { + uint160 hash160 = Hash160(vch); + memcpy(&vchHash[0], &hash160, sizeof(hash160)); + } + else if (opcode == OP_HASH256) + { + uint256 hash = Hash(vch.begin(), vch.end()); + memcpy(&vchHash[0], &hash, sizeof(hash)); + } + stack.pop_back(); + stack.push_back(vchHash); + } + break; + + case OP_CODESEPARATOR: + { + // Hash starts after the code separator + pbegincodehash = pc; + } + break; + + case OP_CHECKSIG: + case OP_CHECKSIGVERIFY: + { + // (sig pubkey -- bool) + if (stack.size() < 2) + return false; + + valtype& vchSig = stacktop(-2); + valtype& vchPubKey = stacktop(-1); + + ////// debug print + //PrintHex(vchSig.begin(), vchSig.end(), "sig: %s\n"); + //PrintHex(vchPubKey.begin(), vchPubKey.end(), "pubkey: %s\n"); + + // Subset of script starting at the most recent codeseparator + CScript scriptCode(pbegincodehash, pend); + + // Drop the signature, since there's no way for a signature to sign itself + scriptCode.FindAndDelete(CScript(vchSig)); + + bool fSuccess = CheckSig(vchSig, vchPubKey, scriptCode, txTo, nIn, nHashType); + + stack.pop_back(); + stack.pop_back(); + stack.push_back(fSuccess ? vchTrue : vchFalse); + if (opcode == OP_CHECKSIGVERIFY) + { + if (fSuccess) + stack.pop_back(); + else + pc = pend; + } + } + break; + + case OP_CHECKMULTISIG: + case OP_CHECKMULTISIGVERIFY: + { + // ([sig ...] num_of_signatures [pubkey ...] num_of_pubkeys -- bool) + + int i = 1; + if (stack.size() < i) + return false; + + int nKeysCount = CBigNum(stacktop(-i)).getint(); + if (nKeysCount < 0) + return false; + int ikey = ++i; + i += nKeysCount; + if (stack.size() < i) + return false; + + int nSigsCount = CBigNum(stacktop(-i)).getint(); + if (nSigsCount < 0 || nSigsCount > nKeysCount) + return false; + int isig = ++i; + i += nSigsCount; + if (stack.size() < i) + return false; + + // Subset of script starting at the most recent codeseparator + CScript scriptCode(pbegincodehash, pend); + + // Drop the signatures, since there's no way for a signature to sign itself + for (int i = 0; i < nSigsCount; i++) + { + valtype& vchSig = stacktop(-isig-i); + scriptCode.FindAndDelete(CScript(vchSig)); + } + + bool fSuccess = true; + while (fSuccess && nSigsCount > 0) + { + valtype& vchSig = stacktop(-isig); + valtype& vchPubKey = stacktop(-ikey); + + // Check signature + if (CheckSig(vchSig, vchPubKey, scriptCode, txTo, nIn, nHashType)) + { + isig++; + nSigsCount--; + } + ikey++; + nKeysCount--; + + // If there are more signatures left than keys left, + // then too many signatures have failed + if (nSigsCount > nKeysCount) + fSuccess = false; + } + + while (i-- > 0) + stack.pop_back(); + stack.push_back(fSuccess ? vchTrue : vchFalse); + + if (opcode == OP_CHECKMULTISIGVERIFY) + { + if (fSuccess) + stack.pop_back(); + else + pc = pend; + } + } + break; + + default: + return false; + } + } + + + if (pvStackRet) + *pvStackRet = stack; + return (stack.empty() ? false : CastToBool(stack.back())); +} + +#undef top + + + + + + + + + +uint256 SignatureHash(CScript scriptCode, const CTransaction& txTo, unsigned int nIn, int nHashType) +{ + if (nIn >= txTo.vin.size()) + { + printf("ERROR: SignatureHash() : nIn=%d out of range\n", nIn); + return 1; + } + CTransaction txTmp(txTo); + + // In case concatenating two scripts ends up with two codeseparators, + // or an extra one at the end, this prevents all those possible incompatibilities. + scriptCode.FindAndDelete(CScript(OP_CODESEPARATOR)); + + // Blank out other inputs' signatures + for (int i = 0; i < txTmp.vin.size(); i++) + txTmp.vin[i].scriptSig = CScript(); + txTmp.vin[nIn].scriptSig = scriptCode; + + // Blank out some of the outputs + if ((nHashType & 0x1f) == SIGHASH_NONE) + { + // Wildcard payee + txTmp.vout.clear(); + + // Let the others update at will + for (int i = 0; i < txTmp.vin.size(); i++) + if (i != nIn) + txTmp.vin[i].nSequence = 0; + } + else if ((nHashType & 0x1f) == SIGHASH_SINGLE) + { + // Only lockin the txout payee at same index as txin + unsigned int nOut = nIn; + if (nOut >= txTmp.vout.size()) + { + printf("ERROR: SignatureHash() : nOut=%d out of range\n", nOut); + return 1; + } + txTmp.vout.resize(nOut+1); + for (int i = 0; i < nOut; i++) + txTmp.vout[i].SetNull(); + + // Let the others update at will + for (int i = 0; i < txTmp.vin.size(); i++) + if (i != nIn) + txTmp.vin[i].nSequence = 0; + } + + // Blank out other inputs completely, not recommended for open transactions + if (nHashType & SIGHASH_ANYONECANPAY) + { + txTmp.vin[0] = txTmp.vin[nIn]; + txTmp.vin.resize(1); + } + + // Serialize and hash + CDataStream ss(SER_GETHASH); + ss.reserve(10000); + ss << txTmp << nHashType; + return Hash(ss.begin(), ss.end()); +} + + +bool CheckSig(vector vchSig, vector vchPubKey, CScript scriptCode, + const CTransaction& txTo, unsigned int nIn, int nHashType) +{ + CKey key; + if (!key.SetPubKey(vchPubKey)) + return false; + + // Hash type is one byte tacked on to the end of the signature + if (vchSig.empty()) + return false; + if (nHashType == 0) + nHashType = vchSig.back(); + else if (nHashType != vchSig.back()) + return false; + vchSig.pop_back(); + + if (key.Verify(SignatureHash(scriptCode, txTo, nIn, nHashType), vchSig)) + return true; + + return false; +} + + + + + + + + + + + +bool Solver(const CScript& scriptPubKey, vector >& vSolutionRet) +{ + // Templates + static vector vTemplates; + if (vTemplates.empty()) + { + // Standard tx, sender provides pubkey, receiver adds signature + vTemplates.push_back(CScript() << OP_PUBKEY << OP_CHECKSIG); + + // Short account number tx, sender provides hash of pubkey, receiver provides signature and pubkey + vTemplates.push_back(CScript() << OP_DUP << OP_HASH160 << OP_PUBKEYHASH << OP_EQUALVERIFY << OP_CHECKSIG); + } + + // Scan templates + const CScript& script1 = scriptPubKey; + foreach(const CScript& script2, vTemplates) + { + vSolutionRet.clear(); + opcodetype opcode1, opcode2; + vector vch1, vch2; + + // Compare + CScript::const_iterator pc1 = script1.begin(); + CScript::const_iterator pc2 = script2.begin(); + loop + { + bool f1 = script1.GetOp(pc1, opcode1, vch1); + bool f2 = script2.GetOp(pc2, opcode2, vch2); + if (!f1 && !f2) + { + // Success + reverse(vSolutionRet.begin(), vSolutionRet.end()); + return true; + } + else if (f1 != f2) + { + break; + } + else if (opcode2 == OP_PUBKEY) + { + if (vch1.size() <= sizeof(uint256)) + break; + vSolutionRet.push_back(make_pair(opcode2, vch1)); + } + else if (opcode2 == OP_PUBKEYHASH) + { + if (vch1.size() != sizeof(uint160)) + break; + vSolutionRet.push_back(make_pair(opcode2, vch1)); + } + else if (opcode1 != opcode2) + { + break; + } + } + } + + vSolutionRet.clear(); + return false; +} + + +bool Solver(const CScript& scriptPubKey, uint256 hash, int nHashType, CScript& scriptSigRet) +{ + scriptSigRet.clear(); + + vector > vSolution; + if (!Solver(scriptPubKey, vSolution)) + return false; + + // Compile solution + CRITICAL_BLOCK(cs_mapKeys) + { + foreach(PAIRTYPE(opcodetype, valtype)& item, vSolution) + { + if (item.first == OP_PUBKEY) + { + // Sign + const valtype& vchPubKey = item.second; + if (!mapKeys.count(vchPubKey)) + return false; + if (hash != 0) + { + vector vchSig; + if (!CKey::Sign(mapKeys[vchPubKey], hash, vchSig)) + return false; + vchSig.push_back((unsigned char)nHashType); + scriptSigRet << vchSig; + } + } + else if (item.first == OP_PUBKEYHASH) + { + // Sign and give pubkey + map::iterator mi = mapPubKeys.find(uint160(item.second)); + if (mi == mapPubKeys.end()) + return false; + const vector& vchPubKey = (*mi).second; + if (!mapKeys.count(vchPubKey)) + return false; + if (hash != 0) + { + vector vchSig; + if (!CKey::Sign(mapKeys[vchPubKey], hash, vchSig)) + return false; + vchSig.push_back((unsigned char)nHashType); + scriptSigRet << vchSig << vchPubKey; + } + } + } + } + + return true; +} + + +bool IsMine(const CScript& scriptPubKey) +{ + CScript scriptSig; + return Solver(scriptPubKey, 0, 0, scriptSig); +} + + +bool ExtractPubKey(const CScript& scriptPubKey, bool fMineOnly, vector& vchPubKeyRet) +{ + vchPubKeyRet.clear(); + + vector > vSolution; + if (!Solver(scriptPubKey, vSolution)) + return false; + + CRITICAL_BLOCK(cs_mapKeys) + { + foreach(PAIRTYPE(opcodetype, valtype)& item, vSolution) + { + valtype vchPubKey; + if (item.first == OP_PUBKEY) + { + vchPubKey = item.second; + } + else if (item.first == OP_PUBKEYHASH) + { + map::iterator mi = mapPubKeys.find(uint160(item.second)); + if (mi == mapPubKeys.end()) + continue; + vchPubKey = (*mi).second; + } + if (!fMineOnly || mapKeys.count(vchPubKey)) + { + vchPubKeyRet = vchPubKey; + return true; + } + } + } + return false; +} + + +bool ExtractHash160(const CScript& scriptPubKey, uint160& hash160Ret) +{ + hash160Ret = 0; + + vector > vSolution; + if (!Solver(scriptPubKey, vSolution)) + return false; + + foreach(PAIRTYPE(opcodetype, valtype)& item, vSolution) + { + if (item.first == OP_PUBKEYHASH) + { + hash160Ret = uint160(item.second); + return true; + } + } + return false; +} + + +bool SignSignature(const CTransaction& txFrom, CTransaction& txTo, unsigned int nIn, int nHashType, CScript scriptPrereq) +{ + assert(nIn < txTo.vin.size()); + CTxIn& txin = txTo.vin[nIn]; + assert(txin.prevout.n < txFrom.vout.size()); + const CTxOut& txout = txFrom.vout[txin.prevout.n]; + + // Leave out the signature from the hash, since a signature can't sign itself. + // The checksig op will also drop the signatures from its hash. + uint256 hash = SignatureHash(scriptPrereq + txout.scriptPubKey, txTo, nIn, nHashType); + + if (!Solver(txout.scriptPubKey, hash, nHashType, txin.scriptSig)) + return false; + + txin.scriptSig = scriptPrereq + txin.scriptSig; + + // Test solution + if (scriptPrereq.empty()) + if (!EvalScript(txin.scriptSig + CScript(OP_CODESEPARATOR) + txout.scriptPubKey, txTo, nIn)) + return false; + + return true; +} + + +bool VerifySignature(const CTransaction& txFrom, const CTransaction& txTo, unsigned int nIn, int nHashType) +{ + assert(nIn < txTo.vin.size()); + const CTxIn& txin = txTo.vin[nIn]; + if (txin.prevout.n >= txFrom.vout.size()) + return false; + const CTxOut& txout = txFrom.vout[txin.prevout.n]; + + if (txin.prevout.hash != txFrom.GetHash()) + return false; + + return EvalScript(txin.scriptSig + CScript(OP_CODESEPARATOR) + txout.scriptPubKey, txTo, nIn, nHashType); +} diff --git a/script.h b/script.h new file mode 100644 index 0000000000..0d977734b9 --- /dev/null +++ b/script.h @@ -0,0 +1,597 @@ +// Copyright (c) 2009 Satoshi Nakamoto +// Distributed under the MIT/X11 software license, see the accompanying +// file license.txt or http://www.opensource.org/licenses/mit-license.php. + +class CTransaction; + +enum +{ + SIGHASH_ALL = 1, + SIGHASH_NONE = 2, + SIGHASH_SINGLE = 3, + SIGHASH_ANYONECANPAY = 0x80, +}; + + + +enum opcodetype +{ + // push value + OP_0=0, + OP_FALSE=OP_0, + OP_PUSHDATA1=76, + OP_PUSHDATA2, + OP_PUSHDATA4, + OP_1NEGATE, + OP_RESERVED, + OP_1, + OP_TRUE=OP_1, + OP_2, + OP_3, + OP_4, + OP_5, + OP_6, + OP_7, + OP_8, + OP_9, + OP_10, + OP_11, + OP_12, + OP_13, + OP_14, + OP_15, + OP_16, + + // control + OP_NOP, + OP_VER, + OP_IF, + OP_NOTIF, + OP_VERIF, + OP_VERNOTIF, + OP_ELSE, + OP_ENDIF, + OP_VERIFY, + OP_RETURN, + + // stack ops + OP_TOALTSTACK, + OP_FROMALTSTACK, + OP_2DROP, + OP_2DUP, + OP_3DUP, + OP_2OVER, + OP_2ROT, + OP_2SWAP, + OP_IFDUP, + OP_DEPTH, + OP_DROP, + OP_DUP, + OP_NIP, + OP_OVER, + OP_PICK, + OP_ROLL, + OP_ROT, + OP_SWAP, + OP_TUCK, + + // splice ops + OP_CAT, + OP_SUBSTR, + OP_LEFT, + OP_RIGHT, + OP_SIZE, + + // bit logic + OP_INVERT, + OP_AND, + OP_OR, + OP_XOR, + OP_EQUAL, + OP_EQUALVERIFY, + OP_RESERVED1, + OP_RESERVED2, + + // numeric + OP_1ADD, + OP_1SUB, + OP_2MUL, + OP_2DIV, + OP_NEGATE, + OP_ABS, + OP_NOT, + OP_0NOTEQUAL, + + OP_ADD, + OP_SUB, + OP_MUL, + OP_DIV, + OP_MOD, + OP_LSHIFT, + OP_RSHIFT, + + OP_BOOLAND, + OP_BOOLOR, + OP_NUMEQUAL, + OP_NUMEQUALVERIFY, + OP_NUMNOTEQUAL, + OP_LESSTHAN, + OP_GREATERTHAN, + OP_LESSTHANOREQUAL, + OP_GREATERTHANOREQUAL, + OP_MIN, + OP_MAX, + + OP_WITHIN, + + // crypto + OP_RIPEMD160, + OP_SHA1, + OP_SHA256, + OP_HASH160, + OP_HASH256, + OP_CODESEPARATOR, + OP_CHECKSIG, + OP_CHECKSIGVERIFY, + OP_CHECKMULTISIG, + OP_CHECKMULTISIGVERIFY, + + + // multi-byte opcodes + OP_SINGLEBYTE_END = 0xF0, + OP_DOUBLEBYTE_BEGIN = 0xF000, + + // template matching params + OP_PUBKEY, + OP_PUBKEYHASH, + + + + OP_INVALIDOPCODE = 0xFFFF, +}; + + + + + + + + +inline const char* GetOpName(opcodetype opcode) +{ + switch (opcode) + { + // push value + case OP_0 : return "0"; + case OP_PUSHDATA1 : return "OP_PUSHDATA1"; + case OP_PUSHDATA2 : return "OP_PUSHDATA2"; + case OP_PUSHDATA4 : return "OP_PUSHDATA4"; + case OP_1NEGATE : return "-1"; + case OP_RESERVED : return "OP_RESERVED"; + case OP_1 : return "1"; + case OP_2 : return "2"; + case OP_3 : return "3"; + case OP_4 : return "4"; + case OP_5 : return "5"; + case OP_6 : return "6"; + case OP_7 : return "7"; + case OP_8 : return "8"; + case OP_9 : return "9"; + case OP_10 : return "10"; + case OP_11 : return "11"; + case OP_12 : return "12"; + case OP_13 : return "13"; + case OP_14 : return "14"; + case OP_15 : return "15"; + case OP_16 : return "16"; + + // control + case OP_NOP : return "OP_NOP"; + case OP_VER : return "OP_VER"; + case OP_IF : return "OP_IF"; + case OP_NOTIF : return "OP_NOTIF"; + case OP_VERIF : return "OP_VERIF"; + case OP_VERNOTIF : return "OP_VERNOTIF"; + case OP_ELSE : return "OP_ELSE"; + case OP_ENDIF : return "OP_ENDIF"; + case OP_VERIFY : return "OP_VERIFY"; + case OP_RETURN : return "OP_RETURN"; + + // stack ops + case OP_TOALTSTACK : return "OP_TOALTSTACK"; + case OP_FROMALTSTACK : return "OP_FROMALTSTACK"; + case OP_2DROP : return "OP_2DROP"; + case OP_2DUP : return "OP_2DUP"; + case OP_3DUP : return "OP_3DUP"; + case OP_2OVER : return "OP_2OVER"; + case OP_2ROT : return "OP_2ROT"; + case OP_2SWAP : return "OP_2SWAP"; + case OP_IFDUP : return "OP_IFDUP"; + case OP_DEPTH : return "OP_DEPTH"; + case OP_DROP : return "OP_DROP"; + case OP_DUP : return "OP_DUP"; + case OP_NIP : return "OP_NIP"; + case OP_OVER : return "OP_OVER"; + case OP_PICK : return "OP_PICK"; + case OP_ROLL : return "OP_ROLL"; + case OP_ROT : return "OP_ROT"; + case OP_SWAP : return "OP_SWAP"; + case OP_TUCK : return "OP_TUCK"; + + // splice ops + case OP_CAT : return "OP_CAT"; + case OP_SUBSTR : return "OP_SUBSTR"; + case OP_LEFT : return "OP_LEFT"; + case OP_RIGHT : return "OP_RIGHT"; + case OP_SIZE : return "OP_SIZE"; + + // bit logic + case OP_INVERT : return "OP_INVERT"; + case OP_AND : return "OP_AND"; + case OP_OR : return "OP_OR"; + case OP_XOR : return "OP_XOR"; + case OP_EQUAL : return "OP_EQUAL"; + case OP_EQUALVERIFY : return "OP_EQUALVERIFY"; + case OP_RESERVED1 : return "OP_RESERVED1"; + case OP_RESERVED2 : return "OP_RESERVED2"; + + // numeric + case OP_1ADD : return "OP_1ADD"; + case OP_1SUB : return "OP_1SUB"; + case OP_2MUL : return "OP_2MUL"; + case OP_2DIV : return "OP_2DIV"; + case OP_NEGATE : return "OP_NEGATE"; + case OP_ABS : return "OP_ABS"; + case OP_NOT : return "OP_NOT"; + case OP_0NOTEQUAL : return "OP_0NOTEQUAL"; + case OP_ADD : return "OP_ADD"; + case OP_SUB : return "OP_SUB"; + case OP_MUL : return "OP_MUL"; + case OP_DIV : return "OP_DIV"; + case OP_MOD : return "OP_MOD"; + case OP_LSHIFT : return "OP_LSHIFT"; + case OP_RSHIFT : return "OP_RSHIFT"; + case OP_BOOLAND : return "OP_BOOLAND"; + case OP_BOOLOR : return "OP_BOOLOR"; + case OP_NUMEQUAL : return "OP_NUMEQUAL"; + case OP_NUMEQUALVERIFY : return "OP_NUMEQUALVERIFY"; + case OP_NUMNOTEQUAL : return "OP_NUMNOTEQUAL"; + case OP_LESSTHAN : return "OP_LESSTHAN"; + case OP_GREATERTHAN : return "OP_GREATERTHAN"; + case OP_LESSTHANOREQUAL : return "OP_LESSTHANOREQUAL"; + case OP_GREATERTHANOREQUAL : return "OP_GREATERTHANOREQUAL"; + case OP_MIN : return "OP_MIN"; + case OP_MAX : return "OP_MAX"; + case OP_WITHIN : return "OP_WITHIN"; + + // crypto + case OP_RIPEMD160 : return "OP_RIPEMD160"; + case OP_SHA1 : return "OP_SHA1"; + case OP_SHA256 : return "OP_SHA256"; + case OP_HASH160 : return "OP_HASH160"; + case OP_HASH256 : return "OP_HASH256"; + case OP_CODESEPARATOR : return "OP_CODESEPARATOR"; + case OP_CHECKSIG : return "OP_CHECKSIG"; + case OP_CHECKSIGVERIFY : return "OP_CHECKSIGVERIFY"; + case OP_CHECKMULTISIG : return "OP_CHECKMULTISIG"; + case OP_CHECKMULTISIGVERIFY : return "OP_CHECKMULTISIGVERIFY"; + + + + // multi-byte opcodes + case OP_SINGLEBYTE_END : return "OP_SINGLEBYTE_END"; + case OP_DOUBLEBYTE_BEGIN : return "OP_DOUBLEBYTE_BEGIN"; + case OP_PUBKEY : return "OP_PUBKEY"; + case OP_PUBKEYHASH : return "OP_PUBKEYHASH"; + + + + case OP_INVALIDOPCODE : return "OP_INVALIDOPCODE"; + default: + return "UNKNOWN_OPCODE"; + } +}; + + + + +inline string ValueString(const vector& vch) +{ + if (vch.size() <= 4) + return strprintf("%d", CBigNum(vch).getint()); + else + return HexNumStr(vch.begin(), vch.end()); + //return string("(") + HexStr(vch.begin(), vch.end()) + string(")"); +} + +inline string StackString(const vector >& vStack) +{ + string str; + foreach(const vector& vch, vStack) + { + if (!str.empty()) + str += " "; + str += ValueString(vch); + } + return str; +} + + + + + + + + + +class CScript : public vector +{ +protected: + CScript& push_int64(int64 n) + { + if (n == -1 || (n >= 1 && n <= 16)) + { + push_back(n + (OP_1 - 1)); + } + else + { + CBigNum bn(n); + *this << bn.getvch(); + } + return (*this); + } + + CScript& push_uint64(uint64 n) + { + if (n == -1 || (n >= 1 && n <= 16)) + { + push_back(n + (OP_1 - 1)); + } + else + { + CBigNum bn(n); + *this << bn.getvch(); + } + return (*this); + } + +public: + CScript() { } + CScript(const CScript& b) : vector(b.begin(), b.end()) { } + CScript(const_iterator pbegin, const_iterator pend) : vector(pbegin, pend) { } +#ifndef _MSC_VER + CScript(const unsigned char* pbegin, const unsigned char* pend) : vector(pbegin, pend) { } +#endif + + CScript& operator+=(const CScript& b) + { + insert(end(), b.begin(), b.end()); + return *this; + } + + friend CScript operator+(const CScript& a, const CScript& b) + { + CScript ret = a; + ret += b; + return (ret); + } + + + explicit CScript(char b) { operator<<(b); } + explicit CScript(short b) { operator<<(b); } + explicit CScript(int b) { operator<<(b); } + explicit CScript(long b) { operator<<(b); } + explicit CScript(int64 b) { operator<<(b); } + explicit CScript(unsigned char b) { operator<<(b); } + explicit CScript(unsigned int b) { operator<<(b); } + explicit CScript(unsigned short b) { operator<<(b); } + explicit CScript(unsigned long b) { operator<<(b); } + explicit CScript(uint64 b) { operator<<(b); } + + explicit CScript(opcodetype b) { operator<<(b); } + explicit CScript(const uint256& b) { operator<<(b); } + explicit CScript(const CBigNum& b) { operator<<(b); } + explicit CScript(const vector& b) { operator<<(b); } + + + CScript& operator<<(char b) { return (push_int64(b)); } + CScript& operator<<(short b) { return (push_int64(b)); } + CScript& operator<<(int b) { return (push_int64(b)); } + CScript& operator<<(long b) { return (push_int64(b)); } + CScript& operator<<(int64 b) { return (push_int64(b)); } + CScript& operator<<(unsigned char b) { return (push_uint64(b)); } + CScript& operator<<(unsigned int b) { return (push_uint64(b)); } + CScript& operator<<(unsigned short b) { return (push_uint64(b)); } + CScript& operator<<(unsigned long b) { return (push_uint64(b)); } + CScript& operator<<(uint64 b) { return (push_uint64(b)); } + + CScript& operator<<(opcodetype opcode) + { + if (opcode <= OP_SINGLEBYTE_END) + { + insert(end(), (unsigned char)opcode); + } + else + { + assert(opcode >= OP_DOUBLEBYTE_BEGIN); + insert(end(), (unsigned char)(opcode >> 8)); + insert(end(), (unsigned char)(opcode & 0xFF)); + } + return (*this); + } + + CScript& operator<<(const uint160& b) + { + insert(end(), sizeof(b)); + insert(end(), (unsigned char*)&b, (unsigned char*)&b + sizeof(b)); + return (*this); + } + + CScript& operator<<(const uint256& b) + { + insert(end(), sizeof(b)); + insert(end(), (unsigned char*)&b, (unsigned char*)&b + sizeof(b)); + return (*this); + } + + CScript& operator<<(const CBigNum& b) + { + *this << b.getvch(); + return (*this); + } + + CScript& operator<<(const vector& b) + { + if (b.size() < OP_PUSHDATA1) + { + insert(end(), (unsigned char)b.size()); + } + else if (b.size() <= 0xff) + { + insert(end(), OP_PUSHDATA1); + insert(end(), (unsigned char)b.size()); + } + else + { + insert(end(), OP_PUSHDATA2); + unsigned short nSize = b.size(); + insert(end(), (unsigned char*)&nSize, (unsigned char*)&nSize + sizeof(nSize)); + } + insert(end(), b.begin(), b.end()); + return (*this); + } + + CScript& operator<<(const CScript& b) + { + // 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)); + return (*this); + } + + + bool GetOp(iterator& pc, opcodetype& opcodeRet, vector& vchRet) + { + // This is why people hate C++ + const_iterator pc2 = pc; + bool fRet = GetOp(pc2, opcodeRet, vchRet); + pc = begin() + (pc2 - begin()); + return fRet; + } + + bool GetOp(const_iterator& pc, opcodetype& opcodeRet, vector& vchRet) const + { + opcodeRet = OP_INVALIDOPCODE; + vchRet.clear(); + if (pc >= end()) + return false; + + // Read instruction + unsigned int opcode = *pc++; + if (opcode >= OP_SINGLEBYTE_END) + { + if (pc + 1 > end()) + return false; + opcode <<= 8; + opcode |= *pc++; + } + + // Immediate operand + if (opcode <= OP_PUSHDATA4) + { + unsigned int nSize = opcode; + if (opcode == OP_PUSHDATA1) + { + if (pc + 1 > end()) + return false; + nSize = *pc++; + } + else if (opcode == OP_PUSHDATA2) + { + if (pc + 2 > end()) + return false; + nSize = 0; + memcpy(&nSize, &pc[0], 2); + pc += 2; + } + else if (opcode == OP_PUSHDATA4) + { + if (pc + 4 > end()) + return false; + memcpy(&nSize, &pc[0], 4); + pc += 4; + } + if (pc + nSize > end()) + return false; + vchRet.assign(pc, pc + nSize); + pc += nSize; + } + + opcodeRet = (opcodetype)opcode; + return true; + } + + + void FindAndDelete(const CScript& b) + { + iterator pc = begin(); + opcodetype opcode; + vector vchPushValue; + int count = 0; + do + { + while (end() - pc >= b.size() && memcmp(&pc[0], &b[0], b.size()) == 0) + { + erase(pc, pc + b.size()); + count++; + } + } + while (GetOp(pc, opcode, vchPushValue)); + //printf("FindAndDeleted deleted %d items\n", count); /// debug + } + + + void PrintHex() const + { + printf("CScript(%s)\n", HexStr(begin(), end()).c_str()); + } + + string ToString() const + { + string str; + opcodetype opcode; + vector vch; + const_iterator it = begin(); + while (GetOp(it, opcode, vch)) + { + if (!str.empty()) + str += " "; + if (opcode <= OP_PUSHDATA4) + str += ValueString(vch); + else + str += GetOpName(opcode); + } + return str; + } + + void print() const + { + printf("%s\n", ToString().c_str()); + } +}; + + + + + + + + +bool EvalScript(const CScript& script, const CTransaction& txTo, unsigned int nIn, int nHashType=0, + vector >* pvStackRet=NULL); +uint256 SignatureHash(CScript scriptCode, const CTransaction& txTo, unsigned int nIn, int nHashType); +bool IsMine(const CScript& scriptPubKey); +bool ExtractPubKey(const CScript& scriptPubKey, bool fMineOnly, vector& vchPubKeyRet); +bool ExtractHash160(const CScript& scriptPubKey, uint160& hash160Ret); +bool SignSignature(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/serialize.h b/serialize.h new file mode 100644 index 0000000000..b7ab86d22a --- /dev/null +++ b/serialize.h @@ -0,0 +1,1158 @@ +// Copyright (c) 2009 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 +#include +#include +#if defined(_MSC_VER) || defined(__BORLANDC__) +typedef __int64 int64; +typedef unsigned __int64 uint64; +#else +typedef long long int64; +typedef unsigned long long uint64; +#endif +#if defined(_MSC_VER) && _MSC_VER < 1300 +#define for if (false) ; else for +#endif +class CScript; +class CDataStream; +class CAutoFile; + +static const int VERSION = 105; + + + + + +///////////////////////////////////////////////////////////////// +// +// Templates for serializing to anything that looks like a stream, +// i.e. anything that supports .read(char*, int) and .write(char*, int) +// + +enum +{ + // primary actions + SER_NETWORK = (1 << 0), + SER_DISK = (1 << 1), + SER_GETHASH = (1 << 2), + + // modifiers + SER_SKIPSIG = (1 << 16), + SER_BLOCKHEADERONLY = (1 << 17), +}; + +#define IMPLEMENT_SERIALIZE(statements) \ + unsigned int GetSerializeSize(int nType=0, int nVersion=VERSION) const \ + { \ + CSerActionGetSerializeSize ser_action; \ + const bool fGetSize = true; \ + const bool fWrite = false; \ + const bool fRead = false; \ + unsigned int nSerSize = 0; \ + ser_streamplaceholder s; \ + s.nType = nType; \ + s.nVersion = nVersion; \ + {statements} \ + return nSerSize; \ + } \ + template \ + void Serialize(Stream& s, int nType=0, int nVersion=VERSION) const \ + { \ + CSerActionSerialize ser_action; \ + const bool fGetSize = false; \ + const bool fWrite = true; \ + const bool fRead = false; \ + unsigned int nSerSize = 0; \ + {statements} \ + } \ + template \ + void Unserialize(Stream& s, int nType=0, int nVersion=VERSION) \ + { \ + CSerActionUnserialize ser_action; \ + const bool fGetSize = false; \ + const bool fWrite = false; \ + const bool fRead = true; \ + unsigned int nSerSize = 0; \ + {statements} \ + } + +#define READWRITE(obj) (nSerSize += ::SerReadWrite(s, (obj), nType, nVersion, ser_action)) + + + + + + +// +// Basic types +// +#define WRITEDATA(s, obj) s.write((char*)&(obj), sizeof(obj)) +#define READDATA(s, obj) s.read((char*)&(obj), sizeof(obj)) + +inline unsigned int GetSerializeSize(char a, int, int=0) { return sizeof(a); } +inline unsigned int GetSerializeSize(signed char a, int, int=0) { return sizeof(a); } +inline unsigned int GetSerializeSize(unsigned char a, int, int=0) { return sizeof(a); } +inline unsigned int GetSerializeSize(signed short a, int, int=0) { return sizeof(a); } +inline unsigned int GetSerializeSize(unsigned short a, int, int=0) { return sizeof(a); } +inline unsigned int GetSerializeSize(signed int a, int, int=0) { return sizeof(a); } +inline unsigned int GetSerializeSize(unsigned int a, int, int=0) { return sizeof(a); } +inline unsigned int GetSerializeSize(signed long a, int, int=0) { return sizeof(a); } +inline unsigned int GetSerializeSize(unsigned long a, int, int=0) { return sizeof(a); } +inline unsigned int GetSerializeSize(int64 a, int, int=0) { return sizeof(a); } +inline unsigned int GetSerializeSize(uint64 a, int, int=0) { return sizeof(a); } +inline unsigned int GetSerializeSize(float a, int, int=0) { return sizeof(a); } +inline unsigned int GetSerializeSize(double a, int, int=0) { return sizeof(a); } + +template inline void Serialize(Stream& s, char a, int, int=0) { WRITEDATA(s, a); } +template inline void Serialize(Stream& s, signed char a, int, int=0) { WRITEDATA(s, a); } +template inline void Serialize(Stream& s, unsigned char a, int, int=0) { WRITEDATA(s, a); } +template inline void Serialize(Stream& s, signed short a, int, int=0) { WRITEDATA(s, a); } +template inline void Serialize(Stream& s, unsigned short a, int, int=0) { WRITEDATA(s, a); } +template inline void Serialize(Stream& s, signed int a, int, int=0) { WRITEDATA(s, a); } +template inline void Serialize(Stream& s, unsigned int a, int, int=0) { WRITEDATA(s, a); } +template inline void Serialize(Stream& s, signed long a, int, int=0) { WRITEDATA(s, a); } +template inline void Serialize(Stream& s, unsigned long a, int, int=0) { WRITEDATA(s, a); } +template inline void Serialize(Stream& s, int64 a, int, int=0) { WRITEDATA(s, a); } +template inline void Serialize(Stream& s, uint64 a, int, int=0) { WRITEDATA(s, a); } +template inline void Serialize(Stream& s, float a, int, int=0) { WRITEDATA(s, a); } +template inline void Serialize(Stream& s, double a, int, int=0) { WRITEDATA(s, a); } + +template inline void Unserialize(Stream& s, char& a, int, int=0) { READDATA(s, a); } +template inline void Unserialize(Stream& s, signed char& a, int, int=0) { READDATA(s, a); } +template inline void Unserialize(Stream& s, unsigned char& a, int, int=0) { READDATA(s, a); } +template inline void Unserialize(Stream& s, signed short& a, int, int=0) { READDATA(s, a); } +template inline void Unserialize(Stream& s, unsigned short& a, int, int=0) { READDATA(s, a); } +template inline void Unserialize(Stream& s, signed int& a, int, int=0) { READDATA(s, a); } +template inline void Unserialize(Stream& s, unsigned int& a, int, int=0) { READDATA(s, a); } +template inline void Unserialize(Stream& s, signed long& a, int, int=0) { READDATA(s, a); } +template inline void Unserialize(Stream& s, unsigned long& a, int, int=0) { READDATA(s, a); } +template inline void Unserialize(Stream& s, int64& a, int, int=0) { READDATA(s, a); } +template inline void Unserialize(Stream& s, uint64& a, int, int=0) { READDATA(s, a); } +template inline void Unserialize(Stream& s, float& a, int, int=0) { READDATA(s, a); } +template inline void Unserialize(Stream& s, double& a, int, int=0) { READDATA(s, a); } + +inline unsigned int GetSerializeSize(bool a, int, int=0) { return sizeof(char); } +template inline void Serialize(Stream& s, bool a, int, int=0) { char f=a; WRITEDATA(s, f); } +template inline void Unserialize(Stream& s, bool& a, int, int=0) { char f; READDATA(s, f); a=f; } + + + + + + +// +// Compact size +// size < 253 -- 1 byte +// size <= USHRT_MAX -- 3 bytes (253 + 2 bytes) +// size <= UINT_MAX -- 5 bytes (254 + 4 bytes) +// size > UINT_MAX -- 9 bytes (255 + 8 bytes) +// +inline unsigned int GetSizeOfCompactSize(uint64 nSize) +{ + if (nSize < UCHAR_MAX-2) return sizeof(unsigned char); + else if (nSize <= USHRT_MAX) return sizeof(unsigned char) + sizeof(unsigned short); + else if (nSize <= UINT_MAX) return sizeof(unsigned char) + sizeof(unsigned int); + else return sizeof(unsigned char) + sizeof(uint64); +} + +template +void WriteCompactSize(Stream& os, uint64 nSize) +{ + if (nSize < UCHAR_MAX-2) + { + unsigned char chSize = nSize; + WRITEDATA(os, chSize); + } + else if (nSize <= USHRT_MAX) + { + unsigned char chSize = UCHAR_MAX-2; + unsigned short xSize = nSize; + WRITEDATA(os, chSize); + WRITEDATA(os, xSize); + } + else if (nSize <= UINT_MAX) + { + unsigned char chSize = UCHAR_MAX-1; + unsigned int xSize = nSize; + WRITEDATA(os, chSize); + WRITEDATA(os, xSize); + } + else + { + unsigned char chSize = UCHAR_MAX; + WRITEDATA(os, chSize); + WRITEDATA(os, nSize); + } + return; +} + +template +uint64 ReadCompactSize(Stream& is) +{ + unsigned char chSize; + READDATA(is, chSize); + if (chSize < UCHAR_MAX-2) + { + return chSize; + } + else if (chSize == UCHAR_MAX-2) + { + unsigned short nSize; + READDATA(is, nSize); + return nSize; + } + else if (chSize == UCHAR_MAX-1) + { + unsigned int nSize; + READDATA(is, nSize); + return nSize; + } + else + { + uint64 nSize; + READDATA(is, nSize); + return nSize; + } +} + + + +// +// Wrapper for serializing arrays and POD +// There's a clever template way to make arrays serialize normally, but MSVC6 doesn't support it +// +#define FLATDATA(obj) REF(CFlatData((char*)&(obj), (char*)&(obj) + sizeof(obj))) +class CFlatData +{ +protected: + char* pbegin; + char* pend; +public: + CFlatData(void* pbeginIn, void* pendIn) : pbegin((char*)pbeginIn), pend((char*)pendIn) { } + char* begin() { return pbegin; } + const char* begin() const { return pbegin; } + char* end() { return pend; } + const char* end() const { return pend; } + + unsigned int GetSerializeSize(int, int=0) const + { + return pend - pbegin; + } + + template + void Serialize(Stream& s, int, int=0) const + { + s.write(pbegin, pend - pbegin); + } + + template + void Unserialize(Stream& s, int, int=0) + { + s.read(pbegin, pend - pbegin); + } +}; + + + +// +// string stored as a fixed length field +// +template +class CFixedFieldString +{ +protected: + const string* pcstr; + string* pstr; +public: + explicit CFixedFieldString(const string& str) : pcstr(&str), pstr(NULL) { } + explicit CFixedFieldString(string& str) : pcstr(&str), pstr(&str) { } + + unsigned int GetSerializeSize(int, int=0) const + { + return LEN; + } + + template + void Serialize(Stream& s, int, int=0) const + { + char pszBuf[LEN]; + strncpy(pszBuf, pcstr->c_str(), LEN); + s.write(pszBuf, LEN); + } + + template + void Unserialize(Stream& s, int, int=0) + { + if (pstr == NULL) + throw std::ios_base::failure("CFixedFieldString::Unserialize : trying to unserialize to const string"); + char pszBuf[LEN+1]; + s.read(pszBuf, LEN); + pszBuf[LEN] = '\0'; + *pstr = pszBuf; + } +}; + + + + + +// +// Forward declarations +// + +// string +template unsigned int GetSerializeSize(const basic_string& str, int, int=0); +template void Serialize(Stream& os, const basic_string& str, int, int=0); +template void Unserialize(Stream& is, basic_string& str, int, int=0); + +// vector +template unsigned int GetSerializeSize_impl(const std::vector& v, int nType, int nVersion, const boost::true_type&); +template unsigned int GetSerializeSize_impl(const std::vector& v, int nType, int nVersion, const boost::false_type&); +template inline unsigned int GetSerializeSize(const std::vector& v, int nType, int nVersion=VERSION); +template void Serialize_impl(Stream& os, const std::vector& v, int nType, int nVersion, const boost::true_type&); +template void Serialize_impl(Stream& os, const std::vector& v, int nType, int nVersion, const boost::false_type&); +template inline void Serialize(Stream& os, const std::vector& v, int nType, int nVersion=VERSION); +template void Unserialize_impl(Stream& is, std::vector& v, int nType, int nVersion, const boost::true_type&); +template void Unserialize_impl(Stream& is, std::vector& v, int nType, int nVersion, const boost::false_type&); +template inline void Unserialize(Stream& is, std::vector& v, int nType, int nVersion=VERSION); + +// others derived from vector +extern inline unsigned int GetSerializeSize(const CScript& v, int nType, int nVersion=VERSION); +template void Serialize(Stream& os, const CScript& v, int nType, int nVersion=VERSION); +template void Unserialize(Stream& is, CScript& v, int nType, int nVersion=VERSION); + +// pair +template unsigned int GetSerializeSize(const std::pair& item, int nType, int nVersion=VERSION); +template void Serialize(Stream& os, const std::pair& item, int nType, int nVersion=VERSION); +template void Unserialize(Stream& is, std::pair& item, int nType, int nVersion=VERSION); + +// map +template unsigned int GetSerializeSize(const std::map& m, int nType, int nVersion=VERSION); +template void Serialize(Stream& os, const std::map& m, int nType, int nVersion=VERSION); +template void Unserialize(Stream& is, std::map& m, int nType, int nVersion=VERSION); + +// set +template unsigned int GetSerializeSize(const std::set& m, int nType, int nVersion=VERSION); +template void Serialize(Stream& os, const std::set& m, int nType, int nVersion=VERSION); +template void Unserialize(Stream& is, std::set& m, int nType, int nVersion=VERSION); + + + + + +// +// If none of the specialized versions above matched, default to calling member function. +// "int nType" is changed to "long nType" to keep from getting an ambiguous overload error. +// The compiler will only cast int to long if none of the other templates matched. +// Thanks to Boost serialization for this idea. +// +template +inline unsigned int GetSerializeSize(const T& a, long nType, int nVersion=VERSION) +{ + return a.GetSerializeSize((int)nType, nVersion); +} + +template +inline void Serialize(Stream& os, const T& a, long nType, int nVersion=VERSION) +{ + a.Serialize(os, (int)nType, nVersion); +} + +template +inline void Unserialize(Stream& is, T& a, long nType, int nVersion=VERSION) +{ + a.Unserialize(is, (int)nType, nVersion); +} + + + + + +// +// string +// +template +unsigned int GetSerializeSize(const basic_string& str, int, int) +{ + return GetSizeOfCompactSize(str.size()) + str.size() * sizeof(str[0]); +} + +template +void Serialize(Stream& os, const basic_string& str, int, int) +{ + WriteCompactSize(os, str.size()); + if (!str.empty()) + os.write((char*)&str[0], str.size() * sizeof(str[0])); +} + +template +void Unserialize(Stream& is, basic_string& str, int, int) +{ + unsigned int nSize = ReadCompactSize(is); + str.resize(nSize); + if (nSize != 0) + is.read((char*)&str[0], nSize * sizeof(str[0])); +} + + + +// +// vector +// +template +unsigned int GetSerializeSize_impl(const std::vector& v, int nType, int nVersion, const boost::true_type&) +{ + return (GetSizeOfCompactSize(v.size()) + v.size() * sizeof(T)); +} + +template +unsigned int GetSerializeSize_impl(const std::vector& v, int nType, int nVersion, const boost::false_type&) +{ + unsigned int nSize = GetSizeOfCompactSize(v.size()); + for (typename std::vector::const_iterator vi = v.begin(); vi != v.end(); ++vi) + nSize += GetSerializeSize((*vi), nType, nVersion); + return nSize; +} + +template +inline unsigned int GetSerializeSize(const std::vector& v, int nType, int nVersion) +{ + return GetSerializeSize_impl(v, nType, nVersion, boost::is_fundamental()); +} + + +template +void Serialize_impl(Stream& os, const std::vector& v, int nType, int nVersion, const boost::true_type&) +{ + WriteCompactSize(os, v.size()); + if (!v.empty()) + os.write((char*)&v[0], v.size() * sizeof(T)); +} + +template +void Serialize_impl(Stream& os, const std::vector& v, int nType, int nVersion, const boost::false_type&) +{ + WriteCompactSize(os, v.size()); + for (typename std::vector::const_iterator vi = v.begin(); vi != v.end(); ++vi) + ::Serialize(os, (*vi), nType, nVersion); +} + +template +inline void Serialize(Stream& os, const std::vector& v, int nType, int nVersion) +{ + Serialize_impl(os, v, nType, nVersion, boost::is_fundamental()); +} + + +template +void Unserialize_impl(Stream& is, std::vector& v, int nType, int nVersion, const boost::true_type&) +{ + //unsigned int nSize = ReadCompactSize(is); + //v.resize(nSize); + //is.read((char*)&v[0], nSize * sizeof(T)); + + // Limit size per read so bogus size value won't cause out of memory + v.clear(); + unsigned int nSize = ReadCompactSize(is); + unsigned int i = 0; + while (i < nSize) + { + unsigned int blk = min(nSize - i, 1 + 4999999 / sizeof(T)); + v.resize(i + blk); + is.read((char*)&v[i], blk * sizeof(T)); + i += blk; + } +} + +template +void Unserialize_impl(Stream& is, std::vector& v, int nType, int nVersion, const boost::false_type&) +{ + //unsigned int nSize = ReadCompactSize(is); + //v.resize(nSize); + //for (std::vector::iterator vi = v.begin(); vi != v.end(); ++vi) + // Unserialize(is, (*vi), nType, nVersion); + + v.clear(); + unsigned int nSize = ReadCompactSize(is); + unsigned int i = 0; + unsigned int nMid = 0; + while (nMid < nSize) + { + nMid += 5000000 / sizeof(T); + if (nMid > nSize) + nMid = nSize; + v.resize(nMid); + for (; i < nMid; i++) + Unserialize(is, v[i], nType, nVersion); + } +} + +template +inline void Unserialize(Stream& is, std::vector& v, int nType, int nVersion) +{ + Unserialize_impl(is, v, nType, nVersion, boost::is_fundamental()); +} + + + +// +// others derived from vector +// +inline unsigned int GetSerializeSize(const CScript& v, int nType, int nVersion) +{ + return GetSerializeSize((const vector&)v, nType, nVersion); +} + +template +void Serialize(Stream& os, const CScript& v, int nType, int nVersion) +{ + Serialize(os, (const vector&)v, nType, nVersion); +} + +template +void Unserialize(Stream& is, CScript& v, int nType, int nVersion) +{ + Unserialize(is, (vector&)v, nType, nVersion); +} + + + +// +// pair +// +template +unsigned int GetSerializeSize(const std::pair& item, int nType, int nVersion) +{ + return GetSerializeSize(item.first, nType, nVersion) + GetSerializeSize(item.second, nType, nVersion); +} + +template +void Serialize(Stream& os, const std::pair& item, int nType, int nVersion) +{ + Serialize(os, item.first, nType, nVersion); + Serialize(os, item.second, nType, nVersion); +} + +template +void Unserialize(Stream& is, std::pair& item, int nType, int nVersion) +{ + Unserialize(is, item.first, nType, nVersion); + Unserialize(is, item.second, nType, nVersion); +} + + + +// +// map +// +template +unsigned int GetSerializeSize(const std::map& m, int nType, int nVersion) +{ + unsigned int nSize = GetSizeOfCompactSize(m.size()); + for (typename std::map::const_iterator mi = m.begin(); mi != m.end(); ++mi) + nSize += GetSerializeSize((*mi), nType, nVersion); + return nSize; +} + +template +void Serialize(Stream& os, const std::map& m, int nType, int nVersion) +{ + WriteCompactSize(os, m.size()); + for (typename std::map::const_iterator mi = m.begin(); mi != m.end(); ++mi) + Serialize(os, (*mi), nType, nVersion); +} + +template +void Unserialize(Stream& is, std::map& m, int nType, int nVersion) +{ + m.clear(); + unsigned int nSize = ReadCompactSize(is); + typename std::map::iterator mi = m.begin(); + for (unsigned int i = 0; i < nSize; i++) + { + pair item; + Unserialize(is, item, nType, nVersion); + mi = m.insert(mi, item); + } +} + + + +// +// set +// +template +unsigned int GetSerializeSize(const std::set& m, int nType, int nVersion) +{ + unsigned int nSize = GetSizeOfCompactSize(m.size()); + for (typename std::set::const_iterator it = m.begin(); it != m.end(); ++it) + nSize += GetSerializeSize((*it), nType, nVersion); + return nSize; +} + +template +void Serialize(Stream& os, const std::set& m, int nType, int nVersion) +{ + WriteCompactSize(os, m.size()); + for (typename std::set::const_iterator it = m.begin(); it != m.end(); ++it) + Serialize(os, (*it), nType, nVersion); +} + +template +void Unserialize(Stream& is, std::set& m, int nType, int nVersion) +{ + m.clear(); + unsigned int nSize = ReadCompactSize(is); + typename std::set::iterator it = m.begin(); + for (unsigned int i = 0; i < nSize; i++) + { + K key; + Unserialize(is, key, nType, nVersion); + it = m.insert(it, key); + } +} + + + +// +// Support for IMPLEMENT_SERIALIZE and READWRITE macro +// +class CSerActionGetSerializeSize { }; +class CSerActionSerialize { }; +class CSerActionUnserialize { }; + +template +inline unsigned int SerReadWrite(Stream& s, const T& obj, int nType, int nVersion, CSerActionGetSerializeSize ser_action) +{ + return ::GetSerializeSize(obj, nType, nVersion); +} + +template +inline unsigned int SerReadWrite(Stream& s, const T& obj, int nType, int nVersion, CSerActionSerialize ser_action) +{ + ::Serialize(s, obj, nType, nVersion); + return 0; +} + +template +inline unsigned int SerReadWrite(Stream& s, T& obj, int nType, int nVersion, CSerActionUnserialize ser_action) +{ + ::Unserialize(s, obj, nType, nVersion); + return 0; +} + +struct ser_streamplaceholder +{ + int nType; + int nVersion; +}; + + + + + + + + + +// +// Allocator that clears its contents before deletion +// +template +struct secure_allocator : public std::allocator +{ + // MSVC8 default copy constructor is broken + typedef std::allocator base; + typedef typename base::size_type size_type; + typedef typename base::difference_type difference_type; + typedef typename base::pointer pointer; + typedef typename base::const_pointer const_pointer; + typedef typename base::reference reference; + typedef typename base::const_reference const_reference; + typedef typename base::value_type value_type; + secure_allocator() throw() {} + secure_allocator(const secure_allocator& a) throw() : base(a) {} + ~secure_allocator() throw() {} + template struct rebind + { typedef secure_allocator<_Other> other; }; + + void deallocate(T* p, std::size_t n) + { + if (p != NULL) + memset(p, 0, sizeof(T) * n); + allocator::deallocate(p, n); + } +}; + + + +// +// Double ended buffer combining vector and stream-like interfaces. +// >> and << read and write unformatted data using the above serialization templates. +// Fills with data in linear time; some stringstream implementations take N^2 time. +// +class CDataStream +{ +protected: + typedef vector > vector_type; + vector_type vch; + unsigned int nReadPos; + short state; + short exceptmask; +public: + int nType; + int nVersion; + + typedef vector_type::allocator_type allocator_type; + typedef vector_type::size_type size_type; + typedef vector_type::difference_type difference_type; + typedef vector_type::reference reference; + typedef vector_type::const_reference const_reference; + typedef vector_type::value_type value_type; + typedef vector_type::iterator iterator; + typedef vector_type::const_iterator const_iterator; + typedef vector_type::reverse_iterator reverse_iterator; + + explicit CDataStream(int nTypeIn=0, int nVersionIn=VERSION) + { + Init(nTypeIn, nVersionIn); + } + + CDataStream(const_iterator pbegin, const_iterator pend, int nTypeIn=0, int nVersionIn=VERSION) : vch(pbegin, pend) + { + Init(nTypeIn, nVersionIn); + } + +#if !defined(_MSC_VER) || _MSC_VER >= 1300 + CDataStream(const char* pbegin, const char* pend, int nTypeIn=0, int nVersionIn=VERSION) : vch(pbegin, pend) + { + Init(nTypeIn, nVersionIn); + } +#endif + + CDataStream(const vector_type& vchIn, int nTypeIn=0, int nVersionIn=VERSION) : vch(vchIn.begin(), vchIn.end()) + { + Init(nTypeIn, nVersionIn); + } + + CDataStream(const vector& vchIn, int nTypeIn=0, int nVersionIn=VERSION) : vch(vchIn.begin(), vchIn.end()) + { + Init(nTypeIn, nVersionIn); + } + + CDataStream(const vector& vchIn, int nTypeIn=0, int nVersionIn=VERSION) : vch((char*)&vchIn.begin()[0], (char*)&vchIn.end()[0]) + { + Init(nTypeIn, nVersionIn); + } + + void Init(int nTypeIn=0, int nVersionIn=VERSION) + { + nReadPos = 0; + nType = nTypeIn; + nVersion = nVersionIn; + state = 0; + exceptmask = ios::badbit | ios::failbit; + } + + CDataStream& operator+=(const CDataStream& b) + { + vch.insert(vch.end(), b.begin(), b.end()); + return *this; + } + + friend CDataStream operator+(const CDataStream& a, const CDataStream& b) + { + CDataStream ret = a; + ret += b; + return (ret); + } + + string str() const + { + return (string(begin(), end())); + } + + + // + // Vector subset + // + const_iterator begin() const { return vch.begin() + nReadPos; } + iterator begin() { return vch.begin() + nReadPos; } + const_iterator end() const { return vch.end(); } + iterator end() { return vch.end(); } + size_type size() const { return vch.size() - nReadPos; } + bool empty() const { return vch.size() == nReadPos; } + void resize(size_type n, value_type c=0) { vch.resize(n + nReadPos, c); } + void reserve(size_type n) { vch.reserve(n + nReadPos); } + const_reference operator[](size_type pos) const { return vch[pos + nReadPos]; } + reference operator[](size_type pos) { return vch[pos + nReadPos]; } + void clear() { vch.clear(); nReadPos = 0; } + iterator insert(iterator it, const char& x=char()) { return vch.insert(it, x); } + void insert(iterator it, size_type n, const char& x) { vch.insert(it, n, x); } + + void insert(iterator it, const_iterator first, const_iterator last) + { + if (it == vch.begin() + nReadPos && last - first <= nReadPos) + { + // special case for inserting at the front when there's room + nReadPos -= (last - first); + memcpy(&vch[nReadPos], &first[0], last - first); + } + else + vch.insert(it, first, last); + } + +#if !defined(_MSC_VER) || _MSC_VER >= 1300 + void insert(iterator it, const char* first, const char* last) + { + if (it == vch.begin() + nReadPos && last - first <= nReadPos) + { + // special case for inserting at the front when there's room + nReadPos -= (last - first); + memcpy(&vch[nReadPos], &first[0], last - first); + } + else + vch.insert(it, first, last); + } +#endif + + iterator erase(iterator it) + { + if (it == vch.begin() + nReadPos) + { + // special case for erasing from the front + if (++nReadPos >= vch.size()) + { + // whenever we reach the end, we take the opportunity to clear the buffer + nReadPos = 0; + return vch.erase(vch.begin(), vch.end()); + } + return vch.begin() + nReadPos; + } + else + return vch.erase(it); + } + + iterator erase(iterator first, iterator last) + { + if (first == vch.begin() + nReadPos) + { + // special case for erasing from the front + if (last == vch.end()) + { + nReadPos = 0; + return vch.erase(vch.begin(), vch.end()); + } + else + { + nReadPos = (last - vch.begin()); + return last; + } + } + else + return vch.erase(first, last); + } + + inline void Compact() + { + vch.erase(vch.begin(), vch.begin() + nReadPos); + nReadPos = 0; + } + + bool Rewind(size_type n) + { + // Rewind by n characters if the buffer hasn't been compacted yet + if (n > nReadPos) + return false; + nReadPos -= n; + return true; + } + + + // + // Stream subset + // + void setstate(short bits, const char* psz) + { + state |= bits; + if (state & exceptmask) + throw std::ios_base::failure(psz); + } + + bool eof() const { return size() == 0; } + bool fail() const { return state & (ios::badbit | ios::failbit); } + bool good() const { return !eof() && (state == 0); } + void clear(short n) { state = n; } // name conflict with vector clear() + short exceptions() { return exceptmask; } + short exceptions(short mask) { short prev = exceptmask; exceptmask = mask; setstate(0, "CDataStream"); return prev; } + CDataStream* rdbuf() { return this; } + int in_avail() { return size(); } + + void SetType(int n) { nType = n; } + int GetType() { return nType; } + void SetVersion(int n) { nVersion = n; } + int GetVersion() { return nVersion; } + void ReadVersion() { *this >> nVersion; } + void WriteVersion() { *this << nVersion; } + + CDataStream& read(char* pch, int nSize) + { + // Read from the beginning of the buffer + assert(nSize >= 0); + unsigned int nReadPosNext = nReadPos + nSize; + if (nReadPosNext >= vch.size()) + { + if (nReadPosNext > vch.size()) + { + setstate(ios::failbit, "CDataStream::read() : end of data"); + memset(pch, 0, nSize); + nSize = vch.size() - nReadPos; + } + memcpy(pch, &vch[nReadPos], nSize); + nReadPos = 0; + vch.clear(); + return (*this); + } + memcpy(pch, &vch[nReadPos], nSize); + nReadPos = nReadPosNext; + return (*this); + } + + CDataStream& ignore(int nSize) + { + // Ignore from the beginning of the buffer + assert(nSize >= 0); + unsigned int nReadPosNext = nReadPos + nSize; + if (nReadPosNext >= vch.size()) + { + if (nReadPosNext > vch.size()) + { + setstate(ios::failbit, "CDataStream::ignore() : end of data"); + nSize = vch.size() - nReadPos; + } + nReadPos = 0; + vch.clear(); + return (*this); + } + nReadPos = nReadPosNext; + return (*this); + } + + CDataStream& write(const char* pch, int nSize) + { + // Write to the end of the buffer + assert(nSize >= 0); + vch.insert(vch.end(), pch, pch + nSize); + return (*this); + } + + template + void Serialize(Stream& s, int nType=0, int nVersion=VERSION) const + { + // Special case: stream << stream concatenates like stream += stream + if (!vch.empty()) + s.write((char*)&vch[0], vch.size() * sizeof(vch[0])); + } + + template + unsigned int GetSerializeSize(const T& obj) + { + // Tells the size of the object if serialized to this stream + return ::GetSerializeSize(obj, nType, nVersion); + } + + template + CDataStream& operator<<(const T& obj) + { + // Serialize to this stream + ::Serialize(*this, obj, nType, nVersion); + return (*this); + } + + template + CDataStream& operator>>(T& obj) + { + // Unserialize from this stream + ::Unserialize(*this, obj, nType, nVersion); + return (*this); + } +}; + +#ifdef TESTCDATASTREAM +// VC6sp6 +// CDataStream: +// n=1000 0 seconds +// n=2000 0 seconds +// n=4000 0 seconds +// n=8000 0 seconds +// n=16000 0 seconds +// n=32000 0 seconds +// n=64000 1 seconds +// n=128000 1 seconds +// n=256000 2 seconds +// n=512000 4 seconds +// n=1024000 8 seconds +// n=2048000 16 seconds +// n=4096000 32 seconds +// stringstream: +// n=1000 1 seconds +// n=2000 1 seconds +// n=4000 13 seconds +// n=8000 87 seconds +// n=16000 400 seconds +// n=32000 1660 seconds +// n=64000 6749 seconds +// n=128000 27241 seconds +// n=256000 109804 seconds +#include +int main(int argc, char *argv[]) +{ + vector vch(0xcc, 250); + printf("CDataStream:\n"); + for (int n = 1000; n <= 4500000; n *= 2) + { + CDataStream ss; + time_t nStart = time(NULL); + for (int i = 0; i < n; i++) + ss.write((char*)&vch[0], vch.size()); + printf("n=%-10d %d seconds\n", n, time(NULL) - nStart); + } + printf("stringstream:\n"); + for (int n = 1000; n <= 4500000; n *= 2) + { + stringstream ss; + time_t nStart = time(NULL); + for (int i = 0; i < n; i++) + ss.write((char*)&vch[0], vch.size()); + printf("n=%-10d %d seconds\n", n, time(NULL) - nStart); + } +} +#endif + + + + + + + + + + +// +// Automatic closing wrapper for FILE* +// - Will automatically close the file when it goes out of scope if not null. +// - If you're returning the file pointer, return file.release(). +// - If you need to close the file early, use file.fclose() instead of fclose(file). +// +class CAutoFile +{ +protected: + FILE* file; + short state; + short exceptmask; +public: + int nType; + int nVersion; + + typedef FILE element_type; + + CAutoFile(FILE* filenew=NULL, int nTypeIn=SER_DISK, int nVersionIn=VERSION) + { + file = filenew; + nType = nTypeIn; + nVersion = nVersionIn; + state = 0; + exceptmask = ios::badbit | ios::failbit; + } + + ~CAutoFile() + { + fclose(); + } + + void fclose() + { + if (file != NULL && file != stdin && file != stdout && file != stderr) + ::fclose(file); + file = NULL; + } + + FILE* release() { FILE* ret = file; file = NULL; return ret; } + operator FILE*() { return file; } + FILE* operator->() { return file; } + FILE& operator*() { return *file; } + FILE** operator&() { return &file; } + FILE* operator=(FILE* pnew) { return file = pnew; } + bool operator!() { return (file == NULL); } + + + // + // Stream subset + // + void setstate(short bits, const char* psz) + { + state |= bits; + if (state & exceptmask) + throw std::ios_base::failure(psz); + } + + bool fail() const { return state & (ios::badbit | ios::failbit); } + bool good() const { return state == 0; } + void clear(short n = 0) { state = n; } + short exceptions() { return exceptmask; } + short exceptions(short mask) { short prev = exceptmask; exceptmask = mask; setstate(0, "CAutoFile"); return prev; } + + void SetType(int n) { nType = n; } + int GetType() { return nType; } + void SetVersion(int n) { nVersion = n; } + int GetVersion() { return nVersion; } + void ReadVersion() { *this >> nVersion; } + void WriteVersion() { *this << nVersion; } + + CAutoFile& read(char* pch, int nSize) + { + if (!file) + throw std::ios_base::failure("CAutoFile::read : file handle is NULL"); + if (fread(pch, 1, nSize, file) != nSize) + setstate(ios::failbit, feof(file) ? "CAutoFile::read : end of file" : "CAutoFile::read : fread failed"); + return (*this); + } + + CAutoFile& write(const char* pch, int nSize) + { + if (!file) + throw std::ios_base::failure("CAutoFile::write : file handle is NULL"); + if (fwrite(pch, 1, nSize, file) != nSize) + setstate(ios::failbit, "CAutoFile::write : write failed"); + return (*this); + } + + template + unsigned int GetSerializeSize(const T& obj) + { + // Tells the size of the object if serialized to this stream + return ::GetSerializeSize(obj, nType, nVersion); + } + + template + CAutoFile& operator<<(const T& obj) + { + // Serialize to this stream + if (!file) + throw std::ios_base::failure("CAutoFile::operator<< : file handle is NULL"); + ::Serialize(*this, obj, nType, nVersion); + return (*this); + } + + template + CAutoFile& operator>>(T& obj) + { + // Unserialize from this stream + if (!file) + throw std::ios_base::failure("CAutoFile::operator>> : file handle is NULL"); + ::Unserialize(*this, obj, nType, nVersion); + return (*this); + } +}; diff --git a/sha.cpp b/sha.cpp new file mode 100644 index 0000000000..09b62fdc89 --- /dev/null +++ b/sha.cpp @@ -0,0 +1,554 @@ +// This file is public domain +// SHA routines extracted as a standalone file from: +// Crypto++: a C++ Class Library of Cryptographic Schemes +// Version 5.5.2 (9/24/2007) +// http://www.cryptopp.com + +// 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. + +#include +#include +#include "sha.h" + +namespace 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)); +} + +static const word32 SHA256_K[64] = { + 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 +}; + +#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) ((x&y)|(z&(x|y))) + +#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]; + 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); +} + +/* +// 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 += 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 += 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 += 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 + +// ************************************************************* + +#ifdef WORD64_AVAILABLE + +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)); +} + +CRYPTOPP_ALIGN_DATA(16) static const word64 SHA512_K[80] CRYPTOPP_SECTION_ALIGN16 = { + 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( movq mm4, [ecx+0*8]) + AS2( movq [edi+0*8], mm4) + AS2( movq mm0, [ecx+1*8]) + AS2( movq [edi+1*8], mm0) + AS2( movq mm0, [ecx+2*8]) + AS2( movq [edi+2*8], mm0) + AS2( movq mm0, [ecx+3*8]) + AS2( movq [edi+3*8], mm0) + AS2( movq mm5, [ecx+4*8]) + AS2( movq [edi+4*8], mm5) + AS2( movq mm0, [ecx+5*8]) + AS2( movq [edi+5*8], mm0) + AS2( movq mm0, [ecx+6*8]) + AS2( movq [edi+6*8], mm0) + AS2( movq mm0, [ecx+7*8]) + AS2( movq [edi+7*8], mm0) + 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( movq mm0, [edi+i*8])\ + AS2( paddq mm0, [ecx+i*8])\ + AS2( movq [ecx+i*8], mm0) + + SSE2_CombineState(0) + SSE2_CombineState(1) + SSE2_CombineState(2) + SSE2_CombineState(3) + SSE2_CombineState(4) + SSE2_CombineState(5) + SSE2_CombineState(6) + SSE2_CombineState(7) + + 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); +} + +#endif + +} diff --git a/sha.h b/sha.h new file mode 100644 index 0000000000..4e56b56d9c --- /dev/null +++ b/sha.h @@ -0,0 +1,177 @@ +// This file is public domain +// SHA routines extracted as a standalone file from: +// Crypto++: a C++ Class Library of Cryptographic Schemes +// Version 5.5.2 (9/24/2007) +// http://www.cryptopp.com +#ifndef CRYPTOPP_SHA_H +#define CRYPTOPP_SHA_H +#include + +namespace CryptoPP +{ + +// +// Dependencies +// + +typedef unsigned char byte; +typedef unsigned short word16; +typedef unsigned int word32; +#if defined(_MSC_VER) || defined(__BORLANDC__) +typedef unsigned __int64 word64; +#else +typedef unsigned long long word64; +#endif + +template inline T rotlFixed(T x, unsigned int y) +{ + assert(y < sizeof(T)*8); + return T((x<>(sizeof(T)*8-y))); +} + +template inline T rotrFixed(T x, unsigned int y) +{ + assert(y < sizeof(T)*8); + return T((x>>y) | (x<<(sizeof(T)*8-y))); +} + +// ************** endian reversal *************** + +#ifdef _MSC_VER + #if _MSC_VER >= 1400 + #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 + +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__) + __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 +} + +#ifdef WORD64_AVAILABLE +inline word64 ByteReverse(word64 value) +{ +#if defined(__GNUC__) && 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 defined(CRYPTOPP_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 +} +#endif + + +// +// SHA +// + +// http://www.weidai.com/scan-mirror/md.html#SHA-1 +class SHA1 +{ +public: + typedef word32 HashWordType; + static void InitState(word32 *state); + static void Transform(word32 *digest, const word32 *data); + static const char * StaticAlgorithmName() {return "SHA-1";} +}; + +typedef SHA1 SHA; // for backwards compatibility + +// implements the SHA-256 standard +class SHA256 +{ +public: + typedef word32 HashWordType; + static void InitState(word32 *state); + static void Transform(word32 *digest, const word32 *data); + static const char * StaticAlgorithmName() {return "SHA-256";} +}; + +// implements the SHA-224 standard +class SHA224 +{ +public: + typedef word32 HashWordType; + static void InitState(word32 *state); + static void Transform(word32 *digest, const word32 *data) {SHA256::Transform(digest, data);} + static const char * StaticAlgorithmName() {return "SHA-224";} +}; + +#ifdef WORD64_AVAILABLE + +// implements the SHA-512 standard +class SHA512 +{ +public: + typedef word64 HashWordType; + static void InitState(word64 *state); + static void Transform(word64 *digest, const word64 *data); + static const char * StaticAlgorithmName() {return "SHA-512";} +}; + +// implements the SHA-384 standard +class SHA384 +{ +public: + typedef word64 HashWordType; + static void InitState(word64 *state); + static void Transform(word64 *digest, const word64 *data) {SHA512::Transform(digest, data);} + static const char * StaticAlgorithmName() {return "SHA-384";} +}; + +#endif + +} + +#endif diff --git a/ui.cpp b/ui.cpp new file mode 100644 index 0000000000..96c5a83d58 --- /dev/null +++ b/ui.cpp @@ -0,0 +1,3290 @@ +// Copyright (c) 2009 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" +#ifdef _MSC_VER +#include +#endif + + + +DEFINE_EVENT_TYPE(wxEVT_CROSSTHREADCALL) +DEFINE_EVENT_TYPE(wxEVT_REPLY1) +DEFINE_EVENT_TYPE(wxEVT_REPLY2) +DEFINE_EVENT_TYPE(wxEVT_REPLY3) +DEFINE_EVENT_TYPE(wxEVT_TABLEADDED) +DEFINE_EVENT_TYPE(wxEVT_TABLEUPDATED) +DEFINE_EVENT_TYPE(wxEVT_TABLEDELETED) + +CMainFrame* pframeMain = NULL; +map mapAddressBook; + + +void ThreadRequestProductDetails(void* parg); +void ThreadRandSendTest(void* parg); +bool fRandSendTest = false; +void RandSend(); +extern int g_isPainting; + + + + + + +////////////////////////////////////////////////////////////////////////////// +// +// Util +// + +void HandleCtrlA(wxKeyEvent& event) +{ + // Ctrl-a select all + wxTextCtrl* textCtrl = (wxTextCtrl*)event.GetEventObject(); + if (event.GetModifiers() == wxMOD_CONTROL && event.GetKeyCode() == 'A') + textCtrl->SetSelection(-1, -1); + event.Skip(); +} + +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) +{ + return (string)wxDateTime((time_t)nTime).FormatDate(); +} + +string DateTimeStr(int64 nTime) +{ + 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 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 += "
\n"; + else + str += *p; + } + return str; +} + +string HtmlEscape(const string& str, bool fMultiLine=false) +{ + return HtmlEscape(str.c_str(), fMultiLine); +} + +void AddToMyProducts(CProduct product) +{ + CProduct& productInsert = mapMyProducts[product.GetHash()]; + productInsert = product; + InsertLine(pframeMain->m_listCtrlProductsSent, &productInsert, + product.mapValue["category"], + product.mapValue["title"].substr(0, 100), + product.mapValue["description"].substr(0, 100), + product.mapValue["price"], + ""); +} + + + + + + +////////////////////////////////////////////////////////////////////////////// +// +// Custom events +// + +set setCallbackAvailable; +CCriticalSection cs_setCallbackAvailable; + +void AddCallbackAvailable(void* p) +{ + CRITICAL_BLOCK(cs_setCallbackAvailable) + setCallbackAvailable.insert(p); +} + +void RemoveCallbackAvailable(void* p) +{ + CRITICAL_BLOCK(cs_setCallbackAvailable) + setCallbackAvailable.erase(p); +} + +bool IsCallbackAvailable(void* p) +{ + CRITICAL_BLOCK(cs_setCallbackAvailable) + return setCallbackAvailable.count(p); + return false; +} + +template +void AddPendingCustomEvent(wxEvtHandler* pevthandler, int nEventID, const T pbeginIn, const T pendIn) +{ + if (!pevthandler) + return; + + const char* pbegin = (pendIn != pbeginIn) ? &pbeginIn[0] : NULL; + const char* pend = pbegin + (pendIn - pbeginIn) * sizeof(pbeginIn[0]); + wxCommandEvent event(nEventID); + wxString strData(wxChar(0), (pend - pbegin) / sizeof(wxChar) + 1); + memcpy(&strData[0], pbegin, pend - pbegin); + event.SetString(strData); + event.SetInt(pend - pbegin); + + pevthandler->AddPendingEvent(event); +} + +template +void AddPendingCustomEvent(wxEvtHandler* pevthandler, int nEventID, const T& obj) +{ + CDataStream ss; + ss << obj; + AddPendingCustomEvent(pevthandler, nEventID, ss.begin(), ss.end()); +} + +void AddPendingReplyEvent1(void* pevthandler, CDataStream& vRecv) +{ + if (IsCallbackAvailable(pevthandler)) + AddPendingCustomEvent((wxEvtHandler*)pevthandler, wxEVT_REPLY1, vRecv.begin(), vRecv.end()); +} + +void AddPendingReplyEvent2(void* pevthandler, CDataStream& vRecv) +{ + if (IsCallbackAvailable(pevthandler)) + AddPendingCustomEvent((wxEvtHandler*)pevthandler, wxEVT_REPLY2, vRecv.begin(), vRecv.end()); +} + +void AddPendingReplyEvent3(void* pevthandler, CDataStream& vRecv) +{ + if (IsCallbackAvailable(pevthandler)) + AddPendingCustomEvent((wxEvtHandler*)pevthandler, wxEVT_REPLY3, vRecv.begin(), vRecv.end()); +} + +CDataStream GetStreamFromEvent(const wxCommandEvent& event) +{ + wxString strData = event.GetString(); + return CDataStream(strData.begin(), strData.begin() + event.GetInt(), SER_NETWORK); +} + + + + + + + +////////////////////////////////////////////////////////////////////////////// +// +// CMainFrame +// + +CMainFrame::CMainFrame(wxWindow* parent) : CMainFrameBase(parent) +{ + Connect(wxEVT_CROSSTHREADCALL, wxCommandEventHandler(CMainFrame::OnCrossThreadCall), NULL, this); + + // Init + fRefreshListCtrl = false; + fRefreshListCtrlRunning = false; + fOnSetFocusAddress = false; + pindexBestLast = NULL; + m_choiceFilter->SetSelection(0); + m_staticTextBalance->SetLabel(FormatMoney(GetBalance()) + " "); + m_listCtrl->SetFocus(); + SetIcon(wxICON(bitcoin)); + m_menuOptions->Check(wxID_OPTIONSGENERATEBITCOINS, fGenerateBitcoins); + + // Init toolbar with transparency masked bitmaps + m_toolBar->ClearTools(); + + //// shouldn't have to do mask separately anymore, bitmap alpha support added in wx 2.8.9, + wxBitmap bmpSend(wxT("send20"), wxBITMAP_TYPE_RESOURCE); + bmpSend.SetMask(new wxMask(wxBitmap(wxT("send20mask"), wxBITMAP_TYPE_RESOURCE))); + m_toolBar->AddTool(wxID_BUTTONSEND, wxT("&Send Coins"), bmpSend, wxNullBitmap, wxITEM_NORMAL, wxEmptyString, wxEmptyString); + + wxBitmap bmpAddressBook(wxT("addressbook20"), wxBITMAP_TYPE_RESOURCE); + bmpAddressBook.SetMask(new wxMask(wxBitmap(wxT("addressbook20mask"), wxBITMAP_TYPE_RESOURCE))); + m_toolBar->AddTool(wxID_BUTTONRECEIVE, wxT("&Address Book"), bmpAddressBook, wxNullBitmap, wxITEM_NORMAL, wxEmptyString, wxEmptyString); + + m_toolBar->Realize(); + + // Init column headers + int nDateWidth = DateTimeStr(1229413914).size() * 6 + 8; + m_listCtrl->InsertColumn(0, "", wxLIST_FORMAT_LEFT, 0); + m_listCtrl->InsertColumn(1, "", wxLIST_FORMAT_LEFT, 0); + m_listCtrl->InsertColumn(2, "Status", wxLIST_FORMAT_LEFT, 90); + m_listCtrl->InsertColumn(3, "Date", wxLIST_FORMAT_LEFT, nDateWidth); + m_listCtrl->InsertColumn(4, "Description", wxLIST_FORMAT_LEFT, 409 - nDateWidth); + m_listCtrl->InsertColumn(5, "Debit", wxLIST_FORMAT_RIGHT, 79); + m_listCtrl->InsertColumn(6, "Credit", wxLIST_FORMAT_RIGHT, 79); + + //m_listCtrlProductsSent->InsertColumn(0, "Category", wxLIST_FORMAT_LEFT, 100); + //m_listCtrlProductsSent->InsertColumn(1, "Title", wxLIST_FORMAT_LEFT, 100); + //m_listCtrlProductsSent->InsertColumn(2, "Description", wxLIST_FORMAT_LEFT, 100); + //m_listCtrlProductsSent->InsertColumn(3, "Price", wxLIST_FORMAT_LEFT, 100); + //m_listCtrlProductsSent->InsertColumn(4, "", wxLIST_FORMAT_LEFT, 100); + + //m_listCtrlOrdersSent->InsertColumn(0, "Time", wxLIST_FORMAT_LEFT, 100); + //m_listCtrlOrdersSent->InsertColumn(1, "Price", wxLIST_FORMAT_LEFT, 100); + //m_listCtrlOrdersSent->InsertColumn(2, "", wxLIST_FORMAT_LEFT, 100); + //m_listCtrlOrdersSent->InsertColumn(3, "", wxLIST_FORMAT_LEFT, 100); + //m_listCtrlOrdersSent->InsertColumn(4, "", wxLIST_FORMAT_LEFT, 100); + + //m_listCtrlOrdersReceived->InsertColumn(0, "Time", wxLIST_FORMAT_LEFT, 100); + //m_listCtrlOrdersReceived->InsertColumn(1, "Price", wxLIST_FORMAT_LEFT, 100); + //m_listCtrlOrdersReceived->InsertColumn(2, "Payment Status", wxLIST_FORMAT_LEFT, 100); + //m_listCtrlOrdersReceived->InsertColumn(3, "", wxLIST_FORMAT_LEFT, 100); + //m_listCtrlOrdersReceived->InsertColumn(4, "", wxLIST_FORMAT_LEFT, 100); + + // Init status bar + int pnWidths[3] = { -100, 81, 286 }; + m_statusBar->SetFieldsCount(3, pnWidths); + + // Fill your address text box + vector vchPubKey; + if (CWalletDB("r").ReadDefaultKey(vchPubKey)) + m_textCtrlAddress->SetValue(PubKeyToAddress(vchPubKey)); + + // Fill listctrl with wallet transactions + RefreshListCtrl(); +} + +CMainFrame::~CMainFrame() +{ + pframeMain = NULL; +} + +void Shutdown(void* parg) +{ + static CCriticalSection cs_Shutdown; + CRITICAL_BLOCK(cs_Shutdown) + { + fShutdown = true; + nTransactionsUpdated++; + DBFlush(false); + StopNode(); + DBFlush(true); + + printf("Bitcoin exiting\n"); + exit(0); + } +} + +void CMainFrame::OnClose(wxCloseEvent& event) +{ + Destroy(); + _beginthread(Shutdown, 0, NULL); +} + +void CMainFrame::OnMouseEvents(wxMouseEvent& event) +{ + 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(); +} + +void CMainFrame::InsertLine(bool fNew, int nIndex, uint256 hashKey, string strSort, const wxString& str2, const wxString& str3, const wxString& str4, const wxString& str5, const wxString& str6) +{ + string str0 = strSort; + long nData = *(long*)&hashKey; + + if (fNew) + { + nIndex = m_listCtrl->InsertItem(0, str0); + } + else + { + if (nIndex == -1) + { + // Find item + while ((nIndex = m_listCtrl->FindItem(nIndex, nData)) != -1) + if (GetItemText(m_listCtrl, nIndex, 1) == hashKey.ToString()) + break; + if (nIndex == -1) + { + printf("CMainFrame::InsertLine : Couldn't find item to be updated\n"); + return; + } + } + + // If sort key changed, must delete and reinsert to make it relocate + if (GetItemText(m_listCtrl, nIndex, 0) != str0) + { + m_listCtrl->DeleteItem(nIndex); + nIndex = m_listCtrl->InsertItem(0, str0); + } + } + + 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); +} + +string FormatTxStatus(const CWalletTx& wtx) +{ + // Status + int nDepth = wtx.GetDepthInMainChain(); + if (!wtx.IsFinal()) + return strprintf("Open for %d blocks", nBestHeight - wtx.nLockTime); + else if (nDepth < 6) + return strprintf("%d/unconfirmed", nDepth); + else + return strprintf("%d blocks", nDepth); +} + +string SingleLine(const string& strIn) +{ + string strOut; + bool fOneSpace = false; + foreach(int c, strIn) + { + if (isspace(c)) + { + fOneSpace = true; + } + else if (c > ' ') + { + if (fOneSpace && !strOut.empty()) + strOut += ' '; + strOut += c; + fOneSpace = false; + } + } + return strOut; +} + +void CMainFrame::InsertTransaction(const CWalletTx& wtx, bool fNew, int nIndex) +{ + int64 nTime = wtx.nTimeDisplayed = wtx.GetTxTime(); + int64 nCredit = wtx.GetCredit(); + int64 nDebit = wtx.GetDebit(); + int64 nNet = nCredit - nDebit; + uint256 hash = wtx.GetHash(); + string strStatus = FormatTxStatus(wtx); + map mapValue = wtx.mapValue; + + // Find the block the tx is in + CBlockIndex* pindex = NULL; + map::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()) + { + // Coinbase + strDescription = "Generated"; + if (nCredit == 0) + { + int64 nUnmatured = 0; + foreach(const CTxOut& txout, wtx.vout) + nUnmatured += txout.GetCredit(); + if (wtx.IsInMainChain()) + strDescription += strprintf(" (%s matures in %d more blocks)", FormatMoney(nUnmatured).c_str(), wtx.GetBlocksToMaturity()); + else + strDescription += " (not accepted)"; + } + } + else if (!mapValue["from"].empty() || !mapValue["message"].empty()) + { + // Online transaction + if (!mapValue["from"].empty()) + strDescription += "From: " + mapValue["from"]; + if (!mapValue["message"].empty()) + { + if (!strDescription.empty()) + strDescription += " - "; + strDescription += mapValue["message"]; + } + } + else + { + // Offline transaction + foreach(const CTxOut& txout, wtx.vout) + { + if (txout.IsMine()) + { + vector vchPubKey; + if (ExtractPubKey(txout.scriptPubKey, true, vchPubKey)) + { + string strAddress = PubKeyToAddress(vchPubKey); + if (mapAddressBook.count(strAddress)) + { + //strDescription += "Received payment to "; + //strDescription += "Received with address "; + strDescription += "From: unknown, To: "; + strDescription += strAddress; + /// The labeling feature is just too confusing, so I hid it + /// by putting it at the end where it runs off the screen. + /// It can still be seen by widening the column, or in the + /// details dialog. + if (!mapAddressBook[strAddress].empty()) + strDescription += " (" + mapAddressBook[strAddress] + ")"; + } + } + break; + } + } + } + + InsertLine(fNew, nIndex, hash, strSort, + strStatus, + nTime ? DateTimeStr(nTime) : "", + SingleLine(strDescription), + "", + FormatMoney(nNet, true)); + } + else + { + bool fAllFromMe = true; + foreach(const CTxIn& txin, wtx.vin) + fAllFromMe = fAllFromMe && txin.IsMine(); + + bool fAllToMe = true; + foreach(const CTxOut& txout, wtx.vout) + fAllToMe = fAllToMe && txout.IsMine(); + + if (fAllFromMe && fAllToMe) + { + // Payment to self + int64 nValue = wtx.vout[0].nValue; + InsertLine(fNew, nIndex, hash, strSort, + strStatus, + nTime ? DateTimeStr(nTime) : "", + "Payment to yourself", + FormatMoney(nNet - nValue, true), + FormatMoney(nValue, true)); + } + else if (fAllFromMe) + { + // + // Debit + // + int64 nTxFee = nDebit - wtx.GetValueOut(); + for (int nOut = 0; nOut < wtx.vout.size(); nOut++) + { + const CTxOut& txout = wtx.vout[nOut]; + if (txout.IsMine()) + continue; + + string strAddress; + if (!mapValue["to"].empty()) + { + // Online transaction + strAddress = mapValue["to"]; + } + else + { + // Offline transaction + uint160 hash160; + if (ExtractHash160(txout.scriptPubKey, hash160)) + strAddress = Hash160ToAddress(hash160); + } + + string strDescription = "To: "; + if (mapAddressBook.count(strAddress) && !mapAddressBook[strAddress].empty()) + strDescription += mapAddressBook[strAddress] + " "; + strDescription += strAddress; + if (!mapValue["message"].empty()) + { + if (!strDescription.empty()) + strDescription += " - "; + strDescription += mapValue["message"]; + } + + int64 nValue = txout.nValue; + if (nOut == 0 && nTxFee > 0) + nValue += nTxFee; + + InsertLine(fNew, nIndex, hash, strprintf("%s-%d", strSort.c_str(), nOut), + strStatus, + nTime ? DateTimeStr(nTime) : "", + SingleLine(strDescription), + FormatMoney(-nValue, true), + ""); + } + } + else + { + // + // Mixed debit transaction, can't break down payees + // + bool fAllMine = true; + foreach(const CTxOut& txout, wtx.vout) + fAllMine = fAllMine && txout.IsMine(); + foreach(const CTxIn& txin, wtx.vin) + fAllMine = fAllMine && txin.IsMine(); + + InsertLine(fNew, nIndex, hash, strSort, + strStatus, + nTime ? DateTimeStr(nTime) : "", + "", + FormatMoney(nNet, true), + ""); + } + } +} + +void CMainFrame::RefreshStatus() +{ + static int nLastTop; + int nTop = m_listCtrl->GetTopItem(); + if (nTop == nLastTop && pindexBestLast == pindexBest) + return; + + TRY_CRITICAL_BLOCK(cs_mapWallet) + { + int nStart = nTop; + int nEnd = min(nStart + 100, m_listCtrl->GetItemCount()); + if (pindexBestLast == pindexBest) + { + if (nStart >= nLastTop && nStart < nLastTop + 100) + nStart = nLastTop + 100; + if (nEnd >= nLastTop && nEnd < nLastTop + 100) + nEnd = nLastTop; + } + nLastTop = nTop; + pindexBestLast = pindexBest; + + for (int nIndex = nStart; nIndex < nEnd; nIndex++) + { + uint256 hash((string)GetItemText(m_listCtrl, nIndex, 1)); + map::iterator mi = mapWallet.find(hash); + if (mi == mapWallet.end()) + { + printf("CMainFrame::RefreshStatus() : tx not found in mapWallet\n"); + continue; + } + const CWalletTx& wtx = (*mi).second; + if (wtx.IsCoinBase() || wtx.GetTxTime() != wtx.nTimeDisplayed) + InsertTransaction(wtx, false, nIndex); + else + m_listCtrl->SetItem(nIndex, 2, FormatTxStatus(wtx)); + } + } +} + +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 > vSorted; + TRY_CRITICAL_BLOCK(cs_mapWallet) + { + printf("RefreshListCtrl starting\n"); + fEntered = true; + fRefreshListCtrl = false; + vWalletUpdated.clear(); + + // Do the newest transactions first + vSorted.reserve(mapWallet.size()); + for (map::iterator it = mapWallet.begin(); it != 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(cs_mapWallet) + { + fEntered = true; + uint256& hash = vSorted[i++].second; + map::iterator mi = mapWallet.find(hash); + if (mi != mapWallet.end()) + InsertTransaction((*mi).second, true); + } + if (!fEntered || i == 100 || i % 500 == 0) + wxYield(); + } + + printf("RefreshListCtrl done\n"); + } + else + { + // Check for time updates + static int64 nLastTime; + if (GetTime() > nLastTime + 30) + { + TRY_CRITICAL_BLOCK(cs_mapWallet) + { + nLastTime = GetTime(); + for (map::iterator it = mapWallet.begin(); it != mapWallet.end(); ++it) + { + CWalletTx& wtx = (*it).second; + if (wtx.nTimeDisplayed && wtx.nTimeDisplayed != wtx.GetTxTime()) + InsertTransaction(wtx, false); + } + } + } + } +} + +void CMainFrame::OnPaint(wxPaintEvent& event) +{ + event.Skip(); +} + +void CMainFrame::OnPaintListCtrl(wxPaintEvent& event) +{ + // Update listctrl contents + if (!vWalletUpdated.empty()) + { + TRY_CRITICAL_BLOCK(cs_mapWallet) + { + pair item; + foreach(item, vWalletUpdated) + { + bool fNew = item.second; + map::iterator mi = mapWallet.find(item.first); + if (mi != mapWallet.end()) + { + printf("vWalletUpdated: %s %s\n", (*mi).second.GetHash().ToString().substr(0,6).c_str(), fNew ? "new" : ""); + InsertTransaction((*mi).second, fNew); + } + } + m_listCtrl->ScrollList(0, INT_MAX); + vWalletUpdated.clear(); + } + } + + // Update status column of visible items only + RefreshStatus(); + + // Update status bar + 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 + 1, m_listCtrl->GetItemCount()); + m_statusBar->SetStatusText(strStatus, 2); + + // Balance total + TRY_CRITICAL_BLOCK(cs_mapWallet) + m_staticTextBalance->SetLabel(FormatMoney(GetBalance()) + " "); + + m_listCtrl->OnPaint(event); +} + +void CrossThreadCall(wxCommandEvent& event) +{ + if (pframeMain) + pframeMain->GetEventHandler()->AddPendingEvent(event); +} + +void CrossThreadCall(int nID, void* pdata) +{ + wxCommandEvent event; + event.SetInt(nID); + event.SetClientData(pdata); + if (pframeMain) + pframeMain->GetEventHandler()->AddPendingEvent(event); +} + +void CMainFrame::OnCrossThreadCall(wxCommandEvent& event) +{ + void* pdata = event.GetClientData(); + switch (event.GetInt()) + { + case UICALL_ADDORDER: + { + break; + } + + case UICALL_UPDATEORDER: + { + break; + } + } +} + +void CMainFrame::OnMenuFileExit(wxCommandEvent& event) +{ + Close(true); +} + +void CMainFrame::OnMenuOptionsGenerate(wxCommandEvent& event) +{ + fGenerateBitcoins = event.IsChecked(); + nTransactionsUpdated++; + CWalletDB().WriteSetting("fGenerateBitcoins", fGenerateBitcoins); + + if (fGenerateBitcoins) + if (_beginthread(ThreadBitcoinMiner, 0, NULL) == -1) + printf("Error: _beginthread(ThreadBitcoinMiner) failed\n"); + + Refresh(); + wxPaintEvent eventPaint; + AddPendingEvent(eventPaint); +} + +void CMainFrame::OnMenuOptionsChangeYourAddress(wxCommandEvent& event) +{ + OnButtonChange(event); +} + +void CMainFrame::OnMenuOptionsOptions(wxCommandEvent& event) +{ + COptionsDialog dialog(this); + dialog.ShowModal(); +} + +void CMainFrame::OnMenuHelpAbout(wxCommandEvent& event) +{ + CAboutDialog dialog(this); + dialog.ShowModal(); +} + +void CMainFrame::OnButtonSend(wxCommandEvent& event) +{ + /// debug test + if (fRandSendTest) + { + RandSend(); + return; + } + + // Toolbar: Send + CSendDialog dialog(this); + dialog.ShowModal(); +} + +void CMainFrame::OnButtonAddressBook(wxCommandEvent& event) +{ + // Toolbar: Address Book + CAddressBookDialog dialogAddr(this, "", false); + if (dialogAddr.ShowModal() == 2) + { + // Send + CSendDialog dialogSend(this, dialogAddr.GetAddress()); + dialogSend.ShowModal(); + } +} + +void CMainFrame::OnSetFocusAddress(wxFocusEvent& event) +{ + // Automatically select-all when entering window + m_textCtrlAddress->SetSelection(-1, -1); + fOnSetFocusAddress = true; + event.Skip(); +} + +void CMainFrame::OnMouseEventsAddress(wxMouseEvent& event) +{ + if (fOnSetFocusAddress) + m_textCtrlAddress->SetSelection(-1, -1); + fOnSetFocusAddress = false; + event.Skip(); +} + +void CMainFrame::OnButtonCopy(wxCommandEvent& event) +{ + // Copy address box to clipboard + if (wxTheClipboard->Open()) + { + wxTheClipboard->SetData(new wxTextDataObject(m_textCtrlAddress->GetValue())); + wxTheClipboard->Close(); + } +} + +void CMainFrame::OnButtonChange(wxCommandEvent& event) +{ + CYourAddressDialog dialog(this, string(m_textCtrlAddress->GetValue())); + if (!dialog.ShowModal()) + return; + string strAddress = (string)dialog.GetAddress(); + if (strAddress != m_textCtrlAddress->GetValue()) + { + uint160 hash160; + if (!AddressToHash160(strAddress, hash160)) + return; + if (!mapPubKeys.count(hash160)) + return; + CWalletDB().WriteDefaultKey(mapPubKeys[hash160]); + m_textCtrlAddress->SetValue(strAddress); + } +} + +void CMainFrame::OnListItemActivatedAllTransactions(wxListEvent& event) +{ + uint256 hash((string)GetItemText(m_listCtrl, event.GetIndex(), 1)); + CWalletTx wtx; + CRITICAL_BLOCK(cs_mapWallet) + { + map::iterator mi = mapWallet.find(hash); + if (mi == mapWallet.end()) + { + printf("CMainFrame::OnListItemActivatedAllTransactions() : tx not found in mapWallet\n"); + return; + } + wtx = (*mi).second; + } + CTxDetailsDialog dialog(this, wtx); + dialog.ShowModal(); + //CTxDetailsDialog* pdialog = new CTxDetailsDialog(this, wtx); + //pdialog->Show(); +} + +void CMainFrame::OnListItemActivatedProductsSent(wxListEvent& event) +{ + CProduct& product = *(CProduct*)event.GetItem().GetData(); + CEditProductDialog* pdialog = new CEditProductDialog(this); + pdialog->SetProduct(product); + pdialog->Show(); +} + +void CMainFrame::OnListItemActivatedOrdersSent(wxListEvent& event) +{ + CWalletTx& order = *(CWalletTx*)event.GetItem().GetData(); + CViewOrderDialog* pdialog = new CViewOrderDialog(this, order, false); + pdialog->Show(); +} + +void CMainFrame::OnListItemActivatedOrdersReceived(wxListEvent& event) +{ + CWalletTx& order = *(CWalletTx*)event.GetItem().GetData(); + CViewOrderDialog* pdialog = new CViewOrderDialog(this, order, true); + pdialog->Show(); +} + + + + + + + +////////////////////////////////////////////////////////////////////////////// +// +// CTxDetailsDialog +// + +CTxDetailsDialog::CTxDetailsDialog(wxWindow* parent, CWalletTx wtx) : CTxDetailsDialogBase(parent) +{ + string strHTML; + strHTML.reserve(4000); + strHTML += ""; + + int64 nTime = wtx.GetTxTime(); + int64 nCredit = wtx.GetCredit(); + int64 nDebit = wtx.GetDebit(); + int64 nNet = nCredit - nDebit; + + + + strHTML += "Status: " + FormatTxStatus(wtx) + "
"; + strHTML += "Date: " + (nTime ? DateTimeStr(nTime) : "") + "
"; + + + // + // From + // + if (wtx.IsCoinBase()) + { + strHTML += "Source: Generated
"; + } + else if (!wtx.mapValue["from"].empty()) + { + // Online transaction + if (!wtx.mapValue["from"].empty()) + strHTML += "From: " + HtmlEscape(wtx.mapValue["from"]) + "
"; + } + else + { + // Offline transaction + if (nNet > 0) + { + // Credit + foreach(const CTxOut& txout, wtx.vout) + { + if (txout.IsMine()) + { + vector vchPubKey; + if (ExtractPubKey(txout.scriptPubKey, true, vchPubKey)) + { + string strAddress = PubKeyToAddress(vchPubKey); + if (mapAddressBook.count(strAddress)) + { + strHTML += "From: unknown
"; + strHTML += "To: "; + strHTML += HtmlEscape(strAddress); + if (!mapAddressBook[strAddress].empty()) + strHTML += " (yours, label: " + mapAddressBook[strAddress] + ")"; + else + strHTML += " (yours)"; + strHTML += "
"; + } + } + break; + } + } + } + } + + + // + // To + // + string strAddress; + if (!wtx.mapValue["to"].empty()) + { + // Online transaction + strAddress = wtx.mapValue["to"]; + strHTML += "To: "; + if (mapAddressBook.count(strAddress) && !mapAddressBook[strAddress].empty()) + strHTML += mapAddressBook[strAddress] + " "; + strHTML += HtmlEscape(strAddress) + "
"; + } + + + // + // Amount + // + if (wtx.IsCoinBase() && nCredit == 0) + { + // + // Coinbase + // + int64 nUnmatured = 0; + foreach(const CTxOut& txout, wtx.vout) + nUnmatured += txout.GetCredit(); + if (wtx.IsInMainChain()) + strHTML += strprintf("Credit: (%s matures in %d more blocks)
", FormatMoney(nUnmatured).c_str(), wtx.GetBlocksToMaturity()); + else + strHTML += "Credit: (not accepted)
"; + } + else if (nNet > 0) + { + // + // Credit + // + strHTML += "Credit: " + FormatMoney(nNet) + "
"; + } + else + { + bool fAllFromMe = true; + foreach(const CTxIn& txin, wtx.vin) + fAllFromMe = fAllFromMe && txin.IsMine(); + + bool fAllToMe = true; + foreach(const CTxOut& txout, wtx.vout) + fAllToMe = fAllToMe && txout.IsMine(); + + if (fAllFromMe) + { + // + // Debit + // + foreach(const CTxOut& txout, wtx.vout) + { + if (txout.IsMine()) + continue; + + if (wtx.mapValue["to"].empty()) + { + // Offline transaction + uint160 hash160; + if (ExtractHash160(txout.scriptPubKey, hash160)) + { + string strAddress = Hash160ToAddress(hash160); + strHTML += "To: "; + if (mapAddressBook.count(strAddress) && !mapAddressBook[strAddress].empty()) + strHTML += mapAddressBook[strAddress] + " "; + strHTML += strAddress; + strHTML += "
"; + } + } + + strHTML += "Debit: " + FormatMoney(-txout.nValue) + "
"; + } + + if (fAllToMe) + { + // Payment to self + int64 nValue = wtx.vout[0].nValue; + strHTML += "Debit: " + FormatMoney(-nValue) + "
"; + strHTML += "Credit: " + FormatMoney(nValue) + "
"; + } + + int64 nTxFee = nDebit - wtx.GetValueOut(); + if (nTxFee > 0) + strHTML += "Transaction fee: " + FormatMoney(-nTxFee) + "
"; + } + else + { + // + // Mixed debit transaction + // + foreach(const CTxIn& txin, wtx.vin) + if (txin.IsMine()) + strHTML += "Debit: " + FormatMoney(-txin.GetDebit()) + "
"; + foreach(const CTxOut& txout, wtx.vout) + if (txout.IsMine()) + strHTML += "Credit: " + FormatMoney(txout.GetCredit()) + "
"; + } + } + + strHTML += "Net amount: " + FormatMoney(nNet, true) + "
"; + + + // + // Message + // + if (!wtx.mapValue["message"].empty()) + strHTML += "
Message:
" + HtmlEscape(wtx.mapValue["message"], true) + "
"; + + if (wtx.IsCoinBase()) + strHTML += "
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.
"; + + + // + // Debug view + // + if (fDebug) + { + strHTML += "

debug print

"; + foreach(const CTxIn& txin, wtx.vin) + if (txin.IsMine()) + strHTML += "Debit: " + FormatMoney(-txin.GetDebit()) + "
"; + foreach(const CTxOut& txout, wtx.vout) + if (txout.IsMine()) + strHTML += "Credit: " + FormatMoney(txout.GetCredit()) + "
"; + + strHTML += "Inputs:
"; + CRITICAL_BLOCK(cs_mapWallet) + { + foreach(const CTxIn& txin, wtx.vin) + { + COutPoint prevout = txin.prevout; + map::iterator mi = mapWallet.find(prevout.hash); + if (mi != mapWallet.end()) + { + const CWalletTx& prev = (*mi).second; + if (prevout.n < prev.vout.size()) + { + strHTML += HtmlEscape(prev.ToString(), true); + strHTML += "    " + FormatTxStatus(prev) + ", "; + strHTML = strHTML + "IsMine=" + (prev.vout[prevout.n].IsMine() ? "true" : "false") + "
"; + } + } + } + } + + strHTML += "


Transaction:
"; + strHTML += HtmlEscape(wtx.ToString(), true); + } + + + + strHTML += "
"; + string(strHTML.begin(), strHTML.end()).swap(strHTML); + m_htmlWin->SetPage(strHTML); + m_buttonOK->SetFocus(); +} + +void CTxDetailsDialog::OnButtonOK(wxCommandEvent& event) +{ + Close(); + //Destroy(); +} + + + + + +////////////////////////////////////////////////////////////////////////////// +// +// COptionsDialog +// + +COptionsDialog::COptionsDialog(wxWindow* parent) : COptionsDialogBase(parent) +{ + m_textCtrlTransactionFee->SetValue(FormatMoney(nTransactionFee)); + m_buttonOK->SetFocus(); +} + +void COptionsDialog::OnKillFocusTransactionFee(wxFocusEvent& event) +{ + int64 nTmp = nTransactionFee; + ParseMoney(m_textCtrlTransactionFee->GetValue(), nTmp); + m_textCtrlTransactionFee->SetValue(FormatMoney(nTmp)); +} + +void COptionsDialog::OnButtonOK(wxCommandEvent& event) +{ + // nTransactionFee + int64 nPrevTransactionFee = nTransactionFee; + if (ParseMoney(m_textCtrlTransactionFee->GetValue(), nTransactionFee) && nTransactionFee != nPrevTransactionFee) + CWalletDB().WriteSetting("nTransactionFee", nTransactionFee); + + Close(); +} + +void COptionsDialog::OnButtonCancel(wxCommandEvent& event) +{ + Close(); +} + + + + + + +////////////////////////////////////////////////////////////////////////////// +// +// CAboutDialog +// + +CAboutDialog::CAboutDialog(wxWindow* parent) : CAboutDialogBase(parent) +{ + m_staticTextVersion->SetLabel(strprintf("version 0.%d.%d Alpha", VERSION/100, VERSION%100)); + + // Workaround until upgrade to wxWidgets supporting UTF-8 + wxString str = m_staticTextMain->GetLabel(); + if (str.Find('Â') != wxNOT_FOUND) + str.Remove(str.Find('Â'), 1); + m_staticTextMain->SetLabel(str); +} + +void CAboutDialog::OnButtonOK(wxCommandEvent& event) +{ + Close(); +} + + + + + + +////////////////////////////////////////////////////////////////////////////// +// +// CSendDialog +// + +CSendDialog::CSendDialog(wxWindow* parent, const wxString& strAddress) : CSendDialogBase(parent) +{ + // Init + m_textCtrlAddress->SetValue(strAddress); + m_choiceTransferType->SetSelection(0); + m_bitmapCheckMark->Show(false); + //// todo: should add a display of your balance for convenience + + // Set Icon + wxBitmap bmpSend(wxT("send16"), wxBITMAP_TYPE_RESOURCE); + bmpSend.SetMask(new wxMask(wxBitmap(wxT("send16masknoshadow"), wxBITMAP_TYPE_RESOURCE))); + wxIcon iconSend; + iconSend.CopyFromBitmap(bmpSend); + SetIcon(iconSend); + + wxCommandEvent event; + OnTextAddress(event); + + // Fixup the tab order + m_buttonPaste->MoveAfterInTabOrder(m_buttonCancel); + m_buttonAddress->MoveAfterInTabOrder(m_buttonPaste); + this->Layout(); +} + +void CSendDialog::OnTextAddress(wxCommandEvent& event) +{ + // Check mark + bool fBitcoinAddress = IsValidBitcoinAddress(m_textCtrlAddress->GetValue()); + m_bitmapCheckMark->Show(fBitcoinAddress); + + // Grey out message if bitcoin address + bool fEnable = !fBitcoinAddress; + m_staticTextFrom->Enable(fEnable); + m_textCtrlFrom->Enable(fEnable); + m_staticTextMessage->Enable(fEnable); + m_textCtrlMessage->Enable(fEnable); + m_textCtrlMessage->SetBackgroundColour(wxSystemSettings::GetColour(fEnable ? wxSYS_COLOUR_WINDOW : wxSYS_COLOUR_BTNFACE)); +} + +void CSendDialog::OnKillFocusAmount(wxFocusEvent& event) +{ + // Reformat the amount + 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(), true); + if (dialog.ShowModal()) + m_textCtrlAddress->SetValue(dialog.GetAddress()); +} + +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) +{ + 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 > GetBalance()) + { + wxMessageBox("Amount exceeds your balance ", "Send Coins"); + return; + } + if (nValue + nTransactionFee > 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) + { + // Send to bitcoin address + CScript scriptPubKey; + scriptPubKey << OP_DUP << OP_HASH160 << hash160 << OP_EQUALVERIFY << OP_CHECKSIG; + + if (!SendMoney(scriptPubKey, nValue, wtx)) + return; + + wxMessageBox("Payment sent ", "Sending..."); + } + else + { + // Parse IP address + CAddress addr(strAddress.c_str()); + if (addr.ip == 0) + { + wxMessageBox("Invalid address ", "Send Coins"); + return; + } + + // Message + wtx.mapValue["to"] = strAddress; + wtx.mapValue["from"] = m_textCtrlFrom->GetValue(); + wtx.mapValue["message"] = m_textCtrlMessage->GetValue(); + + // Send to IP address + CSendingDialog* pdialog = new CSendingDialog(this, addr, nValue, wtx); + if (!pdialog->ShowModal()) + return; + } + + if (!mapAddressBook.count(strAddress)) + 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(); + strStatus = ""; + fCanCancel = true; + fAbort = false; + fSuccess = false; + fUIDone = false; + fWorkDone = false; + + SetTitle(strprintf("Sending %s to %s...", FormatMoney(nPrice).c_str(), wtx.mapValue["to"].c_str())); + m_textCtrlStatus->SetValue(""); + + _beginthread(SendingDialogStartTransfer, 0, 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) +{ + if (strStatus.size() > 130) + m_textCtrlStatus->SetValue(string("\n") + strStatus); + else + m_textCtrlStatus->SetValue(string("\n\n") + strStatus); + 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()) + { + strStatus = "CANCELLED"; + m_buttonOK->Enable(true); + m_buttonOK->SetFocus(); + m_buttonCancel->Enable(false); + m_buttonCancel->SetLabel("Cancelled"); + Close(); + wxMessageBox("Transfer cancelled ", "Sending...", wxOK, this); + } + event.Skip(); + + /// debug test + if (fRandSendTest && fWorkDone && fSuccess) + { + Close(); + Sleep(1000); + RandSend(); + } +} + + +// +// 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; + AddPendingEvent(event); +} + +bool CSendingDialog::Status() +{ + if (fUIDone) + { + Destroy(); + return false; + } + if (fAbort && fCanCancel) + { + strStatus = "CANCELLED"; + Repaint(); + fWorkDone = true; + return false; + } + return true; +} + +bool CSendingDialog::Status(const string& str) +{ + if (!Status()) + return false; + strStatus = str; + 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 > GetBalance()) + { + Error("You don't have enough money"); + return; + } + + // We may have connected already for product details + if (!Status("Connecting...")) + return; + CNode* pnode = ConnectNode(addr, 5 * 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; + vRecv >> strMessage; + 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; + } + + // Should already be connected + CNode* pnode = ConnectNode(addr, 5 * 60); + if (!pnode) + { + Error("Lost connection"); + 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 > GetBalance()) + { + Error("You don't have enough money"); + return; + } + int64 nFeeRequired; + if (!CreateTransaction(scriptPubKey, nPrice, wtx, nFeeRequired)) + { + if (nPrice + nFeeRequired > GetBalance()) + Error(strprintf("This is an oversized transaction that requires a transaction fee of %s", FormatMoney(nFeeRequired).c_str())); + else + Error("Transaction creation failed"); + 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 (!CommitTransactionSpent(wtx)) + { + Error("Error finalizing payment"); + return; + } + + // Send payment tx to seller, with response going to OnReply3 via event handler + pnode->PushRequest("submitorder", wtx, SendingDialogOnReply3, this); + + // Accept and broadcast transaction + if (!wtx.AcceptTransaction()) + printf("ERROR: CSendingDialog : wtxNew.AcceptTransaction() %s failed\n", wtx.GetHash().ToString().c_str()); + wtx.RelayWalletTransaction(); + + 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 if it is valid,\n" + "but without comment information."); + 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"); +} + + + + + + +////////////////////////////////////////////////////////////////////////////// +// +// CYourAddressDialog +// + +CYourAddressDialog::CYourAddressDialog(wxWindow* parent, const string& strInitSelected) : CYourAddressDialogBase(parent) +{ + // Init column headers + m_listCtrl->InsertColumn(0, "Label", wxLIST_FORMAT_LEFT, 200); + m_listCtrl->InsertColumn(1, "Bitcoin Address", wxLIST_FORMAT_LEFT, 350); + m_listCtrl->SetFocus(); + + // Fill listctrl with address book data + CRITICAL_BLOCK(cs_mapKeys) + { + foreach(const PAIRTYPE(string, string)& item, mapAddressBook) + { + string strAddress = item.first; + string strName = item.second; + uint160 hash160; + bool fMine = (AddressToHash160(strAddress, hash160) && mapPubKeys.count(hash160)); + if (fMine) + { + int nIndex = InsertLine(m_listCtrl, strName, strAddress); + if (strAddress == strInitSelected) + m_listCtrl->SetItemState(nIndex, wxLIST_STATE_SELECTED|wxLIST_STATE_FOCUSED, wxLIST_STATE_SELECTED|wxLIST_STATE_FOCUSED); + } + } + } +} + +wxString CYourAddressDialog::GetAddress() +{ + int nIndex = GetSelection(m_listCtrl); + if (nIndex == -1) + return ""; + return GetItemText(m_listCtrl, nIndex, 1); +} + +void CYourAddressDialog::OnListEndLabelEdit(wxListEvent& event) +{ + // Update address book with edited name + if (event.IsEditCancelled()) + return; + string strAddress = (string)GetItemText(m_listCtrl, event.GetIndex(), 1); + SetAddressBookName(strAddress, string(event.GetText())); + pframeMain->RefreshListCtrl(); +} + +void CYourAddressDialog::OnListItemSelected(wxListEvent& event) +{ +} + +void CYourAddressDialog::OnListItemActivated(wxListEvent& event) +{ + // Doubleclick edits item + wxCommandEvent event2; + OnButtonRename(event2); +} + +void CYourAddressDialog::OnButtonRename(wxCommandEvent& event) +{ + // Ask new name + int nIndex = GetSelection(m_listCtrl); + if (nIndex == -1) + return; + string strName = (string)m_listCtrl->GetItemText(nIndex); + string strAddress = (string)GetItemText(m_listCtrl, nIndex, 1); + CGetTextFromUserDialog dialog(this, "Edit Address Label", "New Label", strName); + if (!dialog.ShowModal()) + return; + strName = dialog.GetValue(); + + // Change name + SetAddressBookName(strAddress, strName); + m_listCtrl->SetItemText(nIndex, strName); + pframeMain->RefreshListCtrl(); +} + +void CYourAddressDialog::OnButtonNew(wxCommandEvent& event) +{ + // Ask name + CGetTextFromUserDialog dialog(this, "New Bitcoin Address", "Label", ""); + if (!dialog.ShowModal()) + return; + string strName = dialog.GetValue(); + + // Generate new key + string strAddress = PubKeyToAddress(GenerateNewKey()); + SetAddressBookName(strAddress, strName); + + // Add to list and select it + int nIndex = InsertLine(m_listCtrl, strName, strAddress); + SetSelection(m_listCtrl, nIndex); + m_listCtrl->SetFocus(); +} + +void CYourAddressDialog::OnButtonCopy(wxCommandEvent& event) +{ + // Copy address box to clipboard + if (wxTheClipboard->Open()) + { + wxTheClipboard->SetData(new wxTextDataObject(GetAddress())); + wxTheClipboard->Close(); + } +} + +void CYourAddressDialog::OnButtonOK(wxCommandEvent& event) +{ + // OK + EndModal(true); +} + +void CYourAddressDialog::OnButtonCancel(wxCommandEvent& event) +{ + // Cancel + EndModal(false); +} + +void CYourAddressDialog::OnClose(wxCloseEvent& event) +{ + // Close + EndModal(false); +} + + + + + + +////////////////////////////////////////////////////////////////////////////// +// +// CAddressBookDialog +// + +CAddressBookDialog::CAddressBookDialog(wxWindow* parent, const wxString& strInitSelected, bool fSendingIn) : CAddressBookDialogBase(parent) +{ + fSending = fSendingIn; + if (!fSending) + m_buttonCancel->Show(false); + + // Init column headers + m_listCtrl->InsertColumn(0, "Name", wxLIST_FORMAT_LEFT, 200); + m_listCtrl->InsertColumn(1, "Address", wxLIST_FORMAT_LEFT, 350); + m_listCtrl->SetFocus(); + + // Set Icon + wxBitmap bmpAddressBook(wxT("addressbook16"), wxBITMAP_TYPE_RESOURCE); + bmpAddressBook.SetMask(new wxMask(wxBitmap(wxT("addressbook16mask"), wxBITMAP_TYPE_RESOURCE))); + wxIcon iconAddressBook; + iconAddressBook.CopyFromBitmap(bmpAddressBook); + SetIcon(iconAddressBook); + + // Fill listctrl with address book data + CRITICAL_BLOCK(cs_mapKeys) + { + foreach(const PAIRTYPE(string, string)& item, mapAddressBook) + { + string strAddress = item.first; + string strName = item.second; + uint160 hash160; + bool fMine = (AddressToHash160(strAddress, hash160) && mapPubKeys.count(hash160)); + if (!fMine) + { + int nIndex = InsertLine(m_listCtrl, strName, strAddress); + if (strAddress == strInitSelected) + m_listCtrl->SetItemState(nIndex, wxLIST_STATE_SELECTED|wxLIST_STATE_FOCUSED, wxLIST_STATE_SELECTED|wxLIST_STATE_FOCUSED); + } + } + } +} + +wxString CAddressBookDialog::GetAddress() +{ + int nIndex = GetSelection(m_listCtrl); + if (nIndex == -1) + return ""; + return GetItemText(m_listCtrl, nIndex, 1); +} + +void CAddressBookDialog::OnListEndLabelEdit(wxListEvent& event) +{ + // Update address book with edited name + if (event.IsEditCancelled()) + return; + string strAddress = (string)GetItemText(m_listCtrl, event.GetIndex(), 1); + SetAddressBookName(strAddress, string(event.GetText())); + pframeMain->RefreshListCtrl(); +} + +void CAddressBookDialog::OnListItemSelected(wxListEvent& event) +{ +} + +void CAddressBookDialog::OnListItemActivated(wxListEvent& event) +{ + if (fSending) + { + // Doubleclick returns selection + EndModal(GetAddress() != "" ? 2 : 0); + } + else + { + // Doubleclick edits item + wxCommandEvent event2; + OnButtonEdit(event2); + } +} + +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) +{ + // Ask new name + 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; + 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")); + + // Change name + if (strAddress != strAddressOrg) + CWalletDB().EraseName(strAddressOrg); + SetAddressBookName(strAddress, strName); + m_listCtrl->SetItem(nIndex, 1, strAddress); + m_listCtrl->SetItemText(nIndex, strName); + pframeMain->RefreshListCtrl(); +} + +void CAddressBookDialog::OnButtonNew(wxCommandEvent& event) +{ + // Ask name + string strName; + string strAddress; + do + { + CGetTextFromUserDialog dialog(this, "New Address", "Name", strName, "Address", strAddress); + if (!dialog.ShowModal()) + return; + strName = dialog.GetValue1(); + strAddress = dialog.GetValue2(); + } + while (CheckIfMine(strAddress, "New Address")); + + // Add to list and select it + SetAddressBookName(strAddress, strName); + int nIndex = InsertLine(m_listCtrl, strName, strAddress); + SetSelection(m_listCtrl, nIndex); + m_listCtrl->SetFocus(); + pframeMain->RefreshListCtrl(); +} + +void CAddressBookDialog::OnButtonDelete(wxCommandEvent& event) +{ + 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); + CWalletDB().EraseName(strAddress); + m_listCtrl->DeleteItem(nIndex); + } + } + pframeMain->RefreshListCtrl(); +} + +void CAddressBookDialog::OnButtonCopy(wxCommandEvent& event) +{ + // Copy address box to clipboard + if (wxTheClipboard->Open()) + { + wxTheClipboard->SetData(new wxTextDataObject(GetAddress())); + wxTheClipboard->Close(); + } +} + +void CAddressBookDialog::OnButtonOK(wxCommandEvent& event) +{ + // OK + EndModal(GetAddress() != "" ? 1 : 0); +} + +void CAddressBookDialog::OnButtonCancel(wxCommandEvent& event) +{ + // Cancel + EndModal(0); +} + +void CAddressBookDialog::OnClose(wxCloseEvent& event) +{ + // Close + EndModal(0); +} + + + + + + +////////////////////////////////////////////////////////////////////////////// +// +// CProductsDialog +// + +bool CompareIntStringPairBestFirst(const pair& item1, const pair& item2) +{ + return (item1.first > item2.first); +} + +CProductsDialog::CProductsDialog(wxWindow* parent) : CProductsDialogBase(parent) +{ + // Init column headers + m_listCtrl->InsertColumn(0, "Title", wxLIST_FORMAT_LEFT, 200); + m_listCtrl->InsertColumn(1, "Price", wxLIST_FORMAT_LEFT, 80); + m_listCtrl->InsertColumn(2, "Seller", wxLIST_FORMAT_LEFT, 80); + m_listCtrl->InsertColumn(3, "Stars", wxLIST_FORMAT_LEFT, 50); + m_listCtrl->InsertColumn(4, "Power", wxLIST_FORMAT_LEFT, 50); + + // Tally top categories + map mapTopCategories; + CRITICAL_BLOCK(cs_mapProducts) + for (map::iterator mi = mapProducts.begin(); mi != mapProducts.end(); ++mi) + mapTopCategories[(*mi).second.mapValue["category"]]++; + + // Sort top categories + vector > vTopCategories; + for (map::iterator mi = mapTopCategories.begin(); mi != mapTopCategories.end(); ++mi) + vTopCategories.push_back(make_pair((*mi).second, (*mi).first)); + sort(vTopCategories.begin(), vTopCategories.end(), CompareIntStringPairBestFirst); + + // Fill categories combo box + int nLimit = 250; + for (vector >::iterator it = vTopCategories.begin(); it != vTopCategories.end() && nLimit-- > 0; ++it) + m_comboBoxCategory->Append((*it).second); + + // Fill window with initial search + //wxCommandEvent event; + //OnButtonSearch(event); +} + +void CProductsDialog::OnCombobox(wxCommandEvent& event) +{ + OnButtonSearch(event); +} + +bool CompareProductsBestFirst(const CProduct* p1, const CProduct* p2) +{ + return (p1->nAtoms > p2->nAtoms); +} + +void CProductsDialog::OnButtonSearch(wxCommandEvent& event) +{ + string strCategory = (string)m_comboBoxCategory->GetValue(); + string strSearch = (string)m_textCtrlSearch->GetValue(); + + // Search products + vector vProductsFound; + CRITICAL_BLOCK(cs_mapProducts) + { + for (map::iterator mi = mapProducts.begin(); mi != mapProducts.end(); ++mi) + { + CProduct& product = (*mi).second; + if (product.mapValue["category"].find(strCategory) != -1) + { + if (product.mapValue["title"].find(strSearch) != -1 || + product.mapValue["description"].find(strSearch) != -1 || + product.mapValue["seller"].find(strSearch) != -1) + { + vProductsFound.push_back(&product); + } + } + } + } + + // Sort + sort(vProductsFound.begin(), vProductsFound.end(), CompareProductsBestFirst); + + // Display + foreach(CProduct* pproduct, vProductsFound) + { + InsertLine(m_listCtrl, + pproduct->mapValue["title"], + pproduct->mapValue["price"], + pproduct->mapValue["seller"], + pproduct->mapValue["stars"], + itostr(pproduct->nAtoms)); + } +} + +void CProductsDialog::OnListItemActivated(wxListEvent& event) +{ + // Doubleclick opens product + CViewProductDialog* pdialog = new CViewProductDialog(this, m_vProduct[event.GetIndex()]); + pdialog->Show(); +} + + + + + + + +////////////////////////////////////////////////////////////////////////////// +// +// CEditProductDialog +// + +CEditProductDialog::CEditProductDialog(wxWindow* parent) : CEditProductDialogBase(parent) +{ + m_textCtrlLabel[0 ] = m_textCtrlLabel0; + m_textCtrlLabel[1 ] = m_textCtrlLabel1; + m_textCtrlLabel[2 ] = m_textCtrlLabel2; + m_textCtrlLabel[3 ] = m_textCtrlLabel3; + m_textCtrlLabel[4 ] = m_textCtrlLabel4; + m_textCtrlLabel[5 ] = m_textCtrlLabel5; + m_textCtrlLabel[6 ] = m_textCtrlLabel6; + m_textCtrlLabel[7 ] = m_textCtrlLabel7; + m_textCtrlLabel[8 ] = m_textCtrlLabel8; + m_textCtrlLabel[9 ] = m_textCtrlLabel9; + m_textCtrlLabel[10] = m_textCtrlLabel10; + m_textCtrlLabel[11] = m_textCtrlLabel11; + m_textCtrlLabel[12] = m_textCtrlLabel12; + m_textCtrlLabel[13] = m_textCtrlLabel13; + m_textCtrlLabel[14] = m_textCtrlLabel14; + m_textCtrlLabel[15] = m_textCtrlLabel15; + m_textCtrlLabel[16] = m_textCtrlLabel16; + m_textCtrlLabel[17] = m_textCtrlLabel17; + m_textCtrlLabel[18] = m_textCtrlLabel18; + m_textCtrlLabel[19] = m_textCtrlLabel19; + + m_textCtrlField[0 ] = m_textCtrlField0; + m_textCtrlField[1 ] = m_textCtrlField1; + m_textCtrlField[2 ] = m_textCtrlField2; + m_textCtrlField[3 ] = m_textCtrlField3; + m_textCtrlField[4 ] = m_textCtrlField4; + m_textCtrlField[5 ] = m_textCtrlField5; + m_textCtrlField[6 ] = m_textCtrlField6; + m_textCtrlField[7 ] = m_textCtrlField7; + m_textCtrlField[8 ] = m_textCtrlField8; + m_textCtrlField[9 ] = m_textCtrlField9; + m_textCtrlField[10] = m_textCtrlField10; + m_textCtrlField[11] = m_textCtrlField11; + m_textCtrlField[12] = m_textCtrlField12; + m_textCtrlField[13] = m_textCtrlField13; + m_textCtrlField[14] = m_textCtrlField14; + m_textCtrlField[15] = m_textCtrlField15; + m_textCtrlField[16] = m_textCtrlField16; + m_textCtrlField[17] = m_textCtrlField17; + m_textCtrlField[18] = m_textCtrlField18; + m_textCtrlField[19] = m_textCtrlField19; + + m_buttonDel[0 ] = m_buttonDel0; + m_buttonDel[1 ] = m_buttonDel1; + m_buttonDel[2 ] = m_buttonDel2; + m_buttonDel[3 ] = m_buttonDel3; + m_buttonDel[4 ] = m_buttonDel4; + m_buttonDel[5 ] = m_buttonDel5; + m_buttonDel[6 ] = m_buttonDel6; + m_buttonDel[7 ] = m_buttonDel7; + m_buttonDel[8 ] = m_buttonDel8; + m_buttonDel[9 ] = m_buttonDel9; + m_buttonDel[10] = m_buttonDel10; + m_buttonDel[11] = m_buttonDel11; + m_buttonDel[12] = m_buttonDel12; + m_buttonDel[13] = m_buttonDel13; + m_buttonDel[14] = m_buttonDel14; + m_buttonDel[15] = m_buttonDel15; + m_buttonDel[16] = m_buttonDel16; + m_buttonDel[17] = m_buttonDel17; + m_buttonDel[18] = m_buttonDel18; + m_buttonDel[19] = m_buttonDel19; + + for (int i = 1; i < FIELDS_MAX; i++) + ShowLine(i, false); + + LayoutAll(); +} + +void CEditProductDialog::LayoutAll() +{ + m_scrolledWindow->Layout(); + m_scrolledWindow->GetSizer()->Fit(m_scrolledWindow); + this->Layout(); +} + +void CEditProductDialog::ShowLine(int i, bool fShow) +{ + m_textCtrlLabel[i]->Show(fShow); + m_textCtrlField[i]->Show(fShow); + m_buttonDel[i]->Show(fShow); +} + +void CEditProductDialog::OnButtonDel0(wxCommandEvent& event) { OnButtonDel(event, 0); } +void CEditProductDialog::OnButtonDel1(wxCommandEvent& event) { OnButtonDel(event, 1); } +void CEditProductDialog::OnButtonDel2(wxCommandEvent& event) { OnButtonDel(event, 2); } +void CEditProductDialog::OnButtonDel3(wxCommandEvent& event) { OnButtonDel(event, 3); } +void CEditProductDialog::OnButtonDel4(wxCommandEvent& event) { OnButtonDel(event, 4); } +void CEditProductDialog::OnButtonDel5(wxCommandEvent& event) { OnButtonDel(event, 5); } +void CEditProductDialog::OnButtonDel6(wxCommandEvent& event) { OnButtonDel(event, 6); } +void CEditProductDialog::OnButtonDel7(wxCommandEvent& event) { OnButtonDel(event, 7); } +void CEditProductDialog::OnButtonDel8(wxCommandEvent& event) { OnButtonDel(event, 8); } +void CEditProductDialog::OnButtonDel9(wxCommandEvent& event) { OnButtonDel(event, 9); } +void CEditProductDialog::OnButtonDel10(wxCommandEvent& event) { OnButtonDel(event, 10); } +void CEditProductDialog::OnButtonDel11(wxCommandEvent& event) { OnButtonDel(event, 11); } +void CEditProductDialog::OnButtonDel12(wxCommandEvent& event) { OnButtonDel(event, 12); } +void CEditProductDialog::OnButtonDel13(wxCommandEvent& event) { OnButtonDel(event, 13); } +void CEditProductDialog::OnButtonDel14(wxCommandEvent& event) { OnButtonDel(event, 14); } +void CEditProductDialog::OnButtonDel15(wxCommandEvent& event) { OnButtonDel(event, 15); } +void CEditProductDialog::OnButtonDel16(wxCommandEvent& event) { OnButtonDel(event, 16); } +void CEditProductDialog::OnButtonDel17(wxCommandEvent& event) { OnButtonDel(event, 17); } +void CEditProductDialog::OnButtonDel18(wxCommandEvent& event) { OnButtonDel(event, 18); } +void CEditProductDialog::OnButtonDel19(wxCommandEvent& event) { OnButtonDel(event, 19); } + +void CEditProductDialog::OnButtonDel(wxCommandEvent& event, int n) +{ + Freeze(); + int x, y; + m_scrolledWindow->GetViewStart(&x, &y); + int i; + for (i = n; i < FIELDS_MAX-1; i++) + { + m_textCtrlLabel[i]->SetValue(m_textCtrlLabel[i+1]->GetValue()); + m_textCtrlField[i]->SetValue(m_textCtrlField[i+1]->GetValue()); + if (!m_buttonDel[i+1]->IsShown()) + break; + } + m_textCtrlLabel[i]->SetValue(""); + m_textCtrlField[i]->SetValue(""); + ShowLine(i, false); + m_buttonAddField->Enable(true); + LayoutAll(); + m_scrolledWindow->Scroll(0, y); + Thaw(); +} + +void CEditProductDialog::OnButtonAddField(wxCommandEvent& event) +{ + for (int i = 0; i < FIELDS_MAX; i++) + { + if (!m_buttonDel[i]->IsShown()) + { + Freeze(); + ShowLine(i, true); + if (i == FIELDS_MAX-1) + m_buttonAddField->Enable(false); + LayoutAll(); + m_scrolledWindow->Scroll(0, 99999); + Thaw(); + break; + } + } +} + +void CEditProductDialog::OnButtonSend(wxCommandEvent& event) +{ + CProduct product; + GetProduct(product); + + // Sign the detailed product + product.vchPubKeyFrom = keyUser.GetPubKey(); + if (!keyUser.Sign(product.GetSigHash(), product.vchSig)) + { + wxMessageBox("Error digitally signing the product "); + return; + } + + // Save detailed product + AddToMyProducts(product); + + // Strip down to summary product + product.mapDetails.clear(); + product.vOrderForm.clear(); + + // Sign the summary product + if (!keyUser.Sign(product.GetSigHash(), product.vchSig)) + { + wxMessageBox("Error digitally signing the product "); + return; + } + + // Verify + if (!product.CheckProduct()) + { + wxMessageBox("Errors found in product "); + return; + } + + // Broadcast + AdvertStartPublish(pnodeLocalHost, MSG_PRODUCT, 0, product); + + Destroy(); +} + +void CEditProductDialog::OnButtonPreview(wxCommandEvent& event) +{ + CProduct product; + GetProduct(product); + CViewProductDialog* pdialog = new CViewProductDialog(this, product); + pdialog->Show(); +} + +void CEditProductDialog::OnButtonCancel(wxCommandEvent& event) +{ + Destroy(); +} + +void CEditProductDialog::SetProduct(const CProduct& productIn) +{ + CProduct product = productIn; + + m_comboBoxCategory->SetValue(product.mapValue["category"]); + m_textCtrlTitle->SetValue(product.mapValue["title"]); + m_textCtrlPrice->SetValue(product.mapValue["price"]); + m_textCtrlDescription->SetValue(product.mapValue["description"]); + m_textCtrlInstructions->SetValue(product.mapValue["instructions"]); + + for (int i = 0; i < FIELDS_MAX; i++) + { + bool fUsed = i < product.vOrderForm.size(); + m_buttonDel[i]->Show(fUsed); + m_textCtrlLabel[i]->Show(fUsed); + m_textCtrlField[i]->Show(fUsed); + if (!fUsed) + continue; + + m_textCtrlLabel[i]->SetValue(product.vOrderForm[i].first); + string strControl = product.vOrderForm[i].second; + if (strControl.substr(0, 5) == "text=") + m_textCtrlField[i]->SetValue(""); + else if (strControl.substr(0, 7) == "choice=") + m_textCtrlField[i]->SetValue(strControl.substr(7)); + else + m_textCtrlField[i]->SetValue(strControl); + } +} + +void CEditProductDialog::GetProduct(CProduct& product) +{ + // map mapValue; + // vector > vOrderForm; + + product.mapValue["category"] = m_comboBoxCategory->GetValue().Trim(); + product.mapValue["title"] = m_textCtrlTitle->GetValue().Trim(); + product.mapValue["price"] = m_textCtrlPrice->GetValue().Trim(); + product.mapValue["description"] = m_textCtrlDescription->GetValue().Trim(); + product.mapValue["instructions"] = m_textCtrlInstructions->GetValue().Trim(); + + for (int i = 0; i < FIELDS_MAX; i++) + { + if (m_buttonDel[i]->IsShown()) + { + string strLabel = (string)m_textCtrlLabel[i]->GetValue().Trim(); + string strControl = (string)m_textCtrlField[i]->GetValue(); + if (strControl.empty()) + strControl = "text="; + else + strControl = "choice=" + strControl; + product.vOrderForm.push_back(make_pair(strLabel, strControl)); + } + } +} + + + + + + + +////////////////////////////////////////////////////////////////////////////// +// +// CViewProductDialog +// + +CViewProductDialog::CViewProductDialog(wxWindow* parent, const CProduct& productIn) : CViewProductDialogBase(parent) +{ + Connect(wxEVT_REPLY1, wxCommandEventHandler(CViewProductDialog::OnReply1), NULL, this); + AddCallbackAvailable(GetEventHandler()); + + // Fill display with product summary while waiting for details + product = productIn; + UpdateProductDisplay(false); + + m_buttonBack->Enable(false); + m_buttonNext->Enable(!product.vOrderForm.empty()); + m_htmlWinReviews->Show(true); + m_scrolledWindow->Show(false); + this->Layout(); + + // Request details from seller + _beginthread(ThreadRequestProductDetails, 0, new pair(product, GetEventHandler())); +} + +CViewProductDialog::~CViewProductDialog() +{ + RemoveCallbackAvailable(GetEventHandler()); +} + +void ThreadRequestProductDetails(void* parg) +{ + // Extract parameters + pair* pitem = (pair*)parg; + CProduct product = pitem->first; + wxEvtHandler* pevthandler = pitem->second; + delete pitem; + + // Connect to seller + CNode* pnode = ConnectNode(product.addr, 5 * 60); + if (!pnode) + { + CDataStream ssEmpty; + AddPendingReplyEvent1(pevthandler, ssEmpty); + return; + } + + // Request detailed product, with response going to OnReply1 via dialog's event handler + pnode->PushRequest("getdetails", product.GetHash(), AddPendingReplyEvent1, (void*)pevthandler); +} + +void CViewProductDialog::OnReply1(wxCommandEvent& event) +{ + CDataStream ss = GetStreamFromEvent(event); + if (ss.empty()) + { + product.mapValue["description"] = "-- CAN'T CONNECT TO SELLER --\n"; + UpdateProductDisplay(true); + return; + } + + int nRet; + CProduct product2; + try + { + ss >> nRet; + if (nRet > 0) + throw false; + ss >> product2; + if (product2.GetHash() != product.GetHash()) + throw false; + if (!product2.CheckSignature()) + throw false; + } + catch (...) + { + product.mapValue["description"] = "-- INVALID RESPONSE --\n"; + UpdateProductDisplay(true); + return; + } + + product = product2; + UpdateProductDisplay(true); +} + +bool CompareReviewsBestFirst(const CReview* p1, const CReview* p2) +{ + return (p1->nAtoms > p2->nAtoms); +} + +void CViewProductDialog::UpdateProductDisplay(bool fDetails) +{ + // Product and reviews + string strHTML; + strHTML.reserve(4000); + strHTML += "\n" + "\n" + "\n" + "\n" + "\n"; + strHTML += "Category: " + HtmlEscape(product.mapValue["category"]) + "
\n"; + strHTML += "Title: " + HtmlEscape(product.mapValue["title"]) + "
\n"; + strHTML += "Price: " + HtmlEscape(product.mapValue["price"]) + "
\n"; + + if (!fDetails) + strHTML += "Loading details...
\n
\n"; + else + strHTML += HtmlEscape(product.mapValue["description"], true) + "
\n
\n"; + + strHTML += "Reviews:
\n
\n"; + + if (!product.vchPubKeyFrom.empty()) + { + CReviewDB reviewdb("r"); + + // Get reviews + vector vReviews; + reviewdb.ReadReviews(product.GetUserHash(), vReviews); + + // Get reviewer's number of atoms + vector vSortedReviews; + vSortedReviews.reserve(vReviews.size()); + for (vector::reverse_iterator it = vReviews.rbegin(); it != vReviews.rend(); ++it) + { + CReview& review = *it; + CUser user; + reviewdb.ReadUser(review.GetUserHash(), user); + review.nAtoms = user.GetAtomCount(); + vSortedReviews.push_back(&review); + } + + reviewdb.Close(); + + // Sort + stable_sort(vSortedReviews.begin(), vSortedReviews.end(), CompareReviewsBestFirst); + + // Format reviews + foreach(CReview* preview, vSortedReviews) + { + CReview& review = *preview; + int nStars = atoi(review.mapValue["stars"].c_str()); + if (nStars < 1 || nStars > 5) + continue; + + strHTML += "" + itostr(nStars) + (nStars == 1 ? " star" : " stars") + ""; + strHTML += "     "; + strHTML += DateStr(atoi64(review.mapValue["date"])) + "
\n"; + strHTML += HtmlEscape(review.mapValue["review"], true); + strHTML += "
\n
\n"; + } + } + + strHTML += "\n\n"; + + // Shrink capacity to fit + string(strHTML.begin(), strHTML.end()).swap(strHTML); + + m_htmlWinReviews->SetPage(strHTML); + + ///// need to find some other indicator to use so can allow empty order form + if (product.vOrderForm.empty()) + return; + + // Order form + m_staticTextInstructions->SetLabel(product.mapValue["instructions"]); + for (int i = 0; i < FIELDS_MAX; i++) + { + m_staticTextLabel[i] = NULL; + m_textCtrlField[i] = NULL; + m_choiceField[i] = NULL; + } + + // Construct flexgridsizer + wxBoxSizer* bSizer21 = (wxBoxSizer*)m_scrolledWindow->GetSizer(); + wxFlexGridSizer* fgSizer; + fgSizer = new wxFlexGridSizer(0, 2, 0, 0); + fgSizer->AddGrowableCol(1); + fgSizer->SetFlexibleDirection(wxBOTH); + fgSizer->SetNonFlexibleGrowMode(wxFLEX_GROWMODE_SPECIFIED); + + // Construct order form fields + wxWindow* windowLast = NULL; + for (int i = 0; i < product.vOrderForm.size(); i++) + { + string strLabel = product.vOrderForm[i].first; + string strControl = product.vOrderForm[i].second; + + if (strLabel.size() < 20) + strLabel.insert(strLabel.begin(), 20 - strLabel.size(), ' '); + + m_staticTextLabel[i] = new wxStaticText(m_scrolledWindow, wxID_ANY, strLabel, wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT); + m_staticTextLabel[i]->Wrap(-1); + fgSizer->Add(m_staticTextLabel[i], 0, wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxALL, 5); + + if (strControl.substr(0, 5) == "text=") + { + m_textCtrlField[i] = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0); + fgSizer->Add(m_textCtrlField[i], 1, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5); + windowLast = m_textCtrlField[i]; + } + else if (strControl.substr(0, 7) == "choice=") + { + vector vChoices; + ParseString(strControl.substr(7), ',', vChoices); + + wxArrayString arraystring; + foreach(const string& str, vChoices) + arraystring.Add(str); + + m_choiceField[i] = new wxChoice(m_scrolledWindow, wxID_ANY, wxDefaultPosition, wxDefaultSize, arraystring, 0); + fgSizer->Add(m_choiceField[i], 0, wxALL|wxALIGN_CENTER_VERTICAL, 5); + windowLast = m_choiceField[i]; + } + else + { + m_textCtrlField[i] = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0); + fgSizer->Add(m_textCtrlField[i], 1, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5); + m_staticTextLabel[i]->Show(false); + m_textCtrlField[i]->Show(false); + } + } + + // Insert after instructions and before submit/cancel buttons + bSizer21->Insert(2, fgSizer, 0, wxEXPAND|wxRIGHT|wxLEFT, 5); + m_scrolledWindow->Layout(); + bSizer21->Fit(m_scrolledWindow); + this->Layout(); + + // Fixup the tab order + m_buttonSubmitForm->MoveAfterInTabOrder(windowLast); + m_buttonCancelForm->MoveAfterInTabOrder(m_buttonSubmitForm); + //m_buttonBack->MoveAfterInTabOrder(m_buttonCancelForm); + //m_buttonNext->MoveAfterInTabOrder(m_buttonBack); + //m_buttonCancel->MoveAfterInTabOrder(m_buttonNext); + this->Layout(); +} + +void CViewProductDialog::GetOrder(CWalletTx& wtx) +{ + wtx.SetNull(); + for (int i = 0; i < product.vOrderForm.size(); i++) + { + string strValue; + if (m_textCtrlField[i]) + strValue = m_textCtrlField[i]->GetValue().Trim(); + else + strValue = m_choiceField[i]->GetStringSelection(); + wtx.vOrderForm.push_back(make_pair(m_staticTextLabel[i]->GetLabel(), strValue)); + } +} + +void CViewProductDialog::OnButtonSubmitForm(wxCommandEvent& event) +{ + m_buttonSubmitForm->Enable(false); + m_buttonCancelForm->Enable(false); + + CWalletTx wtx; + GetOrder(wtx); + + CSendingDialog* pdialog = new CSendingDialog(this, product.addr, atoi64(product.mapValue["price"]), wtx); + if (!pdialog->ShowModal()) + { + m_buttonSubmitForm->Enable(true); + m_buttonCancelForm->Enable(true); + return; + } +} + +void CViewProductDialog::OnButtonCancelForm(wxCommandEvent& event) +{ + Destroy(); +} + +void CViewProductDialog::OnButtonBack(wxCommandEvent& event) +{ + Freeze(); + m_htmlWinReviews->Show(true); + m_scrolledWindow->Show(false); + m_buttonBack->Enable(false); + m_buttonNext->Enable(!product.vOrderForm.empty()); + this->Layout(); + Thaw(); +} + +void CViewProductDialog::OnButtonNext(wxCommandEvent& event) +{ + if (!product.vOrderForm.empty()) + { + Freeze(); + m_htmlWinReviews->Show(false); + m_scrolledWindow->Show(true); + m_buttonBack->Enable(true); + m_buttonNext->Enable(false); + this->Layout(); + Thaw(); + } +} + +void CViewProductDialog::OnButtonCancel(wxCommandEvent& event) +{ + Destroy(); +} + + + + + + + +////////////////////////////////////////////////////////////////////////////// +// +// CViewOrderDialog +// + +CViewOrderDialog::CViewOrderDialog(wxWindow* parent, CWalletTx order, bool fReceived) : CViewOrderDialogBase(parent) +{ + int64 nPrice = (fReceived ? order.GetCredit() : order.GetDebit()); + + string strHTML; + strHTML.reserve(4000); + strHTML += "\n" + "\n" + "\n" + "\n" + "\n"; + strHTML += "Time: " + HtmlEscape(DateTimeStr(order.nTimeReceived)) + "
\n"; + strHTML += "Price: " + HtmlEscape(FormatMoney(nPrice)) + "
\n"; + strHTML += "Status: " + HtmlEscape(FormatTxStatus(order)) + "
\n"; + + strHTML += "\n"; + for (int i = 0; i < order.vOrderForm.size(); i++) + { + strHTML += " "; + strHTML += "\n"; + } + strHTML += "
" + HtmlEscape(order.vOrderForm[i].first) + ":" + HtmlEscape(order.vOrderForm[i].second) + "
\n"; + + strHTML += "\n\n"; + + // Shrink capacity to fit + // (strings are ref counted, so it may live on in SetPage) + string(strHTML.begin(), strHTML.end()).swap(strHTML); + + m_htmlWin->SetPage(strHTML); +} + +void CViewOrderDialog::OnButtonOK(wxCommandEvent& event) +{ + Destroy(); +} + + + + + + + +////////////////////////////////////////////////////////////////////////////// +// +// CEditReviewDialog +// + +CEditReviewDialog::CEditReviewDialog(wxWindow* parent) : CEditReviewDialogBase(parent) +{ +} + +void CEditReviewDialog::OnButtonSubmit(wxCommandEvent& event) +{ + if (m_choiceStars->GetSelection() == -1) + { + wxMessageBox("Please select a rating "); + return; + } + + CReview review; + GetReview(review); + + // Sign the review + review.vchPubKeyFrom = keyUser.GetPubKey(); + if (!keyUser.Sign(review.GetSigHash(), review.vchSig)) + { + wxMessageBox("Unable to digitally sign the review "); + return; + } + + // Broadcast + if (!review.AcceptReview()) + { + wxMessageBox("Save failed "); + return; + } + RelayMessage(CInv(MSG_REVIEW, review.GetHash()), review); + + Destroy(); +} + +void CEditReviewDialog::OnButtonCancel(wxCommandEvent& event) +{ + Destroy(); +} + +void CEditReviewDialog::GetReview(CReview& review) +{ + review.mapValue["time"] = i64tostr(GetAdjustedTime()); + review.mapValue["stars"] = itostr(m_choiceStars->GetSelection()+1); + review.mapValue["review"] = m_textCtrlReview->GetValue(); +} + + + + + + + + + + + + +////////////////////////////////////////////////////////////////////////////// +// +// CMyApp +// + +// Define a new application +class CMyApp: public wxApp +{ + public: + CMyApp(){}; + ~CMyApp(){}; + bool OnInit(); + bool OnInit2(); + int OnExit(); + + // 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::OnInit() +{ + try + { + return OnInit2(); + } + catch (std::exception& e) { + PrintException(&e, "OnInit()"); + } catch (...) { + PrintException(NULL, "OnInit()"); + } + return false; +} + +map ParseParameters(int argc, char* argv[]) +{ + map mapArgs; + for (int i = 0; i < argc; i++) + { + char psz[10000]; + strcpy(psz, argv[i]); + char* pszValue = ""; + if (strchr(psz, '=')) + { + pszValue = strchr(psz, '='); + *pszValue++ = '\0'; + } + strlwr(psz); + if (psz[0] == '-') + psz[0] = '/'; + mapArgs[psz] = pszValue; + } + return mapArgs; +} + +bool CMyApp::OnInit2() +{ +#ifdef _MSC_VER + // Turn off microsoft heap dump noise for now + _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE); + _CrtSetReportFile(_CRT_WARN, CreateFile("NUL", GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0)); +#endif +#ifdef __WXDEBUG__ + // Disable malfunctioning wxWidgets debug assertion + g_isPainting = 10000; +#endif + + //// debug print + printf("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"); + printf("Bitcoin version %d, Windows version %08x\n", VERSION, GetVersion()); + + // + // Limit to single instance per user + // Required to protect the database files if we're going to keep deleting log.* + // + wxString strMutexName = wxString("Bitcoin.") + 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 = FindWindow("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; + } + } + + // + // Parameters + // + wxImage::AddHandler(new wxPNGHandler); + map mapArgs = ParseParameters(argc, argv); + + if (mapArgs.count("/datadir")) + strSetDataDir = mapArgs["/datadir"]; + + if (mapArgs.count("/proxy")) + addrProxy = CAddress(mapArgs["/proxy"].c_str()); + + if (mapArgs.count("/debug")) + fDebug = true; + + if (mapArgs.count("/dropmessages")) + { + nDropMessagesTest = atoi(mapArgs["/dropmessages"]); + if (nDropMessagesTest == 0) + nDropMessagesTest = 20; + } + + if (mapArgs.count("/loadblockindextest")) + { + CTxDB txdb("r"); + txdb.LoadBlockIndex(); + PrintBlockTree(); + ExitProcess(0); + } + + // + // Load data files + // + string strErrors; + int64 nStart, nEnd; + + printf("Loading addresses...\n"); + QueryPerformanceCounter((LARGE_INTEGER*)&nStart); + if (!LoadAddresses()) + strErrors += "Error loading addr.dat \n"; + QueryPerformanceCounter((LARGE_INTEGER*)&nEnd); + printf(" addresses %20I64d\n", nEnd - nStart); + + printf("Loading block index...\n"); + QueryPerformanceCounter((LARGE_INTEGER*)&nStart); + if (!LoadBlockIndex()) + strErrors += "Error loading blkindex.dat \n"; + QueryPerformanceCounter((LARGE_INTEGER*)&nEnd); + printf(" block index %20I64d\n", nEnd - nStart); + + printf("Loading wallet...\n"); + QueryPerformanceCounter((LARGE_INTEGER*)&nStart); + if (!LoadWallet()) + strErrors += "Error loading wallet.dat \n"; + QueryPerformanceCounter((LARGE_INTEGER*)&nEnd); + printf(" wallet %20I64d\n", nEnd - nStart); + + printf("Done loading\n"); + + //// debug print + printf("mapBlockIndex.size() = %d\n", mapBlockIndex.size()); + printf("nBestHeight = %d\n", nBestHeight); + printf("mapKeys.size() = %d\n", mapKeys.size()); + printf("mapPubKeys.size() = %d\n", mapPubKeys.size()); + printf("mapWallet.size() = %d\n", mapWallet.size()); + printf("mapAddressBook.size() = %d\n", mapAddressBook.size()); + + if (!strErrors.empty()) + { + wxMessageBox(strErrors, "Bitcoin"); + OnExit(); + return false; + } + + // Add wallet transactions that aren't already in a block to mapTransactions + ReacceptWalletTransactions(); + + // + // Parameters + // + if (mapArgs.count("/printblockindex") || mapArgs.count("/printblocktree")) + { + PrintBlockTree(); + OnExit(); + return false; + } + + if (mapArgs.count("/gen")) + { + if (mapArgs["/gen"].empty()) + fGenerateBitcoins = true; + else + fGenerateBitcoins = atoi(mapArgs["/gen"].c_str()); + } + + // + // Create the main frame window + // + { + pframeMain = new CMainFrame(NULL); + pframeMain->Show(); + + if (!CheckDiskSpace()) + { + OnExit(); + return false; + } + + if (!StartNode(strErrors)) + wxMessageBox(strErrors, "Bitcoin"); + + if (fGenerateBitcoins) + if (_beginthread(ThreadBitcoinMiner, 0, NULL) == -1) + printf("Error: _beginthread(ThreadBitcoinMiner) failed\n"); + + // + // Tests + // + if (argc >= 2 && stricmp(argv[1], "/send") == 0) + { + int64 nValue = 1; + if (argc >= 3) + ParseMoney(argv[2], nValue); + + string strAddress; + if (argc >= 4) + strAddress = argv[3]; + CAddress addr(strAddress.c_str()); + + CWalletTx wtx; + wtx.mapValue["to"] = strAddress; + wtx.mapValue["from"] = addrLocalHost.ToString(); + wtx.mapValue["message"] = "command line send"; + + // Send to IP address + CSendingDialog* pdialog = new CSendingDialog(pframeMain, addr, nValue, wtx); + if (!pdialog->ShowModal()) + return false; + } + + if (mapArgs.count("/randsendtest")) + { + if (!mapArgs["/randsendtest"].empty()) + _beginthread(ThreadRandSendTest, 0, new string(mapArgs["/randsendtest"])); + else + fRandSendTest = true; + fDebug = true; + } + } + + return true; +} + +int CMyApp::OnExit() +{ + Shutdown(NULL); + return wxApp::OnExit(); +} + +bool CMyApp::OnExceptionInMainLoop() +{ + try + { + throw; + } + catch (std::exception& e) + { + PrintException(&e, "CMyApp::OnExceptionInMainLoop()"); + wxLogWarning(_T("Exception %s %s"), typeid(e).name(), e.what()); + Sleep(1000); + throw; + } + catch (...) + { + PrintException(NULL, "CMyApp::OnExceptionInMainLoop()"); + wxLogWarning(_T("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(_T("Exception %s %s"), typeid(e).name(), e.what()); + Sleep(1000); + throw; + } + catch (...) + { + PrintException(NULL, "CMyApp::OnUnhandledException()"); + wxLogWarning(_T("Unknown exception")); + Sleep(1000); + throw; + } +} + +void CMyApp::OnFatalException() +{ + wxMessageBox("Program has crashed and will terminate. ", "Bitcoin", wxOK | wxICON_ERROR); +} + + + +void MainFrameRepaint() +{ + if (pframeMain) + { + printf("MainFrameRepaint()\n"); + wxPaintEvent event; + pframeMain->Refresh(); + pframeMain->AddPendingEvent(event); + } +} + + + + + + + +// randsendtest to bitcoin address +void ThreadRandSendTest(void* parg) +{ + string strAddress = *(string*)parg; + uint160 hash160; + if (!AddressToHash160(strAddress, hash160)) + { + wxMessageBox(strprintf("ThreadRandSendTest: Bitcoin address '%s' not valid ", strAddress.c_str())); + return; + } + + loop + { + Sleep(GetRand(30) * 1000 + 100); + + // Message + CWalletTx wtx; + wtx.mapValue["to"] = strAddress; + wtx.mapValue["from"] = addrLocalHost.ToString(); + static int nRep; + wtx.mapValue["message"] = strprintf("randsendtest %d\n", ++nRep); + + // Value + int64 nValue = (GetRand(9) + 1) * 100 * CENT; + if (GetBalance() < nValue) + { + wxMessageBox("Out of money "); + return; + } + nValue += (nRep % 100) * CENT; + + // Send to bitcoin address + CScript scriptPubKey; + scriptPubKey << OP_DUP << OP_HASH160 << hash160 << OP_EQUALVERIFY << OP_CHECKSIG; + + if (!SendMoney(scriptPubKey, nValue, wtx)) + return; + } +} + + +// randsendtest to any connected node +void RandSend() +{ + CWalletTx wtx; + + while (vNodes.empty()) + Sleep(1000); + CAddress addr; + CRITICAL_BLOCK(cs_vNodes) + addr = vNodes[GetRand(vNodes.size())]->addr; + + // Message + wtx.mapValue["to"] = addr.ToString(); + wtx.mapValue["from"] = addrLocalHost.ToString(); + static int nRep; + wtx.mapValue["message"] = strprintf("randsendtest %d\n", ++nRep); + + // Value + int64 nValue = (GetRand(999) + 1) * CENT; + if (GetBalance() < nValue) + { + wxMessageBox("Out of money "); + return; + } + + // Send to IP address + CSendingDialog* pdialog = new CSendingDialog(pframeMain, addr, nValue, wtx); + if (!pdialog->Show()) + wxMessageBox("ShowModal Failed "); +} diff --git a/ui.h b/ui.h new file mode 100644 index 0000000000..163554a599 --- /dev/null +++ b/ui.h @@ -0,0 +1,420 @@ +// Copyright (c) 2009 Satoshi Nakamoto +// Distributed under the MIT/X11 software license, see the accompanying +// file license.txt or http://www.opensource.org/licenses/mit-license.php. + + + + +DECLARE_EVENT_TYPE(wxEVT_CROSSTHREADCALL, -1) +DECLARE_EVENT_TYPE(wxEVT_REPLY1, -1) +DECLARE_EVENT_TYPE(wxEVT_REPLY2, -1) +DECLARE_EVENT_TYPE(wxEVT_REPLY3, -1) +DECLARE_EVENT_TYPE(wxEVT_TABLEADDED, -1) +DECLARE_EVENT_TYPE(wxEVT_TABLEUPDATED, -1) +DECLARE_EVENT_TYPE(wxEVT_TABLEDELETED, -1) + +enum +{ + UICALL_ADDORDER = 1, + UICALL_UPDATEORDER, +}; + + + +extern void HandleCtrlA(wxKeyEvent& event); +extern string DateTimeStr(int64 nTime); +extern string FormatTxStatus(const CWalletTx& wtx); +extern void CrossThreadCall(int nID, void* pdata); +extern void MainFrameRepaint(); +extern void Shutdown(void* parg); + + + + + + +class CMainFrame : public CMainFrameBase +{ +protected: + // Event handlers + void OnClose(wxCloseEvent& 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 OnMenuOptionsGenerate(wxCommandEvent& 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 OnButtonCopy(wxCommandEvent& event); + void OnButtonChange(wxCommandEvent& event); + void OnListColBeginDrag(wxListEvent& event); + void OnListItemActivatedAllTransactions(wxListEvent& event); + void OnListItemActivatedProductsSent(wxListEvent& event); + void OnListItemActivatedOrdersSent(wxListEvent& event); + void OnListItemActivatedOrdersReceived(wxListEvent& event); + +public: + /** Constructor */ + CMainFrame(wxWindow* parent); + ~CMainFrame(); + + // Custom + bool fRefreshListCtrl; + bool fRefreshListCtrlRunning; + bool fOnSetFocusAddress; + CBlockIndex* pindexBestLast; + set setUnmaturedDisplayed; + + void OnCrossThreadCall(wxCommandEvent& event); + void InsertLine(bool fNew, int nIndex, uint256 hashKey, string strSort, const wxString& str1, const wxString& str2, const wxString& str3, const wxString& str4, const wxString& str5); + void InsertTransaction(const CWalletTx& wtx, bool fNew, int nIndex=-1); + void RefreshListCtrl(); + void RefreshStatus(); +}; + + + + +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 OnKillFocusTransactionFee(wxFocusEvent& event); + void OnButtonOK(wxCommandEvent& event); + void OnButtonCancel(wxCommandEvent& event); + +public: + /** Constructor */ + COptionsDialog(wxWindow* parent); +}; + + + +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 OnTextAddress(wxCommandEvent& 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=""); +}; + + + +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; + string strStatus; + bool fCanCancel; + bool fAbort; + bool fSuccess; + bool fUIDone; + bool fWorkDone; + + void Close(); + void Repaint(); + bool Status(); + bool Status(const string& str); + bool Error(const 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 CYourAddressDialog : public CYourAddressDialogBase +{ +protected: + // Event handlers + void OnListEndLabelEdit(wxListEvent& event); + void OnListItemSelected(wxListEvent& event); + void OnListItemActivated(wxListEvent& event); + void OnButtonRename(wxCommandEvent& event); + void OnButtonNew(wxCommandEvent& event); + void OnButtonCopy(wxCommandEvent& event); + void OnButtonOK(wxCommandEvent& event); + void OnButtonCancel(wxCommandEvent& event); + void OnClose(wxCloseEvent& event); + +public: + /** Constructor */ + CYourAddressDialog(wxWindow* parent); + CYourAddressDialog(wxWindow* parent, const string& strInitSelected); + + // Custom + wxString GetAddress(); +}; + + + +class CAddressBookDialog : public CAddressBookDialogBase +{ +protected: + // Event handlers + void OnListEndLabelEdit(wxListEvent& event); + void OnListItemSelected(wxListEvent& event); + void OnListItemActivated(wxListEvent& event); + void OnButtonEdit(wxCommandEvent& event); + void OnButtonDelete(wxCommandEvent& event); + void OnButtonNew(wxCommandEvent& event); + void OnButtonCopy(wxCommandEvent& event); + void OnButtonOK(wxCommandEvent& event); + void OnButtonCancel(wxCommandEvent& event); + void OnClose(wxCloseEvent& event); + +public: + /** Constructor */ + CAddressBookDialog(wxWindow* parent, const wxString& strInitSelected, bool fSendingIn); + + // Custom + bool fSending; + wxString GetAddress(); + bool CheckIfMine(const string& strAddress, const string& strTitle); +}; + + + +class CProductsDialog : public CProductsDialogBase +{ +protected: + // Event handlers + void OnKeyDown(wxKeyEvent& event) { HandleCtrlA(event); } + void OnCombobox(wxCommandEvent& event); + void OnButtonSearch(wxCommandEvent& event); + void OnListItemActivated(wxListEvent& event); + +public: + /** Constructor */ + CProductsDialog(wxWindow* parent); + + // Custom + vector m_vProduct; +}; + + + +class CEditProductDialog : public CEditProductDialogBase +{ +protected: + // Event handlers + void OnKeyDown(wxKeyEvent& event) { HandleCtrlA(event); } + void OnButtonDel0(wxCommandEvent& event); + void OnButtonDel1(wxCommandEvent& event); + void OnButtonDel2(wxCommandEvent& event); + void OnButtonDel3(wxCommandEvent& event); + void OnButtonDel4(wxCommandEvent& event); + void OnButtonDel5(wxCommandEvent& event); + void OnButtonDel6(wxCommandEvent& event); + void OnButtonDel7(wxCommandEvent& event); + void OnButtonDel8(wxCommandEvent& event); + void OnButtonDel9(wxCommandEvent& event); + void OnButtonDel10(wxCommandEvent& event); + void OnButtonDel11(wxCommandEvent& event); + void OnButtonDel12(wxCommandEvent& event); + void OnButtonDel13(wxCommandEvent& event); + void OnButtonDel14(wxCommandEvent& event); + void OnButtonDel15(wxCommandEvent& event); + void OnButtonDel16(wxCommandEvent& event); + void OnButtonDel17(wxCommandEvent& event); + void OnButtonDel18(wxCommandEvent& event); + void OnButtonDel19(wxCommandEvent& event); + void OnButtonAddField(wxCommandEvent& event); + void OnButtonSend(wxCommandEvent& event); + void OnButtonPreview(wxCommandEvent& event); + void OnButtonCancel(wxCommandEvent& event); + +public: + /** Constructor */ + CEditProductDialog(wxWindow* parent); + + // Custom + enum { FIELDS_MAX = 20 }; + wxTextCtrl* m_textCtrlLabel[FIELDS_MAX]; + wxTextCtrl* m_textCtrlField[FIELDS_MAX]; + wxButton* m_buttonDel[FIELDS_MAX]; + + void LayoutAll(); + void ShowLine(int i, bool fShow=true); + void OnButtonDel(wxCommandEvent& event, int n); + void SetProduct(const CProduct& productIn); + void GetProduct(CProduct& product); + +}; + + + +class CViewProductDialog : public CViewProductDialogBase +{ +protected: + // Event handlers + void OnButtonSubmitForm(wxCommandEvent& event); + void OnButtonCancelForm(wxCommandEvent& event); + void OnButtonBack(wxCommandEvent& event); + void OnButtonNext(wxCommandEvent& event); + void OnButtonCancel(wxCommandEvent& event); + +public: + /** Constructor */ + CViewProductDialog(wxWindow* parent, const CProduct& productIn); + ~CViewProductDialog(); + + // Custom + CProduct product; + enum { FIELDS_MAX = 20 }; + wxStaticText* m_staticTextLabel[FIELDS_MAX]; + wxTextCtrl* m_textCtrlField[FIELDS_MAX]; + wxChoice* m_choiceField[FIELDS_MAX]; + + void GetOrder(CWalletTx& order); + void UpdateProductDisplay(bool fDetails); + void OnReply1(wxCommandEvent& event); +}; + + + +class CViewOrderDialog : public CViewOrderDialogBase +{ +protected: + // Event handlers + void OnButtonOK(wxCommandEvent& event); + +public: + /** Constructor */ + CViewOrderDialog(wxWindow* parent, CWalletTx order, bool fReceived); + + // Custom + bool fReceived; +}; + + + +class CEditReviewDialog : public CEditReviewDialogBase +{ +protected: + // Event handlers + void OnKeyDown(wxKeyEvent& event) { HandleCtrlA(event); } + void OnButtonSubmit(wxCommandEvent& event); + void OnButtonCancel(wxCommandEvent& event); + +public: + /** Constructor */ + CEditReviewDialog(wxWindow* parent); + + // Custom + void GetReview(CReview& review); +}; + + + +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 string& strCaption, + const string& strMessage1, + const string& strValue1="", + const string& strMessage2="", + const string& strValue2="") : CGetTextFromUserDialogBase(parent, wxID_ANY, strCaption) + { + m_staticTextMessage1->SetLabel(strMessage1); + m_textCtrl1->SetValue(strValue1); + if (!strMessage2.empty()) + { + m_staticTextMessage2->Show(true); + m_staticTextMessage2->SetLabel(strMessage2); + m_textCtrl2->Show(true); + m_textCtrl2->SetValue(strValue2); + SetSize(wxDefaultCoord, 180); + } + } + + // Custom + string GetValue() { return (string)m_textCtrl1->GetValue(); } + string GetValue1() { return (string)m_textCtrl1->GetValue(); } + string GetValue2() { return (string)m_textCtrl2->GetValue(); } +}; + + + + + diff --git a/ui.rc b/ui.rc new file mode 100644 index 0000000000..95258c7d59 --- /dev/null +++ b/ui.rc @@ -0,0 +1,14 @@ +bitcoin ICON "rc/bitcoin.ico" + +#include "wx/msw/wx.rc" + +check ICON "rc/check.ico" +send16 BITMAP "rc/send16.bmp" +send16mask BITMAP "rc/send16mask.bmp" +send16masknoshadow BITMAP "rc/send16masknoshadow.bmp" +send20 BITMAP "rc/send20.bmp" +send20mask BITMAP "rc/send20mask.bmp" +addressbook16 BITMAP "rc/addressbook16.bmp" +addressbook16mask BITMAP "rc/addressbook16mask.bmp" +addressbook20 BITMAP "rc/addressbook20.bmp" +addressbook20mask BITMAP "rc/addressbook20mask.bmp" diff --git a/uibase.cpp b/uibase.cpp new file mode 100644 index 0000000000..2972e9af3b --- /dev/null +++ b/uibase.cpp @@ -0,0 +1,1825 @@ +// Copyright (c) 2009 Satoshi Nakamoto +// Distributed under the MIT/X11 software license, see the accompanying +// file license.txt or http://www.opensource.org/licenses/mit-license.php. + +/////////////////////////////////////////////////////////////////////////// +// C++ code generated with wxFormBuilder (version Apr 16 2008) +// http://www.wxformbuilder.org/ +// +// PLEASE DO "NOT" EDIT THIS FILE! +/////////////////////////////////////////////////////////////////////////// + +#include "uibase.h" + +/////////////////////////////////////////////////////////////////////////// + +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_menubar->SetBackgroundColour(wxColour(240, 240, 240)); + + m_menuFile = new wxMenu(); + wxMenuItem* m_menuFileExit; + m_menuFileExit = new wxMenuItem(m_menuFile, wxID_ANY, wxString(wxT("E&xit")) , wxEmptyString, wxITEM_NORMAL); + m_menuFile->Append(m_menuFileExit); + + m_menubar->Append(m_menuFile, wxT("&File")); + + m_menuOptions = new wxMenu(); + wxMenuItem* m_menuOptionsGenerateBitcoins; + m_menuOptionsGenerateBitcoins = new wxMenuItem(m_menuOptions, wxID_OPTIONSGENERATEBITCOINS, wxString(wxT("&Generate Coins")) , wxEmptyString, wxITEM_CHECK); + m_menuOptions->Append(m_menuOptionsGenerateBitcoins); + + wxMenuItem* m_menuChangeYourAddress; + m_menuChangeYourAddress = new wxMenuItem(m_menuOptions, wxID_ANY, wxString(wxT("&Change Your Address...")) , wxEmptyString, wxITEM_NORMAL); + m_menuOptions->Append(m_menuChangeYourAddress); + + wxMenuItem* m_menuOptionsOptions; + m_menuOptionsOptions = new wxMenuItem(m_menuOptions, wxID_ANY, wxString(wxT("&Options...")) , wxEmptyString, wxITEM_NORMAL); + m_menuOptions->Append(m_menuOptionsOptions); + + m_menubar->Append(m_menuOptions, wxT("&Options")); + + m_menuHelp = new wxMenu(); + wxMenuItem* m_menuHelpAbout; + m_menuHelpAbout = new wxMenuItem(m_menuHelp, wxID_ANY, wxString(wxT("&About...")) , wxEmptyString, wxITEM_NORMAL); + m_menuHelp->Append(m_menuHelpAbout); + + m_menubar->Append(m_menuHelp, wxT("&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, wxT("&Send Coins"), wxBitmap(wxT("send20"), wxBITMAP_TYPE_RESOURCE), wxNullBitmap, wxITEM_NORMAL, wxEmptyString, wxEmptyString); + m_toolBar->AddTool(wxID_BUTTONRECEIVE, wxT("&Address Book"), wxBitmap(wxT("addressbook20"), wxBITMAP_TYPE_RESOURCE), wxNullBitmap, wxITEM_NORMAL, wxEmptyString, wxEmptyString); + m_toolBar->Realize(); + + m_statusBar = this->CreateStatusBar(1, wxST_SIZEGRIP, wxID_ANY); + m_statusBar->SetBackgroundColour(wxColour(240, 240, 240)); + + 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, wxT("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(250,-1), wxTE_READONLY); + m_textCtrlAddress->SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_MENU)); + + bSizer85->Add(m_textCtrlAddress, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5); + + m_buttonCopy = new wxButton(this, wxID_BUTTONCOPY, wxT("&Copy to Clipboard"), wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT); + bSizer85->Add(m_buttonCopy, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 5); + + m_button91 = new wxButton(this, wxID_BUTTONCHANGE, wxT("C&hange..."), wxDefaultPosition, wxDefaultSize, 0); + m_button91->Hide(); + + bSizer85->Add(m_button91, 0, wxRIGHT, 5); + + + bSizer85->Add(0, 0, 0, wxEXPAND, 5); + + bSizer2->Add(bSizer85, 0, wxEXPAND|wxRIGHT|wxLEFT, 5); + + wxBoxSizer* bSizer3; + bSizer3 = new wxBoxSizer(wxHORIZONTAL); + + m_panel14 = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL); + wxBoxSizer* bSizer66; + bSizer66 = new wxBoxSizer(wxHORIZONTAL); + + m_staticText41 = new wxStaticText(m_panel14, wxID_ANY, wxT("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(m_panel14, 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(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW)); + + bSizer66->Add(m_staticTextBalance, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5); + + m_panel14->SetSizer(bSizer66); + m_panel14->Layout(); + bSizer66->Fit(m_panel14); + bSizer3->Add(m_panel14, 1, wxEXPAND|wxALIGN_BOTTOM|wxALL, 5); + + + bSizer3->Add(0, 0, 0, wxEXPAND, 5); + + wxString m_choiceFilterChoices[] = { wxT(" All"), wxT(" Sent"), wxT(" Received"), wxT(" 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_panel7 = new wxPanel(m_notebook, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL); + wxBoxSizer* bSizer157; + bSizer157 = new wxBoxSizer(wxVERTICAL); + + m_listCtrl = new wxListCtrl(m_panel7, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_NO_SORT_HEADER|wxLC_REPORT|wxLC_SORT_DESCENDING|wxALWAYS_SHOW_SB); + bSizer157->Add(m_listCtrl, 1, wxEXPAND|wxALL, 5); + + m_panel7->SetSizer(bSizer157); + m_panel7->Layout(); + bSizer157->Fit(m_panel7); + m_notebook->AddPage(m_panel7, wxT("All Transactions"), false); + + bSizer2->Add(m_notebook, 1, wxEXPAND, 5); + + wxBoxSizer* bSizer_TabsForFutureUse; + bSizer_TabsForFutureUse = new wxBoxSizer(wxVERTICAL); + + m_panel9 = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL); + m_panel9->Hide(); + + wxBoxSizer* bSizer159; + bSizer159 = new wxBoxSizer(wxVERTICAL); + + m_listCtrlEscrows = new wxListCtrl(m_panel9, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_NO_SORT_HEADER|wxLC_REPORT); + bSizer159->Add(m_listCtrlEscrows, 1, wxALL|wxEXPAND, 5); + + m_panel9->SetSizer(bSizer159); + m_panel9->Layout(); + bSizer159->Fit(m_panel9); + bSizer_TabsForFutureUse->Add(m_panel9, 1, wxEXPAND | wxALL, 5); + + m_panel8 = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL); + m_panel8->Hide(); + + wxBoxSizer* bSizer158; + bSizer158 = new wxBoxSizer(wxVERTICAL); + + m_listCtrlOrdersSent = new wxListCtrl(m_panel8, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_NO_SORT_HEADER|wxLC_REPORT); + bSizer158->Add(m_listCtrlOrdersSent, 1, wxALL|wxEXPAND, 5); + + m_panel8->SetSizer(bSizer158); + m_panel8->Layout(); + bSizer158->Fit(m_panel8); + bSizer_TabsForFutureUse->Add(m_panel8, 1, wxEXPAND | wxALL, 5); + + m_panel10 = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL); + m_panel10->Hide(); + + wxBoxSizer* bSizer160; + bSizer160 = new wxBoxSizer(wxVERTICAL); + + m_listCtrlProductsSent = new wxListCtrl(m_panel10, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_NO_SORT_HEADER|wxLC_REPORT); + bSizer160->Add(m_listCtrlProductsSent, 1, wxALL|wxEXPAND, 5); + + m_panel10->SetSizer(bSizer160); + m_panel10->Layout(); + bSizer160->Fit(m_panel10); + bSizer_TabsForFutureUse->Add(m_panel10, 1, wxEXPAND | wxALL, 5); + + m_panel11 = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL); + m_panel11->Hide(); + + wxBoxSizer* bSizer161; + bSizer161 = new wxBoxSizer(wxVERTICAL); + + m_listCtrlOrdersReceived = new wxListCtrl(m_panel11, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_NO_SORT_HEADER|wxLC_REPORT); + bSizer161->Add(m_listCtrlOrdersReceived, 1, wxALL|wxEXPAND, 5); + + m_panel11->SetSizer(bSizer161); + m_panel11->Layout(); + bSizer161->Fit(m_panel11); + bSizer_TabsForFutureUse->Add(m_panel11, 1, wxEXPAND | wxALL, 5); + + bSizer2->Add(bSizer_TabsForFutureUse, 1, wxEXPAND, 5); + + this->SetSizer(bSizer2); + this->Layout(); + + // Connect Events + this->Connect(wxEVT_CLOSE_WINDOW, wxCloseEventHandler(CMainFrameBase::OnClose)); + 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_menuOptionsGenerateBitcoins->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(CMainFrameBase::OnMenuOptionsGenerate)); + this->Connect(m_menuChangeYourAddress->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_buttonCopy->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CMainFrameBase::OnButtonCopy), NULL, this); + m_button91->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CMainFrameBase::OnButtonChange), NULL, this); + m_listCtrl->Connect(wxEVT_COMMAND_LIST_COL_BEGIN_DRAG, wxListEventHandler(CMainFrameBase::OnListColBeginDrag), NULL, this); + m_listCtrl->Connect(wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler(CMainFrameBase::OnListItemActivatedAllTransactions), NULL, this); + m_listCtrl->Connect(wxEVT_PAINT, wxPaintEventHandler(CMainFrameBase::OnPaintListCtrl), NULL, this); + m_listCtrlOrdersSent->Connect(wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler(CMainFrameBase::OnListItemActivatedOrdersSent), NULL, this); + m_listCtrlProductsSent->Connect(wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler(CMainFrameBase::OnListItemActivatedProductsSent), NULL, this); + m_listCtrlOrdersReceived->Connect(wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler(CMainFrameBase::OnListItemActivatedOrdersReceived), NULL, this); +} + +CMainFrameBase::~CMainFrameBase() +{ + // Disconnect Events + this->Disconnect(wxEVT_CLOSE_WINDOW, wxCloseEventHandler(CMainFrameBase::OnClose)); + 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::OnMenuOptionsGenerate)); + 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_buttonCopy->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CMainFrameBase::OnButtonCopy), NULL, this); + m_button91->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CMainFrameBase::OnButtonChange), NULL, this); + m_listCtrl->Disconnect(wxEVT_COMMAND_LIST_COL_BEGIN_DRAG, wxListEventHandler(CMainFrameBase::OnListColBeginDrag), NULL, this); + m_listCtrl->Disconnect(wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler(CMainFrameBase::OnListItemActivatedAllTransactions), NULL, this); + m_listCtrl->Disconnect(wxEVT_PAINT, wxPaintEventHandler(CMainFrameBase::OnPaintListCtrl), NULL, this); + m_listCtrlOrdersSent->Disconnect(wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler(CMainFrameBase::OnListItemActivatedOrdersSent), NULL, this); + m_listCtrlProductsSent->Disconnect(wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler(CMainFrameBase::OnListItemActivatedProductsSent), NULL, this); + m_listCtrlOrdersReceived->Disconnect(wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler(CMainFrameBase::OnListItemActivatedOrdersReceived), 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(wxVERTICAL); + + m_buttonOK = new wxButton(this, wxID_OK, wxT("OK"), wxDefaultPosition, wxSize(85,25), 0); + bSizer65->Add(m_buttonOK, 0, wxALL, 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* bSizer57; + bSizer57 = new wxBoxSizer(wxVERTICAL); + + + bSizer57->Add(0, 20, 0, wxEXPAND, 5); + + m_staticText32 = new wxStaticText(this, wxID_ANY, wxT("Optional transaction fee you give to the nodes that process your transactions."), wxDefaultPosition, wxDefaultSize, 0); + m_staticText32->Wrap(-1); + bSizer57->Add(m_staticText32, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5); + + wxBoxSizer* bSizer56; + bSizer56 = new wxBoxSizer(wxHORIZONTAL); + + m_staticText31 = new wxStaticText(this, wxID_ANY, wxT("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(this, wxID_TRANSACTIONFEE, wxEmptyString, wxDefaultPosition, wxSize(70,-1), 0); + bSizer56->Add(m_textCtrlTransactionFee, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5); + + bSizer57->Add(bSizer56, 0, wxEXPAND, 5); + + bSizer55->Add(bSizer57, 1, wxEXPAND|wxLEFT, 5); + + wxBoxSizer* bSizer58; + bSizer58 = new wxBoxSizer(wxHORIZONTAL); + + m_buttonOK = new wxButton(this, wxID_OK, wxT("OK"), wxDefaultPosition, wxSize(85,25), 0); + bSizer58->Add(m_buttonOK, 0, wxALL, 5); + + m_buttonCancel = new wxButton(this, wxID_CANCEL, wxT("Cancel"), wxDefaultPosition, wxSize(-1,-1), 0); + m_buttonCancel->SetMinSize(wxSize(85,25)); + + bSizer58->Add(m_buttonCancel, 0, wxALL, 5); + + bSizer55->Add(bSizer58, 0, wxALIGN_RIGHT, 5); + + this->SetSizer(bSizer55); + this->Layout(); + + // Connect Events + 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); +} + +COptionsDialogBase::~COptionsDialogBase() +{ + // Disconnect Events + 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); +} + +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* bSizer60; + bSizer60 = new wxBoxSizer(wxVERTICAL); + + wxBoxSizer* bSizer62; + bSizer62 = new wxBoxSizer(wxHORIZONTAL); + + + bSizer62->Add(60, 0, 0, wxEXPAND, 5); + + wxBoxSizer* bSizer63; + bSizer63 = new wxBoxSizer(wxVERTICAL); + + + bSizer63->Add(0, 50, 0, wxEXPAND, 5); + + wxBoxSizer* bSizer64; + bSizer64 = new wxBoxSizer(wxHORIZONTAL); + + m_staticText40 = new wxStaticText(this, wxID_ANY, wxT("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, wxT("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); + + bSizer63->Add(bSizer64, 0, wxEXPAND, 5); + + + bSizer63->Add(0, 4, 0, wxEXPAND, 5); + + m_staticTextMain = new wxStaticText(this, wxID_ANY, wxT("Copyright © 2009 Satoshi Nakamoto.\n\nThis is experimental software. Do not rely on it for actual financial transactions.\n\nDistributed under the MIT/X11 software license, see the accompanying file license.txt or http://www.opensource.org/licenses/mit-license.php.\n\nThis 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)."), wxDefaultPosition, wxDefaultSize, 0); + m_staticTextMain->Wrap(400); + bSizer63->Add(m_staticTextMain, 0, wxALL, 5); + + + bSizer63->Add(0, 0, 1, wxEXPAND, 5); + + bSizer62->Add(bSizer63, 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, wxT("OK"), wxDefaultPosition, wxSize(85,25), 0); + bSizer61->Add(m_buttonOK, 0, wxALL, 5); + + bSizer60->Add(bSizer61, 0, wxALIGN_RIGHT|wxEXPAND, 5); + + this->SetSizer(bSizer60); + 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(3, 2, 0, 0); + fgSizer1->AddGrowableCol(1); + fgSizer1->SetFlexibleDirection(wxBOTH); + fgSizer1->SetNonFlexibleGrowMode(wxFLEX_GROWMODE_SPECIFIED); + + + fgSizer1->Add(0, 0, 0, wxEXPAND, 5); + + m_staticText14 = new wxStaticText(this, wxID_ANY, wxT("Enter the recipient's IP address (e.g. 123.45.6.7) for online transfer with comments and confirmation, \nor Bitcoin address (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJED9L) if recipient is not online."), wxDefaultPosition, wxDefaultSize, 0); + m_staticText14->Wrap(-1); + fgSizer1->Add(m_staticText14, 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, wxICON(check), wxDefaultPosition, wxSize(16,16), 0); + bSizer47->Add(m_bitmapCheckMark, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5); + + m_staticText36 = new wxStaticText(this, wxID_ANY, wxT("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); + + m_buttonPaste = new wxButton(this, wxID_BUTTONPASTE, wxT("&Paste"), wxDefaultPosition, wxSize(-1,-1), wxBU_EXACTFIT); + bSizer19->Add(m_buttonPaste, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 5); + + m_buttonAddress = new wxButton(this, wxID_BUTTONADDRESSBOOK, wxT(" Address &Book..."), wxDefaultPosition, wxDefaultSize, 0); + bSizer19->Add(m_buttonAddress, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 5); + + fgSizer1->Add(bSizer19, 1, wxEXPAND|wxRIGHT, 5); + + m_staticText19 = new wxStaticText(this, wxID_ANY, wxT("&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, wxT("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[] = { wxT(" 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); + + wxBoxSizer* bSizer681; + bSizer681 = new wxBoxSizer(wxVERTICAL); + + m_staticTextFrom = new wxStaticText(this, wxID_ANY, wxT("&From:"), wxDefaultPosition, wxDefaultSize, 0); + m_staticTextFrom->Wrap(-1); + bSizer681->Add(m_staticTextFrom, 0, wxBOTTOM|wxLEFT, 5); + + m_textCtrlFrom = new wxTextCtrl(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(-1,-1), 0); + bSizer681->Add(m_textCtrlFrom, 0, wxLEFT|wxEXPAND, 5); + + bSizer672->Add(bSizer681, 1, wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT, 5); + + bSizer21->Add(bSizer672, 0, wxEXPAND, 5); + + wxBoxSizer* bSizer67; + bSizer67 = new wxBoxSizer(wxHORIZONTAL); + + wxBoxSizer* bSizer68; + bSizer68 = new wxBoxSizer(wxVERTICAL); + + m_staticTextMessage = new wxStaticText(this, wxID_ANY, wxT("&Message:"), wxDefaultPosition, wxDefaultSize, 0); + m_staticTextMessage->Wrap(-1); + bSizer68->Add(m_staticTextMessage, 0, wxTOP|wxBOTTOM|wxLEFT, 5); + + m_textCtrlMessage = new wxTextCtrl(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE); + bSizer68->Add(m_textCtrlMessage, 1, wxEXPAND|wxLEFT, 5); + + bSizer67->Add(bSizer68, 1, wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT, 5); + + bSizer21->Add(bSizer67, 1, wxEXPAND, 5); + + wxBoxSizer* bSizer23; + bSizer23 = new wxBoxSizer(wxHORIZONTAL); + + + bSizer23->Add(0, 0, 1, wxEXPAND, 5); + + m_buttonSend = new wxButton(this, wxID_BUTTONSEND, wxT("&Send"), wxDefaultPosition, wxSize(-1,-1), 0); + m_buttonSend->SetFont(wxFont(wxNORMAL_FONT->GetPointSize(), 70, 90, 90, false, wxEmptyString)); + m_buttonSend->SetMinSize(wxSize(85,25)); + + bSizer23->Add(m_buttonSend, 0, wxALL, 5); + + m_buttonCancel = new wxButton(this, wxID_CANCEL, wxT("Cancel"), wxDefaultPosition, wxSize(-1,-1), 0); + m_buttonCancel->SetMinSize(wxSize(85,25)); + + bSizer23->Add(m_buttonCancel, 0, wxALL, 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_textCtrlFrom->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CSendDialogBase::OnKeyDown), NULL, this); + m_textCtrlMessage->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CSendDialogBase::OnKeyDown), 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_textCtrlFrom->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CSendDialogBase::OnKeyDown), NULL, this); + m_textCtrlMessage->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CSendDialogBase::OnKeyDown), 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, wxT("\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, wxT("OK"), wxDefaultPosition, wxDefaultSize, 0); + m_buttonOK->Enable(false); + m_buttonOK->SetMinSize(wxSize(85,25)); + + bSizer69->Add(m_buttonOK, 0, wxALL, 5); + + m_buttonCancel = new wxButton(this, wxID_CANCEL, wxT("Cancel"), wxDefaultPosition, wxSize(-1,-1), 0); + m_buttonCancel->SetMinSize(wxSize(85,25)); + + bSizer69->Add(m_buttonCancel, 0, wxALL, 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, wxT("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, wxT("&Edit..."), wxDefaultPosition, wxDefaultSize, 0); + m_buttonRename->SetMinSize(wxSize(85,25)); + + bSizer69->Add(m_buttonRename, 0, wxALL, 5); + + m_buttonNew = new wxButton(this, wxID_BUTTONNEW, wxT("&New Address..."), wxDefaultPosition, wxSize(-1,-1), 0); + m_buttonNew->SetMinSize(wxSize(110,25)); + + bSizer69->Add(m_buttonNew, 0, wxALL, 5); + + m_buttonCopy = new wxButton(this, wxID_BUTTONCOPY, wxT("&Copy to Clipboard"), wxDefaultPosition, wxSize(-1,-1), 0); + m_buttonCopy->SetMinSize(wxSize(120,25)); + + bSizer69->Add(m_buttonCopy, 0, wxALL, 5); + + m_buttonOK = new wxButton(this, wxID_OK, wxT("OK"), wxDefaultPosition, wxDefaultSize, 0); + m_buttonOK->SetMinSize(wxSize(85,25)); + + bSizer69->Add(m_buttonOK, 0, wxALL, 5); + + m_buttonCancel = new wxButton(this, wxID_CANCEL, wxT("Cancel"), wxDefaultPosition, wxSize(-1,-1), 0); + m_buttonCancel->Hide(); + m_buttonCancel->SetMinSize(wxSize(85,25)); + + bSizer69->Add(m_buttonCancel, 0, wxALL, 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* bSizer68; + bSizer68 = new wxBoxSizer(wxVERTICAL); + + + bSizer68->Add(0, 5, 0, wxEXPAND, 5); + + m_staticText55 = new wxStaticText(this, wxID_ANY, wxT("Bitcoin Address"), wxDefaultPosition, wxDefaultSize, 0); + m_staticText55->Wrap(-1); + m_staticText55->Hide(); + + bSizer68->Add(m_staticText55, 0, wxTOP|wxRIGHT|wxLEFT, 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_buttonEdit = new wxButton(this, wxID_BUTTONEDIT, wxT("&Edit..."), wxDefaultPosition, wxDefaultSize, 0); + m_buttonEdit->SetMinSize(wxSize(85,25)); + + bSizer69->Add(m_buttonEdit, 0, wxALL, 5); + + m_buttonNew = new wxButton(this, wxID_BUTTONNEW, wxT("&New Address..."), wxDefaultPosition, wxDefaultSize, 0); + m_buttonNew->SetMinSize(wxSize(110,25)); + + bSizer69->Add(m_buttonNew, 0, wxALL, 5); + + m_buttonDelete = new wxButton(this, wxID_BUTTONDELETE, wxT("&Delete"), wxDefaultPosition, wxDefaultSize, 0); + m_buttonDelete->SetMinSize(wxSize(85,25)); + + bSizer69->Add(m_buttonDelete, 0, wxALL, 5); + + m_buttonOK = new wxButton(this, wxID_OK, wxT("OK"), wxDefaultPosition, wxSize(-1,-1), 0); + m_buttonOK->SetMinSize(wxSize(85,25)); + + bSizer69->Add(m_buttonOK, 0, wxALL, 5); + + m_buttonCancel = new wxButton(this, wxID_CANCEL, wxT("Cancel"), wxDefaultPosition, wxSize(-1,-1), 0); + m_buttonCancel->SetMinSize(wxSize(85,25)); + + bSizer69->Add(m_buttonCancel, 0, wxALL, 5); + + bSizer68->Add(bSizer69, 0, wxEXPAND, 5); + + this->SetSizer(bSizer68); + this->Layout(); + + // Connect Events + this->Connect(wxEVT_CLOSE_WINDOW, wxCloseEventHandler(CAddressBookDialogBase::OnClose)); + m_listCtrl->Connect(wxEVT_COMMAND_LIST_END_LABEL_EDIT, wxListEventHandler(CAddressBookDialogBase::OnListEndLabelEdit), NULL, this); + m_listCtrl->Connect(wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler(CAddressBookDialogBase::OnListItemActivated), NULL, this); + m_listCtrl->Connect(wxEVT_COMMAND_LIST_ITEM_SELECTED, wxListEventHandler(CAddressBookDialogBase::OnListItemSelected), 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_buttonDelete->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CAddressBookDialogBase::OnButtonDelete), 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_listCtrl->Disconnect(wxEVT_COMMAND_LIST_END_LABEL_EDIT, wxListEventHandler(CAddressBookDialogBase::OnListEndLabelEdit), NULL, this); + m_listCtrl->Disconnect(wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler(CAddressBookDialogBase::OnListItemActivated), NULL, this); + m_listCtrl->Disconnect(wxEVT_COMMAND_LIST_ITEM_SELECTED, wxListEventHandler(CAddressBookDialogBase::OnListItemSelected), 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_buttonDelete->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CAddressBookDialogBase::OnButtonDelete), 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); +} + +CProductsDialogBase::CProductsDialogBase(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* bSizer22; + bSizer22 = new wxBoxSizer(wxVERTICAL); + + wxBoxSizer* bSizer23; + bSizer23 = new wxBoxSizer(wxHORIZONTAL); + + m_comboBoxCategory = new wxComboBox(this, wxID_ANY, wxT("(Any Category)"), wxDefaultPosition, wxSize(150,-1), 0, NULL, 0); + m_comboBoxCategory->Append(wxT("(Any Category)")); + bSizer23->Add(m_comboBoxCategory, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5); + + m_textCtrlSearch = new wxTextCtrl(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0); + bSizer23->Add(m_textCtrlSearch, 1, wxALL|wxALIGN_CENTER_VERTICAL, 5); + + m_buttonSearch = new wxButton(this, wxID_ANY, wxT("&Search"), wxDefaultPosition, wxDefaultSize, 0); + bSizer23->Add(m_buttonSearch, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5); + + bSizer22->Add(bSizer23, 0, wxEXPAND|wxTOP|wxBOTTOM|wxRIGHT, 5); + + m_listCtrl = new wxListCtrl(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_NO_SORT_HEADER|wxLC_REPORT); + bSizer22->Add(m_listCtrl, 1, wxALL|wxEXPAND, 5); + + this->SetSizer(bSizer22); + this->Layout(); + + // Connect Events + m_comboBoxCategory->Connect(wxEVT_COMMAND_COMBOBOX_SELECTED, wxCommandEventHandler(CProductsDialogBase::OnCombobox), NULL, this); + m_textCtrlSearch->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CProductsDialogBase::OnKeyDown), NULL, this); + m_buttonSearch->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CProductsDialogBase::OnButtonSearch), NULL, this); + m_listCtrl->Connect(wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler(CProductsDialogBase::OnListItemActivated), NULL, this); +} + +CProductsDialogBase::~CProductsDialogBase() +{ + // Disconnect Events + m_comboBoxCategory->Disconnect(wxEVT_COMMAND_COMBOBOX_SELECTED, wxCommandEventHandler(CProductsDialogBase::OnCombobox), NULL, this); + m_textCtrlSearch->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CProductsDialogBase::OnKeyDown), NULL, this); + m_buttonSearch->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CProductsDialogBase::OnButtonSearch), NULL, this); + m_listCtrl->Disconnect(wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler(CProductsDialogBase::OnListItemActivated), NULL, this); +} + +CEditProductDialogBase::CEditProductDialogBase(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_MENU)); + + wxBoxSizer* bSizer20; + bSizer20 = new wxBoxSizer(wxVERTICAL); + + m_scrolledWindow = new wxScrolledWindow(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxHSCROLL|wxTAB_TRAVERSAL|wxVSCROLL); + m_scrolledWindow->SetScrollRate(5, 5); + m_scrolledWindow->SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW)); + + wxBoxSizer* bSizer21; + bSizer21 = new wxBoxSizer(wxVERTICAL); + + wxFlexGridSizer* fgSizer8; + fgSizer8 = new wxFlexGridSizer(0, 2, 0, 0); + fgSizer8->AddGrowableCol(1); + fgSizer8->SetFlexibleDirection(wxBOTH); + fgSizer8->SetNonFlexibleGrowMode(wxFLEX_GROWMODE_SPECIFIED); + + m_staticText106 = new wxStaticText(m_scrolledWindow, wxID_ANY, wxT("Category"), wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT); + m_staticText106->Wrap(-1); + fgSizer8->Add(m_staticText106, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxTOP|wxBOTTOM|wxLEFT, 5); + + m_comboBoxCategory = new wxComboBox(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0, NULL, 0); + m_comboBoxCategory->SetMinSize(wxSize(180,-1)); + + fgSizer8->Add(m_comboBoxCategory, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5); + + m_staticText108 = new wxStaticText(m_scrolledWindow, wxID_ANY, wxT("Title"), wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT); + m_staticText108->Wrap(-1); + fgSizer8->Add(m_staticText108, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxTOP|wxBOTTOM|wxLEFT, 5); + + m_textCtrlTitle = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0); + fgSizer8->Add(m_textCtrlTitle, 1, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5); + + m_staticText107 = new wxStaticText(m_scrolledWindow, wxID_ANY, wxT("Price"), wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT); + m_staticText107->Wrap(-1); + fgSizer8->Add(m_staticText107, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxTOP|wxBOTTOM|wxLEFT, 5); + + m_textCtrlPrice = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0); + m_textCtrlPrice->SetMinSize(wxSize(105,-1)); + + fgSizer8->Add(m_textCtrlPrice, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5); + + bSizer21->Add(fgSizer8, 0, wxEXPAND|wxTOP|wxRIGHT|wxLEFT, 5); + + m_staticText22 = new wxStaticText(m_scrolledWindow, wxID_ANY, wxT("Page 1: Description"), wxDefaultPosition, wxDefaultSize, 0); + m_staticText22->Wrap(-1); + bSizer21->Add(m_staticText22, 0, wxTOP|wxRIGHT|wxLEFT, 5); + + m_textCtrlDescription = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE); + m_textCtrlDescription->SetMinSize(wxSize(-1,170)); + + bSizer21->Add(m_textCtrlDescription, 0, wxALL|wxEXPAND, 5); + + m_staticText23 = new wxStaticText(m_scrolledWindow, wxID_ANY, wxT("Page 2: Order Form"), wxDefaultPosition, wxDefaultSize, 0); + m_staticText23->Wrap(-1); + bSizer21->Add(m_staticText23, 0, wxTOP|wxRIGHT|wxLEFT, 5); + + m_textCtrlInstructions = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE); + m_textCtrlInstructions->SetMinSize(wxSize(-1,120)); + + bSizer21->Add(m_textCtrlInstructions, 0, wxEXPAND|wxALL, 5); + + fgSizer5 = new wxFlexGridSizer(0, 3, 0, 0); + fgSizer5->AddGrowableCol(1); + fgSizer5->SetFlexibleDirection(wxBOTH); + fgSizer5->SetNonFlexibleGrowMode(wxFLEX_GROWMODE_SPECIFIED); + + m_staticText24 = new wxStaticText(m_scrolledWindow, wxID_ANY, wxT("Label"), wxDefaultPosition, wxDefaultSize, 0); + m_staticText24->Wrap(-1); + fgSizer5->Add(m_staticText24, 0, wxALIGN_CENTER_VERTICAL|wxTOP|wxRIGHT|wxLEFT, 5); + + m_staticText25 = new wxStaticText(m_scrolledWindow, wxID_ANY, wxT("Comma separated list of choices, or leave blank for text field"), wxDefaultPosition, wxDefaultSize, 0); + m_staticText25->Wrap(-1); + fgSizer5->Add(m_staticText25, 0, wxALIGN_CENTER_VERTICAL|wxTOP|wxRIGHT|wxLEFT, 5); + + + fgSizer5->Add(0, 0, 1, wxEXPAND, 5); + + m_textCtrlLabel0 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0); + m_textCtrlLabel0->SetMinSize(wxSize(150,-1)); + + fgSizer5->Add(m_textCtrlLabel0, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5); + + m_textCtrlField0 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(-1,-1), 0); + fgSizer5->Add(m_textCtrlField0, 0, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5); + + m_buttonDel0 = new wxButton(m_scrolledWindow, wxID_DEL0, wxT("Delete"), wxDefaultPosition, wxSize(60,20), 0); + fgSizer5->Add(m_buttonDel0, 0, wxRIGHT|wxLEFT|wxALIGN_CENTER_VERTICAL, 5); + + m_textCtrlLabel1 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0); + m_textCtrlLabel1->SetMinSize(wxSize(150,-1)); + + fgSizer5->Add(m_textCtrlLabel1, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5); + + m_textCtrlField1 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(-1,-1), 0); + fgSizer5->Add(m_textCtrlField1, 0, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5); + + m_buttonDel1 = new wxButton(m_scrolledWindow, wxID_DEL1, wxT("Delete"), wxDefaultPosition, wxSize(60,20), 0); + fgSizer5->Add(m_buttonDel1, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5); + + m_textCtrlLabel2 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0); + m_textCtrlLabel2->SetMinSize(wxSize(150,-1)); + + fgSizer5->Add(m_textCtrlLabel2, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5); + + m_textCtrlField2 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(-1,-1), 0); + fgSizer5->Add(m_textCtrlField2, 0, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5); + + m_buttonDel2 = new wxButton(m_scrolledWindow, wxID_DEL2, wxT("Delete"), wxDefaultPosition, wxSize(60,20), 0); + fgSizer5->Add(m_buttonDel2, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5); + + m_textCtrlLabel3 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0); + m_textCtrlLabel3->SetMinSize(wxSize(150,-1)); + + fgSizer5->Add(m_textCtrlLabel3, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5); + + m_textCtrlField3 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(-1,-1), 0); + fgSizer5->Add(m_textCtrlField3, 0, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5); + + m_buttonDel3 = new wxButton(m_scrolledWindow, wxID_DEL3, wxT("Delete"), wxDefaultPosition, wxSize(60,20), 0); + fgSizer5->Add(m_buttonDel3, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5); + + m_textCtrlLabel4 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0); + m_textCtrlLabel4->SetMinSize(wxSize(150,-1)); + + fgSizer5->Add(m_textCtrlLabel4, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5); + + m_textCtrlField4 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(-1,-1), 0); + fgSizer5->Add(m_textCtrlField4, 0, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5); + + m_buttonDel4 = new wxButton(m_scrolledWindow, wxID_DEL4, wxT("Delete"), wxDefaultPosition, wxSize(60,20), 0); + fgSizer5->Add(m_buttonDel4, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5); + + m_textCtrlLabel5 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0); + m_textCtrlLabel5->SetMinSize(wxSize(150,-1)); + + fgSizer5->Add(m_textCtrlLabel5, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5); + + m_textCtrlField5 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(-1,-1), 0); + fgSizer5->Add(m_textCtrlField5, 0, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5); + + m_buttonDel5 = new wxButton(m_scrolledWindow, wxID_DEL5, wxT("Delete"), wxDefaultPosition, wxSize(60,20), 0); + fgSizer5->Add(m_buttonDel5, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5); + + m_textCtrlLabel6 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0); + m_textCtrlLabel6->SetMinSize(wxSize(150,-1)); + + fgSizer5->Add(m_textCtrlLabel6, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5); + + m_textCtrlField6 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(-1,-1), 0); + fgSizer5->Add(m_textCtrlField6, 0, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5); + + m_buttonDel6 = new wxButton(m_scrolledWindow, wxID_DEL6, wxT("Delete"), wxDefaultPosition, wxSize(60,20), 0); + fgSizer5->Add(m_buttonDel6, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5); + + m_textCtrlLabel7 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0); + m_textCtrlLabel7->SetMinSize(wxSize(150,-1)); + + fgSizer5->Add(m_textCtrlLabel7, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5); + + m_textCtrlField7 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(-1,-1), 0); + fgSizer5->Add(m_textCtrlField7, 0, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5); + + m_buttonDel7 = new wxButton(m_scrolledWindow, wxID_DEL7, wxT("Delete"), wxDefaultPosition, wxSize(60,20), 0); + fgSizer5->Add(m_buttonDel7, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5); + + m_textCtrlLabel8 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0); + m_textCtrlLabel8->SetMinSize(wxSize(150,-1)); + + fgSizer5->Add(m_textCtrlLabel8, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5); + + m_textCtrlField8 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(-1,-1), 0); + fgSizer5->Add(m_textCtrlField8, 0, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5); + + m_buttonDel8 = new wxButton(m_scrolledWindow, wxID_DEL8, wxT("Delete"), wxDefaultPosition, wxSize(60,20), 0); + fgSizer5->Add(m_buttonDel8, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5); + + m_textCtrlLabel9 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0); + m_textCtrlLabel9->SetMinSize(wxSize(150,-1)); + + fgSizer5->Add(m_textCtrlLabel9, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5); + + m_textCtrlField9 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(-1,-1), 0); + fgSizer5->Add(m_textCtrlField9, 0, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5); + + m_buttonDel9 = new wxButton(m_scrolledWindow, wxID_DEL9, wxT("Delete"), wxDefaultPosition, wxSize(60,20), 0); + fgSizer5->Add(m_buttonDel9, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5); + + m_textCtrlLabel10 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0); + m_textCtrlLabel10->SetMinSize(wxSize(150,-1)); + + fgSizer5->Add(m_textCtrlLabel10, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5); + + m_textCtrlField10 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(-1,-1), 0); + fgSizer5->Add(m_textCtrlField10, 0, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5); + + m_buttonDel10 = new wxButton(m_scrolledWindow, wxID_DEL10, wxT("Delete"), wxDefaultPosition, wxSize(60,20), 0); + fgSizer5->Add(m_buttonDel10, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5); + + m_textCtrlLabel11 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0); + m_textCtrlLabel11->SetMinSize(wxSize(150,-1)); + + fgSizer5->Add(m_textCtrlLabel11, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5); + + m_textCtrlField11 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(-1,-1), 0); + fgSizer5->Add(m_textCtrlField11, 0, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5); + + m_buttonDel11 = new wxButton(m_scrolledWindow, wxID_DEL11, wxT("Delete"), wxDefaultPosition, wxSize(60,20), 0); + fgSizer5->Add(m_buttonDel11, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5); + + m_textCtrlLabel12 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0); + m_textCtrlLabel12->SetMinSize(wxSize(150,-1)); + + fgSizer5->Add(m_textCtrlLabel12, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5); + + m_textCtrlField12 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(-1,-1), 0); + fgSizer5->Add(m_textCtrlField12, 0, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5); + + m_buttonDel12 = new wxButton(m_scrolledWindow, wxID_DEL12, wxT("Delete"), wxDefaultPosition, wxSize(60,20), 0); + fgSizer5->Add(m_buttonDel12, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5); + + m_textCtrlLabel13 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0); + m_textCtrlLabel13->SetMinSize(wxSize(150,-1)); + + fgSizer5->Add(m_textCtrlLabel13, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5); + + m_textCtrlField13 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(-1,-1), 0); + fgSizer5->Add(m_textCtrlField13, 0, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5); + + m_buttonDel13 = new wxButton(m_scrolledWindow, wxID_DEL13, wxT("Delete"), wxDefaultPosition, wxSize(60,20), 0); + fgSizer5->Add(m_buttonDel13, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5); + + m_textCtrlLabel14 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0); + m_textCtrlLabel14->SetMinSize(wxSize(150,-1)); + + fgSizer5->Add(m_textCtrlLabel14, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5); + + m_textCtrlField14 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(-1,-1), 0); + fgSizer5->Add(m_textCtrlField14, 0, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5); + + m_buttonDel14 = new wxButton(m_scrolledWindow, wxID_DEL14, wxT("Delete"), wxDefaultPosition, wxSize(60,20), 0); + fgSizer5->Add(m_buttonDel14, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5); + + m_textCtrlLabel15 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0); + m_textCtrlLabel15->SetMinSize(wxSize(150,-1)); + + fgSizer5->Add(m_textCtrlLabel15, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5); + + m_textCtrlField15 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(-1,-1), 0); + fgSizer5->Add(m_textCtrlField15, 0, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5); + + m_buttonDel15 = new wxButton(m_scrolledWindow, wxID_DEL15, wxT("Delete"), wxDefaultPosition, wxSize(60,20), 0); + fgSizer5->Add(m_buttonDel15, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5); + + m_textCtrlLabel16 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0); + m_textCtrlLabel16->SetMinSize(wxSize(150,-1)); + + fgSizer5->Add(m_textCtrlLabel16, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5); + + m_textCtrlField16 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(-1,-1), 0); + fgSizer5->Add(m_textCtrlField16, 0, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5); + + m_buttonDel16 = new wxButton(m_scrolledWindow, wxID_DEL16, wxT("Delete"), wxDefaultPosition, wxSize(60,20), 0); + fgSizer5->Add(m_buttonDel16, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5); + + m_textCtrlLabel17 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0); + m_textCtrlLabel17->SetMinSize(wxSize(150,-1)); + + fgSizer5->Add(m_textCtrlLabel17, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5); + + m_textCtrlField17 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(-1,-1), 0); + fgSizer5->Add(m_textCtrlField17, 0, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5); + + m_buttonDel17 = new wxButton(m_scrolledWindow, wxID_DEL17, wxT("Delete"), wxDefaultPosition, wxSize(60,20), 0); + fgSizer5->Add(m_buttonDel17, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5); + + m_textCtrlLabel18 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0); + m_textCtrlLabel18->SetMinSize(wxSize(150,-1)); + + fgSizer5->Add(m_textCtrlLabel18, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5); + + m_textCtrlField18 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(-1,-1), 0); + fgSizer5->Add(m_textCtrlField18, 0, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5); + + m_buttonDel18 = new wxButton(m_scrolledWindow, wxID_DEL18, wxT("Delete"), wxDefaultPosition, wxSize(60,20), 0); + fgSizer5->Add(m_buttonDel18, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5); + + m_textCtrlLabel19 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0); + m_textCtrlLabel19->SetMinSize(wxSize(150,-1)); + + fgSizer5->Add(m_textCtrlLabel19, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5); + + m_textCtrlField19 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(-1,-1), 0); + fgSizer5->Add(m_textCtrlField19, 0, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5); + + m_buttonDel19 = new wxButton(m_scrolledWindow, wxID_DEL19, wxT("Delete"), wxDefaultPosition, wxSize(60,20), 0); + fgSizer5->Add(m_buttonDel19, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5); + + bSizer21->Add(fgSizer5, 0, wxEXPAND, 5); + + wxBoxSizer* bSizer25; + bSizer25 = new wxBoxSizer(wxHORIZONTAL); + + m_buttonAddField = new wxButton(m_scrolledWindow, wxID_ANY, wxT("&Add Field"), wxDefaultPosition, wxDefaultSize, 0); + bSizer25->Add(m_buttonAddField, 0, wxALL, 5); + + bSizer21->Add(bSizer25, 0, wxALIGN_CENTER_HORIZONTAL, 5); + + m_scrolledWindow->SetSizer(bSizer21); + m_scrolledWindow->Layout(); + bSizer21->Fit(m_scrolledWindow); + bSizer20->Add(m_scrolledWindow, 1, wxEXPAND|wxALL, 5); + + wxBoxSizer* bSizer26; + bSizer26 = new wxBoxSizer(wxHORIZONTAL); + + m_buttonOK = new wxButton(this, wxID_BUTTONSEND, wxT("&Send"), wxDefaultPosition, wxDefaultSize, 0); + m_buttonOK->SetMinSize(wxSize(85,25)); + + bSizer26->Add(m_buttonOK, 0, wxALL, 5); + + m_buttonPreview = new wxButton(this, wxID_BUTTONPREVIEW, wxT("&Preview"), wxDefaultPosition, wxDefaultSize, 0); + m_buttonPreview->SetMinSize(wxSize(85,25)); + + bSizer26->Add(m_buttonPreview, 0, wxALL, 5); + + m_buttonCancel = new wxButton(this, wxID_CANCEL, wxT("Cancel"), wxDefaultPosition, wxDefaultSize, 0); + m_buttonCancel->SetMinSize(wxSize(85,25)); + + bSizer26->Add(m_buttonCancel, 0, wxALL, 5); + + bSizer20->Add(bSizer26, 0, wxALIGN_RIGHT, 5); + + this->SetSizer(bSizer20); + this->Layout(); + + // Connect Events + m_textCtrlTitle->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); + m_textCtrlPrice->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); + m_textCtrlDescription->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); + m_textCtrlInstructions->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); + m_textCtrlLabel0->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); + m_textCtrlField0->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); + m_buttonDel0->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel0), NULL, this); + m_textCtrlLabel1->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); + m_textCtrlField1->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); + m_buttonDel1->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel1), NULL, this); + m_textCtrlLabel2->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); + m_textCtrlField2->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); + m_buttonDel2->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel2), NULL, this); + m_textCtrlLabel3->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); + m_textCtrlField3->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); + m_buttonDel3->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel3), NULL, this); + m_textCtrlLabel4->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); + m_textCtrlField4->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); + m_buttonDel4->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel4), NULL, this); + m_textCtrlLabel5->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); + m_textCtrlField5->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); + m_buttonDel5->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel5), NULL, this); + m_textCtrlLabel6->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); + m_textCtrlField6->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); + m_buttonDel6->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel6), NULL, this); + m_textCtrlLabel7->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); + m_textCtrlField7->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); + m_buttonDel7->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel7), NULL, this); + m_textCtrlLabel8->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); + m_textCtrlField8->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); + m_buttonDel8->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel8), NULL, this); + m_textCtrlLabel9->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); + m_textCtrlField9->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); + m_buttonDel9->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel9), NULL, this); + m_textCtrlLabel10->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); + m_textCtrlField10->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); + m_buttonDel10->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel10), NULL, this); + m_textCtrlLabel11->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); + m_textCtrlField11->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); + m_buttonDel11->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel11), NULL, this); + m_textCtrlLabel12->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); + m_textCtrlField12->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); + m_buttonDel12->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel12), NULL, this); + m_textCtrlLabel13->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); + m_textCtrlField13->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); + m_buttonDel13->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel13), NULL, this); + m_textCtrlLabel14->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); + m_textCtrlField14->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); + m_buttonDel14->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel14), NULL, this); + m_textCtrlLabel15->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); + m_textCtrlField15->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); + m_buttonDel15->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel15), NULL, this); + m_textCtrlLabel16->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); + m_textCtrlField16->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); + m_buttonDel16->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel16), NULL, this); + m_textCtrlLabel17->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); + m_textCtrlField17->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); + m_buttonDel17->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel17), NULL, this); + m_textCtrlLabel18->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); + m_textCtrlField18->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); + m_buttonDel18->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel18), NULL, this); + m_textCtrlLabel19->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); + m_textCtrlField19->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); + m_buttonDel19->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel19), NULL, this); + m_buttonAddField->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonAddField), NULL, this); + m_buttonOK->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonSend), NULL, this); + m_buttonPreview->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonPreview), NULL, this); + m_buttonCancel->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonCancel), NULL, this); +} + +CEditProductDialogBase::~CEditProductDialogBase() +{ + // Disconnect Events + m_textCtrlTitle->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); + m_textCtrlPrice->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); + m_textCtrlDescription->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); + m_textCtrlInstructions->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); + m_textCtrlLabel0->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); + m_textCtrlField0->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); + m_buttonDel0->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel0), NULL, this); + m_textCtrlLabel1->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); + m_textCtrlField1->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); + m_buttonDel1->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel1), NULL, this); + m_textCtrlLabel2->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); + m_textCtrlField2->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); + m_buttonDel2->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel2), NULL, this); + m_textCtrlLabel3->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); + m_textCtrlField3->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); + m_buttonDel3->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel3), NULL, this); + m_textCtrlLabel4->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); + m_textCtrlField4->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); + m_buttonDel4->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel4), NULL, this); + m_textCtrlLabel5->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); + m_textCtrlField5->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); + m_buttonDel5->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel5), NULL, this); + m_textCtrlLabel6->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); + m_textCtrlField6->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); + m_buttonDel6->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel6), NULL, this); + m_textCtrlLabel7->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); + m_textCtrlField7->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); + m_buttonDel7->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel7), NULL, this); + m_textCtrlLabel8->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); + m_textCtrlField8->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); + m_buttonDel8->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel8), NULL, this); + m_textCtrlLabel9->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); + m_textCtrlField9->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); + m_buttonDel9->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel9), NULL, this); + m_textCtrlLabel10->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); + m_textCtrlField10->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); + m_buttonDel10->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel10), NULL, this); + m_textCtrlLabel11->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); + m_textCtrlField11->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); + m_buttonDel11->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel11), NULL, this); + m_textCtrlLabel12->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); + m_textCtrlField12->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); + m_buttonDel12->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel12), NULL, this); + m_textCtrlLabel13->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); + m_textCtrlField13->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); + m_buttonDel13->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel13), NULL, this); + m_textCtrlLabel14->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); + m_textCtrlField14->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); + m_buttonDel14->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel14), NULL, this); + m_textCtrlLabel15->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); + m_textCtrlField15->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); + m_buttonDel15->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel15), NULL, this); + m_textCtrlLabel16->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); + m_textCtrlField16->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); + m_buttonDel16->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel16), NULL, this); + m_textCtrlLabel17->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); + m_textCtrlField17->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); + m_buttonDel17->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel17), NULL, this); + m_textCtrlLabel18->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); + m_textCtrlField18->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); + m_buttonDel18->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel18), NULL, this); + m_textCtrlLabel19->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); + m_textCtrlField19->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); + m_buttonDel19->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel19), NULL, this); + m_buttonAddField->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonAddField), NULL, this); + m_buttonOK->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonSend), NULL, this); + m_buttonPreview->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonPreview), NULL, this); + m_buttonCancel->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonCancel), NULL, this); +} + +CViewProductDialogBase::CViewProductDialogBase(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_MENU)); + + wxBoxSizer* bSizer20; + bSizer20 = new wxBoxSizer(wxVERTICAL); + + wxBoxSizer* bSizer116; + bSizer116 = new wxBoxSizer(wxHORIZONTAL); + + m_htmlWinReviews = new wxHtmlWindow(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxHW_SCROLLBAR_AUTO); + m_htmlWinReviews->Hide(); + + bSizer116->Add(m_htmlWinReviews, 1, wxALL|wxEXPAND, 5); + + m_scrolledWindow = new wxScrolledWindow(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxHSCROLL|wxTAB_TRAVERSAL|wxVSCROLL); + m_scrolledWindow->SetScrollRate(5, 5); + m_scrolledWindow->SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW)); + + wxBoxSizer* bSizer21; + bSizer21 = new wxBoxSizer(wxVERTICAL); + + m_richTextHeading = new wxRichTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(-1,50), wxTE_READONLY|wxNO_BORDER); + bSizer21->Add(m_richTextHeading, 0, wxEXPAND, 5); + + m_staticTextInstructions = new wxStaticText(m_scrolledWindow, wxID_ANY, wxT("Order Form instructions here\nmultiple lines\n1\n2\n3\n4\n5\n6"), wxDefaultPosition, wxDefaultSize, 0); + m_staticTextInstructions->Wrap(-1); + bSizer21->Add(m_staticTextInstructions, 0, wxALL|wxEXPAND, 5); + + wxBoxSizer* bSizer25; + bSizer25 = new wxBoxSizer(wxHORIZONTAL); + + m_buttonSubmitForm = new wxButton(m_scrolledWindow, wxID_BUTTONSAMPLE, wxT("&Submit"), wxDefaultPosition, wxDefaultSize, 0); + bSizer25->Add(m_buttonSubmitForm, 0, wxALL, 5); + + m_buttonCancelForm = new wxButton(m_scrolledWindow, wxID_CANCEL2, wxT("Cancel"), wxDefaultPosition, wxDefaultSize, 0); + bSizer25->Add(m_buttonCancelForm, 0, wxALL, 5); + + bSizer21->Add(bSizer25, 0, wxALIGN_CENTER_HORIZONTAL, 5); + + m_scrolledWindow->SetSizer(bSizer21); + m_scrolledWindow->Layout(); + bSizer21->Fit(m_scrolledWindow); + bSizer116->Add(m_scrolledWindow, 1, wxEXPAND|wxALL, 5); + + bSizer20->Add(bSizer116, 1, wxEXPAND, 5); + + wxBoxSizer* bSizer26; + bSizer26 = new wxBoxSizer(wxHORIZONTAL); + + m_buttonBack = new wxButton(this, wxID_BUTTONBACK, wxT("< &Back "), wxDefaultPosition, wxDefaultSize, 0); + m_buttonBack->Enable(false); + m_buttonBack->SetMinSize(wxSize(85,25)); + + bSizer26->Add(m_buttonBack, 0, wxALL, 5); + + m_buttonNext = new wxButton(this, wxID_BUTTONNEXT, wxT(" &Next >"), wxDefaultPosition, wxDefaultSize, 0); + m_buttonNext->SetMinSize(wxSize(85,25)); + + bSizer26->Add(m_buttonNext, 0, wxALL, 5); + + m_buttonCancel = new wxButton(this, wxID_CANCEL, wxT("Cancel"), wxDefaultPosition, wxDefaultSize, 0); + m_buttonCancel->SetMinSize(wxSize(85,25)); + + bSizer26->Add(m_buttonCancel, 0, wxALL, 5); + + bSizer20->Add(bSizer26, 0, wxALIGN_RIGHT, 5); + + this->SetSizer(bSizer20); + this->Layout(); + + // Connect Events + m_buttonSubmitForm->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CViewProductDialogBase::OnButtonSubmitForm), NULL, this); + m_buttonCancelForm->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CViewProductDialogBase::OnButtonCancelForm), NULL, this); + m_buttonBack->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CViewProductDialogBase::OnButtonBack), NULL, this); + m_buttonNext->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CViewProductDialogBase::OnButtonNext), NULL, this); + m_buttonCancel->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CViewProductDialogBase::OnButtonCancel), NULL, this); +} + +CViewProductDialogBase::~CViewProductDialogBase() +{ + // Disconnect Events + m_buttonSubmitForm->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CViewProductDialogBase::OnButtonSubmitForm), NULL, this); + m_buttonCancelForm->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CViewProductDialogBase::OnButtonCancelForm), NULL, this); + m_buttonBack->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CViewProductDialogBase::OnButtonBack), NULL, this); + m_buttonNext->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CViewProductDialogBase::OnButtonNext), NULL, this); + m_buttonCancel->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CViewProductDialogBase::OnButtonCancel), NULL, this); +} + +CViewOrderDialogBase::CViewOrderDialogBase(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_MENU)); + + wxBoxSizer* bSizer20; + bSizer20 = new wxBoxSizer(wxVERTICAL); + + wxBoxSizer* bSizer116; + bSizer116 = new wxBoxSizer(wxHORIZONTAL); + + m_htmlWin = new wxHtmlWindow(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxHW_SCROLLBAR_AUTO); + bSizer116->Add(m_htmlWin, 1, wxALL|wxEXPAND, 5); + + bSizer20->Add(bSizer116, 1, wxEXPAND, 5); + + wxBoxSizer* bSizer26; + bSizer26 = new wxBoxSizer(wxHORIZONTAL); + + m_buttonOK = new wxButton(this, wxID_OK, wxT("OK"), wxDefaultPosition, wxDefaultSize, 0); + m_buttonOK->SetMinSize(wxSize(85,25)); + + bSizer26->Add(m_buttonOK, 0, wxALL, 5); + + bSizer20->Add(bSizer26, 0, wxALIGN_RIGHT, 5); + + this->SetSizer(bSizer20); + this->Layout(); + + // Connect Events + m_buttonOK->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CViewOrderDialogBase::OnButtonOK), NULL, this); +} + +CViewOrderDialogBase::~CViewOrderDialogBase() +{ + // Disconnect Events + m_buttonOK->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CViewOrderDialogBase::OnButtonOK), NULL, this); +} + +CEditReviewDialogBase::CEditReviewDialogBase(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_MENU)); + + wxBoxSizer* bSizer112; + bSizer112 = new wxBoxSizer(wxVERTICAL); + + + bSizer112->Add(0, 3, 0, 0, 5); + + m_staticTextSeller = new wxStaticText(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0); + m_staticTextSeller->Wrap(-1); + bSizer112->Add(m_staticTextSeller, 0, wxALL|wxEXPAND, 5); + + + bSizer112->Add(0, 3, 0, 0, 5); + + m_staticText110 = new wxStaticText(this, wxID_ANY, wxT("Rating"), wxDefaultPosition, wxDefaultSize, 0); + m_staticText110->Wrap(-1); + bSizer112->Add(m_staticText110, 0, wxTOP|wxRIGHT|wxLEFT, 5); + + wxString m_choiceStarsChoices[] = { wxT(" 1 star"), wxT(" 2 stars"), wxT(" 3 stars"), wxT(" 4 stars"), wxT(" 5 stars") }; + int m_choiceStarsNChoices = sizeof(m_choiceStarsChoices) / sizeof(wxString); + m_choiceStars = new wxChoice(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, m_choiceStarsNChoices, m_choiceStarsChoices, 0); + m_choiceStars->SetSelection(0); + bSizer112->Add(m_choiceStars, 0, wxALL, 5); + + m_staticText43 = new wxStaticText(this, wxID_ANY, wxT("Review"), wxDefaultPosition, wxDefaultSize, 0); + m_staticText43->Wrap(-1); + bSizer112->Add(m_staticText43, 0, wxTOP|wxRIGHT|wxLEFT, 5); + + m_textCtrlReview = new wxTextCtrl(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE); + bSizer112->Add(m_textCtrlReview, 1, wxALL|wxEXPAND, 5); + + wxBoxSizer* bSizer113; + bSizer113 = new wxBoxSizer(wxHORIZONTAL); + + m_buttonSubmit = new wxButton(this, wxID_SUBMIT, wxT("&Submit"), wxDefaultPosition, wxDefaultSize, 0); + m_buttonSubmit->SetMinSize(wxSize(85,25)); + + bSizer113->Add(m_buttonSubmit, 0, wxALL, 5); + + m_buttonCancel = new wxButton(this, wxID_CANCEL, wxT("Cancel"), wxDefaultPosition, wxDefaultSize, 0); + m_buttonCancel->SetMinSize(wxSize(85,25)); + + bSizer113->Add(m_buttonCancel, 0, wxALL, 5); + + bSizer112->Add(bSizer113, 0, wxALIGN_RIGHT, 5); + + this->SetSizer(bSizer112); + this->Layout(); + + // Connect Events + m_textCtrlReview->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditReviewDialogBase::OnKeyDown), NULL, this); + m_buttonSubmit->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditReviewDialogBase::OnButtonSubmit), NULL, this); + m_buttonCancel->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditReviewDialogBase::OnButtonCancel), NULL, this); +} + +CEditReviewDialogBase::~CEditReviewDialogBase() +{ + // Disconnect Events + m_textCtrlReview->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditReviewDialogBase::OnKeyDown), NULL, this); + m_buttonSubmit->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditReviewDialogBase::OnButtonSubmit), NULL, this); + m_buttonCancel->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditReviewDialogBase::OnButtonCancel), NULL, this); +} + +CPokerLobbyDialogBase::CPokerLobbyDialogBase(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)); + + wxBoxSizer* bSizer156; + bSizer156 = new wxBoxSizer(wxHORIZONTAL); + + m_treeCtrl = new wxTreeCtrl(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTR_HAS_BUTTONS|wxTR_HIDE_ROOT|wxTR_LINES_AT_ROOT); + m_treeCtrl->SetMinSize(wxSize(130,-1)); + + bSizer156->Add(m_treeCtrl, 0, wxEXPAND|wxTOP|wxBOTTOM|wxLEFT, 5); + + wxBoxSizer* bSizer172; + bSizer172 = new wxBoxSizer(wxVERTICAL); + + m_listCtrl = new wxListCtrl(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_NO_SORT_HEADER|wxLC_REPORT); + bSizer172->Add(m_listCtrl, 1, wxEXPAND|wxALL, 5); + + m_buttonNewTable = new wxButton(this, wxID_OPENNEWTABLE, wxT("&Open New Table"), wxDefaultPosition, wxDefaultSize, 0); + bSizer172->Add(m_buttonNewTable, 0, wxALL, 5); + + bSizer156->Add(bSizer172, 1, wxEXPAND, 5); + + this->SetSizer(bSizer156); + this->Layout(); + + // Connect Events + m_treeCtrl->Connect(wxEVT_COMMAND_TREE_SEL_CHANGED, wxTreeEventHandler(CPokerLobbyDialogBase::OnTreeSelChanged), NULL, this); + m_listCtrl->Connect(wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler(CPokerLobbyDialogBase::OnListItemActivated), NULL, this); + m_listCtrl->Connect(wxEVT_COMMAND_LIST_ITEM_SELECTED, wxListEventHandler(CPokerLobbyDialogBase::OnListItemSelected), NULL, this); + m_buttonNewTable->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CPokerLobbyDialogBase::OnButtonNewTable), NULL, this); +} + +CPokerLobbyDialogBase::~CPokerLobbyDialogBase() +{ + // Disconnect Events + m_treeCtrl->Disconnect(wxEVT_COMMAND_TREE_SEL_CHANGED, wxTreeEventHandler(CPokerLobbyDialogBase::OnTreeSelChanged), NULL, this); + m_listCtrl->Disconnect(wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler(CPokerLobbyDialogBase::OnListItemActivated), NULL, this); + m_listCtrl->Disconnect(wxEVT_COMMAND_LIST_ITEM_SELECTED, wxListEventHandler(CPokerLobbyDialogBase::OnListItemSelected), NULL, this); + m_buttonNewTable->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CPokerLobbyDialogBase::OnButtonNewTable), NULL, this); +} + +CPokerDialogBase::CPokerDialogBase(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); + + wxBoxSizer* bSizer174; + bSizer174 = new wxBoxSizer(wxVERTICAL); + + m_checkSitOut = new wxCheckBox(this, wxID_ANY, wxT("Deal Me Out"), wxDefaultPosition, wxDefaultSize, 0); + + bSizer174->Add(m_checkSitOut, 0, wxALL, 5); + + m_buttonDealHand = new wxButton(this, wxID_DEALHAND, wxT("&Deal Hand"), wxDefaultPosition, wxSize(150,25), 0); + bSizer174->Add(m_buttonDealHand, 0, wxALL, 5); + + m_buttonFold = new wxButton(this, wxID_FOLD, wxT("&Fold"), wxDefaultPosition, wxSize(80,25), 0); + bSizer174->Add(m_buttonFold, 0, wxALL, 5); + + m_buttonCall = new wxButton(this, wxID_CALL, wxT("&Call"), wxDefaultPosition, wxSize(80,25), 0); + bSizer174->Add(m_buttonCall, 0, wxALL, 5); + + m_buttonRaise = new wxButton(this, wxID_RAISE, wxT("&Raise"), wxDefaultPosition, wxSize(80,25), 0); + bSizer174->Add(m_buttonRaise, 0, wxALL, 5); + + m_buttonLeaveTable = new wxButton(this, wxID_LEAVETABLE, wxT("&Leave Table"), wxDefaultPosition, wxSize(90,25), 0); + bSizer174->Add(m_buttonLeaveTable, 0, wxALL, 5); + + m_textDitchPlayer = new wxTextCtrl(this, wxID_DITCHPLAYER, wxEmptyString, wxDefaultPosition, wxSize(45,-1), wxTE_PROCESS_ENTER); + bSizer174->Add(m_textDitchPlayer, 0, wxALL, 5); + + m_checkPreFold = new wxCheckBox(this, wxID_ANY, wxT("FOLD"), wxDefaultPosition, wxSize(100,-1), 0); + + bSizer174->Add(m_checkPreFold, 0, wxALL, 5); + + m_checkPreCall = new wxCheckBox(this, wxID_ANY, wxT("CALL"), wxDefaultPosition, wxSize(100,-1), 0); + + bSizer174->Add(m_checkPreCall, 0, wxALL, 5); + + m_checkPreCallAny = new wxCheckBox(this, wxID_ANY, wxT("CALL ANY"), wxDefaultPosition, wxSize(100,-1), 0); + + bSizer174->Add(m_checkPreCallAny, 0, wxALL, 5); + + m_checkPreRaise = new wxCheckBox(this, wxID_ANY, wxT("RAISE"), wxDefaultPosition, wxSize(100,-1), 0); + + bSizer174->Add(m_checkPreRaise, 0, wxALL, 5); + + m_checkPreRaiseAny = new wxCheckBox(this, wxID_ANY, wxT("RAISE ANY"), wxDefaultPosition, wxSize(100,-1), 0); + + bSizer174->Add(m_checkPreRaiseAny, 0, wxALL, 5); + + this->SetSizer(bSizer174); + this->Layout(); + m_statusBar = this->CreateStatusBar(1, wxST_SIZEGRIP, wxID_ANY); + + // Connect Events + this->Connect(wxEVT_CLOSE_WINDOW, wxCloseEventHandler(CPokerDialogBase::OnClose)); + this->Connect(wxEVT_LEFT_DOWN, wxMouseEventHandler(CPokerDialogBase::OnMouseEvents)); + this->Connect(wxEVT_LEFT_UP, wxMouseEventHandler(CPokerDialogBase::OnMouseEvents)); + this->Connect(wxEVT_MIDDLE_DOWN, wxMouseEventHandler(CPokerDialogBase::OnMouseEvents)); + this->Connect(wxEVT_MIDDLE_UP, wxMouseEventHandler(CPokerDialogBase::OnMouseEvents)); + this->Connect(wxEVT_RIGHT_DOWN, wxMouseEventHandler(CPokerDialogBase::OnMouseEvents)); + this->Connect(wxEVT_RIGHT_UP, wxMouseEventHandler(CPokerDialogBase::OnMouseEvents)); + this->Connect(wxEVT_MOTION, wxMouseEventHandler(CPokerDialogBase::OnMouseEvents)); + this->Connect(wxEVT_LEFT_DCLICK, wxMouseEventHandler(CPokerDialogBase::OnMouseEvents)); + this->Connect(wxEVT_MIDDLE_DCLICK, wxMouseEventHandler(CPokerDialogBase::OnMouseEvents)); + this->Connect(wxEVT_RIGHT_DCLICK, wxMouseEventHandler(CPokerDialogBase::OnMouseEvents)); + this->Connect(wxEVT_LEAVE_WINDOW, wxMouseEventHandler(CPokerDialogBase::OnMouseEvents)); + this->Connect(wxEVT_ENTER_WINDOW, wxMouseEventHandler(CPokerDialogBase::OnMouseEvents)); + this->Connect(wxEVT_MOUSEWHEEL, wxMouseEventHandler(CPokerDialogBase::OnMouseEvents)); + this->Connect(wxEVT_PAINT, wxPaintEventHandler(CPokerDialogBase::OnPaint)); + this->Connect(wxEVT_SIZE, wxSizeEventHandler(CPokerDialogBase::OnSize)); + m_checkSitOut->Connect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler(CPokerDialogBase::OnCheckSitOut), NULL, this); + m_buttonDealHand->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CPokerDialogBase::OnButtonDealHand), NULL, this); + m_buttonFold->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CPokerDialogBase::OnButtonFold), NULL, this); + m_buttonCall->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CPokerDialogBase::OnButtonCall), NULL, this); + m_buttonRaise->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CPokerDialogBase::OnButtonRaise), NULL, this); + m_buttonLeaveTable->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CPokerDialogBase::OnButtonLeaveTable), NULL, this); + m_textDitchPlayer->Connect(wxEVT_COMMAND_TEXT_ENTER, wxCommandEventHandler(CPokerDialogBase::OnDitchPlayer), NULL, this); + m_checkPreFold->Connect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler(CPokerDialogBase::OnCheckPreFold), NULL, this); + m_checkPreCall->Connect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler(CPokerDialogBase::OnCheckPreCall), NULL, this); + m_checkPreCallAny->Connect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler(CPokerDialogBase::OnCheckPreCallAny), NULL, this); + m_checkPreRaise->Connect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler(CPokerDialogBase::OnCheckPreRaise), NULL, this); + m_checkPreRaiseAny->Connect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler(CPokerDialogBase::OnCheckPreRaiseAny), NULL, this); +} + +CPokerDialogBase::~CPokerDialogBase() +{ + // Disconnect Events + this->Disconnect(wxEVT_CLOSE_WINDOW, wxCloseEventHandler(CPokerDialogBase::OnClose)); + this->Disconnect(wxEVT_LEFT_DOWN, wxMouseEventHandler(CPokerDialogBase::OnMouseEvents)); + this->Disconnect(wxEVT_LEFT_UP, wxMouseEventHandler(CPokerDialogBase::OnMouseEvents)); + this->Disconnect(wxEVT_MIDDLE_DOWN, wxMouseEventHandler(CPokerDialogBase::OnMouseEvents)); + this->Disconnect(wxEVT_MIDDLE_UP, wxMouseEventHandler(CPokerDialogBase::OnMouseEvents)); + this->Disconnect(wxEVT_RIGHT_DOWN, wxMouseEventHandler(CPokerDialogBase::OnMouseEvents)); + this->Disconnect(wxEVT_RIGHT_UP, wxMouseEventHandler(CPokerDialogBase::OnMouseEvents)); + this->Disconnect(wxEVT_MOTION, wxMouseEventHandler(CPokerDialogBase::OnMouseEvents)); + this->Disconnect(wxEVT_LEFT_DCLICK, wxMouseEventHandler(CPokerDialogBase::OnMouseEvents)); + this->Disconnect(wxEVT_MIDDLE_DCLICK, wxMouseEventHandler(CPokerDialogBase::OnMouseEvents)); + this->Disconnect(wxEVT_RIGHT_DCLICK, wxMouseEventHandler(CPokerDialogBase::OnMouseEvents)); + this->Disconnect(wxEVT_LEAVE_WINDOW, wxMouseEventHandler(CPokerDialogBase::OnMouseEvents)); + this->Disconnect(wxEVT_ENTER_WINDOW, wxMouseEventHandler(CPokerDialogBase::OnMouseEvents)); + this->Disconnect(wxEVT_MOUSEWHEEL, wxMouseEventHandler(CPokerDialogBase::OnMouseEvents)); + this->Disconnect(wxEVT_PAINT, wxPaintEventHandler(CPokerDialogBase::OnPaint)); + this->Disconnect(wxEVT_SIZE, wxSizeEventHandler(CPokerDialogBase::OnSize)); + m_checkSitOut->Disconnect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler(CPokerDialogBase::OnCheckSitOut), NULL, this); + m_buttonDealHand->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CPokerDialogBase::OnButtonDealHand), NULL, this); + m_buttonFold->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CPokerDialogBase::OnButtonFold), NULL, this); + m_buttonCall->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CPokerDialogBase::OnButtonCall), NULL, this); + m_buttonRaise->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CPokerDialogBase::OnButtonRaise), NULL, this); + m_buttonLeaveTable->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CPokerDialogBase::OnButtonLeaveTable), NULL, this); + m_textDitchPlayer->Disconnect(wxEVT_COMMAND_TEXT_ENTER, wxCommandEventHandler(CPokerDialogBase::OnDitchPlayer), NULL, this); + m_checkPreFold->Disconnect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler(CPokerDialogBase::OnCheckPreFold), NULL, this); + m_checkPreCall->Disconnect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler(CPokerDialogBase::OnCheckPreCall), NULL, this); + m_checkPreCallAny->Disconnect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler(CPokerDialogBase::OnCheckPreCallAny), NULL, this); + m_checkPreRaise->Disconnect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler(CPokerDialogBase::OnCheckPreRaise), NULL, this); + m_checkPreRaiseAny->Disconnect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler(CPokerDialogBase::OnCheckPreRaiseAny), 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, wxT("OK"), wxDefaultPosition, wxSize(-1,-1), 0); + m_buttonOK->SetMinSize(wxSize(85,25)); + + bSizer80->Add(m_buttonOK, 0, wxALL, 5); + + m_buttonCancel = new wxButton(this, wxID_CANCEL, wxT("Cancel"), wxDefaultPosition, wxDefaultSize, 0); + m_buttonCancel->SetMinSize(wxSize(85,25)); + + bSizer80->Add(m_buttonCancel, 0, wxALL, 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/uibase.h b/uibase.h new file mode 100644 index 0000000000..bfcd8eccb8 --- /dev/null +++ b/uibase.h @@ -0,0 +1,723 @@ +// Copyright (c) 2009 Satoshi Nakamoto +// Distributed under the MIT/X11 software license, see the accompanying +// file license.txt or http://www.opensource.org/licenses/mit-license.php. + +/////////////////////////////////////////////////////////////////////////// +// C++ code generated with wxFormBuilder (version Apr 16 2008) +// http://www.wxformbuilder.org/ +// +// PLEASE DO "NOT" EDIT THIS FILE! +/////////////////////////////////////////////////////////////////////////// + +#ifndef __uibase__ +#define __uibase__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/////////////////////////////////////////////////////////////////////////// + +#define wxID_MAINFRAME 1000 +#define wxID_OPTIONSGENERATEBITCOINS 1001 +#define wxID_BUTTONSEND 1002 +#define wxID_BUTTONRECEIVE 1003 +#define wxID_TEXTCTRLADDRESS 1004 +#define wxID_BUTTONCOPY 1005 +#define wxID_BUTTONCHANGE 1006 +#define wxID_TRANSACTIONFEE 1007 +#define wxID_TEXTCTRLPAYTO 1008 +#define wxID_BUTTONPASTE 1009 +#define wxID_BUTTONADDRESSBOOK 1010 +#define wxID_TEXTCTRLAMOUNT 1011 +#define wxID_CHOICETRANSFERTYPE 1012 +#define wxID_LISTCTRL 1013 +#define wxID_BUTTONRENAME 1014 +#define wxID_BUTTONNEW 1015 +#define wxID_BUTTONEDIT 1016 +#define wxID_BUTTONDELETE 1017 +#define wxID_DEL0 1018 +#define wxID_DEL1 1019 +#define wxID_DEL2 1020 +#define wxID_DEL3 1021 +#define wxID_DEL4 1022 +#define wxID_DEL5 1023 +#define wxID_DEL6 1024 +#define wxID_DEL7 1025 +#define wxID_DEL8 1026 +#define wxID_DEL9 1027 +#define wxID_DEL10 1028 +#define wxID_DEL11 1029 +#define wxID_DEL12 1030 +#define wxID_DEL13 1031 +#define wxID_DEL14 1032 +#define wxID_DEL15 1033 +#define wxID_DEL16 1034 +#define wxID_DEL17 1035 +#define wxID_DEL18 1036 +#define wxID_DEL19 1037 +#define wxID_BUTTONPREVIEW 1038 +#define wxID_BUTTONSAMPLE 1039 +#define wxID_CANCEL2 1040 +#define wxID_BUTTONBACK 1041 +#define wxID_BUTTONNEXT 1042 +#define wxID_SUBMIT 1043 +#define wxID_OPENNEWTABLE 1044 +#define wxID_DEALHAND 1045 +#define wxID_FOLD 1046 +#define wxID_CALL 1047 +#define wxID_RAISE 1048 +#define wxID_LEAVETABLE 1049 +#define wxID_DITCHPLAYER 1050 +#define wxID_TEXTCTRL 1051 + +/////////////////////////////////////////////////////////////////////////////// +/// Class CMainFrameBase +/////////////////////////////////////////////////////////////////////////////// +class CMainFrameBase : public wxFrame +{ +private: + +protected: + wxMenuBar* m_menubar; + wxMenu* m_menuFile; + wxMenu* m_menuHelp; + wxToolBar* m_toolBar; + wxStatusBar* m_statusBar; + + wxStaticText* m_staticText32; + wxTextCtrl* m_textCtrlAddress; + wxButton* m_buttonCopy; + wxButton* m_button91; + + wxPanel* m_panel14; + wxStaticText* m_staticText41; + wxStaticText* m_staticTextBalance; + + wxChoice* m_choiceFilter; + wxNotebook* m_notebook; + wxPanel* m_panel7; + wxPanel* m_panel9; + wxPanel* m_panel8; + wxPanel* m_panel10; + wxPanel* m_panel11; + + // Virtual event handlers, overide them in your derived class + virtual void OnClose(wxCloseEvent& 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 OnMenuOptionsGenerate(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 OnButtonCopy(wxCommandEvent& event){ event.Skip(); } + virtual void OnButtonChange(wxCommandEvent& event){ event.Skip(); } + virtual void OnListColBeginDrag(wxListEvent& event){ event.Skip(); } + virtual void OnListItemActivatedAllTransactions(wxListEvent& event){ event.Skip(); } + virtual void OnPaintListCtrl(wxPaintEvent& event){ event.Skip(); } + virtual void OnListItemActivatedOrdersSent(wxListEvent& event){ event.Skip(); } + virtual void OnListItemActivatedProductsSent(wxListEvent& event){ event.Skip(); } + virtual void OnListItemActivatedOrdersReceived(wxListEvent& event){ event.Skip(); } + + +public: + wxMenu* m_menuOptions; + wxListCtrl* m_listCtrl; + wxListCtrl* m_listCtrlEscrows; + wxListCtrl* m_listCtrlOrdersSent; + wxListCtrl* m_listCtrlProductsSent; + wxListCtrl* m_listCtrlOrdersReceived; + CMainFrameBase(wxWindow* parent, wxWindowID id = wxID_MAINFRAME, const wxString& title = wxT("Bitcoin"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize(705,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 = wxT("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: + + wxStaticText* m_staticText32; + wxStaticText* m_staticText31; + wxTextCtrl* m_textCtrlTransactionFee; + wxButton* m_buttonOK; + wxButton* m_buttonCancel; + + // Virtual event handlers, overide them in your derived class + virtual void OnKillFocusTransactionFee(wxFocusEvent& event){ event.Skip(); } + virtual void OnButtonOK(wxCommandEvent& event){ event.Skip(); } + virtual void OnButtonCancel(wxCommandEvent& event){ event.Skip(); } + + +public: + COptionsDialogBase(wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxT("Options"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize(500,261), long style = wxDEFAULT_DIALOG_STYLE); + ~COptionsDialogBase(); + +}; + +/////////////////////////////////////////////////////////////////////////////// +/// Class CAboutDialogBase +/////////////////////////////////////////////////////////////////////////////// +class CAboutDialogBase : public wxDialog +{ +private: + +protected: + + + 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 = wxT("About Bitcoin"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize(507,298), long style = wxDEFAULT_DIALOG_STYLE); + ~CAboutDialogBase(); + +}; + +/////////////////////////////////////////////////////////////////////////////// +/// Class CSendDialogBase +/////////////////////////////////////////////////////////////////////////////// +class CSendDialogBase : public wxDialog +{ +private: + +protected: + + + wxStaticText* m_staticText14; + + 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; + + + wxStaticText* m_staticTextFrom; + wxTextCtrl* m_textCtrlFrom; + wxStaticText* m_staticTextMessage; + wxTextCtrl* m_textCtrlMessage; + + 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 = wxT("Send Coins"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize(675,312), 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 = wxT("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 = wxT("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: + + wxStaticText* m_staticText55; + wxListCtrl* m_listCtrl; + + wxButton* m_buttonEdit; + wxButton* m_buttonNew; + wxButton* m_buttonDelete; + wxButton* m_buttonOK; + + // 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 OnButtonEdit(wxCommandEvent& event){ event.Skip(); } + virtual void OnButtonNew(wxCommandEvent& event){ event.Skip(); } + virtual void OnButtonDelete(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 = wxT("Address Book"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize(610,390), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER); + ~CAddressBookDialogBase(); + +}; + +/////////////////////////////////////////////////////////////////////////////// +/// Class CProductsDialogBase +/////////////////////////////////////////////////////////////////////////////// +class CProductsDialogBase : public wxDialog +{ +private: + +protected: + wxComboBox* m_comboBoxCategory; + wxTextCtrl* m_textCtrlSearch; + wxButton* m_buttonSearch; + wxListCtrl* m_listCtrl; + + // Virtual event handlers, overide them in your derived class + virtual void OnCombobox(wxCommandEvent& event){ event.Skip(); } + virtual void OnKeyDown(wxKeyEvent& event){ event.Skip(); } + virtual void OnButtonSearch(wxCommandEvent& event){ event.Skip(); } + virtual void OnListItemActivated(wxListEvent& event){ event.Skip(); } + + +public: + CProductsDialogBase(wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxT("Marketplace"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize(708,535), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER); + ~CProductsDialogBase(); + +}; + +/////////////////////////////////////////////////////////////////////////////// +/// Class CEditProductDialogBase +/////////////////////////////////////////////////////////////////////////////// +class CEditProductDialogBase : public wxFrame +{ +private: + +protected: + wxScrolledWindow* m_scrolledWindow; + wxStaticText* m_staticText106; + wxComboBox* m_comboBoxCategory; + wxStaticText* m_staticText108; + wxTextCtrl* m_textCtrlTitle; + wxStaticText* m_staticText107; + wxTextCtrl* m_textCtrlPrice; + wxStaticText* m_staticText22; + wxTextCtrl* m_textCtrlDescription; + wxStaticText* m_staticText23; + wxTextCtrl* m_textCtrlInstructions; + wxStaticText* m_staticText24; + wxStaticText* m_staticText25; + + wxTextCtrl* m_textCtrlLabel0; + wxTextCtrl* m_textCtrlField0; + wxButton* m_buttonDel0; + wxTextCtrl* m_textCtrlLabel1; + wxTextCtrl* m_textCtrlField1; + wxButton* m_buttonDel1; + wxTextCtrl* m_textCtrlLabel2; + wxTextCtrl* m_textCtrlField2; + wxButton* m_buttonDel2; + wxTextCtrl* m_textCtrlLabel3; + wxTextCtrl* m_textCtrlField3; + wxButton* m_buttonDel3; + wxTextCtrl* m_textCtrlLabel4; + wxTextCtrl* m_textCtrlField4; + wxButton* m_buttonDel4; + wxTextCtrl* m_textCtrlLabel5; + wxTextCtrl* m_textCtrlField5; + wxButton* m_buttonDel5; + wxTextCtrl* m_textCtrlLabel6; + wxTextCtrl* m_textCtrlField6; + wxButton* m_buttonDel6; + wxTextCtrl* m_textCtrlLabel7; + wxTextCtrl* m_textCtrlField7; + wxButton* m_buttonDel7; + wxTextCtrl* m_textCtrlLabel8; + wxTextCtrl* m_textCtrlField8; + wxButton* m_buttonDel8; + wxTextCtrl* m_textCtrlLabel9; + wxTextCtrl* m_textCtrlField9; + wxButton* m_buttonDel9; + wxTextCtrl* m_textCtrlLabel10; + wxTextCtrl* m_textCtrlField10; + wxButton* m_buttonDel10; + wxTextCtrl* m_textCtrlLabel11; + wxTextCtrl* m_textCtrlField11; + wxButton* m_buttonDel11; + wxTextCtrl* m_textCtrlLabel12; + wxTextCtrl* m_textCtrlField12; + wxButton* m_buttonDel12; + wxTextCtrl* m_textCtrlLabel13; + wxTextCtrl* m_textCtrlField13; + wxButton* m_buttonDel13; + wxTextCtrl* m_textCtrlLabel14; + wxTextCtrl* m_textCtrlField14; + wxButton* m_buttonDel14; + wxTextCtrl* m_textCtrlLabel15; + wxTextCtrl* m_textCtrlField15; + wxButton* m_buttonDel15; + wxTextCtrl* m_textCtrlLabel16; + wxTextCtrl* m_textCtrlField16; + wxButton* m_buttonDel16; + wxTextCtrl* m_textCtrlLabel17; + wxTextCtrl* m_textCtrlField17; + wxButton* m_buttonDel17; + wxTextCtrl* m_textCtrlLabel18; + wxTextCtrl* m_textCtrlField18; + wxButton* m_buttonDel18; + wxTextCtrl* m_textCtrlLabel19; + wxTextCtrl* m_textCtrlField19; + wxButton* m_buttonDel19; + wxButton* m_buttonAddField; + wxButton* m_buttonOK; + wxButton* m_buttonPreview; + wxButton* m_buttonCancel; + + // Virtual event handlers, overide them in your derived class + virtual void OnKeyDown(wxKeyEvent& event){ event.Skip(); } + virtual void OnButtonDel0(wxCommandEvent& event){ event.Skip(); } + virtual void OnButtonDel1(wxCommandEvent& event){ event.Skip(); } + virtual void OnButtonDel2(wxCommandEvent& event){ event.Skip(); } + virtual void OnButtonDel3(wxCommandEvent& event){ event.Skip(); } + virtual void OnButtonDel4(wxCommandEvent& event){ event.Skip(); } + virtual void OnButtonDel5(wxCommandEvent& event){ event.Skip(); } + virtual void OnButtonDel6(wxCommandEvent& event){ event.Skip(); } + virtual void OnButtonDel7(wxCommandEvent& event){ event.Skip(); } + virtual void OnButtonDel8(wxCommandEvent& event){ event.Skip(); } + virtual void OnButtonDel9(wxCommandEvent& event){ event.Skip(); } + virtual void OnButtonDel10(wxCommandEvent& event){ event.Skip(); } + virtual void OnButtonDel11(wxCommandEvent& event){ event.Skip(); } + virtual void OnButtonDel12(wxCommandEvent& event){ event.Skip(); } + virtual void OnButtonDel13(wxCommandEvent& event){ event.Skip(); } + virtual void OnButtonDel14(wxCommandEvent& event){ event.Skip(); } + virtual void OnButtonDel15(wxCommandEvent& event){ event.Skip(); } + virtual void OnButtonDel16(wxCommandEvent& event){ event.Skip(); } + virtual void OnButtonDel17(wxCommandEvent& event){ event.Skip(); } + virtual void OnButtonDel18(wxCommandEvent& event){ event.Skip(); } + virtual void OnButtonDel19(wxCommandEvent& event){ event.Skip(); } + virtual void OnButtonAddField(wxCommandEvent& event){ event.Skip(); } + virtual void OnButtonSend(wxCommandEvent& event){ event.Skip(); } + virtual void OnButtonPreview(wxCommandEvent& event){ event.Skip(); } + virtual void OnButtonCancel(wxCommandEvent& event){ event.Skip(); } + + +public: + wxFlexGridSizer* fgSizer5; + CEditProductDialogBase(wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxT("Edit Product"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize(660,640), long style = wxDEFAULT_FRAME_STYLE|wxRESIZE_BORDER|wxTAB_TRAVERSAL); + ~CEditProductDialogBase(); + +}; + +/////////////////////////////////////////////////////////////////////////////// +/// Class CViewProductDialogBase +/////////////////////////////////////////////////////////////////////////////// +class CViewProductDialogBase : public wxFrame +{ +private: + +protected: + wxHtmlWindow* m_htmlWinReviews; + wxScrolledWindow* m_scrolledWindow; + wxRichTextCtrl* m_richTextHeading; + wxStaticText* m_staticTextInstructions; + wxButton* m_buttonSubmitForm; + wxButton* m_buttonCancelForm; + wxButton* m_buttonBack; + wxButton* m_buttonNext; + wxButton* m_buttonCancel; + + // Virtual event handlers, overide them in your derived class + virtual void OnButtonSubmitForm(wxCommandEvent& event){ event.Skip(); } + virtual void OnButtonCancelForm(wxCommandEvent& event){ event.Skip(); } + virtual void OnButtonBack(wxCommandEvent& event){ event.Skip(); } + virtual void OnButtonNext(wxCommandEvent& event){ event.Skip(); } + virtual void OnButtonCancel(wxCommandEvent& event){ event.Skip(); } + + +public: + CViewProductDialogBase(wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxT("Order Form"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize(630,520), long style = wxDEFAULT_FRAME_STYLE|wxRESIZE_BORDER|wxTAB_TRAVERSAL); + ~CViewProductDialogBase(); + +}; + +/////////////////////////////////////////////////////////////////////////////// +/// Class CViewOrderDialogBase +/////////////////////////////////////////////////////////////////////////////// +class CViewOrderDialogBase : public wxFrame +{ +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: + CViewOrderDialogBase(wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxT("View Order"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize(630,520), long style = wxDEFAULT_FRAME_STYLE|wxRESIZE_BORDER|wxTAB_TRAVERSAL); + ~CViewOrderDialogBase(); + +}; + +/////////////////////////////////////////////////////////////////////////////// +/// Class CEditReviewDialogBase +/////////////////////////////////////////////////////////////////////////////// +class CEditReviewDialogBase : public wxFrame +{ +private: + +protected: + + wxStaticText* m_staticTextSeller; + + wxStaticText* m_staticText110; + wxChoice* m_choiceStars; + wxStaticText* m_staticText43; + wxTextCtrl* m_textCtrlReview; + wxButton* m_buttonSubmit; + wxButton* m_buttonCancel; + + // Virtual event handlers, overide them in your derived class + virtual void OnKeyDown(wxKeyEvent& event){ event.Skip(); } + virtual void OnButtonSubmit(wxCommandEvent& event){ event.Skip(); } + virtual void OnButtonCancel(wxCommandEvent& event){ event.Skip(); } + + +public: + CEditReviewDialogBase(wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxT("Enter Review"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize(630,440), long style = wxDEFAULT_FRAME_STYLE|wxRESIZE_BORDER|wxTAB_TRAVERSAL); + ~CEditReviewDialogBase(); + +}; + +/////////////////////////////////////////////////////////////////////////////// +/// Class CPokerLobbyDialogBase +/////////////////////////////////////////////////////////////////////////////// +class CPokerLobbyDialogBase : public wxFrame +{ +private: + +protected: + wxTreeCtrl* m_treeCtrl; + wxListCtrl* m_listCtrl; + wxButton* m_buttonNewTable; + + // Virtual event handlers, overide them in your derived class + virtual void OnTreeSelChanged(wxTreeEvent& event){ event.Skip(); } + virtual void OnListItemActivated(wxListEvent& event){ event.Skip(); } + virtual void OnListItemSelected(wxListEvent& event){ event.Skip(); } + virtual void OnButtonNewTable(wxCommandEvent& event){ event.Skip(); } + + +public: + CPokerLobbyDialogBase(wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxT("Poker Lobby"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize(586,457), long style = wxDEFAULT_FRAME_STYLE|wxTAB_TRAVERSAL); + ~CPokerLobbyDialogBase(); + +}; + +/////////////////////////////////////////////////////////////////////////////// +/// Class CPokerDialogBase +/////////////////////////////////////////////////////////////////////////////// +class CPokerDialogBase : public wxFrame +{ +private: + +protected: + wxButton* m_buttonDealHand; + wxButton* m_buttonFold; + wxButton* m_buttonCall; + wxButton* m_buttonRaise; + wxButton* m_buttonLeaveTable; + wxTextCtrl* m_textDitchPlayer; + + // Virtual event handlers, overide them in your derived class + virtual void OnClose(wxCloseEvent& event){ event.Skip(); } + virtual void OnMouseEvents(wxMouseEvent& event){ event.Skip(); } + virtual void OnPaint(wxPaintEvent& event){ event.Skip(); } + virtual void OnSize(wxSizeEvent& event){ event.Skip(); } + virtual void OnCheckSitOut(wxCommandEvent& event){ event.Skip(); } + virtual void OnButtonDealHand(wxCommandEvent& event){ event.Skip(); } + virtual void OnButtonFold(wxCommandEvent& event){ event.Skip(); } + virtual void OnButtonCall(wxCommandEvent& event){ event.Skip(); } + virtual void OnButtonRaise(wxCommandEvent& event){ event.Skip(); } + virtual void OnButtonLeaveTable(wxCommandEvent& event){ event.Skip(); } + virtual void OnDitchPlayer(wxCommandEvent& event){ event.Skip(); } + virtual void OnCheckPreFold(wxCommandEvent& event){ event.Skip(); } + virtual void OnCheckPreCall(wxCommandEvent& event){ event.Skip(); } + virtual void OnCheckPreCallAny(wxCommandEvent& event){ event.Skip(); } + virtual void OnCheckPreRaise(wxCommandEvent& event){ event.Skip(); } + virtual void OnCheckPreRaiseAny(wxCommandEvent& event){ event.Skip(); } + + +public: + wxCheckBox* m_checkSitOut; + wxCheckBox* m_checkPreFold; + wxCheckBox* m_checkPreCall; + wxCheckBox* m_checkPreCallAny; + wxCheckBox* m_checkPreRaise; + wxCheckBox* m_checkPreRaiseAny; + wxStatusBar* m_statusBar; + CPokerDialogBase(wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxT("Poker"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize(806,550), long style = wxDEFAULT_FRAME_STYLE|wxFRAME_NO_TASKBAR|wxFULL_REPAINT_ON_RESIZE|wxTAB_TRAVERSAL); + ~CPokerDialogBase(); + +}; + +/////////////////////////////////////////////////////////////////////////////// +/// 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(403,138), long style = wxDEFAULT_DIALOG_STYLE); + ~CGetTextFromUserDialogBase(); + +}; + +#endif //__uibase__ diff --git a/uint256.h b/uint256.h new file mode 100644 index 0000000000..9a0c770497 --- /dev/null +++ b/uint256.h @@ -0,0 +1,750 @@ +// Copyright (c) 2009 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 +#include +#if defined(_MSC_VER) || defined(__BORLANDC__) +typedef __int64 int64; +typedef unsigned __int64 uint64; +#else +typedef long long int64; +typedef unsigned long long uint64; +#endif +#if defined(_MSC_VER) && _MSC_VER < 1300 +#define for if (false) ; else for +#endif + + +inline int Testuint256AdHoc(vector vArg); + + + +// We have to keep a separate base class without constructors +// so the compiler will let us use it in a union +template +class base_uint +{ +protected: + enum { WIDTH=BITS/32 }; + unsigned int pn[WIDTH]; +public: + + bool operator!() const + { + for (int i = 0; i < WIDTH; i++) + if (pn[i] != 0) + return false; + return true; + } + + const base_uint operator~() const + { + base_uint ret; + for (int i = 0; i < WIDTH; i++) + ret.pn[i] = ~pn[i]; + return ret; + } + + const base_uint operator-() const + { + base_uint ret; + for (int i = 0; i < WIDTH; i++) + ret.pn[i] = ~pn[i]; + ret++; + return ret; + } + + + base_uint& operator=(uint64 b) + { + pn[0] = (unsigned int)b; + pn[1] = (unsigned int)(b >> 32); + for (int i = 2; i < WIDTH; i++) + pn[i] = 0; + return *this; + } + + base_uint& operator^=(const base_uint& b) + { + for (int i = 0; i < WIDTH; i++) + pn[i] ^= b.pn[i]; + return *this; + } + + base_uint& operator&=(const base_uint& b) + { + for (int i = 0; i < WIDTH; i++) + pn[i] &= b.pn[i]; + return *this; + } + + base_uint& operator|=(const base_uint& b) + { + for (int i = 0; i < WIDTH; i++) + pn[i] |= b.pn[i]; + return *this; + } + + base_uint& operator^=(uint64 b) + { + pn[0] ^= (unsigned int)b; + pn[1] ^= (unsigned int)(b >> 32); + return *this; + } + + base_uint& operator&=(uint64 b) + { + pn[0] &= (unsigned int)b; + pn[1] &= (unsigned int)(b >> 32); + return *this; + } + + base_uint& operator|=(uint64 b) + { + pn[0] |= (unsigned int)b; + pn[1] |= (unsigned int)(b >> 32); + return *this; + } + + base_uint& operator<<=(unsigned int shift) + { + base_uint a(*this); + for (int i = 0; i < WIDTH; i++) + pn[i] = 0; + int k = shift / 32; + shift = shift % 32; + for (int i = 0; i < WIDTH; i++) + { + if (i+k+1 < WIDTH && shift != 0) + pn[i+k+1] |= (a.pn[i] >> (32-shift)); + if (i+k < WIDTH) + pn[i+k] |= (a.pn[i] << shift); + } + return *this; + } + + base_uint& operator>>=(unsigned int shift) + { + base_uint a(*this); + for (int i = 0; i < WIDTH; i++) + pn[i] = 0; + int k = shift / 32; + shift = shift % 32; + for (int i = 0; i < WIDTH; i++) + { + if (i-k-1 >= 0 && shift != 0) + pn[i-k-1] |= (a.pn[i] << (32-shift)); + if (i-k >= 0) + pn[i-k] |= (a.pn[i] >> shift); + } + return *this; + } + + base_uint& operator+=(const base_uint& b) + { + uint64 carry = 0; + for (int i = 0; i < WIDTH; i++) + { + uint64 n = carry + pn[i] + b.pn[i]; + pn[i] = n & 0xffffffff; + carry = n >> 32; + } + return *this; + } + + base_uint& operator-=(const base_uint& b) + { + *this += -b; + return *this; + } + + base_uint& operator+=(uint64 b64) + { + base_uint b; + b = b64; + *this += b; + return *this; + } + + base_uint& operator-=(uint64 b64) + { + base_uint b; + b = b64; + *this += -b; + return *this; + } + + + base_uint& operator++() + { + // prefix operator + int i = 0; + while (++pn[i] == 0 && i < WIDTH-1) + i++; + return *this; + } + + const base_uint operator++(int) + { + // postfix operator + const base_uint ret = *this; + ++(*this); + return ret; + } + + base_uint& operator--() + { + // prefix operator + int i = 0; + while (--pn[i] == -1 && i < WIDTH-1) + i++; + return *this; + } + + const base_uint operator--(int) + { + // postfix operator + const base_uint ret = *this; + --(*this); + return ret; + } + + + friend inline bool operator<(const base_uint& a, const base_uint& b) + { + for (int i = base_uint::WIDTH-1; i >= 0; i--) + { + if (a.pn[i] < b.pn[i]) + return true; + else if (a.pn[i] > b.pn[i]) + return false; + } + return false; + } + + friend inline bool operator<=(const base_uint& a, const base_uint& b) + { + for (int i = base_uint::WIDTH-1; i >= 0; i--) + { + if (a.pn[i] < b.pn[i]) + return true; + else if (a.pn[i] > b.pn[i]) + return false; + } + return true; + } + + friend inline bool operator>(const base_uint& a, const base_uint& b) + { + for (int i = base_uint::WIDTH-1; i >= 0; i--) + { + if (a.pn[i] > b.pn[i]) + return true; + else if (a.pn[i] < b.pn[i]) + return false; + } + return false; + } + + friend inline bool operator>=(const base_uint& a, const base_uint& b) + { + for (int i = base_uint::WIDTH-1; i >= 0; i--) + { + if (a.pn[i] > b.pn[i]) + return true; + else if (a.pn[i] < b.pn[i]) + return false; + } + return true; + } + + friend inline bool operator==(const base_uint& a, const base_uint& b) + { + for (int i = 0; i < base_uint::WIDTH; i++) + if (a.pn[i] != b.pn[i]) + return false; + return true; + } + + friend inline bool operator==(const base_uint& a, uint64 b) + { + if (a.pn[0] != (unsigned int)b) + return false; + if (a.pn[1] != (unsigned int)(b >> 32)) + return false; + for (int i = 2; i < base_uint::WIDTH; i++) + if (a.pn[i] != 0) + return false; + return true; + } + + friend inline bool operator!=(const base_uint& a, const base_uint& b) + { + return (!(a == b)); + } + + friend inline bool operator!=(const base_uint& a, uint64 b) + { + return (!(a == b)); + } + + + + std::string GetHex() const + { + char psz[sizeof(pn)*2 + 1]; + for (int i = 0; i < sizeof(pn); i++) + sprintf(psz + i*2, "%02x", ((unsigned char*)pn)[sizeof(pn) - i - 1]); + return string(psz, psz + sizeof(pn)*2); + } + + void SetHex(const std::string& str) + { + for (int i = 0; i < WIDTH; i++) + pn[i] = 0; + + // skip 0x + const char* psz = str.c_str(); + while (isspace(*psz)) + psz++; + if (psz[0] == '0' && tolower(psz[1]) == 'x') + psz += 2; + while (isspace(*psz)) + psz++; + + // hex string to uint + static char phexdigit[256] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,1,2,3,4,5,6,7,8,9,0,0,0,0,0,0, 0,0xa,0xb,0xc,0xd,0xe,0xf,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0xa,0xb,0xc,0xd,0xe,0xf,0,0,0,0,0,0,0,0,0 }; + const char* pbegin = psz; + while (phexdigit[*psz] || *psz == '0') + psz++; + psz--; + unsigned char* p1 = (unsigned char*)pn; + unsigned char* pend = p1 + WIDTH * 4; + while (psz >= pbegin && p1 < pend) + { + *p1 = phexdigit[(unsigned char)*psz--]; + if (psz >= pbegin) + { + *p1 |= (phexdigit[(unsigned char)*psz--] << 4); + p1++; + } + } + } + + std::string ToString() const + { + return (GetHex()); + } + + unsigned char* begin() + { + return (unsigned char*)&pn[0]; + } + + unsigned char* end() + { + return (unsigned char*)&pn[WIDTH]; + } + + unsigned int size() + { + return sizeof(pn); + } + + + unsigned int GetSerializeSize(int nType=0, int nVersion=VERSION) const + { + return sizeof(pn); + } + + template + void Serialize(Stream& s, int nType=0, int nVersion=VERSION) const + { + s.write((char*)pn, sizeof(pn)); + } + + template + void Unserialize(Stream& s, int nType=0, int nVersion=VERSION) + { + s.read((char*)pn, sizeof(pn)); + } + + + friend class uint160; + friend class uint256; + friend inline int Testuint256AdHoc(vector vArg); +}; + +typedef base_uint<160> base_uint160; +typedef base_uint<256> base_uint256; + + + +// +// uint160 and uint256 could be implemented as templates, but to keep +// compile errors and debugging cleaner, they're copy and pasted. +// It's safe to search and replace 160 with 256 and vice versa. +// + + + +////////////////////////////////////////////////////////////////////////////// +// +// uint160 +// + +class uint160 : public base_uint160 +{ +public: + typedef base_uint160 basetype; + + uint160() + { + } + + uint160(const basetype& b) + { + for (int i = 0; i < WIDTH; i++) + pn[i] = b.pn[i]; + } + + uint160& operator=(const basetype& b) + { + for (int i = 0; i < WIDTH; i++) + pn[i] = b.pn[i]; + return *this; + } + + uint160(uint64 b) + { + pn[0] = (unsigned int)b; + pn[1] = (unsigned int)(b >> 32); + for (int i = 2; i < WIDTH; i++) + pn[i] = 0; + } + + uint160& operator=(uint64 b) + { + pn[0] = (unsigned int)b; + pn[1] = (unsigned int)(b >> 32); + for (int i = 2; i < WIDTH; i++) + pn[i] = 0; + return *this; + } + + explicit uint160(const std::string& str) + { + SetHex(str); + } + + explicit uint160(const std::vector& vch) + { + if (vch.size() == sizeof(pn)) + memcpy(pn, &vch[0], sizeof(pn)); + else + *this = 0; + } +}; + +inline bool operator==(const uint160& a, uint64 b) { return (base_uint160)a == b; } +inline bool operator!=(const uint160& a, uint64 b) { return (base_uint160)a != b; } +inline const uint160 operator<<(const base_uint160& a, unsigned int shift) { return uint160(a) <<= shift; } +inline const uint160 operator>>(const base_uint160& a, unsigned int shift) { return uint160(a) >>= shift; } +inline const uint160 operator<<(const uint160& a, unsigned int shift) { return uint160(a) <<= shift; } +inline const uint160 operator>>(const uint160& a, unsigned int shift) { return uint160(a) >>= shift; } + +inline const uint160 operator^(const base_uint160& a, const base_uint160& b) { return uint160(a) ^= b; } +inline const uint160 operator&(const base_uint160& a, const base_uint160& b) { return uint160(a) &= b; } +inline const uint160 operator|(const base_uint160& a, const base_uint160& b) { return uint160(a) |= b; } +inline const uint160 operator+(const base_uint160& a, const base_uint160& b) { return uint160(a) += b; } +inline const uint160 operator-(const base_uint160& a, const base_uint160& b) { return uint160(a) -= b; } + +inline bool operator<(const base_uint160& a, const uint160& b) { return (base_uint160)a < (base_uint160)b; } +inline bool operator<=(const base_uint160& a, const uint160& b) { return (base_uint160)a <= (base_uint160)b; } +inline bool operator>(const base_uint160& a, const uint160& b) { return (base_uint160)a > (base_uint160)b; } +inline bool operator>=(const base_uint160& a, const uint160& b) { return (base_uint160)a >= (base_uint160)b; } +inline bool operator==(const base_uint160& a, const uint160& b) { return (base_uint160)a == (base_uint160)b; } +inline bool operator!=(const base_uint160& a, const uint160& b) { return (base_uint160)a != (base_uint160)b; } +inline const uint160 operator^(const base_uint160& a, const uint160& b) { return (base_uint160)a ^ (base_uint160)b; } +inline const uint160 operator&(const base_uint160& a, const uint160& b) { return (base_uint160)a & (base_uint160)b; } +inline const uint160 operator|(const base_uint160& a, const uint160& b) { return (base_uint160)a | (base_uint160)b; } +inline const uint160 operator+(const base_uint160& a, const uint160& b) { return (base_uint160)a + (base_uint160)b; } +inline const uint160 operator-(const base_uint160& a, const uint160& b) { return (base_uint160)a - (base_uint160)b; } + +inline bool operator<(const uint160& a, const base_uint160& b) { return (base_uint160)a < (base_uint160)b; } +inline bool operator<=(const uint160& a, const base_uint160& b) { return (base_uint160)a <= (base_uint160)b; } +inline bool operator>(const uint160& a, const base_uint160& b) { return (base_uint160)a > (base_uint160)b; } +inline bool operator>=(const uint160& a, const base_uint160& b) { return (base_uint160)a >= (base_uint160)b; } +inline bool operator==(const uint160& a, const base_uint160& b) { return (base_uint160)a == (base_uint160)b; } +inline bool operator!=(const uint160& a, const base_uint160& b) { return (base_uint160)a != (base_uint160)b; } +inline const uint160 operator^(const uint160& a, const base_uint160& b) { return (base_uint160)a ^ (base_uint160)b; } +inline const uint160 operator&(const uint160& a, const base_uint160& b) { return (base_uint160)a & (base_uint160)b; } +inline const uint160 operator|(const uint160& a, const base_uint160& b) { return (base_uint160)a | (base_uint160)b; } +inline const uint160 operator+(const uint160& a, const base_uint160& b) { return (base_uint160)a + (base_uint160)b; } +inline const uint160 operator-(const uint160& a, const base_uint160& b) { return (base_uint160)a - (base_uint160)b; } + +inline bool operator<(const uint160& a, const uint160& b) { return (base_uint160)a < (base_uint160)b; } +inline bool operator<=(const uint160& a, const uint160& b) { return (base_uint160)a <= (base_uint160)b; } +inline bool operator>(const uint160& a, const uint160& b) { return (base_uint160)a > (base_uint160)b; } +inline bool operator>=(const uint160& a, const uint160& b) { return (base_uint160)a >= (base_uint160)b; } +inline bool operator==(const uint160& a, const uint160& b) { return (base_uint160)a == (base_uint160)b; } +inline bool operator!=(const uint160& a, const uint160& b) { return (base_uint160)a != (base_uint160)b; } +inline const uint160 operator^(const uint160& a, const uint160& b) { return (base_uint160)a ^ (base_uint160)b; } +inline const uint160 operator&(const uint160& a, const uint160& b) { return (base_uint160)a & (base_uint160)b; } +inline const uint160 operator|(const uint160& a, const uint160& b) { return (base_uint160)a | (base_uint160)b; } +inline const uint160 operator+(const uint160& a, const uint160& b) { return (base_uint160)a + (base_uint160)b; } +inline const uint160 operator-(const uint160& a, const uint160& b) { return (base_uint160)a - (base_uint160)b; } + + + + + + +////////////////////////////////////////////////////////////////////////////// +// +// uint256 +// + +class uint256 : public base_uint256 +{ +public: + typedef base_uint256 basetype; + + uint256() + { + } + + uint256(const basetype& b) + { + for (int i = 0; i < WIDTH; i++) + pn[i] = b.pn[i]; + } + + uint256& operator=(const basetype& b) + { + for (int i = 0; i < WIDTH; i++) + pn[i] = b.pn[i]; + return *this; + } + + uint256(uint64 b) + { + pn[0] = (unsigned int)b; + pn[1] = (unsigned int)(b >> 32); + for (int i = 2; i < WIDTH; i++) + pn[i] = 0; + } + + uint256& operator=(uint64 b) + { + pn[0] = (unsigned int)b; + pn[1] = (unsigned int)(b >> 32); + for (int i = 2; i < WIDTH; i++) + pn[i] = 0; + return *this; + } + + explicit uint256(const std::string& str) + { + SetHex(str); + } + + explicit uint256(const std::vector& vch) + { + if (vch.size() == sizeof(pn)) + memcpy(pn, &vch[0], sizeof(pn)); + else + *this = 0; + } +}; + +inline bool operator==(const uint256& a, uint64 b) { return (base_uint256)a == b; } +inline bool operator!=(const uint256& a, uint64 b) { return (base_uint256)a != b; } +inline const uint256 operator<<(const base_uint256& a, unsigned int shift) { return uint256(a) <<= shift; } +inline const uint256 operator>>(const base_uint256& a, unsigned int shift) { return uint256(a) >>= shift; } +inline const uint256 operator<<(const uint256& a, unsigned int shift) { return uint256(a) <<= shift; } +inline const uint256 operator>>(const uint256& a, unsigned int shift) { return uint256(a) >>= shift; } + +inline const uint256 operator^(const base_uint256& a, const base_uint256& b) { return uint256(a) ^= b; } +inline const uint256 operator&(const base_uint256& a, const base_uint256& b) { return uint256(a) &= b; } +inline const uint256 operator|(const base_uint256& a, const base_uint256& b) { return uint256(a) |= b; } +inline const uint256 operator+(const base_uint256& a, const base_uint256& b) { return uint256(a) += b; } +inline const uint256 operator-(const base_uint256& a, const base_uint256& b) { return uint256(a) -= b; } + +inline bool operator<(const base_uint256& a, const uint256& b) { return (base_uint256)a < (base_uint256)b; } +inline bool operator<=(const base_uint256& a, const uint256& b) { return (base_uint256)a <= (base_uint256)b; } +inline bool operator>(const base_uint256& a, const uint256& b) { return (base_uint256)a > (base_uint256)b; } +inline bool operator>=(const base_uint256& a, const uint256& b) { return (base_uint256)a >= (base_uint256)b; } +inline bool operator==(const base_uint256& a, const uint256& b) { return (base_uint256)a == (base_uint256)b; } +inline bool operator!=(const base_uint256& a, const uint256& b) { return (base_uint256)a != (base_uint256)b; } +inline const uint256 operator^(const base_uint256& a, const uint256& b) { return (base_uint256)a ^ (base_uint256)b; } +inline const uint256 operator&(const base_uint256& a, const uint256& b) { return (base_uint256)a & (base_uint256)b; } +inline const uint256 operator|(const base_uint256& a, const uint256& b) { return (base_uint256)a | (base_uint256)b; } +inline const uint256 operator+(const base_uint256& a, const uint256& b) { return (base_uint256)a + (base_uint256)b; } +inline const uint256 operator-(const base_uint256& a, const uint256& b) { return (base_uint256)a - (base_uint256)b; } + +inline bool operator<(const uint256& a, const base_uint256& b) { return (base_uint256)a < (base_uint256)b; } +inline bool operator<=(const uint256& a, const base_uint256& b) { return (base_uint256)a <= (base_uint256)b; } +inline bool operator>(const uint256& a, const base_uint256& b) { return (base_uint256)a > (base_uint256)b; } +inline bool operator>=(const uint256& a, const base_uint256& b) { return (base_uint256)a >= (base_uint256)b; } +inline bool operator==(const uint256& a, const base_uint256& b) { return (base_uint256)a == (base_uint256)b; } +inline bool operator!=(const uint256& a, const base_uint256& b) { return (base_uint256)a != (base_uint256)b; } +inline const uint256 operator^(const uint256& a, const base_uint256& b) { return (base_uint256)a ^ (base_uint256)b; } +inline const uint256 operator&(const uint256& a, const base_uint256& b) { return (base_uint256)a & (base_uint256)b; } +inline const uint256 operator|(const uint256& a, const base_uint256& b) { return (base_uint256)a | (base_uint256)b; } +inline const uint256 operator+(const uint256& a, const base_uint256& b) { return (base_uint256)a + (base_uint256)b; } +inline const uint256 operator-(const uint256& a, const base_uint256& b) { return (base_uint256)a - (base_uint256)b; } + +inline bool operator<(const uint256& a, const uint256& b) { return (base_uint256)a < (base_uint256)b; } +inline bool operator<=(const uint256& a, const uint256& b) { return (base_uint256)a <= (base_uint256)b; } +inline bool operator>(const uint256& a, const uint256& b) { return (base_uint256)a > (base_uint256)b; } +inline bool operator>=(const uint256& a, const uint256& b) { return (base_uint256)a >= (base_uint256)b; } +inline bool operator==(const uint256& a, const uint256& b) { return (base_uint256)a == (base_uint256)b; } +inline bool operator!=(const uint256& a, const uint256& b) { return (base_uint256)a != (base_uint256)b; } +inline const uint256 operator^(const uint256& a, const uint256& b) { return (base_uint256)a ^ (base_uint256)b; } +inline const uint256 operator&(const uint256& a, const uint256& b) { return (base_uint256)a & (base_uint256)b; } +inline const uint256 operator|(const uint256& a, const uint256& b) { return (base_uint256)a | (base_uint256)b; } +inline const uint256 operator+(const uint256& a, const uint256& b) { return (base_uint256)a + (base_uint256)b; } +inline const uint256 operator-(const uint256& a, const uint256& b) { return (base_uint256)a - (base_uint256)b; } + + + + + + + + + + + + +inline int Testuint256AdHoc(vector vArg) +{ + uint256 g(0); + + + printf("%s\n", g.ToString().c_str()); + g--; printf("g--\n"); + printf("%s\n", g.ToString().c_str()); + g--; printf("g--\n"); + printf("%s\n", g.ToString().c_str()); + g++; printf("g++\n"); + printf("%s\n", g.ToString().c_str()); + g++; printf("g++\n"); + printf("%s\n", g.ToString().c_str()); + g++; printf("g++\n"); + printf("%s\n", g.ToString().c_str()); + g++; printf("g++\n"); + printf("%s\n", g.ToString().c_str()); + + + + uint256 a(7); + printf("a=7\n"); + printf("%s\n", a.ToString().c_str()); + + uint256 b; + printf("b undefined\n"); + printf("%s\n", b.ToString().c_str()); + int c = 3; + + a = c; + a.pn[3] = 15; + printf("%s\n", a.ToString().c_str()); + uint256 k(c); + + a = 5; + a.pn[3] = 15; + printf("%s\n", a.ToString().c_str()); + b = 1; + b <<= 52; + + a |= b; + + a ^= 0x500; + + printf("a %s\n", a.ToString().c_str()); + + a = a | b | (uint256)0x1000; + + + printf("a %s\n", a.ToString().c_str()); + printf("b %s\n", b.ToString().c_str()); + + a = 0xfffffffe; + a.pn[4] = 9; + + printf("%s\n", a.ToString().c_str()); + a++; + printf("%s\n", a.ToString().c_str()); + a++; + printf("%s\n", a.ToString().c_str()); + a++; + printf("%s\n", a.ToString().c_str()); + a++; + printf("%s\n", a.ToString().c_str()); + + a--; + printf("%s\n", a.ToString().c_str()); + a--; + printf("%s\n", a.ToString().c_str()); + a--; + printf("%s\n", a.ToString().c_str()); + uint256 d = a--; + printf("%s\n", d.ToString().c_str()); + printf("%s\n", a.ToString().c_str()); + a--; + printf("%s\n", a.ToString().c_str()); + a--; + printf("%s\n", a.ToString().c_str()); + + d = a; + + printf("%s\n", d.ToString().c_str()); + for (int i = uint256::WIDTH-1; i >= 0; i--) printf("%08x", d.pn[i]); printf("\n"); + + uint256 neg = d; + neg = ~neg; + printf("%s\n", neg.ToString().c_str()); + + + uint256 e = uint256("0xABCDEF123abcdef12345678909832180000011111111"); + printf("\n"); + printf("%s\n", e.ToString().c_str()); + + + printf("\n"); + uint256 x1 = uint256("0xABCDEF123abcdef12345678909832180000011111111"); + uint256 x2; + printf("%s\n", x1.ToString().c_str()); + for (int i = 0; i < 270; i += 4) + { + x2 = x1 << i; + printf("%s\n", x2.ToString().c_str()); + } + + printf("\n"); + printf("%s\n", x1.ToString().c_str()); + for (int i = 0; i < 270; i += 4) + { + x2 = x1; + x2 >>= i; + printf("%s\n", x2.ToString().c_str()); + } + + + for (int i = 0; i < 100; i++) + { + uint256 k = (~uint256(0) >> i); + printf("%s\n", k.ToString().c_str()); + } + + for (int i = 0; i < 100; i++) + { + uint256 k = (~uint256(0) << i); + printf("%s\n", k.ToString().c_str()); + } + + return (0); +} diff --git a/uiproject.fbp b/uiproject.fbp new file mode 100644 index 0000000000..49b1fefaaf --- /dev/null +++ b/uiproject.fbp @@ -0,0 +1,11860 @@ + + + + + + C++ + 1 + UTF-8 + connect + uibase + 1000 + none + 0 + + + . + + 1 + 0 + 0 + + wxSYS_COLOUR_BTNFACE + + + 1 + + + + 0 + wxID_MAINFRAME + + + CMainFrameBase + + 705,484 + wxDEFAULT_FRAME_STYLE|wxRESIZE_BORDER + + Bitcoin + + + + wxTAB_TRAVERSAL + 1 + + + + OnClose + + + + + OnIdle + + + + + + + + + + + + OnMouseEvents + + OnPaint + + + + + + + + 240,240,240 + + 1 + + + 0 + wxID_ANY + MyMenuBar + + + m_menubar + protected + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + &File + m_menuFile + protected + + + 0 + 1 + + wxID_ANY + wxITEM_NORMAL + E&xit + m_menuFileExit + none + + + OnMenuFileExit + + + + + &Options + m_menuOptions + public + + + 0 + 1 + + wxID_OPTIONSGENERATEBITCOINS + wxITEM_CHECK + &Generate Coins + m_menuOptionsGenerateBitcoins + none + + + OnMenuOptionsGenerate + + + + + 0 + 1 + + wxID_ANY + wxITEM_NORMAL + &Change Your Address... + m_menuChangeYourAddress + none + + + OnMenuOptionsChangeYourAddress + + + + + 0 + 1 + + wxID_ANY + wxITEM_NORMAL + &Options... + m_menuOptionsOptions + none + + + OnMenuOptionsOptions + + + + + &Help + m_menuHelp + protected + + + 0 + 1 + + wxID_ANY + wxITEM_NORMAL + &About... + m_menuHelpAbout + none + + + OnMenuHelpAbout + + + + + + + 20,20 + + 1 + + ,90,90,-1,70,0 + 0 + wxID_ANY + + + + m_toolBar + 1 + protected + + 1 + -1,-1 + wxTB_FLAT|wxTB_HORZ_TEXT + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + send20; Load From Resource + wxID_BUTTONSEND + wxITEM_NORMAL + &Send Coins + m_tool1 + + + + OnButtonSend + + + + + + addressbook20; Load From Resource + wxID_BUTTONRECEIVE + wxITEM_NORMAL + &Address Book + m_tool2 + + + + OnButtonAddressBook + + + + + + + 240,240,240 + + 1 + + 1 + + 0 + wxID_ANY + + + m_statusBar + protected + + + wxST_SIZEGRIP + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + bSizer2 + wxVERTICAL + none + + 5 + wxEXPAND + 0 + + 2 + protected + 0 + + + + 5 + wxEXPAND|wxRIGHT|wxLEFT + 0 + + + bSizer85 + wxHORIZONTAL + none + + 5 + wxALIGN_CENTER_VERTICAL|wxLEFT + 0 + + + + 1 + + + 0 + wxID_ANY + Your Bitcoin Address: + + + m_staticText32 + protected + + + + + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT + 0 + + wxSYS_COLOUR_MENU + + 1 + + + 0 + wxID_TEXTCTRLADDRESS + -1,-1 + 0 + -1,-1 + m_textCtrlAddress + protected + + 250,-1 + wxTE_READONLY + + + + + + + + + + OnKeyDown + + + + + + + + + + + OnMouseEventsAddress + + + + + + OnSetFocusAddress + + + + + + + + + + 5 + wxALIGN_CENTER_VERTICAL|wxRIGHT + 0 + + + + 0 + 1 + + + 0 + wxID_BUTTONCOPY + &Copy to Clipboard + + + m_buttonCopy + protected + + + wxBU_EXACTFIT + + + + + + OnButtonCopy + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxRIGHT + 0 + + + + 0 + 1 + + + 1 + wxID_BUTTONCHANGE + C&hange... + + + m_button91 + protected + + + + + + + + + OnButtonChange + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND + 0 + + 0 + protected + 0 + + + + + + 5 + wxEXPAND + 0 + + + bSizer3 + wxHORIZONTAL + none + + 5 + wxEXPAND|wxALIGN_BOTTOM|wxALL + 1 + + + + 1 + + + 0 + wxID_ANY + + + m_panel14 + protected + + + + + + + wxTAB_TRAVERSAL + + + + + + + + + + + + + + + + + + + + + + + + + + bSizer66 + wxHORIZONTAL + none + + 5 + wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxLEFT + 0 + + + + 1 + + + 0 + wxID_ANY + Balance: + + + m_staticText41 + protected + + -1,15 + + + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALIGN_CENTER_VERTICAL|wxALL + 0 + + wxSYS_COLOUR_WINDOW + + 1 + + ,90,90,8,70,0 + 0 + wxID_ANY + + + + m_staticTextBalance + protected + + 120,15 + wxALIGN_RIGHT|wxST_NO_AUTORESIZE + + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND + 0 + + 0 + protected + 0 + + + + 5 + wxALIGN_BOTTOM|wxTOP|wxRIGHT|wxLEFT + 0 + + + " All" " Sent" " Received" " In Progress" + + 1 + + + 1 + wxID_ANY + + + m_choiceFilter + protected + + 0 + 110,-1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND + 1 + + + + + 1 + + + 0 + wxID_ANY + + + m_notebook + protected + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + All Transactions + 0 + + + + 1 + + + 0 + wxID_ANY + + + m_panel7 + protected + + + + + + + wxTAB_TRAVERSAL + + + + + + + + + + + + + + + + + + + + + + + + + + bSizer157 + wxVERTICAL + none + + 5 + wxEXPAND|wxALL + 1 + + + + 1 + + + 0 + wxID_ANY + + + m_listCtrl + public + + + wxLC_NO_SORT_HEADER|wxLC_REPORT|wxLC_SORT_DESCENDING + + + + + wxALWAYS_SHOW_SB + + + + + + + + + + + + + + + OnListColBeginDrag + + + + + + + + + OnListItemActivatedAllTransactions + + + + + + + + + + + + + OnPaintListCtrl + + + + + + + + + + + + + + + 5 + wxEXPAND + 1 + + + bSizer_TabsForFutureUse + wxVERTICAL + none + + 5 + wxEXPAND | wxALL + 1 + + + + 1 + + + 1 + wxID_ANY + + + m_panel9 + protected + + + + + + + wxTAB_TRAVERSAL + + + + + + + + + + + + + + + + + + + + + + + + + + bSizer159 + wxVERTICAL + none + + 5 + wxALL|wxEXPAND + 1 + + + + 1 + + + 0 + wxID_ANY + + + m_listCtrlEscrows + public + + + wxLC_NO_SORT_HEADER|wxLC_REPORT + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND | wxALL + 1 + + + + 1 + + + 1 + wxID_ANY + + + m_panel8 + protected + + + + + + + wxTAB_TRAVERSAL + + + + + + + + + + + + + + + + + + + + + + + + + + bSizer158 + wxVERTICAL + none + + 5 + wxALL|wxEXPAND + 1 + + + + 1 + + + 0 + wxID_ANY + + + m_listCtrlOrdersSent + public + + + wxLC_NO_SORT_HEADER|wxLC_REPORT + + + + + + + + + + + + + + + + + + + + + + + + + + + + + OnListItemActivatedOrdersSent + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND | wxALL + 1 + + + + 1 + + + 1 + wxID_ANY + + + m_panel10 + protected + + + + + + + wxTAB_TRAVERSAL + + + + + + + + + + + + + + + + + + + + + + + + + + bSizer160 + wxVERTICAL + none + + 5 + wxALL|wxEXPAND + 1 + + + + 1 + + + 0 + wxID_ANY + + + m_listCtrlProductsSent + public + + + wxLC_NO_SORT_HEADER|wxLC_REPORT + + + + + + + + + + + + + + + + + + + + + + + + + + + + + OnListItemActivatedProductsSent + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND | wxALL + 1 + + + + 1 + + + 1 + wxID_ANY + + + m_panel11 + protected + + + + + + + wxTAB_TRAVERSAL + + + + + + + + + + + + + + + + + + + + + + + + + + bSizer161 + wxVERTICAL + none + + 5 + wxALL|wxEXPAND + 1 + + + + 1 + + + 0 + wxID_ANY + + + m_listCtrlOrdersReceived + public + + + wxLC_NO_SORT_HEADER|wxLC_REPORT + + + + + + + + + + + + + + + + + + + + + + + + + + + + + OnListItemActivatedOrdersReceived + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1 + + + + 0 + wxID_ANY + + + CTxDetailsDialogBase + + 620,450 + wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER + + Transaction Details + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + bSizer64 + wxVERTICAL + none + + 5 + wxEXPAND + 1 + + + bSizer66 + wxVERTICAL + none + + 5 + wxALL|wxEXPAND + 1 + + + + 1 + + + 0 + wxID_ANY + + + m_htmlWin + protected + + + wxHW_SCROLLBAR_AUTO + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALIGN_RIGHT + 0 + + + bSizer65 + wxVERTICAL + none + + 5 + wxALL + 0 + + + + 0 + 1 + + + 0 + wxID_OK + OK + + + m_buttonOK + protected + + 85,25 + + + + + + + OnButtonOK + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1 + + + + 0 + wxID_ANY + + + COptionsDialogBase + + 500,261 + wxDEFAULT_DIALOG_STYLE + + Options + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + bSizer55 + wxVERTICAL + none + + 5 + wxEXPAND|wxLEFT + 1 + + + bSizer57 + wxVERTICAL + none + + 5 + wxEXPAND + 0 + + 20 + protected + 0 + + + + 5 + wxALIGN_CENTER_VERTICAL|wxALL + 0 + + + + 1 + + + 0 + wxID_ANY + Optional transaction fee you give to the nodes that process your transactions. + + + m_staticText32 + protected + + + + + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND + 0 + + + bSizer56 + wxHORIZONTAL + none + + 5 + wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxLEFT + 0 + + + + 1 + + + 0 + wxID_ANY + Transaction fee: + + + m_staticText31 + protected + + + + + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL|wxALIGN_CENTER_VERTICAL + 0 + + + + 1 + + + 0 + wxID_TRANSACTIONFEE + + 0 + + m_textCtrlTransactionFee + protected + + 70,-1 + + + + + + + + + + + + + OnKillFocusTransactionFee + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALIGN_RIGHT + 0 + + + bSizer58 + wxHORIZONTAL + none + + 5 + wxALL + 0 + + + + 0 + 1 + + + 0 + wxID_OK + OK + + + m_buttonOK + protected + + 85,25 + + + + + + + OnButtonOK + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL + 0 + + + + 0 + 1 + + + 0 + wxID_CANCEL + Cancel + + 85,25 + m_buttonCancel + protected + + -1,-1 + + + + + + + OnButtonCancel + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1 + + + + 0 + wxID_ANY + + + CAboutDialogBase + + 507,298 + wxDEFAULT_DIALOG_STYLE + + About Bitcoin + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + bSizer60 + wxVERTICAL + none + + 5 + wxEXPAND + 1 + + + bSizer62 + wxHORIZONTAL + none + + 5 + wxEXPAND + 0 + + 0 + protected + 60 + + + + 5 + wxEXPAND + 1 + + + bSizer63 + wxVERTICAL + none + + 5 + wxEXPAND + 0 + + 50 + protected + 0 + + + + 5 + wxEXPAND + 0 + + + bSizer64 + wxHORIZONTAL + none + + 5 + wxALIGN_BOTTOM|wxTOP|wxBOTTOM|wxLEFT + 0 + + + + 1 + + Tahoma,90,92,10,74,0 + 0 + wxID_ANY + Bitcoin + + + m_staticText40 + protected + + + + + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALIGN_BOTTOM|wxTOP|wxBOTTOM|wxRIGHT + 0 + + + + 1 + + Tahoma,90,90,10,74,0 + 0 + wxID_ANY + version + + + m_staticTextVersion + public + + + + + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND + 0 + + 4 + protected + 0 + + + + 5 + wxALL + 0 + + + + 1 + + + 0 + wxID_ANY + Copyright © 2009 Satoshi Nakamoto. This is experimental software. Do not rely on it for actual financial transactions. 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). + + + m_staticTextMain + protected + + + + + + + + + 400 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND + 1 + + 0 + protected + 0 + + + + + + + + 5 + wxALIGN_RIGHT|wxEXPAND + 0 + + + bSizer61 + wxHORIZONTAL + none + + 5 + wxEXPAND + 1 + + 0 + protected + 0 + + + + 5 + wxALL + 0 + + + + 0 + 1 + + + 0 + wxID_OK + OK + + + m_buttonOK + protected + + 85,25 + + + + + + + OnButtonOK + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1 + + + + 0 + wxID_ANY + + + CSendDialogBase + + 675,312 + wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER + + Send Coins + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + bSizer21 + wxVERTICAL + none + + 5 + wxEXPAND + 0 + + 5 + protected + 0 + + + + 5 + wxEXPAND|wxLEFT + 0 + + 2 + wxBOTH + 1 + + 0 + + fgSizer1 + wxFLEX_GROWMODE_SPECIFIED + none + 3 + 0 + + 5 + wxEXPAND + 0 + + 0 + protected + 0 + + + + 5 + wxTOP|wxRIGHT|wxLEFT + 0 + + + + 1 + + + 0 + wxID_ANY + Enter the recipient's IP address (e.g. 123.45.6.7) for online transfer with comments and confirmation, or Bitcoin address (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJED9L) if recipient is not online. + + + m_staticText14 + protected + + + + + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND|wxLEFT + 1 + + 70,-1 + bSizer47 + wxHORIZONTAL + none + + 5 + wxEXPAND + 1 + + 0 + protected + 0 + + + + 5 + wxALL|wxALIGN_CENTER_VERTICAL + 0 + + + check; Load From Icon Resource [-1; -1] + + 1 + + + 0 + wxID_ANY + + + m_bitmapCheckMark + protected + + 16,16 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxLEFT + 0 + + + + 1 + + + 0 + wxID_ANY + Pay &To: + + + m_staticText36 + protected + + -1,-1 + wxALIGN_RIGHT + + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND|wxRIGHT + 1 + + + bSizer19 + wxHORIZONTAL + none + + 5 + wxALIGN_CENTER_VERTICAL|wxALL + 1 + + + + 1 + + + 0 + wxID_TEXTCTRLPAYTO + + 0 + + m_textCtrlAddress + protected + + + + + + + + + + + + + OnKeyDown + + + + + + + + + + + + + + + + + + + OnTextAddress + + + + + + + + 5 + wxALIGN_CENTER_VERTICAL|wxRIGHT + 0 + + + + 0 + 1 + + + 0 + wxID_BUTTONPASTE + &Paste + + + m_buttonPaste + protected + + -1,-1 + wxBU_EXACTFIT + + + + + + OnButtonPaste + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALIGN_CENTER_VERTICAL|wxRIGHT + 0 + + + + 0 + 1 + + + 0 + wxID_BUTTONADDRESSBOOK + Address &Book... + + + m_buttonAddress + protected + + + + + + + + + OnButtonAddressBook + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxLEFT|wxALIGN_RIGHT + 0 + + + + 1 + + + 0 + wxID_ANY + &Amount: + + + m_staticText19 + protected + + -1,-1 + wxALIGN_RIGHT + + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALIGN_CENTER_VERTICAL|wxALL + 0 + + + + 1 + + ,90,90,-1,70,0 + 0 + wxID_TEXTCTRLAMOUNT + + 20 + + m_textCtrlAmount + protected + + 145,-1 + + + + + + + + + + + OnKeyDown + + OnKillFocusAmount + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxTOP|wxBOTTOM|wxLEFT + 0 + + + + 1 + + + 1 + wxID_ANY + T&ransfer: + + + m_staticText20 + protected + + -1,-1 + wxALIGN_RIGHT + + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALIGN_CENTER_VERTICAL|wxALL + 0 + + + " Standard" + + 1 + + + 1 + wxID_CHOICETRANSFERTYPE + + + m_choiceTransferType + protected + + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND + 0 + + 3 + protected + 0 + + + + 5 + wxEXPAND + 0 + + 0 + protected + 0 + + + + + + 5 + wxEXPAND + 0 + + + bSizer672 + wxHORIZONTAL + none + + 5 + wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT + 1 + + + bSizer681 + wxVERTICAL + none + + 5 + wxBOTTOM|wxLEFT + 0 + + + + 1 + + + 0 + wxID_ANY + &From: + + + m_staticTextFrom + protected + + + + + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxLEFT|wxEXPAND + 0 + + + + 1 + + + 0 + wxID_ANY + + 0 + + m_textCtrlFrom + protected + + -1,-1 + + + + + + + + + + + OnKeyDown + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND + 1 + + + bSizer67 + wxHORIZONTAL + none + + 5 + wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT + 1 + + + bSizer68 + wxVERTICAL + none + + 5 + wxTOP|wxBOTTOM|wxLEFT + 0 + + + + 1 + + + 0 + wxID_ANY + &Message: + + + m_staticTextMessage + protected + + + + + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND|wxLEFT + 1 + + + + 1 + + + 0 + wxID_ANY + + 0 + + m_textCtrlMessage + protected + + + wxTE_MULTILINE + + + + + + + + + + OnKeyDown + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND + 0 + + + bSizer23 + wxHORIZONTAL + none + + 5 + wxEXPAND + 1 + + 0 + protected + 0 + + + + 5 + wxALL + 0 + + + + 0 + 1 + + ,90,90,-1,70,0 + 0 + wxID_BUTTONSEND + &Send + + 85,25 + m_buttonSend + protected + + -1,-1 + + + + + + + OnButtonSend + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL + 0 + + + + 0 + 1 + + + 0 + wxID_CANCEL + Cancel + + 85,25 + m_buttonCancel + protected + + -1,-1 + + + + + + + OnButtonCancel + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1 + + + + 0 + wxID_ANY + + + CSendingDialogBase + + 442,151 + wxDEFAULT_DIALOG_STYLE + + Sending... + + + + + + + + OnClose + + + + + + + + + + + + + + + + + + + + OnPaint + + + + + + + + + bSizer68 + wxVERTICAL + none + + 8 + wxALIGN_CENTER_VERTICAL|wxEXPAND|wxTOP|wxRIGHT|wxLEFT + 0 + + + + 1 + + + 0 + wxID_ANY + + + + m_staticTextSending + protected + + -1,14 + + + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + 10 + wxEXPAND|wxRIGHT|wxLEFT + 1 + + wxSYS_COLOUR_BTNFACE + + 1 + + + 0 + wxID_ANY + + 0 + + m_textCtrlStatus + protected + + + wxTE_CENTRE|wxTE_MULTILINE|wxTE_NO_VSCROLL|wxTE_READONLY + + + Connecting... + + + wxNO_BORDER + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND + 0 + + + bSizer69 + wxHORIZONTAL + none + + 5 + wxEXPAND + 1 + + 0 + protected + 0 + + + + 5 + wxALL + 0 + + + + 0 + 0 + + + 0 + wxID_ANY + OK + + 85,25 + m_buttonOK + protected + + + + + + + + + OnButtonOK + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL + 0 + + + + 0 + 1 + + + 0 + wxID_CANCEL + Cancel + + 85,25 + m_buttonCancel + protected + + -1,-1 + + + + + + + OnButtonCancel + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1 + + + + 0 + wxID_ANY + + + CYourAddressDialogBase + + 610,390 + wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER + + Your Bitcoin Addresses + + + + + + + + OnClose + + + + + + + + + + + + + + + + + + + + + + + + + + + + + bSizer68 + wxVERTICAL + none + + 5 + wxEXPAND + 0 + + 5 + protected + 0 + + + + 5 + wxALL + 0 + + + + 1 + + + 0 + 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. + + + m_staticText45 + protected + + + + + + + + + 590 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL|wxEXPAND + 1 + + + + 1 + + + 0 + wxID_LISTCTRL + + + m_listCtrl + protected + + + wxLC_NO_SORT_HEADER|wxLC_REPORT|wxLC_SORT_ASCENDING + + + + + + + + + + + + + + + + + + + + + + + + + + + OnListEndLabelEdit + + OnListItemActivated + + + + + OnListItemSelected + + + + + + + + + + + + + + + + + + 5 + wxEXPAND + 0 + + + bSizer69 + wxHORIZONTAL + none + + 5 + wxEXPAND + 1 + + 0 + protected + 0 + + + + 5 + wxALL + 0 + + + + 0 + 1 + + + 0 + wxID_BUTTONRENAME + &Edit... + + 85,25 + m_buttonRename + protected + + + + + + + + + OnButtonRename + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL + 0 + + + + 0 + 1 + + + 0 + wxID_BUTTONNEW + &New Address... + + 110,25 + m_buttonNew + protected + + -1,-1 + + + + + + + OnButtonNew + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL + 0 + + + + 0 + 1 + + + 0 + wxID_BUTTONCOPY + &Copy to Clipboard + + 120,25 + m_buttonCopy + protected + + -1,-1 + + + + + + + OnButtonCopy + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL + 0 + + + + 0 + 1 + + + 0 + wxID_OK + OK + + 85,25 + m_buttonOK + protected + + + + + + + + + OnButtonOK + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL + 0 + + + + 0 + 1 + + + 1 + wxID_CANCEL + Cancel + + 85,25 + m_buttonCancel + protected + + -1,-1 + + + + + + + OnButtonCancel + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1 + + + + 0 + wxID_ANY + + + CAddressBookDialogBase + + 610,390 + wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER + + Address Book + + + + + + + + OnClose + + + + + + + + + + + + + + + + + + + + + + + + + + + + + bSizer68 + wxVERTICAL + none + + 5 + wxEXPAND + 0 + + 5 + protected + 0 + + + + 5 + wxTOP|wxRIGHT|wxLEFT + 0 + + + + 1 + + + 1 + wxID_ANY + Bitcoin Address + + + m_staticText55 + protected + + + + + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL|wxEXPAND + 1 + + + + 1 + + + 0 + wxID_LISTCTRL + + + m_listCtrl + protected + + + wxLC_NO_SORT_HEADER|wxLC_REPORT|wxLC_SORT_ASCENDING + + + + + + + + + + + + + + + + + + + + + + + + + + + OnListEndLabelEdit + + OnListItemActivated + + + + + OnListItemSelected + + + + + + + + + + + + + + + + + + 5 + wxEXPAND + 0 + + + bSizer69 + wxHORIZONTAL + none + + 5 + wxEXPAND + 1 + + 0 + protected + 0 + + + + 5 + wxALL + 0 + + + + 0 + 1 + + + 0 + wxID_BUTTONEDIT + &Edit... + + 85,25 + m_buttonEdit + protected + + + + + + + + + OnButtonEdit + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL + 0 + + + + 0 + 1 + + + 0 + wxID_BUTTONNEW + &New Address... + + 110,25 + m_buttonNew + protected + + + + + + + + + OnButtonNew + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL + 0 + + + + 0 + 1 + + + 0 + wxID_BUTTONDELETE + &Delete + + 85,25 + m_buttonDelete + protected + + + + + + + + + OnButtonDelete + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL + 0 + + + + 0 + 1 + + + 0 + wxID_OK + OK + + 85,25 + m_buttonOK + protected + + -1,-1 + + + + + + + OnButtonOK + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL + 0 + + + + 0 + 1 + + + 0 + wxID_CANCEL + Cancel + + 85,25 + m_buttonCancel + public + + -1,-1 + + + + + + + OnButtonCancel + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1 + + + + 0 + wxID_ANY + + + CProductsDialogBase + + 708,535 + wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER + + Marketplace + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + bSizer22 + wxVERTICAL + none + + 5 + wxEXPAND|wxTOP|wxBOTTOM|wxRIGHT + 0 + + + bSizer23 + wxHORIZONTAL + none + + 5 + wxALL|wxALIGN_CENTER_VERTICAL + 0 + + + "(Any Category)" + + 1 + + + 0 + wxID_ANY + + + m_comboBoxCategory + protected + + 150,-1 + + + + (Any Category) + + + + + OnCombobox + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL|wxALIGN_CENTER_VERTICAL + 1 + + + + 1 + + + 0 + wxID_ANY + + 0 + + m_textCtrlSearch + protected + + + + + + + + + + + + + OnKeyDown + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL|wxALIGN_CENTER_VERTICAL + 0 + + + + 0 + 1 + + + 0 + wxID_ANY + &Search + + + m_buttonSearch + protected + + + + + + + + + OnButtonSearch + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL|wxEXPAND + 1 + + + + 1 + + + 0 + wxID_ANY + + + m_listCtrl + protected + + + wxLC_NO_SORT_HEADER|wxLC_REPORT + + + + + + + + + + + + + + + + + + + + + + + + + + + + + OnListItemActivated + + + + + + + + + + + + + + + + + + + + + + + + + wxSYS_COLOUR_MENU + + + 1 + + + + 0 + wxID_ANY + + + CEditProductDialogBase + + 660,640 + wxDEFAULT_FRAME_STYLE|wxRESIZE_BORDER + + Edit Product + + + + wxTAB_TRAVERSAL + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + bSizer20 + wxVERTICAL + none + + 5 + wxEXPAND|wxALL + 1 + + wxSYS_COLOUR_WINDOW + + 1 + + + 0 + wxID_ANY + + + m_scrolledWindow + protected + + 5 + 5 + + + + + + wxHSCROLL|wxTAB_TRAVERSAL|wxVSCROLL + + + + + + + + + + + + + + + + + + + + + + + + + + bSizer21 + wxVERTICAL + none + + 5 + wxEXPAND|wxTOP|wxRIGHT|wxLEFT + 0 + + 2 + wxBOTH + 1 + + 0 + + fgSizer8 + wxFLEX_GROWMODE_SPECIFIED + none + 0 + 0 + + 5 + wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxTOP|wxBOTTOM|wxLEFT + 0 + + + + 1 + + + 0 + wxID_ANY + Category + + + m_staticText106 + protected + + + wxALIGN_RIGHT + + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL|wxALIGN_CENTER_VERTICAL + 0 + + + + + 1 + + + 0 + wxID_ANY + + 180,-1 + m_comboBoxCategory + protected + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxTOP|wxBOTTOM|wxLEFT + 0 + + + + 1 + + + 0 + wxID_ANY + Title + + + m_staticText108 + protected + + + wxALIGN_RIGHT + + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND + 1 + + + + 1 + + + 0 + wxID_ANY + + 0 + + m_textCtrlTitle + protected + + + + + + + + + + + + + OnKeyDown + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxTOP|wxBOTTOM|wxLEFT + 0 + + + + 1 + + + 0 + wxID_ANY + Price + + + m_staticText107 + protected + + + wxALIGN_RIGHT + + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL|wxALIGN_CENTER_VERTICAL + 0 + + + + 1 + + + 0 + wxID_ANY + + 0 + 105,-1 + m_textCtrlPrice + protected + + + + + + + + + + + + + OnKeyDown + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxTOP|wxRIGHT|wxLEFT + 0 + + + + 1 + + + 0 + wxID_ANY + Page 1: Description + + + m_staticText22 + protected + + + + + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL|wxEXPAND + 0 + + + + 1 + + + 0 + wxID_ANY + + 0 + -1,170 + m_textCtrlDescription + protected + + + wxTE_MULTILINE + + + + + + + + + + OnKeyDown + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxTOP|wxRIGHT|wxLEFT + 0 + + + + 1 + + + 0 + wxID_ANY + Page 2: Order Form + + + m_staticText23 + protected + + + + + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND|wxALL + 0 + + + + 1 + + + 0 + wxID_ANY + + 0 + -1,120 + m_textCtrlInstructions + protected + + + wxTE_MULTILINE + + + + + + + + + + OnKeyDown + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND + 0 + + 3 + wxBOTH + 1 + + 0 + + fgSizer5 + wxFLEX_GROWMODE_SPECIFIED + public + 0 + 0 + + 5 + wxALIGN_CENTER_VERTICAL|wxTOP|wxRIGHT|wxLEFT + 0 + + + + 1 + + + 0 + wxID_ANY + Label + + + m_staticText24 + protected + + + + + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALIGN_CENTER_VERTICAL|wxTOP|wxRIGHT|wxLEFT + 0 + + + + 1 + + + 0 + wxID_ANY + Comma separated list of choices, or leave blank for text field + + + m_staticText25 + protected + + + + + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND + 1 + + 0 + protected + 0 + + + + 5 + wxALL|wxALIGN_CENTER_VERTICAL + 0 + + + + 1 + + + 0 + wxID_ANY + + 0 + 150,-1 + m_textCtrlLabel0 + protected + + + + + + + + + + + + + OnKeyDown + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL + 0 + + + + 1 + + + 0 + wxID_ANY + -1,-1 + 0 + -1,-1 + m_textCtrlField0 + protected + + -1,-1 + + + + + + + + + + + OnKeyDown + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxRIGHT|wxLEFT|wxALIGN_CENTER_VERTICAL + 0 + + + + 0 + 1 + + + 0 + wxID_DEL0 + Delete + + -1,-1 + m_buttonDel0 + protected + + 60,20 + + + + + + + OnButtonDel0 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL|wxALIGN_CENTER_VERTICAL + 0 + + + + 1 + + + 0 + wxID_ANY + + 0 + 150,-1 + m_textCtrlLabel1 + protected + + + + + + + + + + + + + OnKeyDown + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL + 0 + + + + 1 + + + 0 + wxID_ANY + -1,-1 + 0 + -1,-1 + m_textCtrlField1 + protected + + -1,-1 + + + + + + + + + + + OnKeyDown + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT + 0 + + + + 0 + 1 + + + 0 + wxID_DEL1 + Delete + + -1,-1 + m_buttonDel1 + protected + + 60,20 + + + + + + + OnButtonDel1 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL|wxALIGN_CENTER_VERTICAL + 0 + + + + 1 + + + 0 + wxID_ANY + + 0 + 150,-1 + m_textCtrlLabel2 + protected + + + + + + + + + + + + + OnKeyDown + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL + 0 + + + + 1 + + + 0 + wxID_ANY + -1,-1 + 0 + -1,-1 + m_textCtrlField2 + protected + + -1,-1 + + + + + + + + + + + OnKeyDown + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT + 0 + + + + 0 + 1 + + + 0 + wxID_DEL2 + Delete + + -1,-1 + m_buttonDel2 + protected + + 60,20 + + + + + + + OnButtonDel2 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL|wxALIGN_CENTER_VERTICAL + 0 + + + + 1 + + + 0 + wxID_ANY + + 0 + 150,-1 + m_textCtrlLabel3 + protected + + + + + + + + + + + + + OnKeyDown + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL + 0 + + + + 1 + + + 0 + wxID_ANY + -1,-1 + 0 + -1,-1 + m_textCtrlField3 + protected + + -1,-1 + + + + + + + + + + + OnKeyDown + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT + 0 + + + + 0 + 1 + + + 0 + wxID_DEL3 + Delete + + -1,-1 + m_buttonDel3 + protected + + 60,20 + + + + + + + OnButtonDel3 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL|wxALIGN_CENTER_VERTICAL + 0 + + + + 1 + + + 0 + wxID_ANY + + 0 + 150,-1 + m_textCtrlLabel4 + protected + + + + + + + + + + + + + OnKeyDown + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL + 0 + + + + 1 + + + 0 + wxID_ANY + -1,-1 + 0 + -1,-1 + m_textCtrlField4 + protected + + -1,-1 + + + + + + + + + + + OnKeyDown + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT + 0 + + + + 0 + 1 + + + 0 + wxID_DEL4 + Delete + + -1,-1 + m_buttonDel4 + protected + + 60,20 + + + + + + + OnButtonDel4 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL|wxALIGN_CENTER_VERTICAL + 0 + + + + 1 + + + 0 + wxID_ANY + + 0 + 150,-1 + m_textCtrlLabel5 + protected + + + + + + + + + + + + + OnKeyDown + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL + 0 + + + + 1 + + + 0 + wxID_ANY + -1,-1 + 0 + -1,-1 + m_textCtrlField5 + protected + + -1,-1 + + + + + + + + + + + OnKeyDown + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT + 0 + + + + 0 + 1 + + + 0 + wxID_DEL5 + Delete + + -1,-1 + m_buttonDel5 + protected + + 60,20 + + + + + + + OnButtonDel5 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL|wxALIGN_CENTER_VERTICAL + 0 + + + + 1 + + + 0 + wxID_ANY + + 0 + 150,-1 + m_textCtrlLabel6 + protected + + + + + + + + + + + + + OnKeyDown + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL + 0 + + + + 1 + + + 0 + wxID_ANY + -1,-1 + 0 + -1,-1 + m_textCtrlField6 + protected + + -1,-1 + + + + + + + + + + + OnKeyDown + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT + 0 + + + + 0 + 1 + + + 0 + wxID_DEL6 + Delete + + -1,-1 + m_buttonDel6 + protected + + 60,20 + + + + + + + OnButtonDel6 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL|wxALIGN_CENTER_VERTICAL + 0 + + + + 1 + + + 0 + wxID_ANY + + 0 + 150,-1 + m_textCtrlLabel7 + protected + + + + + + + + + + + + + OnKeyDown + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL + 0 + + + + 1 + + + 0 + wxID_ANY + -1,-1 + 0 + -1,-1 + m_textCtrlField7 + protected + + -1,-1 + + + + + + + + + + + OnKeyDown + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT + 0 + + + + 0 + 1 + + + 0 + wxID_DEL7 + Delete + + -1,-1 + m_buttonDel7 + protected + + 60,20 + + + + + + + OnButtonDel7 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL|wxALIGN_CENTER_VERTICAL + 0 + + + + 1 + + + 0 + wxID_ANY + + 0 + 150,-1 + m_textCtrlLabel8 + protected + + + + + + + + + + + + + OnKeyDown + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL + 0 + + + + 1 + + + 0 + wxID_ANY + -1,-1 + 0 + -1,-1 + m_textCtrlField8 + protected + + -1,-1 + + + + + + + + + + + OnKeyDown + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT + 0 + + + + 0 + 1 + + + 0 + wxID_DEL8 + Delete + + -1,-1 + m_buttonDel8 + protected + + 60,20 + + + + + + + OnButtonDel8 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL|wxALIGN_CENTER_VERTICAL + 0 + + + + 1 + + + 0 + wxID_ANY + + 0 + 150,-1 + m_textCtrlLabel9 + protected + + + + + + + + + + + + + OnKeyDown + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL + 0 + + + + 1 + + + 0 + wxID_ANY + -1,-1 + 0 + -1,-1 + m_textCtrlField9 + protected + + -1,-1 + + + + + + + + + + + OnKeyDown + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT + 0 + + + + 0 + 1 + + + 0 + wxID_DEL9 + Delete + + -1,-1 + m_buttonDel9 + protected + + 60,20 + + + + + + + OnButtonDel9 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL|wxALIGN_CENTER_VERTICAL + 0 + + + + 1 + + + 0 + wxID_ANY + + 0 + 150,-1 + m_textCtrlLabel10 + protected + + + + + + + + + + + + + OnKeyDown + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL + 0 + + + + 1 + + + 0 + wxID_ANY + -1,-1 + 0 + -1,-1 + m_textCtrlField10 + protected + + -1,-1 + + + + + + + + + + + OnKeyDown + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT + 0 + + + + 0 + 1 + + + 0 + wxID_DEL10 + Delete + + -1,-1 + m_buttonDel10 + protected + + 60,20 + + + + + + + OnButtonDel10 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL|wxALIGN_CENTER_VERTICAL + 0 + + + + 1 + + + 0 + wxID_ANY + + 0 + 150,-1 + m_textCtrlLabel11 + protected + + + + + + + + + + + + + OnKeyDown + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL + 0 + + + + 1 + + + 0 + wxID_ANY + -1,-1 + 0 + -1,-1 + m_textCtrlField11 + protected + + -1,-1 + + + + + + + + + + + OnKeyDown + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT + 0 + + + + 0 + 1 + + + 0 + wxID_DEL11 + Delete + + -1,-1 + m_buttonDel11 + protected + + 60,20 + + + + + + + OnButtonDel11 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL|wxALIGN_CENTER_VERTICAL + 0 + + + + 1 + + + 0 + wxID_ANY + + 0 + 150,-1 + m_textCtrlLabel12 + protected + + + + + + + + + + + + + OnKeyDown + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL + 0 + + + + 1 + + + 0 + wxID_ANY + -1,-1 + 0 + -1,-1 + m_textCtrlField12 + protected + + -1,-1 + + + + + + + + + + + OnKeyDown + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT + 0 + + + + 0 + 1 + + + 0 + wxID_DEL12 + Delete + + -1,-1 + m_buttonDel12 + protected + + 60,20 + + + + + + + OnButtonDel12 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL|wxALIGN_CENTER_VERTICAL + 0 + + + + 1 + + + 0 + wxID_ANY + + 0 + 150,-1 + m_textCtrlLabel13 + protected + + + + + + + + + + + + + OnKeyDown + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL + 0 + + + + 1 + + + 0 + wxID_ANY + -1,-1 + 0 + -1,-1 + m_textCtrlField13 + protected + + -1,-1 + + + + + + + + + + + OnKeyDown + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT + 0 + + + + 0 + 1 + + + 0 + wxID_DEL13 + Delete + + -1,-1 + m_buttonDel13 + protected + + 60,20 + + + + + + + OnButtonDel13 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL|wxALIGN_CENTER_VERTICAL + 0 + + + + 1 + + + 0 + wxID_ANY + + 0 + 150,-1 + m_textCtrlLabel14 + protected + + + + + + + + + + + + + OnKeyDown + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL + 0 + + + + 1 + + + 0 + wxID_ANY + -1,-1 + 0 + -1,-1 + m_textCtrlField14 + protected + + -1,-1 + + + + + + + + + + + OnKeyDown + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT + 0 + + + + 0 + 1 + + + 0 + wxID_DEL14 + Delete + + -1,-1 + m_buttonDel14 + protected + + 60,20 + + + + + + + OnButtonDel14 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL|wxALIGN_CENTER_VERTICAL + 0 + + + + 1 + + + 0 + wxID_ANY + + 0 + 150,-1 + m_textCtrlLabel15 + protected + + + + + + + + + + + + + OnKeyDown + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL + 0 + + + + 1 + + + 0 + wxID_ANY + -1,-1 + 0 + -1,-1 + m_textCtrlField15 + protected + + -1,-1 + + + + + + + + + + + OnKeyDown + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT + 0 + + + + 0 + 1 + + + 0 + wxID_DEL15 + Delete + + -1,-1 + m_buttonDel15 + protected + + 60,20 + + + + + + + OnButtonDel15 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL|wxALIGN_CENTER_VERTICAL + 0 + + + + 1 + + + 0 + wxID_ANY + + 0 + 150,-1 + m_textCtrlLabel16 + protected + + + + + + + + + + + + + OnKeyDown + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL + 0 + + + + 1 + + + 0 + wxID_ANY + -1,-1 + 0 + -1,-1 + m_textCtrlField16 + protected + + -1,-1 + + + + + + + + + + + OnKeyDown + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT + 0 + + + + 0 + 1 + + + 0 + wxID_DEL16 + Delete + + -1,-1 + m_buttonDel16 + protected + + 60,20 + + + + + + + OnButtonDel16 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL|wxALIGN_CENTER_VERTICAL + 0 + + + + 1 + + + 0 + wxID_ANY + + 0 + 150,-1 + m_textCtrlLabel17 + protected + + + + + + + + + + + + + OnKeyDown + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL + 0 + + + + 1 + + + 0 + wxID_ANY + -1,-1 + 0 + -1,-1 + m_textCtrlField17 + protected + + -1,-1 + + + + + + + + + + + OnKeyDown + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT + 0 + + + + 0 + 1 + + + 0 + wxID_DEL17 + Delete + + -1,-1 + m_buttonDel17 + protected + + 60,20 + + + + + + + OnButtonDel17 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL|wxALIGN_CENTER_VERTICAL + 0 + + + + 1 + + + 0 + wxID_ANY + + 0 + 150,-1 + m_textCtrlLabel18 + protected + + + + + + + + + + + + + OnKeyDown + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL + 0 + + + + 1 + + + 0 + wxID_ANY + -1,-1 + 0 + -1,-1 + m_textCtrlField18 + protected + + -1,-1 + + + + + + + + + + + OnKeyDown + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT + 0 + + + + 0 + 1 + + + 0 + wxID_DEL18 + Delete + + -1,-1 + m_buttonDel18 + protected + + 60,20 + + + + + + + OnButtonDel18 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL|wxALIGN_CENTER_VERTICAL + 0 + + + + 1 + + + 0 + wxID_ANY + + 0 + 150,-1 + m_textCtrlLabel19 + protected + + + + + + + + + + + + + OnKeyDown + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL + 0 + + + + 1 + + + 0 + wxID_ANY + -1,-1 + 0 + -1,-1 + m_textCtrlField19 + protected + + -1,-1 + + + + + + + + + + + OnKeyDown + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT + 0 + + + + 0 + 1 + + + 0 + wxID_DEL19 + Delete + + -1,-1 + m_buttonDel19 + protected + + 60,20 + + + + + + + OnButtonDel19 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALIGN_CENTER_HORIZONTAL + 0 + + + bSizer25 + wxHORIZONTAL + none + + 5 + wxALL + 0 + + + + 0 + 1 + + + 0 + wxID_ANY + &Add Field + + + m_buttonAddField + protected + + + + + + + + + OnButtonAddField + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALIGN_RIGHT + 0 + + + bSizer26 + wxHORIZONTAL + none + + 5 + wxALL + 0 + + + + 0 + 1 + + + 0 + wxID_BUTTONSEND + &Send + + 85,25 + m_buttonOK + protected + + + + + + + + + OnButtonSend + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL + 0 + + + + 0 + 1 + + + 0 + wxID_BUTTONPREVIEW + &Preview + + 85,25 + m_buttonPreview + protected + + + + + + + + + OnButtonPreview + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL + 0 + + + + 0 + 1 + + + 0 + wxID_CANCEL + Cancel + + 85,25 + m_buttonCancel + protected + + + + + + + + + OnButtonCancel + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + wxSYS_COLOUR_MENU + + + 1 + + + + 0 + wxID_ANY + + + CViewProductDialogBase + + 630,520 + wxDEFAULT_FRAME_STYLE|wxRESIZE_BORDER + + Order Form + + + + wxTAB_TRAVERSAL + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + bSizer20 + wxVERTICAL + none + + 5 + wxEXPAND + 1 + + + bSizer116 + wxHORIZONTAL + none + + 5 + wxALL|wxEXPAND + 1 + + + + 1 + + + 1 + wxID_ANY + + + m_htmlWinReviews + protected + + + wxHW_SCROLLBAR_AUTO + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND|wxALL + 1 + + wxSYS_COLOUR_WINDOW + + 1 + + + 0 + wxID_ANY + + + m_scrolledWindow + protected + + 5 + 5 + + + + + + wxHSCROLL|wxTAB_TRAVERSAL|wxVSCROLL + + + + + + + + + + + + + + + + + + + + + + + + + + bSizer21 + wxVERTICAL + none + + 5 + wxEXPAND + 0 + + + + 1 + + + 0 + wxID_ANY + + -1,-1 + m_richTextHeading + protected + + -1,50 + wxTE_READONLY + + + + + wxNO_BORDER + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL|wxEXPAND + 0 + + + + 1 + + + 0 + wxID_ANY + Order Form instructions here multiple lines 1 2 3 4 5 6 + + + m_staticTextInstructions + protected + + + + + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALIGN_CENTER_HORIZONTAL + 0 + + + bSizer25 + wxHORIZONTAL + none + + 5 + wxALL + 0 + + + + 0 + 1 + + + 0 + wxID_BUTTONSAMPLE + &Submit + + -1,-1 + m_buttonSubmitForm + protected + + + + + + + + + OnButtonSubmitForm + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL + 0 + + + + 0 + 1 + + + 0 + wxID_CANCEL2 + Cancel + + + m_buttonCancelForm + protected + + + + + + + + + OnButtonCancelForm + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALIGN_RIGHT + 0 + + + bSizer26 + wxHORIZONTAL + none + + 5 + wxALL + 0 + + + + 0 + 0 + + + 0 + wxID_BUTTONBACK + < &Back + + 85,25 + m_buttonBack + protected + + + + + + + + + OnButtonBack + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL + 0 + + + + 0 + 1 + + + 0 + wxID_BUTTONNEXT + &Next > + + 85,25 + m_buttonNext + protected + + + + + + + + + OnButtonNext + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL + 0 + + + + 0 + 1 + + + 0 + wxID_CANCEL + Cancel + + 85,25 + m_buttonCancel + protected + + + + + + + + + OnButtonCancel + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + wxSYS_COLOUR_MENU + + + 1 + + + + 0 + wxID_ANY + + + CViewOrderDialogBase + + 630,520 + wxDEFAULT_FRAME_STYLE|wxRESIZE_BORDER + + View Order + + + + wxTAB_TRAVERSAL + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + bSizer20 + wxVERTICAL + none + + 5 + wxEXPAND + 1 + + + bSizer116 + wxHORIZONTAL + none + + 5 + wxALL|wxEXPAND + 1 + + + + 1 + + + 0 + wxID_ANY + + + m_htmlWin + protected + + + wxHW_SCROLLBAR_AUTO + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALIGN_RIGHT + 0 + + + bSizer26 + wxHORIZONTAL + none + + 5 + wxALL + 0 + + + + 0 + 1 + + + 0 + wxID_OK + OK + + 85,25 + m_buttonOK + protected + + + + + + + + + OnButtonOK + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + wxSYS_COLOUR_MENU + + + 1 + + + + 0 + wxID_ANY + + + CEditReviewDialogBase + + 630,440 + wxDEFAULT_FRAME_STYLE|wxRESIZE_BORDER + + Enter Review + + + + wxTAB_TRAVERSAL + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + bSizer112 + wxVERTICAL + none + + 5 + + 0 + + 3 + protected + 0 + + + + 5 + wxALL|wxEXPAND + 0 + + + + 1 + + + 0 + wxID_ANY + + + + m_staticTextSeller + protected + + + + + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + + 0 + + 3 + protected + 0 + + + + 5 + wxTOP|wxRIGHT|wxLEFT + 0 + + + + 1 + + + 0 + wxID_ANY + Rating + + + m_staticText110 + protected + + + + + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL + 0 + + + " 1 star" " 2 stars" " 3 stars" " 4 stars" " 5 stars" + + 1 + + + 0 + wxID_ANY + + + m_choiceStars + protected + + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxTOP|wxRIGHT|wxLEFT + 0 + + + + 1 + + + 0 + wxID_ANY + Review + + + m_staticText43 + protected + + + + + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL|wxEXPAND + 1 + + + + 1 + + + 0 + wxID_ANY + + 0 + + m_textCtrlReview + protected + + + wxTE_MULTILINE + + + + + + + + + + OnKeyDown + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALIGN_RIGHT + 0 + + + bSizer113 + wxHORIZONTAL + none + + 5 + wxALL + 0 + + + + 0 + 1 + + + 0 + wxID_SUBMIT + &Submit + + 85,25 + m_buttonSubmit + protected + + + + + + + + + OnButtonSubmit + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL + 0 + + + + 0 + 1 + + + 0 + wxID_CANCEL + Cancel + + 85,25 + m_buttonCancel + protected + + + + + + + + + OnButtonCancel + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + wxSYS_COLOUR_BTNFACE + + + 1 + + + + 0 + wxID_ANY + + + CPokerLobbyDialogBase + + 586,457 + wxDEFAULT_FRAME_STYLE + + Poker Lobby + + + + wxTAB_TRAVERSAL + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + bSizer156 + wxHORIZONTAL + none + + 5 + wxEXPAND|wxTOP|wxBOTTOM|wxLEFT + 0 + + + + 1 + + + 0 + wxID_ANY + + 130,-1 + m_treeCtrl + protected + + + wxTR_HAS_BUTTONS|wxTR_HIDE_ROOT|wxTR_LINES_AT_ROOT + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + OnTreeSelChanged + + + + + + + + 5 + wxEXPAND + 1 + + + bSizer172 + wxVERTICAL + none + + 5 + wxEXPAND|wxALL + 1 + + + + 1 + + + 0 + wxID_ANY + + + m_listCtrl + protected + + + wxLC_NO_SORT_HEADER|wxLC_REPORT + + + + + + + + + + + + + + + + + + + + + + + + + + + + + OnListItemActivated + + + + + OnListItemSelected + + + + + + + + + + + + + + + + + + 5 + wxALL + 0 + + + + 0 + 1 + + + 0 + wxID_OPENNEWTABLE + &Open New Table + + + m_buttonNewTable + protected + + + + + + + + + OnButtonNewTable + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1 + + + + 0 + wxID_ANY + + + CPokerDialogBase + + 806,550 + wxDEFAULT_FRAME_STYLE|wxFRAME_NO_TASKBAR + + Poker + + + + wxFULL_REPAINT_ON_RESIZE|wxTAB_TRAVERSAL + 1 + + + + OnClose + + + + + + + + + + + + + + + + + OnMouseEvents + + OnPaint + + + + + OnSize + + + + bSizer174 + wxVERTICAL + none + + 5 + wxALL + 0 + + + 0 + + 1 + + + 0 + wxID_ANY + Deal Me Out + + + m_checkSitOut + public + + + + + + + + + + OnCheckSitOut + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL + 0 + + + + 0 + 1 + + + 0 + wxID_DEALHAND + &Deal Hand + + + m_buttonDealHand + protected + + 150,25 + + + + + + + OnButtonDealHand + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL + 0 + + + + 0 + 1 + + + 0 + wxID_FOLD + &Fold + + + m_buttonFold + protected + + 80,25 + + + + + + + OnButtonFold + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL + 0 + + + + 0 + 1 + + + 0 + wxID_CALL + &Call + + + m_buttonCall + protected + + 80,25 + + + + + + + OnButtonCall + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL + 0 + + + + 0 + 1 + + + 0 + wxID_RAISE + &Raise + + + m_buttonRaise + protected + + 80,25 + + + + + + + OnButtonRaise + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL + 0 + + + + 0 + 1 + + + 0 + wxID_LEAVETABLE + &Leave Table + + + m_buttonLeaveTable + protected + + 90,25 + + + + + + + OnButtonLeaveTable + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL + 0 + + + + 1 + + + 0 + wxID_DITCHPLAYER + + 0 + + m_textDitchPlayer + protected + + 45,-1 + wxTE_PROCESS_ENTER + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + OnDitchPlayer + + + + + + + 5 + wxALL + 0 + + + 0 + + 1 + + + 0 + wxID_ANY + FOLD + + + m_checkPreFold + public + + 100,-1 + + + + + + + + OnCheckPreFold + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL + 0 + + + 0 + + 1 + + + 0 + wxID_ANY + CALL + + + m_checkPreCall + public + + 100,-1 + + + + + + + + OnCheckPreCall + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL + 0 + + + 0 + + 1 + + + 0 + wxID_ANY + CALL ANY + + + m_checkPreCallAny + public + + 100,-1 + + + + + + + + OnCheckPreCallAny + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL + 0 + + + 0 + + 1 + + + 0 + wxID_ANY + RAISE + + + m_checkPreRaise + public + + 100,-1 + + + + + + + + OnCheckPreRaise + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL + 0 + + + 0 + + 1 + + + 0 + wxID_ANY + RAISE ANY + + + m_checkPreRaiseAny + public + + 100,-1 + + + + + + + + OnCheckPreRaiseAny + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1 + + 1 + + 0 + wxID_ANY + + + m_statusBar + public + + + wxST_SIZEGRIP + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1 + + + + 0 + wxID_ANY + + + CGetTextFromUserDialogBase + + 403,138 + wxDEFAULT_DIALOG_STYLE + + + + + + + + + + OnClose + + + + + + + + + + + + + + + + + + + + + + + + + + + + + bSizer79 + wxVERTICAL + none + + 10 + wxEXPAND|wxALL + 1 + + + bSizer81 + wxVERTICAL + none + + 5 + wxEXPAND + 1 + + 0 + protected + 0 + + + + 5 + wxTOP|wxRIGHT|wxLEFT + 0 + + + + 1 + + + 0 + wxID_ANY + + + + m_staticTextMessage1 + protected + + + + + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL|wxEXPAND|wxALIGN_CENTER_HORIZONTAL + 0 + + + + 1 + + + 0 + wxID_TEXTCTRL + + 0 + + m_textCtrl1 + protected + + + wxTE_PROCESS_ENTER + + + + + + + + + + OnKeyDown + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxTOP|wxRIGHT|wxLEFT + 0 + + + + 1 + + + 1 + wxID_ANY + + + + m_staticTextMessage2 + protected + + + + + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL|wxEXPAND|wxALIGN_CENTER_HORIZONTAL + 0 + + + + 1 + + + 1 + wxID_TEXTCTRL + + 0 + + m_textCtrl2 + protected + + + wxTE_PROCESS_ENTER + + + + + + + + + + OnKeyDown + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND + 1 + + 0 + protected + 0 + + + + + + 5 + wxEXPAND + 0 + + + bSizer80 + wxHORIZONTAL + none + + 5 + wxEXPAND + 1 + + 0 + protected + 0 + + + + 5 + wxALL + 0 + + + + 0 + 1 + + + 0 + wxID_OK + OK + + 85,25 + m_buttonOK + protected + + -1,-1 + + + + + + + OnButtonOK + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL + 0 + + + + 0 + 1 + + + 0 + wxID_CANCEL + Cancel + + 85,25 + m_buttonCancel + protected + + + + + + + + + OnButtonCancel + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/util.cpp b/util.cpp new file mode 100644 index 0000000000..9c0ab142e1 --- /dev/null +++ b/util.cpp @@ -0,0 +1,383 @@ +// Copyright (c) 2009 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" + + + +bool fDebug = false; + + + + +// Init openssl library multithreading support +static HANDLE* lock_cs; + +void win32_locking_callback(int mode, int type, const char* file, int line) +{ + if (mode & CRYPTO_LOCK) + WaitForSingleObject(lock_cs[type], INFINITE); + else + ReleaseMutex(lock_cs[type]); +} + +// Init +class CInit +{ +public: + CInit() + { + // Init openssl library multithreading support + lock_cs = (HANDLE*)OPENSSL_malloc(CRYPTO_num_locks() * sizeof(HANDLE)); + for (int i = 0; i < CRYPTO_num_locks(); i++) + lock_cs[i] = CreateMutex(NULL,FALSE,NULL); + CRYPTO_set_locking_callback(win32_locking_callback); + + // Seed random number generator with screen scrape and other hardware sources + RAND_screen(); + + // Seed random number generator with perfmon data + RandAddSeed(true); + } + ~CInit() + { + // Shutdown openssl library multithreading support + CRYPTO_set_locking_callback(NULL); + for (int i =0 ; i < CRYPTO_num_locks(); i++) + CloseHandle(lock_cs[i]); + OPENSSL_free(lock_cs); + } +} +instance_of_cinit; + + + + +void RandAddSeed(bool fPerfmon) +{ + // Seed with CPU performance counter + LARGE_INTEGER PerformanceCount; + QueryPerformanceCounter(&PerformanceCount); + RAND_add(&PerformanceCount, sizeof(PerformanceCount), 1.5); + memset(&PerformanceCount, 0, sizeof(PerformanceCount)); + + static int64 nLastPerfmon; + if (fPerfmon || GetTime() > nLastPerfmon + 5 * 60) + { + nLastPerfmon = GetTime(); + + // Seed with the entire set of perfmon data + unsigned char pdata[250000]; + memset(pdata, 0, sizeof(pdata)); + unsigned long nSize = sizeof(pdata); + long ret = RegQueryValueEx(HKEY_PERFORMANCE_DATA, "Global", NULL, NULL, pdata, &nSize); + RegCloseKey(HKEY_PERFORMANCE_DATA); + if (ret == ERROR_SUCCESS) + { + uint256 hash; + SHA256(pdata, nSize, (unsigned char*)&hash); + RAND_add(&hash, sizeof(hash), min(nSize/500.0, (double)sizeof(hash))); + hash = 0; + memset(pdata, 0, nSize); + + time_t nTime; + time(&nTime); + struct tm* ptmTime = gmtime(&nTime); + char pszTime[200]; + strftime(pszTime, sizeof(pszTime), "%x %H:%M:%S", ptmTime); + printf("%s RandAddSeed() got %d bytes of performance data\n", pszTime, nSize); + } + } +} + + + + + + + + + + +// Safer snprintf +// - prints up to limit-1 characters +// - output string is always null terminated even if limit reached +// - return value is the number of characters actually printed +int my_snprintf(char* buffer, size_t limit, const char* format, ...) +{ + if (limit == 0) + return 0; + va_list arg_ptr; + va_start(arg_ptr, format); + int ret = _vsnprintf(buffer, limit, format, arg_ptr); + va_end(arg_ptr); + if (ret < 0 || ret >= limit) + { + ret = limit - 1; + buffer[limit-1] = 0; + } + return ret; +} + + +string strprintf(const char* format, ...) +{ + char buffer[50000]; + char* p = buffer; + int limit = sizeof(buffer); + int ret; + loop + { + va_list arg_ptr; + va_start(arg_ptr, format); + ret = _vsnprintf(p, limit, format, arg_ptr); + va_end(arg_ptr); + if (ret >= 0 && ret < limit) + break; + if (p != buffer) + delete p; + limit *= 2; + p = new char[limit]; + if (p == NULL) + throw std::bad_alloc(); + } +#ifdef _MSC_VER + // msvc optimisation + if (p == buffer) + return string(p, p+ret); +#endif + string str(p, p+ret); + if (p != buffer) + delete p; + return str; +} + + +bool error(const char* format, ...) +{ + char buffer[50000]; + int limit = sizeof(buffer); + va_list arg_ptr; + va_start(arg_ptr, format); + int ret = _vsnprintf(buffer, limit, format, arg_ptr); + va_end(arg_ptr); + if (ret < 0 || ret >= limit) + { + ret = limit - 1; + buffer[limit-1] = 0; + } + printf("ERROR: %s\n", buffer); + return false; +} + + +void PrintException(std::exception* pex, const char* pszThread) +{ + char pszModule[260]; + pszModule[0] = '\0'; + GetModuleFileName(NULL, pszModule, sizeof(pszModule)); + _strlwr(pszModule); + char pszMessage[1000]; + if (pex) + snprintf(pszMessage, sizeof(pszMessage), + "EXCEPTION: %s \n%s \n%s in %s \n", typeid(*pex).name(), pex->what(), pszModule, pszThread); + else + snprintf(pszMessage, sizeof(pszMessage), + "UNKNOWN EXCEPTION \n%s in %s \n", pszModule, pszThread); + printf("\n\n************************\n%s", pszMessage); + if (wxTheApp) + wxMessageBox(pszMessage, "Error", wxOK | wxICON_ERROR); + throw; + //DebugBreak(); +} + + +void ParseString(const string& str, char c, vector& v) +{ + unsigned int i1 = 0; + unsigned int i2; + do + { + i2 = str.find(c, i1); + v.push_back(str.substr(i1, i2-i1)); + i1 = i2+1; + } + while (i2 != str.npos); +} + + +string FormatMoney(int64 n, bool fPlus) +{ + n /= CENT; + string str = strprintf("%I64d.%02I64d", (n > 0 ? n : -n)/100, (n > 0 ? n : -n)%100); + for (int i = 6; i < str.size(); i += 4) + if (isdigit(str[str.size() - i - 1])) + str.insert(str.size() - i, 1, ','); + if (n < 0) + str.insert((unsigned int)0, 1, '-'); + else if (fPlus && n > 0) + str.insert((unsigned int)0, 1, '+'); + return str; +} + +bool ParseMoney(const char* pszIn, int64& nRet) +{ + string strWhole; + int64 nCents = 0; + const char* p = pszIn; + while (isspace(*p)) + p++; + for (; *p; p++) + { + if (*p == ',' && p > pszIn && isdigit(p[-1]) && isdigit(p[1]) && isdigit(p[2]) && isdigit(p[3]) && !isdigit(p[4])) + continue; + if (*p == '.') + { + p++; + if (isdigit(*p)) + { + nCents = 10 * (*p++ - '0'); + if (isdigit(*p)) + nCents += (*p++ - '0'); + } + break; + } + if (isspace(*p)) + break; + if (!isdigit(*p)) + return false; + strWhole.insert(strWhole.end(), *p); + } + for (; *p; p++) + if (!isspace(*p)) + return false; + if (strWhole.size() > 14) + return false; + if (nCents < 0 || nCents > 99) + return false; + int64 nWhole = atoi64(strWhole); + int64 nPreValue = nWhole * 100 + nCents; + int64 nValue = nPreValue * CENT; + if (nValue / CENT != nPreValue) + return false; + if (nValue / COIN != nWhole) + return false; + nRet = nValue; + return true; +} + + + + + + + + + + +bool FileExists(const char* psz) +{ +#ifdef WIN32 + return GetFileAttributes(psz) != -1; +#else + return access(psz, 0) != -1; +#endif +} + +int GetFilesize(FILE* file) +{ + int nSavePos = ftell(file); + int nFilesize = -1; + if (fseek(file, 0, SEEK_END) == 0) + nFilesize = ftell(file); + fseek(file, nSavePos, SEEK_SET); + return nFilesize; +} + + + + + + + + +uint64 GetRand(uint64 nMax) +{ + if (nMax == 0) + return 0; + + // The range of the random source must be a multiple of the modulus + // to give every possible output value an equal possibility + uint64 nRange = (_UI64_MAX / nMax) * nMax; + uint64 nRand = 0; + do + RAND_bytes((unsigned char*)&nRand, sizeof(nRand)); + while (nRand >= nRange); + return (nRand % nMax); +} + + + + + + + + + + +// +// "Never go to sea with two chronometers; take one or three." +// Our three chronometers are: +// - System clock +// - Median of other server's clocks +// - NTP servers +// +// note: NTP isn't implemented yet, so until then we just use the median +// of other nodes clocks to correct ours. +// + +int64 GetTime() +{ + return time(NULL); +} + +static int64 nTimeOffset = 0; + +int64 GetAdjustedTime() +{ + return GetTime() + nTimeOffset; +} + +void AddTimeData(unsigned int ip, int64 nTime) +{ + int64 nOffsetSample = nTime - GetTime(); + + // Ignore duplicates + static set setKnown; + if (!setKnown.insert(ip).second) + return; + + // Add data + static vector vTimeOffsets; + if (vTimeOffsets.empty()) + vTimeOffsets.push_back(0); + vTimeOffsets.push_back(nOffsetSample); + printf("Added time data, samples %d, ip %08x, offset %+I64d (%+I64d minutes)\n", vTimeOffsets.size(), ip, vTimeOffsets.back(), vTimeOffsets.back()/60); + if (vTimeOffsets.size() >= 5 && vTimeOffsets.size() % 2 == 1) + { + sort(vTimeOffsets.begin(), vTimeOffsets.end()); + int64 nMedian = vTimeOffsets[vTimeOffsets.size()/2]; + nTimeOffset = nMedian; + if ((nMedian > 0 ? nMedian : -nMedian) > 5 * 60) + { + // Only let other nodes change our clock so far before we + // go to the NTP servers + /// todo: Get time from NTP servers, then set a flag + /// to make sure it doesn't get changed again + } + foreach(int64 n, vTimeOffsets) + printf("%+I64d ", n); + printf("| nTimeOffset = %+I64d (%+I64d minutes)\n", nTimeOffset, nTimeOffset/60); + } +} diff --git a/util.h b/util.h new file mode 100644 index 0000000000..97617ab490 --- /dev/null +++ b/util.h @@ -0,0 +1,399 @@ +// Copyright (c) 2009 Satoshi Nakamoto +// Distributed under the MIT/X11 software license, see the accompanying +// file license.txt or http://www.opensource.org/licenses/mit-license.php. + + +#if defined(_MSC_VER) || defined(__BORLANDC__) +typedef __int64 int64; +typedef unsigned __int64 uint64; +#else +typedef long long int64; +typedef unsigned long long uint64; +#endif +#if defined(_MSC_VER) && _MSC_VER < 1300 +#define for if (false) ; else for +#endif + +#ifndef _MSC_VER +#define __forceinline inline +#endif + +#define foreach BOOST_FOREACH +#define loop for (;;) +#define BEGIN(a) ((char*)&(a)) +#define END(a) ((char*)&((&(a))[1])) +#define UBEGIN(a) ((unsigned char*)&(a)) +#define UEND(a) ((unsigned char*)&((&(a))[1])) +#define ARRAYLEN(array) (sizeof(array)/sizeof((array)[0])) + +#ifdef _WINDOWS +#define printf OutputDebugStringF +#endif + +#ifdef snprintf +#undef snprintf +#endif +#define snprintf my_snprintf + +#ifndef PRId64 +#if defined(_MSC_VER) || defined(__BORLANDC__) || defined(__MSVCRT__) +#define PRId64 "I64d" +#define PRIu64 "I64u" +#define PRIx64 "I64x" +#else +#define PRId64 "lld" +#define PRIu64 "llu" +#define PRIx64 "llx" +#endif +#endif + +// This is needed because the foreach macro can't get over the comma in pair +#define PAIRTYPE(t1, t2) pair + +// Used to bypass the rule against non-const reference to temporary +// where it makes sense with wrappers such as CFlatData or CTxDB +template +inline T& REF(const T& val) +{ + return (T&)val; +} + + + + + + + + + +extern bool fDebug; + +void RandAddSeed(bool fPerfmon=false); +int my_snprintf(char* buffer, size_t limit, const char* format, ...); +string strprintf(const char* format, ...); +bool error(const char* format, ...); +void PrintException(std::exception* pex, const char* pszThread); +void ParseString(const string& str, char c, vector& v); +string FormatMoney(int64 n, bool fPlus=false); +bool ParseMoney(const char* pszIn, int64& nRet); +bool FileExists(const char* psz); +int GetFilesize(FILE* file); +uint64 GetRand(uint64 nMax); +int64 GetTime(); +int64 GetAdjustedTime(); +void AddTimeData(unsigned int ip, int64 nTime); + + + + + + + + + + + + +// Wrapper to automatically initialize critical section +// Could use wxCriticalSection for portability, but it doesn't support TryEnterCriticalSection +class CCriticalSection +{ +protected: + CRITICAL_SECTION cs; +public: + char* pszFile; + int nLine; + explicit CCriticalSection() { InitializeCriticalSection(&cs); } + ~CCriticalSection() { DeleteCriticalSection(&cs); } + void Enter() { EnterCriticalSection(&cs); } + void Leave() { LeaveCriticalSection(&cs); } + bool TryEnter() { return TryEnterCriticalSection(&cs); } + CRITICAL_SECTION* operator&() { return &cs; } +}; + +// Automatically leave critical section when leaving block, needed for exception safety +class CCriticalBlock +{ +protected: + CRITICAL_SECTION* pcs; +public: + CCriticalBlock(CRITICAL_SECTION& csIn) { pcs = &csIn; EnterCriticalSection(pcs); } + CCriticalBlock(CCriticalSection& csIn) { pcs = &csIn; EnterCriticalSection(pcs); } + ~CCriticalBlock() { LeaveCriticalSection(pcs); } +}; + +// WARNING: This will catch continue and break! +// break is caught with an assertion, but there's no way to detect continue. +// 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) + +class CTryCriticalBlock +{ +protected: + CRITICAL_SECTION* pcs; +public: + CTryCriticalBlock(CRITICAL_SECTION& csIn) { pcs = (TryEnterCriticalSection(&csIn) ? &csIn : NULL); } + CTryCriticalBlock(CCriticalSection& csIn) { pcs = (TryEnterCriticalSection(&csIn) ? &csIn : NULL); } + ~CTryCriticalBlock() { if (pcs) LeaveCriticalSection(pcs); } + 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) + + + + + + + + + + + + +inline string i64tostr(int64 n) +{ + return strprintf("%"PRId64, n); +} + +inline string itostr(int n) +{ + return strprintf("%d", n); +} + +inline int64 atoi64(const char* psz) +{ +#ifdef _MSC_VER + return _atoi64(psz); +#else + return strtoll(psz, NULL, 10); +#endif +} + +inline int64 atoi64(const string& str) +{ +#ifdef _MSC_VER + return _atoi64(str.c_str()); +#else + return strtoll(str.c_str(), NULL, 10); +#endif +} + +inline int atoi(const string& str) +{ + return atoi(str.c_str()); +} + +inline int roundint(double d) +{ + return (int)(d > 0 ? d + 0.5 : d - 0.5); +} + +template +string HexStr(const T itbegin, const T itend, bool fSpaces=true) +{ + const unsigned char* pbegin = (const unsigned char*)&itbegin[0]; + const unsigned char* pend = pbegin + (itend - itbegin) * sizeof(itbegin[0]); + string str; + for (const unsigned char* p = pbegin; p != pend; p++) + str += strprintf((fSpaces && p != pend-1 ? "%02x " : "%02x"), *p); + return str; +} + +template +string HexNumStr(const T itbegin, const T itend, bool f0x=true) +{ + const unsigned char* pbegin = (const unsigned char*)&itbegin[0]; + const unsigned char* pend = pbegin + (itend - itbegin) * sizeof(itbegin[0]); + string str = (f0x ? "0x" : ""); + for (const unsigned char* p = pend-1; p >= pbegin; p--) + str += strprintf("%02X", *p); + return str; +} + +template +void PrintHex(const T pbegin, const T pend, const char* pszFormat="%s", bool fSpaces=true) +{ + printf(pszFormat, HexStr(pbegin, pend, fSpaces).c_str()); +} + + + + + + + + +inline int OutputDebugStringF(const char* pszFormat, ...) +{ +#ifdef __WXDEBUG__ + // log file + FILE* fileout = fopen("debug.log", "a"); + if (fileout) + { + va_list arg_ptr; + va_start(arg_ptr, pszFormat); + vfprintf(fileout, pszFormat, arg_ptr); + va_end(arg_ptr); + fclose(fileout); + } + + // accumulate a line at a time + static CCriticalSection cs_OutputDebugStringF; + CRITICAL_BLOCK(cs_OutputDebugStringF) + { + static char pszBuffer[50000]; + static char* pend; + if (pend == NULL) + pend = pszBuffer; + va_list arg_ptr; + va_start(arg_ptr, pszFormat); + int limit = END(pszBuffer) - pend - 2; + int ret = _vsnprintf(pend, limit, pszFormat, arg_ptr); + va_end(arg_ptr); + if (ret < 0 || ret >= limit) + { + pend = END(pszBuffer) - 2; + *pend++ = '\n'; + } + else + pend += ret; + *pend = '\0'; + char* p1 = pszBuffer; + char* p2; + while (p2 = strchr(p1, '\n')) + { + p2++; + char c = *p2; + *p2 = '\0'; + OutputDebugString(p1); + *p2 = c; + p1 = p2; + } + if (p1 != pszBuffer) + memmove(pszBuffer, p1, pend - p1 + 1); + pend -= (p1 - pszBuffer); + return ret; + } +#endif + + if (!wxTheApp) + { + // print to console + va_list arg_ptr; + va_start(arg_ptr, pszFormat); + vprintf(pszFormat, arg_ptr); + va_end(arg_ptr); + } + return 0; +} + + + + + + + + + +inline void heapchk() +{ + if (_heapchk() != _HEAPOK) + DebugBreak(); +} + +// Randomize the stack to help protect against buffer overrun exploits +#define IMPLEMENT_RANDOMIZE_STACK(ThreadFn) \ + { \ + static char nLoops; \ + if (nLoops <= 0) \ + nLoops = GetRand(50) + 1; \ + if (nLoops-- > 1) \ + { \ + ThreadFn; \ + return; \ + } \ + } + +#define CATCH_PRINT_EXCEPTION(pszFn) \ + catch (std::exception& e) { \ + PrintException(&e, (pszFn)); \ + } catch (...) { \ + PrintException(NULL, (pszFn)); \ + } + + + + + + + + + +template +inline uint256 Hash(const T1 pbegin, const T1 pend) +{ + uint256 hash1; + SHA256((unsigned char*)&pbegin[0], (pend - pbegin) * sizeof(pbegin[0]), (unsigned char*)&hash1); + uint256 hash2; + SHA256((unsigned char*)&hash1, sizeof(hash1), (unsigned char*)&hash2); + return hash2; +} + +template +inline uint256 Hash(const T1 p1begin, const T1 p1end, + const T2 p2begin, const T2 p2end) +{ + uint256 hash1; + SHA256_CTX ctx; + SHA256_Init(&ctx); + SHA256_Update(&ctx, (unsigned char*)&p1begin[0], (p1end - p1begin) * sizeof(p1begin[0])); + SHA256_Update(&ctx, (unsigned char*)&p2begin[0], (p2end - p2begin) * sizeof(p2begin[0])); + SHA256_Final((unsigned char*)&hash1, &ctx); + uint256 hash2; + SHA256((unsigned char*)&hash1, sizeof(hash1), (unsigned char*)&hash2); + return hash2; +} + +template +inline uint256 Hash(const T1 p1begin, const T1 p1end, + const T2 p2begin, const T2 p2end, + const T3 p3begin, const T3 p3end) +{ + uint256 hash1; + SHA256_CTX ctx; + SHA256_Init(&ctx); + SHA256_Update(&ctx, (unsigned char*)&p1begin[0], (p1end - p1begin) * sizeof(p1begin[0])); + SHA256_Update(&ctx, (unsigned char*)&p2begin[0], (p2end - p2begin) * sizeof(p2begin[0])); + SHA256_Update(&ctx, (unsigned char*)&p3begin[0], (p3end - p3begin) * sizeof(p3begin[0])); + SHA256_Final((unsigned char*)&hash1, &ctx); + uint256 hash2; + SHA256((unsigned char*)&hash1, sizeof(hash1), (unsigned char*)&hash2); + return hash2; +} + +template +uint256 SerializeHash(const T& obj, int nType=SER_GETHASH, int nVersion=VERSION) +{ + // Most of the time is spent allocating and deallocating CDataStream's + // buffer. If this ever needs to be optimized further, make a CStaticStream + // class with its buffer on the stack. + CDataStream ss(nType, nVersion); + ss.reserve(10000); + ss << obj; + return Hash(ss.begin(), ss.end()); +} + +inline uint160 Hash160(const vector& vch) +{ + uint256 hash1; + SHA256(&vch[0], vch.size(), (unsigned char*)&hash1); + uint160 hash2; + RIPEMD160((unsigned char*)&hash1, sizeof(hash1), (unsigned char*)&hash2); + return hash2; +} -- cgit v1.2.3 From e071a3f6c06f41068ad17134189a4ac3073ef76b Mon Sep 17 00:00:00 2001 From: sirius-m Date: Sun, 30 Aug 2009 03:46:39 +0000 Subject: First commit git-svn-id: https://bitcoin.svn.sourceforge.net/svnroot/bitcoin/trunk@1 1a98c847-1fd6-4fd8-948a-caf3550aa51b --- base58.h | 201 + bignum.h | 498 ++ db.cpp | 614 +++ db.h | 420 ++ headers.h | 71 + irc.cpp | 314 ++ irc.h | 10 + key.h | 156 + libeay32.dll | Bin 0 -> 1306630 bytes license.txt | 19 + main.cpp | 2692 ++++++++++ main.h | 1329 +++++ makefile | 83 + makefile.vc | 77 + market.cpp | 264 + market.h | 182 + mingwm10.dll | Bin 0 -> 11673 bytes net.cpp | 1100 ++++ net.h | 856 ++++ rc/addressbook16.bmp | Bin 0 -> 1334 bytes rc/addressbook16mask.bmp | Bin 0 -> 126 bytes rc/addressbook20.bmp | Bin 0 -> 1478 bytes rc/addressbook20mask.bmp | Bin 0 -> 142 bytes rc/bitcoin.ico | Bin 0 -> 22486 bytes rc/check.ico | Bin 0 -> 766 bytes rc/send16.bmp | Bin 0 -> 1334 bytes rc/send16mask.bmp | Bin 0 -> 126 bytes rc/send16masknoshadow.bmp | Bin 0 -> 126 bytes rc/send20.bmp | Bin 0 -> 1478 bytes rc/send20mask.bmp | Bin 0 -> 142 bytes readme.txt | 76 + script.cpp | 1127 +++++ script.h | 597 +++ serialize.h | 1158 +++++ sha.cpp | 554 +++ sha.h | 177 + ui.cpp | 3290 ++++++++++++ ui.h | 420 ++ ui.rc | 14 + uibase.cpp | 1825 +++++++ uibase.h | 723 +++ uint256.h | 750 +++ uiproject.fbp | 11860 ++++++++++++++++++++++++++++++++++++++++++++ util.cpp | 383 ++ util.h | 399 ++ 45 files changed, 32239 insertions(+) create mode 100644 base58.h create mode 100644 bignum.h create mode 100644 db.cpp create mode 100644 db.h create mode 100644 headers.h create mode 100644 irc.cpp create mode 100644 irc.h create mode 100644 key.h create mode 100644 libeay32.dll create mode 100644 license.txt create mode 100644 main.cpp create mode 100644 main.h create mode 100644 makefile create mode 100644 makefile.vc create mode 100644 market.cpp create mode 100644 market.h create mode 100644 mingwm10.dll create mode 100644 net.cpp create mode 100644 net.h create mode 100644 rc/addressbook16.bmp create mode 100644 rc/addressbook16mask.bmp create mode 100644 rc/addressbook20.bmp create mode 100644 rc/addressbook20mask.bmp create mode 100644 rc/bitcoin.ico create mode 100644 rc/check.ico create mode 100644 rc/send16.bmp create mode 100644 rc/send16mask.bmp create mode 100644 rc/send16masknoshadow.bmp create mode 100644 rc/send20.bmp create mode 100644 rc/send20mask.bmp create mode 100644 readme.txt create mode 100644 script.cpp create mode 100644 script.h create mode 100644 serialize.h create mode 100644 sha.cpp create mode 100644 sha.h create mode 100644 ui.cpp create mode 100644 ui.h create mode 100644 ui.rc create mode 100644 uibase.cpp create mode 100644 uibase.h create mode 100644 uint256.h create mode 100644 uiproject.fbp create mode 100644 util.cpp create mode 100644 util.h diff --git a/base58.h b/base58.h new file mode 100644 index 0000000000..69f40bd208 --- /dev/null +++ b/base58.h @@ -0,0 +1,201 @@ +// Copyright (c) 2009 Satoshi Nakamoto +// Distributed under the MIT/X11 software license, see the accompanying +// file license.txt or http://www.opensource.org/licenses/mit-license.php. + + +// +// Why base-58 instead of standard base-64 encoding? +// - Don't want 0OIl characters that look the same in some fonts and +// could be used to create visually identical looking account numbers. +// - A string with non-alphanumeric characters is not as easily accepted as an account number. +// - E-mail usually won't line-break if there's no punctuation to break at. +// - Doubleclicking selects the whole number as one word if it's all alphanumeric. +// + + +static const char* pszBase58 = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"; + + +inline string EncodeBase58(const unsigned char* pbegin, const unsigned char* pend) +{ + CAutoBN_CTX pctx; + CBigNum bn58 = 58; + CBigNum bn0 = 0; + + // Convert big endian data to little endian + // Extra zero at the end make sure bignum will interpret as a positive number + vector vchTmp(pend-pbegin+1, 0); + reverse_copy(pbegin, pend, vchTmp.begin()); + + // Convert little endian data to bignum + CBigNum bn; + bn.setvch(vchTmp); + + // Convert bignum to string + string str; + str.reserve((pend - pbegin) * 138 / 100 + 1); + CBigNum dv; + CBigNum rem; + while (bn > bn0) + { + if (!BN_div(&dv, &rem, &bn, &bn58, pctx)) + throw bignum_error("EncodeBase58 : BN_div failed"); + bn = dv; + unsigned int c = rem.getulong(); + str += pszBase58[c]; + } + + // Leading zeroes encoded as base58 zeros + for (const unsigned char* p = pbegin; p < pend && *p == 0; p++) + str += pszBase58[0]; + + // Convert little endian string to big endian + reverse(str.begin(), str.end()); + return str; +} + +inline string EncodeBase58(const vector& vch) +{ + return EncodeBase58(&vch[0], &vch[0] + vch.size()); +} + +inline bool DecodeBase58(const char* psz, vector& vchRet) +{ + CAutoBN_CTX pctx; + vchRet.clear(); + CBigNum bn58 = 58; + CBigNum bn = 0; + CBigNum bnChar; + while (isspace(*psz)) + psz++; + + // Convert big endian string to bignum + for (const char* p = psz; *p; p++) + { + const char* p1 = strchr(pszBase58, *p); + if (p1 == NULL) + { + while (isspace(*p)) + p++; + if (*p != '\0') + return false; + break; + } + bnChar.setulong(p1 - pszBase58); + if (!BN_mul(&bn, &bn, &bn58, pctx)) + throw bignum_error("DecodeBase58 : BN_mul failed"); + bn += bnChar; + } + + // Get bignum as little endian data + vector vchTmp = bn.getvch(); + + // Trim off sign byte if present + if (vchTmp.size() >= 2 && vchTmp.end()[-1] == 0 && vchTmp.end()[-2] >= 0x80) + vchTmp.erase(vchTmp.end()-1); + + // Restore leading zeros + int nLeadingZeros = 0; + for (const char* p = psz; *p == pszBase58[0]; p++) + nLeadingZeros++; + vchRet.assign(nLeadingZeros + vchTmp.size(), 0); + + // Convert little endian data to big endian + reverse_copy(vchTmp.begin(), vchTmp.end(), vchRet.end() - vchTmp.size()); + return true; +} + +inline bool DecodeBase58(const string& str, vector& vchRet) +{ + return DecodeBase58(str.c_str(), vchRet); +} + + + + + +inline string EncodeBase58Check(const vector& vchIn) +{ + // add 4-byte hash check to the end + vector vch(vchIn); + uint256 hash = Hash(vch.begin(), vch.end()); + vch.insert(vch.end(), (unsigned char*)&hash, (unsigned char*)&hash + 4); + return EncodeBase58(vch); +} + +inline bool DecodeBase58Check(const char* psz, vector& vchRet) +{ + if (!DecodeBase58(psz, vchRet)) + return false; + if (vchRet.size() < 4) + { + vchRet.clear(); + return false; + } + uint256 hash = Hash(vchRet.begin(), vchRet.end()-4); + if (memcmp(&hash, &vchRet.end()[-4], 4) != 0) + { + vchRet.clear(); + return false; + } + vchRet.resize(vchRet.size()-4); + return true; +} + +inline bool DecodeBase58Check(const string& str, vector& vchRet) +{ + return DecodeBase58Check(str.c_str(), vchRet); +} + + + + + + +static const unsigned char ADDRESSVERSION = 0; + +inline string Hash160ToAddress(uint160 hash160) +{ + // add 1-byte version number to the front + vector vch(1, ADDRESSVERSION); + vch.insert(vch.end(), UBEGIN(hash160), UEND(hash160)); + return EncodeBase58Check(vch); +} + +inline bool AddressToHash160(const char* psz, uint160& hash160Ret) +{ + vector 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); +} + +inline bool AddressToHash160(const string& str, uint160& hash160Ret) +{ + return AddressToHash160(str.c_str(), hash160Ret); +} + +inline bool IsValidBitcoinAddress(const char* psz) +{ + uint160 hash160; + return AddressToHash160(psz, hash160); +} + +inline bool IsValidBitcoinAddress(const string& str) +{ + return IsValidBitcoinAddress(str.c_str()); +} + + + + +inline string PubKeyToAddress(const vector& vchPubKey) +{ + return Hash160ToAddress(Hash160(vchPubKey)); +} diff --git a/bignum.h b/bignum.h new file mode 100644 index 0000000000..8aa4e9c4ff --- /dev/null +++ b/bignum.h @@ -0,0 +1,498 @@ +// Copyright (c) 2009 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 +#include +#include + + + + + +class bignum_error : public std::runtime_error +{ +public: + explicit bignum_error(const std::string& str) : std::runtime_error(str) {} +}; + + + +class CAutoBN_CTX +{ +protected: + BN_CTX* pctx; + BN_CTX* operator=(BN_CTX* pnew) { return pctx = pnew; } + +public: + CAutoBN_CTX() + { + pctx = BN_CTX_new(); + if (pctx == NULL) + throw bignum_error("CAutoBN_CTX : BN_CTX_new() returned NULL"); + } + + ~CAutoBN_CTX() + { + if (pctx != NULL) + BN_CTX_free(pctx); + } + + operator BN_CTX*() { return pctx; } + BN_CTX& operator*() { return *pctx; } + BN_CTX** operator&() { return &pctx; } + bool operator!() { return (pctx == NULL); } +}; + + + +class CBigNum : public BIGNUM +{ +public: + CBigNum() + { + BN_init(this); + } + + CBigNum(const CBigNum& b) + { + BN_init(this); + if (!BN_copy(this, &b)) + { + BN_clear_free(this); + throw bignum_error("CBigNum::CBigNum(const CBigNum&) : BN_copy failed"); + } + } + + explicit CBigNum(const std::string& str) + { + BN_init(this); + SetHex(str); + } + + CBigNum& operator=(const CBigNum& b) + { + if (!BN_copy(this, &b)) + throw bignum_error("CBigNum::operator= : BN_copy failed"); + return (*this); + } + + ~CBigNum() + { + BN_clear_free(this); + } + + CBigNum(char n) { BN_init(this); if (n >= 0) setulong(n); else setint64(n); } + CBigNum(short n) { BN_init(this); if (n >= 0) setulong(n); else setint64(n); } + CBigNum(int n) { BN_init(this); if (n >= 0) setulong(n); else setint64(n); } + CBigNum(long n) { BN_init(this); if (n >= 0) setulong(n); else setint64(n); } + CBigNum(int64 n) { BN_init(this); setint64(n); } + CBigNum(unsigned char n) { BN_init(this); setulong(n); } + CBigNum(unsigned short n) { BN_init(this); setulong(n); } + CBigNum(unsigned int n) { BN_init(this); setulong(n); } + CBigNum(unsigned long n) { BN_init(this); setulong(n); } + CBigNum(uint64 n) { BN_init(this); setuint64(n); } + explicit CBigNum(uint256 n) { BN_init(this); setuint256(n); } + + explicit CBigNum(const std::vector& vch) + { + BN_init(this); + setvch(vch); + } + + void setulong(unsigned long n) + { + if (!BN_set_word(this, n)) + throw bignum_error("CBigNum conversion from unsigned long : BN_set_word failed"); + } + + unsigned long getulong() const + { + return BN_get_word(this); + } + + unsigned int getuint() const + { + return BN_get_word(this); + } + + int getint() const + { + unsigned long n = BN_get_word(this); + if (!BN_is_negative(this)) + return (n > INT_MAX ? INT_MAX : n); + else + return (n > INT_MAX ? INT_MIN : -(int)n); + } + + void setint64(int64 n) + { + unsigned char pch[sizeof(n) + 6]; + unsigned char* p = pch + 4; + bool fNegative = false; + if (n < (int64)0) + { + n = -n; + fNegative = true; + } + bool fLeadingZeroes = true; + for (int i = 0; i < 8; i++) + { + unsigned char c = (n >> 56) & 0xff; + n <<= 8; + if (fLeadingZeroes) + { + if (c == 0) + continue; + if (c & 0x80) + *p++ = (fNegative ? 0x80 : 0); + else if (fNegative) + c |= 0x80; + fLeadingZeroes = false; + } + *p++ = c; + } + unsigned int nSize = p - (pch + 4); + pch[0] = (nSize >> 24) & 0xff; + pch[1] = (nSize >> 16) & 0xff; + pch[2] = (nSize >> 8) & 0xff; + pch[3] = (nSize) & 0xff; + BN_mpi2bn(pch, p - pch, this); + } + + void setuint64(uint64 n) + { + unsigned char pch[sizeof(n) + 6]; + unsigned char* p = pch + 4; + bool fLeadingZeroes = true; + for (int i = 0; i < 8; i++) + { + unsigned char c = (n >> 56) & 0xff; + n <<= 8; + if (fLeadingZeroes) + { + if (c == 0) + continue; + if (c & 0x80) + *p++ = 0; + fLeadingZeroes = false; + } + *p++ = c; + } + unsigned int nSize = p - (pch + 4); + pch[0] = (nSize >> 24) & 0xff; + pch[1] = (nSize >> 16) & 0xff; + pch[2] = (nSize >> 8) & 0xff; + pch[3] = (nSize) & 0xff; + BN_mpi2bn(pch, p - pch, this); + } + + void setuint256(uint256 n) + { + unsigned char pch[sizeof(n) + 6]; + unsigned char* p = pch + 4; + bool fLeadingZeroes = true; + unsigned char* pbegin = (unsigned char*)&n; + unsigned char* psrc = pbegin + sizeof(n); + while (psrc != pbegin) + { + unsigned char c = *(--psrc); + if (fLeadingZeroes) + { + if (c == 0) + continue; + if (c & 0x80) + *p++ = 0; + fLeadingZeroes = false; + } + *p++ = c; + } + unsigned int nSize = p - (pch + 4); + pch[0] = (nSize >> 24) & 0xff; + pch[1] = (nSize >> 16) & 0xff; + pch[2] = (nSize >> 8) & 0xff; + pch[3] = (nSize >> 0) & 0xff; + BN_mpi2bn(pch, p - pch, this); + } + + uint256 getuint256() + { + unsigned int nSize = BN_bn2mpi(this, NULL); + if (nSize < 4) + return 0; + std::vector vch(nSize); + BN_bn2mpi(this, &vch[0]); + if (vch.size() > 4) + vch[4] &= 0x7f; + uint256 n = 0; + for (int i = 0, j = vch.size()-1; i < sizeof(n) && j >= 4; i++, j--) + ((unsigned char*)&n)[i] = vch[j]; + return n; + } + + void setvch(const std::vector& vch) + { + std::vector vch2(vch.size() + 4); + unsigned int nSize = vch.size(); + vch2[0] = (nSize >> 24) & 0xff; + vch2[1] = (nSize >> 16) & 0xff; + vch2[2] = (nSize >> 8) & 0xff; + vch2[3] = (nSize >> 0) & 0xff; + reverse_copy(vch.begin(), vch.end(), vch2.begin() + 4); + BN_mpi2bn(&vch2[0], vch2.size(), this); + } + + std::vector getvch() const + { + unsigned int nSize = BN_bn2mpi(this, NULL); + if (nSize < 4) + return std::vector(); + std::vector vch(nSize); + BN_bn2mpi(this, &vch[0]); + vch.erase(vch.begin(), vch.begin() + 4); + reverse(vch.begin(), vch.end()); + return vch; + } + + CBigNum& SetCompact(unsigned int nCompact) + { + unsigned int nSize = nCompact >> 24; + std::vector vch(4 + nSize); + vch[3] = nSize; + if (nSize >= 1) vch[4] = (nCompact >> 16) & 0xff; + if (nSize >= 2) vch[5] = (nCompact >> 8) & 0xff; + if (nSize >= 3) vch[6] = (nCompact >> 0) & 0xff; + BN_mpi2bn(&vch[0], vch.size(), this); + return *this; + } + + unsigned int GetCompact() const + { + unsigned int nSize = BN_bn2mpi(this, NULL); + std::vector vch(nSize); + nSize -= 4; + BN_bn2mpi(this, &vch[0]); + unsigned int nCompact = nSize << 24; + if (nSize >= 1) nCompact |= (vch[4] << 16); + if (nSize >= 2) nCompact |= (vch[5] << 8); + if (nSize >= 3) nCompact |= (vch[6] << 0); + return nCompact; + } + + void SetHex(const std::string& str) + { + // skip 0x + const char* psz = str.c_str(); + while (isspace(*psz)) + psz++; + bool fNegative = false; + if (*psz == '-') + { + fNegative = true; + psz++; + } + if (psz[0] == '0' && tolower(psz[1]) == 'x') + psz += 2; + while (isspace(*psz)) + psz++; + + // hex string to bignum + static char phexdigit[256] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,1,2,3,4,5,6,7,8,9,0,0,0,0,0,0, 0,0xa,0xb,0xc,0xd,0xe,0xf,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0xa,0xb,0xc,0xd,0xe,0xf,0,0,0,0,0,0,0,0,0 }; + *this = 0; + while (isxdigit(*psz)) + { + *this <<= 4; + int n = phexdigit[*psz++]; + *this += n; + } + if (fNegative) + *this = 0 - *this; + } + + unsigned int GetSerializeSize(int nType=0, int nVersion=VERSION) const + { + return ::GetSerializeSize(getvch(), nType, nVersion); + } + + template + void Serialize(Stream& s, int nType=0, int nVersion=VERSION) const + { + ::Serialize(s, getvch(), nType, nVersion); + } + + template + void Unserialize(Stream& s, int nType=0, int nVersion=VERSION) + { + vector vch; + ::Unserialize(s, vch, nType, nVersion); + setvch(vch); + } + + + bool operator!() const + { + return BN_is_zero(this); + } + + CBigNum& operator+=(const CBigNum& b) + { + if (!BN_add(this, this, &b)) + throw bignum_error("CBigNum::operator+= : BN_add failed"); + return *this; + } + + CBigNum& operator-=(const CBigNum& b) + { + *this = *this - b; + return *this; + } + + CBigNum& operator*=(const CBigNum& b) + { + CAutoBN_CTX pctx; + if (!BN_mul(this, this, &b, pctx)) + throw bignum_error("CBigNum::operator*= : BN_mul failed"); + return *this; + } + + CBigNum& operator/=(const CBigNum& b) + { + *this = *this / b; + return *this; + } + + CBigNum& operator%=(const CBigNum& b) + { + *this = *this % b; + return *this; + } + + CBigNum& operator<<=(unsigned int shift) + { + if (!BN_lshift(this, this, shift)) + throw bignum_error("CBigNum:operator<<= : BN_lshift failed"); + return *this; + } + + CBigNum& operator>>=(unsigned int shift) + { + if (!BN_rshift(this, this, shift)) + throw bignum_error("CBigNum:operator>>= : BN_rshift failed"); + return *this; + } + + + CBigNum& operator++() + { + // prefix operator + if (!BN_add(this, this, BN_value_one())) + throw bignum_error("CBigNum::operator++ : BN_add failed"); + return *this; + } + + const CBigNum operator++(int) + { + // postfix operator + const CBigNum ret = *this; + ++(*this); + return ret; + } + + CBigNum& operator--() + { + // prefix operator + CBigNum r; + if (!BN_sub(&r, this, BN_value_one())) + throw bignum_error("CBigNum::operator-- : BN_sub failed"); + *this = r; + return *this; + } + + const CBigNum operator--(int) + { + // postfix operator + const CBigNum ret = *this; + --(*this); + return ret; + } + + + friend inline const CBigNum operator-(const CBigNum& a, const CBigNum& b); + friend inline const CBigNum operator/(const CBigNum& a, const CBigNum& b); + friend inline const CBigNum operator%(const CBigNum& a, const CBigNum& b); +}; + + + +inline const CBigNum operator+(const CBigNum& a, const CBigNum& b) +{ + CBigNum r; + if (!BN_add(&r, &a, &b)) + throw bignum_error("CBigNum::operator+ : BN_add failed"); + return r; +} + +inline const CBigNum operator-(const CBigNum& a, const CBigNum& b) +{ + CBigNum r; + if (!BN_sub(&r, &a, &b)) + throw bignum_error("CBigNum::operator- : BN_sub failed"); + return r; +} + +inline const CBigNum operator-(const CBigNum& a) +{ + CBigNum r(a); + BN_set_negative(&r, !BN_is_negative(&r)); + return r; +} + +inline const CBigNum operator*(const CBigNum& a, const CBigNum& b) +{ + CAutoBN_CTX pctx; + CBigNum r; + if (!BN_mul(&r, &a, &b, pctx)) + throw bignum_error("CBigNum::operator* : BN_mul failed"); + return r; +} + +inline const CBigNum operator/(const CBigNum& a, const CBigNum& b) +{ + CAutoBN_CTX pctx; + CBigNum r; + if (!BN_div(&r, NULL, &a, &b, pctx)) + throw bignum_error("CBigNum::operator/ : BN_div failed"); + return r; +} + +inline const CBigNum operator%(const CBigNum& a, const CBigNum& b) +{ + CAutoBN_CTX pctx; + CBigNum r; + if (!BN_mod(&r, &a, &b, pctx)) + throw bignum_error("CBigNum::operator% : BN_div failed"); + return r; +} + +inline const CBigNum operator<<(const CBigNum& a, unsigned int shift) +{ + CBigNum r; + if (!BN_lshift(&r, &a, shift)) + throw bignum_error("CBigNum:operator<< : BN_lshift failed"); + return r; +} + +inline const CBigNum operator>>(const CBigNum& a, unsigned int shift) +{ + CBigNum r; + if (!BN_rshift(&r, &a, shift)) + throw bignum_error("CBigNum:operator>> : BN_rshift failed"); + return r; +} + +inline bool operator==(const CBigNum& a, const CBigNum& b) { return (BN_cmp(&a, &b) == 0); } +inline bool operator!=(const CBigNum& a, const CBigNum& b) { return (BN_cmp(&a, &b) != 0); } +inline bool operator<=(const CBigNum& a, const CBigNum& b) { return (BN_cmp(&a, &b) <= 0); } +inline bool operator>=(const CBigNum& a, const CBigNum& b) { return (BN_cmp(&a, &b) >= 0); } +inline bool operator<(const CBigNum& a, const CBigNum& b) { return (BN_cmp(&a, &b) < 0); } +inline bool operator>(const CBigNum& a, const CBigNum& b) { return (BN_cmp(&a, &b) > 0); } diff --git a/db.cpp b/db.cpp new file mode 100644 index 0000000000..f38f3ffad8 --- /dev/null +++ b/db.cpp @@ -0,0 +1,614 @@ +// Copyright (c) 2009 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" + + + + + + +// +// CDB +// + +static CCriticalSection cs_db; +static bool fDbEnvInit = false; +DbEnv dbenv(0); +static map mapFileUseCount; + +class CDBInit +{ +public: + CDBInit() + { + } + ~CDBInit() + { + if (fDbEnvInit) + { + dbenv.close(0); + fDbEnvInit = false; + } + } +} +instance_of_cdbinit; + + +CDB::CDB(const char* pszFile, const char* pszMode, bool fTxn) : pdb(NULL) +{ + int ret; + if (pszFile == NULL) + return; + + bool fCreate = strchr(pszMode, 'c'); + bool fReadOnly = (!strchr(pszMode, '+') && !strchr(pszMode, 'w')); + unsigned int nFlags = DB_THREAD; + if (fCreate) + nFlags |= DB_CREATE; + else if (fReadOnly) + nFlags |= DB_RDONLY; + if (!fReadOnly || fTxn) + nFlags |= DB_AUTO_COMMIT; + + CRITICAL_BLOCK(cs_db) + { + if (!fDbEnvInit) + { + string strAppDir = GetAppDir(); + string strLogDir = strAppDir + "\\database"; + _mkdir(strLogDir.c_str()); + printf("dbenv.open strAppDir=%s\n", strAppDir.c_str()); + + dbenv.set_lg_dir(strLogDir.c_str()); + dbenv.set_lg_max(10000000); + dbenv.set_lk_max_locks(10000); + dbenv.set_lk_max_objects(10000); + dbenv.set_errfile(fopen("db.log", "a")); /// debug + ///dbenv.log_set_config(DB_LOG_AUTO_REMOVE, 1); /// causes corruption + ret = dbenv.open(strAppDir.c_str(), + DB_CREATE | + DB_INIT_LOCK | + DB_INIT_LOG | + DB_INIT_MPOOL | + DB_INIT_TXN | + DB_THREAD | + DB_PRIVATE | + DB_RECOVER, + 0); + if (ret > 0) + throw runtime_error(strprintf("CDB() : error %d opening database environment\n", ret)); + fDbEnvInit = true; + } + + strFile = pszFile; + ++mapFileUseCount[strFile]; + } + + pdb = new Db(&dbenv, 0); + + ret = pdb->open(NULL, // Txn pointer + pszFile, // Filename + "main", // Logical db name + DB_BTREE, // Database type + nFlags, // Flags + 0); + + if (ret > 0) + { + delete pdb; + pdb = NULL; + CRITICAL_BLOCK(cs_db) + --mapFileUseCount[strFile]; + strFile = ""; + throw runtime_error(strprintf("CDB() : can't open database file %s, error %d\n", pszFile, ret)); + } + + if (fCreate && !Exists(string("version"))) + WriteVersion(VERSION); + + RandAddSeed(); +} + +void CDB::Close() +{ + if (!pdb) + return; + if (!vTxn.empty()) + vTxn.front()->abort(); + vTxn.clear(); + pdb->close(0); + delete pdb; + pdb = NULL; + dbenv.txn_checkpoint(0, 0, 0); + + CRITICAL_BLOCK(cs_db) + --mapFileUseCount[strFile]; + + RandAddSeed(); +} + +void DBFlush(bool fShutdown) +{ + // Flush log data to the actual data file + // on all files that are not in use + printf("DBFlush(%s)\n", fShutdown ? "true" : "false"); + CRITICAL_BLOCK(cs_db) + { + dbenv.txn_checkpoint(0, 0, 0); + map::iterator mi = mapFileUseCount.begin(); + while (mi != mapFileUseCount.end()) + { + string strFile = (*mi).first; + int nRefCount = (*mi).second; + if (nRefCount == 0) + { + dbenv.lsn_reset(strFile.c_str(), 0); + mapFileUseCount.erase(mi++); + } + else + mi++; + } + if (fShutdown) + { + char** listp; + if (mapFileUseCount.empty()) + dbenv.log_archive(&listp, DB_ARCH_REMOVE); + dbenv.close(0); + fDbEnvInit = false; + } + } +} + + + + + + +// +// CTxDB +// + +bool CTxDB::ReadTxIndex(uint256 hash, CTxIndex& txindex) +{ + assert(!fClient); + txindex.SetNull(); + return Read(make_pair(string("tx"), hash), txindex); +} + +bool CTxDB::UpdateTxIndex(uint256 hash, const CTxIndex& txindex) +{ + assert(!fClient); + return Write(make_pair(string("tx"), hash), txindex); +} + +bool CTxDB::AddTxIndex(const CTransaction& tx, const CDiskTxPos& pos, int nHeight) +{ + assert(!fClient); + + // Add to tx index + uint256 hash = tx.GetHash(); + CTxIndex txindex(pos, tx.vout.size()); + return Write(make_pair(string("tx"), hash), txindex); +} + +bool CTxDB::EraseTxIndex(const CTransaction& tx) +{ + assert(!fClient); + uint256 hash = tx.GetHash(); + + return Erase(make_pair(string("tx"), hash)); +} + +bool CTxDB::ContainsTx(uint256 hash) +{ + assert(!fClient); + return Exists(make_pair(string("tx"), hash)); +} + +bool CTxDB::ReadOwnerTxes(uint160 hash160, int nMinHeight, vector& vtx) +{ + assert(!fClient); + vtx.clear(); + + // Get cursor + Dbc* pcursor = GetCursor(); + if (!pcursor) + return false; + + unsigned int fFlags = DB_SET_RANGE; + loop + { + // Read next record + CDataStream ssKey; + if (fFlags == DB_SET_RANGE) + ssKey << string("owner") << hash160 << CDiskTxPos(0, 0, 0); + CDataStream ssValue; + int ret = ReadAtCursor(pcursor, ssKey, ssValue, fFlags); + fFlags = DB_NEXT; + if (ret == DB_NOTFOUND) + break; + else if (ret != 0) + return false; + + // Unserialize + string strType; + uint160 hashItem; + CDiskTxPos pos; + ssKey >> strType >> hashItem >> pos; + int nItemHeight; + ssValue >> nItemHeight; + + // Read transaction + if (strType != "owner" || hashItem != hash160) + break; + if (nItemHeight >= nMinHeight) + { + vtx.resize(vtx.size()+1); + if (!vtx.back().ReadFromDisk(pos)) + return false; + } + } + return true; +} + +bool CTxDB::ReadDiskTx(uint256 hash, CTransaction& tx, CTxIndex& txindex) +{ + assert(!fClient); + tx.SetNull(); + if (!ReadTxIndex(hash, txindex)) + return false; + return (tx.ReadFromDisk(txindex.pos)); +} + +bool CTxDB::ReadDiskTx(uint256 hash, CTransaction& tx) +{ + CTxIndex txindex; + return ReadDiskTx(hash, tx, txindex); +} + +bool CTxDB::ReadDiskTx(COutPoint outpoint, CTransaction& tx, CTxIndex& txindex) +{ + return ReadDiskTx(outpoint.hash, tx, txindex); +} + +bool CTxDB::ReadDiskTx(COutPoint outpoint, CTransaction& tx) +{ + CTxIndex txindex; + return ReadDiskTx(outpoint.hash, tx, txindex); +} + +bool CTxDB::WriteBlockIndex(const CDiskBlockIndex& blockindex) +{ + return Write(make_pair(string("blockindex"), blockindex.GetBlockHash()), blockindex); +} + +bool CTxDB::EraseBlockIndex(uint256 hash) +{ + return Erase(make_pair(string("blockindex"), hash)); +} + +bool CTxDB::ReadHashBestChain(uint256& hashBestChain) +{ + return Read(string("hashBestChain"), hashBestChain); +} + +bool CTxDB::WriteHashBestChain(uint256 hashBestChain) +{ + return Write(string("hashBestChain"), hashBestChain); +} + +CBlockIndex* InsertBlockIndex(uint256 hash) +{ + if (hash == 0) + return NULL; + + // Return existing + map::iterator mi = mapBlockIndex.find(hash); + if (mi != mapBlockIndex.end()) + return (*mi).second; + + // Create new + CBlockIndex* pindexNew = new CBlockIndex(); + if (!pindexNew) + throw runtime_error("LoadBlockIndex() : new CBlockIndex failed"); + mi = mapBlockIndex.insert(make_pair(hash, pindexNew)).first; + pindexNew->phashBlock = &((*mi).first); + + return pindexNew; +} + +bool CTxDB::LoadBlockIndex() +{ + // Get cursor + Dbc* pcursor = GetCursor(); + if (!pcursor) + return false; + + unsigned int fFlags = DB_SET_RANGE; + loop + { + // Read next record + CDataStream ssKey; + if (fFlags == DB_SET_RANGE) + ssKey << make_pair(string("blockindex"), uint256(0)); + CDataStream ssValue; + int ret = ReadAtCursor(pcursor, ssKey, ssValue, fFlags); + fFlags = DB_NEXT; + if (ret == DB_NOTFOUND) + break; + else if (ret != 0) + return false; + + // Unserialize + string strType; + ssKey >> strType; + if (strType == "blockindex") + { + CDiskBlockIndex diskindex; + ssValue >> diskindex; + + // Construct block index object + CBlockIndex* pindexNew = InsertBlockIndex(diskindex.GetBlockHash()); + pindexNew->pprev = InsertBlockIndex(diskindex.hashPrev); + pindexNew->pnext = InsertBlockIndex(diskindex.hashNext); + pindexNew->nFile = diskindex.nFile; + pindexNew->nBlockPos = diskindex.nBlockPos; + pindexNew->nHeight = diskindex.nHeight; + pindexNew->nVersion = diskindex.nVersion; + pindexNew->hashMerkleRoot = diskindex.hashMerkleRoot; + pindexNew->nTime = diskindex.nTime; + pindexNew->nBits = diskindex.nBits; + pindexNew->nNonce = diskindex.nNonce; + + // Watch for genesis block and best block + if (pindexGenesisBlock == NULL && diskindex.GetBlockHash() == hashGenesisBlock) + pindexGenesisBlock = pindexNew; + } + else + { + break; + } + } + + if (!ReadHashBestChain(hashBestChain)) + { + if (pindexGenesisBlock == NULL) + return true; + return error("CTxDB::LoadBlockIndex() : hashBestChain not found\n"); + } + + if (!mapBlockIndex.count(hashBestChain)) + return error("CTxDB::LoadBlockIndex() : blockindex for hashBestChain not found\n"); + pindexBest = mapBlockIndex[hashBestChain]; + nBestHeight = pindexBest->nHeight; + printf("LoadBlockIndex(): hashBestChain=%s height=%d\n", hashBestChain.ToString().substr(0,14).c_str(), nBestHeight); + + return true; +} + + + + + +// +// CAddrDB +// + +bool CAddrDB::WriteAddress(const CAddress& addr) +{ + return Write(make_pair(string("addr"), addr.GetKey()), addr); +} + +bool CAddrDB::LoadAddresses() +{ + CRITICAL_BLOCK(cs_mapIRCAddresses) + CRITICAL_BLOCK(cs_mapAddresses) + { + // Load user provided addresses + CAutoFile filein = fopen("addr.txt", "rt"); + if (filein) + { + try + { + char psz[1000]; + while (fgets(psz, sizeof(psz), filein)) + { + CAddress addr(psz, NODE_NETWORK); + if (addr.ip != 0) + { + AddAddress(*this, addr); + mapIRCAddresses.insert(make_pair(addr.GetKey(), addr)); + } + } + } + catch (...) { } + } + + // Get cursor + Dbc* pcursor = GetCursor(); + if (!pcursor) + return false; + + loop + { + // Read next record + CDataStream ssKey; + CDataStream ssValue; + int ret = ReadAtCursor(pcursor, ssKey, ssValue); + if (ret == DB_NOTFOUND) + break; + else if (ret != 0) + return false; + + // Unserialize + string strType; + ssKey >> strType; + if (strType == "addr") + { + CAddress addr; + ssValue >> addr; + mapAddresses.insert(make_pair(addr.GetKey(), addr)); + } + } + + //// debug print + printf("mapAddresses:\n"); + foreach(const PAIRTYPE(vector, CAddress)& item, mapAddresses) + item.second.print(); + printf("-----\n"); + + // Fix for possible bug that manifests in mapAddresses.count in irc.cpp, + // just need to call count here and it doesn't happen there. The bug was the + // pack pragma in irc.cpp and has been fixed, but I'm not in a hurry to delete this. + mapAddresses.count(vector(18)); + } + + return true; +} + +bool LoadAddresses() +{ + return CAddrDB("cr+").LoadAddresses(); +} + + + + +// +// CReviewDB +// + +bool CReviewDB::ReadReviews(uint256 hash, vector& vReviews) +{ + vReviews.size(); // msvc workaround, just need to do anything with vReviews + return Read(make_pair(string("reviews"), hash), vReviews); +} + +bool CReviewDB::WriteReviews(uint256 hash, const vector& vReviews) +{ + return Write(make_pair(string("reviews"), hash), vReviews); +} + + + + + + + +// +// CWalletDB +// + +bool CWalletDB::LoadWallet(vector& vchDefaultKeyRet) +{ + vchDefaultKeyRet.clear(); + + //// todo: shouldn't we catch exceptions and try to recover and continue? + CRITICAL_BLOCK(cs_mapKeys) + CRITICAL_BLOCK(cs_mapWallet) + { + // Get cursor + Dbc* pcursor = GetCursor(); + if (!pcursor) + return false; + + loop + { + // Read next record + CDataStream ssKey; + CDataStream ssValue; + int ret = ReadAtCursor(pcursor, ssKey, ssValue); + if (ret == DB_NOTFOUND) + break; + else if (ret != 0) + return false; + + // Unserialize + // Taking advantage of the fact that pair serialization + // is just the two items serialized one after the other + string strType; + ssKey >> strType; + if (strType == "name") + { + string strAddress; + ssKey >> strAddress; + ssValue >> mapAddressBook[strAddress]; + } + else if (strType == "tx") + { + uint256 hash; + ssKey >> hash; + CWalletTx& wtx = mapWallet[hash]; + ssValue >> wtx; + + if (wtx.GetHash() != hash) + printf("Error in wallet.dat, hash mismatch\n"); + + //// debug print + //printf("LoadWallet %s\n", wtx.GetHash().ToString().c_str()); + //printf(" %12I64d %s %s %s\n", + // wtx.vout[0].nValue, + // DateTimeStr(wtx.nTime).c_str(), + // wtx.hashBlock.ToString().substr(0,14).c_str(), + // wtx.mapValue["message"].c_str()); + } + else if (strType == "key") + { + vector vchPubKey; + ssKey >> vchPubKey; + CPrivKey vchPrivKey; + ssValue >> vchPrivKey; + + mapKeys[vchPubKey] = vchPrivKey; + mapPubKeys[Hash160(vchPubKey)] = vchPubKey; + } + else if (strType == "defaultkey") + { + ssValue >> vchDefaultKeyRet; + } + else if (strType == "setting") /// or settings or option or options or config? + { + string strKey; + ssKey >> strKey; + if (strKey == "fGenerateBitcoins") ssValue >> fGenerateBitcoins; + if (strKey == "nTransactionFee") ssValue >> nTransactionFee; + if (strKey == "addrIncoming") ssValue >> addrIncoming; + } + } + } + + printf("fGenerateBitcoins = %d\n", fGenerateBitcoins); + printf("nTransactionFee = %I64d\n", nTransactionFee); + printf("addrIncoming = %s\n", addrIncoming.ToString().c_str()); + + return true; +} + +bool LoadWallet() +{ + vector vchDefaultKey; + if (!CWalletDB("cr").LoadWallet(vchDefaultKey)) + return false; + + if (mapKeys.count(vchDefaultKey)) + { + // Set keyUser + keyUser.SetPubKey(vchDefaultKey); + keyUser.SetPrivKey(mapKeys[vchDefaultKey]); + } + else + { + // Create new keyUser and set as default key + RandAddSeed(true); + keyUser.MakeNewKey(); + if (!AddKey(keyUser)) + return false; + if (!SetAddressBookName(PubKeyToAddress(keyUser.GetPubKey()), "Your Address")) + return false; + CWalletDB().WriteDefaultKey(keyUser.GetPubKey()); + } + + return true; +} diff --git a/db.h b/db.h new file mode 100644 index 0000000000..1139f7686c --- /dev/null +++ b/db.h @@ -0,0 +1,420 @@ +// Copyright (c) 2009 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 +class CTransaction; +class CTxIndex; +class CDiskBlockIndex; +class CDiskTxPos; +class COutPoint; +class CUser; +class CReview; +class CAddress; +class CWalletTx; + +extern map mapAddressBook; +extern bool fClient; + + +extern DbEnv dbenv; +extern void DBFlush(bool fShutdown); + + + + +class CDB +{ +protected: + Db* pdb; + string strFile; + vector vTxn; + + explicit CDB(const char* pszFile, const char* pszMode="r+", bool fTxn=false); + ~CDB() { Close(); } +public: + void Close(); +private: + CDB(const CDB&); + void operator=(const CDB&); + +protected: + template + bool Read(const K& key, T& value) + { + if (!pdb) + return false; + + // Key + CDataStream ssKey(SER_DISK); + ssKey.reserve(1000); + ssKey << key; + Dbt datKey(&ssKey[0], ssKey.size()); + + // Read + Dbt datValue; + datValue.set_flags(DB_DBT_MALLOC); + int ret = pdb->get(GetTxn(), &datKey, &datValue, 0); + memset(datKey.get_data(), 0, datKey.get_size()); + if (datValue.get_data() == NULL) + return false; + + // Unserialize value + CDataStream ssValue((char*)datValue.get_data(), (char*)datValue.get_data() + datValue.get_size(), SER_DISK); + ssValue >> value; + + // Clear and free memory + memset(datValue.get_data(), 0, datValue.get_size()); + free(datValue.get_data()); + return (ret == 0); + } + + template + bool Write(const K& key, const T& value, bool fOverwrite=true) + { + if (!pdb) + return false; + + // Key + CDataStream ssKey(SER_DISK); + ssKey.reserve(1000); + ssKey << key; + Dbt datKey(&ssKey[0], ssKey.size()); + + // Value + CDataStream ssValue(SER_DISK); + ssValue.reserve(10000); + ssValue << value; + Dbt datValue(&ssValue[0], ssValue.size()); + + // Write + int ret = pdb->put(GetTxn(), &datKey, &datValue, (fOverwrite ? 0 : DB_NOOVERWRITE)); + + // Clear memory in case it was a private key + memset(datKey.get_data(), 0, datKey.get_size()); + memset(datValue.get_data(), 0, datValue.get_size()); + return (ret == 0); + } + + template + bool Erase(const K& key) + { + if (!pdb) + return false; + + // Key + CDataStream ssKey(SER_DISK); + ssKey.reserve(1000); + ssKey << key; + Dbt datKey(&ssKey[0], ssKey.size()); + + // Erase + int ret = pdb->del(GetTxn(), &datKey, 0); + + // Clear memory + memset(datKey.get_data(), 0, datKey.get_size()); + return (ret == 0 || ret == DB_NOTFOUND); + } + + template + bool Exists(const K& key) + { + if (!pdb) + return false; + + // Key + CDataStream ssKey(SER_DISK); + ssKey.reserve(1000); + ssKey << key; + Dbt datKey(&ssKey[0], ssKey.size()); + + // Exists + int ret = pdb->exists(GetTxn(), &datKey, 0); + + // Clear memory + memset(datKey.get_data(), 0, datKey.get_size()); + return (ret == 0); + } + + Dbc* GetCursor() + { + if (!pdb) + return NULL; + Dbc* pcursor = NULL; + int ret = pdb->cursor(NULL, &pcursor, 0); + if (ret != 0) + return NULL; + return pcursor; + } + + int ReadAtCursor(Dbc* pcursor, CDataStream& ssKey, CDataStream& ssValue, unsigned int fFlags=DB_NEXT) + { + // Read at cursor + Dbt datKey; + if (fFlags == DB_SET || fFlags == DB_SET_RANGE || fFlags == DB_GET_BOTH || fFlags == DB_GET_BOTH_RANGE) + { + datKey.set_data(&ssKey[0]); + datKey.set_size(ssKey.size()); + } + Dbt datValue; + if (fFlags == DB_GET_BOTH || fFlags == DB_GET_BOTH_RANGE) + { + datValue.set_data(&ssValue[0]); + datValue.set_size(ssValue.size()); + } + datKey.set_flags(DB_DBT_MALLOC); + datValue.set_flags(DB_DBT_MALLOC); + int ret = pcursor->get(&datKey, &datValue, fFlags); + if (ret != 0) + return ret; + else if (datKey.get_data() == NULL || datValue.get_data() == NULL) + return 99999; + + // Convert to streams + ssKey.SetType(SER_DISK); + ssKey.clear(); + ssKey.write((char*)datKey.get_data(), datKey.get_size()); + ssValue.SetType(SER_DISK); + ssValue.clear(); + ssValue.write((char*)datValue.get_data(), datValue.get_size()); + + // Clear and free memory + memset(datKey.get_data(), 0, datKey.get_size()); + memset(datValue.get_data(), 0, datValue.get_size()); + free(datKey.get_data()); + free(datValue.get_data()); + return 0; + } + + DbTxn* GetTxn() + { + if (!vTxn.empty()) + return vTxn.back(); + else + return NULL; + } + +public: + bool TxnBegin() + { + if (!pdb) + return false; + DbTxn* ptxn = NULL; + int ret = dbenv.txn_begin(GetTxn(), &ptxn, 0); + if (!ptxn || ret != 0) + return false; + vTxn.push_back(ptxn); + return true; + } + + bool TxnCommit() + { + if (!pdb) + return false; + if (vTxn.empty()) + return false; + int ret = vTxn.back()->commit(0); + vTxn.pop_back(); + return (ret == 0); + } + + bool TxnAbort() + { + if (!pdb) + return false; + if (vTxn.empty()) + return false; + int ret = vTxn.back()->abort(); + vTxn.pop_back(); + return (ret == 0); + } + + bool ReadVersion(int& nVersion) + { + nVersion = 0; + return Read(string("version"), nVersion); + } + + bool WriteVersion(int nVersion) + { + return Write(string("version"), nVersion); + } +}; + + + + + + + + +class CTxDB : public CDB +{ +public: + CTxDB(const char* pszMode="r+", bool fTxn=false) : CDB(!fClient ? "blkindex.dat" : NULL, pszMode, fTxn) { } +private: + CTxDB(const CTxDB&); + void operator=(const CTxDB&); +public: + bool ReadTxIndex(uint256 hash, CTxIndex& txindex); + bool UpdateTxIndex(uint256 hash, const CTxIndex& txindex); + bool AddTxIndex(const CTransaction& tx, const CDiskTxPos& pos, int nHeight); + bool EraseTxIndex(const CTransaction& tx); + bool ContainsTx(uint256 hash); + bool ReadOwnerTxes(uint160 hash160, int nHeight, vector& vtx); + bool ReadDiskTx(uint256 hash, CTransaction& tx, CTxIndex& txindex); + bool ReadDiskTx(uint256 hash, CTransaction& tx); + bool ReadDiskTx(COutPoint outpoint, CTransaction& tx, CTxIndex& txindex); + bool ReadDiskTx(COutPoint outpoint, CTransaction& tx); + bool WriteBlockIndex(const CDiskBlockIndex& blockindex); + bool EraseBlockIndex(uint256 hash); + bool ReadHashBestChain(uint256& hashBestChain); + bool WriteHashBestChain(uint256 hashBestChain); + bool LoadBlockIndex(); +}; + + + + + +class CReviewDB : public CDB +{ +public: + CReviewDB(const char* pszMode="r+", bool fTxn=false) : CDB("reviews.dat", pszMode, fTxn) { } +private: + CReviewDB(const CReviewDB&); + void operator=(const CReviewDB&); +public: + bool ReadUser(uint256 hash, CUser& user) + { + return Read(make_pair(string("user"), hash), user); + } + + bool WriteUser(uint256 hash, const CUser& user) + { + return Write(make_pair(string("user"), hash), user); + } + + bool ReadReviews(uint256 hash, vector& vReviews); + bool WriteReviews(uint256 hash, const vector& vReviews); +}; + + + + + +class CMarketDB : public CDB +{ +public: + CMarketDB(const char* pszMode="r+", bool fTxn=false) : CDB("market.dat", pszMode, fTxn) { } +private: + CMarketDB(const CMarketDB&); + void operator=(const CMarketDB&); +}; + + + + + +class CAddrDB : public CDB +{ +public: + CAddrDB(const char* pszMode="r+", bool fTxn=false) : CDB("addr.dat", pszMode, fTxn) { } +private: + CAddrDB(const CAddrDB&); + void operator=(const CAddrDB&); +public: + bool WriteAddress(const CAddress& addr); + bool LoadAddresses(); +}; + +bool LoadAddresses(); + + + + + +class CWalletDB : public CDB +{ +public: + CWalletDB(const char* pszMode="r+", bool fTxn=false) : CDB("wallet.dat", pszMode, fTxn) { } +private: + CWalletDB(const CWalletDB&); + void operator=(const CWalletDB&); +public: + bool ReadName(const string& strAddress, string& strName) + { + strName = ""; + return Read(make_pair(string("name"), strAddress), strName); + } + + bool WriteName(const string& strAddress, const string& strName) + { + mapAddressBook[strAddress] = strName; + return Write(make_pair(string("name"), strAddress), strName); + } + + bool EraseName(const string& strAddress) + { + mapAddressBook.erase(strAddress); + return Erase(make_pair(string("name"), strAddress)); + } + + bool ReadTx(uint256 hash, CWalletTx& wtx) + { + return Read(make_pair(string("tx"), hash), wtx); + } + + bool WriteTx(uint256 hash, const CWalletTx& wtx) + { + return Write(make_pair(string("tx"), hash), wtx); + } + + bool EraseTx(uint256 hash) + { + return Erase(make_pair(string("tx"), hash)); + } + + bool ReadKey(const vector& vchPubKey, CPrivKey& vchPrivKey) + { + vchPrivKey.clear(); + return Read(make_pair(string("key"), vchPubKey), vchPrivKey); + } + + bool WriteKey(const vector& vchPubKey, const CPrivKey& vchPrivKey) + { + return Write(make_pair(string("key"), vchPubKey), vchPrivKey, false); + } + + bool ReadDefaultKey(vector& vchPubKey) + { + vchPubKey.clear(); + return Read(string("defaultkey"), vchPubKey); + } + + bool WriteDefaultKey(const vector& vchPubKey) + { + return Write(string("defaultkey"), vchPubKey); + } + + template + bool ReadSetting(const string& strKey, T& value) + { + return Read(make_pair(string("setting"), strKey), value); + } + + template + bool WriteSetting(const string& strKey, const T& value) + { + return Write(make_pair(string("setting"), strKey), value); + } + + bool LoadWallet(vector& vchDefaultKeyRet); +}; + +bool LoadWallet(); + +inline bool SetAddressBookName(const string& strAddress, const string& strName) +{ + return CWalletDB().WriteName(strAddress, strName); +} diff --git a/headers.h b/headers.h new file mode 100644 index 0000000000..7bd68a1994 --- /dev/null +++ b/headers.h @@ -0,0 +1,71 @@ +// Copyright (c) 2009 Satoshi Nakamoto +// Distributed under the MIT/X11 software license, see the accompanying +// file license.txt or http://www.opensource.org/licenses/mit-license.php. + +#ifdef _MSC_VER +#pragma warning(disable:4786) +#pragma warning(disable:4804) +#pragma warning(disable:4717) +#endif +#ifdef _WIN32_WINNT +#undef _WIN32_WINNT +#endif +#define _WIN32_WINNT 0x0400 +#define WIN32_LEAN_AND_MEAN 1 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#define BOUNDSCHECK 1 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#pragma hdrstop +using namespace std; +using namespace boost; + + + +#include "serialize.h" +#include "uint256.h" +#include "util.h" +#include "key.h" +#include "bignum.h" +#include "base58.h" +#include "script.h" +#include "db.h" +#include "net.h" +#include "irc.h" +#include "main.h" +#include "market.h" +#include "uibase.h" +#include "ui.h" diff --git a/irc.cpp b/irc.cpp new file mode 100644 index 0000000000..3518df2491 --- /dev/null +++ b/irc.cpp @@ -0,0 +1,314 @@ +// Copyright (c) 2009 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" + + +map, CAddress> mapIRCAddresses; +CCriticalSection cs_mapIRCAddresses; + + + + +#pragma pack(push, 1) +struct ircaddr +{ + int ip; + short port; +}; +#pragma pack(pop) + +string EncodeAddress(const CAddress& addr) +{ + struct ircaddr tmp; + tmp.ip = addr.ip; + tmp.port = addr.port; + + vector vch(UBEGIN(tmp), UEND(tmp)); + return string("u") + EncodeBase58Check(vch); +} + +bool DecodeAddress(string str, CAddress& addr) +{ + vector vch; + if (!DecodeBase58Check(str.substr(1), vch)) + return false; + + struct ircaddr tmp; + if (vch.size() != sizeof(tmp)) + return false; + memcpy(&tmp, &vch[0], sizeof(tmp)); + + addr = CAddress(tmp.ip, tmp.port); + return true; +} + + + + + + +static bool Send(SOCKET hSocket, const char* pszSend) +{ + if (strstr(pszSend, "PONG") != pszSend) + printf("SENDING: %s\n", pszSend); + const char* psz = pszSend; + const char* pszEnd = psz + strlen(psz); + while (psz < pszEnd) + { + int ret = send(hSocket, psz, pszEnd - psz, 0); + if (ret < 0) + return false; + psz += ret; + } + return true; +} + +bool RecvLine(SOCKET hSocket, string& strLine) +{ + strLine = ""; + loop + { + char c; + int nBytes = recv(hSocket, &c, 1, 0); + if (nBytes > 0) + { + if (c == '\n') + continue; + if (c == '\r') + return true; + strLine += c; + } + else if (nBytes <= 0) + { + if (!strLine.empty()) + return true; + // socket closed + printf("IRC socket closed\n"); + return false; + } + else + { + // socket error + int nErr = WSAGetLastError(); + if (nErr != WSAEMSGSIZE && nErr != WSAEINTR && nErr != WSAEINPROGRESS) + { + printf("IRC recv failed: %d\n", nErr); + return false; + } + } + } +} + +bool RecvLineIRC(SOCKET hSocket, string& strLine) +{ + loop + { + bool fRet = RecvLine(hSocket, strLine); + if (fRet) + { + if (fShutdown) + return false; + vector vWords; + ParseString(strLine, ' ', vWords); + if (vWords[0] == "PING") + { + strLine[1] = 'O'; + strLine += '\r'; + Send(hSocket, strLine.c_str()); + continue; + } + } + return fRet; + } +} + +bool RecvUntil(SOCKET hSocket, const char* psz1, const char* psz2=NULL, const char* psz3=NULL) +{ + loop + { + string strLine; + if (!RecvLineIRC(hSocket, strLine)) + return false; + printf("IRC %s\n", strLine.c_str()); + if (psz1 && strLine.find(psz1) != -1) + return true; + if (psz2 && strLine.find(psz2) != -1) + return true; + if (psz3 && strLine.find(psz3) != -1) + return true; + } +} + +bool Wait(int nSeconds) +{ + if (fShutdown) + return false; + printf("Waiting %d seconds to reconnect to IRC\n", nSeconds); + for (int i = 0; i < nSeconds; i++) + { + if (fShutdown) + return false; + Sleep(1000); + } + return true; +} + + + +void ThreadIRCSeed(void* parg) +{ + SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_NORMAL); + int nErrorWait = 10; + int nRetryWait = 10; + + while (!fShutdown) + { + CAddress addrConnect("216.155.130.130:6667"); + struct hostent* phostent = gethostbyname("chat.freenode.net"); + if (phostent && phostent->h_addr_list && phostent->h_addr_list[0]) + addrConnect = CAddress(*(u_long*)phostent->h_addr_list[0], htons(6667)); + + SOCKET hSocket; + if (!ConnectSocket(addrConnect, hSocket)) + { + printf("IRC connect failed\n"); + nErrorWait = nErrorWait * 11 / 10; + if (Wait(nErrorWait += 60)) + continue; + else + return; + } + + if (!RecvUntil(hSocket, "Found your hostname", "using your IP address instead", "Couldn't look up your hostname")) + { + closesocket(hSocket); + nErrorWait = nErrorWait * 11 / 10; + if (Wait(nErrorWait += 60)) + continue; + else + return; + } + + string strMyName = EncodeAddress(addrLocalHost); + + if (!addrLocalHost.IsRoutable()) + strMyName = strprintf("x%u", GetRand(1000000000)); + + + Send(hSocket, strprintf("NICK %s\r", strMyName.c_str()).c_str()); + Send(hSocket, strprintf("USER %s 8 * : %s\r", strMyName.c_str(), strMyName.c_str()).c_str()); + + if (!RecvUntil(hSocket, " 004 ")) + { + closesocket(hSocket); + nErrorWait = nErrorWait * 11 / 10; + if (Wait(nErrorWait += 60)) + continue; + else + return; + } + Sleep(500); + + Send(hSocket, "JOIN #bitcoin\r"); + Send(hSocket, "WHO #bitcoin\r"); + + int64 nStart = GetTime(); + string strLine; + while (!fShutdown && RecvLineIRC(hSocket, strLine)) + { + if (strLine.empty() || strLine.size() > 900 || strLine[0] != ':') + continue; + printf("IRC %s\n", strLine.c_str()); + + vector vWords; + ParseString(strLine, ' ', vWords); + if (vWords.size() < 2) + continue; + + char pszName[10000]; + pszName[0] = '\0'; + + if (vWords[1] == "352" && vWords.size() >= 8) + { + // index 7 is limited to 16 characters + // could get full length name at index 10, but would be different from join messages + strcpy(pszName, vWords[7].c_str()); + printf("GOT WHO: [%s] ", pszName); + } + + if (vWords[1] == "JOIN" && vWords[0].size() > 1) + { + // :username!username@50000007.F000000B.90000002.IP JOIN :#channelname + strcpy(pszName, vWords[0].c_str() + 1); + if (strchr(pszName, '!')) + *strchr(pszName, '!') = '\0'; + printf("GOT JOIN: [%s] ", pszName); + } + + if (pszName[0] == 'u') + { + CAddress addr; + if (DecodeAddress(pszName, addr)) + { + CAddrDB addrdb; + if (AddAddress(addrdb, addr)) + printf("new "); + else + { + // make it try connecting again + CRITICAL_BLOCK(cs_mapAddresses) + if (mapAddresses.count(addr.GetKey())) + mapAddresses[addr.GetKey()].nLastFailed = 0; + } + addr.print(); + + CRITICAL_BLOCK(cs_mapIRCAddresses) + mapIRCAddresses.insert(make_pair(addr.GetKey(), addr)); + } + else + { + printf("decode failed\n"); + } + } + } + closesocket(hSocket); + + if (GetTime() - nStart > 20 * 60) + { + nErrorWait /= 3; + nRetryWait /= 3; + } + + nRetryWait = nRetryWait * 11 / 10; + if (!Wait(nRetryWait += 60)) + return; + } +} + + + + + + + + + + +#ifdef TEST +int main(int argc, char *argv[]) +{ + WSADATA wsadata; + if (WSAStartup(MAKEWORD(2,2), &wsadata) != NO_ERROR) + { + printf("Error at WSAStartup()\n"); + return false; + } + + ThreadIRCSeed(NULL); + + WSACleanup(); + return 0; +} +#endif diff --git a/irc.h b/irc.h new file mode 100644 index 0000000000..91c3ffe686 --- /dev/null +++ b/irc.h @@ -0,0 +1,10 @@ +// Copyright (c) 2009 Satoshi Nakamoto +// Distributed under the MIT/X11 software license, see the accompanying +// file license.txt or http://www.opensource.org/licenses/mit-license.php. + +extern bool RecvLine(SOCKET hSocket, string& strLine); +extern void ThreadIRCSeed(void* parg); +extern bool fRestartIRCSeed; + +extern map, CAddress> mapIRCAddresses; +extern CCriticalSection cs_mapIRCAddresses; diff --git a/key.h b/key.h new file mode 100644 index 0000000000..8b0b54e4b3 --- /dev/null +++ b/key.h @@ -0,0 +1,156 @@ +// Copyright (c) 2009 Satoshi Nakamoto +// Distributed under the MIT/X11 software license, see the accompanying +// file license.txt or http://www.opensource.org/licenses/mit-license.php. + + +// secp160k1 +// const unsigned int PRIVATE_KEY_SIZE = 192; +// const unsigned int PUBLIC_KEY_SIZE = 41; +// const unsigned int SIGNATURE_SIZE = 48; +// +// secp192k1 +// const unsigned int PRIVATE_KEY_SIZE = 222; +// const unsigned int PUBLIC_KEY_SIZE = 49; +// const unsigned int SIGNATURE_SIZE = 57; +// +// secp224k1 +// const unsigned int PRIVATE_KEY_SIZE = 250; +// const unsigned int PUBLIC_KEY_SIZE = 57; +// const unsigned int SIGNATURE_SIZE = 66; +// +// secp256k1: +// const unsigned int PRIVATE_KEY_SIZE = 279; +// const unsigned int PUBLIC_KEY_SIZE = 65; +// const unsigned int SIGNATURE_SIZE = 72; +// +// see www.keylength.com +// script supports up to 75 for single byte push + + + +class key_error : public std::runtime_error +{ +public: + explicit key_error(const std::string& str) : std::runtime_error(str) {} +}; + + +// secure_allocator is defined is serialize.h +typedef vector > CPrivKey; + + + +class CKey +{ +protected: + EC_KEY* pkey; + +public: + CKey() + { + pkey = EC_KEY_new_by_curve_name(NID_secp256k1); + if (pkey == NULL) + throw key_error("CKey::CKey() : EC_KEY_new_by_curve_name failed"); + } + + CKey(const CKey& b) + { + pkey = EC_KEY_dup(b.pkey); + if (pkey == NULL) + throw key_error("CKey::CKey(const CKey&) : EC_KEY_dup failed"); + } + + CKey& operator=(const CKey& b) + { + if (!EC_KEY_copy(pkey, b.pkey)) + throw key_error("CKey::operator=(const CKey&) : EC_KEY_copy failed"); + return (*this); + } + + ~CKey() + { + EC_KEY_free(pkey); + } + + void MakeNewKey() + { + if (!EC_KEY_generate_key(pkey)) + throw key_error("CKey::MakeNewKey() : EC_KEY_generate_key failed"); + } + + bool SetPrivKey(const CPrivKey& vchPrivKey) + { + const unsigned char* pbegin = &vchPrivKey[0]; + if (!d2i_ECPrivateKey(&pkey, &pbegin, vchPrivKey.size())) + return false; + return true; + } + + CPrivKey GetPrivKey() const + { + unsigned int nSize = i2d_ECPrivateKey(pkey, NULL); + if (!nSize) + throw key_error("CKey::GetPrivKey() : i2d_ECPrivateKey failed"); + CPrivKey vchPrivKey(nSize, 0); + unsigned char* pbegin = &vchPrivKey[0]; + if (i2d_ECPrivateKey(pkey, &pbegin) != nSize) + throw key_error("CKey::GetPrivKey() : i2d_ECPrivateKey returned unexpected size"); + return vchPrivKey; + } + + bool SetPubKey(const vector& vchPubKey) + { + const unsigned char* pbegin = &vchPubKey[0]; + if (!o2i_ECPublicKey(&pkey, &pbegin, vchPubKey.size())) + return false; + return true; + } + + vector GetPubKey() const + { + unsigned int nSize = i2o_ECPublicKey(pkey, NULL); + if (!nSize) + throw key_error("CKey::GetPubKey() : i2o_ECPublicKey failed"); + vector vchPubKey(nSize, 0); + unsigned char* pbegin = &vchPubKey[0]; + if (i2o_ECPublicKey(pkey, &pbegin) != nSize) + throw key_error("CKey::GetPubKey() : i2o_ECPublicKey returned unexpected size"); + return vchPubKey; + } + + bool Sign(uint256 hash, vector& vchSig) + { + vchSig.clear(); + unsigned char pchSig[10000]; + unsigned int nSize = 0; + if (!ECDSA_sign(0, (unsigned char*)&hash, sizeof(hash), pchSig, &nSize, pkey)) + return false; + vchSig.resize(nSize); + memcpy(&vchSig[0], pchSig, nSize); + return true; + } + + bool Verify(uint256 hash, const vector& vchSig) + { + // -1 = error, 0 = bad sig, 1 = good + if (ECDSA_verify(0, (unsigned char*)&hash, sizeof(hash), &vchSig[0], vchSig.size(), pkey) != 1) + return false; + return true; + } + + static bool Sign(const CPrivKey& vchPrivKey, uint256 hash, vector& vchSig) + { + CKey key; + if (!key.SetPrivKey(vchPrivKey)) + return false; + return key.Sign(hash, vchSig); + } + + static bool Verify(const vector& vchPubKey, uint256 hash, const vector& vchSig) + { + CKey key; + if (!key.SetPubKey(vchPubKey)) + return false; + return key.Verify(hash, vchSig); + } +}; diff --git a/libeay32.dll b/libeay32.dll new file mode 100644 index 0000000000..3bc745c4c0 Binary files /dev/null and b/libeay32.dll differ diff --git a/license.txt b/license.txt new file mode 100644 index 0000000000..3844dfb429 --- /dev/null +++ b/license.txt @@ -0,0 +1,19 @@ +Copyright (c) 2009 Satoshi Nakamoto + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/main.cpp b/main.cpp new file mode 100644 index 0000000000..97000db381 --- /dev/null +++ b/main.cpp @@ -0,0 +1,2692 @@ +// Copyright (c) 2009 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 "sha.h" + + + + + +// +// Global state +// + +CCriticalSection cs_main; + +map mapTransactions; +CCriticalSection cs_mapTransactions; +unsigned int nTransactionsUpdated = 0; +map mapNextTx; + +map mapBlockIndex; +const uint256 hashGenesisBlock("0x000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f"); +CBlockIndex* pindexGenesisBlock = NULL; +int nBestHeight = -1; +uint256 hashBestChain = 0; +CBlockIndex* pindexBest = NULL; + +map mapOrphanBlocks; +multimap mapOrphanBlocksByPrev; + +map mapOrphanTransactions; +multimap mapOrphanTransactionsByPrev; + +map mapWallet; +vector > vWalletUpdated; +CCriticalSection cs_mapWallet; + +map, CPrivKey> mapKeys; +map > mapPubKeys; +CCriticalSection cs_mapKeys; +CKey keyUser; + +string strSetDataDir; +int nDropMessagesTest = 0; + +// Settings +int fGenerateBitcoins; +int64 nTransactionFee = 0; +CAddress addrIncoming; + + + + + + + + +////////////////////////////////////////////////////////////////////////////// +// +// mapKeys +// + +bool AddKey(const CKey& key) +{ + CRITICAL_BLOCK(cs_mapKeys) + { + mapKeys[key.GetPubKey()] = key.GetPrivKey(); + mapPubKeys[Hash160(key.GetPubKey())] = key.GetPubKey(); + } + return CWalletDB().WriteKey(key.GetPubKey(), key.GetPrivKey()); +} + +vector GenerateNewKey() +{ + CKey key; + key.MakeNewKey(); + if (!AddKey(key)) + throw runtime_error("GenerateNewKey() : AddKey failed\n"); + return key.GetPubKey(); +} + + + + +////////////////////////////////////////////////////////////////////////////// +// +// mapWallet +// + +bool AddToWallet(const CWalletTx& wtxIn) +{ + uint256 hash = wtxIn.GetHash(); + CRITICAL_BLOCK(cs_mapWallet) + { + // Inserts only if not already there, returns tx inserted or tx found + pair::iterator, bool> ret = mapWallet.insert(make_pair(hash, wtxIn)); + CWalletTx& wtx = (*ret.first).second; + bool fInsertedNew = ret.second; + if (fInsertedNew) + wtx.nTimeReceived = GetAdjustedTime(); + + //// debug print + printf("AddToWallet %s %s\n", wtxIn.GetHash().ToString().substr(0,6).c_str(), fInsertedNew ? "new" : "update"); + + if (!fInsertedNew) + { + // Merge + bool fUpdated = false; + if (wtxIn.hashBlock != 0 && wtxIn.hashBlock != wtx.hashBlock) + { + wtx.hashBlock = wtxIn.hashBlock; + fUpdated = true; + } + if (wtxIn.nIndex != -1 && (wtxIn.vMerkleBranch != wtx.vMerkleBranch || wtxIn.nIndex != wtx.nIndex)) + { + wtx.vMerkleBranch = wtxIn.vMerkleBranch; + wtx.nIndex = wtxIn.nIndex; + fUpdated = true; + } + if (wtxIn.fFromMe && wtxIn.fFromMe != wtx.fFromMe) + { + wtx.fFromMe = wtxIn.fFromMe; + fUpdated = true; + } + if (wtxIn.fSpent && wtxIn.fSpent != wtx.fSpent) + { + wtx.fSpent = wtxIn.fSpent; + fUpdated = true; + } + if (!fUpdated) + return true; + } + + // Write to disk + if (!wtx.WriteToDisk()) + return false; + + // Notify UI + vWalletUpdated.push_back(make_pair(hash, fInsertedNew)); + } + + // Refresh UI + MainFrameRepaint(); + return true; +} + +bool AddToWalletIfMine(const CTransaction& tx, const CBlock* pblock) +{ + if (tx.IsMine() || mapWallet.count(tx.GetHash())) + { + CWalletTx wtx(tx); + // Get merkle branch if transaction was found in a block + if (pblock) + wtx.SetMerkleBranch(pblock); + return AddToWallet(wtx); + } + return true; +} + +bool EraseFromWallet(uint256 hash) +{ + CRITICAL_BLOCK(cs_mapWallet) + { + if (mapWallet.erase(hash)) + CWalletDB().EraseTx(hash); + } + return true; +} + + + + + + + + + +////////////////////////////////////////////////////////////////////////////// +// +// mapOrphanTransactions +// + +void AddOrphanTx(const CDataStream& vMsg) +{ + CTransaction tx; + CDataStream(vMsg) >> tx; + uint256 hash = tx.GetHash(); + if (mapOrphanTransactions.count(hash)) + return; + CDataStream* pvMsg = mapOrphanTransactions[hash] = new CDataStream(vMsg); + foreach(const CTxIn& txin, tx.vin) + mapOrphanTransactionsByPrev.insert(make_pair(txin.prevout.hash, pvMsg)); +} + +void EraseOrphanTx(uint256 hash) +{ + if (!mapOrphanTransactions.count(hash)) + return; + const CDataStream* pvMsg = mapOrphanTransactions[hash]; + CTransaction tx; + CDataStream(*pvMsg) >> tx; + foreach(const CTxIn& txin, tx.vin) + { + for (multimap::iterator mi = mapOrphanTransactionsByPrev.lower_bound(txin.prevout.hash); + mi != mapOrphanTransactionsByPrev.upper_bound(txin.prevout.hash);) + { + if ((*mi).second == pvMsg) + mapOrphanTransactionsByPrev.erase(mi++); + else + mi++; + } + } + delete pvMsg; + mapOrphanTransactions.erase(hash); +} + + + + + + + + +////////////////////////////////////////////////////////////////////////////// +// +// CTransaction +// + +bool CTxIn::IsMine() const +{ + CRITICAL_BLOCK(cs_mapWallet) + { + map::iterator mi = mapWallet.find(prevout.hash); + if (mi != mapWallet.end()) + { + const CWalletTx& prev = (*mi).second; + if (prevout.n < prev.vout.size()) + if (prev.vout[prevout.n].IsMine()) + return true; + } + } + return false; +} + +int64 CTxIn::GetDebit() const +{ + CRITICAL_BLOCK(cs_mapWallet) + { + map::iterator mi = mapWallet.find(prevout.hash); + if (mi != mapWallet.end()) + { + const CWalletTx& prev = (*mi).second; + if (prevout.n < prev.vout.size()) + if (prev.vout[prevout.n].IsMine()) + return prev.vout[prevout.n].nValue; + } + } + return 0; +} + +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::iterator mi = mapBlockIndex.find(hashBlock); + if (mi != mapBlockIndex.end()) + { + CBlockIndex* pindex = (*mi).second; + if (pindex) + return pindex->GetMedianTime(); + } + } + return nTimeReceived; +} + + + + + + +int CMerkleTx::SetMerkleBranch(const CBlock* pblock) +{ + if (fClient) + { + if (hashBlock == 0) + return 0; + } + else + { + CBlock blockTmp; + if (pblock == NULL) + { + // Load the block this tx is in + CTxIndex txindex; + if (!CTxDB("r").ReadTxIndex(GetHash(), txindex)) + return 0; + if (!blockTmp.ReadFromDisk(txindex.pos.nFile, txindex.pos.nBlockPos, true)) + return 0; + pblock = &blockTmp; + } + + // Update the tx's hashBlock + hashBlock = pblock->GetHash(); + + // Locate the transaction + for (nIndex = 0; nIndex < pblock->vtx.size(); nIndex++) + if (pblock->vtx[nIndex] == *(CTransaction*)this) + break; + if (nIndex == pblock->vtx.size()) + { + vMerkleBranch.clear(); + nIndex = -1; + printf("ERROR: SetMerkleBranch() : couldn't find tx in block\n"); + return 0; + } + + // Fill in merkle branch + vMerkleBranch = pblock->GetMerkleBranch(nIndex); + } + + // Is the tx in a block that's in the main chain + map::iterator mi = mapBlockIndex.find(hashBlock); + if (mi == mapBlockIndex.end()) + return 0; + CBlockIndex* pindex = (*mi).second; + if (!pindex || !pindex->IsInMainChain()) + return 0; + + return pindexBest->nHeight - pindex->nHeight + 1; +} + + + +void CWalletTx::AddSupportingTransactions(CTxDB& txdb) +{ + vtxPrev.clear(); + + const int COPY_DEPTH = 3; + if (SetMerkleBranch() < COPY_DEPTH) + { + vector vWorkQueue; + foreach(const CTxIn& txin, vin) + vWorkQueue.push_back(txin.prevout.hash); + + // This critsect is OK because txdb is already open + CRITICAL_BLOCK(cs_mapWallet) + { + map mapWalletPrev; + set setAlreadyDone; + for (int i = 0; i < vWorkQueue.size(); i++) + { + uint256 hash = vWorkQueue[i]; + if (setAlreadyDone.count(hash)) + continue; + setAlreadyDone.insert(hash); + + CMerkleTx tx; + if (mapWallet.count(hash)) + { + tx = mapWallet[hash]; + foreach(const CMerkleTx& txWalletPrev, mapWallet[hash].vtxPrev) + mapWalletPrev[txWalletPrev.GetHash()] = &txWalletPrev; + } + else if (mapWalletPrev.count(hash)) + { + tx = *mapWalletPrev[hash]; + } + else if (!fClient && txdb.ReadDiskTx(hash, tx)) + { + ; + } + else + { + printf("ERROR: AddSupportingTransactions() : unsupported transaction\n"); + continue; + } + + int nDepth = tx.SetMerkleBranch(); + vtxPrev.push_back(tx); + + if (nDepth < COPY_DEPTH) + foreach(const CTxIn& txin, tx.vin) + vWorkQueue.push_back(txin.prevout.hash); + } + } + } + + reverse(vtxPrev.begin(), vtxPrev.end()); +} + + + + + + + + + + + +bool CTransaction::AcceptTransaction(CTxDB& txdb, bool fCheckInputs, bool* pfMissingInputs) +{ + if (pfMissingInputs) + *pfMissingInputs = false; + + // Coinbase is only valid in a block, not as a loose transaction + if (IsCoinBase()) + return error("AcceptTransaction() : coinbase as individual tx"); + + if (!CheckTransaction()) + return error("AcceptTransaction() : CheckTransaction failed"); + + // Do we already have it? + uint256 hash = GetHash(); + CRITICAL_BLOCK(cs_mapTransactions) + if (mapTransactions.count(hash)) + return false; + if (fCheckInputs) + if (txdb.ContainsTx(hash)) + return false; + + // Check for conflicts with in-memory transactions + CTransaction* ptxOld = NULL; + for (int i = 0; i < vin.size(); i++) + { + COutPoint outpoint = vin[i].prevout; + if (mapNextTx.count(outpoint)) + { + // Allow replacing with a newer version of the same transaction + if (i != 0) + return false; + ptxOld = mapNextTx[outpoint].ptx; + if (!IsNewerThan(*ptxOld)) + return false; + for (int i = 0; i < vin.size(); i++) + { + COutPoint outpoint = vin[i].prevout; + if (!mapNextTx.count(outpoint) || mapNextTx[outpoint].ptx != ptxOld) + return false; + } + break; + } + } + + // Check against previous transactions + map mapUnused; + int64 nFees = 0; + if (fCheckInputs && !ConnectInputs(txdb, mapUnused, CDiskTxPos(1,1,1), 0, nFees, false, false)) + { + if (pfMissingInputs) + *pfMissingInputs = true; + return error("AcceptTransaction() : ConnectInputs failed %s", hash.ToString().substr(0,6).c_str()); + } + + // Store transaction in memory + CRITICAL_BLOCK(cs_mapTransactions) + { + if (ptxOld) + { + printf("mapTransaction.erase(%s) replacing with new version\n", ptxOld->GetHash().ToString().c_str()); + mapTransactions.erase(ptxOld->GetHash()); + } + AddToMemoryPool(); + } + + ///// are we sure this is ok when loading transactions or restoring block txes + // If updated, erase old tx from wallet + if (ptxOld) + EraseFromWallet(ptxOld->GetHash()); + + printf("AcceptTransaction(): accepted %s\n", hash.ToString().substr(0,6).c_str()); + return true; +} + + +bool CTransaction::AddToMemoryPool() +{ + // Add to memory pool without checking anything. Don't call this directly, + // call AcceptTransaction to properly check the transaction first. + CRITICAL_BLOCK(cs_mapTransactions) + { + uint256 hash = GetHash(); + mapTransactions[hash] = *this; + for (int i = 0; i < vin.size(); i++) + mapNextTx[vin[i].prevout] = CInPoint(&mapTransactions[hash], i); + nTransactionsUpdated++; + } + return true; +} + + +bool CTransaction::RemoveFromMemoryPool() +{ + // Remove transaction from memory pool + CRITICAL_BLOCK(cs_mapTransactions) + { + foreach(const CTxIn& txin, vin) + mapNextTx.erase(txin.prevout); + mapTransactions.erase(GetHash()); + nTransactionsUpdated++; + } + return true; +} + + + + + + +int CMerkleTx::GetDepthInMainChain() const +{ + if (hashBlock == 0 || nIndex == -1) + return 0; + + // Find the block it claims to be in + map::iterator mi = mapBlockIndex.find(hashBlock); + if (mi == mapBlockIndex.end()) + return 0; + CBlockIndex* pindex = (*mi).second; + if (!pindex || !pindex->IsInMainChain()) + return 0; + + // Make sure the merkle branch connects to this block + if (!fMerkleVerified) + { + if (CBlock::CheckMerkleBranch(GetHash(), vMerkleBranch, nIndex) != pindex->hashMerkleRoot) + return 0; + fMerkleVerified = true; + } + + return pindexBest->nHeight - pindex->nHeight + 1; +} + + +int CMerkleTx::GetBlocksToMaturity() const +{ + if (!IsCoinBase()) + return 0; + return max(0, (COINBASE_MATURITY+20) - GetDepthInMainChain()); +} + + +bool CMerkleTx::AcceptTransaction(CTxDB& txdb, bool fCheckInputs) +{ + if (fClient) + { + if (!IsInMainChain() && !ClientConnectInputs()) + return false; + return CTransaction::AcceptTransaction(txdb, false); + } + else + { + return CTransaction::AcceptTransaction(txdb, fCheckInputs); + } +} + + + +bool CWalletTx::AcceptWalletTransaction(CTxDB& txdb, bool fCheckInputs) +{ + CRITICAL_BLOCK(cs_mapTransactions) + { + foreach(CMerkleTx& tx, vtxPrev) + { + if (!tx.IsCoinBase()) + { + uint256 hash = tx.GetHash(); + if (!mapTransactions.count(hash) && !txdb.ContainsTx(hash)) + tx.AcceptTransaction(txdb, fCheckInputs); + } + } + if (!IsCoinBase()) + return AcceptTransaction(txdb, fCheckInputs); + } + return true; +} + +void ReacceptWalletTransactions() +{ + // Reaccept any txes of ours that aren't already in a block + CTxDB txdb("r"); + CRITICAL_BLOCK(cs_mapWallet) + { + foreach(PAIRTYPE(const uint256, CWalletTx)& item, mapWallet) + { + CWalletTx& wtx = item.second; + if (!wtx.IsCoinBase() && !txdb.ContainsTx(wtx.GetHash())) + wtx.AcceptWalletTransaction(txdb, false); + } + } +} + + +void CWalletTx::RelayWalletTransaction(CTxDB& txdb) +{ + foreach(const CMerkleTx& tx, vtxPrev) + { + if (!tx.IsCoinBase()) + { + uint256 hash = tx.GetHash(); + if (!txdb.ContainsTx(hash)) + RelayMessage(CInv(MSG_TX, hash), (CTransaction)tx); + } + } + if (!IsCoinBase()) + { + uint256 hash = GetHash(); + if (!txdb.ContainsTx(hash)) + { + printf("Relaying wtx %s\n", hash.ToString().substr(0,6).c_str()); + RelayMessage(CInv(MSG_TX, hash), (CTransaction)*this); + } + } +} + +void RelayWalletTransactions() +{ + static int64 nLastTime; + if (GetTime() - nLastTime < 10 * 60) + return; + nLastTime = GetTime(); + + // Rebroadcast any of our txes that aren't in a block yet + printf("RelayWalletTransactions()\n"); + CTxDB txdb("r"); + CRITICAL_BLOCK(cs_mapWallet) + { + // Sort them in chronological order + multimap mapSorted; + foreach(PAIRTYPE(const uint256, CWalletTx)& item, mapWallet) + { + CWalletTx& wtx = item.second; + mapSorted.insert(make_pair(wtx.nTimeReceived, &wtx)); + } + foreach(PAIRTYPE(const unsigned int, CWalletTx*)& item, mapSorted) + { + CWalletTx& wtx = *item.second; + wtx.RelayWalletTransaction(txdb); + } + } +} + + + + + + + + + + +////////////////////////////////////////////////////////////////////////////// +// +// CBlock and CBlockIndex +// + +bool CBlock::ReadFromDisk(const CBlockIndex* pblockindex, bool fReadTransactions) +{ + return ReadFromDisk(pblockindex->nFile, pblockindex->nBlockPos, fReadTransactions); +} + +uint256 GetOrphanRoot(const CBlock* pblock) +{ + // Work back to the first block in the orphan chain + while (mapOrphanBlocks.count(pblock->hashPrevBlock)) + pblock = mapOrphanBlocks[pblock->hashPrevBlock]; + return pblock->GetHash(); +} + +int64 CBlock::GetBlockValue(int64 nFees) const +{ + int64 nSubsidy = 50 * COIN; + + // Subsidy is cut in half every 4 years + nSubsidy >>= (nBestHeight / 210000); + + return nSubsidy + nFees; +} + +unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast) +{ + const unsigned int nTargetTimespan = 14 * 24 * 60 * 60; // two weeks + const unsigned int nTargetSpacing = 10 * 60; + const unsigned int nInterval = nTargetTimespan / nTargetSpacing; + + // Genesis block + if (pindexLast == NULL) + return bnProofOfWorkLimit.GetCompact(); + + // Only change once per interval + if ((pindexLast->nHeight+1) % nInterval != 0) + return pindexLast->nBits; + + // Go back by what we want to be 14 days worth of blocks + const CBlockIndex* pindexFirst = pindexLast; + for (int i = 0; pindexFirst && i < nInterval-1; i++) + pindexFirst = pindexFirst->pprev; + assert(pindexFirst); + + // Limit adjustment step + unsigned int nActualTimespan = pindexLast->nTime - pindexFirst->nTime; + printf(" nActualTimespan = %d before bounds\n", nActualTimespan); + if (nActualTimespan < nTargetTimespan/4) + nActualTimespan = nTargetTimespan/4; + if (nActualTimespan > nTargetTimespan*4) + nActualTimespan = nTargetTimespan*4; + + // Retarget + CBigNum bnNew; + bnNew.SetCompact(pindexLast->nBits); + bnNew *= nActualTimespan; + bnNew /= nTargetTimespan; + + if (bnNew > bnProofOfWorkLimit) + bnNew = bnProofOfWorkLimit; + + /// debug print + printf("\n\n\nGetNextWorkRequired RETARGET *****\n"); + printf("nTargetTimespan = %d nActualTimespan = %d\n", nTargetTimespan, nActualTimespan); + printf("Before: %08x %s\n", pindexLast->nBits, CBigNum().SetCompact(pindexLast->nBits).getuint256().ToString().c_str()); + printf("After: %08x %s\n", bnNew.GetCompact(), bnNew.getuint256().ToString().c_str()); + + return bnNew.GetCompact(); +} + + + + + + + + + +bool CTransaction::DisconnectInputs(CTxDB& txdb) +{ + // Relinquish previous transactions' spent pointers + if (!IsCoinBase()) + { + foreach(const CTxIn& txin, vin) + { + COutPoint prevout = txin.prevout; + + // Get prev txindex from disk + CTxIndex txindex; + if (!txdb.ReadTxIndex(prevout.hash, txindex)) + return error("DisconnectInputs() : ReadTxIndex failed"); + + if (prevout.n >= txindex.vSpent.size()) + return error("DisconnectInputs() : prevout.n out of range"); + + // Mark outpoint as not spent + txindex.vSpent[prevout.n].SetNull(); + + // Write back + txdb.UpdateTxIndex(prevout.hash, txindex); + } + } + + // Remove transaction from index + if (!txdb.EraseTxIndex(*this)) + return error("DisconnectInputs() : EraseTxPos failed"); + + return true; +} + + +bool CTransaction::ConnectInputs(CTxDB& txdb, map& mapTestPool, CDiskTxPos posThisTx, int nHeight, int64& nFees, bool fBlock, bool fMiner, int64 nMinFee) +{ + // Take over previous transactions' spent pointers + if (!IsCoinBase()) + { + int64 nValueIn = 0; + for (int i = 0; i < vin.size(); i++) + { + COutPoint prevout = vin[i].prevout; + + // Read txindex + CTxIndex txindex; + bool fFound = true; + if (fMiner && mapTestPool.count(prevout.hash)) + { + // Get txindex from current proposed changes + txindex = mapTestPool[prevout.hash]; + } + else + { + // Read txindex from txdb + fFound = txdb.ReadTxIndex(prevout.hash, txindex); + } + if (!fFound && (fBlock || fMiner)) + return fMiner ? false : error("ConnectInputs() : %s prev tx %s index entry not found", GetHash().ToString().substr(0,6).c_str(), prevout.hash.ToString().substr(0,6).c_str()); + + // Read txPrev + CTransaction txPrev; + if (!fFound || txindex.pos == CDiskTxPos(1,1,1)) + { + // Get prev tx from single transactions in memory + CRITICAL_BLOCK(cs_mapTransactions) + { + if (!mapTransactions.count(prevout.hash)) + return error("ConnectInputs() : %s mapTransactions prev not found %s", GetHash().ToString().substr(0,6).c_str(), prevout.hash.ToString().substr(0,6).c_str()); + txPrev = mapTransactions[prevout.hash]; + } + if (!fFound) + txindex.vSpent.resize(txPrev.vout.size()); + } + else + { + // Get prev tx from disk + if (!txPrev.ReadFromDisk(txindex.pos)) + return error("ConnectInputs() : %s ReadFromDisk prev tx %s failed", GetHash().ToString().substr(0,6).c_str(), prevout.hash.ToString().substr(0,6).c_str()); + } + + if (prevout.n >= txPrev.vout.size() || prevout.n >= txindex.vSpent.size()) + return error("ConnectInputs() : %s prevout.n out of range %d %d %d", GetHash().ToString().substr(0,6).c_str(), prevout.n, txPrev.vout.size(), txindex.vSpent.size()); + + // If prev is coinbase, check that it's matured + if (txPrev.IsCoinBase()) + for (CBlockIndex* pindex = pindexBest; pindex && nBestHeight - pindex->nHeight < COINBASE_MATURITY-1; pindex = pindex->pprev) + if (pindex->nBlockPos == txindex.pos.nBlockPos && pindex->nFile == txindex.pos.nFile) + return error("ConnectInputs() : tried to spend coinbase at depth %d", nBestHeight - pindex->nHeight); + + // Verify signature + if (!VerifySignature(txPrev, *this, i)) + return error("ConnectInputs() : %s VerifySignature failed", GetHash().ToString().substr(0,6).c_str()); + + // Check for conflicts + if (!txindex.vSpent[prevout.n].IsNull()) + return fMiner ? false : error("ConnectInputs() : %s prev tx already used at %s", GetHash().ToString().substr(0,6).c_str(), txindex.vSpent[prevout.n].ToString().c_str()); + + // Mark outpoints as spent + txindex.vSpent[prevout.n] = posThisTx; + + // Write back + if (fBlock) + txdb.UpdateTxIndex(prevout.hash, txindex); + else if (fMiner) + mapTestPool[prevout.hash] = txindex; + + nValueIn += txPrev.vout[prevout.n].nValue; + } + + // Tally transaction fees + int64 nTxFee = nValueIn - GetValueOut(); + if (nTxFee < 0) + return error("ConnectInputs() : %s nTxFee < 0", GetHash().ToString().substr(0,6).c_str()); + if (nTxFee < nMinFee) + return false; + nFees += nTxFee; + } + + if (fBlock) + { + // Add transaction to disk index + if (!txdb.AddTxIndex(*this, posThisTx, nHeight)) + return error("ConnectInputs() : AddTxPos failed"); + } + else if (fMiner) + { + // Add transaction to test pool + mapTestPool[GetHash()] = CTxIndex(CDiskTxPos(1,1,1), vout.size()); + } + + return true; +} + + +bool CTransaction::ClientConnectInputs() +{ + if (IsCoinBase()) + return false; + + // Take over previous transactions' spent pointers + CRITICAL_BLOCK(cs_mapTransactions) + { + int64 nValueIn = 0; + for (int i = 0; i < vin.size(); i++) + { + // Get prev tx from single transactions in memory + COutPoint prevout = vin[i].prevout; + if (!mapTransactions.count(prevout.hash)) + return false; + CTransaction& txPrev = mapTransactions[prevout.hash]; + + if (prevout.n >= txPrev.vout.size()) + return false; + + // Verify signature + if (!VerifySignature(txPrev, *this, i)) + return error("ConnectInputs() : VerifySignature failed"); + + ///// this is redundant with the mapNextTx stuff, not sure which I want to get rid of + ///// this has to go away now that posNext is gone + // // Check for conflicts + // if (!txPrev.vout[prevout.n].posNext.IsNull()) + // return error("ConnectInputs() : prev tx already used"); + // + // // Flag outpoints as used + // txPrev.vout[prevout.n].posNext = posThisTx; + + nValueIn += txPrev.vout[prevout.n].nValue; + } + if (GetValueOut() > nValueIn) + return false; + } + + return true; +} + + + + +bool CBlock::DisconnectBlock(CTxDB& txdb, CBlockIndex* pindex) +{ + // Disconnect in reverse order + for (int i = vtx.size()-1; i >= 0; i--) + if (!vtx[i].DisconnectInputs(txdb)) + return false; + + // Update block index on disk without changing it in memory. + // The memory index structure will be changed after the db commits. + if (pindex->pprev) + { + CDiskBlockIndex blockindexPrev(pindex->pprev); + blockindexPrev.hashNext = 0; + txdb.WriteBlockIndex(blockindexPrev); + } + + return true; +} + +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 mapUnused; + int64 nFees = 0; + foreach(CTransaction& tx, vtx) + { + CDiskTxPos posThisTx(pindex->nFile, pindex->nBlockPos, nTxPos); + nTxPos += ::GetSerializeSize(tx, SER_DISK); + + if (!tx.ConnectInputs(txdb, mapUnused, posThisTx, pindex->nHeight, nFees, true, false)) + return false; + } + + if (vtx[0].GetValueOut() > GetBlockValue(nFees)) + return false; + + // Update block index on disk without changing it in memory. + // The memory index structure will be changed after the db commits. + if (pindex->pprev) + { + CDiskBlockIndex blockindexPrev(pindex->pprev); + blockindexPrev.hashNext = pindex->GetBlockHash(); + txdb.WriteBlockIndex(blockindexPrev); + } + + // Watch for transactions paying to me + foreach(CTransaction& tx, vtx) + AddToWalletIfMine(tx, this); + + return true; +} + + + +bool Reorganize(CTxDB& txdb, CBlockIndex* pindexNew) +{ + printf("*** REORGANIZE ***\n"); + + // Find the fork + CBlockIndex* pfork = pindexBest; + CBlockIndex* plonger = pindexNew; + while (pfork != plonger) + { + if (!(pfork = pfork->pprev)) + return error("Reorganize() : pfork->pprev is null"); + while (plonger->nHeight > pfork->nHeight) + if (!(plonger = plonger->pprev)) + return error("Reorganize() : plonger->pprev is null"); + } + + // List of what to disconnect + vector vDisconnect; + for (CBlockIndex* pindex = pindexBest; pindex != pfork; pindex = pindex->pprev) + vDisconnect.push_back(pindex); + + // List of what to connect + vector vConnect; + for (CBlockIndex* pindex = pindexNew; pindex != pfork; pindex = pindex->pprev) + vConnect.push_back(pindex); + reverse(vConnect.begin(), vConnect.end()); + + // Disconnect shorter branch + vector vResurrect; + foreach(CBlockIndex* pindex, vDisconnect) + { + CBlock block; + if (!block.ReadFromDisk(pindex->nFile, pindex->nBlockPos, true)) + return error("Reorganize() : ReadFromDisk for disconnect failed"); + if (!block.DisconnectBlock(txdb, pindex)) + return error("Reorganize() : DisconnectBlock failed"); + + // Queue memory transactions to resurrect + foreach(const CTransaction& tx, block.vtx) + if (!tx.IsCoinBase()) + vResurrect.push_back(tx); + } + + // Connect longer branch + vector vDelete; + for (int i = 0; i < vConnect.size(); i++) + { + CBlockIndex* pindex = vConnect[i]; + CBlock block; + if (!block.ReadFromDisk(pindex->nFile, pindex->nBlockPos, true)) + return error("Reorganize() : ReadFromDisk for connect failed"); + if (!block.ConnectBlock(txdb, pindex)) + { + // Invalid block, delete the rest of this branch + txdb.TxnAbort(); + for (int j = i; j < vConnect.size(); j++) + { + CBlockIndex* pindex = vConnect[j]; + pindex->EraseBlockFromDisk(); + txdb.EraseBlockIndex(pindex->GetBlockHash()); + mapBlockIndex.erase(pindex->GetBlockHash()); + delete pindex; + } + return error("Reorganize() : ConnectBlock failed"); + } + + // Queue memory transactions to delete + foreach(const CTransaction& tx, block.vtx) + vDelete.push_back(tx); + } + if (!txdb.WriteHashBestChain(pindexNew->GetBlockHash())) + return error("Reorganize() : WriteHashBestChain failed"); + + // Commit now because resurrecting could take some time + txdb.TxnCommit(); + + // Disconnect shorter branch + foreach(CBlockIndex* pindex, vDisconnect) + if (pindex->pprev) + pindex->pprev->pnext = NULL; + + // Connect longer branch + foreach(CBlockIndex* pindex, vConnect) + if (pindex->pprev) + pindex->pprev->pnext = pindex; + + // Resurrect memory transactions that were in the disconnected branch + foreach(CTransaction& tx, vResurrect) + tx.AcceptTransaction(txdb, false); + + // Delete redundant memory transactions that are in the connected branch + foreach(CTransaction& tx, vDelete) + tx.RemoveFromMemoryPool(); + + return true; +} + + +bool CBlock::AddToBlockIndex(unsigned int nFile, unsigned int nBlockPos) +{ + // Check for duplicate + uint256 hash = GetHash(); + if (mapBlockIndex.count(hash)) + return error("AddToBlockIndex() : %s already exists", hash.ToString().substr(0,14).c_str()); + + // Construct new block index object + CBlockIndex* pindexNew = new CBlockIndex(nFile, nBlockPos, *this); + if (!pindexNew) + return error("AddToBlockIndex() : new CBlockIndex failed"); + map::iterator mi = mapBlockIndex.insert(make_pair(hash, pindexNew)).first; + pindexNew->phashBlock = &((*mi).first); + map::iterator miPrev = mapBlockIndex.find(hashPrevBlock); + if (miPrev != mapBlockIndex.end()) + { + pindexNew->pprev = (*miPrev).second; + pindexNew->nHeight = pindexNew->pprev->nHeight + 1; + } + + CTxDB txdb; + txdb.TxnBegin(); + txdb.WriteBlockIndex(CDiskBlockIndex(pindexNew)); + + // New best + if (pindexNew->nHeight > nBestHeight) + { + if (pindexGenesisBlock == NULL && hash == hashGenesisBlock) + { + pindexGenesisBlock = pindexNew; + txdb.WriteHashBestChain(hash); + } + else if (hashPrevBlock == hashBestChain) + { + // Adding to current best branch + if (!ConnectBlock(txdb, pindexNew) || !txdb.WriteHashBestChain(hash)) + { + txdb.TxnAbort(); + pindexNew->EraseBlockFromDisk(); + mapBlockIndex.erase(pindexNew->GetBlockHash()); + delete pindexNew; + return error("AddToBlockIndex() : ConnectBlock failed"); + } + txdb.TxnCommit(); + pindexNew->pprev->pnext = pindexNew; + + // Delete redundant memory transactions + foreach(CTransaction& tx, vtx) + tx.RemoveFromMemoryPool(); + } + else + { + // New best branch + if (!Reorganize(txdb, pindexNew)) + { + txdb.TxnAbort(); + return error("AddToBlockIndex() : Reorganize failed"); + } + } + + // New best link + hashBestChain = hash; + pindexBest = pindexNew; + nBestHeight = pindexBest->nHeight; + nTransactionsUpdated++; + printf("AddToBlockIndex: new best=%s height=%d\n", hashBestChain.ToString().substr(0,14).c_str(), nBestHeight); + } + + txdb.TxnCommit(); + txdb.Close(); + + // Relay wallet transactions that haven't gotten in yet + if (pindexNew == pindexBest) + RelayWalletTransactions(); + + MainFrameRepaint(); + return true; +} + + + + +bool CBlock::CheckBlock() const +{ + // These are checks that are independent of context + // that can be verified before saving an orphan block. + + // Size limits + if (vtx.empty() || vtx.size() > MAX_SIZE || ::GetSerializeSize(*this, SER_DISK) > MAX_SIZE) + return error("CheckBlock() : size limits failed"); + + // Check timestamp + if (nTime > GetAdjustedTime() + 2 * 60 * 60) + return error("CheckBlock() : block timestamp too far in the future"); + + // First transaction must be coinbase, the rest must not be + if (vtx.empty() || !vtx[0].IsCoinBase()) + return 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"); + + // Check transactions + foreach(const CTransaction& tx, vtx) + if (!tx.CheckTransaction()) + return error("CheckBlock() : CheckTransaction failed"); + + // Check proof of work matches claimed amount + if (CBigNum().SetCompact(nBits) > bnProofOfWorkLimit) + return error("CheckBlock() : nBits below minimum work"); + if (GetHash() > CBigNum().SetCompact(nBits).getuint256()) + return error("CheckBlock() : hash doesn't match nBits"); + + // Check merkleroot + if (hashMerkleRoot != BuildMerkleTree()) + return error("CheckBlock() : hashMerkleRoot mismatch"); + + return true; +} + +bool CBlock::AcceptBlock() +{ + // Check for duplicate + uint256 hash = GetHash(); + if (mapBlockIndex.count(hash)) + return error("AcceptBlock() : block already in mapBlockIndex"); + + // Get prev block index + map::iterator mi = mapBlockIndex.find(hashPrevBlock); + if (mi == mapBlockIndex.end()) + return error("AcceptBlock() : prev block not found"); + CBlockIndex* pindexPrev = (*mi).second; + + // Check timestamp against prev + if (nTime <= pindexPrev->GetMedianTimePast()) + return error("AcceptBlock() : block's timestamp is too early"); + + // Check proof of work + if (nBits != GetNextWorkRequired(pindexPrev)) + return error("AcceptBlock() : incorrect proof of work"); + + // Write block to history file + if (!CheckDiskSpace(::GetSerializeSize(*this, SER_DISK))) + return error("AcceptBlock() : out of disk space"); + unsigned int nFile; + unsigned int nBlockPos; + if (!WriteToDisk(!fClient, nFile, nBlockPos)) + return error("AcceptBlock() : WriteToDisk failed"); + if (!AddToBlockIndex(nFile, nBlockPos)) + return error("AcceptBlock() : AddToBlockIndex failed"); + + if (hashBestChain == hash) + RelayInventory(CInv(MSG_BLOCK, hash)); + + // // Add atoms to user reviews for coins created + // vector vchPubKey; + // if (ExtractPubKey(vtx[0].vout[0].scriptPubKey, false, vchPubKey)) + // { + // unsigned short nAtom = GetRand(USHRT_MAX - 100) + 100; + // vector vAtoms(1, nAtom); + // AddAtomsAndPropagate(Hash(vchPubKey.begin(), vchPubKey.end()), vAtoms, true); + // } + + return true; +} + +bool ProcessBlock(CNode* pfrom, CBlock* pblock) +{ + // Check for duplicate + uint256 hash = pblock->GetHash(); + if (mapBlockIndex.count(hash)) + return error("ProcessBlock() : already have block %d %s", mapBlockIndex[hash]->nHeight, hash.ToString().substr(0,14).c_str()); + if (mapOrphanBlocks.count(hash)) + return error("ProcessBlock() : already have block (orphan) %s", hash.ToString().substr(0,14).c_str()); + + // Preliminary checks + if (!pblock->CheckBlock()) + { + delete pblock; + return error("ProcessBlock() : CheckBlock FAILED"); + } + + // If don't already have its previous block, shunt it off to holding area until we get it + if (!mapBlockIndex.count(pblock->hashPrevBlock)) + { + printf("ProcessBlock: ORPHAN BLOCK, prev=%s\n", pblock->hashPrevBlock.ToString().substr(0,14).c_str()); + mapOrphanBlocks.insert(make_pair(hash, pblock)); + mapOrphanBlocksByPrev.insert(make_pair(pblock->hashPrevBlock, pblock)); + + // Ask this guy to fill in what we're missing + if (pfrom) + pfrom->PushMessage("getblocks", CBlockLocator(pindexBest), GetOrphanRoot(pblock)); + return true; + } + + // Store to disk + if (!pblock->AcceptBlock()) + { + delete pblock; + return error("ProcessBlock() : AcceptBlock FAILED"); + } + delete pblock; + + // Recursively process any orphan blocks that depended on this one + vector vWorkQueue; + vWorkQueue.push_back(hash); + for (int i = 0; i < vWorkQueue.size(); i++) + { + uint256 hashPrev = vWorkQueue[i]; + for (multimap::iterator mi = mapOrphanBlocksByPrev.lower_bound(hashPrev); + mi != mapOrphanBlocksByPrev.upper_bound(hashPrev); + ++mi) + { + CBlock* pblockOrphan = (*mi).second; + if (pblockOrphan->AcceptBlock()) + vWorkQueue.push_back(pblockOrphan->GetHash()); + mapOrphanBlocks.erase(pblockOrphan->GetHash()); + delete pblockOrphan; + } + mapOrphanBlocksByPrev.erase(hashPrev); + } + + printf("ProcessBlock: ACCEPTED\n"); + return true; +} + + + + + + + + +template +bool 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; + } +} + +string GetAppDir() +{ + string strDir; + if (!strSetDataDir.empty()) + { + strDir = strSetDataDir; + } + else if (getenv("APPDATA")) + { + strDir = strprintf("%s\\Bitcoin", getenv("APPDATA")); + } + else if (getenv("USERPROFILE")) + { + string strAppData = strprintf("%s\\Application Data", getenv("USERPROFILE")); + static bool fMkdirDone; + if (!fMkdirDone) + { + fMkdirDone = true; + _mkdir(strAppData.c_str()); + } + strDir = strprintf("%s\\Bitcoin", strAppData.c_str()); + } + else + { + return "."; + } + static bool fMkdirDone; + if (!fMkdirDone) + { + fMkdirDone = true; + _mkdir(strDir.c_str()); + } + return strDir; +} + +bool CheckDiskSpace(int64 nAdditionalBytes) +{ + uint64 nFreeBytesAvailable = 0; // bytes available to caller + uint64 nTotalNumberOfBytes = 0; // bytes on disk + uint64 nTotalNumberOfFreeBytes = 0; // free bytes on disk + + if (!GetDiskFreeSpaceEx(GetAppDir().c_str(), + (PULARGE_INTEGER)&nFreeBytesAvailable, + (PULARGE_INTEGER)&nTotalNumberOfBytes, + (PULARGE_INTEGER)&nTotalNumberOfFreeBytes)) + { + printf("ERROR: GetDiskFreeSpaceEx() failed\n"); + return true; + } + + // Check for 15MB because database could create another 10MB log file at any time + if ((int64)nFreeBytesAvailable < 15000000 + nAdditionalBytes) + { + fShutdown = true; + wxMessageBox("Warning: Your disk space is low ", "Bitcoin", wxICON_EXCLAMATION); + _beginthread(Shutdown, 0, NULL); + return false; + } + return true; +} + +FILE* OpenBlockFile(unsigned int nFile, unsigned int nBlockPos, const char* pszMode) +{ + if (nFile == -1) + return NULL; + FILE* file = fopen(strprintf("%s\\blk%04d.dat", GetAppDir().c_str(), nFile).c_str(), pszMode); + if (!file) + return NULL; + if (nBlockPos != 0 && !strchr(pszMode, 'a') && !strchr(pszMode, 'w')) + { + if (fseek(file, nBlockPos, SEEK_SET) != 0) + { + fclose(file); + return NULL; + } + } + return file; +} + +static unsigned int nCurrentBlockFile = 1; + +FILE* AppendBlockFile(unsigned int& nFileRet) +{ + nFileRet = 0; + loop + { + FILE* file = OpenBlockFile(nCurrentBlockFile, 0, "ab"); + if (!file) + return NULL; + if (fseek(file, 0, SEEK_END) != 0) + return NULL; + // FAT32 filesize max 4GB, fseek and ftell max 2GB, so we must stay under 2GB + if (ftell(file) < 0x7F000000 - MAX_SIZE) + { + nFileRet = nCurrentBlockFile; + return file; + } + fclose(file); + nCurrentBlockFile++; + } +} + +bool LoadBlockIndex(bool fAllowNew) +{ + // + // Load block index + // + CTxDB txdb("cr"); + if (!txdb.LoadBlockIndex()) + return false; + txdb.Close(); + + // + // Init with genesis block + // + if (mapBlockIndex.empty()) + { + if (!fAllowNew) + return false; + + + // Genesis Block: + // GetHash() = 0x000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f + // hashMerkleRoot = 0x4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b + // txNew.vin[0].scriptSig = 486604799 4 0x736B6E616220726F662074756F6C69616220646E6F63657320666F206B6E697262206E6F20726F6C6C65636E61684320393030322F6E614A2F33302073656D695420656854 + // txNew.vout[0].nValue = 5000000000 + // txNew.vout[0].scriptPubKey = 0x5F1DF16B2B704C8A578D0BBAF74D385CDE12C11EE50455F3C438EF4C3FBCF649B6DE611FEAE06279A60939E028A8D65C10B73071A6F16719274855FEB0FD8A6704 OP_CHECKSIG + // block.nVersion = 1 + // block.nTime = 1231006505 + // block.nBits = 0x1d00ffff + // block.nNonce = 2083236893 + // CBlock(hash=000000000019d6, ver=1, hashPrevBlock=00000000000000, hashMerkleRoot=4a5e1e, nTime=1231006505, nBits=1d00ffff, nNonce=2083236893, vtx=1) + // CTransaction(hash=4a5e1e, ver=1, vin.size=1, vout.size=1, nLockTime=0) + // CTxIn(COutPoint(000000, -1), coinbase 04ffff001d0104455468652054696d65732030332f4a616e2f32303039204368616e63656c6c6f72206f6e206272696e6b206f66207365636f6e64206261696c6f757420666f722062616e6b73) + // CTxOut(nValue=50.00000000, scriptPubKey=0x5F1DF16B2B704C8A578D0B) + // vMerkleTree: 4a5e1e + + // Genesis block + char* pszTimestamp = "The Times 03/Jan/2009 Chancellor on brink of second bailout for banks"; + CTransaction txNew; + txNew.vin.resize(1); + txNew.vout.resize(1); + txNew.vin[0].scriptSig = CScript() << 486604799 << CBigNum(4) << vector((unsigned char*)pszTimestamp, (unsigned char*)pszTimestamp + strlen(pszTimestamp)); + txNew.vout[0].nValue = 50 * COIN; + txNew.vout[0].scriptPubKey = CScript() << CBigNum("0x5F1DF16B2B704C8A578D0BBAF74D385CDE12C11EE50455F3C438EF4C3FBCF649B6DE611FEAE06279A60939E028A8D65C10B73071A6F16719274855FEB0FD8A6704") << OP_CHECKSIG; + CBlock block; + block.vtx.push_back(txNew); + block.hashPrevBlock = 0; + block.hashMerkleRoot = block.BuildMerkleTree(); + block.nVersion = 1; + block.nTime = 1231006505; + block.nBits = 0x1d00ffff; + block.nNonce = 2083236893; + + //// debug print, delete this later + printf("%s\n", block.GetHash().ToString().c_str()); + printf("%s\n", block.hashMerkleRoot.ToString().c_str()); + printf("%s\n", hashGenesisBlock.ToString().c_str()); + txNew.vout[0].scriptPubKey.print(); + block.print(); + assert(block.hashMerkleRoot == uint256("0x4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b")); + + assert(block.GetHash() == hashGenesisBlock); + + // Start new block file + unsigned int nFile; + unsigned int nBlockPos; + if (!block.WriteToDisk(!fClient, nFile, nBlockPos)) + return error("LoadBlockIndex() : writing genesis block to disk failed"); + if (!block.AddToBlockIndex(nFile, nBlockPos)) + return error("LoadBlockIndex() : genesis block not accepted"); + } + + return true; +} + + + +void PrintBlockTree() +{ + // precompute tree structure + map > mapNext; + for (map::iterator mi = mapBlockIndex.begin(); mi != mapBlockIndex.end(); ++mi) + { + CBlockIndex* pindex = (*mi).second; + mapNext[pindex->pprev].push_back(pindex); + // test + //while (rand() % 3 == 0) + // mapNext[pindex->pprev].push_back(pindex); + } + + vector > vStack; + vStack.push_back(make_pair(0, pindexGenesisBlock)); + + int nPrevCol = 0; + while (!vStack.empty()) + { + int nCol = vStack.back().first; + CBlockIndex* pindex = vStack.back().second; + vStack.pop_back(); + + // print split or gap + if (nCol > nPrevCol) + { + for (int i = 0; i < nCol-1; i++) + printf("| "); + printf("|\\\n"); + } + else if (nCol < nPrevCol) + { + for (int i = 0; i < nCol; i++) + printf("| "); + printf("|\n"); + } + nPrevCol = nCol; + + // print columns + for (int i = 0; i < nCol; i++) + printf("| "); + + // print item + CBlock block; + block.ReadFromDisk(pindex, true); + printf("%d (%u,%u) %s %s tx %d", + pindex->nHeight, + pindex->nFile, + pindex->nBlockPos, + block.GetHash().ToString().substr(0,14).c_str(), + DateTimeStr(block.nTime).c_str(), + block.vtx.size()); + + CRITICAL_BLOCK(cs_mapWallet) + { + if (mapWallet.count(block.vtx[0].GetHash())) + { + CWalletTx& wtx = mapWallet[block.vtx[0].GetHash()]; + printf(" mine: %d %d %d", wtx.GetDepthInMainChain(), wtx.GetBlocksToMaturity(), wtx.GetCredit()); + } + } + printf("\n"); + + + // put the main timechain first + vector& vNext = mapNext[pindex]; + for (int i = 0; i < vNext.size(); i++) + { + if (vNext[i]->pnext) + { + swap(vNext[0], vNext[i]); + break; + } + } + + // iterate children + for (int i = 0; i < vNext.size(); i++) + vStack.push_back(make_pair(nCol+i, vNext[i])); + } +} + + + + + + + + + + +////////////////////////////////////////////////////////////////////////////// +// +// Messages +// + + +bool AlreadyHave(CTxDB& txdb, const CInv& inv) +{ + switch (inv.type) + { + case MSG_TX: return mapTransactions.count(inv.hash) || txdb.ContainsTx(inv.hash); + case MSG_BLOCK: return mapBlockIndex.count(inv.hash) || mapOrphanBlocks.count(inv.hash); + case MSG_REVIEW: return true; + case MSG_PRODUCT: return mapProducts.count(inv.hash); + } + // Don't know what it is, just say we already got one + return true; +} + + + + + + + +bool ProcessMessages(CNode* pfrom) +{ + CDataStream& vRecv = pfrom->vRecv; + if (vRecv.empty()) + return true; + printf("ProcessMessages(%d bytes)\n", vRecv.size()); + + // + // Message format + // (4) message start + // (12) command + // (4) size + // (x) data + // + + loop + { + // Scan for message start + CDataStream::iterator pstart = search(vRecv.begin(), vRecv.end(), BEGIN(pchMessageStart), END(pchMessageStart)); + if (vRecv.end() - pstart < sizeof(CMessageHeader)) + { + if (vRecv.size() > sizeof(CMessageHeader)) + { + printf("\n\nPROCESSMESSAGE MESSAGESTART NOT FOUND\n\n"); + vRecv.erase(vRecv.begin(), vRecv.end() - sizeof(CMessageHeader)); + } + break; + } + if (pstart - vRecv.begin() > 0) + printf("\n\nPROCESSMESSAGE SKIPPED %d BYTES\n\n", pstart - vRecv.begin()); + vRecv.erase(vRecv.begin(), pstart); + + // Read header + CMessageHeader hdr; + vRecv >> hdr; + if (!hdr.IsValid()) + { + printf("\n\nPROCESSMESSAGE: ERRORS IN HEADER %s\n\n\n", hdr.GetCommand().c_str()); + continue; + } + string strCommand = hdr.GetCommand(); + + // Message size + unsigned int nMessageSize = hdr.nMessageSize; + if (nMessageSize > vRecv.size()) + { + // Rewind and wait for rest of message + ///// need a mechanism to give up waiting for overlong message size error + printf("MESSAGE-BREAK\n"); + vRecv.insert(vRecv.begin(), BEGIN(hdr), END(hdr)); + Sleep(100); + break; + } + + // Copy message to its own buffer + CDataStream vMsg(vRecv.begin(), vRecv.begin() + nMessageSize, vRecv.nType, vRecv.nVersion); + vRecv.ignore(nMessageSize); + + // Process message + bool fRet = false; + try + { + CheckForShutdown(2); + CRITICAL_BLOCK(cs_main) + fRet = ProcessMessage(pfrom, strCommand, vMsg); + CheckForShutdown(2); + } + CATCH_PRINT_EXCEPTION("ProcessMessage()") + if (!fRet) + printf("ProcessMessage(%s, %d bytes) from %s to %s FAILED\n", strCommand.c_str(), nMessageSize, pfrom->addr.ToString().c_str(), addrLocalHost.ToString().c_str()); + } + + vRecv.Compact(); + return true; +} + + + + +bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) +{ + static map > mapReuseKey; + printf("received: %-12s (%d bytes) ", strCommand.c_str(), vRecv.size()); + for (int i = 0; i < min(vRecv.size(), (unsigned int)20); i++) + printf("%02x ", vRecv[i] & 0xff); + printf("\n"); + if (nDropMessagesTest > 0 && GetRand(nDropMessagesTest) == 0) + { + printf("dropmessages DROPPING RECV MESSAGE\n"); + return true; + } + + + + if (strCommand == "version") + { + // Can only do this once + if (pfrom->nVersion != 0) + return false; + + int64 nTime; + CAddress addrMe; + vRecv >> pfrom->nVersion >> pfrom->nServices >> nTime >> addrMe; + if (pfrom->nVersion == 0) + return false; + + pfrom->vSend.SetVersion(min(pfrom->nVersion, VERSION)); + pfrom->vRecv.SetVersion(min(pfrom->nVersion, VERSION)); + + pfrom->fClient = !(pfrom->nServices & NODE_NETWORK); + if (pfrom->fClient) + { + pfrom->vSend.nType |= SER_BLOCKHEADERONLY; + pfrom->vRecv.nType |= SER_BLOCKHEADERONLY; + } + + AddTimeData(pfrom->addr.ip, nTime); + + // Ask the first connected node for block updates + static bool fAskedForBlocks; + if (!fAskedForBlocks && !pfrom->fClient) + { + fAskedForBlocks = true; + pfrom->PushMessage("getblocks", CBlockLocator(pindexBest), uint256(0)); + } + + printf("version message: %s has version %d, addrMe=%s\n", pfrom->addr.ToString().c_str(), pfrom->nVersion, addrMe.ToString().c_str()); + } + + + else if (pfrom->nVersion == 0) + { + // Must have a version message before anything else + return false; + } + + + else if (strCommand == "addr") + { + vector vAddr; + vRecv >> vAddr; + + // Store the new addresses + CAddrDB addrdb; + foreach(const CAddress& addr, vAddr) + { + if (fShutdown) + return true; + if (AddAddress(addrdb, addr)) + { + // Put on lists to send to other nodes + pfrom->setAddrKnown.insert(addr); + CRITICAL_BLOCK(cs_vNodes) + foreach(CNode* pnode, vNodes) + if (!pnode->setAddrKnown.count(addr)) + pnode->vAddrToSend.push_back(addr); + } + } + } + + + else if (strCommand == "inv") + { + vector vInv; + vRecv >> vInv; + + CTxDB txdb("r"); + foreach(const CInv& inv, vInv) + { + if (fShutdown) + return true; + pfrom->AddInventoryKnown(inv); + + bool fAlreadyHave = AlreadyHave(txdb, inv); + printf(" got inventory: %s %s\n", inv.ToString().c_str(), fAlreadyHave ? "have" : "new"); + + if (!fAlreadyHave) + pfrom->AskFor(inv); + else if (inv.type == MSG_BLOCK && mapOrphanBlocks.count(inv.hash)) + pfrom->PushMessage("getblocks", CBlockLocator(pindexBest), GetOrphanRoot(mapOrphanBlocks[inv.hash])); + } + } + + + else if (strCommand == "getdata") + { + vector vInv; + vRecv >> vInv; + + foreach(const CInv& inv, vInv) + { + if (fShutdown) + return true; + printf("received getdata for: %s\n", inv.ToString().c_str()); + + if (inv.type == MSG_BLOCK) + { + // Send block from disk + map::iterator mi = mapBlockIndex.find(inv.hash); + if (mi != mapBlockIndex.end()) + { + //// could optimize this to send header straight from blockindex for client + CBlock block; + block.ReadFromDisk((*mi).second, !pfrom->fClient); + pfrom->PushMessage("block", block); + } + } + else if (inv.IsKnownType()) + { + // Send stream from relay memory + CRITICAL_BLOCK(cs_mapRelay) + { + map::iterator mi = mapRelay.find(inv); + if (mi != mapRelay.end()) + pfrom->PushMessage(inv.GetCommand(), (*mi).second); + } + } + } + } + + + else if (strCommand == "getblocks") + { + CBlockLocator locator; + uint256 hashStop; + vRecv >> locator >> hashStop; + + // Find the first block the caller has in the main chain + CBlockIndex* pindex = locator.GetBlockIndex(); + + // Send the rest of the chain + if (pindex) + pindex = pindex->pnext; + printf("getblocks %d to %s\n", (pindex ? pindex->nHeight : -1), hashStop.ToString().substr(0,14).c_str()); + for (; pindex; pindex = pindex->pnext) + { + if (pindex->GetBlockHash() == hashStop) + { + printf(" getblocks stopping at %d %s\n", pindex->nHeight, pindex->GetBlockHash().ToString().substr(0,14).c_str()); + break; + } + + // Bypass setInventoryKnown in case an inventory message got lost + CRITICAL_BLOCK(pfrom->cs_inventory) + { + CInv inv(MSG_BLOCK, pindex->GetBlockHash()); + // returns true if wasn't already contained in the set + if (pfrom->setInventoryKnown2.insert(inv).second) + { + pfrom->setInventoryKnown.erase(inv); + pfrom->vInventoryToSend.push_back(inv); + } + } + } + } + + + else if (strCommand == "tx") + { + vector vWorkQueue; + CDataStream vMsg(vRecv); + CTransaction tx; + vRecv >> tx; + + CInv inv(MSG_TX, tx.GetHash()); + pfrom->AddInventoryKnown(inv); + + bool fMissingInputs = false; + if (tx.AcceptTransaction(true, &fMissingInputs)) + { + AddToWalletIfMine(tx, NULL); + RelayMessage(inv, vMsg); + mapAlreadyAskedFor.erase(inv); + vWorkQueue.push_back(inv.hash); + + // Recursively process any orphan transactions that depended on this one + for (int i = 0; i < vWorkQueue.size(); i++) + { + uint256 hashPrev = vWorkQueue[i]; + for (multimap::iterator mi = mapOrphanTransactionsByPrev.lower_bound(hashPrev); + mi != mapOrphanTransactionsByPrev.upper_bound(hashPrev); + ++mi) + { + const CDataStream& vMsg = *((*mi).second); + CTransaction tx; + CDataStream(vMsg) >> tx; + CInv inv(MSG_TX, tx.GetHash()); + + if (tx.AcceptTransaction(true)) + { + printf(" accepted orphan tx %s\n", inv.hash.ToString().substr(0,6).c_str()); + AddToWalletIfMine(tx, NULL); + RelayMessage(inv, vMsg); + mapAlreadyAskedFor.erase(inv); + vWorkQueue.push_back(inv.hash); + } + } + } + + foreach(uint256 hash, vWorkQueue) + EraseOrphanTx(hash); + } + else if (fMissingInputs) + { + printf("storing orphan tx %s\n", inv.hash.ToString().substr(0,6).c_str()); + AddOrphanTx(vMsg); + } + } + + + else if (strCommand == "review") + { + CDataStream vMsg(vRecv); + CReview review; + vRecv >> review; + + CInv inv(MSG_REVIEW, review.GetHash()); + pfrom->AddInventoryKnown(inv); + + if (review.AcceptReview()) + { + // Relay the original message as-is in case it's a higher version than we know how to parse + RelayMessage(inv, vMsg); + mapAlreadyAskedFor.erase(inv); + } + } + + + else if (strCommand == "block") + { + auto_ptr pblock(new CBlock); + vRecv >> *pblock; + + //// debug print + printf("received block:\n"); pblock->print(); + + CInv inv(MSG_BLOCK, pblock->GetHash()); + pfrom->AddInventoryKnown(inv); + + if (ProcessBlock(pfrom, pblock.release())) + mapAlreadyAskedFor.erase(inv); + } + + + else if (strCommand == "getaddr") + { + pfrom->vAddrToSend.clear(); + int64 nSince = GetAdjustedTime() - 5 * 24 * 60 * 60; // in the last 5 days + CRITICAL_BLOCK(cs_mapAddresses) + { + unsigned int nSize = mapAddresses.size(); + foreach(const PAIRTYPE(vector, CAddress)& item, mapAddresses) + { + if (fShutdown) + return true; + const CAddress& addr = item.second; + //// will need this if we lose IRC + //if (addr.nTime > nSince || (rand() % nSize) < 500) + if (addr.nTime > nSince) + pfrom->vAddrToSend.push_back(addr); + } + } + } + + + else if (strCommand == "checkorder") + { + uint256 hashReply; + CWalletTx order; + vRecv >> hashReply >> order; + + /// we have a chance to check the order here + + // Keep giving the same key to the same ip until they use it + if (!mapReuseKey.count(pfrom->addr.ip)) + mapReuseKey[pfrom->addr.ip] = GenerateNewKey(); + + // Send back approval of order and pubkey to use + CScript scriptPubKey; + scriptPubKey << mapReuseKey[pfrom->addr.ip] << OP_CHECKSIG; + pfrom->PushMessage("reply", hashReply, (int)0, scriptPubKey); + } + + + else if (strCommand == "submitorder") + { + uint256 hashReply; + CWalletTx wtxNew; + vRecv >> hashReply >> wtxNew; + + // Broadcast + if (!wtxNew.AcceptWalletTransaction()) + { + pfrom->PushMessage("reply", hashReply, (int)1); + return error("submitorder AcceptWalletTransaction() failed, returning error 1"); + } + wtxNew.fTimeReceivedIsTxTime = true; + AddToWallet(wtxNew); + wtxNew.RelayWalletTransaction(); + mapReuseKey.erase(pfrom->addr.ip); + + // Send back confirmation + pfrom->PushMessage("reply", hashReply, (int)0); + } + + + else if (strCommand == "reply") + { + uint256 hashReply; + vRecv >> hashReply; + + CRequestTracker tracker; + CRITICAL_BLOCK(pfrom->cs_mapRequests) + { + map::iterator mi = pfrom->mapRequests.find(hashReply); + if (mi != pfrom->mapRequests.end()) + { + tracker = (*mi).second; + pfrom->mapRequests.erase(mi); + } + } + if (!tracker.IsNull()) + tracker.fn(tracker.param1, vRecv); + } + + + else + { + // Ignore unknown commands for extensibility + printf("ProcessMessage(%s) : Ignored unknown message\n", strCommand.c_str()); + } + + + if (!vRecv.empty()) + printf("ProcessMessage(%s) : %d extra bytes\n", strCommand.c_str(), vRecv.size()); + + return true; +} + + + + + + + + + +bool SendMessages(CNode* pto) +{ + CheckForShutdown(2); + CRITICAL_BLOCK(cs_main) + { + // Don't send anything until we get their version message + if (pto->nVersion == 0) + return true; + + + // + // Message: addr + // + vector vAddrToSend; + vAddrToSend.reserve(pto->vAddrToSend.size()); + foreach(const CAddress& addr, pto->vAddrToSend) + if (!pto->setAddrKnown.count(addr)) + vAddrToSend.push_back(addr); + pto->vAddrToSend.clear(); + if (!vAddrToSend.empty()) + pto->PushMessage("addr", vAddrToSend); + + + // + // Message: inventory + // + vector vInventoryToSend; + CRITICAL_BLOCK(pto->cs_inventory) + { + vInventoryToSend.reserve(pto->vInventoryToSend.size()); + foreach(const CInv& inv, pto->vInventoryToSend) + { + // returns true if wasn't already contained in the set + if (pto->setInventoryKnown.insert(inv).second) + vInventoryToSend.push_back(inv); + } + pto->vInventoryToSend.clear(); + pto->setInventoryKnown2.clear(); + } + if (!vInventoryToSend.empty()) + pto->PushMessage("inv", vInventoryToSend); + + + // + // Message: getdata + // + vector vAskFor; + int64 nNow = GetTime() * 1000000; + CTxDB txdb("r"); + while (!pto->mapAskFor.empty() && (*pto->mapAskFor.begin()).first <= nNow) + { + const CInv& inv = (*pto->mapAskFor.begin()).second; + printf("sending getdata: %s\n", inv.ToString().c_str()); + if (!AlreadyHave(txdb, inv)) + vAskFor.push_back(inv); + pto->mapAskFor.erase(pto->mapAskFor.begin()); + } + if (!vAskFor.empty()) + pto->PushMessage("getdata", vAskFor); + + } + return true; +} + + + + + + + + + + + + + + +////////////////////////////////////////////////////////////////////////////// +// +// BitcoinMiner +// + +int FormatHashBlocks(void* pbuffer, unsigned int len) +{ + unsigned char* pdata = (unsigned char*)pbuffer; + unsigned int blocks = 1 + ((len + 8) / 64); + unsigned char* pend = pdata + 64 * blocks; + memset(pdata + len, 0, 64 * blocks - len); + pdata[len] = 0x80; + unsigned int bits = len * 8; + pend[-1] = (bits >> 0) & 0xff; + pend[-2] = (bits >> 8) & 0xff; + pend[-3] = (bits >> 16) & 0xff; + pend[-4] = (bits >> 24) & 0xff; + return blocks; +} + +using CryptoPP::ByteReverse; +static int detectlittleendian = 1; + +void BlockSHA256(const void* pin, unsigned int nBlocks, void* pout) +{ + unsigned int* pinput = (unsigned int*)pin; + unsigned int* pstate = (unsigned int*)pout; + + CryptoPP::SHA256::InitState(pstate); + + if (*(char*)&detectlittleendian != 0) + { + for (int n = 0; n < nBlocks; n++) + { + unsigned int pbuf[16]; + for (int i = 0; i < 16; i++) + pbuf[i] = ByteReverse(pinput[n * 16 + i]); + CryptoPP::SHA256::Transform(pstate, pbuf); + } + for (int i = 0; i < 8; i++) + pstate[i] = ByteReverse(pstate[i]); + } + else + { + for (int n = 0; n < nBlocks; n++) + CryptoPP::SHA256::Transform(pstate, pinput + n * 16); + } +} + + +bool BitcoinMiner() +{ + printf("BitcoinMiner started\n"); + SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_LOWEST); + + CKey key; + key.MakeNewKey(); + CBigNum bnExtraNonce = 0; + while (fGenerateBitcoins) + { + Sleep(50); + CheckForShutdown(3); + while (vNodes.empty()) + { + Sleep(1000); + CheckForShutdown(3); + } + + unsigned int nTransactionsUpdatedLast = nTransactionsUpdated; + CBlockIndex* pindexPrev = pindexBest; + unsigned int nBits = GetNextWorkRequired(pindexPrev); + + + // + // Create coinbase tx + // + CTransaction txNew; + txNew.vin.resize(1); + txNew.vin[0].prevout.SetNull(); + txNew.vin[0].scriptSig << nBits << ++bnExtraNonce; + txNew.vout.resize(1); + txNew.vout[0].scriptPubKey << key.GetPubKey() << OP_CHECKSIG; + + + // + // Create new block + // + auto_ptr pblock(new CBlock()); + if (!pblock.get()) + return false; + + // Add our coinbase tx as first transaction + pblock->vtx.push_back(txNew); + + // Collect the latest transactions into the block + int64 nFees = 0; + CRITICAL_BLOCK(cs_main) + CRITICAL_BLOCK(cs_mapTransactions) + { + CTxDB txdb("r"); + map mapTestPool; + vector vfAlreadyAdded(mapTransactions.size()); + bool fFoundSomething = true; + unsigned int nBlockSize = 0; + while (fFoundSomething && nBlockSize < MAX_SIZE/2) + { + fFoundSomething = false; + unsigned int n = 0; + for (map::iterator mi = mapTransactions.begin(); mi != mapTransactions.end(); ++mi, ++n) + { + if (vfAlreadyAdded[n]) + continue; + CTransaction& tx = (*mi).second; + if (tx.IsCoinBase() || !tx.IsFinal()) + continue; + + // Transaction fee requirements, mainly only needed for flood control + // Under 10K (about 80 inputs) is free for first 100 transactions + // Base rate is 0.01 per KB + int64 nMinFee = tx.GetMinFee(pblock->vtx.size() < 100); + + map mapTestPoolTmp(mapTestPool); + if (!tx.ConnectInputs(txdb, mapTestPoolTmp, CDiskTxPos(1,1,1), 0, nFees, false, true, nMinFee)) + continue; + swap(mapTestPool, mapTestPoolTmp); + + pblock->vtx.push_back(tx); + nBlockSize += ::GetSerializeSize(tx, SER_NETWORK); + vfAlreadyAdded[n] = true; + fFoundSomething = true; + } + } + } + pblock->nBits = nBits; + pblock->vtx[0].vout[0].nValue = pblock->GetBlockValue(nFees); + printf("\n\nRunning BitcoinMiner with %d transactions in block\n", pblock->vtx.size()); + + + // + // Prebuild hash buffer + // + struct unnamed1 + { + struct unnamed2 + { + int nVersion; + uint256 hashPrevBlock; + uint256 hashMerkleRoot; + unsigned int nTime; + unsigned int nBits; + unsigned int nNonce; + } + block; + unsigned char pchPadding0[64]; + uint256 hash1; + unsigned char pchPadding1[64]; + } + tmp; + + tmp.block.nVersion = pblock->nVersion; + tmp.block.hashPrevBlock = pblock->hashPrevBlock = (pindexPrev ? pindexPrev->GetBlockHash() : 0); + tmp.block.hashMerkleRoot = pblock->hashMerkleRoot = pblock->BuildMerkleTree(); + tmp.block.nTime = pblock->nTime = max((pindexPrev ? pindexPrev->GetMedianTimePast()+1 : 0), GetAdjustedTime()); + tmp.block.nBits = pblock->nBits = nBits; + tmp.block.nNonce = pblock->nNonce = 1; + + unsigned int nBlocks0 = FormatHashBlocks(&tmp.block, sizeof(tmp.block)); + unsigned int nBlocks1 = FormatHashBlocks(&tmp.hash1, sizeof(tmp.hash1)); + + + // + // Search + // + unsigned int nStart = GetTime(); + uint256 hashTarget = CBigNum().SetCompact(pblock->nBits).getuint256(); + uint256 hash; + loop + { + BlockSHA256(&tmp.block, nBlocks0, &tmp.hash1); + BlockSHA256(&tmp.hash1, nBlocks1, &hash); + + + if (hash <= hashTarget) + { + pblock->nNonce = tmp.block.nNonce; + assert(hash == pblock->GetHash()); + + //// debug print + printf("BitcoinMiner:\n"); + printf("proof-of-work found \n hash: %s \ntarget: %s\n", hash.GetHex().c_str(), hashTarget.GetHex().c_str()); + pblock->print(); + + SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_NORMAL); + CRITICAL_BLOCK(cs_main) + { + // Save key + if (!AddKey(key)) + return false; + key.MakeNewKey(); + + // Process this block the same as if we had received it from another node + if (!ProcessBlock(NULL, pblock.release())) + printf("ERROR in BitcoinMiner, ProcessBlock, block not accepted\n"); + } + SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_LOWEST); + + Sleep(500); + break; + } + + // Update nTime every few seconds + if ((++tmp.block.nNonce & 0x3ffff) == 0) + { + CheckForShutdown(3); + if (tmp.block.nNonce == 0) + break; + if (pindexPrev != pindexBest) + break; + if (nTransactionsUpdated != nTransactionsUpdatedLast && GetTime() - nStart > 60) + break; + if (!fGenerateBitcoins) + break; + tmp.block.nTime = pblock->nTime = max(pindexPrev->GetMedianTimePast()+1, GetAdjustedTime()); + } + } + } + + return true; +} + + + + + + + + + + + + + + + + + + +////////////////////////////////////////////////////////////////////////////// +// +// Actions +// + + +int64 GetBalance() +{ + int64 nStart, nEnd; + QueryPerformanceCounter((LARGE_INTEGER*)&nStart); + + int64 nTotal = 0; + CRITICAL_BLOCK(cs_mapWallet) + { + for (map::iterator it = mapWallet.begin(); it != mapWallet.end(); ++it) + { + CWalletTx* pcoin = &(*it).second; + if (!pcoin->IsFinal() || pcoin->fSpent) + continue; + nTotal += pcoin->GetCredit(); + } + } + + QueryPerformanceCounter((LARGE_INTEGER*)&nEnd); + ///printf(" GetBalance() time = %16I64d\n", nEnd - nStart); + return nTotal; +} + + + +bool SelectCoins(int64 nTargetValue, set& setCoinsRet) +{ + setCoinsRet.clear(); + + // List of values less than target + int64 nLowestLarger = _I64_MAX; + CWalletTx* pcoinLowestLarger = NULL; + vector > vValue; + int64 nTotalLower = 0; + + CRITICAL_BLOCK(cs_mapWallet) + { + for (map::iterator it = mapWallet.begin(); it != mapWallet.end(); ++it) + { + CWalletTx* pcoin = &(*it).second; + if (!pcoin->IsFinal() || pcoin->fSpent) + continue; + int64 n = pcoin->GetCredit(); + if (n <= 0) + continue; + if (n < nTargetValue) + { + vValue.push_back(make_pair(n, pcoin)); + nTotalLower += n; + } + else if (n == nTargetValue) + { + setCoinsRet.insert(pcoin); + return true; + } + else if (n < nLowestLarger) + { + nLowestLarger = n; + pcoinLowestLarger = pcoin; + } + } + } + + if (nTotalLower < nTargetValue) + { + if (pcoinLowestLarger == NULL) + return false; + setCoinsRet.insert(pcoinLowestLarger); + return true; + } + + // Solve subset sum by stochastic approximation + sort(vValue.rbegin(), vValue.rend()); + vector vfIncluded; + vector vfBest(vValue.size(), true); + int64 nBest = nTotalLower; + + for (int nRep = 0; nRep < 1000 && nBest != nTargetValue; nRep++) + { + vfIncluded.assign(vValue.size(), false); + int64 nTotal = 0; + bool fReachedTarget = false; + for (int nPass = 0; nPass < 2 && !fReachedTarget; nPass++) + { + for (int i = 0; i < vValue.size(); i++) + { + if (nPass == 0 ? rand() % 2 : !vfIncluded[i]) + { + nTotal += vValue[i].first; + vfIncluded[i] = true; + if (nTotal >= nTargetValue) + { + fReachedTarget = true; + if (nTotal < nBest) + { + nBest = nTotal; + vfBest = vfIncluded; + } + nTotal -= vValue[i].first; + vfIncluded[i] = false; + } + } + } + } + } + + // If the next larger is still closer, return it + if (pcoinLowestLarger && nLowestLarger - nTargetValue <= nBest - nTargetValue) + setCoinsRet.insert(pcoinLowestLarger); + else + { + for (int i = 0; i < vValue.size(); i++) + if (vfBest[i]) + setCoinsRet.insert(vValue[i].second); + + //// debug print + printf("SelectCoins() best subset: "); + for (int i = 0; i < vValue.size(); i++) + if (vfBest[i]) + printf("%s ", FormatMoney(vValue[i].first).c_str()); + printf("total %s\n", FormatMoney(nBest).c_str()); + } + + return true; +} + + + + +bool CreateTransaction(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew, int64& nFeeRequiredRet) +{ + nFeeRequiredRet = 0; + CRITICAL_BLOCK(cs_main) + { + // txdb must be opened before the mapWallet lock + CTxDB txdb("r"); + CRITICAL_BLOCK(cs_mapWallet) + { + int64 nFee = nTransactionFee; + loop + { + wtxNew.vin.clear(); + wtxNew.vout.clear(); + if (nValue < 0) + return false; + int64 nValueOut = nValue; + nValue += nFee; + + // Choose coins to use + set setCoins; + if (!SelectCoins(nValue, setCoins)) + return false; + int64 nValueIn = 0; + foreach(CWalletTx* pcoin, setCoins) + nValueIn += pcoin->GetCredit(); + + // Fill vout[0] to the payee + wtxNew.vout.push_back(CTxOut(nValueOut, scriptPubKey)); + + // Fill vout[1] back to self with any change + if (nValueIn > nValue) + { + /// todo: for privacy, should randomize the order of outputs, + // would also have to use a new key for the change. + // Use the same key as one of the coins + vector vchPubKey; + CTransaction& txFirst = *(*setCoins.begin()); + foreach(const CTxOut& txout, txFirst.vout) + if (txout.IsMine()) + if (ExtractPubKey(txout.scriptPubKey, true, vchPubKey)) + break; + if (vchPubKey.empty()) + return false; + + // Fill vout[1] to ourself + CScript scriptPubKey; + scriptPubKey << vchPubKey << OP_CHECKSIG; + wtxNew.vout.push_back(CTxOut(nValueIn - nValue, scriptPubKey)); + } + + // Fill vin + foreach(CWalletTx* pcoin, setCoins) + for (int nOut = 0; nOut < pcoin->vout.size(); nOut++) + if (pcoin->vout[nOut].IsMine()) + wtxNew.vin.push_back(CTxIn(pcoin->GetHash(), nOut)); + + // Sign + int nIn = 0; + foreach(CWalletTx* pcoin, setCoins) + for (int nOut = 0; nOut < pcoin->vout.size(); nOut++) + if (pcoin->vout[nOut].IsMine()) + SignSignature(*pcoin, wtxNew, nIn++); + + // Check that enough fee is included + if (nFee < wtxNew.GetMinFee(true)) + { + nFee = nFeeRequiredRet = wtxNew.GetMinFee(true); + continue; + } + + // Fill vtxPrev by copying from previous transactions vtxPrev + wtxNew.AddSupportingTransactions(txdb); + wtxNew.fTimeReceivedIsTxTime = true; + + break; + } + } + } + return true; +} + +// Call after CreateTransaction unless you want to abort +bool CommitTransactionSpent(const CWalletTx& wtxNew) +{ + CRITICAL_BLOCK(cs_main) + CRITICAL_BLOCK(cs_mapWallet) + { + //// todo: make this transactional, never want to add a transaction + //// without marking spent transactions + + // Add tx to wallet, because if it has change it's also ours, + // otherwise just for transaction history. + AddToWallet(wtxNew); + + // Mark old coins as spent + set setCoins; + foreach(const CTxIn& txin, wtxNew.vin) + setCoins.insert(&mapWallet[txin.prevout.hash]); + foreach(CWalletTx* pcoin, setCoins) + { + pcoin->fSpent = true; + pcoin->WriteToDisk(); + vWalletUpdated.push_back(make_pair(pcoin->GetHash(), false)); + } + } + MainFrameRepaint(); + return true; +} + + + + +bool SendMoney(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew) +{ + CRITICAL_BLOCK(cs_main) + { + int64 nFeeRequired; + if (!CreateTransaction(scriptPubKey, nValue, wtxNew, nFeeRequired)) + { + string strError; + if (nValue + nFeeRequired > GetBalance()) + strError = strprintf("Error: This is an oversized transaction that requires a transaction fee of %s ", FormatMoney(nFeeRequired).c_str()); + else + strError = "Error: Transaction creation failed "; + wxMessageBox(strError, "Sending..."); + return error("SendMoney() : %s\n", strError.c_str()); + } + if (!CommitTransactionSpent(wtxNew)) + { + wxMessageBox("Error finalizing transaction ", "Sending..."); + return error("SendMoney() : Error finalizing transaction"); + } + + printf("SendMoney: %s\n", wtxNew.GetHash().ToString().substr(0,6).c_str()); + + // Broadcast + if (!wtxNew.AcceptTransaction()) + { + // This must not fail. The transaction has already been signed and recorded. + throw runtime_error("SendMoney() : wtxNew.AcceptTransaction() failed\n"); + wxMessageBox("Error: Transaction not valid ", "Sending..."); + return error("SendMoney() : Error: Transaction not valid"); + } + wtxNew.RelayWalletTransaction(); + } + MainFrameRepaint(); + return true; +} diff --git a/main.h b/main.h new file mode 100644 index 0000000000..3432b316e7 --- /dev/null +++ b/main.h @@ -0,0 +1,1329 @@ +// Copyright (c) 2009 Satoshi Nakamoto +// Distributed under the MIT/X11 software license, see the accompanying +// file license.txt or http://www.opensource.org/licenses/mit-license.php. + +class COutPoint; +class CInPoint; +class CDiskTxPos; +class CCoinBase; +class CTxIn; +class CTxOut; +class CTransaction; +class CBlock; +class CBlockIndex; +class CWalletTx; +class CKeyItem; + +static const unsigned int MAX_SIZE = 0x02000000; +static const int64 COIN = 100000000; +static const int64 CENT = 1000000; +static const int COINBASE_MATURITY = 100; + +static const CBigNum bnProofOfWorkLimit(~uint256(0) >> 32); + + + + + + +extern CCriticalSection cs_main; +extern map mapBlockIndex; +extern const uint256 hashGenesisBlock; +extern CBlockIndex* pindexGenesisBlock; +extern int nBestHeight; +extern uint256 hashBestChain; +extern CBlockIndex* pindexBest; +extern unsigned int nTransactionsUpdated; +extern string strSetDataDir; +extern int nDropMessagesTest; + +// Settings +extern int fGenerateBitcoins; +extern int64 nTransactionFee; +extern CAddress addrIncoming; + + + + + + + +string GetAppDir(); +bool CheckDiskSpace(int64 nAdditionalBytes=0); +FILE* OpenBlockFile(unsigned int nFile, unsigned int nBlockPos, const char* pszMode="rb"); +FILE* AppendBlockFile(unsigned int& nFileRet); +bool AddKey(const CKey& key); +vector GenerateNewKey(); +bool AddToWallet(const CWalletTx& wtxIn); +void ReacceptWalletTransactions(); +void RelayWalletTransactions(); +bool LoadBlockIndex(bool fAllowNew=true); +void PrintBlockTree(); +bool BitcoinMiner(); +bool ProcessMessages(CNode* pfrom); +bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv); +bool SendMessages(CNode* pto); +int64 GetBalance(); +bool CreateTransaction(CScript scriptPubKey, int64 nValue, CWalletTx& txNew, int64& nFeeRequiredRet); +bool CommitTransactionSpent(const CWalletTx& wtxNew); +bool SendMoney(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew); + + + + + + + + + + + +class CDiskTxPos +{ +public: + unsigned int nFile; + unsigned int nBlockPos; + unsigned int nTxPos; + + CDiskTxPos() + { + SetNull(); + } + + CDiskTxPos(unsigned int nFileIn, unsigned int nBlockPosIn, unsigned int nTxPosIn) + { + nFile = nFileIn; + nBlockPos = nBlockPosIn; + nTxPos = nTxPosIn; + } + + IMPLEMENT_SERIALIZE( READWRITE(FLATDATA(*this)); ) + void SetNull() { nFile = -1; nBlockPos = 0; nTxPos = 0; } + bool IsNull() const { return (nFile == -1); } + + friend bool operator==(const CDiskTxPos& a, const CDiskTxPos& b) + { + return (a.nFile == b.nFile && + a.nBlockPos == b.nBlockPos && + a.nTxPos == b.nTxPos); + } + + friend bool operator!=(const CDiskTxPos& a, const CDiskTxPos& b) + { + return !(a == b); + } + + string ToString() const + { + if (IsNull()) + return strprintf("null"); + else + return strprintf("(nFile=%d, nBlockPos=%d, nTxPos=%d)", nFile, nBlockPos, nTxPos); + } + + void print() const + { + printf("%s", ToString().c_str()); + } +}; + + + + +class CInPoint +{ +public: + CTransaction* ptx; + unsigned int n; + + CInPoint() { SetNull(); } + CInPoint(CTransaction* ptxIn, unsigned int nIn) { ptx = ptxIn; n = nIn; } + void SetNull() { ptx = NULL; n = -1; } + bool IsNull() const { return (ptx == NULL && n == -1); } +}; + + + + +class COutPoint +{ +public: + uint256 hash; + unsigned int n; + + COutPoint() { SetNull(); } + COutPoint(uint256 hashIn, unsigned int nIn) { hash = hashIn; n = nIn; } + IMPLEMENT_SERIALIZE( READWRITE(FLATDATA(*this)); ) + void SetNull() { hash = 0; n = -1; } + bool IsNull() const { return (hash == 0 && n == -1); } + + friend bool operator<(const COutPoint& a, const COutPoint& b) + { + return (a.hash < b.hash || (a.hash == b.hash && a.n < b.n)); + } + + friend bool operator==(const COutPoint& a, const COutPoint& b) + { + return (a.hash == b.hash && a.n == b.n); + } + + friend bool operator!=(const COutPoint& a, const COutPoint& b) + { + return !(a == b); + } + + string ToString() const + { + return strprintf("COutPoint(%s, %d)", hash.ToString().substr(0,6).c_str(), n); + } + + void print() const + { + printf("%s\n", ToString().c_str()); + } +}; + + + + +// +// An input of a transaction. It contains the location of the previous +// transaction's output that it claims and a signature that matches the +// output's public key. +// +class CTxIn +{ +public: + COutPoint prevout; + CScript scriptSig; + unsigned int nSequence; + + CTxIn() + { + nSequence = UINT_MAX; + } + + explicit CTxIn(COutPoint prevoutIn, CScript scriptSigIn=CScript(), unsigned int nSequenceIn=UINT_MAX) + { + prevout = prevoutIn; + scriptSig = scriptSigIn; + nSequence = nSequenceIn; + } + + CTxIn(uint256 hashPrevTx, unsigned int nOut, CScript scriptSigIn=CScript(), unsigned int nSequenceIn=UINT_MAX) + { + prevout = COutPoint(hashPrevTx, nOut); + scriptSig = scriptSigIn; + nSequence = nSequenceIn; + } + + IMPLEMENT_SERIALIZE + ( + READWRITE(prevout); + READWRITE(scriptSig); + READWRITE(nSequence); + ) + + bool IsFinal() const + { + return (nSequence == UINT_MAX); + } + + friend bool operator==(const CTxIn& a, const CTxIn& b) + { + return (a.prevout == b.prevout && + a.scriptSig == b.scriptSig && + a.nSequence == b.nSequence); + } + + friend bool operator!=(const CTxIn& a, const CTxIn& b) + { + return !(a == b); + } + + string ToString() const + { + string str; + str += strprintf("CTxIn("); + str += prevout.ToString(); + if (prevout.IsNull()) + str += strprintf(", coinbase %s", HexStr(scriptSig.begin(), scriptSig.end(), false).c_str()); + else + str += strprintf(", scriptSig=%s", scriptSig.ToString().substr(0,24).c_str()); + if (nSequence != UINT_MAX) + str += strprintf(", nSequence=%u", nSequence); + str += ")"; + return str; + } + + void print() const + { + printf("%s\n", ToString().c_str()); + } + + bool IsMine() const; + int64 GetDebit() const; +}; + + + + +// +// An output of a transaction. It contains the public key that the next input +// must be able to sign with to claim it. +// +class CTxOut +{ +public: + int64 nValue; + CScript scriptPubKey; + +public: + CTxOut() + { + SetNull(); + } + + CTxOut(int64 nValueIn, CScript scriptPubKeyIn) + { + nValue = nValueIn; + scriptPubKey = scriptPubKeyIn; + } + + IMPLEMENT_SERIALIZE + ( + READWRITE(nValue); + READWRITE(scriptPubKey); + ) + + void SetNull() + { + nValue = -1; + scriptPubKey.clear(); + } + + bool IsNull() + { + return (nValue == -1); + } + + uint256 GetHash() const + { + return SerializeHash(*this); + } + + bool IsMine() const + { + return ::IsMine(scriptPubKey); + } + + int64 GetCredit() const + { + if (IsMine()) + return nValue; + return 0; + } + + friend bool operator==(const CTxOut& a, const CTxOut& b) + { + return (a.nValue == b.nValue && + a.scriptPubKey == b.scriptPubKey); + } + + friend bool operator!=(const CTxOut& a, const CTxOut& b) + { + return !(a == b); + } + + string ToString() const + { + if (scriptPubKey.size() < 6) + return "CTxOut(error)"; + return strprintf("CTxOut(nValue=%I64d.%08I64d, scriptPubKey=%s)", nValue / COIN, nValue % COIN, scriptPubKey.ToString().substr(0,24).c_str()); + } + + void print() const + { + printf("%s\n", ToString().c_str()); + } +}; + + + + +// +// The basic transaction that is broadcasted on the network and contained in +// blocks. A transaction can contain multiple inputs and outputs. +// +class CTransaction +{ +public: + int nVersion; + vector vin; + vector vout; + int nLockTime; + + + CTransaction() + { + SetNull(); + } + + IMPLEMENT_SERIALIZE + ( + READWRITE(this->nVersion); + nVersion = this->nVersion; + READWRITE(vin); + READWRITE(vout); + READWRITE(nLockTime); + ) + + void SetNull() + { + nVersion = 1; + vin.clear(); + vout.clear(); + nLockTime = 0; + } + + bool IsNull() const + { + return (vin.empty() && vout.empty()); + } + + uint256 GetHash() const + { + return SerializeHash(*this); + } + + bool IsFinal() const + { + if (nLockTime == 0 || nLockTime < nBestHeight) + return true; + foreach(const CTxIn& txin, vin) + if (!txin.IsFinal()) + return false; + return true; + } + + bool IsNewerThan(const CTransaction& old) const + { + if (vin.size() != old.vin.size()) + return false; + for (int i = 0; i < vin.size(); i++) + if (vin[i].prevout != old.vin[i].prevout) + return false; + + bool fNewer = false; + unsigned int nLowest = UINT_MAX; + for (int i = 0; i < vin.size(); i++) + { + if (vin[i].nSequence != old.vin[i].nSequence) + { + if (vin[i].nSequence <= nLowest) + { + fNewer = false; + nLowest = vin[i].nSequence; + } + if (old.vin[i].nSequence < nLowest) + { + fNewer = true; + nLowest = old.vin[i].nSequence; + } + } + } + return fNewer; + } + + bool IsCoinBase() const + { + return (vin.size() == 1 && vin[0].prevout.IsNull()); + } + + bool CheckTransaction() const + { + // Basic checks that don't depend on any context + if (vin.empty() || vout.empty()) + return error("CTransaction::CheckTransaction() : vin or vout empty"); + + // Check for negative values + foreach(const CTxOut& txout, vout) + if (txout.nValue < 0) + return error("CTransaction::CheckTransaction() : txout.nValue negative"); + + if (IsCoinBase()) + { + if (vin[0].scriptSig.size() < 2 || vin[0].scriptSig.size() > 100) + return error("CTransaction::CheckTransaction() : coinbase script size"); + } + else + { + foreach(const CTxIn& txin, vin) + if (txin.prevout.IsNull()) + return error("CTransaction::CheckTransaction() : prevout is null"); + } + + return true; + } + + bool IsMine() const + { + foreach(const CTxOut& txout, vout) + if (txout.IsMine()) + return true; + return false; + } + + int64 GetDebit() const + { + int64 nDebit = 0; + foreach(const CTxIn& txin, vin) + nDebit += txin.GetDebit(); + return nDebit; + } + + int64 GetCredit() const + { + int64 nCredit = 0; + foreach(const CTxOut& txout, vout) + nCredit += txout.GetCredit(); + return nCredit; + } + + int64 GetValueOut() const + { + int64 nValueOut = 0; + foreach(const CTxOut& txout, vout) + { + if (txout.nValue < 0) + throw runtime_error("CTransaction::GetValueOut() : negative value"); + nValueOut += txout.nValue; + } + return nValueOut; + } + + int64 GetMinFee(bool fDiscount=false) const + { + // Base fee is 1 cent per kilobyte + unsigned int nBytes = ::GetSerializeSize(*this, SER_NETWORK); + int64 nMinFee = (1 + (int64)nBytes / 1000) * CENT; + + // First 100 transactions in a block are free + if (fDiscount && nBytes < 10000) + nMinFee = 0; + + // To limit dust spam, require a 0.01 fee if any output is less than 0.01 + if (nMinFee < CENT) + foreach(const CTxOut& txout, vout) + if (txout.nValue < CENT) + nMinFee = CENT; + + return nMinFee; + } + + + + bool ReadFromDisk(CDiskTxPos pos, FILE** pfileRet=NULL) + { + CAutoFile filein = OpenBlockFile(pos.nFile, 0, pfileRet ? "rb+" : "rb"); + if (!filein) + return error("CTransaction::ReadFromDisk() : OpenBlockFile failed"); + + // Read transaction + if (fseek(filein, pos.nTxPos, SEEK_SET) != 0) + return error("CTransaction::ReadFromDisk() : fseek failed"); + filein >> *this; + + // Return file pointer + if (pfileRet) + { + if (fseek(filein, pos.nTxPos, SEEK_SET) != 0) + return error("CTransaction::ReadFromDisk() : second fseek failed"); + *pfileRet = filein.release(); + } + return true; + } + + + friend bool operator==(const CTransaction& a, const CTransaction& b) + { + return (a.nVersion == b.nVersion && + a.vin == b.vin && + a.vout == b.vout && + a.nLockTime == b.nLockTime); + } + + friend bool operator!=(const CTransaction& a, const CTransaction& b) + { + return !(a == b); + } + + + string ToString() const + { + string str; + str += strprintf("CTransaction(hash=%s, ver=%d, vin.size=%d, vout.size=%d, nLockTime=%d)\n", + GetHash().ToString().substr(0,6).c_str(), + nVersion, + vin.size(), + vout.size(), + nLockTime); + for (int i = 0; i < vin.size(); i++) + str += " " + vin[i].ToString() + "\n"; + for (int i = 0; i < vout.size(); i++) + str += " " + vout[i].ToString() + "\n"; + return str; + } + + void print() const + { + printf("%s", ToString().c_str()); + } + + + + bool DisconnectInputs(CTxDB& txdb); + bool ConnectInputs(CTxDB& txdb, map& mapTestPool, CDiskTxPos posThisTx, int nHeight, int64& nFees, bool fBlock, bool fMiner, int64 nMinFee=0); + bool ClientConnectInputs(); + + bool AcceptTransaction(CTxDB& txdb, bool fCheckInputs=true, bool* pfMissingInputs=NULL); + + bool AcceptTransaction(bool fCheckInputs=true, bool* pfMissingInputs=NULL) + { + CTxDB txdb("r"); + return AcceptTransaction(txdb, fCheckInputs, pfMissingInputs); + } + +protected: + bool AddToMemoryPool(); +public: + bool RemoveFromMemoryPool(); +}; + + + + + +// +// A transaction with a merkle branch linking it to the block chain +// +class CMerkleTx : public CTransaction +{ +public: + uint256 hashBlock; + vector vMerkleBranch; + int nIndex; + + // memory only + mutable bool fMerkleVerified; + + + CMerkleTx() + { + Init(); + } + + CMerkleTx(const CTransaction& txIn) : CTransaction(txIn) + { + Init(); + } + + void Init() + { + hashBlock = 0; + nIndex = -1; + fMerkleVerified = false; + } + + int64 GetCredit() const + { + // Must wait until coinbase is safely deep enough in the chain before valuing it + if (IsCoinBase() && GetBlocksToMaturity() > 0) + return 0; + return CTransaction::GetCredit(); + } + + IMPLEMENT_SERIALIZE + ( + nSerSize += SerReadWrite(s, *(CTransaction*)this, nType, nVersion, ser_action); + nVersion = this->nVersion; + READWRITE(hashBlock); + READWRITE(vMerkleBranch); + READWRITE(nIndex); + ) + + + int SetMerkleBranch(const CBlock* pblock=NULL); + int GetDepthInMainChain() const; + bool IsInMainChain() const { return GetDepthInMainChain() > 0; } + int GetBlocksToMaturity() const; + bool AcceptTransaction(CTxDB& txdb, bool fCheckInputs=true); + bool AcceptTransaction() { CTxDB txdb("r"); return AcceptTransaction(txdb); } +}; + + + + +// +// A transaction with a bunch of additional info that only the owner cares +// about. It includes any unrecorded transactions needed to link it back +// to the block chain. +// +class CWalletTx : public CMerkleTx +{ +public: + vector vtxPrev; + map mapValue; + vector > vOrderForm; + unsigned int fTimeReceivedIsTxTime; + unsigned int nTimeReceived; // time received by this node + char fFromMe; + char fSpent; + //// probably need to sign the order info so know it came from payer + + // memory only + mutable unsigned int nTimeDisplayed; + + + CWalletTx() + { + Init(); + } + + CWalletTx(const CMerkleTx& txIn) : CMerkleTx(txIn) + { + Init(); + } + + CWalletTx(const CTransaction& txIn) : CMerkleTx(txIn) + { + Init(); + } + + void Init() + { + fTimeReceivedIsTxTime = false; + nTimeReceived = 0; + fFromMe = false; + fSpent = false; + nTimeDisplayed = 0; + } + + IMPLEMENT_SERIALIZE + ( + nSerSize += SerReadWrite(s, *(CMerkleTx*)this, nType, nVersion, ser_action); + nVersion = this->nVersion; + READWRITE(vtxPrev); + READWRITE(mapValue); + READWRITE(vOrderForm); + READWRITE(fTimeReceivedIsTxTime); + READWRITE(nTimeReceived); + READWRITE(fFromMe); + READWRITE(fSpent); + ) + + bool WriteToDisk() + { + return CWalletDB().WriteTx(GetHash(), *this); + } + + + int64 GetTxTime() const; + + void AddSupportingTransactions(CTxDB& txdb); + + bool AcceptWalletTransaction(CTxDB& txdb, bool fCheckInputs=true); + bool AcceptWalletTransaction() { CTxDB txdb("r"); return AcceptWalletTransaction(txdb); } + + void RelayWalletTransaction(CTxDB& txdb); + void RelayWalletTransaction() { CTxDB txdb("r"); RelayWalletTransaction(txdb); } +}; + + + + +// +// A txdb record that contains the disk location of a transaction and the +// locations of transactions that spend its outputs. vSpent is really only +// used as a flag, but having the location is very helpful for debugging. +// +class CTxIndex +{ +public: + CDiskTxPos pos; + vector vSpent; + + CTxIndex() + { + SetNull(); + } + + CTxIndex(const CDiskTxPos& posIn, unsigned int nOutputs) + { + pos = posIn; + vSpent.resize(nOutputs); + } + + IMPLEMENT_SERIALIZE + ( + if (!(nType & SER_GETHASH)) + READWRITE(nVersion); + READWRITE(pos); + READWRITE(vSpent); + ) + + void SetNull() + { + pos.SetNull(); + vSpent.clear(); + } + + bool IsNull() + { + return pos.IsNull(); + } + + friend bool operator==(const CTxIndex& a, const CTxIndex& b) + { + if (a.pos != b.pos || a.vSpent.size() != b.vSpent.size()) + return false; + for (int i = 0; i < a.vSpent.size(); i++) + if (a.vSpent[i] != b.vSpent[i]) + return false; + return true; + } + + friend bool operator!=(const CTxIndex& a, const CTxIndex& b) + { + return !(a == b); + } +}; + + + + + +// +// Nodes collect new transactions into a block, hash them into a hash tree, +// and scan through nonce values to make the block's hash satisfy proof-of-work +// requirements. When they solve the proof-of-work, they broadcast the block +// to everyone and the block is added to the block chain. The first transaction +// in the block is a special one that creates a new coin owned by the creator +// of the block. +// +// Blocks are appended to blk0001.dat files on disk. Their location on disk +// is indexed by CBlockIndex objects in memory. +// +class CBlock +{ +public: + // header + int nVersion; + uint256 hashPrevBlock; + uint256 hashMerkleRoot; + unsigned int nTime; + unsigned int nBits; + unsigned int nNonce; + + // network and disk + vector vtx; + + // memory only + mutable vector vMerkleTree; + + + CBlock() + { + SetNull(); + } + + IMPLEMENT_SERIALIZE + ( + READWRITE(this->nVersion); + nVersion = this->nVersion; + READWRITE(hashPrevBlock); + READWRITE(hashMerkleRoot); + READWRITE(nTime); + READWRITE(nBits); + READWRITE(nNonce); + + // ConnectBlock depends on vtx being last so it can calculate offset + if (!(nType & (SER_GETHASH|SER_BLOCKHEADERONLY))) + READWRITE(vtx); + else if (fRead) + const_cast(this)->vtx.clear(); + ) + + void SetNull() + { + nVersion = 1; + hashPrevBlock = 0; + hashMerkleRoot = 0; + nTime = 0; + nBits = 0; + nNonce = 0; + vtx.clear(); + vMerkleTree.clear(); + } + + bool IsNull() const + { + return (nBits == 0); + } + + uint256 GetHash() const + { + return Hash(BEGIN(nVersion), END(nNonce)); + } + + + uint256 BuildMerkleTree() const + { + vMerkleTree.clear(); + foreach(const CTransaction& tx, vtx) + vMerkleTree.push_back(tx.GetHash()); + int j = 0; + for (int nSize = vtx.size(); nSize > 1; nSize = (nSize + 1) / 2) + { + for (int i = 0; i < nSize; i += 2) + { + int i2 = min(i+1, nSize-1); + vMerkleTree.push_back(Hash(BEGIN(vMerkleTree[j+i]), END(vMerkleTree[j+i]), + BEGIN(vMerkleTree[j+i2]), END(vMerkleTree[j+i2]))); + } + j += nSize; + } + return (vMerkleTree.empty() ? 0 : vMerkleTree.back()); + } + + vector GetMerkleBranch(int nIndex) const + { + if (vMerkleTree.empty()) + BuildMerkleTree(); + vector vMerkleBranch; + int j = 0; + for (int nSize = vtx.size(); nSize > 1; nSize = (nSize + 1) / 2) + { + int i = min(nIndex^1, nSize-1); + vMerkleBranch.push_back(vMerkleTree[j+i]); + nIndex >>= 1; + j += nSize; + } + return vMerkleBranch; + } + + static uint256 CheckMerkleBranch(uint256 hash, const vector& vMerkleBranch, int nIndex) + { + if (nIndex == -1) + return 0; + foreach(const uint256& otherside, vMerkleBranch) + { + if (nIndex & 1) + hash = Hash(BEGIN(otherside), END(otherside), BEGIN(hash), END(hash)); + else + hash = Hash(BEGIN(hash), END(hash), BEGIN(otherside), END(otherside)); + nIndex >>= 1; + } + return hash; + } + + + bool WriteToDisk(bool fWriteTransactions, unsigned int& nFileRet, unsigned int& nBlockPosRet) + { + // Open history file to append + CAutoFile fileout = AppendBlockFile(nFileRet); + if (!fileout) + return error("CBlock::WriteToDisk() : AppendBlockFile failed"); + if (!fWriteTransactions) + fileout.nType |= SER_BLOCKHEADERONLY; + + // Write index header + unsigned int nSize = fileout.GetSerializeSize(*this); + fileout << FLATDATA(pchMessageStart) << nSize; + + // Write block + nBlockPosRet = ftell(fileout); + if (nBlockPosRet == -1) + return error("CBlock::WriteToDisk() : ftell failed"); + fileout << *this; + + return true; + } + + bool ReadFromDisk(unsigned int nFile, unsigned int nBlockPos, bool fReadTransactions) + { + SetNull(); + + // Open history file to read + CAutoFile filein = OpenBlockFile(nFile, nBlockPos, "rb"); + if (!filein) + return error("CBlock::ReadFromDisk() : OpenBlockFile failed"); + if (!fReadTransactions) + filein.nType |= SER_BLOCKHEADERONLY; + + // Read block + filein >> *this; + + // Check the header + if (CBigNum().SetCompact(nBits) > bnProofOfWorkLimit) + return error("CBlock::ReadFromDisk() : nBits errors in block header"); + if (GetHash() > CBigNum().SetCompact(nBits).getuint256()) + return error("CBlock::ReadFromDisk() : GetHash() errors in block header"); + + return true; + } + + + + void print() const + { + printf("CBlock(hash=%s, ver=%d, hashPrevBlock=%s, hashMerkleRoot=%s, nTime=%u, nBits=%08x, nNonce=%u, vtx=%d)\n", + GetHash().ToString().substr(0,14).c_str(), + nVersion, + hashPrevBlock.ToString().substr(0,14).c_str(), + hashMerkleRoot.ToString().substr(0,6).c_str(), + nTime, nBits, nNonce, + vtx.size()); + for (int i = 0; i < vtx.size(); i++) + { + printf(" "); + vtx[i].print(); + } + printf(" vMerkleTree: "); + for (int i = 0; i < vMerkleTree.size(); i++) + printf("%s ", vMerkleTree[i].ToString().substr(0,6).c_str()); + printf("\n"); + } + + + int64 GetBlockValue(int64 nFees) const; + bool DisconnectBlock(CTxDB& txdb, CBlockIndex* pindex); + bool ConnectBlock(CTxDB& txdb, CBlockIndex* pindex); + bool ReadFromDisk(const CBlockIndex* blockindex, bool fReadTransactions); + bool AddToBlockIndex(unsigned int nFile, unsigned int nBlockPos); + bool CheckBlock() const; + bool AcceptBlock(); +}; + + + + + + +// +// The block chain is a tree shaped structure starting with the +// genesis block at the root, with each block potentially having multiple +// candidates to be the next block. pprev and pnext link a path through the +// main/longest chain. A blockindex may have multiple pprev pointing back +// to it, but pnext will only point forward to the longest branch, or will +// be null if the block is not part of the longest chain. +// +class CBlockIndex +{ +public: + const uint256* phashBlock; + CBlockIndex* pprev; + CBlockIndex* pnext; + unsigned int nFile; + unsigned int nBlockPos; + int nHeight; + + // block header + int nVersion; + uint256 hashMerkleRoot; + unsigned int nTime; + unsigned int nBits; + unsigned int nNonce; + + + CBlockIndex() + { + phashBlock = NULL; + pprev = NULL; + pnext = NULL; + nFile = 0; + nBlockPos = 0; + nHeight = 0; + + nVersion = 0; + hashMerkleRoot = 0; + nTime = 0; + nBits = 0; + nNonce = 0; + } + + CBlockIndex(unsigned int nFileIn, unsigned int nBlockPosIn, CBlock& block) + { + phashBlock = NULL; + pprev = NULL; + pnext = NULL; + nFile = nFileIn; + nBlockPos = nBlockPosIn; + nHeight = 0; + + nVersion = block.nVersion; + hashMerkleRoot = block.hashMerkleRoot; + nTime = block.nTime; + nBits = block.nBits; + nNonce = block.nNonce; + } + + uint256 GetBlockHash() const + { + return *phashBlock; + } + + bool IsInMainChain() const + { + return (pnext || this == pindexBest); + } + + bool EraseBlockFromDisk() + { + // Open history file + CAutoFile fileout = OpenBlockFile(nFile, nBlockPos, "rb+"); + if (!fileout) + return false; + + // Overwrite with empty null block + CBlock block; + block.SetNull(); + fileout << block; + + return true; + } + + enum { nMedianTimeSpan=11 }; + + int64 GetMedianTimePast() const + { + unsigned int pmedian[nMedianTimeSpan]; + unsigned int* pbegin = &pmedian[nMedianTimeSpan]; + unsigned int* pend = &pmedian[nMedianTimeSpan]; + + const CBlockIndex* pindex = this; + for (int i = 0; i < nMedianTimeSpan && pindex; i++, pindex = pindex->pprev) + *(--pbegin) = pindex->nTime; + + sort(pbegin, pend); + return pbegin[(pend - pbegin)/2]; + } + + int64 GetMedianTime() const + { + const CBlockIndex* pindex = this; + for (int i = 0; i < nMedianTimeSpan/2; i++) + { + if (!pindex->pnext) + return nTime; + pindex = pindex->pnext; + } + return pindex->GetMedianTimePast(); + } + + + + string ToString() const + { + return strprintf("CBlockIndex(nprev=%08x, pnext=%08x, nFile=%d, nBlockPos=%-6d nHeight=%d, merkle=%s, hashBlock=%s)", + pprev, pnext, nFile, nBlockPos, nHeight, + hashMerkleRoot.ToString().substr(0,6).c_str(), + GetBlockHash().ToString().substr(0,14).c_str()); + } + + void print() const + { + printf("%s\n", ToString().c_str()); + } +}; + + + +// +// Used to marshal pointers into hashes for db storage. +// +class CDiskBlockIndex : public CBlockIndex +{ +public: + uint256 hashPrev; + uint256 hashNext; + + CDiskBlockIndex() + { + hashPrev = 0; + hashNext = 0; + } + + explicit CDiskBlockIndex(CBlockIndex* pindex) : CBlockIndex(*pindex) + { + hashPrev = (pprev ? pprev->GetBlockHash() : 0); + hashNext = (pnext ? pnext->GetBlockHash() : 0); + } + + IMPLEMENT_SERIALIZE + ( + if (!(nType & SER_GETHASH)) + READWRITE(nVersion); + + READWRITE(hashNext); + READWRITE(nFile); + READWRITE(nBlockPos); + READWRITE(nHeight); + + // block header + READWRITE(this->nVersion); + READWRITE(hashPrev); + READWRITE(hashMerkleRoot); + READWRITE(nTime); + READWRITE(nBits); + READWRITE(nNonce); + ) + + uint256 GetBlockHash() const + { + CBlock block; + block.nVersion = nVersion; + block.hashPrevBlock = hashPrev; + block.hashMerkleRoot = hashMerkleRoot; + block.nTime = nTime; + block.nBits = nBits; + block.nNonce = nNonce; + return block.GetHash(); + } + + + string ToString() const + { + string str = "CDiskBlockIndex("; + str += CBlockIndex::ToString(); + str += strprintf("\n hashBlock=%s, hashPrev=%s, hashNext=%s)", + GetBlockHash().ToString().c_str(), + hashPrev.ToString().substr(0,14).c_str(), + hashNext.ToString().substr(0,14).c_str()); + return str; + } + + void print() const + { + printf("%s\n", ToString().c_str()); + } +}; + + + + + + + + +// +// Describes a place in the block chain to another node such that if the +// other node doesn't have the same branch, it can find a recent common trunk. +// The further back it is, the further before the fork it may be. +// +class CBlockLocator +{ +protected: + vector vHave; +public: + + CBlockLocator() + { + } + + explicit CBlockLocator(const CBlockIndex* pindex) + { + Set(pindex); + } + + explicit CBlockLocator(uint256 hashBlock) + { + map::iterator mi = mapBlockIndex.find(hashBlock); + if (mi != mapBlockIndex.end()) + Set((*mi).second); + } + + IMPLEMENT_SERIALIZE + ( + if (!(nType & SER_GETHASH)) + READWRITE(nVersion); + READWRITE(vHave); + ) + + void Set(const CBlockIndex* pindex) + { + vHave.clear(); + int nStep = 1; + while (pindex) + { + vHave.push_back(pindex->GetBlockHash()); + + // Exponentially larger steps back + for (int i = 0; pindex && i < nStep; i++) + pindex = pindex->pprev; + if (vHave.size() > 10) + nStep *= 2; + } + vHave.push_back(hashGenesisBlock); + } + + CBlockIndex* GetBlockIndex() + { + // Find the first block the caller has in the main chain + foreach(const uint256& hash, vHave) + { + map::iterator mi = mapBlockIndex.find(hash); + if (mi != mapBlockIndex.end()) + { + CBlockIndex* pindex = (*mi).second; + if (pindex->IsInMainChain()) + return pindex; + } + } + return pindexGenesisBlock; + } + + uint256 GetBlockHash() + { + // Find the first block the caller has in the main chain + foreach(const uint256& hash, vHave) + { + map::iterator mi = mapBlockIndex.find(hash); + if (mi != mapBlockIndex.end()) + { + CBlockIndex* pindex = (*mi).second; + if (pindex->IsInMainChain()) + return hash; + } + } + return hashGenesisBlock; + } + + int GetHeight() + { + CBlockIndex* pindex = GetBlockIndex(); + if (!pindex) + return 0; + return pindex->nHeight; + } +}; + + + + + + + + + + + + +extern map mapTransactions; +extern map mapWallet; +extern vector > vWalletUpdated; +extern CCriticalSection cs_mapWallet; +extern map, CPrivKey> mapKeys; +extern map > mapPubKeys; +extern CCriticalSection cs_mapKeys; +extern CKey keyUser; diff --git a/makefile b/makefile new file mode 100644 index 0000000000..534eb521e8 --- /dev/null +++ b/makefile @@ -0,0 +1,83 @@ +# Copyright (c) 2009 Satoshi Nakamoto +# Distributed under the MIT/X11 software license, see the accompanying +# file license.txt or http://www.opensource.org/licenses/mit-license.php. + + +ifneq "$(BUILD)" "debug" +ifneq "$(BUILD)" "release" +BUILD=debug +endif +endif +ifeq "$(BUILD)" "debug" +D=d +# note: gcc 3.x profile doesn't work +#DEBUGFLAGS=-O0 -g -pg -D__WXDEBUG__ +DEBUGFLAGS=-g -D__WXDEBUG__ +endif + + + +INCLUDEPATHS=-I"/boost" -I"/DB/build_unix" -I"/OpenSSL/include" -I"/wxWidgets/lib/vc_lib/mswd" -I"/wxWidgets/include" +LIBPATHS=-L"/DB/build_unix" -L"/OpenSSL/out" -L"/wxWidgets/lib/gcc_lib" +LIBS= \ + -l db_cxx \ + -l eay32 \ + -l wxmsw28$(D)_richtext -l wxmsw28$(D)_html -l wxmsw28$(D)_core -l wxbase28$(D) -l wxtiff$(D) -l wxjpeg$(D) -l wxpng$(D) -l wxzlib$(D) -l wxregex$(D) -l wxexpat$(D) \ + -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 +WXDEFS=-DWIN32 -D__WXMSW__ -D_WINDOWS -DNOPCH +CFLAGS=-mthreads -O0 -w -Wno-invalid-offsetof -Wformat $(DEBUGFLAGS) $(WXDEFS) $(INCLUDEPATHS) +HEADERS=headers.h util.h main.h serialize.h uint256.h key.h bignum.h script.h db.h base58.h + + + +all: bitcoin.exe + + +headers.h.gch: headers.h $(HEADERS) net.h irc.h market.h uibase.h ui.h + g++ -c $(CFLAGS) -o $@ $< + +obj/util.o: util.cpp $(HEADERS) + g++ -c $(CFLAGS) -o $@ $< + +obj/script.o: script.cpp $(HEADERS) + g++ -c $(CFLAGS) -o $@ $< + +obj/db.o: db.cpp $(HEADERS) market.h + g++ -c $(CFLAGS) -o $@ $< + +obj/net.o: net.cpp $(HEADERS) net.h + g++ -c $(CFLAGS) -o $@ $< + +obj/main.o: main.cpp $(HEADERS) net.h market.h sha.h + g++ -c $(CFLAGS) -o $@ $< + +obj/market.o: market.cpp $(HEADERS) market.h + g++ -c $(CFLAGS) -o $@ $< + +obj/ui.o: ui.cpp $(HEADERS) net.h uibase.h ui.h market.h + g++ -c $(CFLAGS) -o $@ $< + +obj/uibase.o: uibase.cpp uibase.h + g++ -c $(CFLAGS) -o $@ $< + +obj/sha.o: sha.cpp sha.h + g++ -c $(CFLAGS) -O3 -o $@ $< + +obj/irc.o: irc.cpp $(HEADERS) + g++ -c $(CFLAGS) -o $@ $< + +obj/ui_res.o: ui.rc rc/bitcoin.ico rc/check.ico rc/send16.bmp rc/send16mask.bmp rc/send16masknoshadow.bmp rc/send20.bmp rc/send20mask.bmp rc/addressbook16.bmp rc/addressbook16mask.bmp rc/addressbook20.bmp rc/addressbook20mask.bmp + windres $(WXDEFS) $(INCLUDEPATHS) -o $@ -i $< + + + +OBJS=obj/util.o obj/script.o obj/db.o obj/net.o obj/main.o obj/market.o \ + obj/ui.o obj/uibase.o obj/sha.o obj/irc.o obj/ui_res.o + +bitcoin.exe: headers.h.gch $(OBJS) + -kill /f bitcoin.exe + g++ $(CFLAGS) -mwindows -Wl,--subsystem,windows -o $@ $(LIBPATHS) $(OBJS) $(LIBS) + +clean: + -del /Q obj\* + -del /Q headers.h.gch diff --git a/makefile.vc b/makefile.vc new file mode 100644 index 0000000000..bf7e9bc580 --- /dev/null +++ b/makefile.vc @@ -0,0 +1,77 @@ +# Copyright (c) 2009 Satoshi Nakamoto +# Distributed under the MIT/X11 software license, see the accompanying +# file license.txt or http://www.opensource.org/licenses/mit-license.php. + + +!IF "$(BUILD)" != "debug" && "$(BUILD)" != "release" +BUILD=debug +!ENDIF +!IF "$(BUILD)" == "debug" +D=d +DEBUGFLAGS=/Zi /Od /D__WXDEBUG__ +!ENDIF + + + +INCLUDEPATHS=/I"/boost" /I"/DB/build_windows" /I"/OpenSSL/include" /I"/wxWidgets/lib/vc_lib/mswd" /I"/wxWidgets/include" +LIBPATHS=/LIBPATH:"/DB/build_windows/$(BUILD)" /LIBPATH:"/OpenSSL/out" /LIBPATH:"/wxWidgets/lib/vc_lib" +LIBS= \ + libdb47s$(D).lib \ + libeay32.lib \ + wxmsw28$(D)_richtext.lib wxmsw28$(D)_html.lib wxmsw28$(D)_core.lib wxbase28$(D).lib wxtiff$(D).lib wxjpeg$(D).lib wxpng$(D).lib wxzlib$(D).lib wxregex$(D).lib wxexpat$(D).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 +WXDEFS=/DWIN32 /D__WXMSW__ /D_WINDOWS /DNOPCH +CFLAGS=/c /nologo /Ob0 /MD$(D) /EHsc /GR /Zm300 /YX /Fpobj/headers.pch $(DEBUGFLAGS) $(WXDEFS) $(INCLUDEPATHS) +HEADERS=headers.h util.h main.h serialize.h uint256.h key.h bignum.h script.h db.h base58.h + + + +all: bitcoin.exe + + +obj\util.obj: util.cpp $(HEADERS) + cl $(CFLAGS) /Fo$@ %s + +obj\script.obj: script.cpp $(HEADERS) + cl $(CFLAGS) /Fo$@ %s + +obj\db.obj: db.cpp $(HEADERS) market.h + cl $(CFLAGS) /Fo$@ %s + +obj\net.obj: net.cpp $(HEADERS) net.h + cl $(CFLAGS) /Fo$@ %s + +obj\main.obj: main.cpp $(HEADERS) net.h market.h + cl $(CFLAGS) /Fo$@ %s + +obj\market.obj: market.cpp $(HEADERS) market.h + cl $(CFLAGS) /Fo$@ %s + +obj\ui.obj: ui.cpp $(HEADERS) net.h uibase.h ui.h market.h + cl $(CFLAGS) /Fo$@ %s + +obj\uibase.obj: uibase.cpp uibase.h + cl $(CFLAGS) /Fo$@ %s + +obj\sha.obj: sha.cpp sha.h + cl $(CFLAGS) /O2 /Fo$@ %s + +obj\irc.obj: irc.cpp $(HEADERS) + cl $(CFLAGS) /Fo$@ %s + +obj\ui.res: ui.rc rc/bitcoin.ico rc/check.ico rc/send16.bmp rc/send16mask.bmp rc/send16masknoshadow.bmp rc/send20.bmp rc/send20mask.bmp rc/addressbook16.bmp rc/addressbook16mask.bmp rc/addressbook20.bmp rc/addressbook20mask.bmp + rc $(INCLUDEPATHS) $(WXDEFS) /Fo$@ %s + + + +OBJS=obj\util.obj obj\script.obj obj\db.obj obj\net.obj obj\main.obj obj\market.obj \ + obj\ui.obj obj\uibase.obj obj\sha.obj obj\irc.obj obj\ui.res + +bitcoin.exe: $(OBJS) + -kill /f bitcoin.exe & sleep 1 + link /nologo /DEBUG /SUBSYSTEM:WINDOWS /OUT:$@ $(LIBPATHS) $** $(LIBS) + +clean: + -del /Q obj\* + -del *.ilk + -del *.pdb diff --git a/market.cpp b/market.cpp new file mode 100644 index 0000000000..22b5365fa4 --- /dev/null +++ b/market.cpp @@ -0,0 +1,264 @@ +// Copyright (c) 2009 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" + + + + + + + + + + +// +// Global state variables +// + +//// later figure out how these are persisted +map mapMyProducts; + + + + +map mapProducts; +CCriticalSection cs_mapProducts; + +bool AdvertInsert(const CProduct& product) +{ + uint256 hash = product.GetHash(); + bool fNew = false; + bool fUpdated = false; + + CRITICAL_BLOCK(cs_mapProducts) + { + // Insert or find existing product + pair::iterator, bool> item = mapProducts.insert(make_pair(hash, product)); + CProduct* pproduct = &(*(item.first)).second; + fNew = item.second; + + // Update if newer + if (product.nSequence > pproduct->nSequence) + { + *pproduct = product; + fUpdated = true; + } + } + + //if (fNew) + // NotifyProductAdded(hash); + //else if (fUpdated) + // NotifyProductUpdated(hash); + + return (fNew || fUpdated); +} + +void AdvertErase(const CProduct& product) +{ + uint256 hash = product.GetHash(); + CRITICAL_BLOCK(cs_mapProducts) + mapProducts.erase(hash); + //NotifyProductDeleted(hash); +} + + + + + + + + + + + + + + + + + + + +template +unsigned int Union(T& v1, T& v2) +{ + // v1 = v1 union v2 + // v1 and v2 must be sorted + // returns the number of elements added to v1 + + ///// need to check that this is equivalent, then delete this comment + //vector vUnion(v1.size() + v2.size()); + //vUnion.erase(set_union(v1.begin(), v1.end(), + // v2.begin(), v2.end(), + // vUnion.begin()), + // vUnion.end()); + + T vUnion; + vUnion.reserve(v1.size() + v2.size()); + set_union(v1.begin(), v1.end(), + v2.begin(), v2.end(), + back_inserter(vUnion)); + unsigned int nAdded = vUnion.size() - v1.size(); + if (nAdded > 0) + v1 = vUnion; + return nAdded; +} + +void CUser::AddAtom(unsigned short nAtom, bool fOrigin) +{ + // Ignore duplicates + if (binary_search(vAtomsIn.begin(), vAtomsIn.end(), nAtom) || + find(vAtomsNew.begin(), vAtomsNew.end(), nAtom) != vAtomsNew.end()) + return; + + //// instead of zero atom, should change to free atom that propagates, + //// limited to lower than a certain value like 5 so conflicts quickly + // The zero atom never propagates, + // new atoms always propagate through the user that created them + if (nAtom == 0 || fOrigin) + { + vector vTmp(1, nAtom); + Union(vAtomsIn, vTmp); + if (fOrigin) + vAtomsOut.push_back(nAtom); + return; + } + + vAtomsNew.push_back(nAtom); + + if (vAtomsNew.size() >= nFlowthroughRate || vAtomsOut.empty()) + { + // Select atom to flow through to vAtomsOut + vAtomsOut.push_back(vAtomsNew[GetRand(vAtomsNew.size())]); + + // Merge vAtomsNew into vAtomsIn + sort(vAtomsNew.begin(), vAtomsNew.end()); + Union(vAtomsIn, vAtomsNew); + vAtomsNew.clear(); + } +} + +bool AddAtomsAndPropagate(uint256 hashUserStart, const vector& vAtoms, bool fOrigin) +{ + CReviewDB reviewdb; + map > pmapPropagate[2]; + pmapPropagate[0][hashUserStart] = vAtoms; + + for (int side = 0; !pmapPropagate[side].empty(); side = 1 - side) + { + map >& mapFrom = pmapPropagate[side]; + map >& mapTo = pmapPropagate[1 - side]; + + for (map >::iterator mi = mapFrom.begin(); mi != mapFrom.end(); ++mi) + { + const uint256& hashUser = (*mi).first; + const vector& vReceived = (*mi).second; + + ///// this would be a lot easier on the database if it put the new atom at the beginning of the list, + ///// so the change would be right next to the vector size. + + // Read user + CUser user; + reviewdb.ReadUser(hashUser, user); + unsigned int nIn = user.vAtomsIn.size(); + unsigned int nNew = user.vAtomsNew.size(); + unsigned int nOut = user.vAtomsOut.size(); + + // Add atoms received + foreach(unsigned short nAtom, vReceived) + user.AddAtom(nAtom, fOrigin); + fOrigin = false; + + // Don't bother writing to disk if no changes + if (user.vAtomsIn.size() == nIn && user.vAtomsNew.size() == nNew) + continue; + + // Propagate + if (user.vAtomsOut.size() > nOut) + foreach(const uint256& hash, user.vLinksOut) + mapTo[hash].insert(mapTo[hash].end(), user.vAtomsOut.begin() + nOut, user.vAtomsOut.end()); + + // Write back + if (!reviewdb.WriteUser(hashUser, user)) + return false; + } + mapFrom.clear(); + } + return true; +} + + + + + + +bool CReview::AcceptReview() +{ + // Timestamp + nTime = GetTime(); + + // Check signature + if (!CKey::Verify(vchPubKeyFrom, GetSigHash(), vchSig)) + return false; + + CReviewDB reviewdb; + + // Add review text to recipient + vector vReviews; + reviewdb.ReadReviews(hashTo, vReviews); + vReviews.push_back(*this); + if (!reviewdb.WriteReviews(hashTo, vReviews)) + return false; + + // Add link from sender + CUser user; + uint256 hashFrom = Hash(vchPubKeyFrom.begin(), vchPubKeyFrom.end()); + reviewdb.ReadUser(hashFrom, user); + user.vLinksOut.push_back(hashTo); + if (!reviewdb.WriteUser(hashFrom, user)) + return false; + + reviewdb.Close(); + + // Propagate atoms to recipient + vector vZeroAtom(1, 0); + if (!AddAtomsAndPropagate(hashTo, user.vAtomsOut.size() ? user.vAtomsOut : vZeroAtom, false)) + return false; + + return true; +} + + + + + +bool CProduct::CheckSignature() +{ + return (CKey::Verify(vchPubKeyFrom, GetSigHash(), vchSig)); +} + +bool CProduct::CheckProduct() +{ + if (!CheckSignature()) + return false; + + // Make sure it's a summary product + if (!mapDetails.empty() || !vOrderForm.empty()) + return false; + + // Look up seller's atom count + CReviewDB reviewdb("r"); + CUser user; + reviewdb.ReadUser(GetUserHash(), user); + nAtoms = user.GetAtomCount(); + reviewdb.Close(); + + ////// delme, this is now done by AdvertInsert + //// Store to memory + //CRITICAL_BLOCK(cs_mapProducts) + // mapProducts[GetHash()] = *this; + + return true; +} diff --git a/market.h b/market.h new file mode 100644 index 0000000000..2714787307 --- /dev/null +++ b/market.h @@ -0,0 +1,182 @@ +// Copyright (c) 2009 Satoshi Nakamoto +// Distributed under the MIT/X11 software license, see the accompanying +// file license.txt or http://www.opensource.org/licenses/mit-license.php. + +class CUser; +class CReview; +class CProduct; + +static const unsigned int nFlowthroughRate = 2; + + + + +bool AdvertInsert(const CProduct& product); +void AdvertErase(const CProduct& product); +bool AddAtomsAndPropagate(uint256 hashUserStart, const vector& vAtoms, bool fOrigin); + + + + + + + + +class CUser +{ +public: + vector vAtomsIn; + vector vAtomsNew; + vector vAtomsOut; + vector vLinksOut; + + CUser() + { + } + + IMPLEMENT_SERIALIZE + ( + if (!(nType & SER_GETHASH)) + READWRITE(nVersion); + READWRITE(vAtomsIn); + READWRITE(vAtomsNew); + READWRITE(vAtomsOut); + READWRITE(vLinksOut); + ) + + void SetNull() + { + vAtomsIn.clear(); + vAtomsNew.clear(); + vAtomsOut.clear(); + vLinksOut.clear(); + } + + uint256 GetHash() const { return SerializeHash(*this); } + + + int GetAtomCount() const + { + return (vAtomsIn.size() + vAtomsNew.size()); + } + + void AddAtom(unsigned short nAtom, bool fOrigin); +}; + + + + + + + +class CReview +{ +public: + int nVersion; + uint256 hashTo; + map mapValue; + vector vchPubKeyFrom; + vector vchSig; + + // memory only + unsigned int nTime; + int nAtoms; + + + CReview() + { + nVersion = 1; + hashTo = 0; + nTime = 0; + nAtoms = 0; + } + + IMPLEMENT_SERIALIZE + ( + READWRITE(this->nVersion); + nVersion = this->nVersion; + if (!(nType & SER_DISK)) + READWRITE(hashTo); + READWRITE(mapValue); + READWRITE(vchPubKeyFrom); + if (!(nType & SER_GETHASH)) + READWRITE(vchSig); + ) + + uint256 GetHash() const { return SerializeHash(*this); } + uint256 GetSigHash() const { return SerializeHash(*this, SER_GETHASH|SER_SKIPSIG); } + uint256 GetUserHash() const { return Hash(vchPubKeyFrom.begin(), vchPubKeyFrom.end()); } + + + bool AcceptReview(); +}; + + + + + + + +class CProduct +{ +public: + int nVersion; + CAddress addr; + map mapValue; + map mapDetails; + vector > vOrderForm; + unsigned int nSequence; + vector vchPubKeyFrom; + vector vchSig; + + // disk only + int nAtoms; + + // memory only + set setSources; + + CProduct() + { + nVersion = 1; + nAtoms = 0; + nSequence = 0; + } + + IMPLEMENT_SERIALIZE + ( + READWRITE(this->nVersion); + nVersion = this->nVersion; + READWRITE(addr); + READWRITE(mapValue); + if (!(nType & SER_GETHASH)) + { + READWRITE(mapDetails); + READWRITE(vOrderForm); + READWRITE(nSequence); + } + READWRITE(vchPubKeyFrom); + if (!(nType & SER_GETHASH)) + READWRITE(vchSig); + if (nType & SER_DISK) + READWRITE(nAtoms); + ) + + uint256 GetHash() const { return SerializeHash(*this); } + uint256 GetSigHash() const { return SerializeHash(*this, SER_GETHASH|SER_SKIPSIG); } + uint256 GetUserHash() const { return Hash(vchPubKeyFrom.begin(), vchPubKeyFrom.end()); } + + + bool CheckSignature(); + bool CheckProduct(); +}; + + + + + + + + +extern map mapProducts; +extern CCriticalSection cs_mapProducts; +extern map mapMyProducts; diff --git a/mingwm10.dll b/mingwm10.dll new file mode 100644 index 0000000000..bf8544ce13 Binary files /dev/null and b/mingwm10.dll differ diff --git a/net.cpp b/net.cpp new file mode 100644 index 0000000000..b8d96006fc --- /dev/null +++ b/net.cpp @@ -0,0 +1,1100 @@ +// Copyright (c) 2009 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 + +void ThreadMessageHandler2(void* parg); +void ThreadSocketHandler2(void* parg); +void ThreadOpenConnections2(void* parg); + + + + + + +// +// Global state variables +// +bool fClient = false; +uint64 nLocalServices = (fClient ? 0 : NODE_NETWORK); +CAddress addrLocalHost(0, DEFAULT_PORT, nLocalServices); +CNode nodeLocalHost(INVALID_SOCKET, CAddress("127.0.0.1", nLocalServices)); +CNode* pnodeLocalHost = &nodeLocalHost; +bool fShutdown = false; +array vfThreadRunning; +vector vNodes; +CCriticalSection cs_vNodes; +map, CAddress> mapAddresses; +CCriticalSection cs_mapAddresses; +map mapRelay; +deque > vRelayExpiration; +CCriticalSection cs_mapRelay; +map mapAlreadyAskedFor; + + + +CAddress addrProxy; + +bool ConnectSocket(const CAddress& addrConnect, SOCKET& hSocketRet) +{ + hSocketRet = INVALID_SOCKET; + + SOCKET hSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (hSocket == INVALID_SOCKET) + return false; + + bool fRoutable = !(addrConnect.GetByte(3) == 10 || (addrConnect.GetByte(3) == 192 && addrConnect.GetByte(2) == 168)); + bool fProxy = (addrProxy.ip && fRoutable); + struct sockaddr_in sockaddr = (fProxy ? addrProxy.GetSockAddr() : addrConnect.GetSockAddr()); + + if (connect(hSocket, (struct sockaddr*)&sockaddr, sizeof(sockaddr)) == SOCKET_ERROR) + { + closesocket(hSocket); + return false; + } + + if (fProxy) + { + printf("Proxy connecting to %s\n", addrConnect.ToString().c_str()); + char pszSocks4IP[] = "\4\1\0\0\0\0\0\0user"; + memcpy(pszSocks4IP + 2, &addrConnect.port, 2); + memcpy(pszSocks4IP + 4, &addrConnect.ip, 4); + char* pszSocks4 = pszSocks4IP; + int nSize = sizeof(pszSocks4IP); + + int ret = send(hSocket, pszSocks4, nSize, 0); + if (ret != nSize) + { + closesocket(hSocket); + return error("Error sending to proxy\n"); + } + char pchRet[8]; + if (recv(hSocket, pchRet, 8, 0) != 8) + { + closesocket(hSocket); + return error("Error reading proxy response\n"); + } + if (pchRet[1] != 0x5a) + { + closesocket(hSocket); + return error("Proxy returned error %d\n", pchRet[1]); + } + printf("Proxy connection established %s\n", addrConnect.ToString().c_str()); + } + + hSocketRet = hSocket; + return true; +} + + + +bool GetMyExternalIP2(const CAddress& addrConnect, const char* pszGet, const char* pszKeyword, unsigned int& ipRet) +{ + SOCKET hSocket; + if (!ConnectSocket(addrConnect, hSocket)) + return error("GetMyExternalIP() : connection to %s failed\n", addrConnect.ToString().c_str()); + + send(hSocket, pszGet, strlen(pszGet), 0); + + string strLine; + while (RecvLine(hSocket, strLine)) + { + if (strLine.empty()) + { + loop + { + if (!RecvLine(hSocket, strLine)) + { + closesocket(hSocket); + return false; + } + if (strLine.find(pszKeyword) != -1) + { + strLine = strLine.substr(strLine.find(pszKeyword) + strlen(pszKeyword)); + break; + } + } + closesocket(hSocket); + if (strLine.find("<")) + strLine = strLine.substr(0, strLine.find("<")); + strLine = strLine.substr(strspn(strLine.c_str(), " \t\n\r")); + strLine = wxString(strLine).Trim(); + CAddress addr(strLine.c_str()); + printf("GetMyExternalIP() received [%s] %s\n", strLine.c_str(), addr.ToString().c_str()); + if (addr.ip == 0 || !addr.IsRoutable()) + return false; + ipRet = addr.ip; + return true; + } + } + closesocket(hSocket); + return error("GetMyExternalIP() : connection closed\n"); +} + + +bool GetMyExternalIP(unsigned int& ipRet) +{ + CAddress addrConnect; + char* pszGet; + char* pszKeyword; + + for (int nLookup = 0; nLookup <= 1; nLookup++) + for (int nHost = 1; nHost <= 2; nHost++) + { + if (nHost == 1) + { + addrConnect = CAddress("70.86.96.218:80"); // www.ipaddressworld.com + + if (nLookup == 1) + { + struct hostent* phostent = gethostbyname("www.ipaddressworld.com"); + if (phostent && phostent->h_addr_list && phostent->h_addr_list[0]) + addrConnect = CAddress(*(u_long*)phostent->h_addr_list[0], htons(80)); + } + + pszGet = "GET /ip.php HTTP/1.1\r\n" + "Host: www.ipaddressworld.com\r\n" + "User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)\r\n" + "Connection: close\r\n" + "\r\n"; + + pszKeyword = "IP:"; + } + else if (nHost == 2) + { + addrConnect = CAddress("208.78.68.70:80"); // checkip.dyndns.org + + if (nLookup == 1) + { + struct hostent* phostent = gethostbyname("checkip.dyndns.org"); + if (phostent && phostent->h_addr_list && phostent->h_addr_list[0]) + addrConnect = CAddress(*(u_long*)phostent->h_addr_list[0], htons(80)); + } + + pszGet = "GET / HTTP/1.1\r\n" + "Host: checkip.dyndns.org\r\n" + "User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)\r\n" + "Connection: close\r\n" + "\r\n"; + + pszKeyword = "Address:"; + } + + if (GetMyExternalIP2(addrConnect, pszGet, pszKeyword, ipRet)) + return true; + } + + return false; +} + + + + + +bool AddAddress(CAddrDB& addrdb, const CAddress& addr) +{ + if (!addr.IsRoutable()) + return false; + if (addr.ip == addrLocalHost.ip) + return false; + CRITICAL_BLOCK(cs_mapAddresses) + { + map, CAddress>::iterator it = mapAddresses.find(addr.GetKey()); + if (it == mapAddresses.end()) + { + // New address + mapAddresses.insert(make_pair(addr.GetKey(), addr)); + addrdb.WriteAddress(addr); + return true; + } + else + { + CAddress& addrFound = (*it).second; + if ((addrFound.nServices | addr.nServices) != addrFound.nServices) + { + // Services have been added + addrFound.nServices |= addr.nServices; + addrdb.WriteAddress(addrFound); + return true; + } + } + } + return false; +} + + + + + +void AbandonRequests(void (*fn)(void*, CDataStream&), void* param1) +{ + // If the dialog might get closed before the reply comes back, + // call this in the destructor so it doesn't get called after it's deleted. + CRITICAL_BLOCK(cs_vNodes) + { + foreach(CNode* pnode, vNodes) + { + CRITICAL_BLOCK(pnode->cs_mapRequests) + { + for (map::iterator mi = pnode->mapRequests.begin(); mi != pnode->mapRequests.end();) + { + CRequestTracker& tracker = (*mi).second; + if (tracker.fn == fn && tracker.param1 == param1) + pnode->mapRequests.erase(mi++); + else + mi++; + } + } + } + } +} + + + + + + + +// +// Subscription methods for the broadcast and subscription system. +// Channel numbers are message numbers, i.e. MSG_TABLE and MSG_PRODUCT. +// +// The subscription system uses a meet-in-the-middle strategy. +// With 100,000 nodes, if senders broadcast to 1000 random nodes and receivers +// subscribe to 1000 random nodes, 99.995% (1 - 0.99^1000) of messages will get through. +// + +bool AnySubscribed(unsigned int nChannel) +{ + if (pnodeLocalHost->IsSubscribed(nChannel)) + return true; + CRITICAL_BLOCK(cs_vNodes) + foreach(CNode* pnode, vNodes) + if (pnode->IsSubscribed(nChannel)) + return true; + return false; +} + +bool CNode::IsSubscribed(unsigned int nChannel) +{ + if (nChannel >= vfSubscribe.size()) + return false; + return vfSubscribe[nChannel]; +} + +void CNode::Subscribe(unsigned int nChannel, unsigned int nHops) +{ + if (nChannel >= vfSubscribe.size()) + return; + + if (!AnySubscribed(nChannel)) + { + // Relay subscribe + CRITICAL_BLOCK(cs_vNodes) + foreach(CNode* pnode, vNodes) + if (pnode != this) + pnode->PushMessage("subscribe", nChannel, nHops); + } + + vfSubscribe[nChannel] = true; +} + +void CNode::CancelSubscribe(unsigned int nChannel) +{ + if (nChannel >= vfSubscribe.size()) + return; + + // Prevent from relaying cancel if wasn't subscribed + if (!vfSubscribe[nChannel]) + return; + vfSubscribe[nChannel] = false; + + if (!AnySubscribed(nChannel)) + { + // Relay subscription cancel + CRITICAL_BLOCK(cs_vNodes) + foreach(CNode* pnode, vNodes) + if (pnode != this) + pnode->PushMessage("sub-cancel", nChannel); + + // Clear memory, no longer subscribed + if (nChannel == MSG_PRODUCT) + CRITICAL_BLOCK(cs_mapProducts) + mapProducts.clear(); + } +} + + + + + + + + + +CNode* FindNode(unsigned int ip) +{ + CRITICAL_BLOCK(cs_vNodes) + { + foreach(CNode* pnode, vNodes) + if (pnode->addr.ip == ip) + return (pnode); + } + return NULL; +} + +CNode* FindNode(CAddress addr) +{ + CRITICAL_BLOCK(cs_vNodes) + { + foreach(CNode* pnode, vNodes) + if (pnode->addr == addr) + return (pnode); + } + return NULL; +} + +CNode* ConnectNode(CAddress addrConnect, int64 nTimeout) +{ + if (addrConnect.ip == addrLocalHost.ip) + return NULL; + + // Look for an existing connection + CNode* pnode = FindNode(addrConnect.ip); + if (pnode) + { + if (nTimeout != 0) + pnode->AddRef(nTimeout); + else + pnode->AddRef(); + return pnode; + } + + /// debug print + printf("trying %s\n", addrConnect.ToString().c_str()); + + // Connect + SOCKET hSocket; + if (ConnectSocket(addrConnect, hSocket)) + { + /// debug print + printf("connected %s\n", addrConnect.ToString().c_str()); + + // Set to nonblocking + u_long nOne = 1; + if (ioctlsocket(hSocket, FIONBIO, &nOne) == SOCKET_ERROR) + printf("ConnectSocket() : ioctlsocket nonblocking setting failed, error %d\n", WSAGetLastError()); + + // Add node + CNode* pnode = new CNode(hSocket, addrConnect, false); + if (nTimeout != 0) + pnode->AddRef(nTimeout); + else + pnode->AddRef(); + CRITICAL_BLOCK(cs_vNodes) + vNodes.push_back(pnode); + + CRITICAL_BLOCK(cs_mapAddresses) + mapAddresses[addrConnect.GetKey()].nLastFailed = 0; + return pnode; + } + else + { + CRITICAL_BLOCK(cs_mapAddresses) + mapAddresses[addrConnect.GetKey()].nLastFailed = GetTime(); + return NULL; + } +} + +void CNode::Disconnect() +{ + printf("disconnecting node %s\n", addr.ToString().c_str()); + + closesocket(hSocket); + + // If outbound and never got version message, mark address as failed + if (!fInbound && nVersion == 0) + CRITICAL_BLOCK(cs_mapAddresses) + mapAddresses[addr.GetKey()].nLastFailed = GetTime(); + + // All of a nodes broadcasts and subscriptions are automatically torn down + // when it goes down, so a node has to stay up to keep its broadcast going. + + CRITICAL_BLOCK(cs_mapProducts) + for (map::iterator mi = mapProducts.begin(); mi != mapProducts.end();) + AdvertRemoveSource(this, MSG_PRODUCT, 0, (*(mi++)).second); + + // Cancel subscriptions + for (unsigned int nChannel = 0; nChannel < vfSubscribe.size(); nChannel++) + if (vfSubscribe[nChannel]) + CancelSubscribe(nChannel); +} + + + + + + + + + + + + + +void ThreadSocketHandler(void* parg) +{ + IMPLEMENT_RANDOMIZE_STACK(ThreadSocketHandler(parg)); + + loop + { + vfThreadRunning[0] = true; + CheckForShutdown(0); + try + { + ThreadSocketHandler2(parg); + } + CATCH_PRINT_EXCEPTION("ThreadSocketHandler()") + vfThreadRunning[0] = false; + Sleep(5000); + } +} + +void ThreadSocketHandler2(void* parg) +{ + printf("ThreadSocketHandler started\n"); + SOCKET hListenSocket = *(SOCKET*)parg; + list vNodesDisconnected; + int nPrevNodeCount = 0; + + loop + { + // + // Disconnect nodes + // + CRITICAL_BLOCK(cs_vNodes) + { + // Disconnect unused nodes + vector vNodesCopy = vNodes; + foreach(CNode* pnode, vNodesCopy) + { + if (pnode->ReadyToDisconnect() && pnode->vRecv.empty() && pnode->vSend.empty()) + { + // remove from vNodes + vNodes.erase(remove(vNodes.begin(), vNodes.end(), pnode), vNodes.end()); + pnode->Disconnect(); + + // hold in disconnected pool until all refs are released + pnode->nReleaseTime = max(pnode->nReleaseTime, GetTime() + 5 * 60); + if (pnode->fNetworkNode) + pnode->Release(); + vNodesDisconnected.push_back(pnode); + } + } + + // Delete disconnected nodes + list vNodesDisconnectedCopy = vNodesDisconnected; + foreach(CNode* pnode, vNodesDisconnectedCopy) + { + // wait until threads are done using it + if (pnode->GetRefCount() <= 0) + { + bool fDelete = false; + TRY_CRITICAL_BLOCK(pnode->cs_vSend) + TRY_CRITICAL_BLOCK(pnode->cs_vRecv) + TRY_CRITICAL_BLOCK(pnode->cs_mapRequests) + TRY_CRITICAL_BLOCK(pnode->cs_inventory) + fDelete = true; + if (fDelete) + { + vNodesDisconnected.remove(pnode); + delete pnode; + } + } + } + } + if (vNodes.size() != nPrevNodeCount) + { + nPrevNodeCount = vNodes.size(); + MainFrameRepaint(); + } + + + // + // Find which sockets have data to receive + // + struct timeval timeout; + timeout.tv_sec = 0; + timeout.tv_usec = 50000; // frequency to poll pnode->vSend + + struct fd_set fdsetRecv; + struct fd_set fdsetSend; + FD_ZERO(&fdsetRecv); + FD_ZERO(&fdsetSend); + SOCKET hSocketMax = 0; + FD_SET(hListenSocket, &fdsetRecv); + hSocketMax = max(hSocketMax, hListenSocket); + CRITICAL_BLOCK(cs_vNodes) + { + foreach(CNode* pnode, vNodes) + { + FD_SET(pnode->hSocket, &fdsetRecv); + hSocketMax = max(hSocketMax, pnode->hSocket); + TRY_CRITICAL_BLOCK(pnode->cs_vSend) + if (!pnode->vSend.empty()) + FD_SET(pnode->hSocket, &fdsetSend); + } + } + + vfThreadRunning[0] = false; + int nSelect = select(hSocketMax + 1, &fdsetRecv, &fdsetSend, NULL, &timeout); + vfThreadRunning[0] = true; + CheckForShutdown(0); + if (nSelect == SOCKET_ERROR) + { + int nErr = WSAGetLastError(); + printf("select failed: %d\n", nErr); + for (int i = 0; i <= hSocketMax; i++) + { + FD_SET(i, &fdsetRecv); + FD_SET(i, &fdsetSend); + } + Sleep(timeout.tv_usec/1000); + } + RandAddSeed(); + + //// debug print + //foreach(CNode* pnode, vNodes) + //{ + // printf("vRecv = %-5d ", pnode->vRecv.size()); + // printf("vSend = %-5d ", pnode->vSend.size()); + //} + //printf("\n"); + + + // + // Accept new connections + // + if (FD_ISSET(hListenSocket, &fdsetRecv)) + { + struct sockaddr_in sockaddr; + int len = sizeof(sockaddr); + SOCKET hSocket = accept(hListenSocket, (struct sockaddr*)&sockaddr, &len); + CAddress addr(sockaddr); + if (hSocket == INVALID_SOCKET) + { + if (WSAGetLastError() != WSAEWOULDBLOCK) + printf("ERROR ThreadSocketHandler accept failed: %d\n", WSAGetLastError()); + } + else + { + printf("accepted connection from %s\n", addr.ToString().c_str()); + CNode* pnode = new CNode(hSocket, addr, true); + pnode->AddRef(); + CRITICAL_BLOCK(cs_vNodes) + vNodes.push_back(pnode); + } + } + + + // + // Service each socket + // + vector vNodesCopy; + CRITICAL_BLOCK(cs_vNodes) + vNodesCopy = vNodes; + foreach(CNode* pnode, vNodesCopy) + { + CheckForShutdown(0); + SOCKET hSocket = pnode->hSocket; + + // + // Receive + // + if (FD_ISSET(hSocket, &fdsetRecv)) + { + TRY_CRITICAL_BLOCK(pnode->cs_vRecv) + { + CDataStream& vRecv = pnode->vRecv; + unsigned int nPos = vRecv.size(); + + // typical socket buffer is 8K-64K + const unsigned int nBufSize = 0x10000; + vRecv.resize(nPos + nBufSize); + int nBytes = recv(hSocket, &vRecv[nPos], nBufSize, 0); + vRecv.resize(nPos + max(nBytes, 0)); + if (nBytes == 0) + { + // socket closed gracefully + if (!pnode->fDisconnect) + printf("recv: socket closed\n"); + pnode->fDisconnect = true; + } + else if (nBytes < 0) + { + // socket error + int nErr = WSAGetLastError(); + if (nErr != WSAEWOULDBLOCK && nErr != WSAEMSGSIZE && nErr != WSAEINTR && nErr != WSAEINPROGRESS) + { + if (!pnode->fDisconnect) + printf("recv failed: %d\n", nErr); + pnode->fDisconnect = true; + } + } + } + } + + // + // Send + // + if (FD_ISSET(hSocket, &fdsetSend)) + { + TRY_CRITICAL_BLOCK(pnode->cs_vSend) + { + CDataStream& vSend = pnode->vSend; + if (!vSend.empty()) + { + int nBytes = send(hSocket, &vSend[0], vSend.size(), 0); + if (nBytes > 0) + { + vSend.erase(vSend.begin(), vSend.begin() + nBytes); + } + else if (nBytes == 0) + { + if (pnode->ReadyToDisconnect()) + pnode->vSend.clear(); + } + else + { + printf("send error %d\n", nBytes); + if (pnode->ReadyToDisconnect()) + pnode->vSend.clear(); + } + } + } + } + } + + + Sleep(10); + } +} + + + + + + + + + + +void ThreadOpenConnections(void* parg) +{ + IMPLEMENT_RANDOMIZE_STACK(ThreadOpenConnections(parg)); + + loop + { + vfThreadRunning[1] = true; + CheckForShutdown(1); + try + { + ThreadOpenConnections2(parg); + } + CATCH_PRINT_EXCEPTION("ThreadOpenConnections()") + vfThreadRunning[1] = false; + Sleep(5000); + } +} + +void ThreadOpenConnections2(void* parg) +{ + printf("ThreadOpenConnections started\n"); + + // Initiate network connections + int nTry = 0; + bool fIRCOnly = false; + const int nMaxConnections = 15; + loop + { + // Wait + vfThreadRunning[1] = false; + Sleep(500); + while (vNodes.size() >= nMaxConnections || vNodes.size() >= mapAddresses.size()) + { + CheckForShutdown(1); + Sleep(2000); + } + vfThreadRunning[1] = true; + CheckForShutdown(1); + + + // + // The IP selection process is designed to limit vulnerability to address flooding. + // Any class C (a.b.c.?) has an equal chance of being chosen, then an IP is + // chosen within the class C. An attacker may be able to allocate many IPs, but + // they would normally be concentrated in blocks of class C's. They can hog the + // attention within their class C, but not the whole IP address space overall. + // A lone node in a class C will get as much attention as someone holding all 255 + // IPs in another class C. + // + + // Every other try is with IRC addresses only + fIRCOnly = !fIRCOnly; + if (mapIRCAddresses.empty()) + fIRCOnly = false; + else if (nTry++ < 30 && vNodes.size() < nMaxConnections/2) + fIRCOnly = true; + + // Make a list of unique class C's + unsigned char pchIPCMask[4] = { 0xff, 0xff, 0xff, 0x00 }; + unsigned int nIPCMask = *(unsigned int*)pchIPCMask; + vector vIPC; + CRITICAL_BLOCK(cs_mapIRCAddresses) + CRITICAL_BLOCK(cs_mapAddresses) + { + vIPC.reserve(mapAddresses.size()); + unsigned int nPrev = 0; + foreach(const PAIRTYPE(vector, CAddress)& item, mapAddresses) + { + const CAddress& addr = item.second; + if (!addr.IsIPv4()) + continue; + if (fIRCOnly && !mapIRCAddresses.count(item.first)) + continue; + + // Taking advantage of mapAddresses being in sorted order, + // with IPs of the same class C grouped together. + unsigned int ipC = addr.ip & nIPCMask; + if (ipC != nPrev) + vIPC.push_back(nPrev = ipC); + } + } + if (vIPC.empty()) + continue; + + // Choose a random class C + unsigned int ipC = vIPC[GetRand(vIPC.size())]; + + // Organize all addresses in the class C by IP + map > mapIP; + CRITICAL_BLOCK(cs_mapIRCAddresses) + CRITICAL_BLOCK(cs_mapAddresses) + { + int64 nDelay = ((30 * 60) << vNodes.size()); + if (!fIRCOnly) + { + nDelay *= 2; + if (vNodes.size() >= 3) + nDelay *= 4; + if (!mapIRCAddresses.empty()) + nDelay *= 100; + } + + for (map, CAddress>::iterator mi = mapAddresses.lower_bound(CAddress(ipC, 0).GetKey()); + mi != mapAddresses.upper_bound(CAddress(ipC | ~nIPCMask, 0xffff).GetKey()); + ++mi) + { + const CAddress& addr = (*mi).second; + if (fIRCOnly && !mapIRCAddresses.count((*mi).first)) + continue; + + int64 nRandomizer = (addr.nLastFailed * addr.ip * 7777U) % 20000; + if (GetTime() - addr.nLastFailed > nDelay * nRandomizer / 10000) + mapIP[addr.ip].push_back(addr); + } + } + if (mapIP.empty()) + continue; + + // Choose a random IP in the class C + map >::iterator mi = mapIP.begin(); + advance(mi, GetRand(mapIP.size())); + + // Once we've chosen an IP, we'll try every given port before moving on + foreach(const CAddress& addrConnect, (*mi).second) + { + // + // Initiate outbound network connection + // + CheckForShutdown(1); + if (addrConnect.ip == addrLocalHost.ip || !addrConnect.IsIPv4() || FindNode(addrConnect.ip)) + continue; + + vfThreadRunning[1] = false; + CNode* pnode = ConnectNode(addrConnect); + vfThreadRunning[1] = true; + CheckForShutdown(1); + if (!pnode) + continue; + pnode->fNetworkNode = true; + + if (addrLocalHost.IsRoutable()) + { + // Advertise our address + vector vAddrToSend; + vAddrToSend.push_back(addrLocalHost); + pnode->PushMessage("addr", vAddrToSend); + } + + // Get as many addresses as we can + pnode->PushMessage("getaddr"); + + ////// should the one on the receiving end do this too? + // Subscribe our local subscription list + const unsigned int nHops = 0; + for (unsigned int nChannel = 0; nChannel < pnodeLocalHost->vfSubscribe.size(); nChannel++) + if (pnodeLocalHost->vfSubscribe[nChannel]) + pnode->PushMessage("subscribe", nChannel, nHops); + + break; + } + } +} + + + + + + + + +void ThreadMessageHandler(void* parg) +{ + IMPLEMENT_RANDOMIZE_STACK(ThreadMessageHandler(parg)); + + loop + { + vfThreadRunning[2] = true; + CheckForShutdown(2); + try + { + ThreadMessageHandler2(parg); + } + CATCH_PRINT_EXCEPTION("ThreadMessageHandler()") + vfThreadRunning[2] = false; + Sleep(5000); + } +} + +void ThreadMessageHandler2(void* parg) +{ + printf("ThreadMessageHandler started\n"); + SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_BELOW_NORMAL); + loop + { + // Poll the connected nodes for messages + vector vNodesCopy; + CRITICAL_BLOCK(cs_vNodes) + vNodesCopy = vNodes; + foreach(CNode* pnode, vNodesCopy) + { + pnode->AddRef(); + + // Receive messages + TRY_CRITICAL_BLOCK(pnode->cs_vRecv) + ProcessMessages(pnode); + + // Send messages + TRY_CRITICAL_BLOCK(pnode->cs_vSend) + SendMessages(pnode); + + pnode->Release(); + } + + // Wait and allow messages to bunch up + vfThreadRunning[2] = false; + Sleep(100); + vfThreadRunning[2] = true; + CheckForShutdown(2); + } +} + + + + + + + + + +//// todo: start one thread per processor, use getenv("NUMBER_OF_PROCESSORS") +void ThreadBitcoinMiner(void* parg) +{ + vfThreadRunning[3] = true; + CheckForShutdown(3); + try + { + bool fRet = BitcoinMiner(); + printf("BitcoinMiner returned %s\n\n\n", fRet ? "true" : "false"); + } + CATCH_PRINT_EXCEPTION("BitcoinMiner()") + vfThreadRunning[3] = false; +} + + + + + + + + + + + +bool StartNode(string& strError) +{ + strError = ""; + + // Sockets startup + WSADATA wsadata; + int ret = WSAStartup(MAKEWORD(2,2), &wsadata); + if (ret != NO_ERROR) + { + strError = strprintf("Error: TCP/IP socket library failed to start (WSAStartup returned error %d)", ret); + printf("%s\n", strError.c_str()); + return false; + } + + // Get local host ip + char pszHostName[255]; + if (gethostname(pszHostName, 255) == SOCKET_ERROR) + { + strError = strprintf("Error: Unable to get IP address of this computer (gethostname returned error %d)", WSAGetLastError()); + printf("%s\n", strError.c_str()); + return false; + } + struct hostent* phostent = gethostbyname(pszHostName); + if (!phostent) + { + strError = strprintf("Error: Unable to get IP address of this computer (gethostbyname returned error %d)", WSAGetLastError()); + printf("%s\n", strError.c_str()); + return false; + } + addrLocalHost = CAddress(*(long*)(phostent->h_addr_list[0]), + DEFAULT_PORT, + nLocalServices); + printf("addrLocalHost = %s\n", addrLocalHost.ToString().c_str()); + + // Create socket for listening for incoming connections + SOCKET hListenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (hListenSocket == INVALID_SOCKET) + { + strError = strprintf("Error: Couldn't open socket for incoming connections (socket returned error %d)", WSAGetLastError()); + printf("%s\n", strError.c_str()); + return false; + } + + // Set to nonblocking, incoming connections will also inherit this + u_long nOne = 1; + if (ioctlsocket(hListenSocket, FIONBIO, &nOne) == SOCKET_ERROR) + { + strError = strprintf("Error: Couldn't set properties on socket for incoming connections (ioctlsocket returned error %d)", WSAGetLastError()); + printf("%s\n", strError.c_str()); + return false; + } + + // The sockaddr_in structure specifies the address family, + // IP address, and port for the socket that is being bound + int nRetryLimit = 15; + struct sockaddr_in sockaddr = addrLocalHost.GetSockAddr(); + if (bind(hListenSocket, (struct sockaddr*)&sockaddr, sizeof(sockaddr)) == SOCKET_ERROR) + { + int nErr = WSAGetLastError(); + if (nErr == WSAEADDRINUSE) + strError = strprintf("Error: Unable to bind to port %s on this computer. The program is probably already running.", addrLocalHost.ToString().c_str()); + else + strError = strprintf("Error: Unable to bind to port %s on this computer (bind returned error %d)", addrLocalHost.ToString().c_str(), nErr); + printf("%s\n", strError.c_str()); + return false; + } + printf("bound to addrLocalHost = %s\n\n", addrLocalHost.ToString().c_str()); + + // Listen for incoming connections + if (listen(hListenSocket, SOMAXCONN) == SOCKET_ERROR) + { + strError = strprintf("Error: Listening for incoming connections failed (listen returned error %d)", WSAGetLastError()); + printf("%s\n", strError.c_str()); + return false; + } + + // Get our external IP address for incoming connections + if (addrIncoming.ip) + addrLocalHost.ip = addrIncoming.ip; + + if (GetMyExternalIP(addrLocalHost.ip)) + { + addrIncoming = addrLocalHost; + CWalletDB().WriteSetting("addrIncoming", addrIncoming); + } + + // Get addresses from IRC and advertise ours + if (_beginthread(ThreadIRCSeed, 0, NULL) == -1) + printf("Error: _beginthread(ThreadIRCSeed) failed\n"); + + // + // Start threads + // + if (_beginthread(ThreadSocketHandler, 0, new SOCKET(hListenSocket)) == -1) + { + strError = "Error: _beginthread(ThreadSocketHandler) failed"; + printf("%s\n", strError.c_str()); + return false; + } + + if (_beginthread(ThreadOpenConnections, 0, NULL) == -1) + { + strError = "Error: _beginthread(ThreadOpenConnections) failed"; + printf("%s\n", strError.c_str()); + return false; + } + + if (_beginthread(ThreadMessageHandler, 0, NULL) == -1) + { + strError = "Error: _beginthread(ThreadMessageHandler) failed"; + printf("%s\n", strError.c_str()); + return false; + } + + return true; +} + +bool StopNode() +{ + printf("StopNode()\n"); + fShutdown = true; + nTransactionsUpdated++; + int64 nStart = GetTime(); + while (vfThreadRunning[0] || vfThreadRunning[2] || vfThreadRunning[3]) + { + if (GetTime() - nStart > 15) + break; + Sleep(20); + } + if (vfThreadRunning[0]) printf("ThreadSocketHandler still running\n"); + if (vfThreadRunning[1]) printf("ThreadOpenConnections still running\n"); + if (vfThreadRunning[2]) printf("ThreadMessageHandler still running\n"); + if (vfThreadRunning[3]) printf("ThreadBitcoinMiner still running\n"); + while (vfThreadRunning[2]) + Sleep(20); + Sleep(50); + + // Sockets shutdown + WSACleanup(); + return true; +} + +void CheckForShutdown(int n) +{ + if (fShutdown) + { + if (n != -1) + vfThreadRunning[n] = false; + if (n == 0) + foreach(CNode* pnode, vNodes) + closesocket(pnode->hSocket); + _endthread(); + } +} diff --git a/net.h b/net.h new file mode 100644 index 0000000000..cd311fc502 --- /dev/null +++ b/net.h @@ -0,0 +1,856 @@ +// Copyright (c) 2009 Satoshi Nakamoto +// Distributed under the MIT/X11 software license, see the accompanying +// file license.txt or http://www.opensource.org/licenses/mit-license.php. + +class CMessageHeader; +class CAddress; +class CInv; +class CRequestTracker; +class CNode; + + + +static const unsigned short DEFAULT_PORT = htons(8333); +static const unsigned int PUBLISH_HOPS = 5; +enum +{ + NODE_NETWORK = (1 << 0), +}; + + + + + + +bool ConnectSocket(const CAddress& addrConnect, SOCKET& hSocketRet); +bool GetMyExternalIP(unsigned int& ipRet); +bool AddAddress(CAddrDB& addrdb, const CAddress& addr); +CNode* FindNode(unsigned int ip); +CNode* ConnectNode(CAddress addrConnect, int64 nTimeout=0); +void AbandonRequests(void (*fn)(void*, CDataStream&), void* param1); +bool AnySubscribed(unsigned int nChannel); +void ThreadBitcoinMiner(void* parg); +bool StartNode(string& strError=REF(string())); +bool StopNode(); +void CheckForShutdown(int n); + + + + + + + + + +// +// Message header +// (4) message start +// (12) command +// (4) size + +// 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. +static const char pchMessageStart[4] = { 0xf9, 0xbe, 0xb4, 0xd9 }; + +class CMessageHeader +{ +public: + enum { COMMAND_SIZE=12 }; + char pchMessageStart[sizeof(::pchMessageStart)]; + char pchCommand[COMMAND_SIZE]; + unsigned int nMessageSize; + + CMessageHeader() + { + memcpy(pchMessageStart, ::pchMessageStart, sizeof(pchMessageStart)); + memset(pchCommand, 0, sizeof(pchCommand)); + pchCommand[1] = 1; + nMessageSize = -1; + } + + CMessageHeader(const char* pszCommand, unsigned int nMessageSizeIn) + { + memcpy(pchMessageStart, ::pchMessageStart, sizeof(pchMessageStart)); + strncpy(pchCommand, pszCommand, COMMAND_SIZE); + nMessageSize = nMessageSizeIn; + } + + IMPLEMENT_SERIALIZE + ( + READWRITE(FLATDATA(pchMessageStart)); + READWRITE(FLATDATA(pchCommand)); + READWRITE(nMessageSize); + ) + + string GetCommand() + { + if (pchCommand[COMMAND_SIZE-1] == 0) + return string(pchCommand, pchCommand + strlen(pchCommand)); + else + return 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 > 0x10000000) + { + printf("CMessageHeader::IsValid() : nMessageSize too large %u\n", 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 only + unsigned int nTime; + + // memory only + unsigned int nLastFailed; + + CAddress() + { + nServices = 0; + memcpy(pchReserved, pchIPv4, sizeof(pchReserved)); + ip = 0; + port = DEFAULT_PORT; + nTime = GetAdjustedTime(); + nLastFailed = 0; + } + + CAddress(unsigned int ipIn, unsigned short portIn=DEFAULT_PORT, uint64 nServicesIn=0) + { + nServices = nServicesIn; + memcpy(pchReserved, pchIPv4, sizeof(pchReserved)); + ip = ipIn; + port = portIn; + nTime = GetAdjustedTime(); + nLastFailed = 0; + } + + explicit CAddress(const struct sockaddr_in& sockaddr, uint64 nServicesIn=0) + { + nServices = nServicesIn; + memcpy(pchReserved, pchIPv4, sizeof(pchReserved)); + ip = sockaddr.sin_addr.s_addr; + port = sockaddr.sin_port; + nTime = GetAdjustedTime(); + nLastFailed = 0; + } + + explicit CAddress(const char* pszIn, uint64 nServicesIn=0) + { + nServices = nServicesIn; + memcpy(pchReserved, pchIPv4, sizeof(pchReserved)); + ip = 0; + port = DEFAULT_PORT; + nTime = GetAdjustedTime(); + nLastFailed = 0; + + char psz[100]; + if (strlen(pszIn) > ARRAYLEN(psz)-1) + return; + strcpy(psz, pszIn); + unsigned int a, b, c, d, e; + if (sscanf(psz, "%u.%u.%u.%u:%u", &a, &b, &c, &d, &e) < 4) + return; + char* pszPort = strchr(psz, ':'); + if (pszPort) + { + *pszPort++ = '\0'; + port = htons(atoi(pszPort)); + } + ip = inet_addr(psz); + } + + IMPLEMENT_SERIALIZE + ( + if (nType & SER_DISK) + { + READWRITE(nVersion); + READWRITE(nTime); + } + READWRITE(nServices); + READWRITE(FLATDATA(pchReserved)); + 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) + { + 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; + } + + vector GetKey() const + { + CDataStream ss; + ss.reserve(18); + ss << FLATDATA(pchReserved) << ip << port; + + #if defined(_MSC_VER) && _MSC_VER < 1300 + return vector((unsigned char*)&ss.begin()[0], (unsigned char*)&ss.end()[0]); + #else + return vector(ss.begin(), ss.end()); + #endif + } + + struct sockaddr_in GetSockAddr() const + { + struct sockaddr_in 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 IsRoutable() const + { + return !(GetByte(3) == 10 || (GetByte(3) == 192 && GetByte(2) == 168) || GetByte(3) == 127 || GetByte(3) == 0); + } + + unsigned char GetByte(int n) const + { + return ((unsigned char*)&ip)[3-n]; + } + + string ToStringIPPort() const + { + return strprintf("%u.%u.%u.%u:%u", GetByte(3), GetByte(2), GetByte(1), GetByte(0), ntohs(port)); + } + + string ToStringIP() const + { + return strprintf("%u.%u.%u.%u", GetByte(3), GetByte(2), GetByte(1), GetByte(0)); + } + + string ToString() const + { + return strprintf("%u.%u.%u.%u:%u", GetByte(3), GetByte(2), GetByte(1), GetByte(0), ntohs(port)); + //return strprintf("%u.%u.%u.%u", GetByte(3), GetByte(2), GetByte(1), GetByte(0)); + } + + void print() const + { + printf("CAddress(%s)\n", ToString().c_str()); + } +}; + + + + + + + +enum +{ + MSG_TX = 1, + MSG_BLOCK, + MSG_REVIEW, + MSG_PRODUCT, + MSG_TABLE, +}; + +static const char* ppszTypeName[] = +{ + "ERROR", + "tx", + "block", + "review", + "product", + "table", +}; + +class CInv +{ +public: + int type; + uint256 hash; + + CInv() + { + type = 0; + hash = 0; + } + + CInv(int typeIn, const uint256& hashIn) + { + type = typeIn; + hash = hashIn; + } + + CInv(const 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=% unknown type", type)); + return ppszTypeName[type]; + } + + string ToString() const + { + return strprintf("%s %s", GetCommand(), hash.ToString().substr(0,14).c_str()); + } + + void print() const + { + printf("CInv(%s)\n", ToString().c_str()); + } +}; + + + + + +class CRequestTracker +{ +public: + void (*fn)(void*, CDataStream&); + void* param1; + + explicit CRequestTracker(void (*fnIn)(void*, CDataStream&)=NULL, void* param1In=NULL) + { + fn = fnIn; + param1 = param1In; + } + + bool IsNull() + { + return fn == NULL; + } +}; + + + + + +extern bool fClient; +extern uint64 nLocalServices; +extern CAddress addrLocalHost; +extern CNode* pnodeLocalHost; +extern bool fShutdown; +extern array vfThreadRunning; +extern vector vNodes; +extern CCriticalSection cs_vNodes; +extern map, CAddress> mapAddresses; +extern CCriticalSection cs_mapAddresses; +extern map mapRelay; +extern deque > vRelayExpiration; +extern CCriticalSection cs_mapRelay; +extern map mapAlreadyAskedFor; +extern CAddress addrProxy; + + + + + +class CNode +{ +public: + // socket + uint64 nServices; + SOCKET hSocket; + CDataStream vSend; + CDataStream vRecv; + CCriticalSection cs_vSend; + CCriticalSection cs_vRecv; + unsigned int nPushPos; + CAddress addr; + int nVersion; + bool fClient; + bool fInbound; + bool fNetworkNode; + bool fDisconnect; +protected: + int nRefCount; +public: + int64 nReleaseTime; + map mapRequests; + CCriticalSection cs_mapRequests; + + // flood + vector vAddrToSend; + set setAddrKnown; + + // inventory based relay + set setInventoryKnown; + set setInventoryKnown2; + vector vInventoryToSend; + CCriticalSection cs_inventory; + multimap mapAskFor; + + // publish and subscription + vector vfSubscribe; + + + CNode(SOCKET hSocketIn, CAddress addrIn, bool fInboundIn=false) + { + nServices = 0; + hSocket = hSocketIn; + vSend.SetType(SER_NETWORK); + vRecv.SetType(SER_NETWORK); + nPushPos = -1; + addr = addrIn; + nVersion = 0; + fClient = false; // set by version message + fInbound = fInboundIn; + fNetworkNode = false; + fDisconnect = false; + nRefCount = 0; + nReleaseTime = 0; + vfSubscribe.assign(256, false); + + // Push a version message + /// when NTP implemented, change to just nTime = GetAdjustedTime() + int64 nTime = (fInbound ? GetAdjustedTime() : GetTime()); + PushMessage("version", VERSION, nLocalServices, nTime, addr); + } + + ~CNode() + { + if (hSocket != INVALID_SOCKET) + closesocket(hSocket); + } + +private: + CNode(const CNode&); + void operator=(const CNode&); +public: + + + bool ReadyToDisconnect() + { + return fDisconnect || GetRefCount() <= 0; + } + + int GetRefCount() + { + return max(nRefCount, 0) + (GetTime() < nReleaseTime ? 1 : 0); + } + + void AddRef(int64 nTimeout=0) + { + if (nTimeout != 0) + nReleaseTime = max(nReleaseTime, GetTime() + nTimeout); + else + nRefCount++; + } + + void Release() + { + nRefCount--; + } + + + + void AddInventoryKnown(const CInv& inv) + { + CRITICAL_BLOCK(cs_inventory) + setInventoryKnown.insert(inv); + } + + void PushInventory(const CInv& inv) + { + CRITICAL_BLOCK(cs_inventory) + if (!setInventoryKnown.count(inv)) + vInventoryToSend.push_back(inv); + } + + void AskFor(const CInv& inv) + { + // We're using mapAskFor as a priority queue, + // the key is the earliest time the request can be sent + int64& nRequestTime = mapAlreadyAskedFor[inv]; + printf("askfor %s %I64d\n", inv.ToString().c_str(), nRequestTime); + + // Make sure not to reuse time indexes to keep things in the same order + int64 nNow = (GetTime() - 1) * 1000000; + static int64 nLastTime; + nLastTime = nNow = max(nNow, ++nLastTime); + + // Each retry is 2 minutes after the last + nRequestTime = max(nRequestTime + 2 * 60 * 1000000, nNow); + mapAskFor.insert(make_pair(nRequestTime, inv)); + } + + + + void BeginMessage(const char* pszCommand) + { + EnterCriticalSection(&cs_vSend); + if (nPushPos != -1) + AbortMessage(); + nPushPos = vSend.size(); + vSend << CMessageHeader(pszCommand, 0); + printf("sending: %-12s ", pszCommand); + } + + void AbortMessage() + { + if (nPushPos == -1) + return; + vSend.resize(nPushPos); + nPushPos = -1; + LeaveCriticalSection(&cs_vSend); + printf("(aborted)\n"); + } + + void EndMessage() + { + extern int nDropMessagesTest; + if (nDropMessagesTest > 0 && GetRand(nDropMessagesTest) == 0) + { + printf("dropmessages DROPPING SEND MESSAGE\n"); + AbortMessage(); + return; + } + + if (nPushPos == -1) + return; + + // Patch in the size + unsigned int nSize = vSend.size() - nPushPos - sizeof(CMessageHeader); + memcpy((char*)&vSend[nPushPos] + offsetof(CMessageHeader, nMessageSize), &nSize, sizeof(nSize)); + + printf("(%d bytes) ", nSize); + //for (int i = nPushPos+sizeof(CMessageHeader); i < min(vSend.size(), nPushPos+sizeof(CMessageHeader)+20U); i++) + // printf("%02x ", vSend[i] & 0xff); + printf("\n"); + + nPushPos = -1; + LeaveCriticalSection(&cs_vSend); + } + + void EndMessageAbortIfEmpty() + { + if (nPushPos == -1) + return; + int nSize = vSend.size() - nPushPos - sizeof(CMessageHeader); + if (nSize > 0) + EndMessage(); + else + AbortMessage(); + } + + const char* GetMessageCommand() const + { + if (nPushPos == -1) + return ""; + return &vSend[nPushPos] + offsetof(CMessageHeader, pchCommand); + } + + + + + void PushMessage(const char* pszCommand) + { + try + { + BeginMessage(pszCommand); + EndMessage(); + } + catch (...) + { + AbortMessage(); + throw; + } + } + + template + void PushMessage(const char* pszCommand, const T1& a1) + { + try + { + BeginMessage(pszCommand); + vSend << a1; + EndMessage(); + } + catch (...) + { + AbortMessage(); + throw; + } + } + + template + void PushMessage(const char* pszCommand, const T1& a1, const T2& a2) + { + try + { + BeginMessage(pszCommand); + vSend << a1 << a2; + EndMessage(); + } + catch (...) + { + AbortMessage(); + throw; + } + } + + template + void PushMessage(const char* pszCommand, const T1& a1, const T2& a2, const T3& a3) + { + try + { + BeginMessage(pszCommand); + vSend << a1 << a2 << a3; + EndMessage(); + } + catch (...) + { + AbortMessage(); + throw; + } + } + + template + void PushMessage(const char* pszCommand, const T1& a1, const T2& a2, const T3& a3, const T4& a4) + { + try + { + BeginMessage(pszCommand); + vSend << a1 << a2 << a3 << a4; + EndMessage(); + } + catch (...) + { + AbortMessage(); + throw; + } + } + + + void PushRequest(const char* pszCommand, + void (*fn)(void*, CDataStream&), void* param1) + { + uint256 hashReply; + RAND_bytes((unsigned char*)&hashReply, sizeof(hashReply)); + + CRITICAL_BLOCK(cs_mapRequests) + mapRequests[hashReply] = CRequestTracker(fn, param1); + + PushMessage(pszCommand, hashReply); + } + + template + void PushRequest(const char* pszCommand, const T1& a1, + void (*fn)(void*, CDataStream&), void* param1) + { + uint256 hashReply; + RAND_bytes((unsigned char*)&hashReply, sizeof(hashReply)); + + CRITICAL_BLOCK(cs_mapRequests) + mapRequests[hashReply] = CRequestTracker(fn, param1); + + PushMessage(pszCommand, hashReply, a1); + } + + template + void PushRequest(const char* pszCommand, const T1& a1, const T2& a2, + void (*fn)(void*, CDataStream&), void* param1) + { + uint256 hashReply; + RAND_bytes((unsigned char*)&hashReply, sizeof(hashReply)); + + CRITICAL_BLOCK(cs_mapRequests) + mapRequests[hashReply] = CRequestTracker(fn, param1); + + PushMessage(pszCommand, hashReply, a1, a2); + } + + + + bool IsSubscribed(unsigned int nChannel); + void Subscribe(unsigned int nChannel, unsigned int nHops=0); + void CancelSubscribe(unsigned int nChannel); + void Disconnect(); +}; + + + + + + + + + + +inline void RelayInventory(const CInv& inv) +{ + // Put on lists to offer to the other nodes + CRITICAL_BLOCK(cs_vNodes) + foreach(CNode* pnode, vNodes) + pnode->PushInventory(inv); +} + +template +void RelayMessage(const CInv& inv, const T& a) +{ + CDataStream ss(SER_NETWORK); + ss.reserve(10000); + ss << a; + RelayMessage(inv, ss); +} + +template<> +inline void RelayMessage<>(const CInv& inv, const CDataStream& ss) +{ + CRITICAL_BLOCK(cs_mapRelay) + { + // Expire old relay messages + while (!vRelayExpiration.empty() && vRelayExpiration.front().first < GetTime()) + { + mapRelay.erase(vRelayExpiration.front().second); + vRelayExpiration.pop_front(); + } + + // Save original serialized message so newer versions are preserved + mapRelay[inv] = ss; + vRelayExpiration.push_back(make_pair(GetTime() + 15 * 60, inv)); + } + + RelayInventory(inv); +} + + + + + + + + +// +// Templates for the publish and subscription system. +// The object being published as T& obj needs to have: +// a set setSources member +// specializations of AdvertInsert and AdvertErase +// Currently implemented for CTable and CProduct. +// + +template +void AdvertStartPublish(CNode* pfrom, unsigned int nChannel, unsigned int nHops, T& obj) +{ + // Add to sources + obj.setSources.insert(pfrom->addr.ip); + + if (!AdvertInsert(obj)) + return; + + // Relay + CRITICAL_BLOCK(cs_vNodes) + foreach(CNode* pnode, vNodes) + if (pnode != pfrom && (nHops < PUBLISH_HOPS || pnode->IsSubscribed(nChannel))) + pnode->PushMessage("publish", nChannel, nHops, obj); +} + +template +void AdvertStopPublish(CNode* pfrom, unsigned int nChannel, unsigned int nHops, T& obj) +{ + uint256 hash = obj.GetHash(); + + CRITICAL_BLOCK(cs_vNodes) + foreach(CNode* pnode, vNodes) + if (pnode != pfrom && (nHops < PUBLISH_HOPS || pnode->IsSubscribed(nChannel))) + pnode->PushMessage("pub-cancel", nChannel, nHops, hash); + + AdvertErase(obj); +} + +template +void AdvertRemoveSource(CNode* pfrom, unsigned int nChannel, unsigned int nHops, T& obj) +{ + // Remove a source + obj.setSources.erase(pfrom->addr.ip); + + // If no longer supported by any sources, cancel it + if (obj.setSources.empty()) + AdvertStopPublish(pfrom, nChannel, nHops, obj); +} diff --git a/rc/addressbook16.bmp b/rc/addressbook16.bmp new file mode 100644 index 0000000000..c5576910b1 Binary files /dev/null and b/rc/addressbook16.bmp differ diff --git a/rc/addressbook16mask.bmp b/rc/addressbook16mask.bmp new file mode 100644 index 0000000000..d3a478d1ad Binary files /dev/null and b/rc/addressbook16mask.bmp differ diff --git a/rc/addressbook20.bmp b/rc/addressbook20.bmp new file mode 100644 index 0000000000..2b33b228aa Binary files /dev/null and b/rc/addressbook20.bmp differ diff --git a/rc/addressbook20mask.bmp b/rc/addressbook20mask.bmp new file mode 100644 index 0000000000..56ce6125db Binary files /dev/null and b/rc/addressbook20mask.bmp differ diff --git a/rc/bitcoin.ico b/rc/bitcoin.ico new file mode 100644 index 0000000000..88cc240e2d Binary files /dev/null and b/rc/bitcoin.ico differ diff --git a/rc/check.ico b/rc/check.ico new file mode 100644 index 0000000000..0c4e6e8147 Binary files /dev/null and b/rc/check.ico differ diff --git a/rc/send16.bmp b/rc/send16.bmp new file mode 100644 index 0000000000..676b5c4b49 Binary files /dev/null and b/rc/send16.bmp differ diff --git a/rc/send16mask.bmp b/rc/send16mask.bmp new file mode 100644 index 0000000000..06c747f934 Binary files /dev/null and b/rc/send16mask.bmp differ diff --git a/rc/send16masknoshadow.bmp b/rc/send16masknoshadow.bmp new file mode 100644 index 0000000000..faf24e0d8a Binary files /dev/null and b/rc/send16masknoshadow.bmp differ diff --git a/rc/send20.bmp b/rc/send20.bmp new file mode 100644 index 0000000000..2b90422b38 Binary files /dev/null and b/rc/send20.bmp differ diff --git a/rc/send20mask.bmp b/rc/send20mask.bmp new file mode 100644 index 0000000000..f124d0da08 Binary files /dev/null and b/rc/send20mask.bmp differ diff --git a/readme.txt b/readme.txt new file mode 100644 index 0000000000..7615e6fd83 --- /dev/null +++ b/readme.txt @@ -0,0 +1,76 @@ +BitCoin v0.1.5 ALPHA + +Copyright (c) 2009 Satoshi Nakamoto +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/). This product includes +cryptographic software written by Eric Young (eay@cryptsoft.com). + + +Compilers Supported +------------------- +MinGW GCC (v3.4.5) +Microsoft Visual C++ 6.0 SP6 + + +Dependencies +------------ +Libraries you need to obtain separately to build: + + default path download +wxWidgets \wxWidgets http://www.wxwidgets.org/downloads/ +OpenSSL \OpenSSL http://www.openssl.org/source/ +Berkeley DB \DB http://www.oracle.com/technology/software/products/berkeley-db/index.html +Boost \Boost http://www.boost.org/users/download/ + +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 + + +OpenSSL +------- +Bitcoin does not use any encryption. If you want to do a no-everything +build of OpenSSL to exclude encryption routines, a few patches are required. +(OpenSSL v0.9.8h) + +Edit engines\e_gmp.c and put this #ifndef around #include + #ifndef OPENSSL_NO_RSA + #include + #endif + +Add this to crypto\err\err_all.c before the ERR_load_crypto_strings line: + void ERR_load_RSA_strings(void) { } + +Edit ms\mingw32.bat and replace the Configure line's parameters with this +no-everything list. You have to put this in the batch file because batch +files can't handle more than 9 parameters. + perl Configure mingw threads no-rc2 no-rc4 no-rc5 no-idea no-des no-bf no-cast no-aes no-camellia no-seed no-rsa no-dh + +Also REM out the following line in ms\mingw32.bat. The build fails after it's +already finished building libeay32, which is all we care about, but the +failure aborts the script before it runs dllwrap to generate libeay32.dll. + REM if errorlevel 1 goto end + +Build + ms\mingw32.bat + +If you want to use it with MSVC, generate the .lib file + lib /machine:i386 /def:ms\libeay32.def /out:out\libeay32.lib + + +Berkeley DB +----------- +MinGW with MSYS: +cd \DB\build_unix +sh ../dist/configure --enable-mingw --enable-cxx +make + + +Boost +----- +You may need Boost version 1.35 to build with MSVC 6.0. I couldn't get +version 1.37 to compile with MSVC 6.0. diff --git a/script.cpp b/script.cpp new file mode 100644 index 0000000000..0e95af503c --- /dev/null +++ b/script.cpp @@ -0,0 +1,1127 @@ +// Copyright (c) 2009 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" + +bool CheckSig(vector vchSig, vector vchPubKey, CScript scriptCode, const CTransaction& txTo, unsigned int nIn, int nHashType); + + + +typedef vector valtype; +static const valtype vchFalse(0); +static const valtype vchZero(0); +static const valtype vchTrue(1, 1); +static const CBigNum bnZero(0); +static const CBigNum bnOne(1); +static const CBigNum bnFalse(0); +static const CBigNum bnTrue(1); + + +bool CastToBool(const valtype& vch) +{ + return (CBigNum(vch) != bnZero); +} + +void MakeSameSize(valtype& vch1, valtype& vch2) +{ + // Lengthen the shorter one + if (vch1.size() < vch2.size()) + vch1.resize(vch2.size(), 0); + if (vch2.size() < vch1.size()) + vch2.resize(vch1.size(), 0); +} + + + +// +// Script is a stack machine (like Forth) that evaluates a predicate +// returning a bool indicating valid or not. There are no loops. +// +#define stacktop(i) (stack.at(stack.size()+(i))) +#define altstacktop(i) (altstack.at(altstack.size()+(i))) + +bool EvalScript(const CScript& script, const CTransaction& txTo, unsigned int nIn, int nHashType, + vector >* pvStackRet) +{ + CAutoBN_CTX pctx; + CScript::const_iterator pc = script.begin(); + CScript::const_iterator pend = script.end(); + CScript::const_iterator pbegincodehash = script.begin(); + vector vfExec; + vector stack; + vector altstack; + if (pvStackRet) + pvStackRet->clear(); + + + while (pc < pend) + { + bool fExec = !count(vfExec.begin(), vfExec.end(), false); + + // + // Read instruction + // + opcodetype opcode; + valtype vchPushValue; + if (!script.GetOp(pc, opcode, vchPushValue)) + return false; + + if (fExec && opcode <= OP_PUSHDATA4) + stack.push_back(vchPushValue); + else if (fExec || (OP_IF <= opcode && opcode <= OP_ENDIF)) + switch (opcode) + { + // + // Push value + // + case OP_1NEGATE: + case OP_1: + case OP_2: + case OP_3: + case OP_4: + case OP_5: + case OP_6: + case OP_7: + case OP_8: + case OP_9: + case OP_10: + case OP_11: + case OP_12: + case OP_13: + case OP_14: + case OP_15: + case OP_16: + { + // ( -- value) + CBigNum bn((int)opcode - (int)(OP_1 - 1)); + stack.push_back(bn.getvch()); + } + break; + + + // + // Control + // + case OP_NOP: + break; + + case OP_VER: + { + CBigNum bn(VERSION); + stack.push_back(bn.getvch()); + } + break; + + case OP_IF: + case OP_NOTIF: + case OP_VERIF: + case OP_VERNOTIF: + { + // if [statements] [else [statements]] endif + bool fValue = false; + if (fExec) + { + if (stack.size() < 1) + return false; + valtype& vch = stacktop(-1); + if (opcode == OP_VERIF || opcode == OP_VERNOTIF) + fValue = (CBigNum(VERSION) >= CBigNum(vch)); + else + fValue = CastToBool(vch); + if (opcode == OP_NOTIF || opcode == OP_VERNOTIF) + fValue = !fValue; + stack.pop_back(); + } + vfExec.push_back(fValue); + } + break; + + case OP_ELSE: + { + if (vfExec.empty()) + return false; + vfExec.back() = !vfExec.back(); + } + break; + + case OP_ENDIF: + { + if (vfExec.empty()) + return false; + vfExec.pop_back(); + } + break; + + case OP_VERIFY: + { + // (true -- ) or + // (false -- false) and return + if (stack.size() < 1) + return false; + bool fValue = CastToBool(stacktop(-1)); + if (fValue) + stack.pop_back(); + else + pc = pend; + } + break; + + case OP_RETURN: + { + pc = pend; + } + break; + + + // + // Stack ops + // + case OP_TOALTSTACK: + { + if (stack.size() < 1) + return false; + altstack.push_back(stacktop(-1)); + stack.pop_back(); + } + break; + + case OP_FROMALTSTACK: + { + if (altstack.size() < 1) + return false; + stack.push_back(altstacktop(-1)); + altstack.pop_back(); + } + break; + + case OP_2DROP: + { + // (x1 x2 -- ) + stack.pop_back(); + stack.pop_back(); + } + break; + + case OP_2DUP: + { + // (x1 x2 -- x1 x2 x1 x2) + if (stack.size() < 2) + return false; + valtype vch1 = stacktop(-2); + valtype vch2 = stacktop(-1); + stack.push_back(vch1); + stack.push_back(vch2); + } + break; + + case OP_3DUP: + { + // (x1 x2 x3 -- x1 x2 x3 x1 x2 x3) + if (stack.size() < 3) + return false; + valtype vch1 = stacktop(-3); + valtype vch2 = stacktop(-2); + valtype vch3 = stacktop(-1); + stack.push_back(vch1); + stack.push_back(vch2); + stack.push_back(vch3); + } + break; + + case OP_2OVER: + { + // (x1 x2 x3 x4 -- x1 x2 x3 x4 x1 x2) + if (stack.size() < 4) + return false; + valtype vch1 = stacktop(-4); + valtype vch2 = stacktop(-3); + stack.push_back(vch1); + stack.push_back(vch2); + } + break; + + case OP_2ROT: + { + // (x1 x2 x3 x4 x5 x6 -- x3 x4 x5 x6 x1 x2) + if (stack.size() < 6) + return false; + valtype vch1 = stacktop(-6); + valtype vch2 = stacktop(-5); + stack.erase(stack.end()-6, stack.end()-4); + stack.push_back(vch1); + stack.push_back(vch2); + } + break; + + case OP_2SWAP: + { + // (x1 x2 x3 x4 -- x3 x4 x1 x2) + if (stack.size() < 4) + return false; + swap(stacktop(-4), stacktop(-2)); + swap(stacktop(-3), stacktop(-1)); + } + break; + + case OP_IFDUP: + { + // (x - 0 | x x) + if (stack.size() < 1) + return false; + valtype vch = stacktop(-1); + if (CastToBool(vch)) + stack.push_back(vch); + } + break; + + case OP_DEPTH: + { + // -- stacksize + CBigNum bn(stack.size()); + stack.push_back(bn.getvch()); + } + break; + + case OP_DROP: + { + // (x -- ) + if (stack.size() < 1) + return false; + stack.pop_back(); + } + break; + + case OP_DUP: + { + // (x -- x x) + if (stack.size() < 1) + return false; + valtype vch = stacktop(-1); + stack.push_back(vch); + } + break; + + case OP_NIP: + { + // (x1 x2 -- x2) + if (stack.size() < 2) + return false; + stack.erase(stack.end() - 2); + } + break; + + case OP_OVER: + { + // (x1 x2 -- x1 x2 x1) + if (stack.size() < 2) + return false; + valtype vch = stacktop(-2); + stack.push_back(vch); + } + break; + + case OP_PICK: + case OP_ROLL: + { + // (xn ... x2 x1 x0 n - xn ... x2 x1 x0 xn) + // (xn ... x2 x1 x0 n - ... x2 x1 x0 xn) + if (stack.size() < 2) + return false; + int n = CBigNum(stacktop(-1)).getint(); + stack.pop_back(); + if (n < 0 || n >= stack.size()) + return false; + valtype vch = stacktop(-n-1); + if (opcode == OP_ROLL) + stack.erase(stack.end()-n-1); + stack.push_back(vch); + } + break; + + case OP_ROT: + { + // (x1 x2 x3 -- x2 x3 x1) + // x2 x1 x3 after first swap + // x2 x3 x1 after second swap + if (stack.size() < 3) + return false; + swap(stacktop(-3), stacktop(-2)); + swap(stacktop(-2), stacktop(-1)); + } + break; + + case OP_SWAP: + { + // (x1 x2 -- x2 x1) + if (stack.size() < 2) + return false; + swap(stacktop(-2), stacktop(-1)); + } + break; + + case OP_TUCK: + { + // (x1 x2 -- x2 x1 x2) + if (stack.size() < 2) + return false; + valtype vch = stacktop(-1); + stack.insert(stack.end()-2, vch); + } + break; + + + // + // Splice ops + // + case OP_CAT: + { + // (x1 x2 -- out) + if (stack.size() < 2) + return false; + valtype& vch1 = stacktop(-2); + valtype& vch2 = stacktop(-1); + vch1.insert(vch1.end(), vch2.begin(), vch2.end()); + stack.pop_back(); + } + break; + + case OP_SUBSTR: + { + // (in begin size -- out) + if (stack.size() < 3) + return false; + valtype& vch = stacktop(-3); + int nBegin = CBigNum(stacktop(-2)).getint(); + int nEnd = nBegin + CBigNum(stacktop(-1)).getint(); + if (nBegin < 0 || nEnd < nBegin) + return false; + if (nBegin > vch.size()) + nBegin = vch.size(); + if (nEnd > vch.size()) + nEnd = vch.size(); + vch.erase(vch.begin() + nEnd, vch.end()); + vch.erase(vch.begin(), vch.begin() + nBegin); + stack.pop_back(); + stack.pop_back(); + } + break; + + case OP_LEFT: + case OP_RIGHT: + { + // (in size -- out) + if (stack.size() < 2) + return false; + valtype& vch = stacktop(-2); + int nSize = CBigNum(stacktop(-1)).getint(); + if (nSize < 0) + return false; + if (nSize > vch.size()) + nSize = vch.size(); + if (opcode == OP_LEFT) + vch.erase(vch.begin() + nSize, vch.end()); + else + vch.erase(vch.begin(), vch.end() - nSize); + stack.pop_back(); + } + break; + + case OP_SIZE: + { + // (in -- in size) + if (stack.size() < 1) + return false; + CBigNum bn(stacktop(-1).size()); + stack.push_back(bn.getvch()); + } + break; + + + // + // Bitwise logic + // + case OP_INVERT: + { + // (in - out) + if (stack.size() < 1) + return false; + valtype& vch = stacktop(-1); + for (int i = 0; i < vch.size(); i++) + vch[i] = ~vch[i]; + } + break; + + case OP_AND: + case OP_OR: + case OP_XOR: + { + // (x1 x2 - out) + if (stack.size() < 2) + return false; + valtype& vch1 = stacktop(-2); + valtype& vch2 = stacktop(-1); + MakeSameSize(vch1, vch2); + if (opcode == OP_AND) + { + for (int i = 0; i < vch1.size(); i++) + vch1[i] &= vch2[i]; + } + else if (opcode == OP_OR) + { + for (int i = 0; i < vch1.size(); i++) + vch1[i] |= vch2[i]; + } + else if (opcode == OP_XOR) + { + for (int i = 0; i < vch1.size(); i++) + vch1[i] ^= vch2[i]; + } + stack.pop_back(); + } + break; + + case OP_EQUAL: + case OP_EQUALVERIFY: + //case OP_NOTEQUAL: // use OP_NUMNOTEQUAL + { + // (x1 x2 - bool) + if (stack.size() < 2) + return false; + valtype& vch1 = stacktop(-2); + valtype& vch2 = stacktop(-1); + bool fEqual = (vch1 == vch2); + // OP_NOTEQUAL is disabled because it would be too easy to say + // something like n != 1 and have some wiseguy pass in 1 with extra + // zero bytes after it (numerically, 0x01 == 0x0001 == 0x000001) + //if (opcode == OP_NOTEQUAL) + // fEqual = !fEqual; + stack.pop_back(); + stack.pop_back(); + stack.push_back(fEqual ? vchTrue : vchFalse); + if (opcode == OP_EQUALVERIFY) + { + if (fEqual) + stack.pop_back(); + else + pc = pend; + } + } + break; + + + // + // Numeric + // + case OP_1ADD: + case OP_1SUB: + case OP_2MUL: + case OP_2DIV: + case OP_NEGATE: + case OP_ABS: + case OP_NOT: + case OP_0NOTEQUAL: + { + // (in -- out) + if (stack.size() < 1) + return false; + CBigNum bn(stacktop(-1)); + switch (opcode) + { + case OP_1ADD: bn += bnOne; break; + case OP_1SUB: bn -= bnOne; break; + case OP_2MUL: bn <<= 1; break; + case OP_2DIV: bn >>= 1; break; + case OP_NEGATE: bn = -bn; break; + case OP_ABS: if (bn < bnZero) bn = -bn; break; + case OP_NOT: bn = (bn == bnZero); break; + case OP_0NOTEQUAL: bn = (bn != bnZero); break; + } + stack.pop_back(); + stack.push_back(bn.getvch()); + } + break; + + case OP_ADD: + case OP_SUB: + case OP_MUL: + case OP_DIV: + case OP_MOD: + case OP_LSHIFT: + case OP_RSHIFT: + case OP_BOOLAND: + case OP_BOOLOR: + case OP_NUMEQUAL: + case OP_NUMEQUALVERIFY: + case OP_NUMNOTEQUAL: + case OP_LESSTHAN: + case OP_GREATERTHAN: + case OP_LESSTHANOREQUAL: + case OP_GREATERTHANOREQUAL: + case OP_MIN: + case OP_MAX: + { + // (x1 x2 -- out) + if (stack.size() < 2) + return false; + CBigNum bn1(stacktop(-2)); + CBigNum bn2(stacktop(-1)); + CBigNum bn; + switch (opcode) + { + case OP_ADD: + bn = bn1 + bn2; + break; + + case OP_SUB: + bn = bn1 - bn2; + break; + + case OP_MUL: + if (!BN_mul(&bn, &bn1, &bn2, pctx)) + return false; + break; + + case OP_DIV: + if (!BN_div(&bn, NULL, &bn1, &bn2, pctx)) + return false; + break; + + case OP_MOD: + if (!BN_mod(&bn, &bn1, &bn2, pctx)) + return false; + break; + + case OP_LSHIFT: + if (bn2 < bnZero) + return false; + bn = bn1 << bn2.getulong(); + break; + + case OP_RSHIFT: + if (bn2 < bnZero) + return false; + bn = bn1 >> bn2.getulong(); + break; + + case OP_BOOLAND: bn = (bn1 != bnZero && bn2 != bnZero); break; + case OP_BOOLOR: bn = (bn1 != bnZero || bn2 != bnZero); break; + case OP_NUMEQUAL: bn = (bn1 == bn2); break; + case OP_NUMEQUALVERIFY: bn = (bn1 == bn2); break; + case OP_NUMNOTEQUAL: bn = (bn1 != bn2); break; + case OP_LESSTHAN: bn = (bn1 < bn2); break; + case OP_GREATERTHAN: bn = (bn1 > bn2); break; + case OP_LESSTHANOREQUAL: bn = (bn1 <= bn2); break; + 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; + } + stack.pop_back(); + stack.pop_back(); + stack.push_back(bn.getvch()); + + if (opcode == OP_NUMEQUALVERIFY) + { + if (CastToBool(stacktop(-1))) + stack.pop_back(); + else + pc = pend; + } + } + break; + + case OP_WITHIN: + { + // (x min max -- out) + if (stack.size() < 3) + return false; + CBigNum bn1(stacktop(-3)); + CBigNum bn2(stacktop(-2)); + CBigNum bn3(stacktop(-1)); + bool fValue = (bn2 <= bn1 && bn1 < bn3); + stack.pop_back(); + stack.pop_back(); + stack.pop_back(); + stack.push_back(fValue ? vchTrue : vchFalse); + } + break; + + + // + // Crypto + // + case OP_RIPEMD160: + case OP_SHA1: + case OP_SHA256: + case OP_HASH160: + case OP_HASH256: + { + // (in -- hash) + if (stack.size() < 1) + return false; + valtype& vch = stacktop(-1); + valtype vchHash(opcode == OP_RIPEMD160 || opcode == OP_SHA1 || opcode == OP_HASH160 ? 20 : 32); + if (opcode == OP_RIPEMD160) + RIPEMD160(&vch[0], vch.size(), &vchHash[0]); + else if (opcode == OP_SHA1) + SHA1(&vch[0], vch.size(), &vchHash[0]); + else if (opcode == OP_SHA256) + SHA256(&vch[0], vch.size(), &vchHash[0]); + else if (opcode == OP_HASH160) + { + uint160 hash160 = Hash160(vch); + memcpy(&vchHash[0], &hash160, sizeof(hash160)); + } + else if (opcode == OP_HASH256) + { + uint256 hash = Hash(vch.begin(), vch.end()); + memcpy(&vchHash[0], &hash, sizeof(hash)); + } + stack.pop_back(); + stack.push_back(vchHash); + } + break; + + case OP_CODESEPARATOR: + { + // Hash starts after the code separator + pbegincodehash = pc; + } + break; + + case OP_CHECKSIG: + case OP_CHECKSIGVERIFY: + { + // (sig pubkey -- bool) + if (stack.size() < 2) + return false; + + valtype& vchSig = stacktop(-2); + valtype& vchPubKey = stacktop(-1); + + ////// debug print + //PrintHex(vchSig.begin(), vchSig.end(), "sig: %s\n"); + //PrintHex(vchPubKey.begin(), vchPubKey.end(), "pubkey: %s\n"); + + // Subset of script starting at the most recent codeseparator + CScript scriptCode(pbegincodehash, pend); + + // Drop the signature, since there's no way for a signature to sign itself + scriptCode.FindAndDelete(CScript(vchSig)); + + bool fSuccess = CheckSig(vchSig, vchPubKey, scriptCode, txTo, nIn, nHashType); + + stack.pop_back(); + stack.pop_back(); + stack.push_back(fSuccess ? vchTrue : vchFalse); + if (opcode == OP_CHECKSIGVERIFY) + { + if (fSuccess) + stack.pop_back(); + else + pc = pend; + } + } + break; + + case OP_CHECKMULTISIG: + case OP_CHECKMULTISIGVERIFY: + { + // ([sig ...] num_of_signatures [pubkey ...] num_of_pubkeys -- bool) + + int i = 1; + if (stack.size() < i) + return false; + + int nKeysCount = CBigNum(stacktop(-i)).getint(); + if (nKeysCount < 0) + return false; + int ikey = ++i; + i += nKeysCount; + if (stack.size() < i) + return false; + + int nSigsCount = CBigNum(stacktop(-i)).getint(); + if (nSigsCount < 0 || nSigsCount > nKeysCount) + return false; + int isig = ++i; + i += nSigsCount; + if (stack.size() < i) + return false; + + // Subset of script starting at the most recent codeseparator + CScript scriptCode(pbegincodehash, pend); + + // Drop the signatures, since there's no way for a signature to sign itself + for (int i = 0; i < nSigsCount; i++) + { + valtype& vchSig = stacktop(-isig-i); + scriptCode.FindAndDelete(CScript(vchSig)); + } + + bool fSuccess = true; + while (fSuccess && nSigsCount > 0) + { + valtype& vchSig = stacktop(-isig); + valtype& vchPubKey = stacktop(-ikey); + + // Check signature + if (CheckSig(vchSig, vchPubKey, scriptCode, txTo, nIn, nHashType)) + { + isig++; + nSigsCount--; + } + ikey++; + nKeysCount--; + + // If there are more signatures left than keys left, + // then too many signatures have failed + if (nSigsCount > nKeysCount) + fSuccess = false; + } + + while (i-- > 0) + stack.pop_back(); + stack.push_back(fSuccess ? vchTrue : vchFalse); + + if (opcode == OP_CHECKMULTISIGVERIFY) + { + if (fSuccess) + stack.pop_back(); + else + pc = pend; + } + } + break; + + default: + return false; + } + } + + + if (pvStackRet) + *pvStackRet = stack; + return (stack.empty() ? false : CastToBool(stack.back())); +} + +#undef top + + + + + + + + + +uint256 SignatureHash(CScript scriptCode, const CTransaction& txTo, unsigned int nIn, int nHashType) +{ + if (nIn >= txTo.vin.size()) + { + printf("ERROR: SignatureHash() : nIn=%d out of range\n", nIn); + return 1; + } + CTransaction txTmp(txTo); + + // In case concatenating two scripts ends up with two codeseparators, + // or an extra one at the end, this prevents all those possible incompatibilities. + scriptCode.FindAndDelete(CScript(OP_CODESEPARATOR)); + + // Blank out other inputs' signatures + for (int i = 0; i < txTmp.vin.size(); i++) + txTmp.vin[i].scriptSig = CScript(); + txTmp.vin[nIn].scriptSig = scriptCode; + + // Blank out some of the outputs + if ((nHashType & 0x1f) == SIGHASH_NONE) + { + // Wildcard payee + txTmp.vout.clear(); + + // Let the others update at will + for (int i = 0; i < txTmp.vin.size(); i++) + if (i != nIn) + txTmp.vin[i].nSequence = 0; + } + else if ((nHashType & 0x1f) == SIGHASH_SINGLE) + { + // Only lockin the txout payee at same index as txin + unsigned int nOut = nIn; + if (nOut >= txTmp.vout.size()) + { + printf("ERROR: SignatureHash() : nOut=%d out of range\n", nOut); + return 1; + } + txTmp.vout.resize(nOut+1); + for (int i = 0; i < nOut; i++) + txTmp.vout[i].SetNull(); + + // Let the others update at will + for (int i = 0; i < txTmp.vin.size(); i++) + if (i != nIn) + txTmp.vin[i].nSequence = 0; + } + + // Blank out other inputs completely, not recommended for open transactions + if (nHashType & SIGHASH_ANYONECANPAY) + { + txTmp.vin[0] = txTmp.vin[nIn]; + txTmp.vin.resize(1); + } + + // Serialize and hash + CDataStream ss(SER_GETHASH); + ss.reserve(10000); + ss << txTmp << nHashType; + return Hash(ss.begin(), ss.end()); +} + + +bool CheckSig(vector vchSig, vector vchPubKey, CScript scriptCode, + const CTransaction& txTo, unsigned int nIn, int nHashType) +{ + CKey key; + if (!key.SetPubKey(vchPubKey)) + return false; + + // Hash type is one byte tacked on to the end of the signature + if (vchSig.empty()) + return false; + if (nHashType == 0) + nHashType = vchSig.back(); + else if (nHashType != vchSig.back()) + return false; + vchSig.pop_back(); + + if (key.Verify(SignatureHash(scriptCode, txTo, nIn, nHashType), vchSig)) + return true; + + return false; +} + + + + + + + + + + + +bool Solver(const CScript& scriptPubKey, vector >& vSolutionRet) +{ + // Templates + static vector vTemplates; + if (vTemplates.empty()) + { + // Standard tx, sender provides pubkey, receiver adds signature + vTemplates.push_back(CScript() << OP_PUBKEY << OP_CHECKSIG); + + // Short account number tx, sender provides hash of pubkey, receiver provides signature and pubkey + vTemplates.push_back(CScript() << OP_DUP << OP_HASH160 << OP_PUBKEYHASH << OP_EQUALVERIFY << OP_CHECKSIG); + } + + // Scan templates + const CScript& script1 = scriptPubKey; + foreach(const CScript& script2, vTemplates) + { + vSolutionRet.clear(); + opcodetype opcode1, opcode2; + vector vch1, vch2; + + // Compare + CScript::const_iterator pc1 = script1.begin(); + CScript::const_iterator pc2 = script2.begin(); + loop + { + bool f1 = script1.GetOp(pc1, opcode1, vch1); + bool f2 = script2.GetOp(pc2, opcode2, vch2); + if (!f1 && !f2) + { + // Success + reverse(vSolutionRet.begin(), vSolutionRet.end()); + return true; + } + else if (f1 != f2) + { + break; + } + else if (opcode2 == OP_PUBKEY) + { + if (vch1.size() <= sizeof(uint256)) + break; + vSolutionRet.push_back(make_pair(opcode2, vch1)); + } + else if (opcode2 == OP_PUBKEYHASH) + { + if (vch1.size() != sizeof(uint160)) + break; + vSolutionRet.push_back(make_pair(opcode2, vch1)); + } + else if (opcode1 != opcode2) + { + break; + } + } + } + + vSolutionRet.clear(); + return false; +} + + +bool Solver(const CScript& scriptPubKey, uint256 hash, int nHashType, CScript& scriptSigRet) +{ + scriptSigRet.clear(); + + vector > vSolution; + if (!Solver(scriptPubKey, vSolution)) + return false; + + // Compile solution + CRITICAL_BLOCK(cs_mapKeys) + { + foreach(PAIRTYPE(opcodetype, valtype)& item, vSolution) + { + if (item.first == OP_PUBKEY) + { + // Sign + const valtype& vchPubKey = item.second; + if (!mapKeys.count(vchPubKey)) + return false; + if (hash != 0) + { + vector vchSig; + if (!CKey::Sign(mapKeys[vchPubKey], hash, vchSig)) + return false; + vchSig.push_back((unsigned char)nHashType); + scriptSigRet << vchSig; + } + } + else if (item.first == OP_PUBKEYHASH) + { + // Sign and give pubkey + map::iterator mi = mapPubKeys.find(uint160(item.second)); + if (mi == mapPubKeys.end()) + return false; + const vector& vchPubKey = (*mi).second; + if (!mapKeys.count(vchPubKey)) + return false; + if (hash != 0) + { + vector vchSig; + if (!CKey::Sign(mapKeys[vchPubKey], hash, vchSig)) + return false; + vchSig.push_back((unsigned char)nHashType); + scriptSigRet << vchSig << vchPubKey; + } + } + } + } + + return true; +} + + +bool IsMine(const CScript& scriptPubKey) +{ + CScript scriptSig; + return Solver(scriptPubKey, 0, 0, scriptSig); +} + + +bool ExtractPubKey(const CScript& scriptPubKey, bool fMineOnly, vector& vchPubKeyRet) +{ + vchPubKeyRet.clear(); + + vector > vSolution; + if (!Solver(scriptPubKey, vSolution)) + return false; + + CRITICAL_BLOCK(cs_mapKeys) + { + foreach(PAIRTYPE(opcodetype, valtype)& item, vSolution) + { + valtype vchPubKey; + if (item.first == OP_PUBKEY) + { + vchPubKey = item.second; + } + else if (item.first == OP_PUBKEYHASH) + { + map::iterator mi = mapPubKeys.find(uint160(item.second)); + if (mi == mapPubKeys.end()) + continue; + vchPubKey = (*mi).second; + } + if (!fMineOnly || mapKeys.count(vchPubKey)) + { + vchPubKeyRet = vchPubKey; + return true; + } + } + } + return false; +} + + +bool ExtractHash160(const CScript& scriptPubKey, uint160& hash160Ret) +{ + hash160Ret = 0; + + vector > vSolution; + if (!Solver(scriptPubKey, vSolution)) + return false; + + foreach(PAIRTYPE(opcodetype, valtype)& item, vSolution) + { + if (item.first == OP_PUBKEYHASH) + { + hash160Ret = uint160(item.second); + return true; + } + } + return false; +} + + +bool SignSignature(const CTransaction& txFrom, CTransaction& txTo, unsigned int nIn, int nHashType, CScript scriptPrereq) +{ + assert(nIn < txTo.vin.size()); + CTxIn& txin = txTo.vin[nIn]; + assert(txin.prevout.n < txFrom.vout.size()); + const CTxOut& txout = txFrom.vout[txin.prevout.n]; + + // Leave out the signature from the hash, since a signature can't sign itself. + // The checksig op will also drop the signatures from its hash. + uint256 hash = SignatureHash(scriptPrereq + txout.scriptPubKey, txTo, nIn, nHashType); + + if (!Solver(txout.scriptPubKey, hash, nHashType, txin.scriptSig)) + return false; + + txin.scriptSig = scriptPrereq + txin.scriptSig; + + // Test solution + if (scriptPrereq.empty()) + if (!EvalScript(txin.scriptSig + CScript(OP_CODESEPARATOR) + txout.scriptPubKey, txTo, nIn)) + return false; + + return true; +} + + +bool VerifySignature(const CTransaction& txFrom, const CTransaction& txTo, unsigned int nIn, int nHashType) +{ + assert(nIn < txTo.vin.size()); + const CTxIn& txin = txTo.vin[nIn]; + if (txin.prevout.n >= txFrom.vout.size()) + return false; + const CTxOut& txout = txFrom.vout[txin.prevout.n]; + + if (txin.prevout.hash != txFrom.GetHash()) + return false; + + return EvalScript(txin.scriptSig + CScript(OP_CODESEPARATOR) + txout.scriptPubKey, txTo, nIn, nHashType); +} diff --git a/script.h b/script.h new file mode 100644 index 0000000000..0d977734b9 --- /dev/null +++ b/script.h @@ -0,0 +1,597 @@ +// Copyright (c) 2009 Satoshi Nakamoto +// Distributed under the MIT/X11 software license, see the accompanying +// file license.txt or http://www.opensource.org/licenses/mit-license.php. + +class CTransaction; + +enum +{ + SIGHASH_ALL = 1, + SIGHASH_NONE = 2, + SIGHASH_SINGLE = 3, + SIGHASH_ANYONECANPAY = 0x80, +}; + + + +enum opcodetype +{ + // push value + OP_0=0, + OP_FALSE=OP_0, + OP_PUSHDATA1=76, + OP_PUSHDATA2, + OP_PUSHDATA4, + OP_1NEGATE, + OP_RESERVED, + OP_1, + OP_TRUE=OP_1, + OP_2, + OP_3, + OP_4, + OP_5, + OP_6, + OP_7, + OP_8, + OP_9, + OP_10, + OP_11, + OP_12, + OP_13, + OP_14, + OP_15, + OP_16, + + // control + OP_NOP, + OP_VER, + OP_IF, + OP_NOTIF, + OP_VERIF, + OP_VERNOTIF, + OP_ELSE, + OP_ENDIF, + OP_VERIFY, + OP_RETURN, + + // stack ops + OP_TOALTSTACK, + OP_FROMALTSTACK, + OP_2DROP, + OP_2DUP, + OP_3DUP, + OP_2OVER, + OP_2ROT, + OP_2SWAP, + OP_IFDUP, + OP_DEPTH, + OP_DROP, + OP_DUP, + OP_NIP, + OP_OVER, + OP_PICK, + OP_ROLL, + OP_ROT, + OP_SWAP, + OP_TUCK, + + // splice ops + OP_CAT, + OP_SUBSTR, + OP_LEFT, + OP_RIGHT, + OP_SIZE, + + // bit logic + OP_INVERT, + OP_AND, + OP_OR, + OP_XOR, + OP_EQUAL, + OP_EQUALVERIFY, + OP_RESERVED1, + OP_RESERVED2, + + // numeric + OP_1ADD, + OP_1SUB, + OP_2MUL, + OP_2DIV, + OP_NEGATE, + OP_ABS, + OP_NOT, + OP_0NOTEQUAL, + + OP_ADD, + OP_SUB, + OP_MUL, + OP_DIV, + OP_MOD, + OP_LSHIFT, + OP_RSHIFT, + + OP_BOOLAND, + OP_BOOLOR, + OP_NUMEQUAL, + OP_NUMEQUALVERIFY, + OP_NUMNOTEQUAL, + OP_LESSTHAN, + OP_GREATERTHAN, + OP_LESSTHANOREQUAL, + OP_GREATERTHANOREQUAL, + OP_MIN, + OP_MAX, + + OP_WITHIN, + + // crypto + OP_RIPEMD160, + OP_SHA1, + OP_SHA256, + OP_HASH160, + OP_HASH256, + OP_CODESEPARATOR, + OP_CHECKSIG, + OP_CHECKSIGVERIFY, + OP_CHECKMULTISIG, + OP_CHECKMULTISIGVERIFY, + + + // multi-byte opcodes + OP_SINGLEBYTE_END = 0xF0, + OP_DOUBLEBYTE_BEGIN = 0xF000, + + // template matching params + OP_PUBKEY, + OP_PUBKEYHASH, + + + + OP_INVALIDOPCODE = 0xFFFF, +}; + + + + + + + + +inline const char* GetOpName(opcodetype opcode) +{ + switch (opcode) + { + // push value + case OP_0 : return "0"; + case OP_PUSHDATA1 : return "OP_PUSHDATA1"; + case OP_PUSHDATA2 : return "OP_PUSHDATA2"; + case OP_PUSHDATA4 : return "OP_PUSHDATA4"; + case OP_1NEGATE : return "-1"; + case OP_RESERVED : return "OP_RESERVED"; + case OP_1 : return "1"; + case OP_2 : return "2"; + case OP_3 : return "3"; + case OP_4 : return "4"; + case OP_5 : return "5"; + case OP_6 : return "6"; + case OP_7 : return "7"; + case OP_8 : return "8"; + case OP_9 : return "9"; + case OP_10 : return "10"; + case OP_11 : return "11"; + case OP_12 : return "12"; + case OP_13 : return "13"; + case OP_14 : return "14"; + case OP_15 : return "15"; + case OP_16 : return "16"; + + // control + case OP_NOP : return "OP_NOP"; + case OP_VER : return "OP_VER"; + case OP_IF : return "OP_IF"; + case OP_NOTIF : return "OP_NOTIF"; + case OP_VERIF : return "OP_VERIF"; + case OP_VERNOTIF : return "OP_VERNOTIF"; + case OP_ELSE : return "OP_ELSE"; + case OP_ENDIF : return "OP_ENDIF"; + case OP_VERIFY : return "OP_VERIFY"; + case OP_RETURN : return "OP_RETURN"; + + // stack ops + case OP_TOALTSTACK : return "OP_TOALTSTACK"; + case OP_FROMALTSTACK : return "OP_FROMALTSTACK"; + case OP_2DROP : return "OP_2DROP"; + case OP_2DUP : return "OP_2DUP"; + case OP_3DUP : return "OP_3DUP"; + case OP_2OVER : return "OP_2OVER"; + case OP_2ROT : return "OP_2ROT"; + case OP_2SWAP : return "OP_2SWAP"; + case OP_IFDUP : return "OP_IFDUP"; + case OP_DEPTH : return "OP_DEPTH"; + case OP_DROP : return "OP_DROP"; + case OP_DUP : return "OP_DUP"; + case OP_NIP : return "OP_NIP"; + case OP_OVER : return "OP_OVER"; + case OP_PICK : return "OP_PICK"; + case OP_ROLL : return "OP_ROLL"; + case OP_ROT : return "OP_ROT"; + case OP_SWAP : return "OP_SWAP"; + case OP_TUCK : return "OP_TUCK"; + + // splice ops + case OP_CAT : return "OP_CAT"; + case OP_SUBSTR : return "OP_SUBSTR"; + case OP_LEFT : return "OP_LEFT"; + case OP_RIGHT : return "OP_RIGHT"; + case OP_SIZE : return "OP_SIZE"; + + // bit logic + case OP_INVERT : return "OP_INVERT"; + case OP_AND : return "OP_AND"; + case OP_OR : return "OP_OR"; + case OP_XOR : return "OP_XOR"; + case OP_EQUAL : return "OP_EQUAL"; + case OP_EQUALVERIFY : return "OP_EQUALVERIFY"; + case OP_RESERVED1 : return "OP_RESERVED1"; + case OP_RESERVED2 : return "OP_RESERVED2"; + + // numeric + case OP_1ADD : return "OP_1ADD"; + case OP_1SUB : return "OP_1SUB"; + case OP_2MUL : return "OP_2MUL"; + case OP_2DIV : return "OP_2DIV"; + case OP_NEGATE : return "OP_NEGATE"; + case OP_ABS : return "OP_ABS"; + case OP_NOT : return "OP_NOT"; + case OP_0NOTEQUAL : return "OP_0NOTEQUAL"; + case OP_ADD : return "OP_ADD"; + case OP_SUB : return "OP_SUB"; + case OP_MUL : return "OP_MUL"; + case OP_DIV : return "OP_DIV"; + case OP_MOD : return "OP_MOD"; + case OP_LSHIFT : return "OP_LSHIFT"; + case OP_RSHIFT : return "OP_RSHIFT"; + case OP_BOOLAND : return "OP_BOOLAND"; + case OP_BOOLOR : return "OP_BOOLOR"; + case OP_NUMEQUAL : return "OP_NUMEQUAL"; + case OP_NUMEQUALVERIFY : return "OP_NUMEQUALVERIFY"; + case OP_NUMNOTEQUAL : return "OP_NUMNOTEQUAL"; + case OP_LESSTHAN : return "OP_LESSTHAN"; + case OP_GREATERTHAN : return "OP_GREATERTHAN"; + case OP_LESSTHANOREQUAL : return "OP_LESSTHANOREQUAL"; + case OP_GREATERTHANOREQUAL : return "OP_GREATERTHANOREQUAL"; + case OP_MIN : return "OP_MIN"; + case OP_MAX : return "OP_MAX"; + case OP_WITHIN : return "OP_WITHIN"; + + // crypto + case OP_RIPEMD160 : return "OP_RIPEMD160"; + case OP_SHA1 : return "OP_SHA1"; + case OP_SHA256 : return "OP_SHA256"; + case OP_HASH160 : return "OP_HASH160"; + case OP_HASH256 : return "OP_HASH256"; + case OP_CODESEPARATOR : return "OP_CODESEPARATOR"; + case OP_CHECKSIG : return "OP_CHECKSIG"; + case OP_CHECKSIGVERIFY : return "OP_CHECKSIGVERIFY"; + case OP_CHECKMULTISIG : return "OP_CHECKMULTISIG"; + case OP_CHECKMULTISIGVERIFY : return "OP_CHECKMULTISIGVERIFY"; + + + + // multi-byte opcodes + case OP_SINGLEBYTE_END : return "OP_SINGLEBYTE_END"; + case OP_DOUBLEBYTE_BEGIN : return "OP_DOUBLEBYTE_BEGIN"; + case OP_PUBKEY : return "OP_PUBKEY"; + case OP_PUBKEYHASH : return "OP_PUBKEYHASH"; + + + + case OP_INVALIDOPCODE : return "OP_INVALIDOPCODE"; + default: + return "UNKNOWN_OPCODE"; + } +}; + + + + +inline string ValueString(const vector& vch) +{ + if (vch.size() <= 4) + return strprintf("%d", CBigNum(vch).getint()); + else + return HexNumStr(vch.begin(), vch.end()); + //return string("(") + HexStr(vch.begin(), vch.end()) + string(")"); +} + +inline string StackString(const vector >& vStack) +{ + string str; + foreach(const vector& vch, vStack) + { + if (!str.empty()) + str += " "; + str += ValueString(vch); + } + return str; +} + + + + + + + + + +class CScript : public vector +{ +protected: + CScript& push_int64(int64 n) + { + if (n == -1 || (n >= 1 && n <= 16)) + { + push_back(n + (OP_1 - 1)); + } + else + { + CBigNum bn(n); + *this << bn.getvch(); + } + return (*this); + } + + CScript& push_uint64(uint64 n) + { + if (n == -1 || (n >= 1 && n <= 16)) + { + push_back(n + (OP_1 - 1)); + } + else + { + CBigNum bn(n); + *this << bn.getvch(); + } + return (*this); + } + +public: + CScript() { } + CScript(const CScript& b) : vector(b.begin(), b.end()) { } + CScript(const_iterator pbegin, const_iterator pend) : vector(pbegin, pend) { } +#ifndef _MSC_VER + CScript(const unsigned char* pbegin, const unsigned char* pend) : vector(pbegin, pend) { } +#endif + + CScript& operator+=(const CScript& b) + { + insert(end(), b.begin(), b.end()); + return *this; + } + + friend CScript operator+(const CScript& a, const CScript& b) + { + CScript ret = a; + ret += b; + return (ret); + } + + + explicit CScript(char b) { operator<<(b); } + explicit CScript(short b) { operator<<(b); } + explicit CScript(int b) { operator<<(b); } + explicit CScript(long b) { operator<<(b); } + explicit CScript(int64 b) { operator<<(b); } + explicit CScript(unsigned char b) { operator<<(b); } + explicit CScript(unsigned int b) { operator<<(b); } + explicit CScript(unsigned short b) { operator<<(b); } + explicit CScript(unsigned long b) { operator<<(b); } + explicit CScript(uint64 b) { operator<<(b); } + + explicit CScript(opcodetype b) { operator<<(b); } + explicit CScript(const uint256& b) { operator<<(b); } + explicit CScript(const CBigNum& b) { operator<<(b); } + explicit CScript(const vector& b) { operator<<(b); } + + + CScript& operator<<(char b) { return (push_int64(b)); } + CScript& operator<<(short b) { return (push_int64(b)); } + CScript& operator<<(int b) { return (push_int64(b)); } + CScript& operator<<(long b) { return (push_int64(b)); } + CScript& operator<<(int64 b) { return (push_int64(b)); } + CScript& operator<<(unsigned char b) { return (push_uint64(b)); } + CScript& operator<<(unsigned int b) { return (push_uint64(b)); } + CScript& operator<<(unsigned short b) { return (push_uint64(b)); } + CScript& operator<<(unsigned long b) { return (push_uint64(b)); } + CScript& operator<<(uint64 b) { return (push_uint64(b)); } + + CScript& operator<<(opcodetype opcode) + { + if (opcode <= OP_SINGLEBYTE_END) + { + insert(end(), (unsigned char)opcode); + } + else + { + assert(opcode >= OP_DOUBLEBYTE_BEGIN); + insert(end(), (unsigned char)(opcode >> 8)); + insert(end(), (unsigned char)(opcode & 0xFF)); + } + return (*this); + } + + CScript& operator<<(const uint160& b) + { + insert(end(), sizeof(b)); + insert(end(), (unsigned char*)&b, (unsigned char*)&b + sizeof(b)); + return (*this); + } + + CScript& operator<<(const uint256& b) + { + insert(end(), sizeof(b)); + insert(end(), (unsigned char*)&b, (unsigned char*)&b + sizeof(b)); + return (*this); + } + + CScript& operator<<(const CBigNum& b) + { + *this << b.getvch(); + return (*this); + } + + CScript& operator<<(const vector& b) + { + if (b.size() < OP_PUSHDATA1) + { + insert(end(), (unsigned char)b.size()); + } + else if (b.size() <= 0xff) + { + insert(end(), OP_PUSHDATA1); + insert(end(), (unsigned char)b.size()); + } + else + { + insert(end(), OP_PUSHDATA2); + unsigned short nSize = b.size(); + insert(end(), (unsigned char*)&nSize, (unsigned char*)&nSize + sizeof(nSize)); + } + insert(end(), b.begin(), b.end()); + return (*this); + } + + CScript& operator<<(const CScript& b) + { + // 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)); + return (*this); + } + + + bool GetOp(iterator& pc, opcodetype& opcodeRet, vector& vchRet) + { + // This is why people hate C++ + const_iterator pc2 = pc; + bool fRet = GetOp(pc2, opcodeRet, vchRet); + pc = begin() + (pc2 - begin()); + return fRet; + } + + bool GetOp(const_iterator& pc, opcodetype& opcodeRet, vector& vchRet) const + { + opcodeRet = OP_INVALIDOPCODE; + vchRet.clear(); + if (pc >= end()) + return false; + + // Read instruction + unsigned int opcode = *pc++; + if (opcode >= OP_SINGLEBYTE_END) + { + if (pc + 1 > end()) + return false; + opcode <<= 8; + opcode |= *pc++; + } + + // Immediate operand + if (opcode <= OP_PUSHDATA4) + { + unsigned int nSize = opcode; + if (opcode == OP_PUSHDATA1) + { + if (pc + 1 > end()) + return false; + nSize = *pc++; + } + else if (opcode == OP_PUSHDATA2) + { + if (pc + 2 > end()) + return false; + nSize = 0; + memcpy(&nSize, &pc[0], 2); + pc += 2; + } + else if (opcode == OP_PUSHDATA4) + { + if (pc + 4 > end()) + return false; + memcpy(&nSize, &pc[0], 4); + pc += 4; + } + if (pc + nSize > end()) + return false; + vchRet.assign(pc, pc + nSize); + pc += nSize; + } + + opcodeRet = (opcodetype)opcode; + return true; + } + + + void FindAndDelete(const CScript& b) + { + iterator pc = begin(); + opcodetype opcode; + vector vchPushValue; + int count = 0; + do + { + while (end() - pc >= b.size() && memcmp(&pc[0], &b[0], b.size()) == 0) + { + erase(pc, pc + b.size()); + count++; + } + } + while (GetOp(pc, opcode, vchPushValue)); + //printf("FindAndDeleted deleted %d items\n", count); /// debug + } + + + void PrintHex() const + { + printf("CScript(%s)\n", HexStr(begin(), end()).c_str()); + } + + string ToString() const + { + string str; + opcodetype opcode; + vector vch; + const_iterator it = begin(); + while (GetOp(it, opcode, vch)) + { + if (!str.empty()) + str += " "; + if (opcode <= OP_PUSHDATA4) + str += ValueString(vch); + else + str += GetOpName(opcode); + } + return str; + } + + void print() const + { + printf("%s\n", ToString().c_str()); + } +}; + + + + + + + + +bool EvalScript(const CScript& script, const CTransaction& txTo, unsigned int nIn, int nHashType=0, + vector >* pvStackRet=NULL); +uint256 SignatureHash(CScript scriptCode, const CTransaction& txTo, unsigned int nIn, int nHashType); +bool IsMine(const CScript& scriptPubKey); +bool ExtractPubKey(const CScript& scriptPubKey, bool fMineOnly, vector& vchPubKeyRet); +bool ExtractHash160(const CScript& scriptPubKey, uint160& hash160Ret); +bool SignSignature(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/serialize.h b/serialize.h new file mode 100644 index 0000000000..b7ab86d22a --- /dev/null +++ b/serialize.h @@ -0,0 +1,1158 @@ +// Copyright (c) 2009 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 +#include +#include +#if defined(_MSC_VER) || defined(__BORLANDC__) +typedef __int64 int64; +typedef unsigned __int64 uint64; +#else +typedef long long int64; +typedef unsigned long long uint64; +#endif +#if defined(_MSC_VER) && _MSC_VER < 1300 +#define for if (false) ; else for +#endif +class CScript; +class CDataStream; +class CAutoFile; + +static const int VERSION = 105; + + + + + +///////////////////////////////////////////////////////////////// +// +// Templates for serializing to anything that looks like a stream, +// i.e. anything that supports .read(char*, int) and .write(char*, int) +// + +enum +{ + // primary actions + SER_NETWORK = (1 << 0), + SER_DISK = (1 << 1), + SER_GETHASH = (1 << 2), + + // modifiers + SER_SKIPSIG = (1 << 16), + SER_BLOCKHEADERONLY = (1 << 17), +}; + +#define IMPLEMENT_SERIALIZE(statements) \ + unsigned int GetSerializeSize(int nType=0, int nVersion=VERSION) const \ + { \ + CSerActionGetSerializeSize ser_action; \ + const bool fGetSize = true; \ + const bool fWrite = false; \ + const bool fRead = false; \ + unsigned int nSerSize = 0; \ + ser_streamplaceholder s; \ + s.nType = nType; \ + s.nVersion = nVersion; \ + {statements} \ + return nSerSize; \ + } \ + template \ + void Serialize(Stream& s, int nType=0, int nVersion=VERSION) const \ + { \ + CSerActionSerialize ser_action; \ + const bool fGetSize = false; \ + const bool fWrite = true; \ + const bool fRead = false; \ + unsigned int nSerSize = 0; \ + {statements} \ + } \ + template \ + void Unserialize(Stream& s, int nType=0, int nVersion=VERSION) \ + { \ + CSerActionUnserialize ser_action; \ + const bool fGetSize = false; \ + const bool fWrite = false; \ + const bool fRead = true; \ + unsigned int nSerSize = 0; \ + {statements} \ + } + +#define READWRITE(obj) (nSerSize += ::SerReadWrite(s, (obj), nType, nVersion, ser_action)) + + + + + + +// +// Basic types +// +#define WRITEDATA(s, obj) s.write((char*)&(obj), sizeof(obj)) +#define READDATA(s, obj) s.read((char*)&(obj), sizeof(obj)) + +inline unsigned int GetSerializeSize(char a, int, int=0) { return sizeof(a); } +inline unsigned int GetSerializeSize(signed char a, int, int=0) { return sizeof(a); } +inline unsigned int GetSerializeSize(unsigned char a, int, int=0) { return sizeof(a); } +inline unsigned int GetSerializeSize(signed short a, int, int=0) { return sizeof(a); } +inline unsigned int GetSerializeSize(unsigned short a, int, int=0) { return sizeof(a); } +inline unsigned int GetSerializeSize(signed int a, int, int=0) { return sizeof(a); } +inline unsigned int GetSerializeSize(unsigned int a, int, int=0) { return sizeof(a); } +inline unsigned int GetSerializeSize(signed long a, int, int=0) { return sizeof(a); } +inline unsigned int GetSerializeSize(unsigned long a, int, int=0) { return sizeof(a); } +inline unsigned int GetSerializeSize(int64 a, int, int=0) { return sizeof(a); } +inline unsigned int GetSerializeSize(uint64 a, int, int=0) { return sizeof(a); } +inline unsigned int GetSerializeSize(float a, int, int=0) { return sizeof(a); } +inline unsigned int GetSerializeSize(double a, int, int=0) { return sizeof(a); } + +template inline void Serialize(Stream& s, char a, int, int=0) { WRITEDATA(s, a); } +template inline void Serialize(Stream& s, signed char a, int, int=0) { WRITEDATA(s, a); } +template inline void Serialize(Stream& s, unsigned char a, int, int=0) { WRITEDATA(s, a); } +template inline void Serialize(Stream& s, signed short a, int, int=0) { WRITEDATA(s, a); } +template inline void Serialize(Stream& s, unsigned short a, int, int=0) { WRITEDATA(s, a); } +template inline void Serialize(Stream& s, signed int a, int, int=0) { WRITEDATA(s, a); } +template inline void Serialize(Stream& s, unsigned int a, int, int=0) { WRITEDATA(s, a); } +template inline void Serialize(Stream& s, signed long a, int, int=0) { WRITEDATA(s, a); } +template inline void Serialize(Stream& s, unsigned long a, int, int=0) { WRITEDATA(s, a); } +template inline void Serialize(Stream& s, int64 a, int, int=0) { WRITEDATA(s, a); } +template inline void Serialize(Stream& s, uint64 a, int, int=0) { WRITEDATA(s, a); } +template inline void Serialize(Stream& s, float a, int, int=0) { WRITEDATA(s, a); } +template inline void Serialize(Stream& s, double a, int, int=0) { WRITEDATA(s, a); } + +template inline void Unserialize(Stream& s, char& a, int, int=0) { READDATA(s, a); } +template inline void Unserialize(Stream& s, signed char& a, int, int=0) { READDATA(s, a); } +template inline void Unserialize(Stream& s, unsigned char& a, int, int=0) { READDATA(s, a); } +template inline void Unserialize(Stream& s, signed short& a, int, int=0) { READDATA(s, a); } +template inline void Unserialize(Stream& s, unsigned short& a, int, int=0) { READDATA(s, a); } +template inline void Unserialize(Stream& s, signed int& a, int, int=0) { READDATA(s, a); } +template inline void Unserialize(Stream& s, unsigned int& a, int, int=0) { READDATA(s, a); } +template inline void Unserialize(Stream& s, signed long& a, int, int=0) { READDATA(s, a); } +template inline void Unserialize(Stream& s, unsigned long& a, int, int=0) { READDATA(s, a); } +template inline void Unserialize(Stream& s, int64& a, int, int=0) { READDATA(s, a); } +template inline void Unserialize(Stream& s, uint64& a, int, int=0) { READDATA(s, a); } +template inline void Unserialize(Stream& s, float& a, int, int=0) { READDATA(s, a); } +template inline void Unserialize(Stream& s, double& a, int, int=0) { READDATA(s, a); } + +inline unsigned int GetSerializeSize(bool a, int, int=0) { return sizeof(char); } +template inline void Serialize(Stream& s, bool a, int, int=0) { char f=a; WRITEDATA(s, f); } +template inline void Unserialize(Stream& s, bool& a, int, int=0) { char f; READDATA(s, f); a=f; } + + + + + + +// +// Compact size +// size < 253 -- 1 byte +// size <= USHRT_MAX -- 3 bytes (253 + 2 bytes) +// size <= UINT_MAX -- 5 bytes (254 + 4 bytes) +// size > UINT_MAX -- 9 bytes (255 + 8 bytes) +// +inline unsigned int GetSizeOfCompactSize(uint64 nSize) +{ + if (nSize < UCHAR_MAX-2) return sizeof(unsigned char); + else if (nSize <= USHRT_MAX) return sizeof(unsigned char) + sizeof(unsigned short); + else if (nSize <= UINT_MAX) return sizeof(unsigned char) + sizeof(unsigned int); + else return sizeof(unsigned char) + sizeof(uint64); +} + +template +void WriteCompactSize(Stream& os, uint64 nSize) +{ + if (nSize < UCHAR_MAX-2) + { + unsigned char chSize = nSize; + WRITEDATA(os, chSize); + } + else if (nSize <= USHRT_MAX) + { + unsigned char chSize = UCHAR_MAX-2; + unsigned short xSize = nSize; + WRITEDATA(os, chSize); + WRITEDATA(os, xSize); + } + else if (nSize <= UINT_MAX) + { + unsigned char chSize = UCHAR_MAX-1; + unsigned int xSize = nSize; + WRITEDATA(os, chSize); + WRITEDATA(os, xSize); + } + else + { + unsigned char chSize = UCHAR_MAX; + WRITEDATA(os, chSize); + WRITEDATA(os, nSize); + } + return; +} + +template +uint64 ReadCompactSize(Stream& is) +{ + unsigned char chSize; + READDATA(is, chSize); + if (chSize < UCHAR_MAX-2) + { + return chSize; + } + else if (chSize == UCHAR_MAX-2) + { + unsigned short nSize; + READDATA(is, nSize); + return nSize; + } + else if (chSize == UCHAR_MAX-1) + { + unsigned int nSize; + READDATA(is, nSize); + return nSize; + } + else + { + uint64 nSize; + READDATA(is, nSize); + return nSize; + } +} + + + +// +// Wrapper for serializing arrays and POD +// There's a clever template way to make arrays serialize normally, but MSVC6 doesn't support it +// +#define FLATDATA(obj) REF(CFlatData((char*)&(obj), (char*)&(obj) + sizeof(obj))) +class CFlatData +{ +protected: + char* pbegin; + char* pend; +public: + CFlatData(void* pbeginIn, void* pendIn) : pbegin((char*)pbeginIn), pend((char*)pendIn) { } + char* begin() { return pbegin; } + const char* begin() const { return pbegin; } + char* end() { return pend; } + const char* end() const { return pend; } + + unsigned int GetSerializeSize(int, int=0) const + { + return pend - pbegin; + } + + template + void Serialize(Stream& s, int, int=0) const + { + s.write(pbegin, pend - pbegin); + } + + template + void Unserialize(Stream& s, int, int=0) + { + s.read(pbegin, pend - pbegin); + } +}; + + + +// +// string stored as a fixed length field +// +template +class CFixedFieldString +{ +protected: + const string* pcstr; + string* pstr; +public: + explicit CFixedFieldString(const string& str) : pcstr(&str), pstr(NULL) { } + explicit CFixedFieldString(string& str) : pcstr(&str), pstr(&str) { } + + unsigned int GetSerializeSize(int, int=0) const + { + return LEN; + } + + template + void Serialize(Stream& s, int, int=0) const + { + char pszBuf[LEN]; + strncpy(pszBuf, pcstr->c_str(), LEN); + s.write(pszBuf, LEN); + } + + template + void Unserialize(Stream& s, int, int=0) + { + if (pstr == NULL) + throw std::ios_base::failure("CFixedFieldString::Unserialize : trying to unserialize to const string"); + char pszBuf[LEN+1]; + s.read(pszBuf, LEN); + pszBuf[LEN] = '\0'; + *pstr = pszBuf; + } +}; + + + + + +// +// Forward declarations +// + +// string +template unsigned int GetSerializeSize(const basic_string& str, int, int=0); +template void Serialize(Stream& os, const basic_string& str, int, int=0); +template void Unserialize(Stream& is, basic_string& str, int, int=0); + +// vector +template unsigned int GetSerializeSize_impl(const std::vector& v, int nType, int nVersion, const boost::true_type&); +template unsigned int GetSerializeSize_impl(const std::vector& v, int nType, int nVersion, const boost::false_type&); +template inline unsigned int GetSerializeSize(const std::vector& v, int nType, int nVersion=VERSION); +template void Serialize_impl(Stream& os, const std::vector& v, int nType, int nVersion, const boost::true_type&); +template void Serialize_impl(Stream& os, const std::vector& v, int nType, int nVersion, const boost::false_type&); +template inline void Serialize(Stream& os, const std::vector& v, int nType, int nVersion=VERSION); +template void Unserialize_impl(Stream& is, std::vector& v, int nType, int nVersion, const boost::true_type&); +template void Unserialize_impl(Stream& is, std::vector& v, int nType, int nVersion, const boost::false_type&); +template inline void Unserialize(Stream& is, std::vector& v, int nType, int nVersion=VERSION); + +// others derived from vector +extern inline unsigned int GetSerializeSize(const CScript& v, int nType, int nVersion=VERSION); +template void Serialize(Stream& os, const CScript& v, int nType, int nVersion=VERSION); +template void Unserialize(Stream& is, CScript& v, int nType, int nVersion=VERSION); + +// pair +template unsigned int GetSerializeSize(const std::pair& item, int nType, int nVersion=VERSION); +template void Serialize(Stream& os, const std::pair& item, int nType, int nVersion=VERSION); +template void Unserialize(Stream& is, std::pair& item, int nType, int nVersion=VERSION); + +// map +template unsigned int GetSerializeSize(const std::map& m, int nType, int nVersion=VERSION); +template void Serialize(Stream& os, const std::map& m, int nType, int nVersion=VERSION); +template void Unserialize(Stream& is, std::map& m, int nType, int nVersion=VERSION); + +// set +template unsigned int GetSerializeSize(const std::set& m, int nType, int nVersion=VERSION); +template void Serialize(Stream& os, const std::set& m, int nType, int nVersion=VERSION); +template void Unserialize(Stream& is, std::set& m, int nType, int nVersion=VERSION); + + + + + +// +// If none of the specialized versions above matched, default to calling member function. +// "int nType" is changed to "long nType" to keep from getting an ambiguous overload error. +// The compiler will only cast int to long if none of the other templates matched. +// Thanks to Boost serialization for this idea. +// +template +inline unsigned int GetSerializeSize(const T& a, long nType, int nVersion=VERSION) +{ + return a.GetSerializeSize((int)nType, nVersion); +} + +template +inline void Serialize(Stream& os, const T& a, long nType, int nVersion=VERSION) +{ + a.Serialize(os, (int)nType, nVersion); +} + +template +inline void Unserialize(Stream& is, T& a, long nType, int nVersion=VERSION) +{ + a.Unserialize(is, (int)nType, nVersion); +} + + + + + +// +// string +// +template +unsigned int GetSerializeSize(const basic_string& str, int, int) +{ + return GetSizeOfCompactSize(str.size()) + str.size() * sizeof(str[0]); +} + +template +void Serialize(Stream& os, const basic_string& str, int, int) +{ + WriteCompactSize(os, str.size()); + if (!str.empty()) + os.write((char*)&str[0], str.size() * sizeof(str[0])); +} + +template +void Unserialize(Stream& is, basic_string& str, int, int) +{ + unsigned int nSize = ReadCompactSize(is); + str.resize(nSize); + if (nSize != 0) + is.read((char*)&str[0], nSize * sizeof(str[0])); +} + + + +// +// vector +// +template +unsigned int GetSerializeSize_impl(const std::vector& v, int nType, int nVersion, const boost::true_type&) +{ + return (GetSizeOfCompactSize(v.size()) + v.size() * sizeof(T)); +} + +template +unsigned int GetSerializeSize_impl(const std::vector& v, int nType, int nVersion, const boost::false_type&) +{ + unsigned int nSize = GetSizeOfCompactSize(v.size()); + for (typename std::vector::const_iterator vi = v.begin(); vi != v.end(); ++vi) + nSize += GetSerializeSize((*vi), nType, nVersion); + return nSize; +} + +template +inline unsigned int GetSerializeSize(const std::vector& v, int nType, int nVersion) +{ + return GetSerializeSize_impl(v, nType, nVersion, boost::is_fundamental()); +} + + +template +void Serialize_impl(Stream& os, const std::vector& v, int nType, int nVersion, const boost::true_type&) +{ + WriteCompactSize(os, v.size()); + if (!v.empty()) + os.write((char*)&v[0], v.size() * sizeof(T)); +} + +template +void Serialize_impl(Stream& os, const std::vector& v, int nType, int nVersion, const boost::false_type&) +{ + WriteCompactSize(os, v.size()); + for (typename std::vector::const_iterator vi = v.begin(); vi != v.end(); ++vi) + ::Serialize(os, (*vi), nType, nVersion); +} + +template +inline void Serialize(Stream& os, const std::vector& v, int nType, int nVersion) +{ + Serialize_impl(os, v, nType, nVersion, boost::is_fundamental()); +} + + +template +void Unserialize_impl(Stream& is, std::vector& v, int nType, int nVersion, const boost::true_type&) +{ + //unsigned int nSize = ReadCompactSize(is); + //v.resize(nSize); + //is.read((char*)&v[0], nSize * sizeof(T)); + + // Limit size per read so bogus size value won't cause out of memory + v.clear(); + unsigned int nSize = ReadCompactSize(is); + unsigned int i = 0; + while (i < nSize) + { + unsigned int blk = min(nSize - i, 1 + 4999999 / sizeof(T)); + v.resize(i + blk); + is.read((char*)&v[i], blk * sizeof(T)); + i += blk; + } +} + +template +void Unserialize_impl(Stream& is, std::vector& v, int nType, int nVersion, const boost::false_type&) +{ + //unsigned int nSize = ReadCompactSize(is); + //v.resize(nSize); + //for (std::vector::iterator vi = v.begin(); vi != v.end(); ++vi) + // Unserialize(is, (*vi), nType, nVersion); + + v.clear(); + unsigned int nSize = ReadCompactSize(is); + unsigned int i = 0; + unsigned int nMid = 0; + while (nMid < nSize) + { + nMid += 5000000 / sizeof(T); + if (nMid > nSize) + nMid = nSize; + v.resize(nMid); + for (; i < nMid; i++) + Unserialize(is, v[i], nType, nVersion); + } +} + +template +inline void Unserialize(Stream& is, std::vector& v, int nType, int nVersion) +{ + Unserialize_impl(is, v, nType, nVersion, boost::is_fundamental()); +} + + + +// +// others derived from vector +// +inline unsigned int GetSerializeSize(const CScript& v, int nType, int nVersion) +{ + return GetSerializeSize((const vector&)v, nType, nVersion); +} + +template +void Serialize(Stream& os, const CScript& v, int nType, int nVersion) +{ + Serialize(os, (const vector&)v, nType, nVersion); +} + +template +void Unserialize(Stream& is, CScript& v, int nType, int nVersion) +{ + Unserialize(is, (vector&)v, nType, nVersion); +} + + + +// +// pair +// +template +unsigned int GetSerializeSize(const std::pair& item, int nType, int nVersion) +{ + return GetSerializeSize(item.first, nType, nVersion) + GetSerializeSize(item.second, nType, nVersion); +} + +template +void Serialize(Stream& os, const std::pair& item, int nType, int nVersion) +{ + Serialize(os, item.first, nType, nVersion); + Serialize(os, item.second, nType, nVersion); +} + +template +void Unserialize(Stream& is, std::pair& item, int nType, int nVersion) +{ + Unserialize(is, item.first, nType, nVersion); + Unserialize(is, item.second, nType, nVersion); +} + + + +// +// map +// +template +unsigned int GetSerializeSize(const std::map& m, int nType, int nVersion) +{ + unsigned int nSize = GetSizeOfCompactSize(m.size()); + for (typename std::map::const_iterator mi = m.begin(); mi != m.end(); ++mi) + nSize += GetSerializeSize((*mi), nType, nVersion); + return nSize; +} + +template +void Serialize(Stream& os, const std::map& m, int nType, int nVersion) +{ + WriteCompactSize(os, m.size()); + for (typename std::map::const_iterator mi = m.begin(); mi != m.end(); ++mi) + Serialize(os, (*mi), nType, nVersion); +} + +template +void Unserialize(Stream& is, std::map& m, int nType, int nVersion) +{ + m.clear(); + unsigned int nSize = ReadCompactSize(is); + typename std::map::iterator mi = m.begin(); + for (unsigned int i = 0; i < nSize; i++) + { + pair item; + Unserialize(is, item, nType, nVersion); + mi = m.insert(mi, item); + } +} + + + +// +// set +// +template +unsigned int GetSerializeSize(const std::set& m, int nType, int nVersion) +{ + unsigned int nSize = GetSizeOfCompactSize(m.size()); + for (typename std::set::const_iterator it = m.begin(); it != m.end(); ++it) + nSize += GetSerializeSize((*it), nType, nVersion); + return nSize; +} + +template +void Serialize(Stream& os, const std::set& m, int nType, int nVersion) +{ + WriteCompactSize(os, m.size()); + for (typename std::set::const_iterator it = m.begin(); it != m.end(); ++it) + Serialize(os, (*it), nType, nVersion); +} + +template +void Unserialize(Stream& is, std::set& m, int nType, int nVersion) +{ + m.clear(); + unsigned int nSize = ReadCompactSize(is); + typename std::set::iterator it = m.begin(); + for (unsigned int i = 0; i < nSize; i++) + { + K key; + Unserialize(is, key, nType, nVersion); + it = m.insert(it, key); + } +} + + + +// +// Support for IMPLEMENT_SERIALIZE and READWRITE macro +// +class CSerActionGetSerializeSize { }; +class CSerActionSerialize { }; +class CSerActionUnserialize { }; + +template +inline unsigned int SerReadWrite(Stream& s, const T& obj, int nType, int nVersion, CSerActionGetSerializeSize ser_action) +{ + return ::GetSerializeSize(obj, nType, nVersion); +} + +template +inline unsigned int SerReadWrite(Stream& s, const T& obj, int nType, int nVersion, CSerActionSerialize ser_action) +{ + ::Serialize(s, obj, nType, nVersion); + return 0; +} + +template +inline unsigned int SerReadWrite(Stream& s, T& obj, int nType, int nVersion, CSerActionUnserialize ser_action) +{ + ::Unserialize(s, obj, nType, nVersion); + return 0; +} + +struct ser_streamplaceholder +{ + int nType; + int nVersion; +}; + + + + + + + + + +// +// Allocator that clears its contents before deletion +// +template +struct secure_allocator : public std::allocator +{ + // MSVC8 default copy constructor is broken + typedef std::allocator base; + typedef typename base::size_type size_type; + typedef typename base::difference_type difference_type; + typedef typename base::pointer pointer; + typedef typename base::const_pointer const_pointer; + typedef typename base::reference reference; + typedef typename base::const_reference const_reference; + typedef typename base::value_type value_type; + secure_allocator() throw() {} + secure_allocator(const secure_allocator& a) throw() : base(a) {} + ~secure_allocator() throw() {} + template struct rebind + { typedef secure_allocator<_Other> other; }; + + void deallocate(T* p, std::size_t n) + { + if (p != NULL) + memset(p, 0, sizeof(T) * n); + allocator::deallocate(p, n); + } +}; + + + +// +// Double ended buffer combining vector and stream-like interfaces. +// >> and << read and write unformatted data using the above serialization templates. +// Fills with data in linear time; some stringstream implementations take N^2 time. +// +class CDataStream +{ +protected: + typedef vector > vector_type; + vector_type vch; + unsigned int nReadPos; + short state; + short exceptmask; +public: + int nType; + int nVersion; + + typedef vector_type::allocator_type allocator_type; + typedef vector_type::size_type size_type; + typedef vector_type::difference_type difference_type; + typedef vector_type::reference reference; + typedef vector_type::const_reference const_reference; + typedef vector_type::value_type value_type; + typedef vector_type::iterator iterator; + typedef vector_type::const_iterator const_iterator; + typedef vector_type::reverse_iterator reverse_iterator; + + explicit CDataStream(int nTypeIn=0, int nVersionIn=VERSION) + { + Init(nTypeIn, nVersionIn); + } + + CDataStream(const_iterator pbegin, const_iterator pend, int nTypeIn=0, int nVersionIn=VERSION) : vch(pbegin, pend) + { + Init(nTypeIn, nVersionIn); + } + +#if !defined(_MSC_VER) || _MSC_VER >= 1300 + CDataStream(const char* pbegin, const char* pend, int nTypeIn=0, int nVersionIn=VERSION) : vch(pbegin, pend) + { + Init(nTypeIn, nVersionIn); + } +#endif + + CDataStream(const vector_type& vchIn, int nTypeIn=0, int nVersionIn=VERSION) : vch(vchIn.begin(), vchIn.end()) + { + Init(nTypeIn, nVersionIn); + } + + CDataStream(const vector& vchIn, int nTypeIn=0, int nVersionIn=VERSION) : vch(vchIn.begin(), vchIn.end()) + { + Init(nTypeIn, nVersionIn); + } + + CDataStream(const vector& vchIn, int nTypeIn=0, int nVersionIn=VERSION) : vch((char*)&vchIn.begin()[0], (char*)&vchIn.end()[0]) + { + Init(nTypeIn, nVersionIn); + } + + void Init(int nTypeIn=0, int nVersionIn=VERSION) + { + nReadPos = 0; + nType = nTypeIn; + nVersion = nVersionIn; + state = 0; + exceptmask = ios::badbit | ios::failbit; + } + + CDataStream& operator+=(const CDataStream& b) + { + vch.insert(vch.end(), b.begin(), b.end()); + return *this; + } + + friend CDataStream operator+(const CDataStream& a, const CDataStream& b) + { + CDataStream ret = a; + ret += b; + return (ret); + } + + string str() const + { + return (string(begin(), end())); + } + + + // + // Vector subset + // + const_iterator begin() const { return vch.begin() + nReadPos; } + iterator begin() { return vch.begin() + nReadPos; } + const_iterator end() const { return vch.end(); } + iterator end() { return vch.end(); } + size_type size() const { return vch.size() - nReadPos; } + bool empty() const { return vch.size() == nReadPos; } + void resize(size_type n, value_type c=0) { vch.resize(n + nReadPos, c); } + void reserve(size_type n) { vch.reserve(n + nReadPos); } + const_reference operator[](size_type pos) const { return vch[pos + nReadPos]; } + reference operator[](size_type pos) { return vch[pos + nReadPos]; } + void clear() { vch.clear(); nReadPos = 0; } + iterator insert(iterator it, const char& x=char()) { return vch.insert(it, x); } + void insert(iterator it, size_type n, const char& x) { vch.insert(it, n, x); } + + void insert(iterator it, const_iterator first, const_iterator last) + { + if (it == vch.begin() + nReadPos && last - first <= nReadPos) + { + // special case for inserting at the front when there's room + nReadPos -= (last - first); + memcpy(&vch[nReadPos], &first[0], last - first); + } + else + vch.insert(it, first, last); + } + +#if !defined(_MSC_VER) || _MSC_VER >= 1300 + void insert(iterator it, const char* first, const char* last) + { + if (it == vch.begin() + nReadPos && last - first <= nReadPos) + { + // special case for inserting at the front when there's room + nReadPos -= (last - first); + memcpy(&vch[nReadPos], &first[0], last - first); + } + else + vch.insert(it, first, last); + } +#endif + + iterator erase(iterator it) + { + if (it == vch.begin() + nReadPos) + { + // special case for erasing from the front + if (++nReadPos >= vch.size()) + { + // whenever we reach the end, we take the opportunity to clear the buffer + nReadPos = 0; + return vch.erase(vch.begin(), vch.end()); + } + return vch.begin() + nReadPos; + } + else + return vch.erase(it); + } + + iterator erase(iterator first, iterator last) + { + if (first == vch.begin() + nReadPos) + { + // special case for erasing from the front + if (last == vch.end()) + { + nReadPos = 0; + return vch.erase(vch.begin(), vch.end()); + } + else + { + nReadPos = (last - vch.begin()); + return last; + } + } + else + return vch.erase(first, last); + } + + inline void Compact() + { + vch.erase(vch.begin(), vch.begin() + nReadPos); + nReadPos = 0; + } + + bool Rewind(size_type n) + { + // Rewind by n characters if the buffer hasn't been compacted yet + if (n > nReadPos) + return false; + nReadPos -= n; + return true; + } + + + // + // Stream subset + // + void setstate(short bits, const char* psz) + { + state |= bits; + if (state & exceptmask) + throw std::ios_base::failure(psz); + } + + bool eof() const { return size() == 0; } + bool fail() const { return state & (ios::badbit | ios::failbit); } + bool good() const { return !eof() && (state == 0); } + void clear(short n) { state = n; } // name conflict with vector clear() + short exceptions() { return exceptmask; } + short exceptions(short mask) { short prev = exceptmask; exceptmask = mask; setstate(0, "CDataStream"); return prev; } + CDataStream* rdbuf() { return this; } + int in_avail() { return size(); } + + void SetType(int n) { nType = n; } + int GetType() { return nType; } + void SetVersion(int n) { nVersion = n; } + int GetVersion() { return nVersion; } + void ReadVersion() { *this >> nVersion; } + void WriteVersion() { *this << nVersion; } + + CDataStream& read(char* pch, int nSize) + { + // Read from the beginning of the buffer + assert(nSize >= 0); + unsigned int nReadPosNext = nReadPos + nSize; + if (nReadPosNext >= vch.size()) + { + if (nReadPosNext > vch.size()) + { + setstate(ios::failbit, "CDataStream::read() : end of data"); + memset(pch, 0, nSize); + nSize = vch.size() - nReadPos; + } + memcpy(pch, &vch[nReadPos], nSize); + nReadPos = 0; + vch.clear(); + return (*this); + } + memcpy(pch, &vch[nReadPos], nSize); + nReadPos = nReadPosNext; + return (*this); + } + + CDataStream& ignore(int nSize) + { + // Ignore from the beginning of the buffer + assert(nSize >= 0); + unsigned int nReadPosNext = nReadPos + nSize; + if (nReadPosNext >= vch.size()) + { + if (nReadPosNext > vch.size()) + { + setstate(ios::failbit, "CDataStream::ignore() : end of data"); + nSize = vch.size() - nReadPos; + } + nReadPos = 0; + vch.clear(); + return (*this); + } + nReadPos = nReadPosNext; + return (*this); + } + + CDataStream& write(const char* pch, int nSize) + { + // Write to the end of the buffer + assert(nSize >= 0); + vch.insert(vch.end(), pch, pch + nSize); + return (*this); + } + + template + void Serialize(Stream& s, int nType=0, int nVersion=VERSION) const + { + // Special case: stream << stream concatenates like stream += stream + if (!vch.empty()) + s.write((char*)&vch[0], vch.size() * sizeof(vch[0])); + } + + template + unsigned int GetSerializeSize(const T& obj) + { + // Tells the size of the object if serialized to this stream + return ::GetSerializeSize(obj, nType, nVersion); + } + + template + CDataStream& operator<<(const T& obj) + { + // Serialize to this stream + ::Serialize(*this, obj, nType, nVersion); + return (*this); + } + + template + CDataStream& operator>>(T& obj) + { + // Unserialize from this stream + ::Unserialize(*this, obj, nType, nVersion); + return (*this); + } +}; + +#ifdef TESTCDATASTREAM +// VC6sp6 +// CDataStream: +// n=1000 0 seconds +// n=2000 0 seconds +// n=4000 0 seconds +// n=8000 0 seconds +// n=16000 0 seconds +// n=32000 0 seconds +// n=64000 1 seconds +// n=128000 1 seconds +// n=256000 2 seconds +// n=512000 4 seconds +// n=1024000 8 seconds +// n=2048000 16 seconds +// n=4096000 32 seconds +// stringstream: +// n=1000 1 seconds +// n=2000 1 seconds +// n=4000 13 seconds +// n=8000 87 seconds +// n=16000 400 seconds +// n=32000 1660 seconds +// n=64000 6749 seconds +// n=128000 27241 seconds +// n=256000 109804 seconds +#include +int main(int argc, char *argv[]) +{ + vector vch(0xcc, 250); + printf("CDataStream:\n"); + for (int n = 1000; n <= 4500000; n *= 2) + { + CDataStream ss; + time_t nStart = time(NULL); + for (int i = 0; i < n; i++) + ss.write((char*)&vch[0], vch.size()); + printf("n=%-10d %d seconds\n", n, time(NULL) - nStart); + } + printf("stringstream:\n"); + for (int n = 1000; n <= 4500000; n *= 2) + { + stringstream ss; + time_t nStart = time(NULL); + for (int i = 0; i < n; i++) + ss.write((char*)&vch[0], vch.size()); + printf("n=%-10d %d seconds\n", n, time(NULL) - nStart); + } +} +#endif + + + + + + + + + + +// +// Automatic closing wrapper for FILE* +// - Will automatically close the file when it goes out of scope if not null. +// - If you're returning the file pointer, return file.release(). +// - If you need to close the file early, use file.fclose() instead of fclose(file). +// +class CAutoFile +{ +protected: + FILE* file; + short state; + short exceptmask; +public: + int nType; + int nVersion; + + typedef FILE element_type; + + CAutoFile(FILE* filenew=NULL, int nTypeIn=SER_DISK, int nVersionIn=VERSION) + { + file = filenew; + nType = nTypeIn; + nVersion = nVersionIn; + state = 0; + exceptmask = ios::badbit | ios::failbit; + } + + ~CAutoFile() + { + fclose(); + } + + void fclose() + { + if (file != NULL && file != stdin && file != stdout && file != stderr) + ::fclose(file); + file = NULL; + } + + FILE* release() { FILE* ret = file; file = NULL; return ret; } + operator FILE*() { return file; } + FILE* operator->() { return file; } + FILE& operator*() { return *file; } + FILE** operator&() { return &file; } + FILE* operator=(FILE* pnew) { return file = pnew; } + bool operator!() { return (file == NULL); } + + + // + // Stream subset + // + void setstate(short bits, const char* psz) + { + state |= bits; + if (state & exceptmask) + throw std::ios_base::failure(psz); + } + + bool fail() const { return state & (ios::badbit | ios::failbit); } + bool good() const { return state == 0; } + void clear(short n = 0) { state = n; } + short exceptions() { return exceptmask; } + short exceptions(short mask) { short prev = exceptmask; exceptmask = mask; setstate(0, "CAutoFile"); return prev; } + + void SetType(int n) { nType = n; } + int GetType() { return nType; } + void SetVersion(int n) { nVersion = n; } + int GetVersion() { return nVersion; } + void ReadVersion() { *this >> nVersion; } + void WriteVersion() { *this << nVersion; } + + CAutoFile& read(char* pch, int nSize) + { + if (!file) + throw std::ios_base::failure("CAutoFile::read : file handle is NULL"); + if (fread(pch, 1, nSize, file) != nSize) + setstate(ios::failbit, feof(file) ? "CAutoFile::read : end of file" : "CAutoFile::read : fread failed"); + return (*this); + } + + CAutoFile& write(const char* pch, int nSize) + { + if (!file) + throw std::ios_base::failure("CAutoFile::write : file handle is NULL"); + if (fwrite(pch, 1, nSize, file) != nSize) + setstate(ios::failbit, "CAutoFile::write : write failed"); + return (*this); + } + + template + unsigned int GetSerializeSize(const T& obj) + { + // Tells the size of the object if serialized to this stream + return ::GetSerializeSize(obj, nType, nVersion); + } + + template + CAutoFile& operator<<(const T& obj) + { + // Serialize to this stream + if (!file) + throw std::ios_base::failure("CAutoFile::operator<< : file handle is NULL"); + ::Serialize(*this, obj, nType, nVersion); + return (*this); + } + + template + CAutoFile& operator>>(T& obj) + { + // Unserialize from this stream + if (!file) + throw std::ios_base::failure("CAutoFile::operator>> : file handle is NULL"); + ::Unserialize(*this, obj, nType, nVersion); + return (*this); + } +}; diff --git a/sha.cpp b/sha.cpp new file mode 100644 index 0000000000..09b62fdc89 --- /dev/null +++ b/sha.cpp @@ -0,0 +1,554 @@ +// This file is public domain +// SHA routines extracted as a standalone file from: +// Crypto++: a C++ Class Library of Cryptographic Schemes +// Version 5.5.2 (9/24/2007) +// http://www.cryptopp.com + +// 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. + +#include +#include +#include "sha.h" + +namespace 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)); +} + +static const word32 SHA256_K[64] = { + 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 +}; + +#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) ((x&y)|(z&(x|y))) + +#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]; + 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); +} + +/* +// 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 += 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 += 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 += 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 + +// ************************************************************* + +#ifdef WORD64_AVAILABLE + +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)); +} + +CRYPTOPP_ALIGN_DATA(16) static const word64 SHA512_K[80] CRYPTOPP_SECTION_ALIGN16 = { + 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( movq mm4, [ecx+0*8]) + AS2( movq [edi+0*8], mm4) + AS2( movq mm0, [ecx+1*8]) + AS2( movq [edi+1*8], mm0) + AS2( movq mm0, [ecx+2*8]) + AS2( movq [edi+2*8], mm0) + AS2( movq mm0, [ecx+3*8]) + AS2( movq [edi+3*8], mm0) + AS2( movq mm5, [ecx+4*8]) + AS2( movq [edi+4*8], mm5) + AS2( movq mm0, [ecx+5*8]) + AS2( movq [edi+5*8], mm0) + AS2( movq mm0, [ecx+6*8]) + AS2( movq [edi+6*8], mm0) + AS2( movq mm0, [ecx+7*8]) + AS2( movq [edi+7*8], mm0) + 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( movq mm0, [edi+i*8])\ + AS2( paddq mm0, [ecx+i*8])\ + AS2( movq [ecx+i*8], mm0) + + SSE2_CombineState(0) + SSE2_CombineState(1) + SSE2_CombineState(2) + SSE2_CombineState(3) + SSE2_CombineState(4) + SSE2_CombineState(5) + SSE2_CombineState(6) + SSE2_CombineState(7) + + 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); +} + +#endif + +} diff --git a/sha.h b/sha.h new file mode 100644 index 0000000000..4e56b56d9c --- /dev/null +++ b/sha.h @@ -0,0 +1,177 @@ +// This file is public domain +// SHA routines extracted as a standalone file from: +// Crypto++: a C++ Class Library of Cryptographic Schemes +// Version 5.5.2 (9/24/2007) +// http://www.cryptopp.com +#ifndef CRYPTOPP_SHA_H +#define CRYPTOPP_SHA_H +#include + +namespace CryptoPP +{ + +// +// Dependencies +// + +typedef unsigned char byte; +typedef unsigned short word16; +typedef unsigned int word32; +#if defined(_MSC_VER) || defined(__BORLANDC__) +typedef unsigned __int64 word64; +#else +typedef unsigned long long word64; +#endif + +template inline T rotlFixed(T x, unsigned int y) +{ + assert(y < sizeof(T)*8); + return T((x<>(sizeof(T)*8-y))); +} + +template inline T rotrFixed(T x, unsigned int y) +{ + assert(y < sizeof(T)*8); + return T((x>>y) | (x<<(sizeof(T)*8-y))); +} + +// ************** endian reversal *************** + +#ifdef _MSC_VER + #if _MSC_VER >= 1400 + #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 + +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__) + __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 +} + +#ifdef WORD64_AVAILABLE +inline word64 ByteReverse(word64 value) +{ +#if defined(__GNUC__) && 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 defined(CRYPTOPP_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 +} +#endif + + +// +// SHA +// + +// http://www.weidai.com/scan-mirror/md.html#SHA-1 +class SHA1 +{ +public: + typedef word32 HashWordType; + static void InitState(word32 *state); + static void Transform(word32 *digest, const word32 *data); + static const char * StaticAlgorithmName() {return "SHA-1";} +}; + +typedef SHA1 SHA; // for backwards compatibility + +// implements the SHA-256 standard +class SHA256 +{ +public: + typedef word32 HashWordType; + static void InitState(word32 *state); + static void Transform(word32 *digest, const word32 *data); + static const char * StaticAlgorithmName() {return "SHA-256";} +}; + +// implements the SHA-224 standard +class SHA224 +{ +public: + typedef word32 HashWordType; + static void InitState(word32 *state); + static void Transform(word32 *digest, const word32 *data) {SHA256::Transform(digest, data);} + static const char * StaticAlgorithmName() {return "SHA-224";} +}; + +#ifdef WORD64_AVAILABLE + +// implements the SHA-512 standard +class SHA512 +{ +public: + typedef word64 HashWordType; + static void InitState(word64 *state); + static void Transform(word64 *digest, const word64 *data); + static const char * StaticAlgorithmName() {return "SHA-512";} +}; + +// implements the SHA-384 standard +class SHA384 +{ +public: + typedef word64 HashWordType; + static void InitState(word64 *state); + static void Transform(word64 *digest, const word64 *data) {SHA512::Transform(digest, data);} + static const char * StaticAlgorithmName() {return "SHA-384";} +}; + +#endif + +} + +#endif diff --git a/ui.cpp b/ui.cpp new file mode 100644 index 0000000000..96c5a83d58 --- /dev/null +++ b/ui.cpp @@ -0,0 +1,3290 @@ +// Copyright (c) 2009 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" +#ifdef _MSC_VER +#include +#endif + + + +DEFINE_EVENT_TYPE(wxEVT_CROSSTHREADCALL) +DEFINE_EVENT_TYPE(wxEVT_REPLY1) +DEFINE_EVENT_TYPE(wxEVT_REPLY2) +DEFINE_EVENT_TYPE(wxEVT_REPLY3) +DEFINE_EVENT_TYPE(wxEVT_TABLEADDED) +DEFINE_EVENT_TYPE(wxEVT_TABLEUPDATED) +DEFINE_EVENT_TYPE(wxEVT_TABLEDELETED) + +CMainFrame* pframeMain = NULL; +map mapAddressBook; + + +void ThreadRequestProductDetails(void* parg); +void ThreadRandSendTest(void* parg); +bool fRandSendTest = false; +void RandSend(); +extern int g_isPainting; + + + + + + +////////////////////////////////////////////////////////////////////////////// +// +// Util +// + +void HandleCtrlA(wxKeyEvent& event) +{ + // Ctrl-a select all + wxTextCtrl* textCtrl = (wxTextCtrl*)event.GetEventObject(); + if (event.GetModifiers() == wxMOD_CONTROL && event.GetKeyCode() == 'A') + textCtrl->SetSelection(-1, -1); + event.Skip(); +} + +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) +{ + return (string)wxDateTime((time_t)nTime).FormatDate(); +} + +string DateTimeStr(int64 nTime) +{ + 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 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 += "
\n"; + else + str += *p; + } + return str; +} + +string HtmlEscape(const string& str, bool fMultiLine=false) +{ + return HtmlEscape(str.c_str(), fMultiLine); +} + +void AddToMyProducts(CProduct product) +{ + CProduct& productInsert = mapMyProducts[product.GetHash()]; + productInsert = product; + InsertLine(pframeMain->m_listCtrlProductsSent, &productInsert, + product.mapValue["category"], + product.mapValue["title"].substr(0, 100), + product.mapValue["description"].substr(0, 100), + product.mapValue["price"], + ""); +} + + + + + + +////////////////////////////////////////////////////////////////////////////// +// +// Custom events +// + +set setCallbackAvailable; +CCriticalSection cs_setCallbackAvailable; + +void AddCallbackAvailable(void* p) +{ + CRITICAL_BLOCK(cs_setCallbackAvailable) + setCallbackAvailable.insert(p); +} + +void RemoveCallbackAvailable(void* p) +{ + CRITICAL_BLOCK(cs_setCallbackAvailable) + setCallbackAvailable.erase(p); +} + +bool IsCallbackAvailable(void* p) +{ + CRITICAL_BLOCK(cs_setCallbackAvailable) + return setCallbackAvailable.count(p); + return false; +} + +template +void AddPendingCustomEvent(wxEvtHandler* pevthandler, int nEventID, const T pbeginIn, const T pendIn) +{ + if (!pevthandler) + return; + + const char* pbegin = (pendIn != pbeginIn) ? &pbeginIn[0] : NULL; + const char* pend = pbegin + (pendIn - pbeginIn) * sizeof(pbeginIn[0]); + wxCommandEvent event(nEventID); + wxString strData(wxChar(0), (pend - pbegin) / sizeof(wxChar) + 1); + memcpy(&strData[0], pbegin, pend - pbegin); + event.SetString(strData); + event.SetInt(pend - pbegin); + + pevthandler->AddPendingEvent(event); +} + +template +void AddPendingCustomEvent(wxEvtHandler* pevthandler, int nEventID, const T& obj) +{ + CDataStream ss; + ss << obj; + AddPendingCustomEvent(pevthandler, nEventID, ss.begin(), ss.end()); +} + +void AddPendingReplyEvent1(void* pevthandler, CDataStream& vRecv) +{ + if (IsCallbackAvailable(pevthandler)) + AddPendingCustomEvent((wxEvtHandler*)pevthandler, wxEVT_REPLY1, vRecv.begin(), vRecv.end()); +} + +void AddPendingReplyEvent2(void* pevthandler, CDataStream& vRecv) +{ + if (IsCallbackAvailable(pevthandler)) + AddPendingCustomEvent((wxEvtHandler*)pevthandler, wxEVT_REPLY2, vRecv.begin(), vRecv.end()); +} + +void AddPendingReplyEvent3(void* pevthandler, CDataStream& vRecv) +{ + if (IsCallbackAvailable(pevthandler)) + AddPendingCustomEvent((wxEvtHandler*)pevthandler, wxEVT_REPLY3, vRecv.begin(), vRecv.end()); +} + +CDataStream GetStreamFromEvent(const wxCommandEvent& event) +{ + wxString strData = event.GetString(); + return CDataStream(strData.begin(), strData.begin() + event.GetInt(), SER_NETWORK); +} + + + + + + + +////////////////////////////////////////////////////////////////////////////// +// +// CMainFrame +// + +CMainFrame::CMainFrame(wxWindow* parent) : CMainFrameBase(parent) +{ + Connect(wxEVT_CROSSTHREADCALL, wxCommandEventHandler(CMainFrame::OnCrossThreadCall), NULL, this); + + // Init + fRefreshListCtrl = false; + fRefreshListCtrlRunning = false; + fOnSetFocusAddress = false; + pindexBestLast = NULL; + m_choiceFilter->SetSelection(0); + m_staticTextBalance->SetLabel(FormatMoney(GetBalance()) + " "); + m_listCtrl->SetFocus(); + SetIcon(wxICON(bitcoin)); + m_menuOptions->Check(wxID_OPTIONSGENERATEBITCOINS, fGenerateBitcoins); + + // Init toolbar with transparency masked bitmaps + m_toolBar->ClearTools(); + + //// shouldn't have to do mask separately anymore, bitmap alpha support added in wx 2.8.9, + wxBitmap bmpSend(wxT("send20"), wxBITMAP_TYPE_RESOURCE); + bmpSend.SetMask(new wxMask(wxBitmap(wxT("send20mask"), wxBITMAP_TYPE_RESOURCE))); + m_toolBar->AddTool(wxID_BUTTONSEND, wxT("&Send Coins"), bmpSend, wxNullBitmap, wxITEM_NORMAL, wxEmptyString, wxEmptyString); + + wxBitmap bmpAddressBook(wxT("addressbook20"), wxBITMAP_TYPE_RESOURCE); + bmpAddressBook.SetMask(new wxMask(wxBitmap(wxT("addressbook20mask"), wxBITMAP_TYPE_RESOURCE))); + m_toolBar->AddTool(wxID_BUTTONRECEIVE, wxT("&Address Book"), bmpAddressBook, wxNullBitmap, wxITEM_NORMAL, wxEmptyString, wxEmptyString); + + m_toolBar->Realize(); + + // Init column headers + int nDateWidth = DateTimeStr(1229413914).size() * 6 + 8; + m_listCtrl->InsertColumn(0, "", wxLIST_FORMAT_LEFT, 0); + m_listCtrl->InsertColumn(1, "", wxLIST_FORMAT_LEFT, 0); + m_listCtrl->InsertColumn(2, "Status", wxLIST_FORMAT_LEFT, 90); + m_listCtrl->InsertColumn(3, "Date", wxLIST_FORMAT_LEFT, nDateWidth); + m_listCtrl->InsertColumn(4, "Description", wxLIST_FORMAT_LEFT, 409 - nDateWidth); + m_listCtrl->InsertColumn(5, "Debit", wxLIST_FORMAT_RIGHT, 79); + m_listCtrl->InsertColumn(6, "Credit", wxLIST_FORMAT_RIGHT, 79); + + //m_listCtrlProductsSent->InsertColumn(0, "Category", wxLIST_FORMAT_LEFT, 100); + //m_listCtrlProductsSent->InsertColumn(1, "Title", wxLIST_FORMAT_LEFT, 100); + //m_listCtrlProductsSent->InsertColumn(2, "Description", wxLIST_FORMAT_LEFT, 100); + //m_listCtrlProductsSent->InsertColumn(3, "Price", wxLIST_FORMAT_LEFT, 100); + //m_listCtrlProductsSent->InsertColumn(4, "", wxLIST_FORMAT_LEFT, 100); + + //m_listCtrlOrdersSent->InsertColumn(0, "Time", wxLIST_FORMAT_LEFT, 100); + //m_listCtrlOrdersSent->InsertColumn(1, "Price", wxLIST_FORMAT_LEFT, 100); + //m_listCtrlOrdersSent->InsertColumn(2, "", wxLIST_FORMAT_LEFT, 100); + //m_listCtrlOrdersSent->InsertColumn(3, "", wxLIST_FORMAT_LEFT, 100); + //m_listCtrlOrdersSent->InsertColumn(4, "", wxLIST_FORMAT_LEFT, 100); + + //m_listCtrlOrdersReceived->InsertColumn(0, "Time", wxLIST_FORMAT_LEFT, 100); + //m_listCtrlOrdersReceived->InsertColumn(1, "Price", wxLIST_FORMAT_LEFT, 100); + //m_listCtrlOrdersReceived->InsertColumn(2, "Payment Status", wxLIST_FORMAT_LEFT, 100); + //m_listCtrlOrdersReceived->InsertColumn(3, "", wxLIST_FORMAT_LEFT, 100); + //m_listCtrlOrdersReceived->InsertColumn(4, "", wxLIST_FORMAT_LEFT, 100); + + // Init status bar + int pnWidths[3] = { -100, 81, 286 }; + m_statusBar->SetFieldsCount(3, pnWidths); + + // Fill your address text box + vector vchPubKey; + if (CWalletDB("r").ReadDefaultKey(vchPubKey)) + m_textCtrlAddress->SetValue(PubKeyToAddress(vchPubKey)); + + // Fill listctrl with wallet transactions + RefreshListCtrl(); +} + +CMainFrame::~CMainFrame() +{ + pframeMain = NULL; +} + +void Shutdown(void* parg) +{ + static CCriticalSection cs_Shutdown; + CRITICAL_BLOCK(cs_Shutdown) + { + fShutdown = true; + nTransactionsUpdated++; + DBFlush(false); + StopNode(); + DBFlush(true); + + printf("Bitcoin exiting\n"); + exit(0); + } +} + +void CMainFrame::OnClose(wxCloseEvent& event) +{ + Destroy(); + _beginthread(Shutdown, 0, NULL); +} + +void CMainFrame::OnMouseEvents(wxMouseEvent& event) +{ + 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(); +} + +void CMainFrame::InsertLine(bool fNew, int nIndex, uint256 hashKey, string strSort, const wxString& str2, const wxString& str3, const wxString& str4, const wxString& str5, const wxString& str6) +{ + string str0 = strSort; + long nData = *(long*)&hashKey; + + if (fNew) + { + nIndex = m_listCtrl->InsertItem(0, str0); + } + else + { + if (nIndex == -1) + { + // Find item + while ((nIndex = m_listCtrl->FindItem(nIndex, nData)) != -1) + if (GetItemText(m_listCtrl, nIndex, 1) == hashKey.ToString()) + break; + if (nIndex == -1) + { + printf("CMainFrame::InsertLine : Couldn't find item to be updated\n"); + return; + } + } + + // If sort key changed, must delete and reinsert to make it relocate + if (GetItemText(m_listCtrl, nIndex, 0) != str0) + { + m_listCtrl->DeleteItem(nIndex); + nIndex = m_listCtrl->InsertItem(0, str0); + } + } + + 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); +} + +string FormatTxStatus(const CWalletTx& wtx) +{ + // Status + int nDepth = wtx.GetDepthInMainChain(); + if (!wtx.IsFinal()) + return strprintf("Open for %d blocks", nBestHeight - wtx.nLockTime); + else if (nDepth < 6) + return strprintf("%d/unconfirmed", nDepth); + else + return strprintf("%d blocks", nDepth); +} + +string SingleLine(const string& strIn) +{ + string strOut; + bool fOneSpace = false; + foreach(int c, strIn) + { + if (isspace(c)) + { + fOneSpace = true; + } + else if (c > ' ') + { + if (fOneSpace && !strOut.empty()) + strOut += ' '; + strOut += c; + fOneSpace = false; + } + } + return strOut; +} + +void CMainFrame::InsertTransaction(const CWalletTx& wtx, bool fNew, int nIndex) +{ + int64 nTime = wtx.nTimeDisplayed = wtx.GetTxTime(); + int64 nCredit = wtx.GetCredit(); + int64 nDebit = wtx.GetDebit(); + int64 nNet = nCredit - nDebit; + uint256 hash = wtx.GetHash(); + string strStatus = FormatTxStatus(wtx); + map mapValue = wtx.mapValue; + + // Find the block the tx is in + CBlockIndex* pindex = NULL; + map::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()) + { + // Coinbase + strDescription = "Generated"; + if (nCredit == 0) + { + int64 nUnmatured = 0; + foreach(const CTxOut& txout, wtx.vout) + nUnmatured += txout.GetCredit(); + if (wtx.IsInMainChain()) + strDescription += strprintf(" (%s matures in %d more blocks)", FormatMoney(nUnmatured).c_str(), wtx.GetBlocksToMaturity()); + else + strDescription += " (not accepted)"; + } + } + else if (!mapValue["from"].empty() || !mapValue["message"].empty()) + { + // Online transaction + if (!mapValue["from"].empty()) + strDescription += "From: " + mapValue["from"]; + if (!mapValue["message"].empty()) + { + if (!strDescription.empty()) + strDescription += " - "; + strDescription += mapValue["message"]; + } + } + else + { + // Offline transaction + foreach(const CTxOut& txout, wtx.vout) + { + if (txout.IsMine()) + { + vector vchPubKey; + if (ExtractPubKey(txout.scriptPubKey, true, vchPubKey)) + { + string strAddress = PubKeyToAddress(vchPubKey); + if (mapAddressBook.count(strAddress)) + { + //strDescription += "Received payment to "; + //strDescription += "Received with address "; + strDescription += "From: unknown, To: "; + strDescription += strAddress; + /// The labeling feature is just too confusing, so I hid it + /// by putting it at the end where it runs off the screen. + /// It can still be seen by widening the column, or in the + /// details dialog. + if (!mapAddressBook[strAddress].empty()) + strDescription += " (" + mapAddressBook[strAddress] + ")"; + } + } + break; + } + } + } + + InsertLine(fNew, nIndex, hash, strSort, + strStatus, + nTime ? DateTimeStr(nTime) : "", + SingleLine(strDescription), + "", + FormatMoney(nNet, true)); + } + else + { + bool fAllFromMe = true; + foreach(const CTxIn& txin, wtx.vin) + fAllFromMe = fAllFromMe && txin.IsMine(); + + bool fAllToMe = true; + foreach(const CTxOut& txout, wtx.vout) + fAllToMe = fAllToMe && txout.IsMine(); + + if (fAllFromMe && fAllToMe) + { + // Payment to self + int64 nValue = wtx.vout[0].nValue; + InsertLine(fNew, nIndex, hash, strSort, + strStatus, + nTime ? DateTimeStr(nTime) : "", + "Payment to yourself", + FormatMoney(nNet - nValue, true), + FormatMoney(nValue, true)); + } + else if (fAllFromMe) + { + // + // Debit + // + int64 nTxFee = nDebit - wtx.GetValueOut(); + for (int nOut = 0; nOut < wtx.vout.size(); nOut++) + { + const CTxOut& txout = wtx.vout[nOut]; + if (txout.IsMine()) + continue; + + string strAddress; + if (!mapValue["to"].empty()) + { + // Online transaction + strAddress = mapValue["to"]; + } + else + { + // Offline transaction + uint160 hash160; + if (ExtractHash160(txout.scriptPubKey, hash160)) + strAddress = Hash160ToAddress(hash160); + } + + string strDescription = "To: "; + if (mapAddressBook.count(strAddress) && !mapAddressBook[strAddress].empty()) + strDescription += mapAddressBook[strAddress] + " "; + strDescription += strAddress; + if (!mapValue["message"].empty()) + { + if (!strDescription.empty()) + strDescription += " - "; + strDescription += mapValue["message"]; + } + + int64 nValue = txout.nValue; + if (nOut == 0 && nTxFee > 0) + nValue += nTxFee; + + InsertLine(fNew, nIndex, hash, strprintf("%s-%d", strSort.c_str(), nOut), + strStatus, + nTime ? DateTimeStr(nTime) : "", + SingleLine(strDescription), + FormatMoney(-nValue, true), + ""); + } + } + else + { + // + // Mixed debit transaction, can't break down payees + // + bool fAllMine = true; + foreach(const CTxOut& txout, wtx.vout) + fAllMine = fAllMine && txout.IsMine(); + foreach(const CTxIn& txin, wtx.vin) + fAllMine = fAllMine && txin.IsMine(); + + InsertLine(fNew, nIndex, hash, strSort, + strStatus, + nTime ? DateTimeStr(nTime) : "", + "", + FormatMoney(nNet, true), + ""); + } + } +} + +void CMainFrame::RefreshStatus() +{ + static int nLastTop; + int nTop = m_listCtrl->GetTopItem(); + if (nTop == nLastTop && pindexBestLast == pindexBest) + return; + + TRY_CRITICAL_BLOCK(cs_mapWallet) + { + int nStart = nTop; + int nEnd = min(nStart + 100, m_listCtrl->GetItemCount()); + if (pindexBestLast == pindexBest) + { + if (nStart >= nLastTop && nStart < nLastTop + 100) + nStart = nLastTop + 100; + if (nEnd >= nLastTop && nEnd < nLastTop + 100) + nEnd = nLastTop; + } + nLastTop = nTop; + pindexBestLast = pindexBest; + + for (int nIndex = nStart; nIndex < nEnd; nIndex++) + { + uint256 hash((string)GetItemText(m_listCtrl, nIndex, 1)); + map::iterator mi = mapWallet.find(hash); + if (mi == mapWallet.end()) + { + printf("CMainFrame::RefreshStatus() : tx not found in mapWallet\n"); + continue; + } + const CWalletTx& wtx = (*mi).second; + if (wtx.IsCoinBase() || wtx.GetTxTime() != wtx.nTimeDisplayed) + InsertTransaction(wtx, false, nIndex); + else + m_listCtrl->SetItem(nIndex, 2, FormatTxStatus(wtx)); + } + } +} + +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 > vSorted; + TRY_CRITICAL_BLOCK(cs_mapWallet) + { + printf("RefreshListCtrl starting\n"); + fEntered = true; + fRefreshListCtrl = false; + vWalletUpdated.clear(); + + // Do the newest transactions first + vSorted.reserve(mapWallet.size()); + for (map::iterator it = mapWallet.begin(); it != 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(cs_mapWallet) + { + fEntered = true; + uint256& hash = vSorted[i++].second; + map::iterator mi = mapWallet.find(hash); + if (mi != mapWallet.end()) + InsertTransaction((*mi).second, true); + } + if (!fEntered || i == 100 || i % 500 == 0) + wxYield(); + } + + printf("RefreshListCtrl done\n"); + } + else + { + // Check for time updates + static int64 nLastTime; + if (GetTime() > nLastTime + 30) + { + TRY_CRITICAL_BLOCK(cs_mapWallet) + { + nLastTime = GetTime(); + for (map::iterator it = mapWallet.begin(); it != mapWallet.end(); ++it) + { + CWalletTx& wtx = (*it).second; + if (wtx.nTimeDisplayed && wtx.nTimeDisplayed != wtx.GetTxTime()) + InsertTransaction(wtx, false); + } + } + } + } +} + +void CMainFrame::OnPaint(wxPaintEvent& event) +{ + event.Skip(); +} + +void CMainFrame::OnPaintListCtrl(wxPaintEvent& event) +{ + // Update listctrl contents + if (!vWalletUpdated.empty()) + { + TRY_CRITICAL_BLOCK(cs_mapWallet) + { + pair item; + foreach(item, vWalletUpdated) + { + bool fNew = item.second; + map::iterator mi = mapWallet.find(item.first); + if (mi != mapWallet.end()) + { + printf("vWalletUpdated: %s %s\n", (*mi).second.GetHash().ToString().substr(0,6).c_str(), fNew ? "new" : ""); + InsertTransaction((*mi).second, fNew); + } + } + m_listCtrl->ScrollList(0, INT_MAX); + vWalletUpdated.clear(); + } + } + + // Update status column of visible items only + RefreshStatus(); + + // Update status bar + 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 + 1, m_listCtrl->GetItemCount()); + m_statusBar->SetStatusText(strStatus, 2); + + // Balance total + TRY_CRITICAL_BLOCK(cs_mapWallet) + m_staticTextBalance->SetLabel(FormatMoney(GetBalance()) + " "); + + m_listCtrl->OnPaint(event); +} + +void CrossThreadCall(wxCommandEvent& event) +{ + if (pframeMain) + pframeMain->GetEventHandler()->AddPendingEvent(event); +} + +void CrossThreadCall(int nID, void* pdata) +{ + wxCommandEvent event; + event.SetInt(nID); + event.SetClientData(pdata); + if (pframeMain) + pframeMain->GetEventHandler()->AddPendingEvent(event); +} + +void CMainFrame::OnCrossThreadCall(wxCommandEvent& event) +{ + void* pdata = event.GetClientData(); + switch (event.GetInt()) + { + case UICALL_ADDORDER: + { + break; + } + + case UICALL_UPDATEORDER: + { + break; + } + } +} + +void CMainFrame::OnMenuFileExit(wxCommandEvent& event) +{ + Close(true); +} + +void CMainFrame::OnMenuOptionsGenerate(wxCommandEvent& event) +{ + fGenerateBitcoins = event.IsChecked(); + nTransactionsUpdated++; + CWalletDB().WriteSetting("fGenerateBitcoins", fGenerateBitcoins); + + if (fGenerateBitcoins) + if (_beginthread(ThreadBitcoinMiner, 0, NULL) == -1) + printf("Error: _beginthread(ThreadBitcoinMiner) failed\n"); + + Refresh(); + wxPaintEvent eventPaint; + AddPendingEvent(eventPaint); +} + +void CMainFrame::OnMenuOptionsChangeYourAddress(wxCommandEvent& event) +{ + OnButtonChange(event); +} + +void CMainFrame::OnMenuOptionsOptions(wxCommandEvent& event) +{ + COptionsDialog dialog(this); + dialog.ShowModal(); +} + +void CMainFrame::OnMenuHelpAbout(wxCommandEvent& event) +{ + CAboutDialog dialog(this); + dialog.ShowModal(); +} + +void CMainFrame::OnButtonSend(wxCommandEvent& event) +{ + /// debug test + if (fRandSendTest) + { + RandSend(); + return; + } + + // Toolbar: Send + CSendDialog dialog(this); + dialog.ShowModal(); +} + +void CMainFrame::OnButtonAddressBook(wxCommandEvent& event) +{ + // Toolbar: Address Book + CAddressBookDialog dialogAddr(this, "", false); + if (dialogAddr.ShowModal() == 2) + { + // Send + CSendDialog dialogSend(this, dialogAddr.GetAddress()); + dialogSend.ShowModal(); + } +} + +void CMainFrame::OnSetFocusAddress(wxFocusEvent& event) +{ + // Automatically select-all when entering window + m_textCtrlAddress->SetSelection(-1, -1); + fOnSetFocusAddress = true; + event.Skip(); +} + +void CMainFrame::OnMouseEventsAddress(wxMouseEvent& event) +{ + if (fOnSetFocusAddress) + m_textCtrlAddress->SetSelection(-1, -1); + fOnSetFocusAddress = false; + event.Skip(); +} + +void CMainFrame::OnButtonCopy(wxCommandEvent& event) +{ + // Copy address box to clipboard + if (wxTheClipboard->Open()) + { + wxTheClipboard->SetData(new wxTextDataObject(m_textCtrlAddress->GetValue())); + wxTheClipboard->Close(); + } +} + +void CMainFrame::OnButtonChange(wxCommandEvent& event) +{ + CYourAddressDialog dialog(this, string(m_textCtrlAddress->GetValue())); + if (!dialog.ShowModal()) + return; + string strAddress = (string)dialog.GetAddress(); + if (strAddress != m_textCtrlAddress->GetValue()) + { + uint160 hash160; + if (!AddressToHash160(strAddress, hash160)) + return; + if (!mapPubKeys.count(hash160)) + return; + CWalletDB().WriteDefaultKey(mapPubKeys[hash160]); + m_textCtrlAddress->SetValue(strAddress); + } +} + +void CMainFrame::OnListItemActivatedAllTransactions(wxListEvent& event) +{ + uint256 hash((string)GetItemText(m_listCtrl, event.GetIndex(), 1)); + CWalletTx wtx; + CRITICAL_BLOCK(cs_mapWallet) + { + map::iterator mi = mapWallet.find(hash); + if (mi == mapWallet.end()) + { + printf("CMainFrame::OnListItemActivatedAllTransactions() : tx not found in mapWallet\n"); + return; + } + wtx = (*mi).second; + } + CTxDetailsDialog dialog(this, wtx); + dialog.ShowModal(); + //CTxDetailsDialog* pdialog = new CTxDetailsDialog(this, wtx); + //pdialog->Show(); +} + +void CMainFrame::OnListItemActivatedProductsSent(wxListEvent& event) +{ + CProduct& product = *(CProduct*)event.GetItem().GetData(); + CEditProductDialog* pdialog = new CEditProductDialog(this); + pdialog->SetProduct(product); + pdialog->Show(); +} + +void CMainFrame::OnListItemActivatedOrdersSent(wxListEvent& event) +{ + CWalletTx& order = *(CWalletTx*)event.GetItem().GetData(); + CViewOrderDialog* pdialog = new CViewOrderDialog(this, order, false); + pdialog->Show(); +} + +void CMainFrame::OnListItemActivatedOrdersReceived(wxListEvent& event) +{ + CWalletTx& order = *(CWalletTx*)event.GetItem().GetData(); + CViewOrderDialog* pdialog = new CViewOrderDialog(this, order, true); + pdialog->Show(); +} + + + + + + + +////////////////////////////////////////////////////////////////////////////// +// +// CTxDetailsDialog +// + +CTxDetailsDialog::CTxDetailsDialog(wxWindow* parent, CWalletTx wtx) : CTxDetailsDialogBase(parent) +{ + string strHTML; + strHTML.reserve(4000); + strHTML += ""; + + int64 nTime = wtx.GetTxTime(); + int64 nCredit = wtx.GetCredit(); + int64 nDebit = wtx.GetDebit(); + int64 nNet = nCredit - nDebit; + + + + strHTML += "Status: " + FormatTxStatus(wtx) + "
"; + strHTML += "Date: " + (nTime ? DateTimeStr(nTime) : "") + "
"; + + + // + // From + // + if (wtx.IsCoinBase()) + { + strHTML += "Source: Generated
"; + } + else if (!wtx.mapValue["from"].empty()) + { + // Online transaction + if (!wtx.mapValue["from"].empty()) + strHTML += "From: " + HtmlEscape(wtx.mapValue["from"]) + "
"; + } + else + { + // Offline transaction + if (nNet > 0) + { + // Credit + foreach(const CTxOut& txout, wtx.vout) + { + if (txout.IsMine()) + { + vector vchPubKey; + if (ExtractPubKey(txout.scriptPubKey, true, vchPubKey)) + { + string strAddress = PubKeyToAddress(vchPubKey); + if (mapAddressBook.count(strAddress)) + { + strHTML += "From: unknown
"; + strHTML += "To: "; + strHTML += HtmlEscape(strAddress); + if (!mapAddressBook[strAddress].empty()) + strHTML += " (yours, label: " + mapAddressBook[strAddress] + ")"; + else + strHTML += " (yours)"; + strHTML += "
"; + } + } + break; + } + } + } + } + + + // + // To + // + string strAddress; + if (!wtx.mapValue["to"].empty()) + { + // Online transaction + strAddress = wtx.mapValue["to"]; + strHTML += "To: "; + if (mapAddressBook.count(strAddress) && !mapAddressBook[strAddress].empty()) + strHTML += mapAddressBook[strAddress] + " "; + strHTML += HtmlEscape(strAddress) + "
"; + } + + + // + // Amount + // + if (wtx.IsCoinBase() && nCredit == 0) + { + // + // Coinbase + // + int64 nUnmatured = 0; + foreach(const CTxOut& txout, wtx.vout) + nUnmatured += txout.GetCredit(); + if (wtx.IsInMainChain()) + strHTML += strprintf("Credit: (%s matures in %d more blocks)
", FormatMoney(nUnmatured).c_str(), wtx.GetBlocksToMaturity()); + else + strHTML += "Credit: (not accepted)
"; + } + else if (nNet > 0) + { + // + // Credit + // + strHTML += "Credit: " + FormatMoney(nNet) + "
"; + } + else + { + bool fAllFromMe = true; + foreach(const CTxIn& txin, wtx.vin) + fAllFromMe = fAllFromMe && txin.IsMine(); + + bool fAllToMe = true; + foreach(const CTxOut& txout, wtx.vout) + fAllToMe = fAllToMe && txout.IsMine(); + + if (fAllFromMe) + { + // + // Debit + // + foreach(const CTxOut& txout, wtx.vout) + { + if (txout.IsMine()) + continue; + + if (wtx.mapValue["to"].empty()) + { + // Offline transaction + uint160 hash160; + if (ExtractHash160(txout.scriptPubKey, hash160)) + { + string strAddress = Hash160ToAddress(hash160); + strHTML += "To: "; + if (mapAddressBook.count(strAddress) && !mapAddressBook[strAddress].empty()) + strHTML += mapAddressBook[strAddress] + " "; + strHTML += strAddress; + strHTML += "
"; + } + } + + strHTML += "Debit: " + FormatMoney(-txout.nValue) + "
"; + } + + if (fAllToMe) + { + // Payment to self + int64 nValue = wtx.vout[0].nValue; + strHTML += "Debit: " + FormatMoney(-nValue) + "
"; + strHTML += "Credit: " + FormatMoney(nValue) + "
"; + } + + int64 nTxFee = nDebit - wtx.GetValueOut(); + if (nTxFee > 0) + strHTML += "Transaction fee: " + FormatMoney(-nTxFee) + "
"; + } + else + { + // + // Mixed debit transaction + // + foreach(const CTxIn& txin, wtx.vin) + if (txin.IsMine()) + strHTML += "Debit: " + FormatMoney(-txin.GetDebit()) + "
"; + foreach(const CTxOut& txout, wtx.vout) + if (txout.IsMine()) + strHTML += "Credit: " + FormatMoney(txout.GetCredit()) + "
"; + } + } + + strHTML += "Net amount: " + FormatMoney(nNet, true) + "
"; + + + // + // Message + // + if (!wtx.mapValue["message"].empty()) + strHTML += "
Message:
" + HtmlEscape(wtx.mapValue["message"], true) + "
"; + + if (wtx.IsCoinBase()) + strHTML += "
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.
"; + + + // + // Debug view + // + if (fDebug) + { + strHTML += "

debug print

"; + foreach(const CTxIn& txin, wtx.vin) + if (txin.IsMine()) + strHTML += "Debit: " + FormatMoney(-txin.GetDebit()) + "
"; + foreach(const CTxOut& txout, wtx.vout) + if (txout.IsMine()) + strHTML += "Credit: " + FormatMoney(txout.GetCredit()) + "
"; + + strHTML += "Inputs:
"; + CRITICAL_BLOCK(cs_mapWallet) + { + foreach(const CTxIn& txin, wtx.vin) + { + COutPoint prevout = txin.prevout; + map::iterator mi = mapWallet.find(prevout.hash); + if (mi != mapWallet.end()) + { + const CWalletTx& prev = (*mi).second; + if (prevout.n < prev.vout.size()) + { + strHTML += HtmlEscape(prev.ToString(), true); + strHTML += "    " + FormatTxStatus(prev) + ", "; + strHTML = strHTML + "IsMine=" + (prev.vout[prevout.n].IsMine() ? "true" : "false") + "
"; + } + } + } + } + + strHTML += "


Transaction:
"; + strHTML += HtmlEscape(wtx.ToString(), true); + } + + + + strHTML += "
"; + string(strHTML.begin(), strHTML.end()).swap(strHTML); + m_htmlWin->SetPage(strHTML); + m_buttonOK->SetFocus(); +} + +void CTxDetailsDialog::OnButtonOK(wxCommandEvent& event) +{ + Close(); + //Destroy(); +} + + + + + +////////////////////////////////////////////////////////////////////////////// +// +// COptionsDialog +// + +COptionsDialog::COptionsDialog(wxWindow* parent) : COptionsDialogBase(parent) +{ + m_textCtrlTransactionFee->SetValue(FormatMoney(nTransactionFee)); + m_buttonOK->SetFocus(); +} + +void COptionsDialog::OnKillFocusTransactionFee(wxFocusEvent& event) +{ + int64 nTmp = nTransactionFee; + ParseMoney(m_textCtrlTransactionFee->GetValue(), nTmp); + m_textCtrlTransactionFee->SetValue(FormatMoney(nTmp)); +} + +void COptionsDialog::OnButtonOK(wxCommandEvent& event) +{ + // nTransactionFee + int64 nPrevTransactionFee = nTransactionFee; + if (ParseMoney(m_textCtrlTransactionFee->GetValue(), nTransactionFee) && nTransactionFee != nPrevTransactionFee) + CWalletDB().WriteSetting("nTransactionFee", nTransactionFee); + + Close(); +} + +void COptionsDialog::OnButtonCancel(wxCommandEvent& event) +{ + Close(); +} + + + + + + +////////////////////////////////////////////////////////////////////////////// +// +// CAboutDialog +// + +CAboutDialog::CAboutDialog(wxWindow* parent) : CAboutDialogBase(parent) +{ + m_staticTextVersion->SetLabel(strprintf("version 0.%d.%d Alpha", VERSION/100, VERSION%100)); + + // Workaround until upgrade to wxWidgets supporting UTF-8 + wxString str = m_staticTextMain->GetLabel(); + if (str.Find('Â') != wxNOT_FOUND) + str.Remove(str.Find('Â'), 1); + m_staticTextMain->SetLabel(str); +} + +void CAboutDialog::OnButtonOK(wxCommandEvent& event) +{ + Close(); +} + + + + + + +////////////////////////////////////////////////////////////////////////////// +// +// CSendDialog +// + +CSendDialog::CSendDialog(wxWindow* parent, const wxString& strAddress) : CSendDialogBase(parent) +{ + // Init + m_textCtrlAddress->SetValue(strAddress); + m_choiceTransferType->SetSelection(0); + m_bitmapCheckMark->Show(false); + //// todo: should add a display of your balance for convenience + + // Set Icon + wxBitmap bmpSend(wxT("send16"), wxBITMAP_TYPE_RESOURCE); + bmpSend.SetMask(new wxMask(wxBitmap(wxT("send16masknoshadow"), wxBITMAP_TYPE_RESOURCE))); + wxIcon iconSend; + iconSend.CopyFromBitmap(bmpSend); + SetIcon(iconSend); + + wxCommandEvent event; + OnTextAddress(event); + + // Fixup the tab order + m_buttonPaste->MoveAfterInTabOrder(m_buttonCancel); + m_buttonAddress->MoveAfterInTabOrder(m_buttonPaste); + this->Layout(); +} + +void CSendDialog::OnTextAddress(wxCommandEvent& event) +{ + // Check mark + bool fBitcoinAddress = IsValidBitcoinAddress(m_textCtrlAddress->GetValue()); + m_bitmapCheckMark->Show(fBitcoinAddress); + + // Grey out message if bitcoin address + bool fEnable = !fBitcoinAddress; + m_staticTextFrom->Enable(fEnable); + m_textCtrlFrom->Enable(fEnable); + m_staticTextMessage->Enable(fEnable); + m_textCtrlMessage->Enable(fEnable); + m_textCtrlMessage->SetBackgroundColour(wxSystemSettings::GetColour(fEnable ? wxSYS_COLOUR_WINDOW : wxSYS_COLOUR_BTNFACE)); +} + +void CSendDialog::OnKillFocusAmount(wxFocusEvent& event) +{ + // Reformat the amount + 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(), true); + if (dialog.ShowModal()) + m_textCtrlAddress->SetValue(dialog.GetAddress()); +} + +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) +{ + 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 > GetBalance()) + { + wxMessageBox("Amount exceeds your balance ", "Send Coins"); + return; + } + if (nValue + nTransactionFee > 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) + { + // Send to bitcoin address + CScript scriptPubKey; + scriptPubKey << OP_DUP << OP_HASH160 << hash160 << OP_EQUALVERIFY << OP_CHECKSIG; + + if (!SendMoney(scriptPubKey, nValue, wtx)) + return; + + wxMessageBox("Payment sent ", "Sending..."); + } + else + { + // Parse IP address + CAddress addr(strAddress.c_str()); + if (addr.ip == 0) + { + wxMessageBox("Invalid address ", "Send Coins"); + return; + } + + // Message + wtx.mapValue["to"] = strAddress; + wtx.mapValue["from"] = m_textCtrlFrom->GetValue(); + wtx.mapValue["message"] = m_textCtrlMessage->GetValue(); + + // Send to IP address + CSendingDialog* pdialog = new CSendingDialog(this, addr, nValue, wtx); + if (!pdialog->ShowModal()) + return; + } + + if (!mapAddressBook.count(strAddress)) + 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(); + strStatus = ""; + fCanCancel = true; + fAbort = false; + fSuccess = false; + fUIDone = false; + fWorkDone = false; + + SetTitle(strprintf("Sending %s to %s...", FormatMoney(nPrice).c_str(), wtx.mapValue["to"].c_str())); + m_textCtrlStatus->SetValue(""); + + _beginthread(SendingDialogStartTransfer, 0, 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) +{ + if (strStatus.size() > 130) + m_textCtrlStatus->SetValue(string("\n") + strStatus); + else + m_textCtrlStatus->SetValue(string("\n\n") + strStatus); + 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()) + { + strStatus = "CANCELLED"; + m_buttonOK->Enable(true); + m_buttonOK->SetFocus(); + m_buttonCancel->Enable(false); + m_buttonCancel->SetLabel("Cancelled"); + Close(); + wxMessageBox("Transfer cancelled ", "Sending...", wxOK, this); + } + event.Skip(); + + /// debug test + if (fRandSendTest && fWorkDone && fSuccess) + { + Close(); + Sleep(1000); + RandSend(); + } +} + + +// +// 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; + AddPendingEvent(event); +} + +bool CSendingDialog::Status() +{ + if (fUIDone) + { + Destroy(); + return false; + } + if (fAbort && fCanCancel) + { + strStatus = "CANCELLED"; + Repaint(); + fWorkDone = true; + return false; + } + return true; +} + +bool CSendingDialog::Status(const string& str) +{ + if (!Status()) + return false; + strStatus = str; + 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 > GetBalance()) + { + Error("You don't have enough money"); + return; + } + + // We may have connected already for product details + if (!Status("Connecting...")) + return; + CNode* pnode = ConnectNode(addr, 5 * 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; + vRecv >> strMessage; + 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; + } + + // Should already be connected + CNode* pnode = ConnectNode(addr, 5 * 60); + if (!pnode) + { + Error("Lost connection"); + 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 > GetBalance()) + { + Error("You don't have enough money"); + return; + } + int64 nFeeRequired; + if (!CreateTransaction(scriptPubKey, nPrice, wtx, nFeeRequired)) + { + if (nPrice + nFeeRequired > GetBalance()) + Error(strprintf("This is an oversized transaction that requires a transaction fee of %s", FormatMoney(nFeeRequired).c_str())); + else + Error("Transaction creation failed"); + 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 (!CommitTransactionSpent(wtx)) + { + Error("Error finalizing payment"); + return; + } + + // Send payment tx to seller, with response going to OnReply3 via event handler + pnode->PushRequest("submitorder", wtx, SendingDialogOnReply3, this); + + // Accept and broadcast transaction + if (!wtx.AcceptTransaction()) + printf("ERROR: CSendingDialog : wtxNew.AcceptTransaction() %s failed\n", wtx.GetHash().ToString().c_str()); + wtx.RelayWalletTransaction(); + + 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 if it is valid,\n" + "but without comment information."); + 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"); +} + + + + + + +////////////////////////////////////////////////////////////////////////////// +// +// CYourAddressDialog +// + +CYourAddressDialog::CYourAddressDialog(wxWindow* parent, const string& strInitSelected) : CYourAddressDialogBase(parent) +{ + // Init column headers + m_listCtrl->InsertColumn(0, "Label", wxLIST_FORMAT_LEFT, 200); + m_listCtrl->InsertColumn(1, "Bitcoin Address", wxLIST_FORMAT_LEFT, 350); + m_listCtrl->SetFocus(); + + // Fill listctrl with address book data + CRITICAL_BLOCK(cs_mapKeys) + { + foreach(const PAIRTYPE(string, string)& item, mapAddressBook) + { + string strAddress = item.first; + string strName = item.second; + uint160 hash160; + bool fMine = (AddressToHash160(strAddress, hash160) && mapPubKeys.count(hash160)); + if (fMine) + { + int nIndex = InsertLine(m_listCtrl, strName, strAddress); + if (strAddress == strInitSelected) + m_listCtrl->SetItemState(nIndex, wxLIST_STATE_SELECTED|wxLIST_STATE_FOCUSED, wxLIST_STATE_SELECTED|wxLIST_STATE_FOCUSED); + } + } + } +} + +wxString CYourAddressDialog::GetAddress() +{ + int nIndex = GetSelection(m_listCtrl); + if (nIndex == -1) + return ""; + return GetItemText(m_listCtrl, nIndex, 1); +} + +void CYourAddressDialog::OnListEndLabelEdit(wxListEvent& event) +{ + // Update address book with edited name + if (event.IsEditCancelled()) + return; + string strAddress = (string)GetItemText(m_listCtrl, event.GetIndex(), 1); + SetAddressBookName(strAddress, string(event.GetText())); + pframeMain->RefreshListCtrl(); +} + +void CYourAddressDialog::OnListItemSelected(wxListEvent& event) +{ +} + +void CYourAddressDialog::OnListItemActivated(wxListEvent& event) +{ + // Doubleclick edits item + wxCommandEvent event2; + OnButtonRename(event2); +} + +void CYourAddressDialog::OnButtonRename(wxCommandEvent& event) +{ + // Ask new name + int nIndex = GetSelection(m_listCtrl); + if (nIndex == -1) + return; + string strName = (string)m_listCtrl->GetItemText(nIndex); + string strAddress = (string)GetItemText(m_listCtrl, nIndex, 1); + CGetTextFromUserDialog dialog(this, "Edit Address Label", "New Label", strName); + if (!dialog.ShowModal()) + return; + strName = dialog.GetValue(); + + // Change name + SetAddressBookName(strAddress, strName); + m_listCtrl->SetItemText(nIndex, strName); + pframeMain->RefreshListCtrl(); +} + +void CYourAddressDialog::OnButtonNew(wxCommandEvent& event) +{ + // Ask name + CGetTextFromUserDialog dialog(this, "New Bitcoin Address", "Label", ""); + if (!dialog.ShowModal()) + return; + string strName = dialog.GetValue(); + + // Generate new key + string strAddress = PubKeyToAddress(GenerateNewKey()); + SetAddressBookName(strAddress, strName); + + // Add to list and select it + int nIndex = InsertLine(m_listCtrl, strName, strAddress); + SetSelection(m_listCtrl, nIndex); + m_listCtrl->SetFocus(); +} + +void CYourAddressDialog::OnButtonCopy(wxCommandEvent& event) +{ + // Copy address box to clipboard + if (wxTheClipboard->Open()) + { + wxTheClipboard->SetData(new wxTextDataObject(GetAddress())); + wxTheClipboard->Close(); + } +} + +void CYourAddressDialog::OnButtonOK(wxCommandEvent& event) +{ + // OK + EndModal(true); +} + +void CYourAddressDialog::OnButtonCancel(wxCommandEvent& event) +{ + // Cancel + EndModal(false); +} + +void CYourAddressDialog::OnClose(wxCloseEvent& event) +{ + // Close + EndModal(false); +} + + + + + + +////////////////////////////////////////////////////////////////////////////// +// +// CAddressBookDialog +// + +CAddressBookDialog::CAddressBookDialog(wxWindow* parent, const wxString& strInitSelected, bool fSendingIn) : CAddressBookDialogBase(parent) +{ + fSending = fSendingIn; + if (!fSending) + m_buttonCancel->Show(false); + + // Init column headers + m_listCtrl->InsertColumn(0, "Name", wxLIST_FORMAT_LEFT, 200); + m_listCtrl->InsertColumn(1, "Address", wxLIST_FORMAT_LEFT, 350); + m_listCtrl->SetFocus(); + + // Set Icon + wxBitmap bmpAddressBook(wxT("addressbook16"), wxBITMAP_TYPE_RESOURCE); + bmpAddressBook.SetMask(new wxMask(wxBitmap(wxT("addressbook16mask"), wxBITMAP_TYPE_RESOURCE))); + wxIcon iconAddressBook; + iconAddressBook.CopyFromBitmap(bmpAddressBook); + SetIcon(iconAddressBook); + + // Fill listctrl with address book data + CRITICAL_BLOCK(cs_mapKeys) + { + foreach(const PAIRTYPE(string, string)& item, mapAddressBook) + { + string strAddress = item.first; + string strName = item.second; + uint160 hash160; + bool fMine = (AddressToHash160(strAddress, hash160) && mapPubKeys.count(hash160)); + if (!fMine) + { + int nIndex = InsertLine(m_listCtrl, strName, strAddress); + if (strAddress == strInitSelected) + m_listCtrl->SetItemState(nIndex, wxLIST_STATE_SELECTED|wxLIST_STATE_FOCUSED, wxLIST_STATE_SELECTED|wxLIST_STATE_FOCUSED); + } + } + } +} + +wxString CAddressBookDialog::GetAddress() +{ + int nIndex = GetSelection(m_listCtrl); + if (nIndex == -1) + return ""; + return GetItemText(m_listCtrl, nIndex, 1); +} + +void CAddressBookDialog::OnListEndLabelEdit(wxListEvent& event) +{ + // Update address book with edited name + if (event.IsEditCancelled()) + return; + string strAddress = (string)GetItemText(m_listCtrl, event.GetIndex(), 1); + SetAddressBookName(strAddress, string(event.GetText())); + pframeMain->RefreshListCtrl(); +} + +void CAddressBookDialog::OnListItemSelected(wxListEvent& event) +{ +} + +void CAddressBookDialog::OnListItemActivated(wxListEvent& event) +{ + if (fSending) + { + // Doubleclick returns selection + EndModal(GetAddress() != "" ? 2 : 0); + } + else + { + // Doubleclick edits item + wxCommandEvent event2; + OnButtonEdit(event2); + } +} + +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) +{ + // Ask new name + 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; + 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")); + + // Change name + if (strAddress != strAddressOrg) + CWalletDB().EraseName(strAddressOrg); + SetAddressBookName(strAddress, strName); + m_listCtrl->SetItem(nIndex, 1, strAddress); + m_listCtrl->SetItemText(nIndex, strName); + pframeMain->RefreshListCtrl(); +} + +void CAddressBookDialog::OnButtonNew(wxCommandEvent& event) +{ + // Ask name + string strName; + string strAddress; + do + { + CGetTextFromUserDialog dialog(this, "New Address", "Name", strName, "Address", strAddress); + if (!dialog.ShowModal()) + return; + strName = dialog.GetValue1(); + strAddress = dialog.GetValue2(); + } + while (CheckIfMine(strAddress, "New Address")); + + // Add to list and select it + SetAddressBookName(strAddress, strName); + int nIndex = InsertLine(m_listCtrl, strName, strAddress); + SetSelection(m_listCtrl, nIndex); + m_listCtrl->SetFocus(); + pframeMain->RefreshListCtrl(); +} + +void CAddressBookDialog::OnButtonDelete(wxCommandEvent& event) +{ + 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); + CWalletDB().EraseName(strAddress); + m_listCtrl->DeleteItem(nIndex); + } + } + pframeMain->RefreshListCtrl(); +} + +void CAddressBookDialog::OnButtonCopy(wxCommandEvent& event) +{ + // Copy address box to clipboard + if (wxTheClipboard->Open()) + { + wxTheClipboard->SetData(new wxTextDataObject(GetAddress())); + wxTheClipboard->Close(); + } +} + +void CAddressBookDialog::OnButtonOK(wxCommandEvent& event) +{ + // OK + EndModal(GetAddress() != "" ? 1 : 0); +} + +void CAddressBookDialog::OnButtonCancel(wxCommandEvent& event) +{ + // Cancel + EndModal(0); +} + +void CAddressBookDialog::OnClose(wxCloseEvent& event) +{ + // Close + EndModal(0); +} + + + + + + +////////////////////////////////////////////////////////////////////////////// +// +// CProductsDialog +// + +bool CompareIntStringPairBestFirst(const pair& item1, const pair& item2) +{ + return (item1.first > item2.first); +} + +CProductsDialog::CProductsDialog(wxWindow* parent) : CProductsDialogBase(parent) +{ + // Init column headers + m_listCtrl->InsertColumn(0, "Title", wxLIST_FORMAT_LEFT, 200); + m_listCtrl->InsertColumn(1, "Price", wxLIST_FORMAT_LEFT, 80); + m_listCtrl->InsertColumn(2, "Seller", wxLIST_FORMAT_LEFT, 80); + m_listCtrl->InsertColumn(3, "Stars", wxLIST_FORMAT_LEFT, 50); + m_listCtrl->InsertColumn(4, "Power", wxLIST_FORMAT_LEFT, 50); + + // Tally top categories + map mapTopCategories; + CRITICAL_BLOCK(cs_mapProducts) + for (map::iterator mi = mapProducts.begin(); mi != mapProducts.end(); ++mi) + mapTopCategories[(*mi).second.mapValue["category"]]++; + + // Sort top categories + vector > vTopCategories; + for (map::iterator mi = mapTopCategories.begin(); mi != mapTopCategories.end(); ++mi) + vTopCategories.push_back(make_pair((*mi).second, (*mi).first)); + sort(vTopCategories.begin(), vTopCategories.end(), CompareIntStringPairBestFirst); + + // Fill categories combo box + int nLimit = 250; + for (vector >::iterator it = vTopCategories.begin(); it != vTopCategories.end() && nLimit-- > 0; ++it) + m_comboBoxCategory->Append((*it).second); + + // Fill window with initial search + //wxCommandEvent event; + //OnButtonSearch(event); +} + +void CProductsDialog::OnCombobox(wxCommandEvent& event) +{ + OnButtonSearch(event); +} + +bool CompareProductsBestFirst(const CProduct* p1, const CProduct* p2) +{ + return (p1->nAtoms > p2->nAtoms); +} + +void CProductsDialog::OnButtonSearch(wxCommandEvent& event) +{ + string strCategory = (string)m_comboBoxCategory->GetValue(); + string strSearch = (string)m_textCtrlSearch->GetValue(); + + // Search products + vector vProductsFound; + CRITICAL_BLOCK(cs_mapProducts) + { + for (map::iterator mi = mapProducts.begin(); mi != mapProducts.end(); ++mi) + { + CProduct& product = (*mi).second; + if (product.mapValue["category"].find(strCategory) != -1) + { + if (product.mapValue["title"].find(strSearch) != -1 || + product.mapValue["description"].find(strSearch) != -1 || + product.mapValue["seller"].find(strSearch) != -1) + { + vProductsFound.push_back(&product); + } + } + } + } + + // Sort + sort(vProductsFound.begin(), vProductsFound.end(), CompareProductsBestFirst); + + // Display + foreach(CProduct* pproduct, vProductsFound) + { + InsertLine(m_listCtrl, + pproduct->mapValue["title"], + pproduct->mapValue["price"], + pproduct->mapValue["seller"], + pproduct->mapValue["stars"], + itostr(pproduct->nAtoms)); + } +} + +void CProductsDialog::OnListItemActivated(wxListEvent& event) +{ + // Doubleclick opens product + CViewProductDialog* pdialog = new CViewProductDialog(this, m_vProduct[event.GetIndex()]); + pdialog->Show(); +} + + + + + + + +////////////////////////////////////////////////////////////////////////////// +// +// CEditProductDialog +// + +CEditProductDialog::CEditProductDialog(wxWindow* parent) : CEditProductDialogBase(parent) +{ + m_textCtrlLabel[0 ] = m_textCtrlLabel0; + m_textCtrlLabel[1 ] = m_textCtrlLabel1; + m_textCtrlLabel[2 ] = m_textCtrlLabel2; + m_textCtrlLabel[3 ] = m_textCtrlLabel3; + m_textCtrlLabel[4 ] = m_textCtrlLabel4; + m_textCtrlLabel[5 ] = m_textCtrlLabel5; + m_textCtrlLabel[6 ] = m_textCtrlLabel6; + m_textCtrlLabel[7 ] = m_textCtrlLabel7; + m_textCtrlLabel[8 ] = m_textCtrlLabel8; + m_textCtrlLabel[9 ] = m_textCtrlLabel9; + m_textCtrlLabel[10] = m_textCtrlLabel10; + m_textCtrlLabel[11] = m_textCtrlLabel11; + m_textCtrlLabel[12] = m_textCtrlLabel12; + m_textCtrlLabel[13] = m_textCtrlLabel13; + m_textCtrlLabel[14] = m_textCtrlLabel14; + m_textCtrlLabel[15] = m_textCtrlLabel15; + m_textCtrlLabel[16] = m_textCtrlLabel16; + m_textCtrlLabel[17] = m_textCtrlLabel17; + m_textCtrlLabel[18] = m_textCtrlLabel18; + m_textCtrlLabel[19] = m_textCtrlLabel19; + + m_textCtrlField[0 ] = m_textCtrlField0; + m_textCtrlField[1 ] = m_textCtrlField1; + m_textCtrlField[2 ] = m_textCtrlField2; + m_textCtrlField[3 ] = m_textCtrlField3; + m_textCtrlField[4 ] = m_textCtrlField4; + m_textCtrlField[5 ] = m_textCtrlField5; + m_textCtrlField[6 ] = m_textCtrlField6; + m_textCtrlField[7 ] = m_textCtrlField7; + m_textCtrlField[8 ] = m_textCtrlField8; + m_textCtrlField[9 ] = m_textCtrlField9; + m_textCtrlField[10] = m_textCtrlField10; + m_textCtrlField[11] = m_textCtrlField11; + m_textCtrlField[12] = m_textCtrlField12; + m_textCtrlField[13] = m_textCtrlField13; + m_textCtrlField[14] = m_textCtrlField14; + m_textCtrlField[15] = m_textCtrlField15; + m_textCtrlField[16] = m_textCtrlField16; + m_textCtrlField[17] = m_textCtrlField17; + m_textCtrlField[18] = m_textCtrlField18; + m_textCtrlField[19] = m_textCtrlField19; + + m_buttonDel[0 ] = m_buttonDel0; + m_buttonDel[1 ] = m_buttonDel1; + m_buttonDel[2 ] = m_buttonDel2; + m_buttonDel[3 ] = m_buttonDel3; + m_buttonDel[4 ] = m_buttonDel4; + m_buttonDel[5 ] = m_buttonDel5; + m_buttonDel[6 ] = m_buttonDel6; + m_buttonDel[7 ] = m_buttonDel7; + m_buttonDel[8 ] = m_buttonDel8; + m_buttonDel[9 ] = m_buttonDel9; + m_buttonDel[10] = m_buttonDel10; + m_buttonDel[11] = m_buttonDel11; + m_buttonDel[12] = m_buttonDel12; + m_buttonDel[13] = m_buttonDel13; + m_buttonDel[14] = m_buttonDel14; + m_buttonDel[15] = m_buttonDel15; + m_buttonDel[16] = m_buttonDel16; + m_buttonDel[17] = m_buttonDel17; + m_buttonDel[18] = m_buttonDel18; + m_buttonDel[19] = m_buttonDel19; + + for (int i = 1; i < FIELDS_MAX; i++) + ShowLine(i, false); + + LayoutAll(); +} + +void CEditProductDialog::LayoutAll() +{ + m_scrolledWindow->Layout(); + m_scrolledWindow->GetSizer()->Fit(m_scrolledWindow); + this->Layout(); +} + +void CEditProductDialog::ShowLine(int i, bool fShow) +{ + m_textCtrlLabel[i]->Show(fShow); + m_textCtrlField[i]->Show(fShow); + m_buttonDel[i]->Show(fShow); +} + +void CEditProductDialog::OnButtonDel0(wxCommandEvent& event) { OnButtonDel(event, 0); } +void CEditProductDialog::OnButtonDel1(wxCommandEvent& event) { OnButtonDel(event, 1); } +void CEditProductDialog::OnButtonDel2(wxCommandEvent& event) { OnButtonDel(event, 2); } +void CEditProductDialog::OnButtonDel3(wxCommandEvent& event) { OnButtonDel(event, 3); } +void CEditProductDialog::OnButtonDel4(wxCommandEvent& event) { OnButtonDel(event, 4); } +void CEditProductDialog::OnButtonDel5(wxCommandEvent& event) { OnButtonDel(event, 5); } +void CEditProductDialog::OnButtonDel6(wxCommandEvent& event) { OnButtonDel(event, 6); } +void CEditProductDialog::OnButtonDel7(wxCommandEvent& event) { OnButtonDel(event, 7); } +void CEditProductDialog::OnButtonDel8(wxCommandEvent& event) { OnButtonDel(event, 8); } +void CEditProductDialog::OnButtonDel9(wxCommandEvent& event) { OnButtonDel(event, 9); } +void CEditProductDialog::OnButtonDel10(wxCommandEvent& event) { OnButtonDel(event, 10); } +void CEditProductDialog::OnButtonDel11(wxCommandEvent& event) { OnButtonDel(event, 11); } +void CEditProductDialog::OnButtonDel12(wxCommandEvent& event) { OnButtonDel(event, 12); } +void CEditProductDialog::OnButtonDel13(wxCommandEvent& event) { OnButtonDel(event, 13); } +void CEditProductDialog::OnButtonDel14(wxCommandEvent& event) { OnButtonDel(event, 14); } +void CEditProductDialog::OnButtonDel15(wxCommandEvent& event) { OnButtonDel(event, 15); } +void CEditProductDialog::OnButtonDel16(wxCommandEvent& event) { OnButtonDel(event, 16); } +void CEditProductDialog::OnButtonDel17(wxCommandEvent& event) { OnButtonDel(event, 17); } +void CEditProductDialog::OnButtonDel18(wxCommandEvent& event) { OnButtonDel(event, 18); } +void CEditProductDialog::OnButtonDel19(wxCommandEvent& event) { OnButtonDel(event, 19); } + +void CEditProductDialog::OnButtonDel(wxCommandEvent& event, int n) +{ + Freeze(); + int x, y; + m_scrolledWindow->GetViewStart(&x, &y); + int i; + for (i = n; i < FIELDS_MAX-1; i++) + { + m_textCtrlLabel[i]->SetValue(m_textCtrlLabel[i+1]->GetValue()); + m_textCtrlField[i]->SetValue(m_textCtrlField[i+1]->GetValue()); + if (!m_buttonDel[i+1]->IsShown()) + break; + } + m_textCtrlLabel[i]->SetValue(""); + m_textCtrlField[i]->SetValue(""); + ShowLine(i, false); + m_buttonAddField->Enable(true); + LayoutAll(); + m_scrolledWindow->Scroll(0, y); + Thaw(); +} + +void CEditProductDialog::OnButtonAddField(wxCommandEvent& event) +{ + for (int i = 0; i < FIELDS_MAX; i++) + { + if (!m_buttonDel[i]->IsShown()) + { + Freeze(); + ShowLine(i, true); + if (i == FIELDS_MAX-1) + m_buttonAddField->Enable(false); + LayoutAll(); + m_scrolledWindow->Scroll(0, 99999); + Thaw(); + break; + } + } +} + +void CEditProductDialog::OnButtonSend(wxCommandEvent& event) +{ + CProduct product; + GetProduct(product); + + // Sign the detailed product + product.vchPubKeyFrom = keyUser.GetPubKey(); + if (!keyUser.Sign(product.GetSigHash(), product.vchSig)) + { + wxMessageBox("Error digitally signing the product "); + return; + } + + // Save detailed product + AddToMyProducts(product); + + // Strip down to summary product + product.mapDetails.clear(); + product.vOrderForm.clear(); + + // Sign the summary product + if (!keyUser.Sign(product.GetSigHash(), product.vchSig)) + { + wxMessageBox("Error digitally signing the product "); + return; + } + + // Verify + if (!product.CheckProduct()) + { + wxMessageBox("Errors found in product "); + return; + } + + // Broadcast + AdvertStartPublish(pnodeLocalHost, MSG_PRODUCT, 0, product); + + Destroy(); +} + +void CEditProductDialog::OnButtonPreview(wxCommandEvent& event) +{ + CProduct product; + GetProduct(product); + CViewProductDialog* pdialog = new CViewProductDialog(this, product); + pdialog->Show(); +} + +void CEditProductDialog::OnButtonCancel(wxCommandEvent& event) +{ + Destroy(); +} + +void CEditProductDialog::SetProduct(const CProduct& productIn) +{ + CProduct product = productIn; + + m_comboBoxCategory->SetValue(product.mapValue["category"]); + m_textCtrlTitle->SetValue(product.mapValue["title"]); + m_textCtrlPrice->SetValue(product.mapValue["price"]); + m_textCtrlDescription->SetValue(product.mapValue["description"]); + m_textCtrlInstructions->SetValue(product.mapValue["instructions"]); + + for (int i = 0; i < FIELDS_MAX; i++) + { + bool fUsed = i < product.vOrderForm.size(); + m_buttonDel[i]->Show(fUsed); + m_textCtrlLabel[i]->Show(fUsed); + m_textCtrlField[i]->Show(fUsed); + if (!fUsed) + continue; + + m_textCtrlLabel[i]->SetValue(product.vOrderForm[i].first); + string strControl = product.vOrderForm[i].second; + if (strControl.substr(0, 5) == "text=") + m_textCtrlField[i]->SetValue(""); + else if (strControl.substr(0, 7) == "choice=") + m_textCtrlField[i]->SetValue(strControl.substr(7)); + else + m_textCtrlField[i]->SetValue(strControl); + } +} + +void CEditProductDialog::GetProduct(CProduct& product) +{ + // map mapValue; + // vector > vOrderForm; + + product.mapValue["category"] = m_comboBoxCategory->GetValue().Trim(); + product.mapValue["title"] = m_textCtrlTitle->GetValue().Trim(); + product.mapValue["price"] = m_textCtrlPrice->GetValue().Trim(); + product.mapValue["description"] = m_textCtrlDescription->GetValue().Trim(); + product.mapValue["instructions"] = m_textCtrlInstructions->GetValue().Trim(); + + for (int i = 0; i < FIELDS_MAX; i++) + { + if (m_buttonDel[i]->IsShown()) + { + string strLabel = (string)m_textCtrlLabel[i]->GetValue().Trim(); + string strControl = (string)m_textCtrlField[i]->GetValue(); + if (strControl.empty()) + strControl = "text="; + else + strControl = "choice=" + strControl; + product.vOrderForm.push_back(make_pair(strLabel, strControl)); + } + } +} + + + + + + + +////////////////////////////////////////////////////////////////////////////// +// +// CViewProductDialog +// + +CViewProductDialog::CViewProductDialog(wxWindow* parent, const CProduct& productIn) : CViewProductDialogBase(parent) +{ + Connect(wxEVT_REPLY1, wxCommandEventHandler(CViewProductDialog::OnReply1), NULL, this); + AddCallbackAvailable(GetEventHandler()); + + // Fill display with product summary while waiting for details + product = productIn; + UpdateProductDisplay(false); + + m_buttonBack->Enable(false); + m_buttonNext->Enable(!product.vOrderForm.empty()); + m_htmlWinReviews->Show(true); + m_scrolledWindow->Show(false); + this->Layout(); + + // Request details from seller + _beginthread(ThreadRequestProductDetails, 0, new pair(product, GetEventHandler())); +} + +CViewProductDialog::~CViewProductDialog() +{ + RemoveCallbackAvailable(GetEventHandler()); +} + +void ThreadRequestProductDetails(void* parg) +{ + // Extract parameters + pair* pitem = (pair*)parg; + CProduct product = pitem->first; + wxEvtHandler* pevthandler = pitem->second; + delete pitem; + + // Connect to seller + CNode* pnode = ConnectNode(product.addr, 5 * 60); + if (!pnode) + { + CDataStream ssEmpty; + AddPendingReplyEvent1(pevthandler, ssEmpty); + return; + } + + // Request detailed product, with response going to OnReply1 via dialog's event handler + pnode->PushRequest("getdetails", product.GetHash(), AddPendingReplyEvent1, (void*)pevthandler); +} + +void CViewProductDialog::OnReply1(wxCommandEvent& event) +{ + CDataStream ss = GetStreamFromEvent(event); + if (ss.empty()) + { + product.mapValue["description"] = "-- CAN'T CONNECT TO SELLER --\n"; + UpdateProductDisplay(true); + return; + } + + int nRet; + CProduct product2; + try + { + ss >> nRet; + if (nRet > 0) + throw false; + ss >> product2; + if (product2.GetHash() != product.GetHash()) + throw false; + if (!product2.CheckSignature()) + throw false; + } + catch (...) + { + product.mapValue["description"] = "-- INVALID RESPONSE --\n"; + UpdateProductDisplay(true); + return; + } + + product = product2; + UpdateProductDisplay(true); +} + +bool CompareReviewsBestFirst(const CReview* p1, const CReview* p2) +{ + return (p1->nAtoms > p2->nAtoms); +} + +void CViewProductDialog::UpdateProductDisplay(bool fDetails) +{ + // Product and reviews + string strHTML; + strHTML.reserve(4000); + strHTML += "\n" + "\n" + "\n" + "\n" + "\n"; + strHTML += "Category: " + HtmlEscape(product.mapValue["category"]) + "
\n"; + strHTML += "Title: " + HtmlEscape(product.mapValue["title"]) + "
\n"; + strHTML += "Price: " + HtmlEscape(product.mapValue["price"]) + "
\n"; + + if (!fDetails) + strHTML += "Loading details...
\n
\n"; + else + strHTML += HtmlEscape(product.mapValue["description"], true) + "
\n
\n"; + + strHTML += "Reviews:
\n
\n"; + + if (!product.vchPubKeyFrom.empty()) + { + CReviewDB reviewdb("r"); + + // Get reviews + vector vReviews; + reviewdb.ReadReviews(product.GetUserHash(), vReviews); + + // Get reviewer's number of atoms + vector vSortedReviews; + vSortedReviews.reserve(vReviews.size()); + for (vector::reverse_iterator it = vReviews.rbegin(); it != vReviews.rend(); ++it) + { + CReview& review = *it; + CUser user; + reviewdb.ReadUser(review.GetUserHash(), user); + review.nAtoms = user.GetAtomCount(); + vSortedReviews.push_back(&review); + } + + reviewdb.Close(); + + // Sort + stable_sort(vSortedReviews.begin(), vSortedReviews.end(), CompareReviewsBestFirst); + + // Format reviews + foreach(CReview* preview, vSortedReviews) + { + CReview& review = *preview; + int nStars = atoi(review.mapValue["stars"].c_str()); + if (nStars < 1 || nStars > 5) + continue; + + strHTML += "" + itostr(nStars) + (nStars == 1 ? " star" : " stars") + ""; + strHTML += "     "; + strHTML += DateStr(atoi64(review.mapValue["date"])) + "
\n"; + strHTML += HtmlEscape(review.mapValue["review"], true); + strHTML += "
\n
\n"; + } + } + + strHTML += "\n\n"; + + // Shrink capacity to fit + string(strHTML.begin(), strHTML.end()).swap(strHTML); + + m_htmlWinReviews->SetPage(strHTML); + + ///// need to find some other indicator to use so can allow empty order form + if (product.vOrderForm.empty()) + return; + + // Order form + m_staticTextInstructions->SetLabel(product.mapValue["instructions"]); + for (int i = 0; i < FIELDS_MAX; i++) + { + m_staticTextLabel[i] = NULL; + m_textCtrlField[i] = NULL; + m_choiceField[i] = NULL; + } + + // Construct flexgridsizer + wxBoxSizer* bSizer21 = (wxBoxSizer*)m_scrolledWindow->GetSizer(); + wxFlexGridSizer* fgSizer; + fgSizer = new wxFlexGridSizer(0, 2, 0, 0); + fgSizer->AddGrowableCol(1); + fgSizer->SetFlexibleDirection(wxBOTH); + fgSizer->SetNonFlexibleGrowMode(wxFLEX_GROWMODE_SPECIFIED); + + // Construct order form fields + wxWindow* windowLast = NULL; + for (int i = 0; i < product.vOrderForm.size(); i++) + { + string strLabel = product.vOrderForm[i].first; + string strControl = product.vOrderForm[i].second; + + if (strLabel.size() < 20) + strLabel.insert(strLabel.begin(), 20 - strLabel.size(), ' '); + + m_staticTextLabel[i] = new wxStaticText(m_scrolledWindow, wxID_ANY, strLabel, wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT); + m_staticTextLabel[i]->Wrap(-1); + fgSizer->Add(m_staticTextLabel[i], 0, wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxALL, 5); + + if (strControl.substr(0, 5) == "text=") + { + m_textCtrlField[i] = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0); + fgSizer->Add(m_textCtrlField[i], 1, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5); + windowLast = m_textCtrlField[i]; + } + else if (strControl.substr(0, 7) == "choice=") + { + vector vChoices; + ParseString(strControl.substr(7), ',', vChoices); + + wxArrayString arraystring; + foreach(const string& str, vChoices) + arraystring.Add(str); + + m_choiceField[i] = new wxChoice(m_scrolledWindow, wxID_ANY, wxDefaultPosition, wxDefaultSize, arraystring, 0); + fgSizer->Add(m_choiceField[i], 0, wxALL|wxALIGN_CENTER_VERTICAL, 5); + windowLast = m_choiceField[i]; + } + else + { + m_textCtrlField[i] = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0); + fgSizer->Add(m_textCtrlField[i], 1, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5); + m_staticTextLabel[i]->Show(false); + m_textCtrlField[i]->Show(false); + } + } + + // Insert after instructions and before submit/cancel buttons + bSizer21->Insert(2, fgSizer, 0, wxEXPAND|wxRIGHT|wxLEFT, 5); + m_scrolledWindow->Layout(); + bSizer21->Fit(m_scrolledWindow); + this->Layout(); + + // Fixup the tab order + m_buttonSubmitForm->MoveAfterInTabOrder(windowLast); + m_buttonCancelForm->MoveAfterInTabOrder(m_buttonSubmitForm); + //m_buttonBack->MoveAfterInTabOrder(m_buttonCancelForm); + //m_buttonNext->MoveAfterInTabOrder(m_buttonBack); + //m_buttonCancel->MoveAfterInTabOrder(m_buttonNext); + this->Layout(); +} + +void CViewProductDialog::GetOrder(CWalletTx& wtx) +{ + wtx.SetNull(); + for (int i = 0; i < product.vOrderForm.size(); i++) + { + string strValue; + if (m_textCtrlField[i]) + strValue = m_textCtrlField[i]->GetValue().Trim(); + else + strValue = m_choiceField[i]->GetStringSelection(); + wtx.vOrderForm.push_back(make_pair(m_staticTextLabel[i]->GetLabel(), strValue)); + } +} + +void CViewProductDialog::OnButtonSubmitForm(wxCommandEvent& event) +{ + m_buttonSubmitForm->Enable(false); + m_buttonCancelForm->Enable(false); + + CWalletTx wtx; + GetOrder(wtx); + + CSendingDialog* pdialog = new CSendingDialog(this, product.addr, atoi64(product.mapValue["price"]), wtx); + if (!pdialog->ShowModal()) + { + m_buttonSubmitForm->Enable(true); + m_buttonCancelForm->Enable(true); + return; + } +} + +void CViewProductDialog::OnButtonCancelForm(wxCommandEvent& event) +{ + Destroy(); +} + +void CViewProductDialog::OnButtonBack(wxCommandEvent& event) +{ + Freeze(); + m_htmlWinReviews->Show(true); + m_scrolledWindow->Show(false); + m_buttonBack->Enable(false); + m_buttonNext->Enable(!product.vOrderForm.empty()); + this->Layout(); + Thaw(); +} + +void CViewProductDialog::OnButtonNext(wxCommandEvent& event) +{ + if (!product.vOrderForm.empty()) + { + Freeze(); + m_htmlWinReviews->Show(false); + m_scrolledWindow->Show(true); + m_buttonBack->Enable(true); + m_buttonNext->Enable(false); + this->Layout(); + Thaw(); + } +} + +void CViewProductDialog::OnButtonCancel(wxCommandEvent& event) +{ + Destroy(); +} + + + + + + + +////////////////////////////////////////////////////////////////////////////// +// +// CViewOrderDialog +// + +CViewOrderDialog::CViewOrderDialog(wxWindow* parent, CWalletTx order, bool fReceived) : CViewOrderDialogBase(parent) +{ + int64 nPrice = (fReceived ? order.GetCredit() : order.GetDebit()); + + string strHTML; + strHTML.reserve(4000); + strHTML += "\n" + "\n" + "\n" + "\n" + "\n"; + strHTML += "Time: " + HtmlEscape(DateTimeStr(order.nTimeReceived)) + "
\n"; + strHTML += "Price: " + HtmlEscape(FormatMoney(nPrice)) + "
\n"; + strHTML += "Status: " + HtmlEscape(FormatTxStatus(order)) + "
\n"; + + strHTML += "\n"; + for (int i = 0; i < order.vOrderForm.size(); i++) + { + strHTML += " "; + strHTML += "\n"; + } + strHTML += "
" + HtmlEscape(order.vOrderForm[i].first) + ":" + HtmlEscape(order.vOrderForm[i].second) + "
\n"; + + strHTML += "\n\n"; + + // Shrink capacity to fit + // (strings are ref counted, so it may live on in SetPage) + string(strHTML.begin(), strHTML.end()).swap(strHTML); + + m_htmlWin->SetPage(strHTML); +} + +void CViewOrderDialog::OnButtonOK(wxCommandEvent& event) +{ + Destroy(); +} + + + + + + + +////////////////////////////////////////////////////////////////////////////// +// +// CEditReviewDialog +// + +CEditReviewDialog::CEditReviewDialog(wxWindow* parent) : CEditReviewDialogBase(parent) +{ +} + +void CEditReviewDialog::OnButtonSubmit(wxCommandEvent& event) +{ + if (m_choiceStars->GetSelection() == -1) + { + wxMessageBox("Please select a rating "); + return; + } + + CReview review; + GetReview(review); + + // Sign the review + review.vchPubKeyFrom = keyUser.GetPubKey(); + if (!keyUser.Sign(review.GetSigHash(), review.vchSig)) + { + wxMessageBox("Unable to digitally sign the review "); + return; + } + + // Broadcast + if (!review.AcceptReview()) + { + wxMessageBox("Save failed "); + return; + } + RelayMessage(CInv(MSG_REVIEW, review.GetHash()), review); + + Destroy(); +} + +void CEditReviewDialog::OnButtonCancel(wxCommandEvent& event) +{ + Destroy(); +} + +void CEditReviewDialog::GetReview(CReview& review) +{ + review.mapValue["time"] = i64tostr(GetAdjustedTime()); + review.mapValue["stars"] = itostr(m_choiceStars->GetSelection()+1); + review.mapValue["review"] = m_textCtrlReview->GetValue(); +} + + + + + + + + + + + + +////////////////////////////////////////////////////////////////////////////// +// +// CMyApp +// + +// Define a new application +class CMyApp: public wxApp +{ + public: + CMyApp(){}; + ~CMyApp(){}; + bool OnInit(); + bool OnInit2(); + int OnExit(); + + // 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::OnInit() +{ + try + { + return OnInit2(); + } + catch (std::exception& e) { + PrintException(&e, "OnInit()"); + } catch (...) { + PrintException(NULL, "OnInit()"); + } + return false; +} + +map ParseParameters(int argc, char* argv[]) +{ + map mapArgs; + for (int i = 0; i < argc; i++) + { + char psz[10000]; + strcpy(psz, argv[i]); + char* pszValue = ""; + if (strchr(psz, '=')) + { + pszValue = strchr(psz, '='); + *pszValue++ = '\0'; + } + strlwr(psz); + if (psz[0] == '-') + psz[0] = '/'; + mapArgs[psz] = pszValue; + } + return mapArgs; +} + +bool CMyApp::OnInit2() +{ +#ifdef _MSC_VER + // Turn off microsoft heap dump noise for now + _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE); + _CrtSetReportFile(_CRT_WARN, CreateFile("NUL", GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0)); +#endif +#ifdef __WXDEBUG__ + // Disable malfunctioning wxWidgets debug assertion + g_isPainting = 10000; +#endif + + //// debug print + printf("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"); + printf("Bitcoin version %d, Windows version %08x\n", VERSION, GetVersion()); + + // + // Limit to single instance per user + // Required to protect the database files if we're going to keep deleting log.* + // + wxString strMutexName = wxString("Bitcoin.") + 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 = FindWindow("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; + } + } + + // + // Parameters + // + wxImage::AddHandler(new wxPNGHandler); + map mapArgs = ParseParameters(argc, argv); + + if (mapArgs.count("/datadir")) + strSetDataDir = mapArgs["/datadir"]; + + if (mapArgs.count("/proxy")) + addrProxy = CAddress(mapArgs["/proxy"].c_str()); + + if (mapArgs.count("/debug")) + fDebug = true; + + if (mapArgs.count("/dropmessages")) + { + nDropMessagesTest = atoi(mapArgs["/dropmessages"]); + if (nDropMessagesTest == 0) + nDropMessagesTest = 20; + } + + if (mapArgs.count("/loadblockindextest")) + { + CTxDB txdb("r"); + txdb.LoadBlockIndex(); + PrintBlockTree(); + ExitProcess(0); + } + + // + // Load data files + // + string strErrors; + int64 nStart, nEnd; + + printf("Loading addresses...\n"); + QueryPerformanceCounter((LARGE_INTEGER*)&nStart); + if (!LoadAddresses()) + strErrors += "Error loading addr.dat \n"; + QueryPerformanceCounter((LARGE_INTEGER*)&nEnd); + printf(" addresses %20I64d\n", nEnd - nStart); + + printf("Loading block index...\n"); + QueryPerformanceCounter((LARGE_INTEGER*)&nStart); + if (!LoadBlockIndex()) + strErrors += "Error loading blkindex.dat \n"; + QueryPerformanceCounter((LARGE_INTEGER*)&nEnd); + printf(" block index %20I64d\n", nEnd - nStart); + + printf("Loading wallet...\n"); + QueryPerformanceCounter((LARGE_INTEGER*)&nStart); + if (!LoadWallet()) + strErrors += "Error loading wallet.dat \n"; + QueryPerformanceCounter((LARGE_INTEGER*)&nEnd); + printf(" wallet %20I64d\n", nEnd - nStart); + + printf("Done loading\n"); + + //// debug print + printf("mapBlockIndex.size() = %d\n", mapBlockIndex.size()); + printf("nBestHeight = %d\n", nBestHeight); + printf("mapKeys.size() = %d\n", mapKeys.size()); + printf("mapPubKeys.size() = %d\n", mapPubKeys.size()); + printf("mapWallet.size() = %d\n", mapWallet.size()); + printf("mapAddressBook.size() = %d\n", mapAddressBook.size()); + + if (!strErrors.empty()) + { + wxMessageBox(strErrors, "Bitcoin"); + OnExit(); + return false; + } + + // Add wallet transactions that aren't already in a block to mapTransactions + ReacceptWalletTransactions(); + + // + // Parameters + // + if (mapArgs.count("/printblockindex") || mapArgs.count("/printblocktree")) + { + PrintBlockTree(); + OnExit(); + return false; + } + + if (mapArgs.count("/gen")) + { + if (mapArgs["/gen"].empty()) + fGenerateBitcoins = true; + else + fGenerateBitcoins = atoi(mapArgs["/gen"].c_str()); + } + + // + // Create the main frame window + // + { + pframeMain = new CMainFrame(NULL); + pframeMain->Show(); + + if (!CheckDiskSpace()) + { + OnExit(); + return false; + } + + if (!StartNode(strErrors)) + wxMessageBox(strErrors, "Bitcoin"); + + if (fGenerateBitcoins) + if (_beginthread(ThreadBitcoinMiner, 0, NULL) == -1) + printf("Error: _beginthread(ThreadBitcoinMiner) failed\n"); + + // + // Tests + // + if (argc >= 2 && stricmp(argv[1], "/send") == 0) + { + int64 nValue = 1; + if (argc >= 3) + ParseMoney(argv[2], nValue); + + string strAddress; + if (argc >= 4) + strAddress = argv[3]; + CAddress addr(strAddress.c_str()); + + CWalletTx wtx; + wtx.mapValue["to"] = strAddress; + wtx.mapValue["from"] = addrLocalHost.ToString(); + wtx.mapValue["message"] = "command line send"; + + // Send to IP address + CSendingDialog* pdialog = new CSendingDialog(pframeMain, addr, nValue, wtx); + if (!pdialog->ShowModal()) + return false; + } + + if (mapArgs.count("/randsendtest")) + { + if (!mapArgs["/randsendtest"].empty()) + _beginthread(ThreadRandSendTest, 0, new string(mapArgs["/randsendtest"])); + else + fRandSendTest = true; + fDebug = true; + } + } + + return true; +} + +int CMyApp::OnExit() +{ + Shutdown(NULL); + return wxApp::OnExit(); +} + +bool CMyApp::OnExceptionInMainLoop() +{ + try + { + throw; + } + catch (std::exception& e) + { + PrintException(&e, "CMyApp::OnExceptionInMainLoop()"); + wxLogWarning(_T("Exception %s %s"), typeid(e).name(), e.what()); + Sleep(1000); + throw; + } + catch (...) + { + PrintException(NULL, "CMyApp::OnExceptionInMainLoop()"); + wxLogWarning(_T("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(_T("Exception %s %s"), typeid(e).name(), e.what()); + Sleep(1000); + throw; + } + catch (...) + { + PrintException(NULL, "CMyApp::OnUnhandledException()"); + wxLogWarning(_T("Unknown exception")); + Sleep(1000); + throw; + } +} + +void CMyApp::OnFatalException() +{ + wxMessageBox("Program has crashed and will terminate. ", "Bitcoin", wxOK | wxICON_ERROR); +} + + + +void MainFrameRepaint() +{ + if (pframeMain) + { + printf("MainFrameRepaint()\n"); + wxPaintEvent event; + pframeMain->Refresh(); + pframeMain->AddPendingEvent(event); + } +} + + + + + + + +// randsendtest to bitcoin address +void ThreadRandSendTest(void* parg) +{ + string strAddress = *(string*)parg; + uint160 hash160; + if (!AddressToHash160(strAddress, hash160)) + { + wxMessageBox(strprintf("ThreadRandSendTest: Bitcoin address '%s' not valid ", strAddress.c_str())); + return; + } + + loop + { + Sleep(GetRand(30) * 1000 + 100); + + // Message + CWalletTx wtx; + wtx.mapValue["to"] = strAddress; + wtx.mapValue["from"] = addrLocalHost.ToString(); + static int nRep; + wtx.mapValue["message"] = strprintf("randsendtest %d\n", ++nRep); + + // Value + int64 nValue = (GetRand(9) + 1) * 100 * CENT; + if (GetBalance() < nValue) + { + wxMessageBox("Out of money "); + return; + } + nValue += (nRep % 100) * CENT; + + // Send to bitcoin address + CScript scriptPubKey; + scriptPubKey << OP_DUP << OP_HASH160 << hash160 << OP_EQUALVERIFY << OP_CHECKSIG; + + if (!SendMoney(scriptPubKey, nValue, wtx)) + return; + } +} + + +// randsendtest to any connected node +void RandSend() +{ + CWalletTx wtx; + + while (vNodes.empty()) + Sleep(1000); + CAddress addr; + CRITICAL_BLOCK(cs_vNodes) + addr = vNodes[GetRand(vNodes.size())]->addr; + + // Message + wtx.mapValue["to"] = addr.ToString(); + wtx.mapValue["from"] = addrLocalHost.ToString(); + static int nRep; + wtx.mapValue["message"] = strprintf("randsendtest %d\n", ++nRep); + + // Value + int64 nValue = (GetRand(999) + 1) * CENT; + if (GetBalance() < nValue) + { + wxMessageBox("Out of money "); + return; + } + + // Send to IP address + CSendingDialog* pdialog = new CSendingDialog(pframeMain, addr, nValue, wtx); + if (!pdialog->Show()) + wxMessageBox("ShowModal Failed "); +} diff --git a/ui.h b/ui.h new file mode 100644 index 0000000000..163554a599 --- /dev/null +++ b/ui.h @@ -0,0 +1,420 @@ +// Copyright (c) 2009 Satoshi Nakamoto +// Distributed under the MIT/X11 software license, see the accompanying +// file license.txt or http://www.opensource.org/licenses/mit-license.php. + + + + +DECLARE_EVENT_TYPE(wxEVT_CROSSTHREADCALL, -1) +DECLARE_EVENT_TYPE(wxEVT_REPLY1, -1) +DECLARE_EVENT_TYPE(wxEVT_REPLY2, -1) +DECLARE_EVENT_TYPE(wxEVT_REPLY3, -1) +DECLARE_EVENT_TYPE(wxEVT_TABLEADDED, -1) +DECLARE_EVENT_TYPE(wxEVT_TABLEUPDATED, -1) +DECLARE_EVENT_TYPE(wxEVT_TABLEDELETED, -1) + +enum +{ + UICALL_ADDORDER = 1, + UICALL_UPDATEORDER, +}; + + + +extern void HandleCtrlA(wxKeyEvent& event); +extern string DateTimeStr(int64 nTime); +extern string FormatTxStatus(const CWalletTx& wtx); +extern void CrossThreadCall(int nID, void* pdata); +extern void MainFrameRepaint(); +extern void Shutdown(void* parg); + + + + + + +class CMainFrame : public CMainFrameBase +{ +protected: + // Event handlers + void OnClose(wxCloseEvent& 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 OnMenuOptionsGenerate(wxCommandEvent& 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 OnButtonCopy(wxCommandEvent& event); + void OnButtonChange(wxCommandEvent& event); + void OnListColBeginDrag(wxListEvent& event); + void OnListItemActivatedAllTransactions(wxListEvent& event); + void OnListItemActivatedProductsSent(wxListEvent& event); + void OnListItemActivatedOrdersSent(wxListEvent& event); + void OnListItemActivatedOrdersReceived(wxListEvent& event); + +public: + /** Constructor */ + CMainFrame(wxWindow* parent); + ~CMainFrame(); + + // Custom + bool fRefreshListCtrl; + bool fRefreshListCtrlRunning; + bool fOnSetFocusAddress; + CBlockIndex* pindexBestLast; + set setUnmaturedDisplayed; + + void OnCrossThreadCall(wxCommandEvent& event); + void InsertLine(bool fNew, int nIndex, uint256 hashKey, string strSort, const wxString& str1, const wxString& str2, const wxString& str3, const wxString& str4, const wxString& str5); + void InsertTransaction(const CWalletTx& wtx, bool fNew, int nIndex=-1); + void RefreshListCtrl(); + void RefreshStatus(); +}; + + + + +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 OnKillFocusTransactionFee(wxFocusEvent& event); + void OnButtonOK(wxCommandEvent& event); + void OnButtonCancel(wxCommandEvent& event); + +public: + /** Constructor */ + COptionsDialog(wxWindow* parent); +}; + + + +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 OnTextAddress(wxCommandEvent& 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=""); +}; + + + +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; + string strStatus; + bool fCanCancel; + bool fAbort; + bool fSuccess; + bool fUIDone; + bool fWorkDone; + + void Close(); + void Repaint(); + bool Status(); + bool Status(const string& str); + bool Error(const 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 CYourAddressDialog : public CYourAddressDialogBase +{ +protected: + // Event handlers + void OnListEndLabelEdit(wxListEvent& event); + void OnListItemSelected(wxListEvent& event); + void OnListItemActivated(wxListEvent& event); + void OnButtonRename(wxCommandEvent& event); + void OnButtonNew(wxCommandEvent& event); + void OnButtonCopy(wxCommandEvent& event); + void OnButtonOK(wxCommandEvent& event); + void OnButtonCancel(wxCommandEvent& event); + void OnClose(wxCloseEvent& event); + +public: + /** Constructor */ + CYourAddressDialog(wxWindow* parent); + CYourAddressDialog(wxWindow* parent, const string& strInitSelected); + + // Custom + wxString GetAddress(); +}; + + + +class CAddressBookDialog : public CAddressBookDialogBase +{ +protected: + // Event handlers + void OnListEndLabelEdit(wxListEvent& event); + void OnListItemSelected(wxListEvent& event); + void OnListItemActivated(wxListEvent& event); + void OnButtonEdit(wxCommandEvent& event); + void OnButtonDelete(wxCommandEvent& event); + void OnButtonNew(wxCommandEvent& event); + void OnButtonCopy(wxCommandEvent& event); + void OnButtonOK(wxCommandEvent& event); + void OnButtonCancel(wxCommandEvent& event); + void OnClose(wxCloseEvent& event); + +public: + /** Constructor */ + CAddressBookDialog(wxWindow* parent, const wxString& strInitSelected, bool fSendingIn); + + // Custom + bool fSending; + wxString GetAddress(); + bool CheckIfMine(const string& strAddress, const string& strTitle); +}; + + + +class CProductsDialog : public CProductsDialogBase +{ +protected: + // Event handlers + void OnKeyDown(wxKeyEvent& event) { HandleCtrlA(event); } + void OnCombobox(wxCommandEvent& event); + void OnButtonSearch(wxCommandEvent& event); + void OnListItemActivated(wxListEvent& event); + +public: + /** Constructor */ + CProductsDialog(wxWindow* parent); + + // Custom + vector m_vProduct; +}; + + + +class CEditProductDialog : public CEditProductDialogBase +{ +protected: + // Event handlers + void OnKeyDown(wxKeyEvent& event) { HandleCtrlA(event); } + void OnButtonDel0(wxCommandEvent& event); + void OnButtonDel1(wxCommandEvent& event); + void OnButtonDel2(wxCommandEvent& event); + void OnButtonDel3(wxCommandEvent& event); + void OnButtonDel4(wxCommandEvent& event); + void OnButtonDel5(wxCommandEvent& event); + void OnButtonDel6(wxCommandEvent& event); + void OnButtonDel7(wxCommandEvent& event); + void OnButtonDel8(wxCommandEvent& event); + void OnButtonDel9(wxCommandEvent& event); + void OnButtonDel10(wxCommandEvent& event); + void OnButtonDel11(wxCommandEvent& event); + void OnButtonDel12(wxCommandEvent& event); + void OnButtonDel13(wxCommandEvent& event); + void OnButtonDel14(wxCommandEvent& event); + void OnButtonDel15(wxCommandEvent& event); + void OnButtonDel16(wxCommandEvent& event); + void OnButtonDel17(wxCommandEvent& event); + void OnButtonDel18(wxCommandEvent& event); + void OnButtonDel19(wxCommandEvent& event); + void OnButtonAddField(wxCommandEvent& event); + void OnButtonSend(wxCommandEvent& event); + void OnButtonPreview(wxCommandEvent& event); + void OnButtonCancel(wxCommandEvent& event); + +public: + /** Constructor */ + CEditProductDialog(wxWindow* parent); + + // Custom + enum { FIELDS_MAX = 20 }; + wxTextCtrl* m_textCtrlLabel[FIELDS_MAX]; + wxTextCtrl* m_textCtrlField[FIELDS_MAX]; + wxButton* m_buttonDel[FIELDS_MAX]; + + void LayoutAll(); + void ShowLine(int i, bool fShow=true); + void OnButtonDel(wxCommandEvent& event, int n); + void SetProduct(const CProduct& productIn); + void GetProduct(CProduct& product); + +}; + + + +class CViewProductDialog : public CViewProductDialogBase +{ +protected: + // Event handlers + void OnButtonSubmitForm(wxCommandEvent& event); + void OnButtonCancelForm(wxCommandEvent& event); + void OnButtonBack(wxCommandEvent& event); + void OnButtonNext(wxCommandEvent& event); + void OnButtonCancel(wxCommandEvent& event); + +public: + /** Constructor */ + CViewProductDialog(wxWindow* parent, const CProduct& productIn); + ~CViewProductDialog(); + + // Custom + CProduct product; + enum { FIELDS_MAX = 20 }; + wxStaticText* m_staticTextLabel[FIELDS_MAX]; + wxTextCtrl* m_textCtrlField[FIELDS_MAX]; + wxChoice* m_choiceField[FIELDS_MAX]; + + void GetOrder(CWalletTx& order); + void UpdateProductDisplay(bool fDetails); + void OnReply1(wxCommandEvent& event); +}; + + + +class CViewOrderDialog : public CViewOrderDialogBase +{ +protected: + // Event handlers + void OnButtonOK(wxCommandEvent& event); + +public: + /** Constructor */ + CViewOrderDialog(wxWindow* parent, CWalletTx order, bool fReceived); + + // Custom + bool fReceived; +}; + + + +class CEditReviewDialog : public CEditReviewDialogBase +{ +protected: + // Event handlers + void OnKeyDown(wxKeyEvent& event) { HandleCtrlA(event); } + void OnButtonSubmit(wxCommandEvent& event); + void OnButtonCancel(wxCommandEvent& event); + +public: + /** Constructor */ + CEditReviewDialog(wxWindow* parent); + + // Custom + void GetReview(CReview& review); +}; + + + +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 string& strCaption, + const string& strMessage1, + const string& strValue1="", + const string& strMessage2="", + const string& strValue2="") : CGetTextFromUserDialogBase(parent, wxID_ANY, strCaption) + { + m_staticTextMessage1->SetLabel(strMessage1); + m_textCtrl1->SetValue(strValue1); + if (!strMessage2.empty()) + { + m_staticTextMessage2->Show(true); + m_staticTextMessage2->SetLabel(strMessage2); + m_textCtrl2->Show(true); + m_textCtrl2->SetValue(strValue2); + SetSize(wxDefaultCoord, 180); + } + } + + // Custom + string GetValue() { return (string)m_textCtrl1->GetValue(); } + string GetValue1() { return (string)m_textCtrl1->GetValue(); } + string GetValue2() { return (string)m_textCtrl2->GetValue(); } +}; + + + + + diff --git a/ui.rc b/ui.rc new file mode 100644 index 0000000000..95258c7d59 --- /dev/null +++ b/ui.rc @@ -0,0 +1,14 @@ +bitcoin ICON "rc/bitcoin.ico" + +#include "wx/msw/wx.rc" + +check ICON "rc/check.ico" +send16 BITMAP "rc/send16.bmp" +send16mask BITMAP "rc/send16mask.bmp" +send16masknoshadow BITMAP "rc/send16masknoshadow.bmp" +send20 BITMAP "rc/send20.bmp" +send20mask BITMAP "rc/send20mask.bmp" +addressbook16 BITMAP "rc/addressbook16.bmp" +addressbook16mask BITMAP "rc/addressbook16mask.bmp" +addressbook20 BITMAP "rc/addressbook20.bmp" +addressbook20mask BITMAP "rc/addressbook20mask.bmp" diff --git a/uibase.cpp b/uibase.cpp new file mode 100644 index 0000000000..2972e9af3b --- /dev/null +++ b/uibase.cpp @@ -0,0 +1,1825 @@ +// Copyright (c) 2009 Satoshi Nakamoto +// Distributed under the MIT/X11 software license, see the accompanying +// file license.txt or http://www.opensource.org/licenses/mit-license.php. + +/////////////////////////////////////////////////////////////////////////// +// C++ code generated with wxFormBuilder (version Apr 16 2008) +// http://www.wxformbuilder.org/ +// +// PLEASE DO "NOT" EDIT THIS FILE! +/////////////////////////////////////////////////////////////////////////// + +#include "uibase.h" + +/////////////////////////////////////////////////////////////////////////// + +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_menubar->SetBackgroundColour(wxColour(240, 240, 240)); + + m_menuFile = new wxMenu(); + wxMenuItem* m_menuFileExit; + m_menuFileExit = new wxMenuItem(m_menuFile, wxID_ANY, wxString(wxT("E&xit")) , wxEmptyString, wxITEM_NORMAL); + m_menuFile->Append(m_menuFileExit); + + m_menubar->Append(m_menuFile, wxT("&File")); + + m_menuOptions = new wxMenu(); + wxMenuItem* m_menuOptionsGenerateBitcoins; + m_menuOptionsGenerateBitcoins = new wxMenuItem(m_menuOptions, wxID_OPTIONSGENERATEBITCOINS, wxString(wxT("&Generate Coins")) , wxEmptyString, wxITEM_CHECK); + m_menuOptions->Append(m_menuOptionsGenerateBitcoins); + + wxMenuItem* m_menuChangeYourAddress; + m_menuChangeYourAddress = new wxMenuItem(m_menuOptions, wxID_ANY, wxString(wxT("&Change Your Address...")) , wxEmptyString, wxITEM_NORMAL); + m_menuOptions->Append(m_menuChangeYourAddress); + + wxMenuItem* m_menuOptionsOptions; + m_menuOptionsOptions = new wxMenuItem(m_menuOptions, wxID_ANY, wxString(wxT("&Options...")) , wxEmptyString, wxITEM_NORMAL); + m_menuOptions->Append(m_menuOptionsOptions); + + m_menubar->Append(m_menuOptions, wxT("&Options")); + + m_menuHelp = new wxMenu(); + wxMenuItem* m_menuHelpAbout; + m_menuHelpAbout = new wxMenuItem(m_menuHelp, wxID_ANY, wxString(wxT("&About...")) , wxEmptyString, wxITEM_NORMAL); + m_menuHelp->Append(m_menuHelpAbout); + + m_menubar->Append(m_menuHelp, wxT("&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, wxT("&Send Coins"), wxBitmap(wxT("send20"), wxBITMAP_TYPE_RESOURCE), wxNullBitmap, wxITEM_NORMAL, wxEmptyString, wxEmptyString); + m_toolBar->AddTool(wxID_BUTTONRECEIVE, wxT("&Address Book"), wxBitmap(wxT("addressbook20"), wxBITMAP_TYPE_RESOURCE), wxNullBitmap, wxITEM_NORMAL, wxEmptyString, wxEmptyString); + m_toolBar->Realize(); + + m_statusBar = this->CreateStatusBar(1, wxST_SIZEGRIP, wxID_ANY); + m_statusBar->SetBackgroundColour(wxColour(240, 240, 240)); + + 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, wxT("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(250,-1), wxTE_READONLY); + m_textCtrlAddress->SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_MENU)); + + bSizer85->Add(m_textCtrlAddress, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5); + + m_buttonCopy = new wxButton(this, wxID_BUTTONCOPY, wxT("&Copy to Clipboard"), wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT); + bSizer85->Add(m_buttonCopy, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 5); + + m_button91 = new wxButton(this, wxID_BUTTONCHANGE, wxT("C&hange..."), wxDefaultPosition, wxDefaultSize, 0); + m_button91->Hide(); + + bSizer85->Add(m_button91, 0, wxRIGHT, 5); + + + bSizer85->Add(0, 0, 0, wxEXPAND, 5); + + bSizer2->Add(bSizer85, 0, wxEXPAND|wxRIGHT|wxLEFT, 5); + + wxBoxSizer* bSizer3; + bSizer3 = new wxBoxSizer(wxHORIZONTAL); + + m_panel14 = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL); + wxBoxSizer* bSizer66; + bSizer66 = new wxBoxSizer(wxHORIZONTAL); + + m_staticText41 = new wxStaticText(m_panel14, wxID_ANY, wxT("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(m_panel14, 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(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW)); + + bSizer66->Add(m_staticTextBalance, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5); + + m_panel14->SetSizer(bSizer66); + m_panel14->Layout(); + bSizer66->Fit(m_panel14); + bSizer3->Add(m_panel14, 1, wxEXPAND|wxALIGN_BOTTOM|wxALL, 5); + + + bSizer3->Add(0, 0, 0, wxEXPAND, 5); + + wxString m_choiceFilterChoices[] = { wxT(" All"), wxT(" Sent"), wxT(" Received"), wxT(" 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_panel7 = new wxPanel(m_notebook, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL); + wxBoxSizer* bSizer157; + bSizer157 = new wxBoxSizer(wxVERTICAL); + + m_listCtrl = new wxListCtrl(m_panel7, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_NO_SORT_HEADER|wxLC_REPORT|wxLC_SORT_DESCENDING|wxALWAYS_SHOW_SB); + bSizer157->Add(m_listCtrl, 1, wxEXPAND|wxALL, 5); + + m_panel7->SetSizer(bSizer157); + m_panel7->Layout(); + bSizer157->Fit(m_panel7); + m_notebook->AddPage(m_panel7, wxT("All Transactions"), false); + + bSizer2->Add(m_notebook, 1, wxEXPAND, 5); + + wxBoxSizer* bSizer_TabsForFutureUse; + bSizer_TabsForFutureUse = new wxBoxSizer(wxVERTICAL); + + m_panel9 = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL); + m_panel9->Hide(); + + wxBoxSizer* bSizer159; + bSizer159 = new wxBoxSizer(wxVERTICAL); + + m_listCtrlEscrows = new wxListCtrl(m_panel9, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_NO_SORT_HEADER|wxLC_REPORT); + bSizer159->Add(m_listCtrlEscrows, 1, wxALL|wxEXPAND, 5); + + m_panel9->SetSizer(bSizer159); + m_panel9->Layout(); + bSizer159->Fit(m_panel9); + bSizer_TabsForFutureUse->Add(m_panel9, 1, wxEXPAND | wxALL, 5); + + m_panel8 = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL); + m_panel8->Hide(); + + wxBoxSizer* bSizer158; + bSizer158 = new wxBoxSizer(wxVERTICAL); + + m_listCtrlOrdersSent = new wxListCtrl(m_panel8, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_NO_SORT_HEADER|wxLC_REPORT); + bSizer158->Add(m_listCtrlOrdersSent, 1, wxALL|wxEXPAND, 5); + + m_panel8->SetSizer(bSizer158); + m_panel8->Layout(); + bSizer158->Fit(m_panel8); + bSizer_TabsForFutureUse->Add(m_panel8, 1, wxEXPAND | wxALL, 5); + + m_panel10 = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL); + m_panel10->Hide(); + + wxBoxSizer* bSizer160; + bSizer160 = new wxBoxSizer(wxVERTICAL); + + m_listCtrlProductsSent = new wxListCtrl(m_panel10, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_NO_SORT_HEADER|wxLC_REPORT); + bSizer160->Add(m_listCtrlProductsSent, 1, wxALL|wxEXPAND, 5); + + m_panel10->SetSizer(bSizer160); + m_panel10->Layout(); + bSizer160->Fit(m_panel10); + bSizer_TabsForFutureUse->Add(m_panel10, 1, wxEXPAND | wxALL, 5); + + m_panel11 = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL); + m_panel11->Hide(); + + wxBoxSizer* bSizer161; + bSizer161 = new wxBoxSizer(wxVERTICAL); + + m_listCtrlOrdersReceived = new wxListCtrl(m_panel11, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_NO_SORT_HEADER|wxLC_REPORT); + bSizer161->Add(m_listCtrlOrdersReceived, 1, wxALL|wxEXPAND, 5); + + m_panel11->SetSizer(bSizer161); + m_panel11->Layout(); + bSizer161->Fit(m_panel11); + bSizer_TabsForFutureUse->Add(m_panel11, 1, wxEXPAND | wxALL, 5); + + bSizer2->Add(bSizer_TabsForFutureUse, 1, wxEXPAND, 5); + + this->SetSizer(bSizer2); + this->Layout(); + + // Connect Events + this->Connect(wxEVT_CLOSE_WINDOW, wxCloseEventHandler(CMainFrameBase::OnClose)); + 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_menuOptionsGenerateBitcoins->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(CMainFrameBase::OnMenuOptionsGenerate)); + this->Connect(m_menuChangeYourAddress->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_buttonCopy->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CMainFrameBase::OnButtonCopy), NULL, this); + m_button91->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CMainFrameBase::OnButtonChange), NULL, this); + m_listCtrl->Connect(wxEVT_COMMAND_LIST_COL_BEGIN_DRAG, wxListEventHandler(CMainFrameBase::OnListColBeginDrag), NULL, this); + m_listCtrl->Connect(wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler(CMainFrameBase::OnListItemActivatedAllTransactions), NULL, this); + m_listCtrl->Connect(wxEVT_PAINT, wxPaintEventHandler(CMainFrameBase::OnPaintListCtrl), NULL, this); + m_listCtrlOrdersSent->Connect(wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler(CMainFrameBase::OnListItemActivatedOrdersSent), NULL, this); + m_listCtrlProductsSent->Connect(wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler(CMainFrameBase::OnListItemActivatedProductsSent), NULL, this); + m_listCtrlOrdersReceived->Connect(wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler(CMainFrameBase::OnListItemActivatedOrdersReceived), NULL, this); +} + +CMainFrameBase::~CMainFrameBase() +{ + // Disconnect Events + this->Disconnect(wxEVT_CLOSE_WINDOW, wxCloseEventHandler(CMainFrameBase::OnClose)); + 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::OnMenuOptionsGenerate)); + 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_buttonCopy->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CMainFrameBase::OnButtonCopy), NULL, this); + m_button91->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CMainFrameBase::OnButtonChange), NULL, this); + m_listCtrl->Disconnect(wxEVT_COMMAND_LIST_COL_BEGIN_DRAG, wxListEventHandler(CMainFrameBase::OnListColBeginDrag), NULL, this); + m_listCtrl->Disconnect(wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler(CMainFrameBase::OnListItemActivatedAllTransactions), NULL, this); + m_listCtrl->Disconnect(wxEVT_PAINT, wxPaintEventHandler(CMainFrameBase::OnPaintListCtrl), NULL, this); + m_listCtrlOrdersSent->Disconnect(wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler(CMainFrameBase::OnListItemActivatedOrdersSent), NULL, this); + m_listCtrlProductsSent->Disconnect(wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler(CMainFrameBase::OnListItemActivatedProductsSent), NULL, this); + m_listCtrlOrdersReceived->Disconnect(wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler(CMainFrameBase::OnListItemActivatedOrdersReceived), 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(wxVERTICAL); + + m_buttonOK = new wxButton(this, wxID_OK, wxT("OK"), wxDefaultPosition, wxSize(85,25), 0); + bSizer65->Add(m_buttonOK, 0, wxALL, 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* bSizer57; + bSizer57 = new wxBoxSizer(wxVERTICAL); + + + bSizer57->Add(0, 20, 0, wxEXPAND, 5); + + m_staticText32 = new wxStaticText(this, wxID_ANY, wxT("Optional transaction fee you give to the nodes that process your transactions."), wxDefaultPosition, wxDefaultSize, 0); + m_staticText32->Wrap(-1); + bSizer57->Add(m_staticText32, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5); + + wxBoxSizer* bSizer56; + bSizer56 = new wxBoxSizer(wxHORIZONTAL); + + m_staticText31 = new wxStaticText(this, wxID_ANY, wxT("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(this, wxID_TRANSACTIONFEE, wxEmptyString, wxDefaultPosition, wxSize(70,-1), 0); + bSizer56->Add(m_textCtrlTransactionFee, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5); + + bSizer57->Add(bSizer56, 0, wxEXPAND, 5); + + bSizer55->Add(bSizer57, 1, wxEXPAND|wxLEFT, 5); + + wxBoxSizer* bSizer58; + bSizer58 = new wxBoxSizer(wxHORIZONTAL); + + m_buttonOK = new wxButton(this, wxID_OK, wxT("OK"), wxDefaultPosition, wxSize(85,25), 0); + bSizer58->Add(m_buttonOK, 0, wxALL, 5); + + m_buttonCancel = new wxButton(this, wxID_CANCEL, wxT("Cancel"), wxDefaultPosition, wxSize(-1,-1), 0); + m_buttonCancel->SetMinSize(wxSize(85,25)); + + bSizer58->Add(m_buttonCancel, 0, wxALL, 5); + + bSizer55->Add(bSizer58, 0, wxALIGN_RIGHT, 5); + + this->SetSizer(bSizer55); + this->Layout(); + + // Connect Events + 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); +} + +COptionsDialogBase::~COptionsDialogBase() +{ + // Disconnect Events + 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); +} + +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* bSizer60; + bSizer60 = new wxBoxSizer(wxVERTICAL); + + wxBoxSizer* bSizer62; + bSizer62 = new wxBoxSizer(wxHORIZONTAL); + + + bSizer62->Add(60, 0, 0, wxEXPAND, 5); + + wxBoxSizer* bSizer63; + bSizer63 = new wxBoxSizer(wxVERTICAL); + + + bSizer63->Add(0, 50, 0, wxEXPAND, 5); + + wxBoxSizer* bSizer64; + bSizer64 = new wxBoxSizer(wxHORIZONTAL); + + m_staticText40 = new wxStaticText(this, wxID_ANY, wxT("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, wxT("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); + + bSizer63->Add(bSizer64, 0, wxEXPAND, 5); + + + bSizer63->Add(0, 4, 0, wxEXPAND, 5); + + m_staticTextMain = new wxStaticText(this, wxID_ANY, wxT("Copyright © 2009 Satoshi Nakamoto.\n\nThis is experimental software. Do not rely on it for actual financial transactions.\n\nDistributed under the MIT/X11 software license, see the accompanying file license.txt or http://www.opensource.org/licenses/mit-license.php.\n\nThis 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)."), wxDefaultPosition, wxDefaultSize, 0); + m_staticTextMain->Wrap(400); + bSizer63->Add(m_staticTextMain, 0, wxALL, 5); + + + bSizer63->Add(0, 0, 1, wxEXPAND, 5); + + bSizer62->Add(bSizer63, 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, wxT("OK"), wxDefaultPosition, wxSize(85,25), 0); + bSizer61->Add(m_buttonOK, 0, wxALL, 5); + + bSizer60->Add(bSizer61, 0, wxALIGN_RIGHT|wxEXPAND, 5); + + this->SetSizer(bSizer60); + 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(3, 2, 0, 0); + fgSizer1->AddGrowableCol(1); + fgSizer1->SetFlexibleDirection(wxBOTH); + fgSizer1->SetNonFlexibleGrowMode(wxFLEX_GROWMODE_SPECIFIED); + + + fgSizer1->Add(0, 0, 0, wxEXPAND, 5); + + m_staticText14 = new wxStaticText(this, wxID_ANY, wxT("Enter the recipient's IP address (e.g. 123.45.6.7) for online transfer with comments and confirmation, \nor Bitcoin address (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJED9L) if recipient is not online."), wxDefaultPosition, wxDefaultSize, 0); + m_staticText14->Wrap(-1); + fgSizer1->Add(m_staticText14, 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, wxICON(check), wxDefaultPosition, wxSize(16,16), 0); + bSizer47->Add(m_bitmapCheckMark, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5); + + m_staticText36 = new wxStaticText(this, wxID_ANY, wxT("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); + + m_buttonPaste = new wxButton(this, wxID_BUTTONPASTE, wxT("&Paste"), wxDefaultPosition, wxSize(-1,-1), wxBU_EXACTFIT); + bSizer19->Add(m_buttonPaste, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 5); + + m_buttonAddress = new wxButton(this, wxID_BUTTONADDRESSBOOK, wxT(" Address &Book..."), wxDefaultPosition, wxDefaultSize, 0); + bSizer19->Add(m_buttonAddress, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 5); + + fgSizer1->Add(bSizer19, 1, wxEXPAND|wxRIGHT, 5); + + m_staticText19 = new wxStaticText(this, wxID_ANY, wxT("&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, wxT("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[] = { wxT(" 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); + + wxBoxSizer* bSizer681; + bSizer681 = new wxBoxSizer(wxVERTICAL); + + m_staticTextFrom = new wxStaticText(this, wxID_ANY, wxT("&From:"), wxDefaultPosition, wxDefaultSize, 0); + m_staticTextFrom->Wrap(-1); + bSizer681->Add(m_staticTextFrom, 0, wxBOTTOM|wxLEFT, 5); + + m_textCtrlFrom = new wxTextCtrl(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(-1,-1), 0); + bSizer681->Add(m_textCtrlFrom, 0, wxLEFT|wxEXPAND, 5); + + bSizer672->Add(bSizer681, 1, wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT, 5); + + bSizer21->Add(bSizer672, 0, wxEXPAND, 5); + + wxBoxSizer* bSizer67; + bSizer67 = new wxBoxSizer(wxHORIZONTAL); + + wxBoxSizer* bSizer68; + bSizer68 = new wxBoxSizer(wxVERTICAL); + + m_staticTextMessage = new wxStaticText(this, wxID_ANY, wxT("&Message:"), wxDefaultPosition, wxDefaultSize, 0); + m_staticTextMessage->Wrap(-1); + bSizer68->Add(m_staticTextMessage, 0, wxTOP|wxBOTTOM|wxLEFT, 5); + + m_textCtrlMessage = new wxTextCtrl(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE); + bSizer68->Add(m_textCtrlMessage, 1, wxEXPAND|wxLEFT, 5); + + bSizer67->Add(bSizer68, 1, wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT, 5); + + bSizer21->Add(bSizer67, 1, wxEXPAND, 5); + + wxBoxSizer* bSizer23; + bSizer23 = new wxBoxSizer(wxHORIZONTAL); + + + bSizer23->Add(0, 0, 1, wxEXPAND, 5); + + m_buttonSend = new wxButton(this, wxID_BUTTONSEND, wxT("&Send"), wxDefaultPosition, wxSize(-1,-1), 0); + m_buttonSend->SetFont(wxFont(wxNORMAL_FONT->GetPointSize(), 70, 90, 90, false, wxEmptyString)); + m_buttonSend->SetMinSize(wxSize(85,25)); + + bSizer23->Add(m_buttonSend, 0, wxALL, 5); + + m_buttonCancel = new wxButton(this, wxID_CANCEL, wxT("Cancel"), wxDefaultPosition, wxSize(-1,-1), 0); + m_buttonCancel->SetMinSize(wxSize(85,25)); + + bSizer23->Add(m_buttonCancel, 0, wxALL, 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_textCtrlFrom->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CSendDialogBase::OnKeyDown), NULL, this); + m_textCtrlMessage->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CSendDialogBase::OnKeyDown), 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_textCtrlFrom->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CSendDialogBase::OnKeyDown), NULL, this); + m_textCtrlMessage->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CSendDialogBase::OnKeyDown), 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, wxT("\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, wxT("OK"), wxDefaultPosition, wxDefaultSize, 0); + m_buttonOK->Enable(false); + m_buttonOK->SetMinSize(wxSize(85,25)); + + bSizer69->Add(m_buttonOK, 0, wxALL, 5); + + m_buttonCancel = new wxButton(this, wxID_CANCEL, wxT("Cancel"), wxDefaultPosition, wxSize(-1,-1), 0); + m_buttonCancel->SetMinSize(wxSize(85,25)); + + bSizer69->Add(m_buttonCancel, 0, wxALL, 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, wxT("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, wxT("&Edit..."), wxDefaultPosition, wxDefaultSize, 0); + m_buttonRename->SetMinSize(wxSize(85,25)); + + bSizer69->Add(m_buttonRename, 0, wxALL, 5); + + m_buttonNew = new wxButton(this, wxID_BUTTONNEW, wxT("&New Address..."), wxDefaultPosition, wxSize(-1,-1), 0); + m_buttonNew->SetMinSize(wxSize(110,25)); + + bSizer69->Add(m_buttonNew, 0, wxALL, 5); + + m_buttonCopy = new wxButton(this, wxID_BUTTONCOPY, wxT("&Copy to Clipboard"), wxDefaultPosition, wxSize(-1,-1), 0); + m_buttonCopy->SetMinSize(wxSize(120,25)); + + bSizer69->Add(m_buttonCopy, 0, wxALL, 5); + + m_buttonOK = new wxButton(this, wxID_OK, wxT("OK"), wxDefaultPosition, wxDefaultSize, 0); + m_buttonOK->SetMinSize(wxSize(85,25)); + + bSizer69->Add(m_buttonOK, 0, wxALL, 5); + + m_buttonCancel = new wxButton(this, wxID_CANCEL, wxT("Cancel"), wxDefaultPosition, wxSize(-1,-1), 0); + m_buttonCancel->Hide(); + m_buttonCancel->SetMinSize(wxSize(85,25)); + + bSizer69->Add(m_buttonCancel, 0, wxALL, 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* bSizer68; + bSizer68 = new wxBoxSizer(wxVERTICAL); + + + bSizer68->Add(0, 5, 0, wxEXPAND, 5); + + m_staticText55 = new wxStaticText(this, wxID_ANY, wxT("Bitcoin Address"), wxDefaultPosition, wxDefaultSize, 0); + m_staticText55->Wrap(-1); + m_staticText55->Hide(); + + bSizer68->Add(m_staticText55, 0, wxTOP|wxRIGHT|wxLEFT, 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_buttonEdit = new wxButton(this, wxID_BUTTONEDIT, wxT("&Edit..."), wxDefaultPosition, wxDefaultSize, 0); + m_buttonEdit->SetMinSize(wxSize(85,25)); + + bSizer69->Add(m_buttonEdit, 0, wxALL, 5); + + m_buttonNew = new wxButton(this, wxID_BUTTONNEW, wxT("&New Address..."), wxDefaultPosition, wxDefaultSize, 0); + m_buttonNew->SetMinSize(wxSize(110,25)); + + bSizer69->Add(m_buttonNew, 0, wxALL, 5); + + m_buttonDelete = new wxButton(this, wxID_BUTTONDELETE, wxT("&Delete"), wxDefaultPosition, wxDefaultSize, 0); + m_buttonDelete->SetMinSize(wxSize(85,25)); + + bSizer69->Add(m_buttonDelete, 0, wxALL, 5); + + m_buttonOK = new wxButton(this, wxID_OK, wxT("OK"), wxDefaultPosition, wxSize(-1,-1), 0); + m_buttonOK->SetMinSize(wxSize(85,25)); + + bSizer69->Add(m_buttonOK, 0, wxALL, 5); + + m_buttonCancel = new wxButton(this, wxID_CANCEL, wxT("Cancel"), wxDefaultPosition, wxSize(-1,-1), 0); + m_buttonCancel->SetMinSize(wxSize(85,25)); + + bSizer69->Add(m_buttonCancel, 0, wxALL, 5); + + bSizer68->Add(bSizer69, 0, wxEXPAND, 5); + + this->SetSizer(bSizer68); + this->Layout(); + + // Connect Events + this->Connect(wxEVT_CLOSE_WINDOW, wxCloseEventHandler(CAddressBookDialogBase::OnClose)); + m_listCtrl->Connect(wxEVT_COMMAND_LIST_END_LABEL_EDIT, wxListEventHandler(CAddressBookDialogBase::OnListEndLabelEdit), NULL, this); + m_listCtrl->Connect(wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler(CAddressBookDialogBase::OnListItemActivated), NULL, this); + m_listCtrl->Connect(wxEVT_COMMAND_LIST_ITEM_SELECTED, wxListEventHandler(CAddressBookDialogBase::OnListItemSelected), 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_buttonDelete->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CAddressBookDialogBase::OnButtonDelete), 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_listCtrl->Disconnect(wxEVT_COMMAND_LIST_END_LABEL_EDIT, wxListEventHandler(CAddressBookDialogBase::OnListEndLabelEdit), NULL, this); + m_listCtrl->Disconnect(wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler(CAddressBookDialogBase::OnListItemActivated), NULL, this); + m_listCtrl->Disconnect(wxEVT_COMMAND_LIST_ITEM_SELECTED, wxListEventHandler(CAddressBookDialogBase::OnListItemSelected), 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_buttonDelete->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CAddressBookDialogBase::OnButtonDelete), 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); +} + +CProductsDialogBase::CProductsDialogBase(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* bSizer22; + bSizer22 = new wxBoxSizer(wxVERTICAL); + + wxBoxSizer* bSizer23; + bSizer23 = new wxBoxSizer(wxHORIZONTAL); + + m_comboBoxCategory = new wxComboBox(this, wxID_ANY, wxT("(Any Category)"), wxDefaultPosition, wxSize(150,-1), 0, NULL, 0); + m_comboBoxCategory->Append(wxT("(Any Category)")); + bSizer23->Add(m_comboBoxCategory, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5); + + m_textCtrlSearch = new wxTextCtrl(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0); + bSizer23->Add(m_textCtrlSearch, 1, wxALL|wxALIGN_CENTER_VERTICAL, 5); + + m_buttonSearch = new wxButton(this, wxID_ANY, wxT("&Search"), wxDefaultPosition, wxDefaultSize, 0); + bSizer23->Add(m_buttonSearch, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5); + + bSizer22->Add(bSizer23, 0, wxEXPAND|wxTOP|wxBOTTOM|wxRIGHT, 5); + + m_listCtrl = new wxListCtrl(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_NO_SORT_HEADER|wxLC_REPORT); + bSizer22->Add(m_listCtrl, 1, wxALL|wxEXPAND, 5); + + this->SetSizer(bSizer22); + this->Layout(); + + // Connect Events + m_comboBoxCategory->Connect(wxEVT_COMMAND_COMBOBOX_SELECTED, wxCommandEventHandler(CProductsDialogBase::OnCombobox), NULL, this); + m_textCtrlSearch->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CProductsDialogBase::OnKeyDown), NULL, this); + m_buttonSearch->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CProductsDialogBase::OnButtonSearch), NULL, this); + m_listCtrl->Connect(wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler(CProductsDialogBase::OnListItemActivated), NULL, this); +} + +CProductsDialogBase::~CProductsDialogBase() +{ + // Disconnect Events + m_comboBoxCategory->Disconnect(wxEVT_COMMAND_COMBOBOX_SELECTED, wxCommandEventHandler(CProductsDialogBase::OnCombobox), NULL, this); + m_textCtrlSearch->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CProductsDialogBase::OnKeyDown), NULL, this); + m_buttonSearch->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CProductsDialogBase::OnButtonSearch), NULL, this); + m_listCtrl->Disconnect(wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler(CProductsDialogBase::OnListItemActivated), NULL, this); +} + +CEditProductDialogBase::CEditProductDialogBase(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_MENU)); + + wxBoxSizer* bSizer20; + bSizer20 = new wxBoxSizer(wxVERTICAL); + + m_scrolledWindow = new wxScrolledWindow(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxHSCROLL|wxTAB_TRAVERSAL|wxVSCROLL); + m_scrolledWindow->SetScrollRate(5, 5); + m_scrolledWindow->SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW)); + + wxBoxSizer* bSizer21; + bSizer21 = new wxBoxSizer(wxVERTICAL); + + wxFlexGridSizer* fgSizer8; + fgSizer8 = new wxFlexGridSizer(0, 2, 0, 0); + fgSizer8->AddGrowableCol(1); + fgSizer8->SetFlexibleDirection(wxBOTH); + fgSizer8->SetNonFlexibleGrowMode(wxFLEX_GROWMODE_SPECIFIED); + + m_staticText106 = new wxStaticText(m_scrolledWindow, wxID_ANY, wxT("Category"), wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT); + m_staticText106->Wrap(-1); + fgSizer8->Add(m_staticText106, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxTOP|wxBOTTOM|wxLEFT, 5); + + m_comboBoxCategory = new wxComboBox(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0, NULL, 0); + m_comboBoxCategory->SetMinSize(wxSize(180,-1)); + + fgSizer8->Add(m_comboBoxCategory, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5); + + m_staticText108 = new wxStaticText(m_scrolledWindow, wxID_ANY, wxT("Title"), wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT); + m_staticText108->Wrap(-1); + fgSizer8->Add(m_staticText108, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxTOP|wxBOTTOM|wxLEFT, 5); + + m_textCtrlTitle = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0); + fgSizer8->Add(m_textCtrlTitle, 1, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5); + + m_staticText107 = new wxStaticText(m_scrolledWindow, wxID_ANY, wxT("Price"), wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT); + m_staticText107->Wrap(-1); + fgSizer8->Add(m_staticText107, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxTOP|wxBOTTOM|wxLEFT, 5); + + m_textCtrlPrice = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0); + m_textCtrlPrice->SetMinSize(wxSize(105,-1)); + + fgSizer8->Add(m_textCtrlPrice, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5); + + bSizer21->Add(fgSizer8, 0, wxEXPAND|wxTOP|wxRIGHT|wxLEFT, 5); + + m_staticText22 = new wxStaticText(m_scrolledWindow, wxID_ANY, wxT("Page 1: Description"), wxDefaultPosition, wxDefaultSize, 0); + m_staticText22->Wrap(-1); + bSizer21->Add(m_staticText22, 0, wxTOP|wxRIGHT|wxLEFT, 5); + + m_textCtrlDescription = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE); + m_textCtrlDescription->SetMinSize(wxSize(-1,170)); + + bSizer21->Add(m_textCtrlDescription, 0, wxALL|wxEXPAND, 5); + + m_staticText23 = new wxStaticText(m_scrolledWindow, wxID_ANY, wxT("Page 2: Order Form"), wxDefaultPosition, wxDefaultSize, 0); + m_staticText23->Wrap(-1); + bSizer21->Add(m_staticText23, 0, wxTOP|wxRIGHT|wxLEFT, 5); + + m_textCtrlInstructions = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE); + m_textCtrlInstructions->SetMinSize(wxSize(-1,120)); + + bSizer21->Add(m_textCtrlInstructions, 0, wxEXPAND|wxALL, 5); + + fgSizer5 = new wxFlexGridSizer(0, 3, 0, 0); + fgSizer5->AddGrowableCol(1); + fgSizer5->SetFlexibleDirection(wxBOTH); + fgSizer5->SetNonFlexibleGrowMode(wxFLEX_GROWMODE_SPECIFIED); + + m_staticText24 = new wxStaticText(m_scrolledWindow, wxID_ANY, wxT("Label"), wxDefaultPosition, wxDefaultSize, 0); + m_staticText24->Wrap(-1); + fgSizer5->Add(m_staticText24, 0, wxALIGN_CENTER_VERTICAL|wxTOP|wxRIGHT|wxLEFT, 5); + + m_staticText25 = new wxStaticText(m_scrolledWindow, wxID_ANY, wxT("Comma separated list of choices, or leave blank for text field"), wxDefaultPosition, wxDefaultSize, 0); + m_staticText25->Wrap(-1); + fgSizer5->Add(m_staticText25, 0, wxALIGN_CENTER_VERTICAL|wxTOP|wxRIGHT|wxLEFT, 5); + + + fgSizer5->Add(0, 0, 1, wxEXPAND, 5); + + m_textCtrlLabel0 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0); + m_textCtrlLabel0->SetMinSize(wxSize(150,-1)); + + fgSizer5->Add(m_textCtrlLabel0, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5); + + m_textCtrlField0 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(-1,-1), 0); + fgSizer5->Add(m_textCtrlField0, 0, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5); + + m_buttonDel0 = new wxButton(m_scrolledWindow, wxID_DEL0, wxT("Delete"), wxDefaultPosition, wxSize(60,20), 0); + fgSizer5->Add(m_buttonDel0, 0, wxRIGHT|wxLEFT|wxALIGN_CENTER_VERTICAL, 5); + + m_textCtrlLabel1 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0); + m_textCtrlLabel1->SetMinSize(wxSize(150,-1)); + + fgSizer5->Add(m_textCtrlLabel1, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5); + + m_textCtrlField1 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(-1,-1), 0); + fgSizer5->Add(m_textCtrlField1, 0, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5); + + m_buttonDel1 = new wxButton(m_scrolledWindow, wxID_DEL1, wxT("Delete"), wxDefaultPosition, wxSize(60,20), 0); + fgSizer5->Add(m_buttonDel1, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5); + + m_textCtrlLabel2 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0); + m_textCtrlLabel2->SetMinSize(wxSize(150,-1)); + + fgSizer5->Add(m_textCtrlLabel2, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5); + + m_textCtrlField2 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(-1,-1), 0); + fgSizer5->Add(m_textCtrlField2, 0, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5); + + m_buttonDel2 = new wxButton(m_scrolledWindow, wxID_DEL2, wxT("Delete"), wxDefaultPosition, wxSize(60,20), 0); + fgSizer5->Add(m_buttonDel2, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5); + + m_textCtrlLabel3 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0); + m_textCtrlLabel3->SetMinSize(wxSize(150,-1)); + + fgSizer5->Add(m_textCtrlLabel3, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5); + + m_textCtrlField3 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(-1,-1), 0); + fgSizer5->Add(m_textCtrlField3, 0, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5); + + m_buttonDel3 = new wxButton(m_scrolledWindow, wxID_DEL3, wxT("Delete"), wxDefaultPosition, wxSize(60,20), 0); + fgSizer5->Add(m_buttonDel3, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5); + + m_textCtrlLabel4 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0); + m_textCtrlLabel4->SetMinSize(wxSize(150,-1)); + + fgSizer5->Add(m_textCtrlLabel4, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5); + + m_textCtrlField4 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(-1,-1), 0); + fgSizer5->Add(m_textCtrlField4, 0, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5); + + m_buttonDel4 = new wxButton(m_scrolledWindow, wxID_DEL4, wxT("Delete"), wxDefaultPosition, wxSize(60,20), 0); + fgSizer5->Add(m_buttonDel4, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5); + + m_textCtrlLabel5 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0); + m_textCtrlLabel5->SetMinSize(wxSize(150,-1)); + + fgSizer5->Add(m_textCtrlLabel5, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5); + + m_textCtrlField5 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(-1,-1), 0); + fgSizer5->Add(m_textCtrlField5, 0, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5); + + m_buttonDel5 = new wxButton(m_scrolledWindow, wxID_DEL5, wxT("Delete"), wxDefaultPosition, wxSize(60,20), 0); + fgSizer5->Add(m_buttonDel5, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5); + + m_textCtrlLabel6 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0); + m_textCtrlLabel6->SetMinSize(wxSize(150,-1)); + + fgSizer5->Add(m_textCtrlLabel6, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5); + + m_textCtrlField6 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(-1,-1), 0); + fgSizer5->Add(m_textCtrlField6, 0, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5); + + m_buttonDel6 = new wxButton(m_scrolledWindow, wxID_DEL6, wxT("Delete"), wxDefaultPosition, wxSize(60,20), 0); + fgSizer5->Add(m_buttonDel6, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5); + + m_textCtrlLabel7 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0); + m_textCtrlLabel7->SetMinSize(wxSize(150,-1)); + + fgSizer5->Add(m_textCtrlLabel7, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5); + + m_textCtrlField7 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(-1,-1), 0); + fgSizer5->Add(m_textCtrlField7, 0, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5); + + m_buttonDel7 = new wxButton(m_scrolledWindow, wxID_DEL7, wxT("Delete"), wxDefaultPosition, wxSize(60,20), 0); + fgSizer5->Add(m_buttonDel7, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5); + + m_textCtrlLabel8 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0); + m_textCtrlLabel8->SetMinSize(wxSize(150,-1)); + + fgSizer5->Add(m_textCtrlLabel8, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5); + + m_textCtrlField8 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(-1,-1), 0); + fgSizer5->Add(m_textCtrlField8, 0, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5); + + m_buttonDel8 = new wxButton(m_scrolledWindow, wxID_DEL8, wxT("Delete"), wxDefaultPosition, wxSize(60,20), 0); + fgSizer5->Add(m_buttonDel8, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5); + + m_textCtrlLabel9 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0); + m_textCtrlLabel9->SetMinSize(wxSize(150,-1)); + + fgSizer5->Add(m_textCtrlLabel9, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5); + + m_textCtrlField9 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(-1,-1), 0); + fgSizer5->Add(m_textCtrlField9, 0, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5); + + m_buttonDel9 = new wxButton(m_scrolledWindow, wxID_DEL9, wxT("Delete"), wxDefaultPosition, wxSize(60,20), 0); + fgSizer5->Add(m_buttonDel9, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5); + + m_textCtrlLabel10 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0); + m_textCtrlLabel10->SetMinSize(wxSize(150,-1)); + + fgSizer5->Add(m_textCtrlLabel10, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5); + + m_textCtrlField10 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(-1,-1), 0); + fgSizer5->Add(m_textCtrlField10, 0, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5); + + m_buttonDel10 = new wxButton(m_scrolledWindow, wxID_DEL10, wxT("Delete"), wxDefaultPosition, wxSize(60,20), 0); + fgSizer5->Add(m_buttonDel10, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5); + + m_textCtrlLabel11 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0); + m_textCtrlLabel11->SetMinSize(wxSize(150,-1)); + + fgSizer5->Add(m_textCtrlLabel11, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5); + + m_textCtrlField11 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(-1,-1), 0); + fgSizer5->Add(m_textCtrlField11, 0, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5); + + m_buttonDel11 = new wxButton(m_scrolledWindow, wxID_DEL11, wxT("Delete"), wxDefaultPosition, wxSize(60,20), 0); + fgSizer5->Add(m_buttonDel11, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5); + + m_textCtrlLabel12 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0); + m_textCtrlLabel12->SetMinSize(wxSize(150,-1)); + + fgSizer5->Add(m_textCtrlLabel12, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5); + + m_textCtrlField12 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(-1,-1), 0); + fgSizer5->Add(m_textCtrlField12, 0, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5); + + m_buttonDel12 = new wxButton(m_scrolledWindow, wxID_DEL12, wxT("Delete"), wxDefaultPosition, wxSize(60,20), 0); + fgSizer5->Add(m_buttonDel12, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5); + + m_textCtrlLabel13 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0); + m_textCtrlLabel13->SetMinSize(wxSize(150,-1)); + + fgSizer5->Add(m_textCtrlLabel13, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5); + + m_textCtrlField13 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(-1,-1), 0); + fgSizer5->Add(m_textCtrlField13, 0, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5); + + m_buttonDel13 = new wxButton(m_scrolledWindow, wxID_DEL13, wxT("Delete"), wxDefaultPosition, wxSize(60,20), 0); + fgSizer5->Add(m_buttonDel13, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5); + + m_textCtrlLabel14 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0); + m_textCtrlLabel14->SetMinSize(wxSize(150,-1)); + + fgSizer5->Add(m_textCtrlLabel14, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5); + + m_textCtrlField14 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(-1,-1), 0); + fgSizer5->Add(m_textCtrlField14, 0, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5); + + m_buttonDel14 = new wxButton(m_scrolledWindow, wxID_DEL14, wxT("Delete"), wxDefaultPosition, wxSize(60,20), 0); + fgSizer5->Add(m_buttonDel14, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5); + + m_textCtrlLabel15 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0); + m_textCtrlLabel15->SetMinSize(wxSize(150,-1)); + + fgSizer5->Add(m_textCtrlLabel15, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5); + + m_textCtrlField15 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(-1,-1), 0); + fgSizer5->Add(m_textCtrlField15, 0, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5); + + m_buttonDel15 = new wxButton(m_scrolledWindow, wxID_DEL15, wxT("Delete"), wxDefaultPosition, wxSize(60,20), 0); + fgSizer5->Add(m_buttonDel15, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5); + + m_textCtrlLabel16 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0); + m_textCtrlLabel16->SetMinSize(wxSize(150,-1)); + + fgSizer5->Add(m_textCtrlLabel16, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5); + + m_textCtrlField16 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(-1,-1), 0); + fgSizer5->Add(m_textCtrlField16, 0, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5); + + m_buttonDel16 = new wxButton(m_scrolledWindow, wxID_DEL16, wxT("Delete"), wxDefaultPosition, wxSize(60,20), 0); + fgSizer5->Add(m_buttonDel16, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5); + + m_textCtrlLabel17 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0); + m_textCtrlLabel17->SetMinSize(wxSize(150,-1)); + + fgSizer5->Add(m_textCtrlLabel17, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5); + + m_textCtrlField17 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(-1,-1), 0); + fgSizer5->Add(m_textCtrlField17, 0, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5); + + m_buttonDel17 = new wxButton(m_scrolledWindow, wxID_DEL17, wxT("Delete"), wxDefaultPosition, wxSize(60,20), 0); + fgSizer5->Add(m_buttonDel17, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5); + + m_textCtrlLabel18 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0); + m_textCtrlLabel18->SetMinSize(wxSize(150,-1)); + + fgSizer5->Add(m_textCtrlLabel18, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5); + + m_textCtrlField18 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(-1,-1), 0); + fgSizer5->Add(m_textCtrlField18, 0, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5); + + m_buttonDel18 = new wxButton(m_scrolledWindow, wxID_DEL18, wxT("Delete"), wxDefaultPosition, wxSize(60,20), 0); + fgSizer5->Add(m_buttonDel18, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5); + + m_textCtrlLabel19 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0); + m_textCtrlLabel19->SetMinSize(wxSize(150,-1)); + + fgSizer5->Add(m_textCtrlLabel19, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5); + + m_textCtrlField19 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(-1,-1), 0); + fgSizer5->Add(m_textCtrlField19, 0, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5); + + m_buttonDel19 = new wxButton(m_scrolledWindow, wxID_DEL19, wxT("Delete"), wxDefaultPosition, wxSize(60,20), 0); + fgSizer5->Add(m_buttonDel19, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5); + + bSizer21->Add(fgSizer5, 0, wxEXPAND, 5); + + wxBoxSizer* bSizer25; + bSizer25 = new wxBoxSizer(wxHORIZONTAL); + + m_buttonAddField = new wxButton(m_scrolledWindow, wxID_ANY, wxT("&Add Field"), wxDefaultPosition, wxDefaultSize, 0); + bSizer25->Add(m_buttonAddField, 0, wxALL, 5); + + bSizer21->Add(bSizer25, 0, wxALIGN_CENTER_HORIZONTAL, 5); + + m_scrolledWindow->SetSizer(bSizer21); + m_scrolledWindow->Layout(); + bSizer21->Fit(m_scrolledWindow); + bSizer20->Add(m_scrolledWindow, 1, wxEXPAND|wxALL, 5); + + wxBoxSizer* bSizer26; + bSizer26 = new wxBoxSizer(wxHORIZONTAL); + + m_buttonOK = new wxButton(this, wxID_BUTTONSEND, wxT("&Send"), wxDefaultPosition, wxDefaultSize, 0); + m_buttonOK->SetMinSize(wxSize(85,25)); + + bSizer26->Add(m_buttonOK, 0, wxALL, 5); + + m_buttonPreview = new wxButton(this, wxID_BUTTONPREVIEW, wxT("&Preview"), wxDefaultPosition, wxDefaultSize, 0); + m_buttonPreview->SetMinSize(wxSize(85,25)); + + bSizer26->Add(m_buttonPreview, 0, wxALL, 5); + + m_buttonCancel = new wxButton(this, wxID_CANCEL, wxT("Cancel"), wxDefaultPosition, wxDefaultSize, 0); + m_buttonCancel->SetMinSize(wxSize(85,25)); + + bSizer26->Add(m_buttonCancel, 0, wxALL, 5); + + bSizer20->Add(bSizer26, 0, wxALIGN_RIGHT, 5); + + this->SetSizer(bSizer20); + this->Layout(); + + // Connect Events + m_textCtrlTitle->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); + m_textCtrlPrice->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); + m_textCtrlDescription->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); + m_textCtrlInstructions->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); + m_textCtrlLabel0->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); + m_textCtrlField0->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); + m_buttonDel0->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel0), NULL, this); + m_textCtrlLabel1->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); + m_textCtrlField1->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); + m_buttonDel1->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel1), NULL, this); + m_textCtrlLabel2->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); + m_textCtrlField2->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); + m_buttonDel2->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel2), NULL, this); + m_textCtrlLabel3->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); + m_textCtrlField3->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); + m_buttonDel3->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel3), NULL, this); + m_textCtrlLabel4->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); + m_textCtrlField4->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); + m_buttonDel4->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel4), NULL, this); + m_textCtrlLabel5->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); + m_textCtrlField5->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); + m_buttonDel5->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel5), NULL, this); + m_textCtrlLabel6->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); + m_textCtrlField6->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); + m_buttonDel6->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel6), NULL, this); + m_textCtrlLabel7->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); + m_textCtrlField7->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); + m_buttonDel7->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel7), NULL, this); + m_textCtrlLabel8->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); + m_textCtrlField8->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); + m_buttonDel8->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel8), NULL, this); + m_textCtrlLabel9->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); + m_textCtrlField9->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); + m_buttonDel9->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel9), NULL, this); + m_textCtrlLabel10->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); + m_textCtrlField10->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); + m_buttonDel10->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel10), NULL, this); + m_textCtrlLabel11->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); + m_textCtrlField11->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); + m_buttonDel11->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel11), NULL, this); + m_textCtrlLabel12->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); + m_textCtrlField12->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); + m_buttonDel12->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel12), NULL, this); + m_textCtrlLabel13->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); + m_textCtrlField13->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); + m_buttonDel13->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel13), NULL, this); + m_textCtrlLabel14->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); + m_textCtrlField14->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); + m_buttonDel14->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel14), NULL, this); + m_textCtrlLabel15->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); + m_textCtrlField15->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); + m_buttonDel15->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel15), NULL, this); + m_textCtrlLabel16->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); + m_textCtrlField16->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); + m_buttonDel16->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel16), NULL, this); + m_textCtrlLabel17->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); + m_textCtrlField17->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); + m_buttonDel17->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel17), NULL, this); + m_textCtrlLabel18->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); + m_textCtrlField18->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); + m_buttonDel18->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel18), NULL, this); + m_textCtrlLabel19->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); + m_textCtrlField19->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); + m_buttonDel19->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel19), NULL, this); + m_buttonAddField->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonAddField), NULL, this); + m_buttonOK->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonSend), NULL, this); + m_buttonPreview->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonPreview), NULL, this); + m_buttonCancel->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonCancel), NULL, this); +} + +CEditProductDialogBase::~CEditProductDialogBase() +{ + // Disconnect Events + m_textCtrlTitle->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); + m_textCtrlPrice->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); + m_textCtrlDescription->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); + m_textCtrlInstructions->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); + m_textCtrlLabel0->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); + m_textCtrlField0->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); + m_buttonDel0->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel0), NULL, this); + m_textCtrlLabel1->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); + m_textCtrlField1->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); + m_buttonDel1->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel1), NULL, this); + m_textCtrlLabel2->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); + m_textCtrlField2->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); + m_buttonDel2->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel2), NULL, this); + m_textCtrlLabel3->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); + m_textCtrlField3->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); + m_buttonDel3->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel3), NULL, this); + m_textCtrlLabel4->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); + m_textCtrlField4->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); + m_buttonDel4->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel4), NULL, this); + m_textCtrlLabel5->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); + m_textCtrlField5->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); + m_buttonDel5->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel5), NULL, this); + m_textCtrlLabel6->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); + m_textCtrlField6->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); + m_buttonDel6->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel6), NULL, this); + m_textCtrlLabel7->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); + m_textCtrlField7->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); + m_buttonDel7->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel7), NULL, this); + m_textCtrlLabel8->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); + m_textCtrlField8->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); + m_buttonDel8->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel8), NULL, this); + m_textCtrlLabel9->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); + m_textCtrlField9->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); + m_buttonDel9->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel9), NULL, this); + m_textCtrlLabel10->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); + m_textCtrlField10->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); + m_buttonDel10->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel10), NULL, this); + m_textCtrlLabel11->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); + m_textCtrlField11->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); + m_buttonDel11->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel11), NULL, this); + m_textCtrlLabel12->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); + m_textCtrlField12->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); + m_buttonDel12->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel12), NULL, this); + m_textCtrlLabel13->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); + m_textCtrlField13->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); + m_buttonDel13->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel13), NULL, this); + m_textCtrlLabel14->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); + m_textCtrlField14->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); + m_buttonDel14->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel14), NULL, this); + m_textCtrlLabel15->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); + m_textCtrlField15->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); + m_buttonDel15->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel15), NULL, this); + m_textCtrlLabel16->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); + m_textCtrlField16->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); + m_buttonDel16->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel16), NULL, this); + m_textCtrlLabel17->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); + m_textCtrlField17->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); + m_buttonDel17->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel17), NULL, this); + m_textCtrlLabel18->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); + m_textCtrlField18->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); + m_buttonDel18->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel18), NULL, this); + m_textCtrlLabel19->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); + m_textCtrlField19->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); + m_buttonDel19->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel19), NULL, this); + m_buttonAddField->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonAddField), NULL, this); + m_buttonOK->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonSend), NULL, this); + m_buttonPreview->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonPreview), NULL, this); + m_buttonCancel->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonCancel), NULL, this); +} + +CViewProductDialogBase::CViewProductDialogBase(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_MENU)); + + wxBoxSizer* bSizer20; + bSizer20 = new wxBoxSizer(wxVERTICAL); + + wxBoxSizer* bSizer116; + bSizer116 = new wxBoxSizer(wxHORIZONTAL); + + m_htmlWinReviews = new wxHtmlWindow(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxHW_SCROLLBAR_AUTO); + m_htmlWinReviews->Hide(); + + bSizer116->Add(m_htmlWinReviews, 1, wxALL|wxEXPAND, 5); + + m_scrolledWindow = new wxScrolledWindow(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxHSCROLL|wxTAB_TRAVERSAL|wxVSCROLL); + m_scrolledWindow->SetScrollRate(5, 5); + m_scrolledWindow->SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW)); + + wxBoxSizer* bSizer21; + bSizer21 = new wxBoxSizer(wxVERTICAL); + + m_richTextHeading = new wxRichTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(-1,50), wxTE_READONLY|wxNO_BORDER); + bSizer21->Add(m_richTextHeading, 0, wxEXPAND, 5); + + m_staticTextInstructions = new wxStaticText(m_scrolledWindow, wxID_ANY, wxT("Order Form instructions here\nmultiple lines\n1\n2\n3\n4\n5\n6"), wxDefaultPosition, wxDefaultSize, 0); + m_staticTextInstructions->Wrap(-1); + bSizer21->Add(m_staticTextInstructions, 0, wxALL|wxEXPAND, 5); + + wxBoxSizer* bSizer25; + bSizer25 = new wxBoxSizer(wxHORIZONTAL); + + m_buttonSubmitForm = new wxButton(m_scrolledWindow, wxID_BUTTONSAMPLE, wxT("&Submit"), wxDefaultPosition, wxDefaultSize, 0); + bSizer25->Add(m_buttonSubmitForm, 0, wxALL, 5); + + m_buttonCancelForm = new wxButton(m_scrolledWindow, wxID_CANCEL2, wxT("Cancel"), wxDefaultPosition, wxDefaultSize, 0); + bSizer25->Add(m_buttonCancelForm, 0, wxALL, 5); + + bSizer21->Add(bSizer25, 0, wxALIGN_CENTER_HORIZONTAL, 5); + + m_scrolledWindow->SetSizer(bSizer21); + m_scrolledWindow->Layout(); + bSizer21->Fit(m_scrolledWindow); + bSizer116->Add(m_scrolledWindow, 1, wxEXPAND|wxALL, 5); + + bSizer20->Add(bSizer116, 1, wxEXPAND, 5); + + wxBoxSizer* bSizer26; + bSizer26 = new wxBoxSizer(wxHORIZONTAL); + + m_buttonBack = new wxButton(this, wxID_BUTTONBACK, wxT("< &Back "), wxDefaultPosition, wxDefaultSize, 0); + m_buttonBack->Enable(false); + m_buttonBack->SetMinSize(wxSize(85,25)); + + bSizer26->Add(m_buttonBack, 0, wxALL, 5); + + m_buttonNext = new wxButton(this, wxID_BUTTONNEXT, wxT(" &Next >"), wxDefaultPosition, wxDefaultSize, 0); + m_buttonNext->SetMinSize(wxSize(85,25)); + + bSizer26->Add(m_buttonNext, 0, wxALL, 5); + + m_buttonCancel = new wxButton(this, wxID_CANCEL, wxT("Cancel"), wxDefaultPosition, wxDefaultSize, 0); + m_buttonCancel->SetMinSize(wxSize(85,25)); + + bSizer26->Add(m_buttonCancel, 0, wxALL, 5); + + bSizer20->Add(bSizer26, 0, wxALIGN_RIGHT, 5); + + this->SetSizer(bSizer20); + this->Layout(); + + // Connect Events + m_buttonSubmitForm->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CViewProductDialogBase::OnButtonSubmitForm), NULL, this); + m_buttonCancelForm->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CViewProductDialogBase::OnButtonCancelForm), NULL, this); + m_buttonBack->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CViewProductDialogBase::OnButtonBack), NULL, this); + m_buttonNext->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CViewProductDialogBase::OnButtonNext), NULL, this); + m_buttonCancel->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CViewProductDialogBase::OnButtonCancel), NULL, this); +} + +CViewProductDialogBase::~CViewProductDialogBase() +{ + // Disconnect Events + m_buttonSubmitForm->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CViewProductDialogBase::OnButtonSubmitForm), NULL, this); + m_buttonCancelForm->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CViewProductDialogBase::OnButtonCancelForm), NULL, this); + m_buttonBack->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CViewProductDialogBase::OnButtonBack), NULL, this); + m_buttonNext->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CViewProductDialogBase::OnButtonNext), NULL, this); + m_buttonCancel->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CViewProductDialogBase::OnButtonCancel), NULL, this); +} + +CViewOrderDialogBase::CViewOrderDialogBase(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_MENU)); + + wxBoxSizer* bSizer20; + bSizer20 = new wxBoxSizer(wxVERTICAL); + + wxBoxSizer* bSizer116; + bSizer116 = new wxBoxSizer(wxHORIZONTAL); + + m_htmlWin = new wxHtmlWindow(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxHW_SCROLLBAR_AUTO); + bSizer116->Add(m_htmlWin, 1, wxALL|wxEXPAND, 5); + + bSizer20->Add(bSizer116, 1, wxEXPAND, 5); + + wxBoxSizer* bSizer26; + bSizer26 = new wxBoxSizer(wxHORIZONTAL); + + m_buttonOK = new wxButton(this, wxID_OK, wxT("OK"), wxDefaultPosition, wxDefaultSize, 0); + m_buttonOK->SetMinSize(wxSize(85,25)); + + bSizer26->Add(m_buttonOK, 0, wxALL, 5); + + bSizer20->Add(bSizer26, 0, wxALIGN_RIGHT, 5); + + this->SetSizer(bSizer20); + this->Layout(); + + // Connect Events + m_buttonOK->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CViewOrderDialogBase::OnButtonOK), NULL, this); +} + +CViewOrderDialogBase::~CViewOrderDialogBase() +{ + // Disconnect Events + m_buttonOK->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CViewOrderDialogBase::OnButtonOK), NULL, this); +} + +CEditReviewDialogBase::CEditReviewDialogBase(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_MENU)); + + wxBoxSizer* bSizer112; + bSizer112 = new wxBoxSizer(wxVERTICAL); + + + bSizer112->Add(0, 3, 0, 0, 5); + + m_staticTextSeller = new wxStaticText(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0); + m_staticTextSeller->Wrap(-1); + bSizer112->Add(m_staticTextSeller, 0, wxALL|wxEXPAND, 5); + + + bSizer112->Add(0, 3, 0, 0, 5); + + m_staticText110 = new wxStaticText(this, wxID_ANY, wxT("Rating"), wxDefaultPosition, wxDefaultSize, 0); + m_staticText110->Wrap(-1); + bSizer112->Add(m_staticText110, 0, wxTOP|wxRIGHT|wxLEFT, 5); + + wxString m_choiceStarsChoices[] = { wxT(" 1 star"), wxT(" 2 stars"), wxT(" 3 stars"), wxT(" 4 stars"), wxT(" 5 stars") }; + int m_choiceStarsNChoices = sizeof(m_choiceStarsChoices) / sizeof(wxString); + m_choiceStars = new wxChoice(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, m_choiceStarsNChoices, m_choiceStarsChoices, 0); + m_choiceStars->SetSelection(0); + bSizer112->Add(m_choiceStars, 0, wxALL, 5); + + m_staticText43 = new wxStaticText(this, wxID_ANY, wxT("Review"), wxDefaultPosition, wxDefaultSize, 0); + m_staticText43->Wrap(-1); + bSizer112->Add(m_staticText43, 0, wxTOP|wxRIGHT|wxLEFT, 5); + + m_textCtrlReview = new wxTextCtrl(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE); + bSizer112->Add(m_textCtrlReview, 1, wxALL|wxEXPAND, 5); + + wxBoxSizer* bSizer113; + bSizer113 = new wxBoxSizer(wxHORIZONTAL); + + m_buttonSubmit = new wxButton(this, wxID_SUBMIT, wxT("&Submit"), wxDefaultPosition, wxDefaultSize, 0); + m_buttonSubmit->SetMinSize(wxSize(85,25)); + + bSizer113->Add(m_buttonSubmit, 0, wxALL, 5); + + m_buttonCancel = new wxButton(this, wxID_CANCEL, wxT("Cancel"), wxDefaultPosition, wxDefaultSize, 0); + m_buttonCancel->SetMinSize(wxSize(85,25)); + + bSizer113->Add(m_buttonCancel, 0, wxALL, 5); + + bSizer112->Add(bSizer113, 0, wxALIGN_RIGHT, 5); + + this->SetSizer(bSizer112); + this->Layout(); + + // Connect Events + m_textCtrlReview->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditReviewDialogBase::OnKeyDown), NULL, this); + m_buttonSubmit->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditReviewDialogBase::OnButtonSubmit), NULL, this); + m_buttonCancel->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditReviewDialogBase::OnButtonCancel), NULL, this); +} + +CEditReviewDialogBase::~CEditReviewDialogBase() +{ + // Disconnect Events + m_textCtrlReview->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditReviewDialogBase::OnKeyDown), NULL, this); + m_buttonSubmit->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditReviewDialogBase::OnButtonSubmit), NULL, this); + m_buttonCancel->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditReviewDialogBase::OnButtonCancel), NULL, this); +} + +CPokerLobbyDialogBase::CPokerLobbyDialogBase(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)); + + wxBoxSizer* bSizer156; + bSizer156 = new wxBoxSizer(wxHORIZONTAL); + + m_treeCtrl = new wxTreeCtrl(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTR_HAS_BUTTONS|wxTR_HIDE_ROOT|wxTR_LINES_AT_ROOT); + m_treeCtrl->SetMinSize(wxSize(130,-1)); + + bSizer156->Add(m_treeCtrl, 0, wxEXPAND|wxTOP|wxBOTTOM|wxLEFT, 5); + + wxBoxSizer* bSizer172; + bSizer172 = new wxBoxSizer(wxVERTICAL); + + m_listCtrl = new wxListCtrl(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_NO_SORT_HEADER|wxLC_REPORT); + bSizer172->Add(m_listCtrl, 1, wxEXPAND|wxALL, 5); + + m_buttonNewTable = new wxButton(this, wxID_OPENNEWTABLE, wxT("&Open New Table"), wxDefaultPosition, wxDefaultSize, 0); + bSizer172->Add(m_buttonNewTable, 0, wxALL, 5); + + bSizer156->Add(bSizer172, 1, wxEXPAND, 5); + + this->SetSizer(bSizer156); + this->Layout(); + + // Connect Events + m_treeCtrl->Connect(wxEVT_COMMAND_TREE_SEL_CHANGED, wxTreeEventHandler(CPokerLobbyDialogBase::OnTreeSelChanged), NULL, this); + m_listCtrl->Connect(wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler(CPokerLobbyDialogBase::OnListItemActivated), NULL, this); + m_listCtrl->Connect(wxEVT_COMMAND_LIST_ITEM_SELECTED, wxListEventHandler(CPokerLobbyDialogBase::OnListItemSelected), NULL, this); + m_buttonNewTable->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CPokerLobbyDialogBase::OnButtonNewTable), NULL, this); +} + +CPokerLobbyDialogBase::~CPokerLobbyDialogBase() +{ + // Disconnect Events + m_treeCtrl->Disconnect(wxEVT_COMMAND_TREE_SEL_CHANGED, wxTreeEventHandler(CPokerLobbyDialogBase::OnTreeSelChanged), NULL, this); + m_listCtrl->Disconnect(wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler(CPokerLobbyDialogBase::OnListItemActivated), NULL, this); + m_listCtrl->Disconnect(wxEVT_COMMAND_LIST_ITEM_SELECTED, wxListEventHandler(CPokerLobbyDialogBase::OnListItemSelected), NULL, this); + m_buttonNewTable->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CPokerLobbyDialogBase::OnButtonNewTable), NULL, this); +} + +CPokerDialogBase::CPokerDialogBase(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); + + wxBoxSizer* bSizer174; + bSizer174 = new wxBoxSizer(wxVERTICAL); + + m_checkSitOut = new wxCheckBox(this, wxID_ANY, wxT("Deal Me Out"), wxDefaultPosition, wxDefaultSize, 0); + + bSizer174->Add(m_checkSitOut, 0, wxALL, 5); + + m_buttonDealHand = new wxButton(this, wxID_DEALHAND, wxT("&Deal Hand"), wxDefaultPosition, wxSize(150,25), 0); + bSizer174->Add(m_buttonDealHand, 0, wxALL, 5); + + m_buttonFold = new wxButton(this, wxID_FOLD, wxT("&Fold"), wxDefaultPosition, wxSize(80,25), 0); + bSizer174->Add(m_buttonFold, 0, wxALL, 5); + + m_buttonCall = new wxButton(this, wxID_CALL, wxT("&Call"), wxDefaultPosition, wxSize(80,25), 0); + bSizer174->Add(m_buttonCall, 0, wxALL, 5); + + m_buttonRaise = new wxButton(this, wxID_RAISE, wxT("&Raise"), wxDefaultPosition, wxSize(80,25), 0); + bSizer174->Add(m_buttonRaise, 0, wxALL, 5); + + m_buttonLeaveTable = new wxButton(this, wxID_LEAVETABLE, wxT("&Leave Table"), wxDefaultPosition, wxSize(90,25), 0); + bSizer174->Add(m_buttonLeaveTable, 0, wxALL, 5); + + m_textDitchPlayer = new wxTextCtrl(this, wxID_DITCHPLAYER, wxEmptyString, wxDefaultPosition, wxSize(45,-1), wxTE_PROCESS_ENTER); + bSizer174->Add(m_textDitchPlayer, 0, wxALL, 5); + + m_checkPreFold = new wxCheckBox(this, wxID_ANY, wxT("FOLD"), wxDefaultPosition, wxSize(100,-1), 0); + + bSizer174->Add(m_checkPreFold, 0, wxALL, 5); + + m_checkPreCall = new wxCheckBox(this, wxID_ANY, wxT("CALL"), wxDefaultPosition, wxSize(100,-1), 0); + + bSizer174->Add(m_checkPreCall, 0, wxALL, 5); + + m_checkPreCallAny = new wxCheckBox(this, wxID_ANY, wxT("CALL ANY"), wxDefaultPosition, wxSize(100,-1), 0); + + bSizer174->Add(m_checkPreCallAny, 0, wxALL, 5); + + m_checkPreRaise = new wxCheckBox(this, wxID_ANY, wxT("RAISE"), wxDefaultPosition, wxSize(100,-1), 0); + + bSizer174->Add(m_checkPreRaise, 0, wxALL, 5); + + m_checkPreRaiseAny = new wxCheckBox(this, wxID_ANY, wxT("RAISE ANY"), wxDefaultPosition, wxSize(100,-1), 0); + + bSizer174->Add(m_checkPreRaiseAny, 0, wxALL, 5); + + this->SetSizer(bSizer174); + this->Layout(); + m_statusBar = this->CreateStatusBar(1, wxST_SIZEGRIP, wxID_ANY); + + // Connect Events + this->Connect(wxEVT_CLOSE_WINDOW, wxCloseEventHandler(CPokerDialogBase::OnClose)); + this->Connect(wxEVT_LEFT_DOWN, wxMouseEventHandler(CPokerDialogBase::OnMouseEvents)); + this->Connect(wxEVT_LEFT_UP, wxMouseEventHandler(CPokerDialogBase::OnMouseEvents)); + this->Connect(wxEVT_MIDDLE_DOWN, wxMouseEventHandler(CPokerDialogBase::OnMouseEvents)); + this->Connect(wxEVT_MIDDLE_UP, wxMouseEventHandler(CPokerDialogBase::OnMouseEvents)); + this->Connect(wxEVT_RIGHT_DOWN, wxMouseEventHandler(CPokerDialogBase::OnMouseEvents)); + this->Connect(wxEVT_RIGHT_UP, wxMouseEventHandler(CPokerDialogBase::OnMouseEvents)); + this->Connect(wxEVT_MOTION, wxMouseEventHandler(CPokerDialogBase::OnMouseEvents)); + this->Connect(wxEVT_LEFT_DCLICK, wxMouseEventHandler(CPokerDialogBase::OnMouseEvents)); + this->Connect(wxEVT_MIDDLE_DCLICK, wxMouseEventHandler(CPokerDialogBase::OnMouseEvents)); + this->Connect(wxEVT_RIGHT_DCLICK, wxMouseEventHandler(CPokerDialogBase::OnMouseEvents)); + this->Connect(wxEVT_LEAVE_WINDOW, wxMouseEventHandler(CPokerDialogBase::OnMouseEvents)); + this->Connect(wxEVT_ENTER_WINDOW, wxMouseEventHandler(CPokerDialogBase::OnMouseEvents)); + this->Connect(wxEVT_MOUSEWHEEL, wxMouseEventHandler(CPokerDialogBase::OnMouseEvents)); + this->Connect(wxEVT_PAINT, wxPaintEventHandler(CPokerDialogBase::OnPaint)); + this->Connect(wxEVT_SIZE, wxSizeEventHandler(CPokerDialogBase::OnSize)); + m_checkSitOut->Connect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler(CPokerDialogBase::OnCheckSitOut), NULL, this); + m_buttonDealHand->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CPokerDialogBase::OnButtonDealHand), NULL, this); + m_buttonFold->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CPokerDialogBase::OnButtonFold), NULL, this); + m_buttonCall->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CPokerDialogBase::OnButtonCall), NULL, this); + m_buttonRaise->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CPokerDialogBase::OnButtonRaise), NULL, this); + m_buttonLeaveTable->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CPokerDialogBase::OnButtonLeaveTable), NULL, this); + m_textDitchPlayer->Connect(wxEVT_COMMAND_TEXT_ENTER, wxCommandEventHandler(CPokerDialogBase::OnDitchPlayer), NULL, this); + m_checkPreFold->Connect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler(CPokerDialogBase::OnCheckPreFold), NULL, this); + m_checkPreCall->Connect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler(CPokerDialogBase::OnCheckPreCall), NULL, this); + m_checkPreCallAny->Connect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler(CPokerDialogBase::OnCheckPreCallAny), NULL, this); + m_checkPreRaise->Connect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler(CPokerDialogBase::OnCheckPreRaise), NULL, this); + m_checkPreRaiseAny->Connect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler(CPokerDialogBase::OnCheckPreRaiseAny), NULL, this); +} + +CPokerDialogBase::~CPokerDialogBase() +{ + // Disconnect Events + this->Disconnect(wxEVT_CLOSE_WINDOW, wxCloseEventHandler(CPokerDialogBase::OnClose)); + this->Disconnect(wxEVT_LEFT_DOWN, wxMouseEventHandler(CPokerDialogBase::OnMouseEvents)); + this->Disconnect(wxEVT_LEFT_UP, wxMouseEventHandler(CPokerDialogBase::OnMouseEvents)); + this->Disconnect(wxEVT_MIDDLE_DOWN, wxMouseEventHandler(CPokerDialogBase::OnMouseEvents)); + this->Disconnect(wxEVT_MIDDLE_UP, wxMouseEventHandler(CPokerDialogBase::OnMouseEvents)); + this->Disconnect(wxEVT_RIGHT_DOWN, wxMouseEventHandler(CPokerDialogBase::OnMouseEvents)); + this->Disconnect(wxEVT_RIGHT_UP, wxMouseEventHandler(CPokerDialogBase::OnMouseEvents)); + this->Disconnect(wxEVT_MOTION, wxMouseEventHandler(CPokerDialogBase::OnMouseEvents)); + this->Disconnect(wxEVT_LEFT_DCLICK, wxMouseEventHandler(CPokerDialogBase::OnMouseEvents)); + this->Disconnect(wxEVT_MIDDLE_DCLICK, wxMouseEventHandler(CPokerDialogBase::OnMouseEvents)); + this->Disconnect(wxEVT_RIGHT_DCLICK, wxMouseEventHandler(CPokerDialogBase::OnMouseEvents)); + this->Disconnect(wxEVT_LEAVE_WINDOW, wxMouseEventHandler(CPokerDialogBase::OnMouseEvents)); + this->Disconnect(wxEVT_ENTER_WINDOW, wxMouseEventHandler(CPokerDialogBase::OnMouseEvents)); + this->Disconnect(wxEVT_MOUSEWHEEL, wxMouseEventHandler(CPokerDialogBase::OnMouseEvents)); + this->Disconnect(wxEVT_PAINT, wxPaintEventHandler(CPokerDialogBase::OnPaint)); + this->Disconnect(wxEVT_SIZE, wxSizeEventHandler(CPokerDialogBase::OnSize)); + m_checkSitOut->Disconnect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler(CPokerDialogBase::OnCheckSitOut), NULL, this); + m_buttonDealHand->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CPokerDialogBase::OnButtonDealHand), NULL, this); + m_buttonFold->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CPokerDialogBase::OnButtonFold), NULL, this); + m_buttonCall->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CPokerDialogBase::OnButtonCall), NULL, this); + m_buttonRaise->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CPokerDialogBase::OnButtonRaise), NULL, this); + m_buttonLeaveTable->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CPokerDialogBase::OnButtonLeaveTable), NULL, this); + m_textDitchPlayer->Disconnect(wxEVT_COMMAND_TEXT_ENTER, wxCommandEventHandler(CPokerDialogBase::OnDitchPlayer), NULL, this); + m_checkPreFold->Disconnect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler(CPokerDialogBase::OnCheckPreFold), NULL, this); + m_checkPreCall->Disconnect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler(CPokerDialogBase::OnCheckPreCall), NULL, this); + m_checkPreCallAny->Disconnect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler(CPokerDialogBase::OnCheckPreCallAny), NULL, this); + m_checkPreRaise->Disconnect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler(CPokerDialogBase::OnCheckPreRaise), NULL, this); + m_checkPreRaiseAny->Disconnect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler(CPokerDialogBase::OnCheckPreRaiseAny), 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, wxT("OK"), wxDefaultPosition, wxSize(-1,-1), 0); + m_buttonOK->SetMinSize(wxSize(85,25)); + + bSizer80->Add(m_buttonOK, 0, wxALL, 5); + + m_buttonCancel = new wxButton(this, wxID_CANCEL, wxT("Cancel"), wxDefaultPosition, wxDefaultSize, 0); + m_buttonCancel->SetMinSize(wxSize(85,25)); + + bSizer80->Add(m_buttonCancel, 0, wxALL, 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/uibase.h b/uibase.h new file mode 100644 index 0000000000..bfcd8eccb8 --- /dev/null +++ b/uibase.h @@ -0,0 +1,723 @@ +// Copyright (c) 2009 Satoshi Nakamoto +// Distributed under the MIT/X11 software license, see the accompanying +// file license.txt or http://www.opensource.org/licenses/mit-license.php. + +/////////////////////////////////////////////////////////////////////////// +// C++ code generated with wxFormBuilder (version Apr 16 2008) +// http://www.wxformbuilder.org/ +// +// PLEASE DO "NOT" EDIT THIS FILE! +/////////////////////////////////////////////////////////////////////////// + +#ifndef __uibase__ +#define __uibase__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/////////////////////////////////////////////////////////////////////////// + +#define wxID_MAINFRAME 1000 +#define wxID_OPTIONSGENERATEBITCOINS 1001 +#define wxID_BUTTONSEND 1002 +#define wxID_BUTTONRECEIVE 1003 +#define wxID_TEXTCTRLADDRESS 1004 +#define wxID_BUTTONCOPY 1005 +#define wxID_BUTTONCHANGE 1006 +#define wxID_TRANSACTIONFEE 1007 +#define wxID_TEXTCTRLPAYTO 1008 +#define wxID_BUTTONPASTE 1009 +#define wxID_BUTTONADDRESSBOOK 1010 +#define wxID_TEXTCTRLAMOUNT 1011 +#define wxID_CHOICETRANSFERTYPE 1012 +#define wxID_LISTCTRL 1013 +#define wxID_BUTTONRENAME 1014 +#define wxID_BUTTONNEW 1015 +#define wxID_BUTTONEDIT 1016 +#define wxID_BUTTONDELETE 1017 +#define wxID_DEL0 1018 +#define wxID_DEL1 1019 +#define wxID_DEL2 1020 +#define wxID_DEL3 1021 +#define wxID_DEL4 1022 +#define wxID_DEL5 1023 +#define wxID_DEL6 1024 +#define wxID_DEL7 1025 +#define wxID_DEL8 1026 +#define wxID_DEL9 1027 +#define wxID_DEL10 1028 +#define wxID_DEL11 1029 +#define wxID_DEL12 1030 +#define wxID_DEL13 1031 +#define wxID_DEL14 1032 +#define wxID_DEL15 1033 +#define wxID_DEL16 1034 +#define wxID_DEL17 1035 +#define wxID_DEL18 1036 +#define wxID_DEL19 1037 +#define wxID_BUTTONPREVIEW 1038 +#define wxID_BUTTONSAMPLE 1039 +#define wxID_CANCEL2 1040 +#define wxID_BUTTONBACK 1041 +#define wxID_BUTTONNEXT 1042 +#define wxID_SUBMIT 1043 +#define wxID_OPENNEWTABLE 1044 +#define wxID_DEALHAND 1045 +#define wxID_FOLD 1046 +#define wxID_CALL 1047 +#define wxID_RAISE 1048 +#define wxID_LEAVETABLE 1049 +#define wxID_DITCHPLAYER 1050 +#define wxID_TEXTCTRL 1051 + +/////////////////////////////////////////////////////////////////////////////// +/// Class CMainFrameBase +/////////////////////////////////////////////////////////////////////////////// +class CMainFrameBase : public wxFrame +{ +private: + +protected: + wxMenuBar* m_menubar; + wxMenu* m_menuFile; + wxMenu* m_menuHelp; + wxToolBar* m_toolBar; + wxStatusBar* m_statusBar; + + wxStaticText* m_staticText32; + wxTextCtrl* m_textCtrlAddress; + wxButton* m_buttonCopy; + wxButton* m_button91; + + wxPanel* m_panel14; + wxStaticText* m_staticText41; + wxStaticText* m_staticTextBalance; + + wxChoice* m_choiceFilter; + wxNotebook* m_notebook; + wxPanel* m_panel7; + wxPanel* m_panel9; + wxPanel* m_panel8; + wxPanel* m_panel10; + wxPanel* m_panel11; + + // Virtual event handlers, overide them in your derived class + virtual void OnClose(wxCloseEvent& 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 OnMenuOptionsGenerate(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 OnButtonCopy(wxCommandEvent& event){ event.Skip(); } + virtual void OnButtonChange(wxCommandEvent& event){ event.Skip(); } + virtual void OnListColBeginDrag(wxListEvent& event){ event.Skip(); } + virtual void OnListItemActivatedAllTransactions(wxListEvent& event){ event.Skip(); } + virtual void OnPaintListCtrl(wxPaintEvent& event){ event.Skip(); } + virtual void OnListItemActivatedOrdersSent(wxListEvent& event){ event.Skip(); } + virtual void OnListItemActivatedProductsSent(wxListEvent& event){ event.Skip(); } + virtual void OnListItemActivatedOrdersReceived(wxListEvent& event){ event.Skip(); } + + +public: + wxMenu* m_menuOptions; + wxListCtrl* m_listCtrl; + wxListCtrl* m_listCtrlEscrows; + wxListCtrl* m_listCtrlOrdersSent; + wxListCtrl* m_listCtrlProductsSent; + wxListCtrl* m_listCtrlOrdersReceived; + CMainFrameBase(wxWindow* parent, wxWindowID id = wxID_MAINFRAME, const wxString& title = wxT("Bitcoin"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize(705,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 = wxT("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: + + wxStaticText* m_staticText32; + wxStaticText* m_staticText31; + wxTextCtrl* m_textCtrlTransactionFee; + wxButton* m_buttonOK; + wxButton* m_buttonCancel; + + // Virtual event handlers, overide them in your derived class + virtual void OnKillFocusTransactionFee(wxFocusEvent& event){ event.Skip(); } + virtual void OnButtonOK(wxCommandEvent& event){ event.Skip(); } + virtual void OnButtonCancel(wxCommandEvent& event){ event.Skip(); } + + +public: + COptionsDialogBase(wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxT("Options"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize(500,261), long style = wxDEFAULT_DIALOG_STYLE); + ~COptionsDialogBase(); + +}; + +/////////////////////////////////////////////////////////////////////////////// +/// Class CAboutDialogBase +/////////////////////////////////////////////////////////////////////////////// +class CAboutDialogBase : public wxDialog +{ +private: + +protected: + + + 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 = wxT("About Bitcoin"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize(507,298), long style = wxDEFAULT_DIALOG_STYLE); + ~CAboutDialogBase(); + +}; + +/////////////////////////////////////////////////////////////////////////////// +/// Class CSendDialogBase +/////////////////////////////////////////////////////////////////////////////// +class CSendDialogBase : public wxDialog +{ +private: + +protected: + + + wxStaticText* m_staticText14; + + 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; + + + wxStaticText* m_staticTextFrom; + wxTextCtrl* m_textCtrlFrom; + wxStaticText* m_staticTextMessage; + wxTextCtrl* m_textCtrlMessage; + + 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 = wxT("Send Coins"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize(675,312), 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 = wxT("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 = wxT("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: + + wxStaticText* m_staticText55; + wxListCtrl* m_listCtrl; + + wxButton* m_buttonEdit; + wxButton* m_buttonNew; + wxButton* m_buttonDelete; + wxButton* m_buttonOK; + + // 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 OnButtonEdit(wxCommandEvent& event){ event.Skip(); } + virtual void OnButtonNew(wxCommandEvent& event){ event.Skip(); } + virtual void OnButtonDelete(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 = wxT("Address Book"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize(610,390), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER); + ~CAddressBookDialogBase(); + +}; + +/////////////////////////////////////////////////////////////////////////////// +/// Class CProductsDialogBase +/////////////////////////////////////////////////////////////////////////////// +class CProductsDialogBase : public wxDialog +{ +private: + +protected: + wxComboBox* m_comboBoxCategory; + wxTextCtrl* m_textCtrlSearch; + wxButton* m_buttonSearch; + wxListCtrl* m_listCtrl; + + // Virtual event handlers, overide them in your derived class + virtual void OnCombobox(wxCommandEvent& event){ event.Skip(); } + virtual void OnKeyDown(wxKeyEvent& event){ event.Skip(); } + virtual void OnButtonSearch(wxCommandEvent& event){ event.Skip(); } + virtual void OnListItemActivated(wxListEvent& event){ event.Skip(); } + + +public: + CProductsDialogBase(wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxT("Marketplace"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize(708,535), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER); + ~CProductsDialogBase(); + +}; + +/////////////////////////////////////////////////////////////////////////////// +/// Class CEditProductDialogBase +/////////////////////////////////////////////////////////////////////////////// +class CEditProductDialogBase : public wxFrame +{ +private: + +protected: + wxScrolledWindow* m_scrolledWindow; + wxStaticText* m_staticText106; + wxComboBox* m_comboBoxCategory; + wxStaticText* m_staticText108; + wxTextCtrl* m_textCtrlTitle; + wxStaticText* m_staticText107; + wxTextCtrl* m_textCtrlPrice; + wxStaticText* m_staticText22; + wxTextCtrl* m_textCtrlDescription; + wxStaticText* m_staticText23; + wxTextCtrl* m_textCtrlInstructions; + wxStaticText* m_staticText24; + wxStaticText* m_staticText25; + + wxTextCtrl* m_textCtrlLabel0; + wxTextCtrl* m_textCtrlField0; + wxButton* m_buttonDel0; + wxTextCtrl* m_textCtrlLabel1; + wxTextCtrl* m_textCtrlField1; + wxButton* m_buttonDel1; + wxTextCtrl* m_textCtrlLabel2; + wxTextCtrl* m_textCtrlField2; + wxButton* m_buttonDel2; + wxTextCtrl* m_textCtrlLabel3; + wxTextCtrl* m_textCtrlField3; + wxButton* m_buttonDel3; + wxTextCtrl* m_textCtrlLabel4; + wxTextCtrl* m_textCtrlField4; + wxButton* m_buttonDel4; + wxTextCtrl* m_textCtrlLabel5; + wxTextCtrl* m_textCtrlField5; + wxButton* m_buttonDel5; + wxTextCtrl* m_textCtrlLabel6; + wxTextCtrl* m_textCtrlField6; + wxButton* m_buttonDel6; + wxTextCtrl* m_textCtrlLabel7; + wxTextCtrl* m_textCtrlField7; + wxButton* m_buttonDel7; + wxTextCtrl* m_textCtrlLabel8; + wxTextCtrl* m_textCtrlField8; + wxButton* m_buttonDel8; + wxTextCtrl* m_textCtrlLabel9; + wxTextCtrl* m_textCtrlField9; + wxButton* m_buttonDel9; + wxTextCtrl* m_textCtrlLabel10; + wxTextCtrl* m_textCtrlField10; + wxButton* m_buttonDel10; + wxTextCtrl* m_textCtrlLabel11; + wxTextCtrl* m_textCtrlField11; + wxButton* m_buttonDel11; + wxTextCtrl* m_textCtrlLabel12; + wxTextCtrl* m_textCtrlField12; + wxButton* m_buttonDel12; + wxTextCtrl* m_textCtrlLabel13; + wxTextCtrl* m_textCtrlField13; + wxButton* m_buttonDel13; + wxTextCtrl* m_textCtrlLabel14; + wxTextCtrl* m_textCtrlField14; + wxButton* m_buttonDel14; + wxTextCtrl* m_textCtrlLabel15; + wxTextCtrl* m_textCtrlField15; + wxButton* m_buttonDel15; + wxTextCtrl* m_textCtrlLabel16; + wxTextCtrl* m_textCtrlField16; + wxButton* m_buttonDel16; + wxTextCtrl* m_textCtrlLabel17; + wxTextCtrl* m_textCtrlField17; + wxButton* m_buttonDel17; + wxTextCtrl* m_textCtrlLabel18; + wxTextCtrl* m_textCtrlField18; + wxButton* m_buttonDel18; + wxTextCtrl* m_textCtrlLabel19; + wxTextCtrl* m_textCtrlField19; + wxButton* m_buttonDel19; + wxButton* m_buttonAddField; + wxButton* m_buttonOK; + wxButton* m_buttonPreview; + wxButton* m_buttonCancel; + + // Virtual event handlers, overide them in your derived class + virtual void OnKeyDown(wxKeyEvent& event){ event.Skip(); } + virtual void OnButtonDel0(wxCommandEvent& event){ event.Skip(); } + virtual void OnButtonDel1(wxCommandEvent& event){ event.Skip(); } + virtual void OnButtonDel2(wxCommandEvent& event){ event.Skip(); } + virtual void OnButtonDel3(wxCommandEvent& event){ event.Skip(); } + virtual void OnButtonDel4(wxCommandEvent& event){ event.Skip(); } + virtual void OnButtonDel5(wxCommandEvent& event){ event.Skip(); } + virtual void OnButtonDel6(wxCommandEvent& event){ event.Skip(); } + virtual void OnButtonDel7(wxCommandEvent& event){ event.Skip(); } + virtual void OnButtonDel8(wxCommandEvent& event){ event.Skip(); } + virtual void OnButtonDel9(wxCommandEvent& event){ event.Skip(); } + virtual void OnButtonDel10(wxCommandEvent& event){ event.Skip(); } + virtual void OnButtonDel11(wxCommandEvent& event){ event.Skip(); } + virtual void OnButtonDel12(wxCommandEvent& event){ event.Skip(); } + virtual void OnButtonDel13(wxCommandEvent& event){ event.Skip(); } + virtual void OnButtonDel14(wxCommandEvent& event){ event.Skip(); } + virtual void OnButtonDel15(wxCommandEvent& event){ event.Skip(); } + virtual void OnButtonDel16(wxCommandEvent& event){ event.Skip(); } + virtual void OnButtonDel17(wxCommandEvent& event){ event.Skip(); } + virtual void OnButtonDel18(wxCommandEvent& event){ event.Skip(); } + virtual void OnButtonDel19(wxCommandEvent& event){ event.Skip(); } + virtual void OnButtonAddField(wxCommandEvent& event){ event.Skip(); } + virtual void OnButtonSend(wxCommandEvent& event){ event.Skip(); } + virtual void OnButtonPreview(wxCommandEvent& event){ event.Skip(); } + virtual void OnButtonCancel(wxCommandEvent& event){ event.Skip(); } + + +public: + wxFlexGridSizer* fgSizer5; + CEditProductDialogBase(wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxT("Edit Product"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize(660,640), long style = wxDEFAULT_FRAME_STYLE|wxRESIZE_BORDER|wxTAB_TRAVERSAL); + ~CEditProductDialogBase(); + +}; + +/////////////////////////////////////////////////////////////////////////////// +/// Class CViewProductDialogBase +/////////////////////////////////////////////////////////////////////////////// +class CViewProductDialogBase : public wxFrame +{ +private: + +protected: + wxHtmlWindow* m_htmlWinReviews; + wxScrolledWindow* m_scrolledWindow; + wxRichTextCtrl* m_richTextHeading; + wxStaticText* m_staticTextInstructions; + wxButton* m_buttonSubmitForm; + wxButton* m_buttonCancelForm; + wxButton* m_buttonBack; + wxButton* m_buttonNext; + wxButton* m_buttonCancel; + + // Virtual event handlers, overide them in your derived class + virtual void OnButtonSubmitForm(wxCommandEvent& event){ event.Skip(); } + virtual void OnButtonCancelForm(wxCommandEvent& event){ event.Skip(); } + virtual void OnButtonBack(wxCommandEvent& event){ event.Skip(); } + virtual void OnButtonNext(wxCommandEvent& event){ event.Skip(); } + virtual void OnButtonCancel(wxCommandEvent& event){ event.Skip(); } + + +public: + CViewProductDialogBase(wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxT("Order Form"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize(630,520), long style = wxDEFAULT_FRAME_STYLE|wxRESIZE_BORDER|wxTAB_TRAVERSAL); + ~CViewProductDialogBase(); + +}; + +/////////////////////////////////////////////////////////////////////////////// +/// Class CViewOrderDialogBase +/////////////////////////////////////////////////////////////////////////////// +class CViewOrderDialogBase : public wxFrame +{ +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: + CViewOrderDialogBase(wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxT("View Order"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize(630,520), long style = wxDEFAULT_FRAME_STYLE|wxRESIZE_BORDER|wxTAB_TRAVERSAL); + ~CViewOrderDialogBase(); + +}; + +/////////////////////////////////////////////////////////////////////////////// +/// Class CEditReviewDialogBase +/////////////////////////////////////////////////////////////////////////////// +class CEditReviewDialogBase : public wxFrame +{ +private: + +protected: + + wxStaticText* m_staticTextSeller; + + wxStaticText* m_staticText110; + wxChoice* m_choiceStars; + wxStaticText* m_staticText43; + wxTextCtrl* m_textCtrlReview; + wxButton* m_buttonSubmit; + wxButton* m_buttonCancel; + + // Virtual event handlers, overide them in your derived class + virtual void OnKeyDown(wxKeyEvent& event){ event.Skip(); } + virtual void OnButtonSubmit(wxCommandEvent& event){ event.Skip(); } + virtual void OnButtonCancel(wxCommandEvent& event){ event.Skip(); } + + +public: + CEditReviewDialogBase(wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxT("Enter Review"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize(630,440), long style = wxDEFAULT_FRAME_STYLE|wxRESIZE_BORDER|wxTAB_TRAVERSAL); + ~CEditReviewDialogBase(); + +}; + +/////////////////////////////////////////////////////////////////////////////// +/// Class CPokerLobbyDialogBase +/////////////////////////////////////////////////////////////////////////////// +class CPokerLobbyDialogBase : public wxFrame +{ +private: + +protected: + wxTreeCtrl* m_treeCtrl; + wxListCtrl* m_listCtrl; + wxButton* m_buttonNewTable; + + // Virtual event handlers, overide them in your derived class + virtual void OnTreeSelChanged(wxTreeEvent& event){ event.Skip(); } + virtual void OnListItemActivated(wxListEvent& event){ event.Skip(); } + virtual void OnListItemSelected(wxListEvent& event){ event.Skip(); } + virtual void OnButtonNewTable(wxCommandEvent& event){ event.Skip(); } + + +public: + CPokerLobbyDialogBase(wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxT("Poker Lobby"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize(586,457), long style = wxDEFAULT_FRAME_STYLE|wxTAB_TRAVERSAL); + ~CPokerLobbyDialogBase(); + +}; + +/////////////////////////////////////////////////////////////////////////////// +/// Class CPokerDialogBase +/////////////////////////////////////////////////////////////////////////////// +class CPokerDialogBase : public wxFrame +{ +private: + +protected: + wxButton* m_buttonDealHand; + wxButton* m_buttonFold; + wxButton* m_buttonCall; + wxButton* m_buttonRaise; + wxButton* m_buttonLeaveTable; + wxTextCtrl* m_textDitchPlayer; + + // Virtual event handlers, overide them in your derived class + virtual void OnClose(wxCloseEvent& event){ event.Skip(); } + virtual void OnMouseEvents(wxMouseEvent& event){ event.Skip(); } + virtual void OnPaint(wxPaintEvent& event){ event.Skip(); } + virtual void OnSize(wxSizeEvent& event){ event.Skip(); } + virtual void OnCheckSitOut(wxCommandEvent& event){ event.Skip(); } + virtual void OnButtonDealHand(wxCommandEvent& event){ event.Skip(); } + virtual void OnButtonFold(wxCommandEvent& event){ event.Skip(); } + virtual void OnButtonCall(wxCommandEvent& event){ event.Skip(); } + virtual void OnButtonRaise(wxCommandEvent& event){ event.Skip(); } + virtual void OnButtonLeaveTable(wxCommandEvent& event){ event.Skip(); } + virtual void OnDitchPlayer(wxCommandEvent& event){ event.Skip(); } + virtual void OnCheckPreFold(wxCommandEvent& event){ event.Skip(); } + virtual void OnCheckPreCall(wxCommandEvent& event){ event.Skip(); } + virtual void OnCheckPreCallAny(wxCommandEvent& event){ event.Skip(); } + virtual void OnCheckPreRaise(wxCommandEvent& event){ event.Skip(); } + virtual void OnCheckPreRaiseAny(wxCommandEvent& event){ event.Skip(); } + + +public: + wxCheckBox* m_checkSitOut; + wxCheckBox* m_checkPreFold; + wxCheckBox* m_checkPreCall; + wxCheckBox* m_checkPreCallAny; + wxCheckBox* m_checkPreRaise; + wxCheckBox* m_checkPreRaiseAny; + wxStatusBar* m_statusBar; + CPokerDialogBase(wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxT("Poker"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize(806,550), long style = wxDEFAULT_FRAME_STYLE|wxFRAME_NO_TASKBAR|wxFULL_REPAINT_ON_RESIZE|wxTAB_TRAVERSAL); + ~CPokerDialogBase(); + +}; + +/////////////////////////////////////////////////////////////////////////////// +/// 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(403,138), long style = wxDEFAULT_DIALOG_STYLE); + ~CGetTextFromUserDialogBase(); + +}; + +#endif //__uibase__ diff --git a/uint256.h b/uint256.h new file mode 100644 index 0000000000..9a0c770497 --- /dev/null +++ b/uint256.h @@ -0,0 +1,750 @@ +// Copyright (c) 2009 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 +#include +#if defined(_MSC_VER) || defined(__BORLANDC__) +typedef __int64 int64; +typedef unsigned __int64 uint64; +#else +typedef long long int64; +typedef unsigned long long uint64; +#endif +#if defined(_MSC_VER) && _MSC_VER < 1300 +#define for if (false) ; else for +#endif + + +inline int Testuint256AdHoc(vector vArg); + + + +// We have to keep a separate base class without constructors +// so the compiler will let us use it in a union +template +class base_uint +{ +protected: + enum { WIDTH=BITS/32 }; + unsigned int pn[WIDTH]; +public: + + bool operator!() const + { + for (int i = 0; i < WIDTH; i++) + if (pn[i] != 0) + return false; + return true; + } + + const base_uint operator~() const + { + base_uint ret; + for (int i = 0; i < WIDTH; i++) + ret.pn[i] = ~pn[i]; + return ret; + } + + const base_uint operator-() const + { + base_uint ret; + for (int i = 0; i < WIDTH; i++) + ret.pn[i] = ~pn[i]; + ret++; + return ret; + } + + + base_uint& operator=(uint64 b) + { + pn[0] = (unsigned int)b; + pn[1] = (unsigned int)(b >> 32); + for (int i = 2; i < WIDTH; i++) + pn[i] = 0; + return *this; + } + + base_uint& operator^=(const base_uint& b) + { + for (int i = 0; i < WIDTH; i++) + pn[i] ^= b.pn[i]; + return *this; + } + + base_uint& operator&=(const base_uint& b) + { + for (int i = 0; i < WIDTH; i++) + pn[i] &= b.pn[i]; + return *this; + } + + base_uint& operator|=(const base_uint& b) + { + for (int i = 0; i < WIDTH; i++) + pn[i] |= b.pn[i]; + return *this; + } + + base_uint& operator^=(uint64 b) + { + pn[0] ^= (unsigned int)b; + pn[1] ^= (unsigned int)(b >> 32); + return *this; + } + + base_uint& operator&=(uint64 b) + { + pn[0] &= (unsigned int)b; + pn[1] &= (unsigned int)(b >> 32); + return *this; + } + + base_uint& operator|=(uint64 b) + { + pn[0] |= (unsigned int)b; + pn[1] |= (unsigned int)(b >> 32); + return *this; + } + + base_uint& operator<<=(unsigned int shift) + { + base_uint a(*this); + for (int i = 0; i < WIDTH; i++) + pn[i] = 0; + int k = shift / 32; + shift = shift % 32; + for (int i = 0; i < WIDTH; i++) + { + if (i+k+1 < WIDTH && shift != 0) + pn[i+k+1] |= (a.pn[i] >> (32-shift)); + if (i+k < WIDTH) + pn[i+k] |= (a.pn[i] << shift); + } + return *this; + } + + base_uint& operator>>=(unsigned int shift) + { + base_uint a(*this); + for (int i = 0; i < WIDTH; i++) + pn[i] = 0; + int k = shift / 32; + shift = shift % 32; + for (int i = 0; i < WIDTH; i++) + { + if (i-k-1 >= 0 && shift != 0) + pn[i-k-1] |= (a.pn[i] << (32-shift)); + if (i-k >= 0) + pn[i-k] |= (a.pn[i] >> shift); + } + return *this; + } + + base_uint& operator+=(const base_uint& b) + { + uint64 carry = 0; + for (int i = 0; i < WIDTH; i++) + { + uint64 n = carry + pn[i] + b.pn[i]; + pn[i] = n & 0xffffffff; + carry = n >> 32; + } + return *this; + } + + base_uint& operator-=(const base_uint& b) + { + *this += -b; + return *this; + } + + base_uint& operator+=(uint64 b64) + { + base_uint b; + b = b64; + *this += b; + return *this; + } + + base_uint& operator-=(uint64 b64) + { + base_uint b; + b = b64; + *this += -b; + return *this; + } + + + base_uint& operator++() + { + // prefix operator + int i = 0; + while (++pn[i] == 0 && i < WIDTH-1) + i++; + return *this; + } + + const base_uint operator++(int) + { + // postfix operator + const base_uint ret = *this; + ++(*this); + return ret; + } + + base_uint& operator--() + { + // prefix operator + int i = 0; + while (--pn[i] == -1 && i < WIDTH-1) + i++; + return *this; + } + + const base_uint operator--(int) + { + // postfix operator + const base_uint ret = *this; + --(*this); + return ret; + } + + + friend inline bool operator<(const base_uint& a, const base_uint& b) + { + for (int i = base_uint::WIDTH-1; i >= 0; i--) + { + if (a.pn[i] < b.pn[i]) + return true; + else if (a.pn[i] > b.pn[i]) + return false; + } + return false; + } + + friend inline bool operator<=(const base_uint& a, const base_uint& b) + { + for (int i = base_uint::WIDTH-1; i >= 0; i--) + { + if (a.pn[i] < b.pn[i]) + return true; + else if (a.pn[i] > b.pn[i]) + return false; + } + return true; + } + + friend inline bool operator>(const base_uint& a, const base_uint& b) + { + for (int i = base_uint::WIDTH-1; i >= 0; i--) + { + if (a.pn[i] > b.pn[i]) + return true; + else if (a.pn[i] < b.pn[i]) + return false; + } + return false; + } + + friend inline bool operator>=(const base_uint& a, const base_uint& b) + { + for (int i = base_uint::WIDTH-1; i >= 0; i--) + { + if (a.pn[i] > b.pn[i]) + return true; + else if (a.pn[i] < b.pn[i]) + return false; + } + return true; + } + + friend inline bool operator==(const base_uint& a, const base_uint& b) + { + for (int i = 0; i < base_uint::WIDTH; i++) + if (a.pn[i] != b.pn[i]) + return false; + return true; + } + + friend inline bool operator==(const base_uint& a, uint64 b) + { + if (a.pn[0] != (unsigned int)b) + return false; + if (a.pn[1] != (unsigned int)(b >> 32)) + return false; + for (int i = 2; i < base_uint::WIDTH; i++) + if (a.pn[i] != 0) + return false; + return true; + } + + friend inline bool operator!=(const base_uint& a, const base_uint& b) + { + return (!(a == b)); + } + + friend inline bool operator!=(const base_uint& a, uint64 b) + { + return (!(a == b)); + } + + + + std::string GetHex() const + { + char psz[sizeof(pn)*2 + 1]; + for (int i = 0; i < sizeof(pn); i++) + sprintf(psz + i*2, "%02x", ((unsigned char*)pn)[sizeof(pn) - i - 1]); + return string(psz, psz + sizeof(pn)*2); + } + + void SetHex(const std::string& str) + { + for (int i = 0; i < WIDTH; i++) + pn[i] = 0; + + // skip 0x + const char* psz = str.c_str(); + while (isspace(*psz)) + psz++; + if (psz[0] == '0' && tolower(psz[1]) == 'x') + psz += 2; + while (isspace(*psz)) + psz++; + + // hex string to uint + static char phexdigit[256] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,1,2,3,4,5,6,7,8,9,0,0,0,0,0,0, 0,0xa,0xb,0xc,0xd,0xe,0xf,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0xa,0xb,0xc,0xd,0xe,0xf,0,0,0,0,0,0,0,0,0 }; + const char* pbegin = psz; + while (phexdigit[*psz] || *psz == '0') + psz++; + psz--; + unsigned char* p1 = (unsigned char*)pn; + unsigned char* pend = p1 + WIDTH * 4; + while (psz >= pbegin && p1 < pend) + { + *p1 = phexdigit[(unsigned char)*psz--]; + if (psz >= pbegin) + { + *p1 |= (phexdigit[(unsigned char)*psz--] << 4); + p1++; + } + } + } + + std::string ToString() const + { + return (GetHex()); + } + + unsigned char* begin() + { + return (unsigned char*)&pn[0]; + } + + unsigned char* end() + { + return (unsigned char*)&pn[WIDTH]; + } + + unsigned int size() + { + return sizeof(pn); + } + + + unsigned int GetSerializeSize(int nType=0, int nVersion=VERSION) const + { + return sizeof(pn); + } + + template + void Serialize(Stream& s, int nType=0, int nVersion=VERSION) const + { + s.write((char*)pn, sizeof(pn)); + } + + template + void Unserialize(Stream& s, int nType=0, int nVersion=VERSION) + { + s.read((char*)pn, sizeof(pn)); + } + + + friend class uint160; + friend class uint256; + friend inline int Testuint256AdHoc(vector vArg); +}; + +typedef base_uint<160> base_uint160; +typedef base_uint<256> base_uint256; + + + +// +// uint160 and uint256 could be implemented as templates, but to keep +// compile errors and debugging cleaner, they're copy and pasted. +// It's safe to search and replace 160 with 256 and vice versa. +// + + + +////////////////////////////////////////////////////////////////////////////// +// +// uint160 +// + +class uint160 : public base_uint160 +{ +public: + typedef base_uint160 basetype; + + uint160() + { + } + + uint160(const basetype& b) + { + for (int i = 0; i < WIDTH; i++) + pn[i] = b.pn[i]; + } + + uint160& operator=(const basetype& b) + { + for (int i = 0; i < WIDTH; i++) + pn[i] = b.pn[i]; + return *this; + } + + uint160(uint64 b) + { + pn[0] = (unsigned int)b; + pn[1] = (unsigned int)(b >> 32); + for (int i = 2; i < WIDTH; i++) + pn[i] = 0; + } + + uint160& operator=(uint64 b) + { + pn[0] = (unsigned int)b; + pn[1] = (unsigned int)(b >> 32); + for (int i = 2; i < WIDTH; i++) + pn[i] = 0; + return *this; + } + + explicit uint160(const std::string& str) + { + SetHex(str); + } + + explicit uint160(const std::vector& vch) + { + if (vch.size() == sizeof(pn)) + memcpy(pn, &vch[0], sizeof(pn)); + else + *this = 0; + } +}; + +inline bool operator==(const uint160& a, uint64 b) { return (base_uint160)a == b; } +inline bool operator!=(const uint160& a, uint64 b) { return (base_uint160)a != b; } +inline const uint160 operator<<(const base_uint160& a, unsigned int shift) { return uint160(a) <<= shift; } +inline const uint160 operator>>(const base_uint160& a, unsigned int shift) { return uint160(a) >>= shift; } +inline const uint160 operator<<(const uint160& a, unsigned int shift) { return uint160(a) <<= shift; } +inline const uint160 operator>>(const uint160& a, unsigned int shift) { return uint160(a) >>= shift; } + +inline const uint160 operator^(const base_uint160& a, const base_uint160& b) { return uint160(a) ^= b; } +inline const uint160 operator&(const base_uint160& a, const base_uint160& b) { return uint160(a) &= b; } +inline const uint160 operator|(const base_uint160& a, const base_uint160& b) { return uint160(a) |= b; } +inline const uint160 operator+(const base_uint160& a, const base_uint160& b) { return uint160(a) += b; } +inline const uint160 operator-(const base_uint160& a, const base_uint160& b) { return uint160(a) -= b; } + +inline bool operator<(const base_uint160& a, const uint160& b) { return (base_uint160)a < (base_uint160)b; } +inline bool operator<=(const base_uint160& a, const uint160& b) { return (base_uint160)a <= (base_uint160)b; } +inline bool operator>(const base_uint160& a, const uint160& b) { return (base_uint160)a > (base_uint160)b; } +inline bool operator>=(const base_uint160& a, const uint160& b) { return (base_uint160)a >= (base_uint160)b; } +inline bool operator==(const base_uint160& a, const uint160& b) { return (base_uint160)a == (base_uint160)b; } +inline bool operator!=(const base_uint160& a, const uint160& b) { return (base_uint160)a != (base_uint160)b; } +inline const uint160 operator^(const base_uint160& a, const uint160& b) { return (base_uint160)a ^ (base_uint160)b; } +inline const uint160 operator&(const base_uint160& a, const uint160& b) { return (base_uint160)a & (base_uint160)b; } +inline const uint160 operator|(const base_uint160& a, const uint160& b) { return (base_uint160)a | (base_uint160)b; } +inline const uint160 operator+(const base_uint160& a, const uint160& b) { return (base_uint160)a + (base_uint160)b; } +inline const uint160 operator-(const base_uint160& a, const uint160& b) { return (base_uint160)a - (base_uint160)b; } + +inline bool operator<(const uint160& a, const base_uint160& b) { return (base_uint160)a < (base_uint160)b; } +inline bool operator<=(const uint160& a, const base_uint160& b) { return (base_uint160)a <= (base_uint160)b; } +inline bool operator>(const uint160& a, const base_uint160& b) { return (base_uint160)a > (base_uint160)b; } +inline bool operator>=(const uint160& a, const base_uint160& b) { return (base_uint160)a >= (base_uint160)b; } +inline bool operator==(const uint160& a, const base_uint160& b) { return (base_uint160)a == (base_uint160)b; } +inline bool operator!=(const uint160& a, const base_uint160& b) { return (base_uint160)a != (base_uint160)b; } +inline const uint160 operator^(const uint160& a, const base_uint160& b) { return (base_uint160)a ^ (base_uint160)b; } +inline const uint160 operator&(const uint160& a, const base_uint160& b) { return (base_uint160)a & (base_uint160)b; } +inline const uint160 operator|(const uint160& a, const base_uint160& b) { return (base_uint160)a | (base_uint160)b; } +inline const uint160 operator+(const uint160& a, const base_uint160& b) { return (base_uint160)a + (base_uint160)b; } +inline const uint160 operator-(const uint160& a, const base_uint160& b) { return (base_uint160)a - (base_uint160)b; } + +inline bool operator<(const uint160& a, const uint160& b) { return (base_uint160)a < (base_uint160)b; } +inline bool operator<=(const uint160& a, const uint160& b) { return (base_uint160)a <= (base_uint160)b; } +inline bool operator>(const uint160& a, const uint160& b) { return (base_uint160)a > (base_uint160)b; } +inline bool operator>=(const uint160& a, const uint160& b) { return (base_uint160)a >= (base_uint160)b; } +inline bool operator==(const uint160& a, const uint160& b) { return (base_uint160)a == (base_uint160)b; } +inline bool operator!=(const uint160& a, const uint160& b) { return (base_uint160)a != (base_uint160)b; } +inline const uint160 operator^(const uint160& a, const uint160& b) { return (base_uint160)a ^ (base_uint160)b; } +inline const uint160 operator&(const uint160& a, const uint160& b) { return (base_uint160)a & (base_uint160)b; } +inline const uint160 operator|(const uint160& a, const uint160& b) { return (base_uint160)a | (base_uint160)b; } +inline const uint160 operator+(const uint160& a, const uint160& b) { return (base_uint160)a + (base_uint160)b; } +inline const uint160 operator-(const uint160& a, const uint160& b) { return (base_uint160)a - (base_uint160)b; } + + + + + + +////////////////////////////////////////////////////////////////////////////// +// +// uint256 +// + +class uint256 : public base_uint256 +{ +public: + typedef base_uint256 basetype; + + uint256() + { + } + + uint256(const basetype& b) + { + for (int i = 0; i < WIDTH; i++) + pn[i] = b.pn[i]; + } + + uint256& operator=(const basetype& b) + { + for (int i = 0; i < WIDTH; i++) + pn[i] = b.pn[i]; + return *this; + } + + uint256(uint64 b) + { + pn[0] = (unsigned int)b; + pn[1] = (unsigned int)(b >> 32); + for (int i = 2; i < WIDTH; i++) + pn[i] = 0; + } + + uint256& operator=(uint64 b) + { + pn[0] = (unsigned int)b; + pn[1] = (unsigned int)(b >> 32); + for (int i = 2; i < WIDTH; i++) + pn[i] = 0; + return *this; + } + + explicit uint256(const std::string& str) + { + SetHex(str); + } + + explicit uint256(const std::vector& vch) + { + if (vch.size() == sizeof(pn)) + memcpy(pn, &vch[0], sizeof(pn)); + else + *this = 0; + } +}; + +inline bool operator==(const uint256& a, uint64 b) { return (base_uint256)a == b; } +inline bool operator!=(const uint256& a, uint64 b) { return (base_uint256)a != b; } +inline const uint256 operator<<(const base_uint256& a, unsigned int shift) { return uint256(a) <<= shift; } +inline const uint256 operator>>(const base_uint256& a, unsigned int shift) { return uint256(a) >>= shift; } +inline const uint256 operator<<(const uint256& a, unsigned int shift) { return uint256(a) <<= shift; } +inline const uint256 operator>>(const uint256& a, unsigned int shift) { return uint256(a) >>= shift; } + +inline const uint256 operator^(const base_uint256& a, const base_uint256& b) { return uint256(a) ^= b; } +inline const uint256 operator&(const base_uint256& a, const base_uint256& b) { return uint256(a) &= b; } +inline const uint256 operator|(const base_uint256& a, const base_uint256& b) { return uint256(a) |= b; } +inline const uint256 operator+(const base_uint256& a, const base_uint256& b) { return uint256(a) += b; } +inline const uint256 operator-(const base_uint256& a, const base_uint256& b) { return uint256(a) -= b; } + +inline bool operator<(const base_uint256& a, const uint256& b) { return (base_uint256)a < (base_uint256)b; } +inline bool operator<=(const base_uint256& a, const uint256& b) { return (base_uint256)a <= (base_uint256)b; } +inline bool operator>(const base_uint256& a, const uint256& b) { return (base_uint256)a > (base_uint256)b; } +inline bool operator>=(const base_uint256& a, const uint256& b) { return (base_uint256)a >= (base_uint256)b; } +inline bool operator==(const base_uint256& a, const uint256& b) { return (base_uint256)a == (base_uint256)b; } +inline bool operator!=(const base_uint256& a, const uint256& b) { return (base_uint256)a != (base_uint256)b; } +inline const uint256 operator^(const base_uint256& a, const uint256& b) { return (base_uint256)a ^ (base_uint256)b; } +inline const uint256 operator&(const base_uint256& a, const uint256& b) { return (base_uint256)a & (base_uint256)b; } +inline const uint256 operator|(const base_uint256& a, const uint256& b) { return (base_uint256)a | (base_uint256)b; } +inline const uint256 operator+(const base_uint256& a, const uint256& b) { return (base_uint256)a + (base_uint256)b; } +inline const uint256 operator-(const base_uint256& a, const uint256& b) { return (base_uint256)a - (base_uint256)b; } + +inline bool operator<(const uint256& a, const base_uint256& b) { return (base_uint256)a < (base_uint256)b; } +inline bool operator<=(const uint256& a, const base_uint256& b) { return (base_uint256)a <= (base_uint256)b; } +inline bool operator>(const uint256& a, const base_uint256& b) { return (base_uint256)a > (base_uint256)b; } +inline bool operator>=(const uint256& a, const base_uint256& b) { return (base_uint256)a >= (base_uint256)b; } +inline bool operator==(const uint256& a, const base_uint256& b) { return (base_uint256)a == (base_uint256)b; } +inline bool operator!=(const uint256& a, const base_uint256& b) { return (base_uint256)a != (base_uint256)b; } +inline const uint256 operator^(const uint256& a, const base_uint256& b) { return (base_uint256)a ^ (base_uint256)b; } +inline const uint256 operator&(const uint256& a, const base_uint256& b) { return (base_uint256)a & (base_uint256)b; } +inline const uint256 operator|(const uint256& a, const base_uint256& b) { return (base_uint256)a | (base_uint256)b; } +inline const uint256 operator+(const uint256& a, const base_uint256& b) { return (base_uint256)a + (base_uint256)b; } +inline const uint256 operator-(const uint256& a, const base_uint256& b) { return (base_uint256)a - (base_uint256)b; } + +inline bool operator<(const uint256& a, const uint256& b) { return (base_uint256)a < (base_uint256)b; } +inline bool operator<=(const uint256& a, const uint256& b) { return (base_uint256)a <= (base_uint256)b; } +inline bool operator>(const uint256& a, const uint256& b) { return (base_uint256)a > (base_uint256)b; } +inline bool operator>=(const uint256& a, const uint256& b) { return (base_uint256)a >= (base_uint256)b; } +inline bool operator==(const uint256& a, const uint256& b) { return (base_uint256)a == (base_uint256)b; } +inline bool operator!=(const uint256& a, const uint256& b) { return (base_uint256)a != (base_uint256)b; } +inline const uint256 operator^(const uint256& a, const uint256& b) { return (base_uint256)a ^ (base_uint256)b; } +inline const uint256 operator&(const uint256& a, const uint256& b) { return (base_uint256)a & (base_uint256)b; } +inline const uint256 operator|(const uint256& a, const uint256& b) { return (base_uint256)a | (base_uint256)b; } +inline const uint256 operator+(const uint256& a, const uint256& b) { return (base_uint256)a + (base_uint256)b; } +inline const uint256 operator-(const uint256& a, const uint256& b) { return (base_uint256)a - (base_uint256)b; } + + + + + + + + + + + + +inline int Testuint256AdHoc(vector vArg) +{ + uint256 g(0); + + + printf("%s\n", g.ToString().c_str()); + g--; printf("g--\n"); + printf("%s\n", g.ToString().c_str()); + g--; printf("g--\n"); + printf("%s\n", g.ToString().c_str()); + g++; printf("g++\n"); + printf("%s\n", g.ToString().c_str()); + g++; printf("g++\n"); + printf("%s\n", g.ToString().c_str()); + g++; printf("g++\n"); + printf("%s\n", g.ToString().c_str()); + g++; printf("g++\n"); + printf("%s\n", g.ToString().c_str()); + + + + uint256 a(7); + printf("a=7\n"); + printf("%s\n", a.ToString().c_str()); + + uint256 b; + printf("b undefined\n"); + printf("%s\n", b.ToString().c_str()); + int c = 3; + + a = c; + a.pn[3] = 15; + printf("%s\n", a.ToString().c_str()); + uint256 k(c); + + a = 5; + a.pn[3] = 15; + printf("%s\n", a.ToString().c_str()); + b = 1; + b <<= 52; + + a |= b; + + a ^= 0x500; + + printf("a %s\n", a.ToString().c_str()); + + a = a | b | (uint256)0x1000; + + + printf("a %s\n", a.ToString().c_str()); + printf("b %s\n", b.ToString().c_str()); + + a = 0xfffffffe; + a.pn[4] = 9; + + printf("%s\n", a.ToString().c_str()); + a++; + printf("%s\n", a.ToString().c_str()); + a++; + printf("%s\n", a.ToString().c_str()); + a++; + printf("%s\n", a.ToString().c_str()); + a++; + printf("%s\n", a.ToString().c_str()); + + a--; + printf("%s\n", a.ToString().c_str()); + a--; + printf("%s\n", a.ToString().c_str()); + a--; + printf("%s\n", a.ToString().c_str()); + uint256 d = a--; + printf("%s\n", d.ToString().c_str()); + printf("%s\n", a.ToString().c_str()); + a--; + printf("%s\n", a.ToString().c_str()); + a--; + printf("%s\n", a.ToString().c_str()); + + d = a; + + printf("%s\n", d.ToString().c_str()); + for (int i = uint256::WIDTH-1; i >= 0; i--) printf("%08x", d.pn[i]); printf("\n"); + + uint256 neg = d; + neg = ~neg; + printf("%s\n", neg.ToString().c_str()); + + + uint256 e = uint256("0xABCDEF123abcdef12345678909832180000011111111"); + printf("\n"); + printf("%s\n", e.ToString().c_str()); + + + printf("\n"); + uint256 x1 = uint256("0xABCDEF123abcdef12345678909832180000011111111"); + uint256 x2; + printf("%s\n", x1.ToString().c_str()); + for (int i = 0; i < 270; i += 4) + { + x2 = x1 << i; + printf("%s\n", x2.ToString().c_str()); + } + + printf("\n"); + printf("%s\n", x1.ToString().c_str()); + for (int i = 0; i < 270; i += 4) + { + x2 = x1; + x2 >>= i; + printf("%s\n", x2.ToString().c_str()); + } + + + for (int i = 0; i < 100; i++) + { + uint256 k = (~uint256(0) >> i); + printf("%s\n", k.ToString().c_str()); + } + + for (int i = 0; i < 100; i++) + { + uint256 k = (~uint256(0) << i); + printf("%s\n", k.ToString().c_str()); + } + + return (0); +} diff --git a/uiproject.fbp b/uiproject.fbp new file mode 100644 index 0000000000..49b1fefaaf --- /dev/null +++ b/uiproject.fbp @@ -0,0 +1,11860 @@ + + + + + + C++ + 1 + UTF-8 + connect + uibase + 1000 + none + 0 + + + . + + 1 + 0 + 0 + + wxSYS_COLOUR_BTNFACE + + + 1 + + + + 0 + wxID_MAINFRAME + + + CMainFrameBase + + 705,484 + wxDEFAULT_FRAME_STYLE|wxRESIZE_BORDER + + Bitcoin + + + + wxTAB_TRAVERSAL + 1 + + + + OnClose + + + + + OnIdle + + + + + + + + + + + + OnMouseEvents + + OnPaint + + + + + + + + 240,240,240 + + 1 + + + 0 + wxID_ANY + MyMenuBar + + + m_menubar + protected + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + &File + m_menuFile + protected + + + 0 + 1 + + wxID_ANY + wxITEM_NORMAL + E&xit + m_menuFileExit + none + + + OnMenuFileExit + + + + + &Options + m_menuOptions + public + + + 0 + 1 + + wxID_OPTIONSGENERATEBITCOINS + wxITEM_CHECK + &Generate Coins + m_menuOptionsGenerateBitcoins + none + + + OnMenuOptionsGenerate + + + + + 0 + 1 + + wxID_ANY + wxITEM_NORMAL + &Change Your Address... + m_menuChangeYourAddress + none + + + OnMenuOptionsChangeYourAddress + + + + + 0 + 1 + + wxID_ANY + wxITEM_NORMAL + &Options... + m_menuOptionsOptions + none + + + OnMenuOptionsOptions + + + + + &Help + m_menuHelp + protected + + + 0 + 1 + + wxID_ANY + wxITEM_NORMAL + &About... + m_menuHelpAbout + none + + + OnMenuHelpAbout + + + + + + + 20,20 + + 1 + + ,90,90,-1,70,0 + 0 + wxID_ANY + + + + m_toolBar + 1 + protected + + 1 + -1,-1 + wxTB_FLAT|wxTB_HORZ_TEXT + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + send20; Load From Resource + wxID_BUTTONSEND + wxITEM_NORMAL + &Send Coins + m_tool1 + + + + OnButtonSend + + + + + + addressbook20; Load From Resource + wxID_BUTTONRECEIVE + wxITEM_NORMAL + &Address Book + m_tool2 + + + + OnButtonAddressBook + + + + + + + 240,240,240 + + 1 + + 1 + + 0 + wxID_ANY + + + m_statusBar + protected + + + wxST_SIZEGRIP + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + bSizer2 + wxVERTICAL + none + + 5 + wxEXPAND + 0 + + 2 + protected + 0 + + + + 5 + wxEXPAND|wxRIGHT|wxLEFT + 0 + + + bSizer85 + wxHORIZONTAL + none + + 5 + wxALIGN_CENTER_VERTICAL|wxLEFT + 0 + + + + 1 + + + 0 + wxID_ANY + Your Bitcoin Address: + + + m_staticText32 + protected + + + + + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT + 0 + + wxSYS_COLOUR_MENU + + 1 + + + 0 + wxID_TEXTCTRLADDRESS + -1,-1 + 0 + -1,-1 + m_textCtrlAddress + protected + + 250,-1 + wxTE_READONLY + + + + + + + + + + OnKeyDown + + + + + + + + + + + OnMouseEventsAddress + + + + + + OnSetFocusAddress + + + + + + + + + + 5 + wxALIGN_CENTER_VERTICAL|wxRIGHT + 0 + + + + 0 + 1 + + + 0 + wxID_BUTTONCOPY + &Copy to Clipboard + + + m_buttonCopy + protected + + + wxBU_EXACTFIT + + + + + + OnButtonCopy + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxRIGHT + 0 + + + + 0 + 1 + + + 1 + wxID_BUTTONCHANGE + C&hange... + + + m_button91 + protected + + + + + + + + + OnButtonChange + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND + 0 + + 0 + protected + 0 + + + + + + 5 + wxEXPAND + 0 + + + bSizer3 + wxHORIZONTAL + none + + 5 + wxEXPAND|wxALIGN_BOTTOM|wxALL + 1 + + + + 1 + + + 0 + wxID_ANY + + + m_panel14 + protected + + + + + + + wxTAB_TRAVERSAL + + + + + + + + + + + + + + + + + + + + + + + + + + bSizer66 + wxHORIZONTAL + none + + 5 + wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxLEFT + 0 + + + + 1 + + + 0 + wxID_ANY + Balance: + + + m_staticText41 + protected + + -1,15 + + + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALIGN_CENTER_VERTICAL|wxALL + 0 + + wxSYS_COLOUR_WINDOW + + 1 + + ,90,90,8,70,0 + 0 + wxID_ANY + + + + m_staticTextBalance + protected + + 120,15 + wxALIGN_RIGHT|wxST_NO_AUTORESIZE + + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND + 0 + + 0 + protected + 0 + + + + 5 + wxALIGN_BOTTOM|wxTOP|wxRIGHT|wxLEFT + 0 + + + " All" " Sent" " Received" " In Progress" + + 1 + + + 1 + wxID_ANY + + + m_choiceFilter + protected + + 0 + 110,-1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND + 1 + + + + + 1 + + + 0 + wxID_ANY + + + m_notebook + protected + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + All Transactions + 0 + + + + 1 + + + 0 + wxID_ANY + + + m_panel7 + protected + + + + + + + wxTAB_TRAVERSAL + + + + + + + + + + + + + + + + + + + + + + + + + + bSizer157 + wxVERTICAL + none + + 5 + wxEXPAND|wxALL + 1 + + + + 1 + + + 0 + wxID_ANY + + + m_listCtrl + public + + + wxLC_NO_SORT_HEADER|wxLC_REPORT|wxLC_SORT_DESCENDING + + + + + wxALWAYS_SHOW_SB + + + + + + + + + + + + + + + OnListColBeginDrag + + + + + + + + + OnListItemActivatedAllTransactions + + + + + + + + + + + + + OnPaintListCtrl + + + + + + + + + + + + + + + 5 + wxEXPAND + 1 + + + bSizer_TabsForFutureUse + wxVERTICAL + none + + 5 + wxEXPAND | wxALL + 1 + + + + 1 + + + 1 + wxID_ANY + + + m_panel9 + protected + + + + + + + wxTAB_TRAVERSAL + + + + + + + + + + + + + + + + + + + + + + + + + + bSizer159 + wxVERTICAL + none + + 5 + wxALL|wxEXPAND + 1 + + + + 1 + + + 0 + wxID_ANY + + + m_listCtrlEscrows + public + + + wxLC_NO_SORT_HEADER|wxLC_REPORT + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND | wxALL + 1 + + + + 1 + + + 1 + wxID_ANY + + + m_panel8 + protected + + + + + + + wxTAB_TRAVERSAL + + + + + + + + + + + + + + + + + + + + + + + + + + bSizer158 + wxVERTICAL + none + + 5 + wxALL|wxEXPAND + 1 + + + + 1 + + + 0 + wxID_ANY + + + m_listCtrlOrdersSent + public + + + wxLC_NO_SORT_HEADER|wxLC_REPORT + + + + + + + + + + + + + + + + + + + + + + + + + + + + + OnListItemActivatedOrdersSent + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND | wxALL + 1 + + + + 1 + + + 1 + wxID_ANY + + + m_panel10 + protected + + + + + + + wxTAB_TRAVERSAL + + + + + + + + + + + + + + + + + + + + + + + + + + bSizer160 + wxVERTICAL + none + + 5 + wxALL|wxEXPAND + 1 + + + + 1 + + + 0 + wxID_ANY + + + m_listCtrlProductsSent + public + + + wxLC_NO_SORT_HEADER|wxLC_REPORT + + + + + + + + + + + + + + + + + + + + + + + + + + + + + OnListItemActivatedProductsSent + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND | wxALL + 1 + + + + 1 + + + 1 + wxID_ANY + + + m_panel11 + protected + + + + + + + wxTAB_TRAVERSAL + + + + + + + + + + + + + + + + + + + + + + + + + + bSizer161 + wxVERTICAL + none + + 5 + wxALL|wxEXPAND + 1 + + + + 1 + + + 0 + wxID_ANY + + + m_listCtrlOrdersReceived + public + + + wxLC_NO_SORT_HEADER|wxLC_REPORT + + + + + + + + + + + + + + + + + + + + + + + + + + + + + OnListItemActivatedOrdersReceived + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1 + + + + 0 + wxID_ANY + + + CTxDetailsDialogBase + + 620,450 + wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER + + Transaction Details + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + bSizer64 + wxVERTICAL + none + + 5 + wxEXPAND + 1 + + + bSizer66 + wxVERTICAL + none + + 5 + wxALL|wxEXPAND + 1 + + + + 1 + + + 0 + wxID_ANY + + + m_htmlWin + protected + + + wxHW_SCROLLBAR_AUTO + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALIGN_RIGHT + 0 + + + bSizer65 + wxVERTICAL + none + + 5 + wxALL + 0 + + + + 0 + 1 + + + 0 + wxID_OK + OK + + + m_buttonOK + protected + + 85,25 + + + + + + + OnButtonOK + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1 + + + + 0 + wxID_ANY + + + COptionsDialogBase + + 500,261 + wxDEFAULT_DIALOG_STYLE + + Options + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + bSizer55 + wxVERTICAL + none + + 5 + wxEXPAND|wxLEFT + 1 + + + bSizer57 + wxVERTICAL + none + + 5 + wxEXPAND + 0 + + 20 + protected + 0 + + + + 5 + wxALIGN_CENTER_VERTICAL|wxALL + 0 + + + + 1 + + + 0 + wxID_ANY + Optional transaction fee you give to the nodes that process your transactions. + + + m_staticText32 + protected + + + + + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND + 0 + + + bSizer56 + wxHORIZONTAL + none + + 5 + wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxLEFT + 0 + + + + 1 + + + 0 + wxID_ANY + Transaction fee: + + + m_staticText31 + protected + + + + + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL|wxALIGN_CENTER_VERTICAL + 0 + + + + 1 + + + 0 + wxID_TRANSACTIONFEE + + 0 + + m_textCtrlTransactionFee + protected + + 70,-1 + + + + + + + + + + + + + OnKillFocusTransactionFee + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALIGN_RIGHT + 0 + + + bSizer58 + wxHORIZONTAL + none + + 5 + wxALL + 0 + + + + 0 + 1 + + + 0 + wxID_OK + OK + + + m_buttonOK + protected + + 85,25 + + + + + + + OnButtonOK + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL + 0 + + + + 0 + 1 + + + 0 + wxID_CANCEL + Cancel + + 85,25 + m_buttonCancel + protected + + -1,-1 + + + + + + + OnButtonCancel + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1 + + + + 0 + wxID_ANY + + + CAboutDialogBase + + 507,298 + wxDEFAULT_DIALOG_STYLE + + About Bitcoin + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + bSizer60 + wxVERTICAL + none + + 5 + wxEXPAND + 1 + + + bSizer62 + wxHORIZONTAL + none + + 5 + wxEXPAND + 0 + + 0 + protected + 60 + + + + 5 + wxEXPAND + 1 + + + bSizer63 + wxVERTICAL + none + + 5 + wxEXPAND + 0 + + 50 + protected + 0 + + + + 5 + wxEXPAND + 0 + + + bSizer64 + wxHORIZONTAL + none + + 5 + wxALIGN_BOTTOM|wxTOP|wxBOTTOM|wxLEFT + 0 + + + + 1 + + Tahoma,90,92,10,74,0 + 0 + wxID_ANY + Bitcoin + + + m_staticText40 + protected + + + + + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALIGN_BOTTOM|wxTOP|wxBOTTOM|wxRIGHT + 0 + + + + 1 + + Tahoma,90,90,10,74,0 + 0 + wxID_ANY + version + + + m_staticTextVersion + public + + + + + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND + 0 + + 4 + protected + 0 + + + + 5 + wxALL + 0 + + + + 1 + + + 0 + wxID_ANY + Copyright © 2009 Satoshi Nakamoto. This is experimental software. Do not rely on it for actual financial transactions. 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). + + + m_staticTextMain + protected + + + + + + + + + 400 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND + 1 + + 0 + protected + 0 + + + + + + + + 5 + wxALIGN_RIGHT|wxEXPAND + 0 + + + bSizer61 + wxHORIZONTAL + none + + 5 + wxEXPAND + 1 + + 0 + protected + 0 + + + + 5 + wxALL + 0 + + + + 0 + 1 + + + 0 + wxID_OK + OK + + + m_buttonOK + protected + + 85,25 + + + + + + + OnButtonOK + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1 + + + + 0 + wxID_ANY + + + CSendDialogBase + + 675,312 + wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER + + Send Coins + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + bSizer21 + wxVERTICAL + none + + 5 + wxEXPAND + 0 + + 5 + protected + 0 + + + + 5 + wxEXPAND|wxLEFT + 0 + + 2 + wxBOTH + 1 + + 0 + + fgSizer1 + wxFLEX_GROWMODE_SPECIFIED + none + 3 + 0 + + 5 + wxEXPAND + 0 + + 0 + protected + 0 + + + + 5 + wxTOP|wxRIGHT|wxLEFT + 0 + + + + 1 + + + 0 + wxID_ANY + Enter the recipient's IP address (e.g. 123.45.6.7) for online transfer with comments and confirmation, or Bitcoin address (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJED9L) if recipient is not online. + + + m_staticText14 + protected + + + + + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND|wxLEFT + 1 + + 70,-1 + bSizer47 + wxHORIZONTAL + none + + 5 + wxEXPAND + 1 + + 0 + protected + 0 + + + + 5 + wxALL|wxALIGN_CENTER_VERTICAL + 0 + + + check; Load From Icon Resource [-1; -1] + + 1 + + + 0 + wxID_ANY + + + m_bitmapCheckMark + protected + + 16,16 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxLEFT + 0 + + + + 1 + + + 0 + wxID_ANY + Pay &To: + + + m_staticText36 + protected + + -1,-1 + wxALIGN_RIGHT + + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND|wxRIGHT + 1 + + + bSizer19 + wxHORIZONTAL + none + + 5 + wxALIGN_CENTER_VERTICAL|wxALL + 1 + + + + 1 + + + 0 + wxID_TEXTCTRLPAYTO + + 0 + + m_textCtrlAddress + protected + + + + + + + + + + + + + OnKeyDown + + + + + + + + + + + + + + + + + + + OnTextAddress + + + + + + + + 5 + wxALIGN_CENTER_VERTICAL|wxRIGHT + 0 + + + + 0 + 1 + + + 0 + wxID_BUTTONPASTE + &Paste + + + m_buttonPaste + protected + + -1,-1 + wxBU_EXACTFIT + + + + + + OnButtonPaste + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALIGN_CENTER_VERTICAL|wxRIGHT + 0 + + + + 0 + 1 + + + 0 + wxID_BUTTONADDRESSBOOK + Address &Book... + + + m_buttonAddress + protected + + + + + + + + + OnButtonAddressBook + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxLEFT|wxALIGN_RIGHT + 0 + + + + 1 + + + 0 + wxID_ANY + &Amount: + + + m_staticText19 + protected + + -1,-1 + wxALIGN_RIGHT + + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALIGN_CENTER_VERTICAL|wxALL + 0 + + + + 1 + + ,90,90,-1,70,0 + 0 + wxID_TEXTCTRLAMOUNT + + 20 + + m_textCtrlAmount + protected + + 145,-1 + + + + + + + + + + + OnKeyDown + + OnKillFocusAmount + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxTOP|wxBOTTOM|wxLEFT + 0 + + + + 1 + + + 1 + wxID_ANY + T&ransfer: + + + m_staticText20 + protected + + -1,-1 + wxALIGN_RIGHT + + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALIGN_CENTER_VERTICAL|wxALL + 0 + + + " Standard" + + 1 + + + 1 + wxID_CHOICETRANSFERTYPE + + + m_choiceTransferType + protected + + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND + 0 + + 3 + protected + 0 + + + + 5 + wxEXPAND + 0 + + 0 + protected + 0 + + + + + + 5 + wxEXPAND + 0 + + + bSizer672 + wxHORIZONTAL + none + + 5 + wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT + 1 + + + bSizer681 + wxVERTICAL + none + + 5 + wxBOTTOM|wxLEFT + 0 + + + + 1 + + + 0 + wxID_ANY + &From: + + + m_staticTextFrom + protected + + + + + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxLEFT|wxEXPAND + 0 + + + + 1 + + + 0 + wxID_ANY + + 0 + + m_textCtrlFrom + protected + + -1,-1 + + + + + + + + + + + OnKeyDown + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND + 1 + + + bSizer67 + wxHORIZONTAL + none + + 5 + wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT + 1 + + + bSizer68 + wxVERTICAL + none + + 5 + wxTOP|wxBOTTOM|wxLEFT + 0 + + + + 1 + + + 0 + wxID_ANY + &Message: + + + m_staticTextMessage + protected + + + + + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND|wxLEFT + 1 + + + + 1 + + + 0 + wxID_ANY + + 0 + + m_textCtrlMessage + protected + + + wxTE_MULTILINE + + + + + + + + + + OnKeyDown + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND + 0 + + + bSizer23 + wxHORIZONTAL + none + + 5 + wxEXPAND + 1 + + 0 + protected + 0 + + + + 5 + wxALL + 0 + + + + 0 + 1 + + ,90,90,-1,70,0 + 0 + wxID_BUTTONSEND + &Send + + 85,25 + m_buttonSend + protected + + -1,-1 + + + + + + + OnButtonSend + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL + 0 + + + + 0 + 1 + + + 0 + wxID_CANCEL + Cancel + + 85,25 + m_buttonCancel + protected + + -1,-1 + + + + + + + OnButtonCancel + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1 + + + + 0 + wxID_ANY + + + CSendingDialogBase + + 442,151 + wxDEFAULT_DIALOG_STYLE + + Sending... + + + + + + + + OnClose + + + + + + + + + + + + + + + + + + + + OnPaint + + + + + + + + + bSizer68 + wxVERTICAL + none + + 8 + wxALIGN_CENTER_VERTICAL|wxEXPAND|wxTOP|wxRIGHT|wxLEFT + 0 + + + + 1 + + + 0 + wxID_ANY + + + + m_staticTextSending + protected + + -1,14 + + + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + 10 + wxEXPAND|wxRIGHT|wxLEFT + 1 + + wxSYS_COLOUR_BTNFACE + + 1 + + + 0 + wxID_ANY + + 0 + + m_textCtrlStatus + protected + + + wxTE_CENTRE|wxTE_MULTILINE|wxTE_NO_VSCROLL|wxTE_READONLY + + + Connecting... + + + wxNO_BORDER + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND + 0 + + + bSizer69 + wxHORIZONTAL + none + + 5 + wxEXPAND + 1 + + 0 + protected + 0 + + + + 5 + wxALL + 0 + + + + 0 + 0 + + + 0 + wxID_ANY + OK + + 85,25 + m_buttonOK + protected + + + + + + + + + OnButtonOK + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL + 0 + + + + 0 + 1 + + + 0 + wxID_CANCEL + Cancel + + 85,25 + m_buttonCancel + protected + + -1,-1 + + + + + + + OnButtonCancel + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1 + + + + 0 + wxID_ANY + + + CYourAddressDialogBase + + 610,390 + wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER + + Your Bitcoin Addresses + + + + + + + + OnClose + + + + + + + + + + + + + + + + + + + + + + + + + + + + + bSizer68 + wxVERTICAL + none + + 5 + wxEXPAND + 0 + + 5 + protected + 0 + + + + 5 + wxALL + 0 + + + + 1 + + + 0 + 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. + + + m_staticText45 + protected + + + + + + + + + 590 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL|wxEXPAND + 1 + + + + 1 + + + 0 + wxID_LISTCTRL + + + m_listCtrl + protected + + + wxLC_NO_SORT_HEADER|wxLC_REPORT|wxLC_SORT_ASCENDING + + + + + + + + + + + + + + + + + + + + + + + + + + + OnListEndLabelEdit + + OnListItemActivated + + + + + OnListItemSelected + + + + + + + + + + + + + + + + + + 5 + wxEXPAND + 0 + + + bSizer69 + wxHORIZONTAL + none + + 5 + wxEXPAND + 1 + + 0 + protected + 0 + + + + 5 + wxALL + 0 + + + + 0 + 1 + + + 0 + wxID_BUTTONRENAME + &Edit... + + 85,25 + m_buttonRename + protected + + + + + + + + + OnButtonRename + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL + 0 + + + + 0 + 1 + + + 0 + wxID_BUTTONNEW + &New Address... + + 110,25 + m_buttonNew + protected + + -1,-1 + + + + + + + OnButtonNew + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL + 0 + + + + 0 + 1 + + + 0 + wxID_BUTTONCOPY + &Copy to Clipboard + + 120,25 + m_buttonCopy + protected + + -1,-1 + + + + + + + OnButtonCopy + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL + 0 + + + + 0 + 1 + + + 0 + wxID_OK + OK + + 85,25 + m_buttonOK + protected + + + + + + + + + OnButtonOK + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL + 0 + + + + 0 + 1 + + + 1 + wxID_CANCEL + Cancel + + 85,25 + m_buttonCancel + protected + + -1,-1 + + + + + + + OnButtonCancel + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1 + + + + 0 + wxID_ANY + + + CAddressBookDialogBase + + 610,390 + wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER + + Address Book + + + + + + + + OnClose + + + + + + + + + + + + + + + + + + + + + + + + + + + + + bSizer68 + wxVERTICAL + none + + 5 + wxEXPAND + 0 + + 5 + protected + 0 + + + + 5 + wxTOP|wxRIGHT|wxLEFT + 0 + + + + 1 + + + 1 + wxID_ANY + Bitcoin Address + + + m_staticText55 + protected + + + + + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL|wxEXPAND + 1 + + + + 1 + + + 0 + wxID_LISTCTRL + + + m_listCtrl + protected + + + wxLC_NO_SORT_HEADER|wxLC_REPORT|wxLC_SORT_ASCENDING + + + + + + + + + + + + + + + + + + + + + + + + + + + OnListEndLabelEdit + + OnListItemActivated + + + + + OnListItemSelected + + + + + + + + + + + + + + + + + + 5 + wxEXPAND + 0 + + + bSizer69 + wxHORIZONTAL + none + + 5 + wxEXPAND + 1 + + 0 + protected + 0 + + + + 5 + wxALL + 0 + + + + 0 + 1 + + + 0 + wxID_BUTTONEDIT + &Edit... + + 85,25 + m_buttonEdit + protected + + + + + + + + + OnButtonEdit + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL + 0 + + + + 0 + 1 + + + 0 + wxID_BUTTONNEW + &New Address... + + 110,25 + m_buttonNew + protected + + + + + + + + + OnButtonNew + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL + 0 + + + + 0 + 1 + + + 0 + wxID_BUTTONDELETE + &Delete + + 85,25 + m_buttonDelete + protected + + + + + + + + + OnButtonDelete + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL + 0 + + + + 0 + 1 + + + 0 + wxID_OK + OK + + 85,25 + m_buttonOK + protected + + -1,-1 + + + + + + + OnButtonOK + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL + 0 + + + + 0 + 1 + + + 0 + wxID_CANCEL + Cancel + + 85,25 + m_buttonCancel + public + + -1,-1 + + + + + + + OnButtonCancel + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1 + + + + 0 + wxID_ANY + + + CProductsDialogBase + + 708,535 + wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER + + Marketplace + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + bSizer22 + wxVERTICAL + none + + 5 + wxEXPAND|wxTOP|wxBOTTOM|wxRIGHT + 0 + + + bSizer23 + wxHORIZONTAL + none + + 5 + wxALL|wxALIGN_CENTER_VERTICAL + 0 + + + "(Any Category)" + + 1 + + + 0 + wxID_ANY + + + m_comboBoxCategory + protected + + 150,-1 + + + + (Any Category) + + + + + OnCombobox + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL|wxALIGN_CENTER_VERTICAL + 1 + + + + 1 + + + 0 + wxID_ANY + + 0 + + m_textCtrlSearch + protected + + + + + + + + + + + + + OnKeyDown + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL|wxALIGN_CENTER_VERTICAL + 0 + + + + 0 + 1 + + + 0 + wxID_ANY + &Search + + + m_buttonSearch + protected + + + + + + + + + OnButtonSearch + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL|wxEXPAND + 1 + + + + 1 + + + 0 + wxID_ANY + + + m_listCtrl + protected + + + wxLC_NO_SORT_HEADER|wxLC_REPORT + + + + + + + + + + + + + + + + + + + + + + + + + + + + + OnListItemActivated + + + + + + + + + + + + + + + + + + + + + + + + + wxSYS_COLOUR_MENU + + + 1 + + + + 0 + wxID_ANY + + + CEditProductDialogBase + + 660,640 + wxDEFAULT_FRAME_STYLE|wxRESIZE_BORDER + + Edit Product + + + + wxTAB_TRAVERSAL + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + bSizer20 + wxVERTICAL + none + + 5 + wxEXPAND|wxALL + 1 + + wxSYS_COLOUR_WINDOW + + 1 + + + 0 + wxID_ANY + + + m_scrolledWindow + protected + + 5 + 5 + + + + + + wxHSCROLL|wxTAB_TRAVERSAL|wxVSCROLL + + + + + + + + + + + + + + + + + + + + + + + + + + bSizer21 + wxVERTICAL + none + + 5 + wxEXPAND|wxTOP|wxRIGHT|wxLEFT + 0 + + 2 + wxBOTH + 1 + + 0 + + fgSizer8 + wxFLEX_GROWMODE_SPECIFIED + none + 0 + 0 + + 5 + wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxTOP|wxBOTTOM|wxLEFT + 0 + + + + 1 + + + 0 + wxID_ANY + Category + + + m_staticText106 + protected + + + wxALIGN_RIGHT + + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL|wxALIGN_CENTER_VERTICAL + 0 + + + + + 1 + + + 0 + wxID_ANY + + 180,-1 + m_comboBoxCategory + protected + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxTOP|wxBOTTOM|wxLEFT + 0 + + + + 1 + + + 0 + wxID_ANY + Title + + + m_staticText108 + protected + + + wxALIGN_RIGHT + + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND + 1 + + + + 1 + + + 0 + wxID_ANY + + 0 + + m_textCtrlTitle + protected + + + + + + + + + + + + + OnKeyDown + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxTOP|wxBOTTOM|wxLEFT + 0 + + + + 1 + + + 0 + wxID_ANY + Price + + + m_staticText107 + protected + + + wxALIGN_RIGHT + + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL|wxALIGN_CENTER_VERTICAL + 0 + + + + 1 + + + 0 + wxID_ANY + + 0 + 105,-1 + m_textCtrlPrice + protected + + + + + + + + + + + + + OnKeyDown + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxTOP|wxRIGHT|wxLEFT + 0 + + + + 1 + + + 0 + wxID_ANY + Page 1: Description + + + m_staticText22 + protected + + + + + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL|wxEXPAND + 0 + + + + 1 + + + 0 + wxID_ANY + + 0 + -1,170 + m_textCtrlDescription + protected + + + wxTE_MULTILINE + + + + + + + + + + OnKeyDown + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxTOP|wxRIGHT|wxLEFT + 0 + + + + 1 + + + 0 + wxID_ANY + Page 2: Order Form + + + m_staticText23 + protected + + + + + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND|wxALL + 0 + + + + 1 + + + 0 + wxID_ANY + + 0 + -1,120 + m_textCtrlInstructions + protected + + + wxTE_MULTILINE + + + + + + + + + + OnKeyDown + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND + 0 + + 3 + wxBOTH + 1 + + 0 + + fgSizer5 + wxFLEX_GROWMODE_SPECIFIED + public + 0 + 0 + + 5 + wxALIGN_CENTER_VERTICAL|wxTOP|wxRIGHT|wxLEFT + 0 + + + + 1 + + + 0 + wxID_ANY + Label + + + m_staticText24 + protected + + + + + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALIGN_CENTER_VERTICAL|wxTOP|wxRIGHT|wxLEFT + 0 + + + + 1 + + + 0 + wxID_ANY + Comma separated list of choices, or leave blank for text field + + + m_staticText25 + protected + + + + + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND + 1 + + 0 + protected + 0 + + + + 5 + wxALL|wxALIGN_CENTER_VERTICAL + 0 + + + + 1 + + + 0 + wxID_ANY + + 0 + 150,-1 + m_textCtrlLabel0 + protected + + + + + + + + + + + + + OnKeyDown + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL + 0 + + + + 1 + + + 0 + wxID_ANY + -1,-1 + 0 + -1,-1 + m_textCtrlField0 + protected + + -1,-1 + + + + + + + + + + + OnKeyDown + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxRIGHT|wxLEFT|wxALIGN_CENTER_VERTICAL + 0 + + + + 0 + 1 + + + 0 + wxID_DEL0 + Delete + + -1,-1 + m_buttonDel0 + protected + + 60,20 + + + + + + + OnButtonDel0 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL|wxALIGN_CENTER_VERTICAL + 0 + + + + 1 + + + 0 + wxID_ANY + + 0 + 150,-1 + m_textCtrlLabel1 + protected + + + + + + + + + + + + + OnKeyDown + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL + 0 + + + + 1 + + + 0 + wxID_ANY + -1,-1 + 0 + -1,-1 + m_textCtrlField1 + protected + + -1,-1 + + + + + + + + + + + OnKeyDown + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT + 0 + + + + 0 + 1 + + + 0 + wxID_DEL1 + Delete + + -1,-1 + m_buttonDel1 + protected + + 60,20 + + + + + + + OnButtonDel1 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL|wxALIGN_CENTER_VERTICAL + 0 + + + + 1 + + + 0 + wxID_ANY + + 0 + 150,-1 + m_textCtrlLabel2 + protected + + + + + + + + + + + + + OnKeyDown + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL + 0 + + + + 1 + + + 0 + wxID_ANY + -1,-1 + 0 + -1,-1 + m_textCtrlField2 + protected + + -1,-1 + + + + + + + + + + + OnKeyDown + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT + 0 + + + + 0 + 1 + + + 0 + wxID_DEL2 + Delete + + -1,-1 + m_buttonDel2 + protected + + 60,20 + + + + + + + OnButtonDel2 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL|wxALIGN_CENTER_VERTICAL + 0 + + + + 1 + + + 0 + wxID_ANY + + 0 + 150,-1 + m_textCtrlLabel3 + protected + + + + + + + + + + + + + OnKeyDown + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL + 0 + + + + 1 + + + 0 + wxID_ANY + -1,-1 + 0 + -1,-1 + m_textCtrlField3 + protected + + -1,-1 + + + + + + + + + + + OnKeyDown + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT + 0 + + + + 0 + 1 + + + 0 + wxID_DEL3 + Delete + + -1,-1 + m_buttonDel3 + protected + + 60,20 + + + + + + + OnButtonDel3 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL|wxALIGN_CENTER_VERTICAL + 0 + + + + 1 + + + 0 + wxID_ANY + + 0 + 150,-1 + m_textCtrlLabel4 + protected + + + + + + + + + + + + + OnKeyDown + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL + 0 + + + + 1 + + + 0 + wxID_ANY + -1,-1 + 0 + -1,-1 + m_textCtrlField4 + protected + + -1,-1 + + + + + + + + + + + OnKeyDown + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT + 0 + + + + 0 + 1 + + + 0 + wxID_DEL4 + Delete + + -1,-1 + m_buttonDel4 + protected + + 60,20 + + + + + + + OnButtonDel4 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL|wxALIGN_CENTER_VERTICAL + 0 + + + + 1 + + + 0 + wxID_ANY + + 0 + 150,-1 + m_textCtrlLabel5 + protected + + + + + + + + + + + + + OnKeyDown + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL + 0 + + + + 1 + + + 0 + wxID_ANY + -1,-1 + 0 + -1,-1 + m_textCtrlField5 + protected + + -1,-1 + + + + + + + + + + + OnKeyDown + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT + 0 + + + + 0 + 1 + + + 0 + wxID_DEL5 + Delete + + -1,-1 + m_buttonDel5 + protected + + 60,20 + + + + + + + OnButtonDel5 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL|wxALIGN_CENTER_VERTICAL + 0 + + + + 1 + + + 0 + wxID_ANY + + 0 + 150,-1 + m_textCtrlLabel6 + protected + + + + + + + + + + + + + OnKeyDown + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL + 0 + + + + 1 + + + 0 + wxID_ANY + -1,-1 + 0 + -1,-1 + m_textCtrlField6 + protected + + -1,-1 + + + + + + + + + + + OnKeyDown + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT + 0 + + + + 0 + 1 + + + 0 + wxID_DEL6 + Delete + + -1,-1 + m_buttonDel6 + protected + + 60,20 + + + + + + + OnButtonDel6 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL|wxALIGN_CENTER_VERTICAL + 0 + + + + 1 + + + 0 + wxID_ANY + + 0 + 150,-1 + m_textCtrlLabel7 + protected + + + + + + + + + + + + + OnKeyDown + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL + 0 + + + + 1 + + + 0 + wxID_ANY + -1,-1 + 0 + -1,-1 + m_textCtrlField7 + protected + + -1,-1 + + + + + + + + + + + OnKeyDown + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT + 0 + + + + 0 + 1 + + + 0 + wxID_DEL7 + Delete + + -1,-1 + m_buttonDel7 + protected + + 60,20 + + + + + + + OnButtonDel7 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL|wxALIGN_CENTER_VERTICAL + 0 + + + + 1 + + + 0 + wxID_ANY + + 0 + 150,-1 + m_textCtrlLabel8 + protected + + + + + + + + + + + + + OnKeyDown + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL + 0 + + + + 1 + + + 0 + wxID_ANY + -1,-1 + 0 + -1,-1 + m_textCtrlField8 + protected + + -1,-1 + + + + + + + + + + + OnKeyDown + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT + 0 + + + + 0 + 1 + + + 0 + wxID_DEL8 + Delete + + -1,-1 + m_buttonDel8 + protected + + 60,20 + + + + + + + OnButtonDel8 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL|wxALIGN_CENTER_VERTICAL + 0 + + + + 1 + + + 0 + wxID_ANY + + 0 + 150,-1 + m_textCtrlLabel9 + protected + + + + + + + + + + + + + OnKeyDown + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL + 0 + + + + 1 + + + 0 + wxID_ANY + -1,-1 + 0 + -1,-1 + m_textCtrlField9 + protected + + -1,-1 + + + + + + + + + + + OnKeyDown + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT + 0 + + + + 0 + 1 + + + 0 + wxID_DEL9 + Delete + + -1,-1 + m_buttonDel9 + protected + + 60,20 + + + + + + + OnButtonDel9 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL|wxALIGN_CENTER_VERTICAL + 0 + + + + 1 + + + 0 + wxID_ANY + + 0 + 150,-1 + m_textCtrlLabel10 + protected + + + + + + + + + + + + + OnKeyDown + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL + 0 + + + + 1 + + + 0 + wxID_ANY + -1,-1 + 0 + -1,-1 + m_textCtrlField10 + protected + + -1,-1 + + + + + + + + + + + OnKeyDown + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT + 0 + + + + 0 + 1 + + + 0 + wxID_DEL10 + Delete + + -1,-1 + m_buttonDel10 + protected + + 60,20 + + + + + + + OnButtonDel10 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL|wxALIGN_CENTER_VERTICAL + 0 + + + + 1 + + + 0 + wxID_ANY + + 0 + 150,-1 + m_textCtrlLabel11 + protected + + + + + + + + + + + + + OnKeyDown + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL + 0 + + + + 1 + + + 0 + wxID_ANY + -1,-1 + 0 + -1,-1 + m_textCtrlField11 + protected + + -1,-1 + + + + + + + + + + + OnKeyDown + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT + 0 + + + + 0 + 1 + + + 0 + wxID_DEL11 + Delete + + -1,-1 + m_buttonDel11 + protected + + 60,20 + + + + + + + OnButtonDel11 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL|wxALIGN_CENTER_VERTICAL + 0 + + + + 1 + + + 0 + wxID_ANY + + 0 + 150,-1 + m_textCtrlLabel12 + protected + + + + + + + + + + + + + OnKeyDown + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL + 0 + + + + 1 + + + 0 + wxID_ANY + -1,-1 + 0 + -1,-1 + m_textCtrlField12 + protected + + -1,-1 + + + + + + + + + + + OnKeyDown + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT + 0 + + + + 0 + 1 + + + 0 + wxID_DEL12 + Delete + + -1,-1 + m_buttonDel12 + protected + + 60,20 + + + + + + + OnButtonDel12 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL|wxALIGN_CENTER_VERTICAL + 0 + + + + 1 + + + 0 + wxID_ANY + + 0 + 150,-1 + m_textCtrlLabel13 + protected + + + + + + + + + + + + + OnKeyDown + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL + 0 + + + + 1 + + + 0 + wxID_ANY + -1,-1 + 0 + -1,-1 + m_textCtrlField13 + protected + + -1,-1 + + + + + + + + + + + OnKeyDown + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT + 0 + + + + 0 + 1 + + + 0 + wxID_DEL13 + Delete + + -1,-1 + m_buttonDel13 + protected + + 60,20 + + + + + + + OnButtonDel13 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL|wxALIGN_CENTER_VERTICAL + 0 + + + + 1 + + + 0 + wxID_ANY + + 0 + 150,-1 + m_textCtrlLabel14 + protected + + + + + + + + + + + + + OnKeyDown + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL + 0 + + + + 1 + + + 0 + wxID_ANY + -1,-1 + 0 + -1,-1 + m_textCtrlField14 + protected + + -1,-1 + + + + + + + + + + + OnKeyDown + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT + 0 + + + + 0 + 1 + + + 0 + wxID_DEL14 + Delete + + -1,-1 + m_buttonDel14 + protected + + 60,20 + + + + + + + OnButtonDel14 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL|wxALIGN_CENTER_VERTICAL + 0 + + + + 1 + + + 0 + wxID_ANY + + 0 + 150,-1 + m_textCtrlLabel15 + protected + + + + + + + + + + + + + OnKeyDown + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL + 0 + + + + 1 + + + 0 + wxID_ANY + -1,-1 + 0 + -1,-1 + m_textCtrlField15 + protected + + -1,-1 + + + + + + + + + + + OnKeyDown + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT + 0 + + + + 0 + 1 + + + 0 + wxID_DEL15 + Delete + + -1,-1 + m_buttonDel15 + protected + + 60,20 + + + + + + + OnButtonDel15 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL|wxALIGN_CENTER_VERTICAL + 0 + + + + 1 + + + 0 + wxID_ANY + + 0 + 150,-1 + m_textCtrlLabel16 + protected + + + + + + + + + + + + + OnKeyDown + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL + 0 + + + + 1 + + + 0 + wxID_ANY + -1,-1 + 0 + -1,-1 + m_textCtrlField16 + protected + + -1,-1 + + + + + + + + + + + OnKeyDown + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT + 0 + + + + 0 + 1 + + + 0 + wxID_DEL16 + Delete + + -1,-1 + m_buttonDel16 + protected + + 60,20 + + + + + + + OnButtonDel16 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL|wxALIGN_CENTER_VERTICAL + 0 + + + + 1 + + + 0 + wxID_ANY + + 0 + 150,-1 + m_textCtrlLabel17 + protected + + + + + + + + + + + + + OnKeyDown + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL + 0 + + + + 1 + + + 0 + wxID_ANY + -1,-1 + 0 + -1,-1 + m_textCtrlField17 + protected + + -1,-1 + + + + + + + + + + + OnKeyDown + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT + 0 + + + + 0 + 1 + + + 0 + wxID_DEL17 + Delete + + -1,-1 + m_buttonDel17 + protected + + 60,20 + + + + + + + OnButtonDel17 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL|wxALIGN_CENTER_VERTICAL + 0 + + + + 1 + + + 0 + wxID_ANY + + 0 + 150,-1 + m_textCtrlLabel18 + protected + + + + + + + + + + + + + OnKeyDown + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL + 0 + + + + 1 + + + 0 + wxID_ANY + -1,-1 + 0 + -1,-1 + m_textCtrlField18 + protected + + -1,-1 + + + + + + + + + + + OnKeyDown + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT + 0 + + + + 0 + 1 + + + 0 + wxID_DEL18 + Delete + + -1,-1 + m_buttonDel18 + protected + + 60,20 + + + + + + + OnButtonDel18 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL|wxALIGN_CENTER_VERTICAL + 0 + + + + 1 + + + 0 + wxID_ANY + + 0 + 150,-1 + m_textCtrlLabel19 + protected + + + + + + + + + + + + + OnKeyDown + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL + 0 + + + + 1 + + + 0 + wxID_ANY + -1,-1 + 0 + -1,-1 + m_textCtrlField19 + protected + + -1,-1 + + + + + + + + + + + OnKeyDown + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT + 0 + + + + 0 + 1 + + + 0 + wxID_DEL19 + Delete + + -1,-1 + m_buttonDel19 + protected + + 60,20 + + + + + + + OnButtonDel19 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALIGN_CENTER_HORIZONTAL + 0 + + + bSizer25 + wxHORIZONTAL + none + + 5 + wxALL + 0 + + + + 0 + 1 + + + 0 + wxID_ANY + &Add Field + + + m_buttonAddField + protected + + + + + + + + + OnButtonAddField + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALIGN_RIGHT + 0 + + + bSizer26 + wxHORIZONTAL + none + + 5 + wxALL + 0 + + + + 0 + 1 + + + 0 + wxID_BUTTONSEND + &Send + + 85,25 + m_buttonOK + protected + + + + + + + + + OnButtonSend + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL + 0 + + + + 0 + 1 + + + 0 + wxID_BUTTONPREVIEW + &Preview + + 85,25 + m_buttonPreview + protected + + + + + + + + + OnButtonPreview + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL + 0 + + + + 0 + 1 + + + 0 + wxID_CANCEL + Cancel + + 85,25 + m_buttonCancel + protected + + + + + + + + + OnButtonCancel + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + wxSYS_COLOUR_MENU + + + 1 + + + + 0 + wxID_ANY + + + CViewProductDialogBase + + 630,520 + wxDEFAULT_FRAME_STYLE|wxRESIZE_BORDER + + Order Form + + + + wxTAB_TRAVERSAL + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + bSizer20 + wxVERTICAL + none + + 5 + wxEXPAND + 1 + + + bSizer116 + wxHORIZONTAL + none + + 5 + wxALL|wxEXPAND + 1 + + + + 1 + + + 1 + wxID_ANY + + + m_htmlWinReviews + protected + + + wxHW_SCROLLBAR_AUTO + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND|wxALL + 1 + + wxSYS_COLOUR_WINDOW + + 1 + + + 0 + wxID_ANY + + + m_scrolledWindow + protected + + 5 + 5 + + + + + + wxHSCROLL|wxTAB_TRAVERSAL|wxVSCROLL + + + + + + + + + + + + + + + + + + + + + + + + + + bSizer21 + wxVERTICAL + none + + 5 + wxEXPAND + 0 + + + + 1 + + + 0 + wxID_ANY + + -1,-1 + m_richTextHeading + protected + + -1,50 + wxTE_READONLY + + + + + wxNO_BORDER + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL|wxEXPAND + 0 + + + + 1 + + + 0 + wxID_ANY + Order Form instructions here multiple lines 1 2 3 4 5 6 + + + m_staticTextInstructions + protected + + + + + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALIGN_CENTER_HORIZONTAL + 0 + + + bSizer25 + wxHORIZONTAL + none + + 5 + wxALL + 0 + + + + 0 + 1 + + + 0 + wxID_BUTTONSAMPLE + &Submit + + -1,-1 + m_buttonSubmitForm + protected + + + + + + + + + OnButtonSubmitForm + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL + 0 + + + + 0 + 1 + + + 0 + wxID_CANCEL2 + Cancel + + + m_buttonCancelForm + protected + + + + + + + + + OnButtonCancelForm + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALIGN_RIGHT + 0 + + + bSizer26 + wxHORIZONTAL + none + + 5 + wxALL + 0 + + + + 0 + 0 + + + 0 + wxID_BUTTONBACK + < &Back + + 85,25 + m_buttonBack + protected + + + + + + + + + OnButtonBack + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL + 0 + + + + 0 + 1 + + + 0 + wxID_BUTTONNEXT + &Next > + + 85,25 + m_buttonNext + protected + + + + + + + + + OnButtonNext + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL + 0 + + + + 0 + 1 + + + 0 + wxID_CANCEL + Cancel + + 85,25 + m_buttonCancel + protected + + + + + + + + + OnButtonCancel + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + wxSYS_COLOUR_MENU + + + 1 + + + + 0 + wxID_ANY + + + CViewOrderDialogBase + + 630,520 + wxDEFAULT_FRAME_STYLE|wxRESIZE_BORDER + + View Order + + + + wxTAB_TRAVERSAL + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + bSizer20 + wxVERTICAL + none + + 5 + wxEXPAND + 1 + + + bSizer116 + wxHORIZONTAL + none + + 5 + wxALL|wxEXPAND + 1 + + + + 1 + + + 0 + wxID_ANY + + + m_htmlWin + protected + + + wxHW_SCROLLBAR_AUTO + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALIGN_RIGHT + 0 + + + bSizer26 + wxHORIZONTAL + none + + 5 + wxALL + 0 + + + + 0 + 1 + + + 0 + wxID_OK + OK + + 85,25 + m_buttonOK + protected + + + + + + + + + OnButtonOK + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + wxSYS_COLOUR_MENU + + + 1 + + + + 0 + wxID_ANY + + + CEditReviewDialogBase + + 630,440 + wxDEFAULT_FRAME_STYLE|wxRESIZE_BORDER + + Enter Review + + + + wxTAB_TRAVERSAL + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + bSizer112 + wxVERTICAL + none + + 5 + + 0 + + 3 + protected + 0 + + + + 5 + wxALL|wxEXPAND + 0 + + + + 1 + + + 0 + wxID_ANY + + + + m_staticTextSeller + protected + + + + + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + + 0 + + 3 + protected + 0 + + + + 5 + wxTOP|wxRIGHT|wxLEFT + 0 + + + + 1 + + + 0 + wxID_ANY + Rating + + + m_staticText110 + protected + + + + + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL + 0 + + + " 1 star" " 2 stars" " 3 stars" " 4 stars" " 5 stars" + + 1 + + + 0 + wxID_ANY + + + m_choiceStars + protected + + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxTOP|wxRIGHT|wxLEFT + 0 + + + + 1 + + + 0 + wxID_ANY + Review + + + m_staticText43 + protected + + + + + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL|wxEXPAND + 1 + + + + 1 + + + 0 + wxID_ANY + + 0 + + m_textCtrlReview + protected + + + wxTE_MULTILINE + + + + + + + + + + OnKeyDown + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALIGN_RIGHT + 0 + + + bSizer113 + wxHORIZONTAL + none + + 5 + wxALL + 0 + + + + 0 + 1 + + + 0 + wxID_SUBMIT + &Submit + + 85,25 + m_buttonSubmit + protected + + + + + + + + + OnButtonSubmit + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL + 0 + + + + 0 + 1 + + + 0 + wxID_CANCEL + Cancel + + 85,25 + m_buttonCancel + protected + + + + + + + + + OnButtonCancel + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + wxSYS_COLOUR_BTNFACE + + + 1 + + + + 0 + wxID_ANY + + + CPokerLobbyDialogBase + + 586,457 + wxDEFAULT_FRAME_STYLE + + Poker Lobby + + + + wxTAB_TRAVERSAL + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + bSizer156 + wxHORIZONTAL + none + + 5 + wxEXPAND|wxTOP|wxBOTTOM|wxLEFT + 0 + + + + 1 + + + 0 + wxID_ANY + + 130,-1 + m_treeCtrl + protected + + + wxTR_HAS_BUTTONS|wxTR_HIDE_ROOT|wxTR_LINES_AT_ROOT + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + OnTreeSelChanged + + + + + + + + 5 + wxEXPAND + 1 + + + bSizer172 + wxVERTICAL + none + + 5 + wxEXPAND|wxALL + 1 + + + + 1 + + + 0 + wxID_ANY + + + m_listCtrl + protected + + + wxLC_NO_SORT_HEADER|wxLC_REPORT + + + + + + + + + + + + + + + + + + + + + + + + + + + + + OnListItemActivated + + + + + OnListItemSelected + + + + + + + + + + + + + + + + + + 5 + wxALL + 0 + + + + 0 + 1 + + + 0 + wxID_OPENNEWTABLE + &Open New Table + + + m_buttonNewTable + protected + + + + + + + + + OnButtonNewTable + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1 + + + + 0 + wxID_ANY + + + CPokerDialogBase + + 806,550 + wxDEFAULT_FRAME_STYLE|wxFRAME_NO_TASKBAR + + Poker + + + + wxFULL_REPAINT_ON_RESIZE|wxTAB_TRAVERSAL + 1 + + + + OnClose + + + + + + + + + + + + + + + + + OnMouseEvents + + OnPaint + + + + + OnSize + + + + bSizer174 + wxVERTICAL + none + + 5 + wxALL + 0 + + + 0 + + 1 + + + 0 + wxID_ANY + Deal Me Out + + + m_checkSitOut + public + + + + + + + + + + OnCheckSitOut + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL + 0 + + + + 0 + 1 + + + 0 + wxID_DEALHAND + &Deal Hand + + + m_buttonDealHand + protected + + 150,25 + + + + + + + OnButtonDealHand + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL + 0 + + + + 0 + 1 + + + 0 + wxID_FOLD + &Fold + + + m_buttonFold + protected + + 80,25 + + + + + + + OnButtonFold + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL + 0 + + + + 0 + 1 + + + 0 + wxID_CALL + &Call + + + m_buttonCall + protected + + 80,25 + + + + + + + OnButtonCall + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL + 0 + + + + 0 + 1 + + + 0 + wxID_RAISE + &Raise + + + m_buttonRaise + protected + + 80,25 + + + + + + + OnButtonRaise + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL + 0 + + + + 0 + 1 + + + 0 + wxID_LEAVETABLE + &Leave Table + + + m_buttonLeaveTable + protected + + 90,25 + + + + + + + OnButtonLeaveTable + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL + 0 + + + + 1 + + + 0 + wxID_DITCHPLAYER + + 0 + + m_textDitchPlayer + protected + + 45,-1 + wxTE_PROCESS_ENTER + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + OnDitchPlayer + + + + + + + 5 + wxALL + 0 + + + 0 + + 1 + + + 0 + wxID_ANY + FOLD + + + m_checkPreFold + public + + 100,-1 + + + + + + + + OnCheckPreFold + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL + 0 + + + 0 + + 1 + + + 0 + wxID_ANY + CALL + + + m_checkPreCall + public + + 100,-1 + + + + + + + + OnCheckPreCall + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL + 0 + + + 0 + + 1 + + + 0 + wxID_ANY + CALL ANY + + + m_checkPreCallAny + public + + 100,-1 + + + + + + + + OnCheckPreCallAny + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL + 0 + + + 0 + + 1 + + + 0 + wxID_ANY + RAISE + + + m_checkPreRaise + public + + 100,-1 + + + + + + + + OnCheckPreRaise + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL + 0 + + + 0 + + 1 + + + 0 + wxID_ANY + RAISE ANY + + + m_checkPreRaiseAny + public + + 100,-1 + + + + + + + + OnCheckPreRaiseAny + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1 + + 1 + + 0 + wxID_ANY + + + m_statusBar + public + + + wxST_SIZEGRIP + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1 + + + + 0 + wxID_ANY + + + CGetTextFromUserDialogBase + + 403,138 + wxDEFAULT_DIALOG_STYLE + + + + + + + + + + OnClose + + + + + + + + + + + + + + + + + + + + + + + + + + + + + bSizer79 + wxVERTICAL + none + + 10 + wxEXPAND|wxALL + 1 + + + bSizer81 + wxVERTICAL + none + + 5 + wxEXPAND + 1 + + 0 + protected + 0 + + + + 5 + wxTOP|wxRIGHT|wxLEFT + 0 + + + + 1 + + + 0 + wxID_ANY + + + + m_staticTextMessage1 + protected + + + + + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL|wxEXPAND|wxALIGN_CENTER_HORIZONTAL + 0 + + + + 1 + + + 0 + wxID_TEXTCTRL + + 0 + + m_textCtrl1 + protected + + + wxTE_PROCESS_ENTER + + + + + + + + + + OnKeyDown + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxTOP|wxRIGHT|wxLEFT + 0 + + + + 1 + + + 1 + wxID_ANY + + + + m_staticTextMessage2 + protected + + + + + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL|wxEXPAND|wxALIGN_CENTER_HORIZONTAL + 0 + + + + 1 + + + 1 + wxID_TEXTCTRL + + 0 + + m_textCtrl2 + protected + + + wxTE_PROCESS_ENTER + + + + + + + + + + OnKeyDown + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND + 1 + + 0 + protected + 0 + + + + + + 5 + wxEXPAND + 0 + + + bSizer80 + wxHORIZONTAL + none + + 5 + wxEXPAND + 1 + + 0 + protected + 0 + + + + 5 + wxALL + 0 + + + + 0 + 1 + + + 0 + wxID_OK + OK + + 85,25 + m_buttonOK + protected + + -1,-1 + + + + + + + OnButtonOK + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL + 0 + + + + 0 + 1 + + + 0 + wxID_CANCEL + Cancel + + 85,25 + m_buttonCancel + protected + + + + + + + + + OnButtonCancel + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/util.cpp b/util.cpp new file mode 100644 index 0000000000..9c0ab142e1 --- /dev/null +++ b/util.cpp @@ -0,0 +1,383 @@ +// Copyright (c) 2009 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" + + + +bool fDebug = false; + + + + +// Init openssl library multithreading support +static HANDLE* lock_cs; + +void win32_locking_callback(int mode, int type, const char* file, int line) +{ + if (mode & CRYPTO_LOCK) + WaitForSingleObject(lock_cs[type], INFINITE); + else + ReleaseMutex(lock_cs[type]); +} + +// Init +class CInit +{ +public: + CInit() + { + // Init openssl library multithreading support + lock_cs = (HANDLE*)OPENSSL_malloc(CRYPTO_num_locks() * sizeof(HANDLE)); + for (int i = 0; i < CRYPTO_num_locks(); i++) + lock_cs[i] = CreateMutex(NULL,FALSE,NULL); + CRYPTO_set_locking_callback(win32_locking_callback); + + // Seed random number generator with screen scrape and other hardware sources + RAND_screen(); + + // Seed random number generator with perfmon data + RandAddSeed(true); + } + ~CInit() + { + // Shutdown openssl library multithreading support + CRYPTO_set_locking_callback(NULL); + for (int i =0 ; i < CRYPTO_num_locks(); i++) + CloseHandle(lock_cs[i]); + OPENSSL_free(lock_cs); + } +} +instance_of_cinit; + + + + +void RandAddSeed(bool fPerfmon) +{ + // Seed with CPU performance counter + LARGE_INTEGER PerformanceCount; + QueryPerformanceCounter(&PerformanceCount); + RAND_add(&PerformanceCount, sizeof(PerformanceCount), 1.5); + memset(&PerformanceCount, 0, sizeof(PerformanceCount)); + + static int64 nLastPerfmon; + if (fPerfmon || GetTime() > nLastPerfmon + 5 * 60) + { + nLastPerfmon = GetTime(); + + // Seed with the entire set of perfmon data + unsigned char pdata[250000]; + memset(pdata, 0, sizeof(pdata)); + unsigned long nSize = sizeof(pdata); + long ret = RegQueryValueEx(HKEY_PERFORMANCE_DATA, "Global", NULL, NULL, pdata, &nSize); + RegCloseKey(HKEY_PERFORMANCE_DATA); + if (ret == ERROR_SUCCESS) + { + uint256 hash; + SHA256(pdata, nSize, (unsigned char*)&hash); + RAND_add(&hash, sizeof(hash), min(nSize/500.0, (double)sizeof(hash))); + hash = 0; + memset(pdata, 0, nSize); + + time_t nTime; + time(&nTime); + struct tm* ptmTime = gmtime(&nTime); + char pszTime[200]; + strftime(pszTime, sizeof(pszTime), "%x %H:%M:%S", ptmTime); + printf("%s RandAddSeed() got %d bytes of performance data\n", pszTime, nSize); + } + } +} + + + + + + + + + + +// Safer snprintf +// - prints up to limit-1 characters +// - output string is always null terminated even if limit reached +// - return value is the number of characters actually printed +int my_snprintf(char* buffer, size_t limit, const char* format, ...) +{ + if (limit == 0) + return 0; + va_list arg_ptr; + va_start(arg_ptr, format); + int ret = _vsnprintf(buffer, limit, format, arg_ptr); + va_end(arg_ptr); + if (ret < 0 || ret >= limit) + { + ret = limit - 1; + buffer[limit-1] = 0; + } + return ret; +} + + +string strprintf(const char* format, ...) +{ + char buffer[50000]; + char* p = buffer; + int limit = sizeof(buffer); + int ret; + loop + { + va_list arg_ptr; + va_start(arg_ptr, format); + ret = _vsnprintf(p, limit, format, arg_ptr); + va_end(arg_ptr); + if (ret >= 0 && ret < limit) + break; + if (p != buffer) + delete p; + limit *= 2; + p = new char[limit]; + if (p == NULL) + throw std::bad_alloc(); + } +#ifdef _MSC_VER + // msvc optimisation + if (p == buffer) + return string(p, p+ret); +#endif + string str(p, p+ret); + if (p != buffer) + delete p; + return str; +} + + +bool error(const char* format, ...) +{ + char buffer[50000]; + int limit = sizeof(buffer); + va_list arg_ptr; + va_start(arg_ptr, format); + int ret = _vsnprintf(buffer, limit, format, arg_ptr); + va_end(arg_ptr); + if (ret < 0 || ret >= limit) + { + ret = limit - 1; + buffer[limit-1] = 0; + } + printf("ERROR: %s\n", buffer); + return false; +} + + +void PrintException(std::exception* pex, const char* pszThread) +{ + char pszModule[260]; + pszModule[0] = '\0'; + GetModuleFileName(NULL, pszModule, sizeof(pszModule)); + _strlwr(pszModule); + char pszMessage[1000]; + if (pex) + snprintf(pszMessage, sizeof(pszMessage), + "EXCEPTION: %s \n%s \n%s in %s \n", typeid(*pex).name(), pex->what(), pszModule, pszThread); + else + snprintf(pszMessage, sizeof(pszMessage), + "UNKNOWN EXCEPTION \n%s in %s \n", pszModule, pszThread); + printf("\n\n************************\n%s", pszMessage); + if (wxTheApp) + wxMessageBox(pszMessage, "Error", wxOK | wxICON_ERROR); + throw; + //DebugBreak(); +} + + +void ParseString(const string& str, char c, vector& v) +{ + unsigned int i1 = 0; + unsigned int i2; + do + { + i2 = str.find(c, i1); + v.push_back(str.substr(i1, i2-i1)); + i1 = i2+1; + } + while (i2 != str.npos); +} + + +string FormatMoney(int64 n, bool fPlus) +{ + n /= CENT; + string str = strprintf("%I64d.%02I64d", (n > 0 ? n : -n)/100, (n > 0 ? n : -n)%100); + for (int i = 6; i < str.size(); i += 4) + if (isdigit(str[str.size() - i - 1])) + str.insert(str.size() - i, 1, ','); + if (n < 0) + str.insert((unsigned int)0, 1, '-'); + else if (fPlus && n > 0) + str.insert((unsigned int)0, 1, '+'); + return str; +} + +bool ParseMoney(const char* pszIn, int64& nRet) +{ + string strWhole; + int64 nCents = 0; + const char* p = pszIn; + while (isspace(*p)) + p++; + for (; *p; p++) + { + if (*p == ',' && p > pszIn && isdigit(p[-1]) && isdigit(p[1]) && isdigit(p[2]) && isdigit(p[3]) && !isdigit(p[4])) + continue; + if (*p == '.') + { + p++; + if (isdigit(*p)) + { + nCents = 10 * (*p++ - '0'); + if (isdigit(*p)) + nCents += (*p++ - '0'); + } + break; + } + if (isspace(*p)) + break; + if (!isdigit(*p)) + return false; + strWhole.insert(strWhole.end(), *p); + } + for (; *p; p++) + if (!isspace(*p)) + return false; + if (strWhole.size() > 14) + return false; + if (nCents < 0 || nCents > 99) + return false; + int64 nWhole = atoi64(strWhole); + int64 nPreValue = nWhole * 100 + nCents; + int64 nValue = nPreValue * CENT; + if (nValue / CENT != nPreValue) + return false; + if (nValue / COIN != nWhole) + return false; + nRet = nValue; + return true; +} + + + + + + + + + + +bool FileExists(const char* psz) +{ +#ifdef WIN32 + return GetFileAttributes(psz) != -1; +#else + return access(psz, 0) != -1; +#endif +} + +int GetFilesize(FILE* file) +{ + int nSavePos = ftell(file); + int nFilesize = -1; + if (fseek(file, 0, SEEK_END) == 0) + nFilesize = ftell(file); + fseek(file, nSavePos, SEEK_SET); + return nFilesize; +} + + + + + + + + +uint64 GetRand(uint64 nMax) +{ + if (nMax == 0) + return 0; + + // The range of the random source must be a multiple of the modulus + // to give every possible output value an equal possibility + uint64 nRange = (_UI64_MAX / nMax) * nMax; + uint64 nRand = 0; + do + RAND_bytes((unsigned char*)&nRand, sizeof(nRand)); + while (nRand >= nRange); + return (nRand % nMax); +} + + + + + + + + + + +// +// "Never go to sea with two chronometers; take one or three." +// Our three chronometers are: +// - System clock +// - Median of other server's clocks +// - NTP servers +// +// note: NTP isn't implemented yet, so until then we just use the median +// of other nodes clocks to correct ours. +// + +int64 GetTime() +{ + return time(NULL); +} + +static int64 nTimeOffset = 0; + +int64 GetAdjustedTime() +{ + return GetTime() + nTimeOffset; +} + +void AddTimeData(unsigned int ip, int64 nTime) +{ + int64 nOffsetSample = nTime - GetTime(); + + // Ignore duplicates + static set setKnown; + if (!setKnown.insert(ip).second) + return; + + // Add data + static vector vTimeOffsets; + if (vTimeOffsets.empty()) + vTimeOffsets.push_back(0); + vTimeOffsets.push_back(nOffsetSample); + printf("Added time data, samples %d, ip %08x, offset %+I64d (%+I64d minutes)\n", vTimeOffsets.size(), ip, vTimeOffsets.back(), vTimeOffsets.back()/60); + if (vTimeOffsets.size() >= 5 && vTimeOffsets.size() % 2 == 1) + { + sort(vTimeOffsets.begin(), vTimeOffsets.end()); + int64 nMedian = vTimeOffsets[vTimeOffsets.size()/2]; + nTimeOffset = nMedian; + if ((nMedian > 0 ? nMedian : -nMedian) > 5 * 60) + { + // Only let other nodes change our clock so far before we + // go to the NTP servers + /// todo: Get time from NTP servers, then set a flag + /// to make sure it doesn't get changed again + } + foreach(int64 n, vTimeOffsets) + printf("%+I64d ", n); + printf("| nTimeOffset = %+I64d (%+I64d minutes)\n", nTimeOffset, nTimeOffset/60); + } +} diff --git a/util.h b/util.h new file mode 100644 index 0000000000..97617ab490 --- /dev/null +++ b/util.h @@ -0,0 +1,399 @@ +// Copyright (c) 2009 Satoshi Nakamoto +// Distributed under the MIT/X11 software license, see the accompanying +// file license.txt or http://www.opensource.org/licenses/mit-license.php. + + +#if defined(_MSC_VER) || defined(__BORLANDC__) +typedef __int64 int64; +typedef unsigned __int64 uint64; +#else +typedef long long int64; +typedef unsigned long long uint64; +#endif +#if defined(_MSC_VER) && _MSC_VER < 1300 +#define for if (false) ; else for +#endif + +#ifndef _MSC_VER +#define __forceinline inline +#endif + +#define foreach BOOST_FOREACH +#define loop for (;;) +#define BEGIN(a) ((char*)&(a)) +#define END(a) ((char*)&((&(a))[1])) +#define UBEGIN(a) ((unsigned char*)&(a)) +#define UEND(a) ((unsigned char*)&((&(a))[1])) +#define ARRAYLEN(array) (sizeof(array)/sizeof((array)[0])) + +#ifdef _WINDOWS +#define printf OutputDebugStringF +#endif + +#ifdef snprintf +#undef snprintf +#endif +#define snprintf my_snprintf + +#ifndef PRId64 +#if defined(_MSC_VER) || defined(__BORLANDC__) || defined(__MSVCRT__) +#define PRId64 "I64d" +#define PRIu64 "I64u" +#define PRIx64 "I64x" +#else +#define PRId64 "lld" +#define PRIu64 "llu" +#define PRIx64 "llx" +#endif +#endif + +// This is needed because the foreach macro can't get over the comma in pair +#define PAIRTYPE(t1, t2) pair + +// Used to bypass the rule against non-const reference to temporary +// where it makes sense with wrappers such as CFlatData or CTxDB +template +inline T& REF(const T& val) +{ + return (T&)val; +} + + + + + + + + + +extern bool fDebug; + +void RandAddSeed(bool fPerfmon=false); +int my_snprintf(char* buffer, size_t limit, const char* format, ...); +string strprintf(const char* format, ...); +bool error(const char* format, ...); +void PrintException(std::exception* pex, const char* pszThread); +void ParseString(const string& str, char c, vector& v); +string FormatMoney(int64 n, bool fPlus=false); +bool ParseMoney(const char* pszIn, int64& nRet); +bool FileExists(const char* psz); +int GetFilesize(FILE* file); +uint64 GetRand(uint64 nMax); +int64 GetTime(); +int64 GetAdjustedTime(); +void AddTimeData(unsigned int ip, int64 nTime); + + + + + + + + + + + + +// Wrapper to automatically initialize critical section +// Could use wxCriticalSection for portability, but it doesn't support TryEnterCriticalSection +class CCriticalSection +{ +protected: + CRITICAL_SECTION cs; +public: + char* pszFile; + int nLine; + explicit CCriticalSection() { InitializeCriticalSection(&cs); } + ~CCriticalSection() { DeleteCriticalSection(&cs); } + void Enter() { EnterCriticalSection(&cs); } + void Leave() { LeaveCriticalSection(&cs); } + bool TryEnter() { return TryEnterCriticalSection(&cs); } + CRITICAL_SECTION* operator&() { return &cs; } +}; + +// Automatically leave critical section when leaving block, needed for exception safety +class CCriticalBlock +{ +protected: + CRITICAL_SECTION* pcs; +public: + CCriticalBlock(CRITICAL_SECTION& csIn) { pcs = &csIn; EnterCriticalSection(pcs); } + CCriticalBlock(CCriticalSection& csIn) { pcs = &csIn; EnterCriticalSection(pcs); } + ~CCriticalBlock() { LeaveCriticalSection(pcs); } +}; + +// WARNING: This will catch continue and break! +// break is caught with an assertion, but there's no way to detect continue. +// 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) + +class CTryCriticalBlock +{ +protected: + CRITICAL_SECTION* pcs; +public: + CTryCriticalBlock(CRITICAL_SECTION& csIn) { pcs = (TryEnterCriticalSection(&csIn) ? &csIn : NULL); } + CTryCriticalBlock(CCriticalSection& csIn) { pcs = (TryEnterCriticalSection(&csIn) ? &csIn : NULL); } + ~CTryCriticalBlock() { if (pcs) LeaveCriticalSection(pcs); } + 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) + + + + + + + + + + + + +inline string i64tostr(int64 n) +{ + return strprintf("%"PRId64, n); +} + +inline string itostr(int n) +{ + return strprintf("%d", n); +} + +inline int64 atoi64(const char* psz) +{ +#ifdef _MSC_VER + return _atoi64(psz); +#else + return strtoll(psz, NULL, 10); +#endif +} + +inline int64 atoi64(const string& str) +{ +#ifdef _MSC_VER + return _atoi64(str.c_str()); +#else + return strtoll(str.c_str(), NULL, 10); +#endif +} + +inline int atoi(const string& str) +{ + return atoi(str.c_str()); +} + +inline int roundint(double d) +{ + return (int)(d > 0 ? d + 0.5 : d - 0.5); +} + +template +string HexStr(const T itbegin, const T itend, bool fSpaces=true) +{ + const unsigned char* pbegin = (const unsigned char*)&itbegin[0]; + const unsigned char* pend = pbegin + (itend - itbegin) * sizeof(itbegin[0]); + string str; + for (const unsigned char* p = pbegin; p != pend; p++) + str += strprintf((fSpaces && p != pend-1 ? "%02x " : "%02x"), *p); + return str; +} + +template +string HexNumStr(const T itbegin, const T itend, bool f0x=true) +{ + const unsigned char* pbegin = (const unsigned char*)&itbegin[0]; + const unsigned char* pend = pbegin + (itend - itbegin) * sizeof(itbegin[0]); + string str = (f0x ? "0x" : ""); + for (const unsigned char* p = pend-1; p >= pbegin; p--) + str += strprintf("%02X", *p); + return str; +} + +template +void PrintHex(const T pbegin, const T pend, const char* pszFormat="%s", bool fSpaces=true) +{ + printf(pszFormat, HexStr(pbegin, pend, fSpaces).c_str()); +} + + + + + + + + +inline int OutputDebugStringF(const char* pszFormat, ...) +{ +#ifdef __WXDEBUG__ + // log file + FILE* fileout = fopen("debug.log", "a"); + if (fileout) + { + va_list arg_ptr; + va_start(arg_ptr, pszFormat); + vfprintf(fileout, pszFormat, arg_ptr); + va_end(arg_ptr); + fclose(fileout); + } + + // accumulate a line at a time + static CCriticalSection cs_OutputDebugStringF; + CRITICAL_BLOCK(cs_OutputDebugStringF) + { + static char pszBuffer[50000]; + static char* pend; + if (pend == NULL) + pend = pszBuffer; + va_list arg_ptr; + va_start(arg_ptr, pszFormat); + int limit = END(pszBuffer) - pend - 2; + int ret = _vsnprintf(pend, limit, pszFormat, arg_ptr); + va_end(arg_ptr); + if (ret < 0 || ret >= limit) + { + pend = END(pszBuffer) - 2; + *pend++ = '\n'; + } + else + pend += ret; + *pend = '\0'; + char* p1 = pszBuffer; + char* p2; + while (p2 = strchr(p1, '\n')) + { + p2++; + char c = *p2; + *p2 = '\0'; + OutputDebugString(p1); + *p2 = c; + p1 = p2; + } + if (p1 != pszBuffer) + memmove(pszBuffer, p1, pend - p1 + 1); + pend -= (p1 - pszBuffer); + return ret; + } +#endif + + if (!wxTheApp) + { + // print to console + va_list arg_ptr; + va_start(arg_ptr, pszFormat); + vprintf(pszFormat, arg_ptr); + va_end(arg_ptr); + } + return 0; +} + + + + + + + + + +inline void heapchk() +{ + if (_heapchk() != _HEAPOK) + DebugBreak(); +} + +// Randomize the stack to help protect against buffer overrun exploits +#define IMPLEMENT_RANDOMIZE_STACK(ThreadFn) \ + { \ + static char nLoops; \ + if (nLoops <= 0) \ + nLoops = GetRand(50) + 1; \ + if (nLoops-- > 1) \ + { \ + ThreadFn; \ + return; \ + } \ + } + +#define CATCH_PRINT_EXCEPTION(pszFn) \ + catch (std::exception& e) { \ + PrintException(&e, (pszFn)); \ + } catch (...) { \ + PrintException(NULL, (pszFn)); \ + } + + + + + + + + + +template +inline uint256 Hash(const T1 pbegin, const T1 pend) +{ + uint256 hash1; + SHA256((unsigned char*)&pbegin[0], (pend - pbegin) * sizeof(pbegin[0]), (unsigned char*)&hash1); + uint256 hash2; + SHA256((unsigned char*)&hash1, sizeof(hash1), (unsigned char*)&hash2); + return hash2; +} + +template +inline uint256 Hash(const T1 p1begin, const T1 p1end, + const T2 p2begin, const T2 p2end) +{ + uint256 hash1; + SHA256_CTX ctx; + SHA256_Init(&ctx); + SHA256_Update(&ctx, (unsigned char*)&p1begin[0], (p1end - p1begin) * sizeof(p1begin[0])); + SHA256_Update(&ctx, (unsigned char*)&p2begin[0], (p2end - p2begin) * sizeof(p2begin[0])); + SHA256_Final((unsigned char*)&hash1, &ctx); + uint256 hash2; + SHA256((unsigned char*)&hash1, sizeof(hash1), (unsigned char*)&hash2); + return hash2; +} + +template +inline uint256 Hash(const T1 p1begin, const T1 p1end, + const T2 p2begin, const T2 p2end, + const T3 p3begin, const T3 p3end) +{ + uint256 hash1; + SHA256_CTX ctx; + SHA256_Init(&ctx); + SHA256_Update(&ctx, (unsigned char*)&p1begin[0], (p1end - p1begin) * sizeof(p1begin[0])); + SHA256_Update(&ctx, (unsigned char*)&p2begin[0], (p2end - p2begin) * sizeof(p2begin[0])); + SHA256_Update(&ctx, (unsigned char*)&p3begin[0], (p3end - p3begin) * sizeof(p3begin[0])); + SHA256_Final((unsigned char*)&hash1, &ctx); + uint256 hash2; + SHA256((unsigned char*)&hash1, sizeof(hash1), (unsigned char*)&hash2); + return hash2; +} + +template +uint256 SerializeHash(const T& obj, int nType=SER_GETHASH, int nVersion=VERSION) +{ + // Most of the time is spent allocating and deallocating CDataStream's + // buffer. If this ever needs to be optimized further, make a CStaticStream + // class with its buffer on the stack. + CDataStream ss(nType, nVersion); + ss.reserve(10000); + ss << obj; + return Hash(ss.begin(), ss.end()); +} + +inline uint160 Hash160(const vector& vch) +{ + uint256 hash1; + SHA256(&vch[0], vch.size(), (unsigned char*)&hash1); + uint160 hash2; + RIPEMD160((unsigned char*)&hash1, sizeof(hash1), (unsigned char*)&hash2); + return hash2; +} -- cgit v1.2.3 From edffb50b984ff1c6a4dfdc4ebdb84ca776eb0666 Mon Sep 17 00:00:00 2001 From: sirius-m Date: Sun, 30 Aug 2009 03:50:53 +0000 Subject: Added changelog.txt --- changelog.txt | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 changelog.txt diff --git a/changelog.txt b/changelog.txt new file mode 100644 index 0000000000..19120c3e4b --- /dev/null +++ b/changelog.txt @@ -0,0 +1,2 @@ +Changes after 0.1.5: +-------------------- -- cgit v1.2.3 From 465e1d99f25cc7f45efcacfcbb1f95c1c1f9a4ee Mon Sep 17 00:00:00 2001 From: sirius-m Date: Sun, 30 Aug 2009 03:50:53 +0000 Subject: Added changelog.txt git-svn-id: https://bitcoin.svn.sourceforge.net/svnroot/bitcoin/trunk@2 1a98c847-1fd6-4fd8-948a-caf3550aa51b --- changelog.txt | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 changelog.txt diff --git a/changelog.txt b/changelog.txt new file mode 100644 index 0000000000..19120c3e4b --- /dev/null +++ b/changelog.txt @@ -0,0 +1,2 @@ +Changes after 0.1.5: +-------------------- -- cgit v1.2.3 From e00d4805d71de8bb32c9af600f5bd8fce2414d5d Mon Sep 17 00:00:00 2001 From: sirius-m Date: Wed, 16 Sep 2009 13:26:04 +0000 Subject: No dll's here --- libeay32.dll | Bin 1306630 -> 0 bytes mingwm10.dll | Bin 11673 -> 0 bytes 2 files changed, 0 insertions(+), 0 deletions(-) delete mode 100644 libeay32.dll delete mode 100644 mingwm10.dll diff --git a/libeay32.dll b/libeay32.dll deleted file mode 100644 index 3bc745c4c0..0000000000 Binary files a/libeay32.dll and /dev/null differ diff --git a/mingwm10.dll b/mingwm10.dll deleted file mode 100644 index bf8544ce13..0000000000 Binary files a/mingwm10.dll and /dev/null differ -- cgit v1.2.3 From 8dca7864f793072701f810e4c5ea12a6e1087085 Mon Sep 17 00:00:00 2001 From: sirius-m Date: Wed, 16 Sep 2009 13:26:04 +0000 Subject: No dll's here git-svn-id: https://bitcoin.svn.sourceforge.net/svnroot/bitcoin/trunk@8 1a98c847-1fd6-4fd8-948a-caf3550aa51b --- libeay32.dll | Bin 1306630 -> 0 bytes mingwm10.dll | Bin 11673 -> 0 bytes 2 files changed, 0 insertions(+), 0 deletions(-) delete mode 100644 libeay32.dll delete mode 100644 mingwm10.dll diff --git a/libeay32.dll b/libeay32.dll deleted file mode 100644 index 3bc745c4c0..0000000000 Binary files a/libeay32.dll and /dev/null differ diff --git a/mingwm10.dll b/mingwm10.dll deleted file mode 100644 index bf8544ce13..0000000000 Binary files a/mingwm10.dll and /dev/null differ -- cgit v1.2.3 From d1b70ffa03863b810813dd9d098b38500d4be424 Mon Sep 17 00:00:00 2001 From: sirius-m Date: Thu, 24 Sep 2009 04:09:56 +0000 Subject: tray icon + ask before closing --- bugs.txt | 4 + changelog.txt | 4 + db.cpp | 5 + headers.h | 8 +- main.cpp | 3 - main.h | 1 - makefile | 4 +- ui.cpp | 229 +++- ui.h | 61 +- uibase.cpp | 3467 +++++++++++++++++++++++++++++---------------------------- uibase.h | 1196 ++++++++++---------- uiproject.fbp | 825 +++++++++++--- 12 files changed, 3362 insertions(+), 2445 deletions(-) create mode 100644 bugs.txt diff --git a/bugs.txt b/bugs.txt new file mode 100644 index 0000000000..348c359e8a --- /dev/null +++ b/bugs.txt @@ -0,0 +1,4 @@ +Known bugs: +- For some reason, CreateHardLink doesn't add a shortcut to the startup folder +- When the program is minimized to tray, double clicking the icon only restores it to the task bar +- Window flickers when blocks are added (problem with repainting?) \ No newline at end of file diff --git a/changelog.txt b/changelog.txt index 19120c3e4b..685eb6292b 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,2 +1,6 @@ Changes after 0.1.5: -------------------- ++ Options dialog layout changed - added the UI options panel ++ Minimize to tray feature ++ Startup on system boot feature ++ Ask before closing \ No newline at end of file diff --git a/db.cpp b/db.cpp index f38f3ffad8..6607ff5961 100644 --- a/db.cpp +++ b/db.cpp @@ -575,6 +575,11 @@ bool CWalletDB::LoadWallet(vector& vchDefaultKeyRet) if (strKey == "fGenerateBitcoins") ssValue >> fGenerateBitcoins; if (strKey == "nTransactionFee") ssValue >> nTransactionFee; if (strKey == "addrIncoming") ssValue >> addrIncoming; + if (strKey == "minimizeToTray") ssValue >> minimizeToTray; + if (strKey == "closeToTray") ssValue >> closeToTray; + if (strKey == "startOnSysBoot") ssValue >> startOnSysBoot; + if (strKey == "askBeforeClosing") ssValue >> askBeforeClosing; + if (strKey == "alwaysShowTrayIcon") ssValue >> alwaysShowTrayIcon; } } } diff --git a/headers.h b/headers.h index 7bd68a1994..92911505b8 100644 --- a/headers.h +++ b/headers.h @@ -10,11 +10,16 @@ #ifdef _WIN32_WINNT #undef _WIN32_WINNT #endif -#define _WIN32_WINNT 0x0400 +#define _WIN32_WINNT 0x0500 +#ifdef _WIN32_IE +#undef _WIN32_IE +#endif +#define _WIN32_IE 0x0500 #define WIN32_LEAN_AND_MEAN 1 #include #include #include +#include #include #include #include @@ -32,6 +37,7 @@ #include #include #include +#include #include #define BOUNDSCHECK 1 #include diff --git a/main.cpp b/main.cpp index 97000db381..ebf9d727cb 100644 --- a/main.cpp +++ b/main.cpp @@ -54,9 +54,6 @@ CAddress addrIncoming; - - - ////////////////////////////////////////////////////////////////////////////// // // mapKeys diff --git a/main.h b/main.h index 3432b316e7..9dd29bb6a9 100644 --- a/main.h +++ b/main.h @@ -47,7 +47,6 @@ extern CAddress addrIncoming; - string GetAppDir(); bool CheckDiskSpace(int64 nAdditionalBytes=0); FILE* OpenBlockFile(unsigned int nFile, unsigned int nBlockPos, const char* pszMode="rb"); diff --git a/makefile b/makefile index 534eb521e8..221684e8a9 100644 --- a/makefile +++ b/makefile @@ -12,7 +12,7 @@ ifeq "$(BUILD)" "debug" D=d # note: gcc 3.x profile doesn't work #DEBUGFLAGS=-O0 -g -pg -D__WXDEBUG__ -DEBUGFLAGS=-g -D__WXDEBUG__ +DEBUGFLAGS=-g -D__WXDEBUG__ -Wall -Wextra endif @@ -22,7 +22,7 @@ LIBPATHS=-L"/DB/build_unix" -L"/OpenSSL/out" -L"/wxWidgets/lib/gcc_lib" LIBS= \ -l db_cxx \ -l eay32 \ - -l wxmsw28$(D)_richtext -l wxmsw28$(D)_html -l wxmsw28$(D)_core -l wxbase28$(D) -l wxtiff$(D) -l wxjpeg$(D) -l wxpng$(D) -l wxzlib$(D) -l wxregex$(D) -l wxexpat$(D) \ + -l wxmsw28$(D)_richtext -l wxmsw28$(D)_html -l wxmsw28$(D)_core -l wxmsw28$(D)_adv -l wxbase28$(D) -l wxtiff$(D) -l wxjpeg$(D) -l wxpng$(D) -l wxzlib$(D) -l wxregex$(D) -l wxexpat$(D) \ -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 WXDEFS=-DWIN32 -D__WXMSW__ -D_WINDOWS -DNOPCH CFLAGS=-mthreads -O0 -w -Wno-invalid-offsetof -Wformat $(DEBUGFLAGS) $(WXDEFS) $(INCLUDEPATHS) diff --git a/ui.cpp b/ui.cpp index 96c5a83d58..751a50be68 100644 --- a/ui.cpp +++ b/ui.cpp @@ -7,8 +7,6 @@ #include #endif - - DEFINE_EVENT_TYPE(wxEVT_CROSSTHREADCALL) DEFINE_EVENT_TYPE(wxEVT_REPLY1) DEFINE_EVENT_TYPE(wxEVT_REPLY2) @@ -19,6 +17,7 @@ DEFINE_EVENT_TYPE(wxEVT_TABLEDELETED) CMainFrame* pframeMain = NULL; map mapAddressBook; +CBitcoinTBIcon* taskBarIcon = NULL; // Tray icon void ThreadRequestProductDetails(void* parg); @@ -27,8 +26,12 @@ bool fRandSendTest = false; void RandSend(); extern int g_isPainting; - - +// UI settings and their default values +int minimizeToTray = 1; +int closeToTray = 1; +int startOnSysBoot = 1; +int askBeforeClosing = 1; +int alwaysShowTrayIcon = 1; @@ -359,8 +362,28 @@ void Shutdown(void* parg) void CMainFrame::OnClose(wxCloseEvent& event) { - Destroy(); - _beginthread(Shutdown, 0, NULL); + if (closeToTray && event.CanVeto()) { + event.Veto(); + SendToTray(); + } + else if (!event.CanVeto() || !askBeforeClosing || wxMessageBox("Quit program?", "Confirm", wxYES_NO, this) == wxYES) { + delete taskBarIcon; + Destroy(); + _beginthread(Shutdown, 0, NULL); + } +} + +void CMainFrame::OnIconize(wxIconizeEvent& event) +{ + if (minimizeToTray) { + SendToTray(); + } +} + +void CMainFrame::SendToTray() +{ + Hide(); + taskBarIcon->Show(); } void CMainFrame::OnMouseEvents(wxMouseEvent& event) @@ -836,16 +859,22 @@ void CMainFrame::OnMenuFileExit(wxCommandEvent& event) Close(true); } -void CMainFrame::OnMenuOptionsGenerate(wxCommandEvent& event) +void GenerateBitcoins(bool flag) { - fGenerateBitcoins = event.IsChecked(); + fGenerateBitcoins = flag; nTransactionsUpdated++; CWalletDB().WriteSetting("fGenerateBitcoins", fGenerateBitcoins); - if (fGenerateBitcoins) if (_beginthread(ThreadBitcoinMiner, 0, NULL) == -1) printf("Error: _beginthread(ThreadBitcoinMiner) failed\n"); + taskBarIcon->UpdateTooltip(); +} + +void CMainFrame::OnMenuOptionsGenerate(wxCommandEvent& event) +{ + GenerateBitcoins(event.IsChecked()); + Refresh(); wxPaintEvent eventPaint; AddPendingEvent(eventPaint); @@ -868,6 +897,10 @@ void CMainFrame::OnMenuHelpAbout(wxCommandEvent& event) dialog.ShowModal(); } +void CMainFrame::OnUpdateMenuGenerate( wxUpdateUIEvent& event ) { + event.Check(fGenerateBitcoins); +} + void CMainFrame::OnButtonSend(wxCommandEvent& event) { /// debug test @@ -1231,23 +1264,57 @@ void CTxDetailsDialog::OnButtonOK(wxCommandEvent& event) COptionsDialog::COptionsDialog(wxWindow* parent) : COptionsDialogBase(parent) { - m_textCtrlTransactionFee->SetValue(FormatMoney(nTransactionFee)); m_buttonOK->SetFocus(); + m_treeCtrl->AddRoot(wxT("Settings")); + m_treeCtrl->AppendItem(m_treeCtrl->GetRootItem(), wxT("Bitcoin")); + m_treeCtrl->AppendItem(m_treeCtrl->GetRootItem(), wxT("UI")); + + panelUI = new COptionsPanelUI(this); + panelBitcoin = new COptionsPanelBitcoin(this); + currentPanel = panelBitcoin; + + panelSizer->Add(panelUI); + panelSizer->Hide(panelUI); + panelSizer->Add(panelBitcoin); + panelSizer->Layout(); + } -void COptionsDialog::OnKillFocusTransactionFee(wxFocusEvent& event) +void COptionsDialog::MenuSelChanged( wxTreeEvent& event ) { - int64 nTmp = nTransactionFee; - ParseMoney(m_textCtrlTransactionFee->GetValue(), nTmp); - m_textCtrlTransactionFee->SetValue(FormatMoney(nTmp)); + panelSizer->Hide(currentPanel); + wxString text = m_treeCtrl->GetItemText(event.GetItem()); + if (text == "Bitcoin") { + panelSizer->Show(panelBitcoin); + currentPanel = panelBitcoin; + } + else { + panelSizer->Show(panelUI); + currentPanel = panelUI; + } + panelSizer->Layout(); } void COptionsDialog::OnButtonOK(wxCommandEvent& event) { // nTransactionFee int64 nPrevTransactionFee = nTransactionFee; - if (ParseMoney(m_textCtrlTransactionFee->GetValue(), nTransactionFee) && nTransactionFee != nPrevTransactionFee) - CWalletDB().WriteSetting("nTransactionFee", nTransactionFee); + if (ParseMoney(panelBitcoin->m_textCtrlTransactionFee->GetValue(), nTransactionFee) && nTransactionFee != nPrevTransactionFee) + CWalletDB().WriteSetting("transactionFee", nTransactionFee); + + minimizeToTray = panelUI->m_checkMinToTray->IsChecked(); + closeToTray = panelUI->m_checkCloseToTray->IsChecked(); + startOnSysBoot = panelUI->m_checkStartOnSysBoot->IsChecked(); + askBeforeClosing = panelUI->m_checkAskBeforeClosing->IsChecked(); + alwaysShowTrayIcon = panelUI->m_checkAlwaysShowTray->IsChecked(); + + CWalletDB().WriteSetting("minimizeToTray", minimizeToTray); + CWalletDB().WriteSetting("closeToTray", closeToTray); + CWalletDB().WriteSetting("startOnSysBoot", startOnSysBoot); + CWalletDB().WriteSetting("askBeforeClosing", askBeforeClosing); + CWalletDB().WriteSetting("alwaysShowTrayIcon", alwaysShowTrayIcon); + + ApplyUISettings(); Close(); } @@ -1259,6 +1326,39 @@ void COptionsDialog::OnButtonCancel(wxCommandEvent& event) +////////////////////////////////////////////////////////////////////////////// +// +// COptionsPanelBitcoin +// + +COptionsPanelBitcoin::COptionsPanelBitcoin(wxWindow* parent) : COptionsPanelBitcoinBase(parent) +{ + m_textCtrlTransactionFee->SetValue(FormatMoney(nTransactionFee)); +} + +void COptionsPanelBitcoin::OnKillFocusTransactionFee(wxFocusEvent& event) +{ + int64 nTmp = nTransactionFee; + ParseMoney(m_textCtrlTransactionFee->GetValue(), nTmp); + m_textCtrlTransactionFee->SetValue(FormatMoney(nTmp)); +} + + +////////////////////////////////////////////////////////////////////////////// +// +// COptionsPanelUI +// + +COptionsPanelUI::COptionsPanelUI(wxWindow* parent) : COptionsPanelUIBase(parent) +{ + m_checkMinToTray->SetValue(minimizeToTray); + m_checkCloseToTray->SetValue(closeToTray); + m_checkStartOnSysBoot->SetValue(startOnSysBoot); + m_checkAskBeforeClosing->SetValue(askBeforeClosing); + m_checkAlwaysShowTray->SetValue(alwaysShowTrayIcon); +} + + @@ -2862,10 +2962,79 @@ void CEditReviewDialog::GetReview(CReview& review) +////////////////////////////////////////////////////////////////////////////// +// +// BitcoinTBIcon +// + +enum { + PU_RESTORE = 10001, + PU_GENERATE, + PU_EXIT, +}; +BEGIN_EVENT_TABLE(CBitcoinTBIcon, wxTaskBarIcon) + EVT_TASKBAR_LEFT_DCLICK (CBitcoinTBIcon::OnLeftButtonDClick) + EVT_MENU(PU_RESTORE, CBitcoinTBIcon::OnMenuRestore) + EVT_MENU(PU_GENERATE, CBitcoinTBIcon::OnMenuGenerate) + EVT_MENU(PU_EXIT, CBitcoinTBIcon::OnMenuExit) +END_EVENT_TABLE() +void CBitcoinTBIcon::Show() +{ + string tooltip = "Bitcoin"; + tooltip += fGenerateBitcoins ? " - Generating" : ""; + SetIcon(wxICON(bitcoin), tooltip); +} +void CBitcoinTBIcon::Hide() +{ + RemoveIcon(); +} +void CBitcoinTBIcon::OnLeftButtonDClick(wxTaskBarIconEvent&) +{ + Restore(); +} + +void CBitcoinTBIcon::OnMenuExit(wxCommandEvent&) +{ + pframeMain->Close(true); +} + +void CBitcoinTBIcon::OnMenuGenerate(wxCommandEvent& event) +{ + GenerateBitcoins(event.IsChecked()); + pframeMain->Refresh(); +} + +void CBitcoinTBIcon::OnMenuRestore(wxCommandEvent&) { + Restore(); +} + +void CBitcoinTBIcon::Restore() { + pframeMain->Show(); + pframeMain->Raise(); + if (!alwaysShowTrayIcon) + Hide(); +} + +void CBitcoinTBIcon::UpdateTooltip() { + if (IsIconInstalled()) + Show(); +} + +wxMenu *CBitcoinTBIcon::CreatePopupMenu() +{ + wxMenu *menu = new wxMenu; + wxMenuItem* generateCheck = menu->AppendCheckItem(PU_GENERATE, _T("Generate Coins")); + menu->Append(PU_RESTORE, _T("Open Bitcoin")); + menu->Append(PU_EXIT, _T("Exit")); + + generateCheck->Check(fGenerateBitcoins); + + return menu; +} @@ -3137,6 +3306,9 @@ bool CMyApp::OnInit2() } } + taskBarIcon = new CBitcoinTBIcon(); + ApplyUISettings(); + return true; } @@ -3214,6 +3386,31 @@ void MainFrameRepaint() +void ApplyUISettings() { + // Show the tray icon? + if (alwaysShowTrayIcon) + taskBarIcon->Show(); + else + taskBarIcon->Hide(); + + // Autostart on system startup? + if (startOnSysBoot) { + // Get the startup folder path + char targetPath[ MAX_PATH ]; + SHGetSpecialFolderPath(0, targetPath, CSIDL_STARTUP, 0); + strcat(targetPath, "\\bitcoin.lnk"); + + // And the current executable path + char currentPath[ MAX_PATH ]; + GetModuleFileName(NULL, currentPath, _MAX_PATH + 1); + + // Create the shortcut + CreateHardLink(targetPath, currentPath, NULL); + } +} + + + diff --git a/ui.h b/ui.h index 163554a599..5f3897c1be 100644 --- a/ui.h +++ b/ui.h @@ -27,9 +27,14 @@ extern string FormatTxStatus(const CWalletTx& wtx); extern void CrossThreadCall(int nID, void* pdata); extern void MainFrameRepaint(); extern void Shutdown(void* parg); +void ApplyUISettings(); - - +// UI settings +extern int minimizeToTray; +extern int closeToTray; +extern int startOnSysBoot; +extern int askBeforeClosing; +extern int alwaysShowTrayIcon; @@ -38,6 +43,7 @@ class CMainFrame : public CMainFrameBase protected: // Event handlers void OnClose(wxCloseEvent& event); + void OnIconize( wxIconizeEvent& event ); void OnMouseEvents(wxMouseEvent& event); void OnKeyDown(wxKeyEvent& event) { HandleCtrlA(event); } void OnIdle(wxIdleEvent& event); @@ -59,6 +65,7 @@ protected: void OnListItemActivatedProductsSent(wxListEvent& event); void OnListItemActivatedOrdersSent(wxListEvent& event); void OnListItemActivatedOrdersReceived(wxListEvent& event); + void OnUpdateMenuGenerate( wxUpdateUIEvent& event ); public: /** Constructor */ @@ -77,6 +84,7 @@ public: void InsertTransaction(const CWalletTx& wtx, bool fNew, int nIndex=-1); void RefreshListCtrl(); void RefreshStatus(); + void SendToTray(); }; @@ -98,14 +106,44 @@ public: +class COptionsPanelBitcoin : public COptionsPanelBitcoinBase +{ +protected: + // Event handlers + void OnKillFocusTransactionFee( wxFocusEvent& event ); + +public: + /** Constructor */ + COptionsPanelBitcoin(wxWindow* parent); +}; + + + +class COptionsPanelUI : public COptionsPanelUIBase +{ +protected: + // Event handlers + void OnOptionsChanged( wxCommandEvent& event ); + +public: + /** Constructor */ + COptionsPanelUI(wxWindow* parent); +}; + + + class COptionsDialog : public COptionsDialogBase { protected: // Event handlers - void OnKillFocusTransactionFee(wxFocusEvent& event); + void MenuSelChanged( wxTreeEvent& event ); void OnButtonOK(wxCommandEvent& event); void OnButtonCancel(wxCommandEvent& event); + // Panels + COptionsPanelBitcoin* panelBitcoin; + COptionsPanelUI* panelUI; + wxPanel* currentPanel; public: /** Constructor */ COptionsDialog(wxWindow* parent); @@ -416,5 +454,22 @@ public: +class CBitcoinTBIcon : public wxTaskBarIcon +{ +protected: + void Restore(); + + // Event handlers + void OnLeftButtonDClick(wxTaskBarIconEvent&); + void OnMenuExit(wxCommandEvent&); + void OnMenuGenerate(wxCommandEvent&); + void OnMenuRestore(wxCommandEvent&); +public: + void Show(); + void Hide(); + void UpdateTooltip(); + virtual wxMenu *CreatePopupMenu(); +DECLARE_EVENT_TABLE() +}; diff --git a/uibase.cpp b/uibase.cpp index 2972e9af3b..dcaa697588 100644 --- a/uibase.cpp +++ b/uibase.cpp @@ -1,7 +1,3 @@ -// Copyright (c) 2009 Satoshi Nakamoto -// Distributed under the MIT/X11 software license, see the accompanying -// file license.txt or http://www.opensource.org/licenses/mit-license.php. - /////////////////////////////////////////////////////////////////////////// // C++ code generated with wxFormBuilder (version Apr 16 2008) // http://www.wxformbuilder.org/ @@ -13,1813 +9,1884 @@ /////////////////////////////////////////////////////////////////////////// -CMainFrameBase::CMainFrameBase(wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style) : wxFrame(parent, id, title, pos, size, style) +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_menubar->SetBackgroundColour(wxColour(240, 240, 240)); - - m_menuFile = new wxMenu(); - wxMenuItem* m_menuFileExit; - m_menuFileExit = new wxMenuItem(m_menuFile, wxID_ANY, wxString(wxT("E&xit")) , wxEmptyString, wxITEM_NORMAL); - m_menuFile->Append(m_menuFileExit); - - m_menubar->Append(m_menuFile, wxT("&File")); - - m_menuOptions = new wxMenu(); - wxMenuItem* m_menuOptionsGenerateBitcoins; - m_menuOptionsGenerateBitcoins = new wxMenuItem(m_menuOptions, wxID_OPTIONSGENERATEBITCOINS, wxString(wxT("&Generate Coins")) , wxEmptyString, wxITEM_CHECK); - m_menuOptions->Append(m_menuOptionsGenerateBitcoins); - - wxMenuItem* m_menuChangeYourAddress; - m_menuChangeYourAddress = new wxMenuItem(m_menuOptions, wxID_ANY, wxString(wxT("&Change Your Address...")) , wxEmptyString, wxITEM_NORMAL); - m_menuOptions->Append(m_menuChangeYourAddress); - - wxMenuItem* m_menuOptionsOptions; - m_menuOptionsOptions = new wxMenuItem(m_menuOptions, wxID_ANY, wxString(wxT("&Options...")) , wxEmptyString, wxITEM_NORMAL); - m_menuOptions->Append(m_menuOptionsOptions); - - m_menubar->Append(m_menuOptions, wxT("&Options")); - - m_menuHelp = new wxMenu(); - wxMenuItem* m_menuHelpAbout; - m_menuHelpAbout = new wxMenuItem(m_menuHelp, wxID_ANY, wxString(wxT("&About...")) , wxEmptyString, wxITEM_NORMAL); - m_menuHelp->Append(m_menuHelpAbout); - - m_menubar->Append(m_menuHelp, wxT("&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, wxT("&Send Coins"), wxBitmap(wxT("send20"), wxBITMAP_TYPE_RESOURCE), wxNullBitmap, wxITEM_NORMAL, wxEmptyString, wxEmptyString); - m_toolBar->AddTool(wxID_BUTTONRECEIVE, wxT("&Address Book"), wxBitmap(wxT("addressbook20"), wxBITMAP_TYPE_RESOURCE), wxNullBitmap, wxITEM_NORMAL, wxEmptyString, wxEmptyString); - m_toolBar->Realize(); - - m_statusBar = this->CreateStatusBar(1, wxST_SIZEGRIP, wxID_ANY); - m_statusBar->SetBackgroundColour(wxColour(240, 240, 240)); - - 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, wxT("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(250,-1), wxTE_READONLY); - m_textCtrlAddress->SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_MENU)); - - bSizer85->Add(m_textCtrlAddress, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5); - - m_buttonCopy = new wxButton(this, wxID_BUTTONCOPY, wxT("&Copy to Clipboard"), wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT); - bSizer85->Add(m_buttonCopy, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 5); - - m_button91 = new wxButton(this, wxID_BUTTONCHANGE, wxT("C&hange..."), wxDefaultPosition, wxDefaultSize, 0); - m_button91->Hide(); - - bSizer85->Add(m_button91, 0, wxRIGHT, 5); - - - bSizer85->Add(0, 0, 0, wxEXPAND, 5); - - bSizer2->Add(bSizer85, 0, wxEXPAND|wxRIGHT|wxLEFT, 5); - - wxBoxSizer* bSizer3; - bSizer3 = new wxBoxSizer(wxHORIZONTAL); - - m_panel14 = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL); - wxBoxSizer* bSizer66; - bSizer66 = new wxBoxSizer(wxHORIZONTAL); - - m_staticText41 = new wxStaticText(m_panel14, wxID_ANY, wxT("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(m_panel14, 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(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW)); - - bSizer66->Add(m_staticTextBalance, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5); - - m_panel14->SetSizer(bSizer66); - m_panel14->Layout(); - bSizer66->Fit(m_panel14); - bSizer3->Add(m_panel14, 1, wxEXPAND|wxALIGN_BOTTOM|wxALL, 5); - - - bSizer3->Add(0, 0, 0, wxEXPAND, 5); - - wxString m_choiceFilterChoices[] = { wxT(" All"), wxT(" Sent"), wxT(" Received"), wxT(" 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_panel7 = new wxPanel(m_notebook, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL); - wxBoxSizer* bSizer157; - bSizer157 = new wxBoxSizer(wxVERTICAL); - - m_listCtrl = new wxListCtrl(m_panel7, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_NO_SORT_HEADER|wxLC_REPORT|wxLC_SORT_DESCENDING|wxALWAYS_SHOW_SB); - bSizer157->Add(m_listCtrl, 1, wxEXPAND|wxALL, 5); - - m_panel7->SetSizer(bSizer157); - m_panel7->Layout(); - bSizer157->Fit(m_panel7); - m_notebook->AddPage(m_panel7, wxT("All Transactions"), false); - - bSizer2->Add(m_notebook, 1, wxEXPAND, 5); - - wxBoxSizer* bSizer_TabsForFutureUse; - bSizer_TabsForFutureUse = new wxBoxSizer(wxVERTICAL); - - m_panel9 = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL); - m_panel9->Hide(); - - wxBoxSizer* bSizer159; - bSizer159 = new wxBoxSizer(wxVERTICAL); - - m_listCtrlEscrows = new wxListCtrl(m_panel9, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_NO_SORT_HEADER|wxLC_REPORT); - bSizer159->Add(m_listCtrlEscrows, 1, wxALL|wxEXPAND, 5); - - m_panel9->SetSizer(bSizer159); - m_panel9->Layout(); - bSizer159->Fit(m_panel9); - bSizer_TabsForFutureUse->Add(m_panel9, 1, wxEXPAND | wxALL, 5); - - m_panel8 = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL); - m_panel8->Hide(); - - wxBoxSizer* bSizer158; - bSizer158 = new wxBoxSizer(wxVERTICAL); - - m_listCtrlOrdersSent = new wxListCtrl(m_panel8, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_NO_SORT_HEADER|wxLC_REPORT); - bSizer158->Add(m_listCtrlOrdersSent, 1, wxALL|wxEXPAND, 5); - - m_panel8->SetSizer(bSizer158); - m_panel8->Layout(); - bSizer158->Fit(m_panel8); - bSizer_TabsForFutureUse->Add(m_panel8, 1, wxEXPAND | wxALL, 5); - - m_panel10 = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL); - m_panel10->Hide(); - - wxBoxSizer* bSizer160; - bSizer160 = new wxBoxSizer(wxVERTICAL); - - m_listCtrlProductsSent = new wxListCtrl(m_panel10, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_NO_SORT_HEADER|wxLC_REPORT); - bSizer160->Add(m_listCtrlProductsSent, 1, wxALL|wxEXPAND, 5); - - m_panel10->SetSizer(bSizer160); - m_panel10->Layout(); - bSizer160->Fit(m_panel10); - bSizer_TabsForFutureUse->Add(m_panel10, 1, wxEXPAND | wxALL, 5); - - m_panel11 = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL); - m_panel11->Hide(); - - wxBoxSizer* bSizer161; - bSizer161 = new wxBoxSizer(wxVERTICAL); - - m_listCtrlOrdersReceived = new wxListCtrl(m_panel11, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_NO_SORT_HEADER|wxLC_REPORT); - bSizer161->Add(m_listCtrlOrdersReceived, 1, wxALL|wxEXPAND, 5); - - m_panel11->SetSizer(bSizer161); - m_panel11->Layout(); - bSizer161->Fit(m_panel11); - bSizer_TabsForFutureUse->Add(m_panel11, 1, wxEXPAND | wxALL, 5); - - bSizer2->Add(bSizer_TabsForFutureUse, 1, wxEXPAND, 5); - - this->SetSizer(bSizer2); - this->Layout(); - - // Connect Events - this->Connect(wxEVT_CLOSE_WINDOW, wxCloseEventHandler(CMainFrameBase::OnClose)); - 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_menuOptionsGenerateBitcoins->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(CMainFrameBase::OnMenuOptionsGenerate)); - this->Connect(m_menuChangeYourAddress->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_buttonCopy->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CMainFrameBase::OnButtonCopy), NULL, this); - m_button91->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CMainFrameBase::OnButtonChange), NULL, this); - m_listCtrl->Connect(wxEVT_COMMAND_LIST_COL_BEGIN_DRAG, wxListEventHandler(CMainFrameBase::OnListColBeginDrag), NULL, this); - m_listCtrl->Connect(wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler(CMainFrameBase::OnListItemActivatedAllTransactions), NULL, this); - m_listCtrl->Connect(wxEVT_PAINT, wxPaintEventHandler(CMainFrameBase::OnPaintListCtrl), NULL, this); - m_listCtrlOrdersSent->Connect(wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler(CMainFrameBase::OnListItemActivatedOrdersSent), NULL, this); - m_listCtrlProductsSent->Connect(wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler(CMainFrameBase::OnListItemActivatedProductsSent), NULL, this); - m_listCtrlOrdersReceived->Connect(wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler(CMainFrameBase::OnListItemActivatedOrdersReceived), NULL, this); + this->SetSizeHints( wxDefaultSize, wxDefaultSize ); + this->SetBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_BTNFACE ) ); + + m_menubar = new wxMenuBar( 0 ); + m_menubar->SetBackgroundColour( wxColour( 240, 240, 240 ) ); + + m_menuFile = new wxMenu(); + wxMenuItem* m_menuFileExit; + m_menuFileExit = new wxMenuItem( m_menuFile, wxID_ANY, wxString( wxT("E&xit") ) , wxEmptyString, wxITEM_NORMAL ); + m_menuFile->Append( m_menuFileExit ); + + m_menubar->Append( m_menuFile, wxT("&File") ); + + m_menuOptions = new wxMenu(); + wxMenuItem* m_menuOptionsGenerateBitcoins; + m_menuOptionsGenerateBitcoins = new wxMenuItem( m_menuOptions, wxID_OPTIONSGENERATEBITCOINS, wxString( wxT("&Generate Coins") ) , wxEmptyString, wxITEM_CHECK ); + m_menuOptions->Append( m_menuOptionsGenerateBitcoins ); + + wxMenuItem* m_menuChangeYourAddress; + m_menuChangeYourAddress = new wxMenuItem( m_menuOptions, wxID_ANY, wxString( wxT("&Change Your Address...") ) , wxEmptyString, wxITEM_NORMAL ); + m_menuOptions->Append( m_menuChangeYourAddress ); + + wxMenuItem* m_menuOptionsOptions; + m_menuOptionsOptions = new wxMenuItem( m_menuOptions, wxID_ANY, wxString( wxT("&Options...") ) , wxEmptyString, wxITEM_NORMAL ); + m_menuOptions->Append( m_menuOptionsOptions ); + + m_menubar->Append( m_menuOptions, wxT("&Options") ); + + m_menuHelp = new wxMenu(); + wxMenuItem* m_menuHelpAbout; + m_menuHelpAbout = new wxMenuItem( m_menuHelp, wxID_ANY, wxString( wxT("&About...") ) , wxEmptyString, wxITEM_NORMAL ); + m_menuHelp->Append( m_menuHelpAbout ); + + m_menubar->Append( m_menuHelp, wxT("&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, wxT("&Send Coins"), wxBitmap( wxT("send20"), wxBITMAP_TYPE_RESOURCE ), wxNullBitmap, wxITEM_NORMAL, wxEmptyString, wxEmptyString ); + m_toolBar->AddTool( wxID_BUTTONRECEIVE, wxT("&Address Book"), wxBitmap( wxT("addressbook20"), wxBITMAP_TYPE_RESOURCE ), wxNullBitmap, wxITEM_NORMAL, wxEmptyString, wxEmptyString ); + m_toolBar->Realize(); + + m_statusBar = this->CreateStatusBar( 1, wxST_SIZEGRIP, wxID_ANY ); + m_statusBar->SetBackgroundColour( wxColour( 240, 240, 240 ) ); + + 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, wxT("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( 250,-1 ), wxTE_READONLY ); + m_textCtrlAddress->SetBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_MENU ) ); + + bSizer85->Add( m_textCtrlAddress, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 ); + + m_buttonCopy = new wxButton( this, wxID_BUTTONCOPY, wxT("&Copy to Clipboard"), wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT ); + bSizer85->Add( m_buttonCopy, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 5 ); + + m_button91 = new wxButton( this, wxID_BUTTONCHANGE, wxT("C&hange..."), wxDefaultPosition, wxDefaultSize, 0 ); + m_button91->Hide(); + + bSizer85->Add( m_button91, 0, wxRIGHT, 5 ); + + + bSizer85->Add( 0, 0, 0, wxEXPAND, 5 ); + + bSizer2->Add( bSizer85, 0, wxEXPAND|wxRIGHT|wxLEFT, 5 ); + + wxBoxSizer* bSizer3; + bSizer3 = new wxBoxSizer( wxHORIZONTAL ); + + m_panel14 = new wxPanel( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL ); + wxBoxSizer* bSizer66; + bSizer66 = new wxBoxSizer( wxHORIZONTAL ); + + m_staticText41 = new wxStaticText( m_panel14, wxID_ANY, wxT("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( m_panel14, 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( wxSystemSettings::GetColour( wxSYS_COLOUR_WINDOW ) ); + + bSizer66->Add( m_staticTextBalance, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 ); + + m_panel14->SetSizer( bSizer66 ); + m_panel14->Layout(); + bSizer66->Fit( m_panel14 ); + bSizer3->Add( m_panel14, 1, wxEXPAND|wxALIGN_BOTTOM|wxALL, 5 ); + + + bSizer3->Add( 0, 0, 0, wxEXPAND, 5 ); + + wxString m_choiceFilterChoices[] = { wxT(" All"), wxT(" Sent"), wxT(" Received"), wxT(" 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_panel7 = new wxPanel( m_notebook, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL ); + wxBoxSizer* bSizer157; + bSizer157 = new wxBoxSizer( wxVERTICAL ); + + m_listCtrl = new wxListCtrl( m_panel7, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_NO_SORT_HEADER|wxLC_REPORT|wxLC_SORT_DESCENDING|wxALWAYS_SHOW_SB ); + bSizer157->Add( m_listCtrl, 1, wxEXPAND|wxALL, 5 ); + + m_panel7->SetSizer( bSizer157 ); + m_panel7->Layout(); + bSizer157->Fit( m_panel7 ); + m_notebook->AddPage( m_panel7, wxT("All Transactions"), false ); + + bSizer2->Add( m_notebook, 1, wxEXPAND, 5 ); + + wxBoxSizer* bSizer_TabsForFutureUse; + bSizer_TabsForFutureUse = new wxBoxSizer( wxVERTICAL ); + + m_panel9 = new wxPanel( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL ); + m_panel9->Hide(); + + wxBoxSizer* bSizer159; + bSizer159 = new wxBoxSizer( wxVERTICAL ); + + m_listCtrlEscrows = new wxListCtrl( m_panel9, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_NO_SORT_HEADER|wxLC_REPORT ); + bSizer159->Add( m_listCtrlEscrows, 1, wxALL|wxEXPAND, 5 ); + + m_panel9->SetSizer( bSizer159 ); + m_panel9->Layout(); + bSizer159->Fit( m_panel9 ); + bSizer_TabsForFutureUse->Add( m_panel9, 1, wxEXPAND | wxALL, 5 ); + + m_panel8 = new wxPanel( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL ); + m_panel8->Hide(); + + wxBoxSizer* bSizer158; + bSizer158 = new wxBoxSizer( wxVERTICAL ); + + m_listCtrlOrdersSent = new wxListCtrl( m_panel8, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_NO_SORT_HEADER|wxLC_REPORT ); + bSizer158->Add( m_listCtrlOrdersSent, 1, wxALL|wxEXPAND, 5 ); + + m_panel8->SetSizer( bSizer158 ); + m_panel8->Layout(); + bSizer158->Fit( m_panel8 ); + bSizer_TabsForFutureUse->Add( m_panel8, 1, wxEXPAND | wxALL, 5 ); + + m_panel10 = new wxPanel( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL ); + m_panel10->Hide(); + + wxBoxSizer* bSizer160; + bSizer160 = new wxBoxSizer( wxVERTICAL ); + + m_listCtrlProductsSent = new wxListCtrl( m_panel10, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_NO_SORT_HEADER|wxLC_REPORT ); + bSizer160->Add( m_listCtrlProductsSent, 1, wxALL|wxEXPAND, 5 ); + + m_panel10->SetSizer( bSizer160 ); + m_panel10->Layout(); + bSizer160->Fit( m_panel10 ); + bSizer_TabsForFutureUse->Add( m_panel10, 1, wxEXPAND | wxALL, 5 ); + + m_panel11 = new wxPanel( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL ); + m_panel11->Hide(); + + wxBoxSizer* bSizer161; + bSizer161 = new wxBoxSizer( wxVERTICAL ); + + m_listCtrlOrdersReceived = new wxListCtrl( m_panel11, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_NO_SORT_HEADER|wxLC_REPORT ); + bSizer161->Add( m_listCtrlOrdersReceived, 1, wxALL|wxEXPAND, 5 ); + + m_panel11->SetSizer( bSizer161 ); + m_panel11->Layout(); + bSizer161->Fit( m_panel11 ); + bSizer_TabsForFutureUse->Add( m_panel11, 1, wxEXPAND | wxALL, 5 ); + + bSizer2->Add( bSizer_TabsForFutureUse, 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_menuOptionsGenerateBitcoins->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( CMainFrameBase::OnMenuOptionsGenerate ) ); + this->Connect( m_menuOptionsGenerateBitcoins->GetId(), wxEVT_UPDATE_UI, wxUpdateUIEventHandler( CMainFrameBase::OnUpdateMenuGenerate ) ); + this->Connect( m_menuChangeYourAddress->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_buttonCopy->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CMainFrameBase::OnButtonCopy ), NULL, this ); + m_button91->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CMainFrameBase::OnButtonChange ), NULL, this ); + m_listCtrl->Connect( wxEVT_COMMAND_LIST_COL_BEGIN_DRAG, wxListEventHandler( CMainFrameBase::OnListColBeginDrag ), NULL, this ); + m_listCtrl->Connect( wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler( CMainFrameBase::OnListItemActivatedAllTransactions ), NULL, this ); + m_listCtrl->Connect( wxEVT_PAINT, wxPaintEventHandler( CMainFrameBase::OnPaintListCtrl ), NULL, this ); + m_listCtrlOrdersSent->Connect( wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler( CMainFrameBase::OnListItemActivatedOrdersSent ), NULL, this ); + m_listCtrlProductsSent->Connect( wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler( CMainFrameBase::OnListItemActivatedProductsSent ), NULL, this ); + m_listCtrlOrdersReceived->Connect( wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler( CMainFrameBase::OnListItemActivatedOrdersReceived ), NULL, this ); } CMainFrameBase::~CMainFrameBase() { - // Disconnect Events - this->Disconnect(wxEVT_CLOSE_WINDOW, wxCloseEventHandler(CMainFrameBase::OnClose)); - 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::OnMenuOptionsGenerate)); - 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_buttonCopy->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CMainFrameBase::OnButtonCopy), NULL, this); - m_button91->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CMainFrameBase::OnButtonChange), NULL, this); - m_listCtrl->Disconnect(wxEVT_COMMAND_LIST_COL_BEGIN_DRAG, wxListEventHandler(CMainFrameBase::OnListColBeginDrag), NULL, this); - m_listCtrl->Disconnect(wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler(CMainFrameBase::OnListItemActivatedAllTransactions), NULL, this); - m_listCtrl->Disconnect(wxEVT_PAINT, wxPaintEventHandler(CMainFrameBase::OnPaintListCtrl), NULL, this); - m_listCtrlOrdersSent->Disconnect(wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler(CMainFrameBase::OnListItemActivatedOrdersSent), NULL, this); - m_listCtrlProductsSent->Disconnect(wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler(CMainFrameBase::OnListItemActivatedProductsSent), NULL, this); - m_listCtrlOrdersReceived->Disconnect(wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler(CMainFrameBase::OnListItemActivatedOrdersReceived), NULL, this); + // 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::OnMenuOptionsGenerate ) ); + this->Disconnect( wxID_ANY, wxEVT_UPDATE_UI, wxUpdateUIEventHandler( CMainFrameBase::OnUpdateMenuGenerate ) ); + 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_buttonCopy->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CMainFrameBase::OnButtonCopy ), NULL, this ); + m_button91->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CMainFrameBase::OnButtonChange ), NULL, this ); + m_listCtrl->Disconnect( wxEVT_COMMAND_LIST_COL_BEGIN_DRAG, wxListEventHandler( CMainFrameBase::OnListColBeginDrag ), NULL, this ); + m_listCtrl->Disconnect( wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler( CMainFrameBase::OnListItemActivatedAllTransactions ), NULL, this ); + m_listCtrl->Disconnect( wxEVT_PAINT, wxPaintEventHandler( CMainFrameBase::OnPaintListCtrl ), NULL, this ); + m_listCtrlOrdersSent->Disconnect( wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler( CMainFrameBase::OnListItemActivatedOrdersSent ), NULL, this ); + m_listCtrlProductsSent->Disconnect( wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler( CMainFrameBase::OnListItemActivatedProductsSent ), NULL, this ); + m_listCtrlOrdersReceived->Disconnect( wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler( CMainFrameBase::OnListItemActivatedOrdersReceived ), 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) +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(wxVERTICAL); - - m_buttonOK = new wxButton(this, wxID_OK, wxT("OK"), wxDefaultPosition, wxSize(85,25), 0); - bSizer65->Add(m_buttonOK, 0, wxALL, 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); + 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( wxVERTICAL ); + + m_buttonOK = new wxButton( this, wxID_OK, wxT("OK"), wxDefaultPosition, wxSize( 85,25 ), 0 ); + bSizer65->Add( m_buttonOK, 0, wxALL, 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); + // 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) +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* bSizer57; - bSizer57 = new wxBoxSizer(wxVERTICAL); - - - bSizer57->Add(0, 20, 0, wxEXPAND, 5); - - m_staticText32 = new wxStaticText(this, wxID_ANY, wxT("Optional transaction fee you give to the nodes that process your transactions."), wxDefaultPosition, wxDefaultSize, 0); - m_staticText32->Wrap(-1); - bSizer57->Add(m_staticText32, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5); - - wxBoxSizer* bSizer56; - bSizer56 = new wxBoxSizer(wxHORIZONTAL); - - m_staticText31 = new wxStaticText(this, wxID_ANY, wxT("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(this, wxID_TRANSACTIONFEE, wxEmptyString, wxDefaultPosition, wxSize(70,-1), 0); - bSizer56->Add(m_textCtrlTransactionFee, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5); - - bSizer57->Add(bSizer56, 0, wxEXPAND, 5); - - bSizer55->Add(bSizer57, 1, wxEXPAND|wxLEFT, 5); - - wxBoxSizer* bSizer58; - bSizer58 = new wxBoxSizer(wxHORIZONTAL); - - m_buttonOK = new wxButton(this, wxID_OK, wxT("OK"), wxDefaultPosition, wxSize(85,25), 0); - bSizer58->Add(m_buttonOK, 0, wxALL, 5); - - m_buttonCancel = new wxButton(this, wxID_CANCEL, wxT("Cancel"), wxDefaultPosition, wxSize(-1,-1), 0); - m_buttonCancel->SetMinSize(wxSize(85,25)); - - bSizer58->Add(m_buttonCancel, 0, wxALL, 5); - - bSizer55->Add(bSizer58, 0, wxALIGN_RIGHT, 5); - - this->SetSizer(bSizer55); - this->Layout(); - - // Connect Events - 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); + this->SetSizeHints( wxDefaultSize, wxDefaultSize ); + + wxBoxSizer* bSizer55; + bSizer55 = new wxBoxSizer( wxVERTICAL ); + + panelSizer = new wxBoxSizer( wxHORIZONTAL ); + + m_treeCtrl = new wxTreeCtrl( this, wxID_ANY, wxDefaultPosition, wxSize( 100,-1 ), wxTR_HAS_BUTTONS|wxTR_HIDE_ROOT|wxTR_LINES_AT_ROOT ); + panelSizer->Add( m_treeCtrl, 0, wxALL|wxEXPAND, 5 ); + + bSizer55->Add( panelSizer, 1, wxEXPAND, 5 ); + + m_staticline1 = new wxStaticLine( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL ); + bSizer55->Add( m_staticline1, 0, wxEXPAND | wxALL, 5 ); + + wxBoxSizer* bSizer58; + bSizer58 = new wxBoxSizer( wxHORIZONTAL ); + + m_buttonOK = new wxButton( this, wxID_OK, wxT("OK"), wxDefaultPosition, wxSize( 85,25 ), 0 ); + bSizer58->Add( m_buttonOK, 0, wxALL, 5 ); + + m_buttonCancel = new wxButton( this, wxID_CANCEL, wxT("Cancel"), wxDefaultPosition, wxSize( -1,-1 ), 0 ); + m_buttonCancel->SetMinSize( wxSize( 85,25 ) ); + + bSizer58->Add( m_buttonCancel, 0, wxALL, 5 ); + + m_buttonApply = new wxButton( this, wxID_ANY, wxT("Apply"), wxDefaultPosition, wxDefaultSize, 0 ); + m_buttonApply->Enable( false ); + m_buttonApply->Hide(); + + bSizer58->Add( m_buttonApply, 0, wxALL, 5 ); + + bSizer55->Add( bSizer58, 0, wxALIGN_RIGHT, 5 ); + + this->SetSizer( bSizer55 ); + this->Layout(); + + // Connect Events + m_treeCtrl->Connect( wxEVT_COMMAND_TREE_SEL_CHANGED, wxTreeEventHandler( COptionsDialogBase::MenuSelChanged ), 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 ); } COptionsDialogBase::~COptionsDialogBase() { - // Disconnect Events - 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); + // Disconnect Events + m_treeCtrl->Disconnect( wxEVT_COMMAND_TREE_SEL_CHANGED, wxTreeEventHandler( COptionsDialogBase::MenuSelChanged ), 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 ); } -CAboutDialogBase::CAboutDialogBase(wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style) : wxDialog(parent, id, title, pos, size, style) +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* bSizer60; - bSizer60 = new wxBoxSizer(wxVERTICAL); - - wxBoxSizer* bSizer62; - bSizer62 = new wxBoxSizer(wxHORIZONTAL); - - - bSizer62->Add(60, 0, 0, wxEXPAND, 5); - - wxBoxSizer* bSizer63; - bSizer63 = new wxBoxSizer(wxVERTICAL); - - - bSizer63->Add(0, 50, 0, wxEXPAND, 5); - - wxBoxSizer* bSizer64; - bSizer64 = new wxBoxSizer(wxHORIZONTAL); - - m_staticText40 = new wxStaticText(this, wxID_ANY, wxT("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, wxT("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); - - bSizer63->Add(bSizer64, 0, wxEXPAND, 5); - - - bSizer63->Add(0, 4, 0, wxEXPAND, 5); - - m_staticTextMain = new wxStaticText(this, wxID_ANY, wxT("Copyright © 2009 Satoshi Nakamoto.\n\nThis is experimental software. Do not rely on it for actual financial transactions.\n\nDistributed under the MIT/X11 software license, see the accompanying file license.txt or http://www.opensource.org/licenses/mit-license.php.\n\nThis 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)."), wxDefaultPosition, wxDefaultSize, 0); - m_staticTextMain->Wrap(400); - bSizer63->Add(m_staticTextMain, 0, wxALL, 5); - - - bSizer63->Add(0, 0, 1, wxEXPAND, 5); - - bSizer62->Add(bSizer63, 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, wxT("OK"), wxDefaultPosition, wxSize(85,25), 0); - bSizer61->Add(m_buttonOK, 0, wxALL, 5); - - bSizer60->Add(bSizer61, 0, wxALIGN_RIGHT|wxEXPAND, 5); - - this->SetSizer(bSizer60); - this->Layout(); - - // Connect Events - m_buttonOK->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CAboutDialogBase::OnButtonOK), NULL, this); + this->SetSizeHints( wxDefaultSize, wxDefaultSize ); + + wxBoxSizer* bSizer60; + bSizer60 = new wxBoxSizer( wxVERTICAL ); + + wxBoxSizer* bSizer62; + bSizer62 = new wxBoxSizer( wxHORIZONTAL ); + + + bSizer62->Add( 60, 0, 0, wxEXPAND, 5 ); + + wxBoxSizer* bSizer63; + bSizer63 = new wxBoxSizer( wxVERTICAL ); + + + bSizer63->Add( 0, 50, 0, wxEXPAND, 5 ); + + wxBoxSizer* bSizer64; + bSizer64 = new wxBoxSizer( wxHORIZONTAL ); + + m_staticText40 = new wxStaticText( this, wxID_ANY, wxT("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, wxT("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 ); + + bSizer63->Add( bSizer64, 0, wxEXPAND, 5 ); + + + bSizer63->Add( 0, 4, 0, wxEXPAND, 5 ); + + m_staticTextMain = new wxStaticText( this, wxID_ANY, wxT("Copyright © 2009 Satoshi Nakamoto.\n\nThis is experimental software. Do not rely on it for actual financial transactions.\n\nDistributed under the MIT/X11 software license, see the accompanying file license.txt or http://www.opensource.org/licenses/mit-license.php.\n\nThis 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)."), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticTextMain->Wrap( 400 ); + bSizer63->Add( m_staticTextMain, 0, wxALL, 5 ); + + + bSizer63->Add( 0, 0, 1, wxEXPAND, 5 ); + + bSizer62->Add( bSizer63, 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, wxT("OK"), wxDefaultPosition, wxSize( 85,25 ), 0 ); + bSizer61->Add( m_buttonOK, 0, wxALL, 5 ); + + bSizer60->Add( bSizer61, 0, wxALIGN_RIGHT|wxEXPAND, 5 ); + + this->SetSizer( bSizer60 ); + 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); + // 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) +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(3, 2, 0, 0); - fgSizer1->AddGrowableCol(1); - fgSizer1->SetFlexibleDirection(wxBOTH); - fgSizer1->SetNonFlexibleGrowMode(wxFLEX_GROWMODE_SPECIFIED); - - - fgSizer1->Add(0, 0, 0, wxEXPAND, 5); - - m_staticText14 = new wxStaticText(this, wxID_ANY, wxT("Enter the recipient's IP address (e.g. 123.45.6.7) for online transfer with comments and confirmation, \nor Bitcoin address (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJED9L) if recipient is not online."), wxDefaultPosition, wxDefaultSize, 0); - m_staticText14->Wrap(-1); - fgSizer1->Add(m_staticText14, 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, wxICON(check), wxDefaultPosition, wxSize(16,16), 0); - bSizer47->Add(m_bitmapCheckMark, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5); - - m_staticText36 = new wxStaticText(this, wxID_ANY, wxT("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); - - m_buttonPaste = new wxButton(this, wxID_BUTTONPASTE, wxT("&Paste"), wxDefaultPosition, wxSize(-1,-1), wxBU_EXACTFIT); - bSizer19->Add(m_buttonPaste, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 5); - - m_buttonAddress = new wxButton(this, wxID_BUTTONADDRESSBOOK, wxT(" Address &Book..."), wxDefaultPosition, wxDefaultSize, 0); - bSizer19->Add(m_buttonAddress, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 5); - - fgSizer1->Add(bSizer19, 1, wxEXPAND|wxRIGHT, 5); - - m_staticText19 = new wxStaticText(this, wxID_ANY, wxT("&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, wxT("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[] = { wxT(" 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); - - wxBoxSizer* bSizer681; - bSizer681 = new wxBoxSizer(wxVERTICAL); - - m_staticTextFrom = new wxStaticText(this, wxID_ANY, wxT("&From:"), wxDefaultPosition, wxDefaultSize, 0); - m_staticTextFrom->Wrap(-1); - bSizer681->Add(m_staticTextFrom, 0, wxBOTTOM|wxLEFT, 5); - - m_textCtrlFrom = new wxTextCtrl(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(-1,-1), 0); - bSizer681->Add(m_textCtrlFrom, 0, wxLEFT|wxEXPAND, 5); - - bSizer672->Add(bSizer681, 1, wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT, 5); - - bSizer21->Add(bSizer672, 0, wxEXPAND, 5); - - wxBoxSizer* bSizer67; - bSizer67 = new wxBoxSizer(wxHORIZONTAL); - - wxBoxSizer* bSizer68; - bSizer68 = new wxBoxSizer(wxVERTICAL); - - m_staticTextMessage = new wxStaticText(this, wxID_ANY, wxT("&Message:"), wxDefaultPosition, wxDefaultSize, 0); - m_staticTextMessage->Wrap(-1); - bSizer68->Add(m_staticTextMessage, 0, wxTOP|wxBOTTOM|wxLEFT, 5); - - m_textCtrlMessage = new wxTextCtrl(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE); - bSizer68->Add(m_textCtrlMessage, 1, wxEXPAND|wxLEFT, 5); - - bSizer67->Add(bSizer68, 1, wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT, 5); - - bSizer21->Add(bSizer67, 1, wxEXPAND, 5); - - wxBoxSizer* bSizer23; - bSizer23 = new wxBoxSizer(wxHORIZONTAL); - - - bSizer23->Add(0, 0, 1, wxEXPAND, 5); - - m_buttonSend = new wxButton(this, wxID_BUTTONSEND, wxT("&Send"), wxDefaultPosition, wxSize(-1,-1), 0); - m_buttonSend->SetFont(wxFont(wxNORMAL_FONT->GetPointSize(), 70, 90, 90, false, wxEmptyString)); - m_buttonSend->SetMinSize(wxSize(85,25)); - - bSizer23->Add(m_buttonSend, 0, wxALL, 5); - - m_buttonCancel = new wxButton(this, wxID_CANCEL, wxT("Cancel"), wxDefaultPosition, wxSize(-1,-1), 0); - m_buttonCancel->SetMinSize(wxSize(85,25)); - - bSizer23->Add(m_buttonCancel, 0, wxALL, 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_textCtrlFrom->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CSendDialogBase::OnKeyDown), NULL, this); - m_textCtrlMessage->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CSendDialogBase::OnKeyDown), 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); + this->SetSizeHints( wxDefaultSize, wxDefaultSize ); + + wxBoxSizer* bSizer21; + bSizer21 = new wxBoxSizer( wxVERTICAL ); + + + bSizer21->Add( 0, 5, 0, wxEXPAND, 5 ); + + wxFlexGridSizer* fgSizer1; + fgSizer1 = new wxFlexGridSizer( 3, 2, 0, 0 ); + fgSizer1->AddGrowableCol( 1 ); + fgSizer1->SetFlexibleDirection( wxBOTH ); + fgSizer1->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED ); + + + fgSizer1->Add( 0, 0, 0, wxEXPAND, 5 ); + + m_staticText14 = new wxStaticText( this, wxID_ANY, wxT("Enter the recipient's IP address (e.g. 123.45.6.7) for online transfer with comments and confirmation, \nor Bitcoin address (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJED9L) if recipient is not online."), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticText14->Wrap( -1 ); + fgSizer1->Add( m_staticText14, 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, wxICON( check ), wxDefaultPosition, wxSize( 16,16 ), 0 ); + bSizer47->Add( m_bitmapCheckMark, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); + + m_staticText36 = new wxStaticText( this, wxID_ANY, wxT("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 ); + + m_buttonPaste = new wxButton( this, wxID_BUTTONPASTE, wxT("&Paste"), wxDefaultPosition, wxSize( -1,-1 ), wxBU_EXACTFIT ); + bSizer19->Add( m_buttonPaste, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 5 ); + + m_buttonAddress = new wxButton( this, wxID_BUTTONADDRESSBOOK, wxT(" Address &Book..."), wxDefaultPosition, wxDefaultSize, 0 ); + bSizer19->Add( m_buttonAddress, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 5 ); + + fgSizer1->Add( bSizer19, 1, wxEXPAND|wxRIGHT, 5 ); + + m_staticText19 = new wxStaticText( this, wxID_ANY, wxT("&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, wxT("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[] = { wxT(" 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 ); + + wxBoxSizer* bSizer681; + bSizer681 = new wxBoxSizer( wxVERTICAL ); + + m_staticTextFrom = new wxStaticText( this, wxID_ANY, wxT("&From:"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticTextFrom->Wrap( -1 ); + bSizer681->Add( m_staticTextFrom, 0, wxBOTTOM|wxLEFT, 5 ); + + m_textCtrlFrom = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize( -1,-1 ), 0 ); + bSizer681->Add( m_textCtrlFrom, 0, wxLEFT|wxEXPAND, 5 ); + + bSizer672->Add( bSizer681, 1, wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT, 5 ); + + bSizer21->Add( bSizer672, 0, wxEXPAND, 5 ); + + wxBoxSizer* bSizer67; + bSizer67 = new wxBoxSizer( wxHORIZONTAL ); + + wxBoxSizer* bSizer68; + bSizer68 = new wxBoxSizer( wxVERTICAL ); + + m_staticTextMessage = new wxStaticText( this, wxID_ANY, wxT("&Message:"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticTextMessage->Wrap( -1 ); + bSizer68->Add( m_staticTextMessage, 0, wxTOP|wxBOTTOM|wxLEFT, 5 ); + + m_textCtrlMessage = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE ); + bSizer68->Add( m_textCtrlMessage, 1, wxEXPAND|wxLEFT, 5 ); + + bSizer67->Add( bSizer68, 1, wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT, 5 ); + + bSizer21->Add( bSizer67, 1, wxEXPAND, 5 ); + + wxBoxSizer* bSizer23; + bSizer23 = new wxBoxSizer( wxHORIZONTAL ); + + + bSizer23->Add( 0, 0, 1, wxEXPAND, 5 ); + + m_buttonSend = new wxButton( this, wxID_BUTTONSEND, wxT("&Send"), wxDefaultPosition, wxSize( -1,-1 ), 0 ); + m_buttonSend->SetFont( wxFont( wxNORMAL_FONT->GetPointSize(), 70, 90, 90, false, wxEmptyString ) ); + m_buttonSend->SetMinSize( wxSize( 85,25 ) ); + + bSizer23->Add( m_buttonSend, 0, wxALL, 5 ); + + m_buttonCancel = new wxButton( this, wxID_CANCEL, wxT("Cancel"), wxDefaultPosition, wxSize( -1,-1 ), 0 ); + m_buttonCancel->SetMinSize( wxSize( 85,25 ) ); + + bSizer23->Add( m_buttonCancel, 0, wxALL, 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_textCtrlFrom->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CSendDialogBase::OnKeyDown ), NULL, this ); + m_textCtrlMessage->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CSendDialogBase::OnKeyDown ), 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_textCtrlFrom->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CSendDialogBase::OnKeyDown), NULL, this); - m_textCtrlMessage->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CSendDialogBase::OnKeyDown), 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); + // 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_textCtrlFrom->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CSendDialogBase::OnKeyDown ), NULL, this ); + m_textCtrlMessage->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CSendDialogBase::OnKeyDown ), 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) +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, wxT("\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, wxT("OK"), wxDefaultPosition, wxDefaultSize, 0); - m_buttonOK->Enable(false); - m_buttonOK->SetMinSize(wxSize(85,25)); - - bSizer69->Add(m_buttonOK, 0, wxALL, 5); - - m_buttonCancel = new wxButton(this, wxID_CANCEL, wxT("Cancel"), wxDefaultPosition, wxSize(-1,-1), 0); - m_buttonCancel->SetMinSize(wxSize(85,25)); - - bSizer69->Add(m_buttonCancel, 0, wxALL, 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); + 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, wxT("\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, wxT("OK"), wxDefaultPosition, wxDefaultSize, 0 ); + m_buttonOK->Enable( false ); + m_buttonOK->SetMinSize( wxSize( 85,25 ) ); + + bSizer69->Add( m_buttonOK, 0, wxALL, 5 ); + + m_buttonCancel = new wxButton( this, wxID_CANCEL, wxT("Cancel"), wxDefaultPosition, wxSize( -1,-1 ), 0 ); + m_buttonCancel->SetMinSize( wxSize( 85,25 ) ); + + bSizer69->Add( m_buttonCancel, 0, wxALL, 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); + // 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) +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, wxT("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, wxT("&Edit..."), wxDefaultPosition, wxDefaultSize, 0); - m_buttonRename->SetMinSize(wxSize(85,25)); - - bSizer69->Add(m_buttonRename, 0, wxALL, 5); - - m_buttonNew = new wxButton(this, wxID_BUTTONNEW, wxT("&New Address..."), wxDefaultPosition, wxSize(-1,-1), 0); - m_buttonNew->SetMinSize(wxSize(110,25)); - - bSizer69->Add(m_buttonNew, 0, wxALL, 5); - - m_buttonCopy = new wxButton(this, wxID_BUTTONCOPY, wxT("&Copy to Clipboard"), wxDefaultPosition, wxSize(-1,-1), 0); - m_buttonCopy->SetMinSize(wxSize(120,25)); - - bSizer69->Add(m_buttonCopy, 0, wxALL, 5); - - m_buttonOK = new wxButton(this, wxID_OK, wxT("OK"), wxDefaultPosition, wxDefaultSize, 0); - m_buttonOK->SetMinSize(wxSize(85,25)); - - bSizer69->Add(m_buttonOK, 0, wxALL, 5); - - m_buttonCancel = new wxButton(this, wxID_CANCEL, wxT("Cancel"), wxDefaultPosition, wxSize(-1,-1), 0); - m_buttonCancel->Hide(); - m_buttonCancel->SetMinSize(wxSize(85,25)); - - bSizer69->Add(m_buttonCancel, 0, wxALL, 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); + this->SetSizeHints( wxDefaultSize, wxDefaultSize ); + + wxBoxSizer* bSizer68; + bSizer68 = new wxBoxSizer( wxVERTICAL ); + + + bSizer68->Add( 0, 5, 0, wxEXPAND, 5 ); + + m_staticText45 = new wxStaticText( this, wxID_ANY, wxT("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, wxT("&Edit..."), wxDefaultPosition, wxDefaultSize, 0 ); + m_buttonRename->SetMinSize( wxSize( 85,25 ) ); + + bSizer69->Add( m_buttonRename, 0, wxALL, 5 ); + + m_buttonNew = new wxButton( this, wxID_BUTTONNEW, wxT("&New Address..."), wxDefaultPosition, wxSize( -1,-1 ), 0 ); + m_buttonNew->SetMinSize( wxSize( 110,25 ) ); + + bSizer69->Add( m_buttonNew, 0, wxALL, 5 ); + + m_buttonCopy = new wxButton( this, wxID_BUTTONCOPY, wxT("&Copy to Clipboard"), wxDefaultPosition, wxSize( -1,-1 ), 0 ); + m_buttonCopy->SetMinSize( wxSize( 120,25 ) ); + + bSizer69->Add( m_buttonCopy, 0, wxALL, 5 ); + + m_buttonOK = new wxButton( this, wxID_OK, wxT("OK"), wxDefaultPosition, wxDefaultSize, 0 ); + m_buttonOK->SetMinSize( wxSize( 85,25 ) ); + + bSizer69->Add( m_buttonOK, 0, wxALL, 5 ); + + m_buttonCancel = new wxButton( this, wxID_CANCEL, wxT("Cancel"), wxDefaultPosition, wxSize( -1,-1 ), 0 ); + m_buttonCancel->Hide(); + m_buttonCancel->SetMinSize( wxSize( 85,25 ) ); + + bSizer69->Add( m_buttonCancel, 0, wxALL, 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); + // 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) +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* bSizer68; - bSizer68 = new wxBoxSizer(wxVERTICAL); - - - bSizer68->Add(0, 5, 0, wxEXPAND, 5); - - m_staticText55 = new wxStaticText(this, wxID_ANY, wxT("Bitcoin Address"), wxDefaultPosition, wxDefaultSize, 0); - m_staticText55->Wrap(-1); - m_staticText55->Hide(); - - bSizer68->Add(m_staticText55, 0, wxTOP|wxRIGHT|wxLEFT, 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_buttonEdit = new wxButton(this, wxID_BUTTONEDIT, wxT("&Edit..."), wxDefaultPosition, wxDefaultSize, 0); - m_buttonEdit->SetMinSize(wxSize(85,25)); - - bSizer69->Add(m_buttonEdit, 0, wxALL, 5); - - m_buttonNew = new wxButton(this, wxID_BUTTONNEW, wxT("&New Address..."), wxDefaultPosition, wxDefaultSize, 0); - m_buttonNew->SetMinSize(wxSize(110,25)); - - bSizer69->Add(m_buttonNew, 0, wxALL, 5); - - m_buttonDelete = new wxButton(this, wxID_BUTTONDELETE, wxT("&Delete"), wxDefaultPosition, wxDefaultSize, 0); - m_buttonDelete->SetMinSize(wxSize(85,25)); - - bSizer69->Add(m_buttonDelete, 0, wxALL, 5); - - m_buttonOK = new wxButton(this, wxID_OK, wxT("OK"), wxDefaultPosition, wxSize(-1,-1), 0); - m_buttonOK->SetMinSize(wxSize(85,25)); - - bSizer69->Add(m_buttonOK, 0, wxALL, 5); - - m_buttonCancel = new wxButton(this, wxID_CANCEL, wxT("Cancel"), wxDefaultPosition, wxSize(-1,-1), 0); - m_buttonCancel->SetMinSize(wxSize(85,25)); - - bSizer69->Add(m_buttonCancel, 0, wxALL, 5); - - bSizer68->Add(bSizer69, 0, wxEXPAND, 5); - - this->SetSizer(bSizer68); - this->Layout(); - - // Connect Events - this->Connect(wxEVT_CLOSE_WINDOW, wxCloseEventHandler(CAddressBookDialogBase::OnClose)); - m_listCtrl->Connect(wxEVT_COMMAND_LIST_END_LABEL_EDIT, wxListEventHandler(CAddressBookDialogBase::OnListEndLabelEdit), NULL, this); - m_listCtrl->Connect(wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler(CAddressBookDialogBase::OnListItemActivated), NULL, this); - m_listCtrl->Connect(wxEVT_COMMAND_LIST_ITEM_SELECTED, wxListEventHandler(CAddressBookDialogBase::OnListItemSelected), 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_buttonDelete->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CAddressBookDialogBase::OnButtonDelete), 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); + this->SetSizeHints( wxDefaultSize, wxDefaultSize ); + + wxBoxSizer* bSizer68; + bSizer68 = new wxBoxSizer( wxVERTICAL ); + + + bSizer68->Add( 0, 5, 0, wxEXPAND, 5 ); + + m_staticText55 = new wxStaticText( this, wxID_ANY, wxT("Bitcoin Address"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticText55->Wrap( -1 ); + m_staticText55->Hide(); + + bSizer68->Add( m_staticText55, 0, wxTOP|wxRIGHT|wxLEFT, 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_buttonEdit = new wxButton( this, wxID_BUTTONEDIT, wxT("&Edit..."), wxDefaultPosition, wxDefaultSize, 0 ); + m_buttonEdit->SetMinSize( wxSize( 85,25 ) ); + + bSizer69->Add( m_buttonEdit, 0, wxALL, 5 ); + + m_buttonNew = new wxButton( this, wxID_BUTTONNEW, wxT("&New Address..."), wxDefaultPosition, wxDefaultSize, 0 ); + m_buttonNew->SetMinSize( wxSize( 110,25 ) ); + + bSizer69->Add( m_buttonNew, 0, wxALL, 5 ); + + m_buttonDelete = new wxButton( this, wxID_BUTTONDELETE, wxT("&Delete"), wxDefaultPosition, wxDefaultSize, 0 ); + m_buttonDelete->SetMinSize( wxSize( 85,25 ) ); + + bSizer69->Add( m_buttonDelete, 0, wxALL, 5 ); + + m_buttonOK = new wxButton( this, wxID_OK, wxT("OK"), wxDefaultPosition, wxSize( -1,-1 ), 0 ); + m_buttonOK->SetMinSize( wxSize( 85,25 ) ); + + bSizer69->Add( m_buttonOK, 0, wxALL, 5 ); + + m_buttonCancel = new wxButton( this, wxID_CANCEL, wxT("Cancel"), wxDefaultPosition, wxSize( -1,-1 ), 0 ); + m_buttonCancel->SetMinSize( wxSize( 85,25 ) ); + + bSizer69->Add( m_buttonCancel, 0, wxALL, 5 ); + + bSizer68->Add( bSizer69, 0, wxEXPAND, 5 ); + + this->SetSizer( bSizer68 ); + this->Layout(); + + // Connect Events + this->Connect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( CAddressBookDialogBase::OnClose ) ); + m_listCtrl->Connect( wxEVT_COMMAND_LIST_END_LABEL_EDIT, wxListEventHandler( CAddressBookDialogBase::OnListEndLabelEdit ), NULL, this ); + m_listCtrl->Connect( wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler( CAddressBookDialogBase::OnListItemActivated ), NULL, this ); + m_listCtrl->Connect( wxEVT_COMMAND_LIST_ITEM_SELECTED, wxListEventHandler( CAddressBookDialogBase::OnListItemSelected ), 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_buttonDelete->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CAddressBookDialogBase::OnButtonDelete ), 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_listCtrl->Disconnect(wxEVT_COMMAND_LIST_END_LABEL_EDIT, wxListEventHandler(CAddressBookDialogBase::OnListEndLabelEdit), NULL, this); - m_listCtrl->Disconnect(wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler(CAddressBookDialogBase::OnListItemActivated), NULL, this); - m_listCtrl->Disconnect(wxEVT_COMMAND_LIST_ITEM_SELECTED, wxListEventHandler(CAddressBookDialogBase::OnListItemSelected), 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_buttonDelete->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CAddressBookDialogBase::OnButtonDelete), 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); + // Disconnect Events + this->Disconnect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( CAddressBookDialogBase::OnClose ) ); + m_listCtrl->Disconnect( wxEVT_COMMAND_LIST_END_LABEL_EDIT, wxListEventHandler( CAddressBookDialogBase::OnListEndLabelEdit ), NULL, this ); + m_listCtrl->Disconnect( wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler( CAddressBookDialogBase::OnListItemActivated ), NULL, this ); + m_listCtrl->Disconnect( wxEVT_COMMAND_LIST_ITEM_SELECTED, wxListEventHandler( CAddressBookDialogBase::OnListItemSelected ), 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_buttonDelete->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CAddressBookDialogBase::OnButtonDelete ), 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 ); } -CProductsDialogBase::CProductsDialogBase(wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style) : wxDialog(parent, id, title, pos, size, style) +CProductsDialogBase::CProductsDialogBase( 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* bSizer22; - bSizer22 = new wxBoxSizer(wxVERTICAL); - - wxBoxSizer* bSizer23; - bSizer23 = new wxBoxSizer(wxHORIZONTAL); - - m_comboBoxCategory = new wxComboBox(this, wxID_ANY, wxT("(Any Category)"), wxDefaultPosition, wxSize(150,-1), 0, NULL, 0); - m_comboBoxCategory->Append(wxT("(Any Category)")); - bSizer23->Add(m_comboBoxCategory, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5); - - m_textCtrlSearch = new wxTextCtrl(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0); - bSizer23->Add(m_textCtrlSearch, 1, wxALL|wxALIGN_CENTER_VERTICAL, 5); - - m_buttonSearch = new wxButton(this, wxID_ANY, wxT("&Search"), wxDefaultPosition, wxDefaultSize, 0); - bSizer23->Add(m_buttonSearch, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5); - - bSizer22->Add(bSizer23, 0, wxEXPAND|wxTOP|wxBOTTOM|wxRIGHT, 5); - - m_listCtrl = new wxListCtrl(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_NO_SORT_HEADER|wxLC_REPORT); - bSizer22->Add(m_listCtrl, 1, wxALL|wxEXPAND, 5); - - this->SetSizer(bSizer22); - this->Layout(); - - // Connect Events - m_comboBoxCategory->Connect(wxEVT_COMMAND_COMBOBOX_SELECTED, wxCommandEventHandler(CProductsDialogBase::OnCombobox), NULL, this); - m_textCtrlSearch->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CProductsDialogBase::OnKeyDown), NULL, this); - m_buttonSearch->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CProductsDialogBase::OnButtonSearch), NULL, this); - m_listCtrl->Connect(wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler(CProductsDialogBase::OnListItemActivated), NULL, this); + this->SetSizeHints( wxDefaultSize, wxDefaultSize ); + + wxBoxSizer* bSizer22; + bSizer22 = new wxBoxSizer( wxVERTICAL ); + + wxBoxSizer* bSizer23; + bSizer23 = new wxBoxSizer( wxHORIZONTAL ); + + m_comboBoxCategory = new wxComboBox( this, wxID_ANY, wxT("(Any Category)"), wxDefaultPosition, wxSize( 150,-1 ), 0, NULL, 0 ); + m_comboBoxCategory->Append( wxT("(Any Category)") ); + bSizer23->Add( m_comboBoxCategory, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); + + m_textCtrlSearch = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); + bSizer23->Add( m_textCtrlSearch, 1, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); + + m_buttonSearch = new wxButton( this, wxID_ANY, wxT("&Search"), wxDefaultPosition, wxDefaultSize, 0 ); + bSizer23->Add( m_buttonSearch, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); + + bSizer22->Add( bSizer23, 0, wxEXPAND|wxTOP|wxBOTTOM|wxRIGHT, 5 ); + + m_listCtrl = new wxListCtrl( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_NO_SORT_HEADER|wxLC_REPORT ); + bSizer22->Add( m_listCtrl, 1, wxALL|wxEXPAND, 5 ); + + this->SetSizer( bSizer22 ); + this->Layout(); + + // Connect Events + m_comboBoxCategory->Connect( wxEVT_COMMAND_COMBOBOX_SELECTED, wxCommandEventHandler( CProductsDialogBase::OnCombobox ), NULL, this ); + m_textCtrlSearch->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CProductsDialogBase::OnKeyDown ), NULL, this ); + m_buttonSearch->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CProductsDialogBase::OnButtonSearch ), NULL, this ); + m_listCtrl->Connect( wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler( CProductsDialogBase::OnListItemActivated ), NULL, this ); } CProductsDialogBase::~CProductsDialogBase() { - // Disconnect Events - m_comboBoxCategory->Disconnect(wxEVT_COMMAND_COMBOBOX_SELECTED, wxCommandEventHandler(CProductsDialogBase::OnCombobox), NULL, this); - m_textCtrlSearch->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CProductsDialogBase::OnKeyDown), NULL, this); - m_buttonSearch->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CProductsDialogBase::OnButtonSearch), NULL, this); - m_listCtrl->Disconnect(wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler(CProductsDialogBase::OnListItemActivated), NULL, this); + // Disconnect Events + m_comboBoxCategory->Disconnect( wxEVT_COMMAND_COMBOBOX_SELECTED, wxCommandEventHandler( CProductsDialogBase::OnCombobox ), NULL, this ); + m_textCtrlSearch->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CProductsDialogBase::OnKeyDown ), NULL, this ); + m_buttonSearch->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CProductsDialogBase::OnButtonSearch ), NULL, this ); + m_listCtrl->Disconnect( wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler( CProductsDialogBase::OnListItemActivated ), NULL, this ); } -CEditProductDialogBase::CEditProductDialogBase(wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style) : wxFrame(parent, id, title, pos, size, style) +CEditProductDialogBase::CEditProductDialogBase( 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_MENU)); - - wxBoxSizer* bSizer20; - bSizer20 = new wxBoxSizer(wxVERTICAL); - - m_scrolledWindow = new wxScrolledWindow(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxHSCROLL|wxTAB_TRAVERSAL|wxVSCROLL); - m_scrolledWindow->SetScrollRate(5, 5); - m_scrolledWindow->SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW)); - - wxBoxSizer* bSizer21; - bSizer21 = new wxBoxSizer(wxVERTICAL); - - wxFlexGridSizer* fgSizer8; - fgSizer8 = new wxFlexGridSizer(0, 2, 0, 0); - fgSizer8->AddGrowableCol(1); - fgSizer8->SetFlexibleDirection(wxBOTH); - fgSizer8->SetNonFlexibleGrowMode(wxFLEX_GROWMODE_SPECIFIED); - - m_staticText106 = new wxStaticText(m_scrolledWindow, wxID_ANY, wxT("Category"), wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT); - m_staticText106->Wrap(-1); - fgSizer8->Add(m_staticText106, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxTOP|wxBOTTOM|wxLEFT, 5); - - m_comboBoxCategory = new wxComboBox(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0, NULL, 0); - m_comboBoxCategory->SetMinSize(wxSize(180,-1)); - - fgSizer8->Add(m_comboBoxCategory, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5); - - m_staticText108 = new wxStaticText(m_scrolledWindow, wxID_ANY, wxT("Title"), wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT); - m_staticText108->Wrap(-1); - fgSizer8->Add(m_staticText108, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxTOP|wxBOTTOM|wxLEFT, 5); - - m_textCtrlTitle = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0); - fgSizer8->Add(m_textCtrlTitle, 1, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5); - - m_staticText107 = new wxStaticText(m_scrolledWindow, wxID_ANY, wxT("Price"), wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT); - m_staticText107->Wrap(-1); - fgSizer8->Add(m_staticText107, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxTOP|wxBOTTOM|wxLEFT, 5); - - m_textCtrlPrice = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0); - m_textCtrlPrice->SetMinSize(wxSize(105,-1)); - - fgSizer8->Add(m_textCtrlPrice, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5); - - bSizer21->Add(fgSizer8, 0, wxEXPAND|wxTOP|wxRIGHT|wxLEFT, 5); - - m_staticText22 = new wxStaticText(m_scrolledWindow, wxID_ANY, wxT("Page 1: Description"), wxDefaultPosition, wxDefaultSize, 0); - m_staticText22->Wrap(-1); - bSizer21->Add(m_staticText22, 0, wxTOP|wxRIGHT|wxLEFT, 5); - - m_textCtrlDescription = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE); - m_textCtrlDescription->SetMinSize(wxSize(-1,170)); - - bSizer21->Add(m_textCtrlDescription, 0, wxALL|wxEXPAND, 5); - - m_staticText23 = new wxStaticText(m_scrolledWindow, wxID_ANY, wxT("Page 2: Order Form"), wxDefaultPosition, wxDefaultSize, 0); - m_staticText23->Wrap(-1); - bSizer21->Add(m_staticText23, 0, wxTOP|wxRIGHT|wxLEFT, 5); - - m_textCtrlInstructions = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE); - m_textCtrlInstructions->SetMinSize(wxSize(-1,120)); - - bSizer21->Add(m_textCtrlInstructions, 0, wxEXPAND|wxALL, 5); - - fgSizer5 = new wxFlexGridSizer(0, 3, 0, 0); - fgSizer5->AddGrowableCol(1); - fgSizer5->SetFlexibleDirection(wxBOTH); - fgSizer5->SetNonFlexibleGrowMode(wxFLEX_GROWMODE_SPECIFIED); - - m_staticText24 = new wxStaticText(m_scrolledWindow, wxID_ANY, wxT("Label"), wxDefaultPosition, wxDefaultSize, 0); - m_staticText24->Wrap(-1); - fgSizer5->Add(m_staticText24, 0, wxALIGN_CENTER_VERTICAL|wxTOP|wxRIGHT|wxLEFT, 5); - - m_staticText25 = new wxStaticText(m_scrolledWindow, wxID_ANY, wxT("Comma separated list of choices, or leave blank for text field"), wxDefaultPosition, wxDefaultSize, 0); - m_staticText25->Wrap(-1); - fgSizer5->Add(m_staticText25, 0, wxALIGN_CENTER_VERTICAL|wxTOP|wxRIGHT|wxLEFT, 5); - - - fgSizer5->Add(0, 0, 1, wxEXPAND, 5); - - m_textCtrlLabel0 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0); - m_textCtrlLabel0->SetMinSize(wxSize(150,-1)); - - fgSizer5->Add(m_textCtrlLabel0, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5); - - m_textCtrlField0 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(-1,-1), 0); - fgSizer5->Add(m_textCtrlField0, 0, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5); - - m_buttonDel0 = new wxButton(m_scrolledWindow, wxID_DEL0, wxT("Delete"), wxDefaultPosition, wxSize(60,20), 0); - fgSizer5->Add(m_buttonDel0, 0, wxRIGHT|wxLEFT|wxALIGN_CENTER_VERTICAL, 5); - - m_textCtrlLabel1 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0); - m_textCtrlLabel1->SetMinSize(wxSize(150,-1)); - - fgSizer5->Add(m_textCtrlLabel1, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5); - - m_textCtrlField1 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(-1,-1), 0); - fgSizer5->Add(m_textCtrlField1, 0, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5); - - m_buttonDel1 = new wxButton(m_scrolledWindow, wxID_DEL1, wxT("Delete"), wxDefaultPosition, wxSize(60,20), 0); - fgSizer5->Add(m_buttonDel1, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5); - - m_textCtrlLabel2 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0); - m_textCtrlLabel2->SetMinSize(wxSize(150,-1)); - - fgSizer5->Add(m_textCtrlLabel2, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5); - - m_textCtrlField2 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(-1,-1), 0); - fgSizer5->Add(m_textCtrlField2, 0, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5); - - m_buttonDel2 = new wxButton(m_scrolledWindow, wxID_DEL2, wxT("Delete"), wxDefaultPosition, wxSize(60,20), 0); - fgSizer5->Add(m_buttonDel2, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5); - - m_textCtrlLabel3 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0); - m_textCtrlLabel3->SetMinSize(wxSize(150,-1)); - - fgSizer5->Add(m_textCtrlLabel3, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5); - - m_textCtrlField3 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(-1,-1), 0); - fgSizer5->Add(m_textCtrlField3, 0, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5); - - m_buttonDel3 = new wxButton(m_scrolledWindow, wxID_DEL3, wxT("Delete"), wxDefaultPosition, wxSize(60,20), 0); - fgSizer5->Add(m_buttonDel3, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5); - - m_textCtrlLabel4 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0); - m_textCtrlLabel4->SetMinSize(wxSize(150,-1)); - - fgSizer5->Add(m_textCtrlLabel4, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5); - - m_textCtrlField4 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(-1,-1), 0); - fgSizer5->Add(m_textCtrlField4, 0, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5); - - m_buttonDel4 = new wxButton(m_scrolledWindow, wxID_DEL4, wxT("Delete"), wxDefaultPosition, wxSize(60,20), 0); - fgSizer5->Add(m_buttonDel4, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5); - - m_textCtrlLabel5 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0); - m_textCtrlLabel5->SetMinSize(wxSize(150,-1)); - - fgSizer5->Add(m_textCtrlLabel5, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5); - - m_textCtrlField5 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(-1,-1), 0); - fgSizer5->Add(m_textCtrlField5, 0, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5); - - m_buttonDel5 = new wxButton(m_scrolledWindow, wxID_DEL5, wxT("Delete"), wxDefaultPosition, wxSize(60,20), 0); - fgSizer5->Add(m_buttonDel5, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5); - - m_textCtrlLabel6 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0); - m_textCtrlLabel6->SetMinSize(wxSize(150,-1)); - - fgSizer5->Add(m_textCtrlLabel6, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5); - - m_textCtrlField6 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(-1,-1), 0); - fgSizer5->Add(m_textCtrlField6, 0, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5); - - m_buttonDel6 = new wxButton(m_scrolledWindow, wxID_DEL6, wxT("Delete"), wxDefaultPosition, wxSize(60,20), 0); - fgSizer5->Add(m_buttonDel6, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5); - - m_textCtrlLabel7 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0); - m_textCtrlLabel7->SetMinSize(wxSize(150,-1)); - - fgSizer5->Add(m_textCtrlLabel7, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5); - - m_textCtrlField7 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(-1,-1), 0); - fgSizer5->Add(m_textCtrlField7, 0, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5); - - m_buttonDel7 = new wxButton(m_scrolledWindow, wxID_DEL7, wxT("Delete"), wxDefaultPosition, wxSize(60,20), 0); - fgSizer5->Add(m_buttonDel7, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5); - - m_textCtrlLabel8 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0); - m_textCtrlLabel8->SetMinSize(wxSize(150,-1)); - - fgSizer5->Add(m_textCtrlLabel8, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5); - - m_textCtrlField8 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(-1,-1), 0); - fgSizer5->Add(m_textCtrlField8, 0, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5); - - m_buttonDel8 = new wxButton(m_scrolledWindow, wxID_DEL8, wxT("Delete"), wxDefaultPosition, wxSize(60,20), 0); - fgSizer5->Add(m_buttonDel8, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5); - - m_textCtrlLabel9 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0); - m_textCtrlLabel9->SetMinSize(wxSize(150,-1)); - - fgSizer5->Add(m_textCtrlLabel9, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5); - - m_textCtrlField9 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(-1,-1), 0); - fgSizer5->Add(m_textCtrlField9, 0, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5); - - m_buttonDel9 = new wxButton(m_scrolledWindow, wxID_DEL9, wxT("Delete"), wxDefaultPosition, wxSize(60,20), 0); - fgSizer5->Add(m_buttonDel9, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5); - - m_textCtrlLabel10 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0); - m_textCtrlLabel10->SetMinSize(wxSize(150,-1)); - - fgSizer5->Add(m_textCtrlLabel10, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5); - - m_textCtrlField10 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(-1,-1), 0); - fgSizer5->Add(m_textCtrlField10, 0, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5); - - m_buttonDel10 = new wxButton(m_scrolledWindow, wxID_DEL10, wxT("Delete"), wxDefaultPosition, wxSize(60,20), 0); - fgSizer5->Add(m_buttonDel10, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5); - - m_textCtrlLabel11 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0); - m_textCtrlLabel11->SetMinSize(wxSize(150,-1)); - - fgSizer5->Add(m_textCtrlLabel11, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5); - - m_textCtrlField11 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(-1,-1), 0); - fgSizer5->Add(m_textCtrlField11, 0, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5); - - m_buttonDel11 = new wxButton(m_scrolledWindow, wxID_DEL11, wxT("Delete"), wxDefaultPosition, wxSize(60,20), 0); - fgSizer5->Add(m_buttonDel11, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5); - - m_textCtrlLabel12 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0); - m_textCtrlLabel12->SetMinSize(wxSize(150,-1)); - - fgSizer5->Add(m_textCtrlLabel12, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5); - - m_textCtrlField12 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(-1,-1), 0); - fgSizer5->Add(m_textCtrlField12, 0, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5); - - m_buttonDel12 = new wxButton(m_scrolledWindow, wxID_DEL12, wxT("Delete"), wxDefaultPosition, wxSize(60,20), 0); - fgSizer5->Add(m_buttonDel12, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5); - - m_textCtrlLabel13 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0); - m_textCtrlLabel13->SetMinSize(wxSize(150,-1)); - - fgSizer5->Add(m_textCtrlLabel13, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5); - - m_textCtrlField13 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(-1,-1), 0); - fgSizer5->Add(m_textCtrlField13, 0, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5); - - m_buttonDel13 = new wxButton(m_scrolledWindow, wxID_DEL13, wxT("Delete"), wxDefaultPosition, wxSize(60,20), 0); - fgSizer5->Add(m_buttonDel13, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5); - - m_textCtrlLabel14 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0); - m_textCtrlLabel14->SetMinSize(wxSize(150,-1)); - - fgSizer5->Add(m_textCtrlLabel14, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5); - - m_textCtrlField14 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(-1,-1), 0); - fgSizer5->Add(m_textCtrlField14, 0, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5); - - m_buttonDel14 = new wxButton(m_scrolledWindow, wxID_DEL14, wxT("Delete"), wxDefaultPosition, wxSize(60,20), 0); - fgSizer5->Add(m_buttonDel14, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5); - - m_textCtrlLabel15 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0); - m_textCtrlLabel15->SetMinSize(wxSize(150,-1)); - - fgSizer5->Add(m_textCtrlLabel15, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5); - - m_textCtrlField15 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(-1,-1), 0); - fgSizer5->Add(m_textCtrlField15, 0, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5); - - m_buttonDel15 = new wxButton(m_scrolledWindow, wxID_DEL15, wxT("Delete"), wxDefaultPosition, wxSize(60,20), 0); - fgSizer5->Add(m_buttonDel15, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5); - - m_textCtrlLabel16 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0); - m_textCtrlLabel16->SetMinSize(wxSize(150,-1)); - - fgSizer5->Add(m_textCtrlLabel16, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5); - - m_textCtrlField16 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(-1,-1), 0); - fgSizer5->Add(m_textCtrlField16, 0, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5); - - m_buttonDel16 = new wxButton(m_scrolledWindow, wxID_DEL16, wxT("Delete"), wxDefaultPosition, wxSize(60,20), 0); - fgSizer5->Add(m_buttonDel16, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5); - - m_textCtrlLabel17 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0); - m_textCtrlLabel17->SetMinSize(wxSize(150,-1)); - - fgSizer5->Add(m_textCtrlLabel17, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5); - - m_textCtrlField17 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(-1,-1), 0); - fgSizer5->Add(m_textCtrlField17, 0, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5); - - m_buttonDel17 = new wxButton(m_scrolledWindow, wxID_DEL17, wxT("Delete"), wxDefaultPosition, wxSize(60,20), 0); - fgSizer5->Add(m_buttonDel17, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5); - - m_textCtrlLabel18 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0); - m_textCtrlLabel18->SetMinSize(wxSize(150,-1)); - - fgSizer5->Add(m_textCtrlLabel18, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5); - - m_textCtrlField18 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(-1,-1), 0); - fgSizer5->Add(m_textCtrlField18, 0, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5); - - m_buttonDel18 = new wxButton(m_scrolledWindow, wxID_DEL18, wxT("Delete"), wxDefaultPosition, wxSize(60,20), 0); - fgSizer5->Add(m_buttonDel18, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5); - - m_textCtrlLabel19 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0); - m_textCtrlLabel19->SetMinSize(wxSize(150,-1)); - - fgSizer5->Add(m_textCtrlLabel19, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5); - - m_textCtrlField19 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(-1,-1), 0); - fgSizer5->Add(m_textCtrlField19, 0, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5); - - m_buttonDel19 = new wxButton(m_scrolledWindow, wxID_DEL19, wxT("Delete"), wxDefaultPosition, wxSize(60,20), 0); - fgSizer5->Add(m_buttonDel19, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5); - - bSizer21->Add(fgSizer5, 0, wxEXPAND, 5); - - wxBoxSizer* bSizer25; - bSizer25 = new wxBoxSizer(wxHORIZONTAL); - - m_buttonAddField = new wxButton(m_scrolledWindow, wxID_ANY, wxT("&Add Field"), wxDefaultPosition, wxDefaultSize, 0); - bSizer25->Add(m_buttonAddField, 0, wxALL, 5); - - bSizer21->Add(bSizer25, 0, wxALIGN_CENTER_HORIZONTAL, 5); - - m_scrolledWindow->SetSizer(bSizer21); - m_scrolledWindow->Layout(); - bSizer21->Fit(m_scrolledWindow); - bSizer20->Add(m_scrolledWindow, 1, wxEXPAND|wxALL, 5); - - wxBoxSizer* bSizer26; - bSizer26 = new wxBoxSizer(wxHORIZONTAL); - - m_buttonOK = new wxButton(this, wxID_BUTTONSEND, wxT("&Send"), wxDefaultPosition, wxDefaultSize, 0); - m_buttonOK->SetMinSize(wxSize(85,25)); - - bSizer26->Add(m_buttonOK, 0, wxALL, 5); - - m_buttonPreview = new wxButton(this, wxID_BUTTONPREVIEW, wxT("&Preview"), wxDefaultPosition, wxDefaultSize, 0); - m_buttonPreview->SetMinSize(wxSize(85,25)); - - bSizer26->Add(m_buttonPreview, 0, wxALL, 5); - - m_buttonCancel = new wxButton(this, wxID_CANCEL, wxT("Cancel"), wxDefaultPosition, wxDefaultSize, 0); - m_buttonCancel->SetMinSize(wxSize(85,25)); - - bSizer26->Add(m_buttonCancel, 0, wxALL, 5); - - bSizer20->Add(bSizer26, 0, wxALIGN_RIGHT, 5); - - this->SetSizer(bSizer20); - this->Layout(); - - // Connect Events - m_textCtrlTitle->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); - m_textCtrlPrice->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); - m_textCtrlDescription->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); - m_textCtrlInstructions->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); - m_textCtrlLabel0->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); - m_textCtrlField0->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); - m_buttonDel0->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel0), NULL, this); - m_textCtrlLabel1->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); - m_textCtrlField1->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); - m_buttonDel1->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel1), NULL, this); - m_textCtrlLabel2->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); - m_textCtrlField2->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); - m_buttonDel2->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel2), NULL, this); - m_textCtrlLabel3->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); - m_textCtrlField3->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); - m_buttonDel3->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel3), NULL, this); - m_textCtrlLabel4->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); - m_textCtrlField4->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); - m_buttonDel4->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel4), NULL, this); - m_textCtrlLabel5->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); - m_textCtrlField5->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); - m_buttonDel5->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel5), NULL, this); - m_textCtrlLabel6->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); - m_textCtrlField6->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); - m_buttonDel6->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel6), NULL, this); - m_textCtrlLabel7->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); - m_textCtrlField7->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); - m_buttonDel7->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel7), NULL, this); - m_textCtrlLabel8->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); - m_textCtrlField8->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); - m_buttonDel8->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel8), NULL, this); - m_textCtrlLabel9->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); - m_textCtrlField9->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); - m_buttonDel9->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel9), NULL, this); - m_textCtrlLabel10->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); - m_textCtrlField10->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); - m_buttonDel10->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel10), NULL, this); - m_textCtrlLabel11->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); - m_textCtrlField11->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); - m_buttonDel11->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel11), NULL, this); - m_textCtrlLabel12->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); - m_textCtrlField12->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); - m_buttonDel12->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel12), NULL, this); - m_textCtrlLabel13->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); - m_textCtrlField13->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); - m_buttonDel13->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel13), NULL, this); - m_textCtrlLabel14->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); - m_textCtrlField14->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); - m_buttonDel14->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel14), NULL, this); - m_textCtrlLabel15->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); - m_textCtrlField15->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); - m_buttonDel15->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel15), NULL, this); - m_textCtrlLabel16->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); - m_textCtrlField16->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); - m_buttonDel16->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel16), NULL, this); - m_textCtrlLabel17->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); - m_textCtrlField17->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); - m_buttonDel17->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel17), NULL, this); - m_textCtrlLabel18->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); - m_textCtrlField18->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); - m_buttonDel18->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel18), NULL, this); - m_textCtrlLabel19->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); - m_textCtrlField19->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); - m_buttonDel19->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel19), NULL, this); - m_buttonAddField->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonAddField), NULL, this); - m_buttonOK->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonSend), NULL, this); - m_buttonPreview->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonPreview), NULL, this); - m_buttonCancel->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonCancel), NULL, this); + this->SetSizeHints( wxDefaultSize, wxDefaultSize ); + this->SetBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_MENU ) ); + + wxBoxSizer* bSizer20; + bSizer20 = new wxBoxSizer( wxVERTICAL ); + + m_scrolledWindow = new wxScrolledWindow( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxHSCROLL|wxTAB_TRAVERSAL|wxVSCROLL ); + m_scrolledWindow->SetScrollRate( 5, 5 ); + m_scrolledWindow->SetBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_WINDOW ) ); + + wxBoxSizer* bSizer21; + bSizer21 = new wxBoxSizer( wxVERTICAL ); + + wxFlexGridSizer* fgSizer8; + fgSizer8 = new wxFlexGridSizer( 0, 2, 0, 0 ); + fgSizer8->AddGrowableCol( 1 ); + fgSizer8->SetFlexibleDirection( wxBOTH ); + fgSizer8->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED ); + + m_staticText106 = new wxStaticText( m_scrolledWindow, wxID_ANY, wxT("Category"), wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT ); + m_staticText106->Wrap( -1 ); + fgSizer8->Add( m_staticText106, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxTOP|wxBOTTOM|wxLEFT, 5 ); + + m_comboBoxCategory = new wxComboBox( m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0, NULL, 0 ); + m_comboBoxCategory->SetMinSize( wxSize( 180,-1 ) ); + + fgSizer8->Add( m_comboBoxCategory, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); + + m_staticText108 = new wxStaticText( m_scrolledWindow, wxID_ANY, wxT("Title"), wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT ); + m_staticText108->Wrap( -1 ); + fgSizer8->Add( m_staticText108, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxTOP|wxBOTTOM|wxLEFT, 5 ); + + m_textCtrlTitle = new wxTextCtrl( m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); + fgSizer8->Add( m_textCtrlTitle, 1, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); + + m_staticText107 = new wxStaticText( m_scrolledWindow, wxID_ANY, wxT("Price"), wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT ); + m_staticText107->Wrap( -1 ); + fgSizer8->Add( m_staticText107, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxTOP|wxBOTTOM|wxLEFT, 5 ); + + m_textCtrlPrice = new wxTextCtrl( m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); + m_textCtrlPrice->SetMinSize( wxSize( 105,-1 ) ); + + fgSizer8->Add( m_textCtrlPrice, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); + + bSizer21->Add( fgSizer8, 0, wxEXPAND|wxTOP|wxRIGHT|wxLEFT, 5 ); + + m_staticText22 = new wxStaticText( m_scrolledWindow, wxID_ANY, wxT("Page 1: Description"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticText22->Wrap( -1 ); + bSizer21->Add( m_staticText22, 0, wxTOP|wxRIGHT|wxLEFT, 5 ); + + m_textCtrlDescription = new wxTextCtrl( m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE ); + m_textCtrlDescription->SetMinSize( wxSize( -1,170 ) ); + + bSizer21->Add( m_textCtrlDescription, 0, wxALL|wxEXPAND, 5 ); + + m_staticText23 = new wxStaticText( m_scrolledWindow, wxID_ANY, wxT("Page 2: Order Form"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticText23->Wrap( -1 ); + bSizer21->Add( m_staticText23, 0, wxTOP|wxRIGHT|wxLEFT, 5 ); + + m_textCtrlInstructions = new wxTextCtrl( m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE ); + m_textCtrlInstructions->SetMinSize( wxSize( -1,120 ) ); + + bSizer21->Add( m_textCtrlInstructions, 0, wxEXPAND|wxALL, 5 ); + + fgSizer5 = new wxFlexGridSizer( 0, 3, 0, 0 ); + fgSizer5->AddGrowableCol( 1 ); + fgSizer5->SetFlexibleDirection( wxBOTH ); + fgSizer5->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED ); + + m_staticText24 = new wxStaticText( m_scrolledWindow, wxID_ANY, wxT("Label"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticText24->Wrap( -1 ); + fgSizer5->Add( m_staticText24, 0, wxALIGN_CENTER_VERTICAL|wxTOP|wxRIGHT|wxLEFT, 5 ); + + m_staticText25 = new wxStaticText( m_scrolledWindow, wxID_ANY, wxT("Comma separated list of choices, or leave blank for text field"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticText25->Wrap( -1 ); + fgSizer5->Add( m_staticText25, 0, wxALIGN_CENTER_VERTICAL|wxTOP|wxRIGHT|wxLEFT, 5 ); + + + fgSizer5->Add( 0, 0, 1, wxEXPAND, 5 ); + + m_textCtrlLabel0 = new wxTextCtrl( m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); + m_textCtrlLabel0->SetMinSize( wxSize( 150,-1 ) ); + + fgSizer5->Add( m_textCtrlLabel0, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); + + m_textCtrlField0 = new wxTextCtrl( m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize( -1,-1 ), 0 ); + fgSizer5->Add( m_textCtrlField0, 0, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5 ); + + m_buttonDel0 = new wxButton( m_scrolledWindow, wxID_DEL0, wxT("Delete"), wxDefaultPosition, wxSize( 60,20 ), 0 ); + fgSizer5->Add( m_buttonDel0, 0, wxRIGHT|wxLEFT|wxALIGN_CENTER_VERTICAL, 5 ); + + m_textCtrlLabel1 = new wxTextCtrl( m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); + m_textCtrlLabel1->SetMinSize( wxSize( 150,-1 ) ); + + fgSizer5->Add( m_textCtrlLabel1, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); + + m_textCtrlField1 = new wxTextCtrl( m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize( -1,-1 ), 0 ); + fgSizer5->Add( m_textCtrlField1, 0, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5 ); + + m_buttonDel1 = new wxButton( m_scrolledWindow, wxID_DEL1, wxT("Delete"), wxDefaultPosition, wxSize( 60,20 ), 0 ); + fgSizer5->Add( m_buttonDel1, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 ); + + m_textCtrlLabel2 = new wxTextCtrl( m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); + m_textCtrlLabel2->SetMinSize( wxSize( 150,-1 ) ); + + fgSizer5->Add( m_textCtrlLabel2, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); + + m_textCtrlField2 = new wxTextCtrl( m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize( -1,-1 ), 0 ); + fgSizer5->Add( m_textCtrlField2, 0, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5 ); + + m_buttonDel2 = new wxButton( m_scrolledWindow, wxID_DEL2, wxT("Delete"), wxDefaultPosition, wxSize( 60,20 ), 0 ); + fgSizer5->Add( m_buttonDel2, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 ); + + m_textCtrlLabel3 = new wxTextCtrl( m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); + m_textCtrlLabel3->SetMinSize( wxSize( 150,-1 ) ); + + fgSizer5->Add( m_textCtrlLabel3, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); + + m_textCtrlField3 = new wxTextCtrl( m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize( -1,-1 ), 0 ); + fgSizer5->Add( m_textCtrlField3, 0, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5 ); + + m_buttonDel3 = new wxButton( m_scrolledWindow, wxID_DEL3, wxT("Delete"), wxDefaultPosition, wxSize( 60,20 ), 0 ); + fgSizer5->Add( m_buttonDel3, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 ); + + m_textCtrlLabel4 = new wxTextCtrl( m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); + m_textCtrlLabel4->SetMinSize( wxSize( 150,-1 ) ); + + fgSizer5->Add( m_textCtrlLabel4, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); + + m_textCtrlField4 = new wxTextCtrl( m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize( -1,-1 ), 0 ); + fgSizer5->Add( m_textCtrlField4, 0, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5 ); + + m_buttonDel4 = new wxButton( m_scrolledWindow, wxID_DEL4, wxT("Delete"), wxDefaultPosition, wxSize( 60,20 ), 0 ); + fgSizer5->Add( m_buttonDel4, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 ); + + m_textCtrlLabel5 = new wxTextCtrl( m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); + m_textCtrlLabel5->SetMinSize( wxSize( 150,-1 ) ); + + fgSizer5->Add( m_textCtrlLabel5, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); + + m_textCtrlField5 = new wxTextCtrl( m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize( -1,-1 ), 0 ); + fgSizer5->Add( m_textCtrlField5, 0, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5 ); + + m_buttonDel5 = new wxButton( m_scrolledWindow, wxID_DEL5, wxT("Delete"), wxDefaultPosition, wxSize( 60,20 ), 0 ); + fgSizer5->Add( m_buttonDel5, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 ); + + m_textCtrlLabel6 = new wxTextCtrl( m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); + m_textCtrlLabel6->SetMinSize( wxSize( 150,-1 ) ); + + fgSizer5->Add( m_textCtrlLabel6, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); + + m_textCtrlField6 = new wxTextCtrl( m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize( -1,-1 ), 0 ); + fgSizer5->Add( m_textCtrlField6, 0, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5 ); + + m_buttonDel6 = new wxButton( m_scrolledWindow, wxID_DEL6, wxT("Delete"), wxDefaultPosition, wxSize( 60,20 ), 0 ); + fgSizer5->Add( m_buttonDel6, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 ); + + m_textCtrlLabel7 = new wxTextCtrl( m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); + m_textCtrlLabel7->SetMinSize( wxSize( 150,-1 ) ); + + fgSizer5->Add( m_textCtrlLabel7, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); + + m_textCtrlField7 = new wxTextCtrl( m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize( -1,-1 ), 0 ); + fgSizer5->Add( m_textCtrlField7, 0, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5 ); + + m_buttonDel7 = new wxButton( m_scrolledWindow, wxID_DEL7, wxT("Delete"), wxDefaultPosition, wxSize( 60,20 ), 0 ); + fgSizer5->Add( m_buttonDel7, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 ); + + m_textCtrlLabel8 = new wxTextCtrl( m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); + m_textCtrlLabel8->SetMinSize( wxSize( 150,-1 ) ); + + fgSizer5->Add( m_textCtrlLabel8, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); + + m_textCtrlField8 = new wxTextCtrl( m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize( -1,-1 ), 0 ); + fgSizer5->Add( m_textCtrlField8, 0, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5 ); + + m_buttonDel8 = new wxButton( m_scrolledWindow, wxID_DEL8, wxT("Delete"), wxDefaultPosition, wxSize( 60,20 ), 0 ); + fgSizer5->Add( m_buttonDel8, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 ); + + m_textCtrlLabel9 = new wxTextCtrl( m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); + m_textCtrlLabel9->SetMinSize( wxSize( 150,-1 ) ); + + fgSizer5->Add( m_textCtrlLabel9, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); + + m_textCtrlField9 = new wxTextCtrl( m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize( -1,-1 ), 0 ); + fgSizer5->Add( m_textCtrlField9, 0, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5 ); + + m_buttonDel9 = new wxButton( m_scrolledWindow, wxID_DEL9, wxT("Delete"), wxDefaultPosition, wxSize( 60,20 ), 0 ); + fgSizer5->Add( m_buttonDel9, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 ); + + m_textCtrlLabel10 = new wxTextCtrl( m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); + m_textCtrlLabel10->SetMinSize( wxSize( 150,-1 ) ); + + fgSizer5->Add( m_textCtrlLabel10, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); + + m_textCtrlField10 = new wxTextCtrl( m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize( -1,-1 ), 0 ); + fgSizer5->Add( m_textCtrlField10, 0, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5 ); + + m_buttonDel10 = new wxButton( m_scrolledWindow, wxID_DEL10, wxT("Delete"), wxDefaultPosition, wxSize( 60,20 ), 0 ); + fgSizer5->Add( m_buttonDel10, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 ); + + m_textCtrlLabel11 = new wxTextCtrl( m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); + m_textCtrlLabel11->SetMinSize( wxSize( 150,-1 ) ); + + fgSizer5->Add( m_textCtrlLabel11, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); + + m_textCtrlField11 = new wxTextCtrl( m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize( -1,-1 ), 0 ); + fgSizer5->Add( m_textCtrlField11, 0, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5 ); + + m_buttonDel11 = new wxButton( m_scrolledWindow, wxID_DEL11, wxT("Delete"), wxDefaultPosition, wxSize( 60,20 ), 0 ); + fgSizer5->Add( m_buttonDel11, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 ); + + m_textCtrlLabel12 = new wxTextCtrl( m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); + m_textCtrlLabel12->SetMinSize( wxSize( 150,-1 ) ); + + fgSizer5->Add( m_textCtrlLabel12, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); + + m_textCtrlField12 = new wxTextCtrl( m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize( -1,-1 ), 0 ); + fgSizer5->Add( m_textCtrlField12, 0, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5 ); + + m_buttonDel12 = new wxButton( m_scrolledWindow, wxID_DEL12, wxT("Delete"), wxDefaultPosition, wxSize( 60,20 ), 0 ); + fgSizer5->Add( m_buttonDel12, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 ); + + m_textCtrlLabel13 = new wxTextCtrl( m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); + m_textCtrlLabel13->SetMinSize( wxSize( 150,-1 ) ); + + fgSizer5->Add( m_textCtrlLabel13, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); + + m_textCtrlField13 = new wxTextCtrl( m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize( -1,-1 ), 0 ); + fgSizer5->Add( m_textCtrlField13, 0, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5 ); + + m_buttonDel13 = new wxButton( m_scrolledWindow, wxID_DEL13, wxT("Delete"), wxDefaultPosition, wxSize( 60,20 ), 0 ); + fgSizer5->Add( m_buttonDel13, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 ); + + m_textCtrlLabel14 = new wxTextCtrl( m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); + m_textCtrlLabel14->SetMinSize( wxSize( 150,-1 ) ); + + fgSizer5->Add( m_textCtrlLabel14, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); + + m_textCtrlField14 = new wxTextCtrl( m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize( -1,-1 ), 0 ); + fgSizer5->Add( m_textCtrlField14, 0, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5 ); + + m_buttonDel14 = new wxButton( m_scrolledWindow, wxID_DEL14, wxT("Delete"), wxDefaultPosition, wxSize( 60,20 ), 0 ); + fgSizer5->Add( m_buttonDel14, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 ); + + m_textCtrlLabel15 = new wxTextCtrl( m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); + m_textCtrlLabel15->SetMinSize( wxSize( 150,-1 ) ); + + fgSizer5->Add( m_textCtrlLabel15, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); + + m_textCtrlField15 = new wxTextCtrl( m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize( -1,-1 ), 0 ); + fgSizer5->Add( m_textCtrlField15, 0, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5 ); + + m_buttonDel15 = new wxButton( m_scrolledWindow, wxID_DEL15, wxT("Delete"), wxDefaultPosition, wxSize( 60,20 ), 0 ); + fgSizer5->Add( m_buttonDel15, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 ); + + m_textCtrlLabel16 = new wxTextCtrl( m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); + m_textCtrlLabel16->SetMinSize( wxSize( 150,-1 ) ); + + fgSizer5->Add( m_textCtrlLabel16, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); + + m_textCtrlField16 = new wxTextCtrl( m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize( -1,-1 ), 0 ); + fgSizer5->Add( m_textCtrlField16, 0, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5 ); + + m_buttonDel16 = new wxButton( m_scrolledWindow, wxID_DEL16, wxT("Delete"), wxDefaultPosition, wxSize( 60,20 ), 0 ); + fgSizer5->Add( m_buttonDel16, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 ); + + m_textCtrlLabel17 = new wxTextCtrl( m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); + m_textCtrlLabel17->SetMinSize( wxSize( 150,-1 ) ); + + fgSizer5->Add( m_textCtrlLabel17, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); + + m_textCtrlField17 = new wxTextCtrl( m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize( -1,-1 ), 0 ); + fgSizer5->Add( m_textCtrlField17, 0, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5 ); + + m_buttonDel17 = new wxButton( m_scrolledWindow, wxID_DEL17, wxT("Delete"), wxDefaultPosition, wxSize( 60,20 ), 0 ); + fgSizer5->Add( m_buttonDel17, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 ); + + m_textCtrlLabel18 = new wxTextCtrl( m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); + m_textCtrlLabel18->SetMinSize( wxSize( 150,-1 ) ); + + fgSizer5->Add( m_textCtrlLabel18, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); + + m_textCtrlField18 = new wxTextCtrl( m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize( -1,-1 ), 0 ); + fgSizer5->Add( m_textCtrlField18, 0, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5 ); + + m_buttonDel18 = new wxButton( m_scrolledWindow, wxID_DEL18, wxT("Delete"), wxDefaultPosition, wxSize( 60,20 ), 0 ); + fgSizer5->Add( m_buttonDel18, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 ); + + m_textCtrlLabel19 = new wxTextCtrl( m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); + m_textCtrlLabel19->SetMinSize( wxSize( 150,-1 ) ); + + fgSizer5->Add( m_textCtrlLabel19, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); + + m_textCtrlField19 = new wxTextCtrl( m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize( -1,-1 ), 0 ); + fgSizer5->Add( m_textCtrlField19, 0, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5 ); + + m_buttonDel19 = new wxButton( m_scrolledWindow, wxID_DEL19, wxT("Delete"), wxDefaultPosition, wxSize( 60,20 ), 0 ); + fgSizer5->Add( m_buttonDel19, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 ); + + bSizer21->Add( fgSizer5, 0, wxEXPAND, 5 ); + + wxBoxSizer* bSizer25; + bSizer25 = new wxBoxSizer( wxHORIZONTAL ); + + m_buttonAddField = new wxButton( m_scrolledWindow, wxID_ANY, wxT("&Add Field"), wxDefaultPosition, wxDefaultSize, 0 ); + bSizer25->Add( m_buttonAddField, 0, wxALL, 5 ); + + bSizer21->Add( bSizer25, 0, wxALIGN_CENTER_HORIZONTAL, 5 ); + + m_scrolledWindow->SetSizer( bSizer21 ); + m_scrolledWindow->Layout(); + bSizer21->Fit( m_scrolledWindow ); + bSizer20->Add( m_scrolledWindow, 1, wxEXPAND|wxALL, 5 ); + + wxBoxSizer* bSizer26; + bSizer26 = new wxBoxSizer( wxHORIZONTAL ); + + m_buttonOK = new wxButton( this, wxID_BUTTONSEND, wxT("&Send"), wxDefaultPosition, wxDefaultSize, 0 ); + m_buttonOK->SetMinSize( wxSize( 85,25 ) ); + + bSizer26->Add( m_buttonOK, 0, wxALL, 5 ); + + m_buttonPreview = new wxButton( this, wxID_BUTTONPREVIEW, wxT("&Preview"), wxDefaultPosition, wxDefaultSize, 0 ); + m_buttonPreview->SetMinSize( wxSize( 85,25 ) ); + + bSizer26->Add( m_buttonPreview, 0, wxALL, 5 ); + + m_buttonCancel = new wxButton( this, wxID_CANCEL, wxT("Cancel"), wxDefaultPosition, wxDefaultSize, 0 ); + m_buttonCancel->SetMinSize( wxSize( 85,25 ) ); + + bSizer26->Add( m_buttonCancel, 0, wxALL, 5 ); + + bSizer20->Add( bSizer26, 0, wxALIGN_RIGHT, 5 ); + + this->SetSizer( bSizer20 ); + this->Layout(); + + // Connect Events + m_textCtrlTitle->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); + m_textCtrlPrice->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); + m_textCtrlDescription->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); + m_textCtrlInstructions->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); + m_textCtrlLabel0->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); + m_textCtrlField0->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); + m_buttonDel0->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditProductDialogBase::OnButtonDel0 ), NULL, this ); + m_textCtrlLabel1->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); + m_textCtrlField1->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); + m_buttonDel1->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditProductDialogBase::OnButtonDel1 ), NULL, this ); + m_textCtrlLabel2->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); + m_textCtrlField2->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); + m_buttonDel2->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditProductDialogBase::OnButtonDel2 ), NULL, this ); + m_textCtrlLabel3->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); + m_textCtrlField3->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); + m_buttonDel3->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditProductDialogBase::OnButtonDel3 ), NULL, this ); + m_textCtrlLabel4->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); + m_textCtrlField4->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); + m_buttonDel4->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditProductDialogBase::OnButtonDel4 ), NULL, this ); + m_textCtrlLabel5->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); + m_textCtrlField5->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); + m_buttonDel5->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditProductDialogBase::OnButtonDel5 ), NULL, this ); + m_textCtrlLabel6->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); + m_textCtrlField6->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); + m_buttonDel6->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditProductDialogBase::OnButtonDel6 ), NULL, this ); + m_textCtrlLabel7->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); + m_textCtrlField7->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); + m_buttonDel7->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditProductDialogBase::OnButtonDel7 ), NULL, this ); + m_textCtrlLabel8->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); + m_textCtrlField8->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); + m_buttonDel8->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditProductDialogBase::OnButtonDel8 ), NULL, this ); + m_textCtrlLabel9->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); + m_textCtrlField9->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); + m_buttonDel9->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditProductDialogBase::OnButtonDel9 ), NULL, this ); + m_textCtrlLabel10->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); + m_textCtrlField10->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); + m_buttonDel10->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditProductDialogBase::OnButtonDel10 ), NULL, this ); + m_textCtrlLabel11->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); + m_textCtrlField11->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); + m_buttonDel11->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditProductDialogBase::OnButtonDel11 ), NULL, this ); + m_textCtrlLabel12->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); + m_textCtrlField12->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); + m_buttonDel12->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditProductDialogBase::OnButtonDel12 ), NULL, this ); + m_textCtrlLabel13->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); + m_textCtrlField13->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); + m_buttonDel13->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditProductDialogBase::OnButtonDel13 ), NULL, this ); + m_textCtrlLabel14->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); + m_textCtrlField14->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); + m_buttonDel14->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditProductDialogBase::OnButtonDel14 ), NULL, this ); + m_textCtrlLabel15->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); + m_textCtrlField15->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); + m_buttonDel15->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditProductDialogBase::OnButtonDel15 ), NULL, this ); + m_textCtrlLabel16->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); + m_textCtrlField16->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); + m_buttonDel16->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditProductDialogBase::OnButtonDel16 ), NULL, this ); + m_textCtrlLabel17->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); + m_textCtrlField17->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); + m_buttonDel17->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditProductDialogBase::OnButtonDel17 ), NULL, this ); + m_textCtrlLabel18->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); + m_textCtrlField18->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); + m_buttonDel18->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditProductDialogBase::OnButtonDel18 ), NULL, this ); + m_textCtrlLabel19->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); + m_textCtrlField19->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); + m_buttonDel19->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditProductDialogBase::OnButtonDel19 ), NULL, this ); + m_buttonAddField->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditProductDialogBase::OnButtonAddField ), NULL, this ); + m_buttonOK->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditProductDialogBase::OnButtonSend ), NULL, this ); + m_buttonPreview->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditProductDialogBase::OnButtonPreview ), NULL, this ); + m_buttonCancel->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditProductDialogBase::OnButtonCancel ), NULL, this ); } CEditProductDialogBase::~CEditProductDialogBase() { - // Disconnect Events - m_textCtrlTitle->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); - m_textCtrlPrice->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); - m_textCtrlDescription->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); - m_textCtrlInstructions->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); - m_textCtrlLabel0->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); - m_textCtrlField0->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); - m_buttonDel0->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel0), NULL, this); - m_textCtrlLabel1->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); - m_textCtrlField1->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); - m_buttonDel1->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel1), NULL, this); - m_textCtrlLabel2->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); - m_textCtrlField2->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); - m_buttonDel2->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel2), NULL, this); - m_textCtrlLabel3->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); - m_textCtrlField3->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); - m_buttonDel3->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel3), NULL, this); - m_textCtrlLabel4->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); - m_textCtrlField4->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); - m_buttonDel4->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel4), NULL, this); - m_textCtrlLabel5->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); - m_textCtrlField5->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); - m_buttonDel5->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel5), NULL, this); - m_textCtrlLabel6->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); - m_textCtrlField6->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); - m_buttonDel6->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel6), NULL, this); - m_textCtrlLabel7->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); - m_textCtrlField7->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); - m_buttonDel7->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel7), NULL, this); - m_textCtrlLabel8->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); - m_textCtrlField8->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); - m_buttonDel8->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel8), NULL, this); - m_textCtrlLabel9->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); - m_textCtrlField9->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); - m_buttonDel9->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel9), NULL, this); - m_textCtrlLabel10->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); - m_textCtrlField10->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); - m_buttonDel10->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel10), NULL, this); - m_textCtrlLabel11->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); - m_textCtrlField11->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); - m_buttonDel11->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel11), NULL, this); - m_textCtrlLabel12->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); - m_textCtrlField12->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); - m_buttonDel12->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel12), NULL, this); - m_textCtrlLabel13->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); - m_textCtrlField13->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); - m_buttonDel13->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel13), NULL, this); - m_textCtrlLabel14->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); - m_textCtrlField14->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); - m_buttonDel14->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel14), NULL, this); - m_textCtrlLabel15->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); - m_textCtrlField15->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); - m_buttonDel15->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel15), NULL, this); - m_textCtrlLabel16->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); - m_textCtrlField16->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); - m_buttonDel16->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel16), NULL, this); - m_textCtrlLabel17->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); - m_textCtrlField17->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); - m_buttonDel17->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel17), NULL, this); - m_textCtrlLabel18->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); - m_textCtrlField18->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); - m_buttonDel18->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel18), NULL, this); - m_textCtrlLabel19->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); - m_textCtrlField19->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); - m_buttonDel19->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel19), NULL, this); - m_buttonAddField->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonAddField), NULL, this); - m_buttonOK->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonSend), NULL, this); - m_buttonPreview->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonPreview), NULL, this); - m_buttonCancel->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonCancel), NULL, this); + // Disconnect Events + m_textCtrlTitle->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); + m_textCtrlPrice->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); + m_textCtrlDescription->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); + m_textCtrlInstructions->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); + m_textCtrlLabel0->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); + m_textCtrlField0->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); + m_buttonDel0->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditProductDialogBase::OnButtonDel0 ), NULL, this ); + m_textCtrlLabel1->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); + m_textCtrlField1->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); + m_buttonDel1->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditProductDialogBase::OnButtonDel1 ), NULL, this ); + m_textCtrlLabel2->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); + m_textCtrlField2->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); + m_buttonDel2->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditProductDialogBase::OnButtonDel2 ), NULL, this ); + m_textCtrlLabel3->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); + m_textCtrlField3->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); + m_buttonDel3->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditProductDialogBase::OnButtonDel3 ), NULL, this ); + m_textCtrlLabel4->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); + m_textCtrlField4->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); + m_buttonDel4->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditProductDialogBase::OnButtonDel4 ), NULL, this ); + m_textCtrlLabel5->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); + m_textCtrlField5->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); + m_buttonDel5->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditProductDialogBase::OnButtonDel5 ), NULL, this ); + m_textCtrlLabel6->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); + m_textCtrlField6->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); + m_buttonDel6->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditProductDialogBase::OnButtonDel6 ), NULL, this ); + m_textCtrlLabel7->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); + m_textCtrlField7->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); + m_buttonDel7->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditProductDialogBase::OnButtonDel7 ), NULL, this ); + m_textCtrlLabel8->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); + m_textCtrlField8->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); + m_buttonDel8->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditProductDialogBase::OnButtonDel8 ), NULL, this ); + m_textCtrlLabel9->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); + m_textCtrlField9->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); + m_buttonDel9->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditProductDialogBase::OnButtonDel9 ), NULL, this ); + m_textCtrlLabel10->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); + m_textCtrlField10->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); + m_buttonDel10->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditProductDialogBase::OnButtonDel10 ), NULL, this ); + m_textCtrlLabel11->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); + m_textCtrlField11->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); + m_buttonDel11->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditProductDialogBase::OnButtonDel11 ), NULL, this ); + m_textCtrlLabel12->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); + m_textCtrlField12->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); + m_buttonDel12->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditProductDialogBase::OnButtonDel12 ), NULL, this ); + m_textCtrlLabel13->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); + m_textCtrlField13->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); + m_buttonDel13->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditProductDialogBase::OnButtonDel13 ), NULL, this ); + m_textCtrlLabel14->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); + m_textCtrlField14->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); + m_buttonDel14->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditProductDialogBase::OnButtonDel14 ), NULL, this ); + m_textCtrlLabel15->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); + m_textCtrlField15->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); + m_buttonDel15->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditProductDialogBase::OnButtonDel15 ), NULL, this ); + m_textCtrlLabel16->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); + m_textCtrlField16->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); + m_buttonDel16->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditProductDialogBase::OnButtonDel16 ), NULL, this ); + m_textCtrlLabel17->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); + m_textCtrlField17->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); + m_buttonDel17->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditProductDialogBase::OnButtonDel17 ), NULL, this ); + m_textCtrlLabel18->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); + m_textCtrlField18->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); + m_buttonDel18->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditProductDialogBase::OnButtonDel18 ), NULL, this ); + m_textCtrlLabel19->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); + m_textCtrlField19->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); + m_buttonDel19->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditProductDialogBase::OnButtonDel19 ), NULL, this ); + m_buttonAddField->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditProductDialogBase::OnButtonAddField ), NULL, this ); + m_buttonOK->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditProductDialogBase::OnButtonSend ), NULL, this ); + m_buttonPreview->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditProductDialogBase::OnButtonPreview ), NULL, this ); + m_buttonCancel->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditProductDialogBase::OnButtonCancel ), NULL, this ); } -CViewProductDialogBase::CViewProductDialogBase(wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style) : wxFrame(parent, id, title, pos, size, style) +CViewProductDialogBase::CViewProductDialogBase( 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_MENU)); - - wxBoxSizer* bSizer20; - bSizer20 = new wxBoxSizer(wxVERTICAL); - - wxBoxSizer* bSizer116; - bSizer116 = new wxBoxSizer(wxHORIZONTAL); - - m_htmlWinReviews = new wxHtmlWindow(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxHW_SCROLLBAR_AUTO); - m_htmlWinReviews->Hide(); - - bSizer116->Add(m_htmlWinReviews, 1, wxALL|wxEXPAND, 5); - - m_scrolledWindow = new wxScrolledWindow(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxHSCROLL|wxTAB_TRAVERSAL|wxVSCROLL); - m_scrolledWindow->SetScrollRate(5, 5); - m_scrolledWindow->SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW)); - - wxBoxSizer* bSizer21; - bSizer21 = new wxBoxSizer(wxVERTICAL); - - m_richTextHeading = new wxRichTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(-1,50), wxTE_READONLY|wxNO_BORDER); - bSizer21->Add(m_richTextHeading, 0, wxEXPAND, 5); - - m_staticTextInstructions = new wxStaticText(m_scrolledWindow, wxID_ANY, wxT("Order Form instructions here\nmultiple lines\n1\n2\n3\n4\n5\n6"), wxDefaultPosition, wxDefaultSize, 0); - m_staticTextInstructions->Wrap(-1); - bSizer21->Add(m_staticTextInstructions, 0, wxALL|wxEXPAND, 5); - - wxBoxSizer* bSizer25; - bSizer25 = new wxBoxSizer(wxHORIZONTAL); - - m_buttonSubmitForm = new wxButton(m_scrolledWindow, wxID_BUTTONSAMPLE, wxT("&Submit"), wxDefaultPosition, wxDefaultSize, 0); - bSizer25->Add(m_buttonSubmitForm, 0, wxALL, 5); - - m_buttonCancelForm = new wxButton(m_scrolledWindow, wxID_CANCEL2, wxT("Cancel"), wxDefaultPosition, wxDefaultSize, 0); - bSizer25->Add(m_buttonCancelForm, 0, wxALL, 5); - - bSizer21->Add(bSizer25, 0, wxALIGN_CENTER_HORIZONTAL, 5); - - m_scrolledWindow->SetSizer(bSizer21); - m_scrolledWindow->Layout(); - bSizer21->Fit(m_scrolledWindow); - bSizer116->Add(m_scrolledWindow, 1, wxEXPAND|wxALL, 5); - - bSizer20->Add(bSizer116, 1, wxEXPAND, 5); - - wxBoxSizer* bSizer26; - bSizer26 = new wxBoxSizer(wxHORIZONTAL); - - m_buttonBack = new wxButton(this, wxID_BUTTONBACK, wxT("< &Back "), wxDefaultPosition, wxDefaultSize, 0); - m_buttonBack->Enable(false); - m_buttonBack->SetMinSize(wxSize(85,25)); - - bSizer26->Add(m_buttonBack, 0, wxALL, 5); - - m_buttonNext = new wxButton(this, wxID_BUTTONNEXT, wxT(" &Next >"), wxDefaultPosition, wxDefaultSize, 0); - m_buttonNext->SetMinSize(wxSize(85,25)); - - bSizer26->Add(m_buttonNext, 0, wxALL, 5); - - m_buttonCancel = new wxButton(this, wxID_CANCEL, wxT("Cancel"), wxDefaultPosition, wxDefaultSize, 0); - m_buttonCancel->SetMinSize(wxSize(85,25)); - - bSizer26->Add(m_buttonCancel, 0, wxALL, 5); - - bSizer20->Add(bSizer26, 0, wxALIGN_RIGHT, 5); - - this->SetSizer(bSizer20); - this->Layout(); - - // Connect Events - m_buttonSubmitForm->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CViewProductDialogBase::OnButtonSubmitForm), NULL, this); - m_buttonCancelForm->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CViewProductDialogBase::OnButtonCancelForm), NULL, this); - m_buttonBack->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CViewProductDialogBase::OnButtonBack), NULL, this); - m_buttonNext->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CViewProductDialogBase::OnButtonNext), NULL, this); - m_buttonCancel->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CViewProductDialogBase::OnButtonCancel), NULL, this); + this->SetSizeHints( wxDefaultSize, wxDefaultSize ); + this->SetBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_MENU ) ); + + wxBoxSizer* bSizer20; + bSizer20 = new wxBoxSizer( wxVERTICAL ); + + wxBoxSizer* bSizer116; + bSizer116 = new wxBoxSizer( wxHORIZONTAL ); + + m_htmlWinReviews = new wxHtmlWindow( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxHW_SCROLLBAR_AUTO ); + m_htmlWinReviews->Hide(); + + bSizer116->Add( m_htmlWinReviews, 1, wxALL|wxEXPAND, 5 ); + + m_scrolledWindow = new wxScrolledWindow( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxHSCROLL|wxTAB_TRAVERSAL|wxVSCROLL ); + m_scrolledWindow->SetScrollRate( 5, 5 ); + m_scrolledWindow->SetBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_WINDOW ) ); + + wxBoxSizer* bSizer21; + bSizer21 = new wxBoxSizer( wxVERTICAL ); + + m_richTextHeading = new wxRichTextCtrl( m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize( -1,50 ), wxTE_READONLY|wxNO_BORDER ); + bSizer21->Add( m_richTextHeading, 0, wxEXPAND, 5 ); + + m_staticTextInstructions = new wxStaticText( m_scrolledWindow, wxID_ANY, wxT("Order Form instructions here\nmultiple lines\n1\n2\n3\n4\n5\n6"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticTextInstructions->Wrap( -1 ); + bSizer21->Add( m_staticTextInstructions, 0, wxALL|wxEXPAND, 5 ); + + wxBoxSizer* bSizer25; + bSizer25 = new wxBoxSizer( wxHORIZONTAL ); + + m_buttonSubmitForm = new wxButton( m_scrolledWindow, wxID_BUTTONSAMPLE, wxT("&Submit"), wxDefaultPosition, wxDefaultSize, 0 ); + bSizer25->Add( m_buttonSubmitForm, 0, wxALL, 5 ); + + m_buttonCancelForm = new wxButton( m_scrolledWindow, wxID_CANCEL2, wxT("Cancel"), wxDefaultPosition, wxDefaultSize, 0 ); + bSizer25->Add( m_buttonCancelForm, 0, wxALL, 5 ); + + bSizer21->Add( bSizer25, 0, wxALIGN_CENTER_HORIZONTAL, 5 ); + + m_scrolledWindow->SetSizer( bSizer21 ); + m_scrolledWindow->Layout(); + bSizer21->Fit( m_scrolledWindow ); + bSizer116->Add( m_scrolledWindow, 1, wxEXPAND|wxALL, 5 ); + + bSizer20->Add( bSizer116, 1, wxEXPAND, 5 ); + + wxBoxSizer* bSizer26; + bSizer26 = new wxBoxSizer( wxHORIZONTAL ); + + m_buttonBack = new wxButton( this, wxID_BUTTONBACK, wxT("< &Back "), wxDefaultPosition, wxDefaultSize, 0 ); + m_buttonBack->Enable( false ); + m_buttonBack->SetMinSize( wxSize( 85,25 ) ); + + bSizer26->Add( m_buttonBack, 0, wxALL, 5 ); + + m_buttonNext = new wxButton( this, wxID_BUTTONNEXT, wxT(" &Next >"), wxDefaultPosition, wxDefaultSize, 0 ); + m_buttonNext->SetMinSize( wxSize( 85,25 ) ); + + bSizer26->Add( m_buttonNext, 0, wxALL, 5 ); + + m_buttonCancel = new wxButton( this, wxID_CANCEL, wxT("Cancel"), wxDefaultPosition, wxDefaultSize, 0 ); + m_buttonCancel->SetMinSize( wxSize( 85,25 ) ); + + bSizer26->Add( m_buttonCancel, 0, wxALL, 5 ); + + bSizer20->Add( bSizer26, 0, wxALIGN_RIGHT, 5 ); + + this->SetSizer( bSizer20 ); + this->Layout(); + + // Connect Events + m_buttonSubmitForm->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CViewProductDialogBase::OnButtonSubmitForm ), NULL, this ); + m_buttonCancelForm->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CViewProductDialogBase::OnButtonCancelForm ), NULL, this ); + m_buttonBack->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CViewProductDialogBase::OnButtonBack ), NULL, this ); + m_buttonNext->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CViewProductDialogBase::OnButtonNext ), NULL, this ); + m_buttonCancel->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CViewProductDialogBase::OnButtonCancel ), NULL, this ); } CViewProductDialogBase::~CViewProductDialogBase() { - // Disconnect Events - m_buttonSubmitForm->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CViewProductDialogBase::OnButtonSubmitForm), NULL, this); - m_buttonCancelForm->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CViewProductDialogBase::OnButtonCancelForm), NULL, this); - m_buttonBack->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CViewProductDialogBase::OnButtonBack), NULL, this); - m_buttonNext->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CViewProductDialogBase::OnButtonNext), NULL, this); - m_buttonCancel->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CViewProductDialogBase::OnButtonCancel), NULL, this); + // Disconnect Events + m_buttonSubmitForm->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CViewProductDialogBase::OnButtonSubmitForm ), NULL, this ); + m_buttonCancelForm->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CViewProductDialogBase::OnButtonCancelForm ), NULL, this ); + m_buttonBack->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CViewProductDialogBase::OnButtonBack ), NULL, this ); + m_buttonNext->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CViewProductDialogBase::OnButtonNext ), NULL, this ); + m_buttonCancel->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CViewProductDialogBase::OnButtonCancel ), NULL, this ); } -CViewOrderDialogBase::CViewOrderDialogBase(wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style) : wxFrame(parent, id, title, pos, size, style) +CViewOrderDialogBase::CViewOrderDialogBase( 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_MENU)); - - wxBoxSizer* bSizer20; - bSizer20 = new wxBoxSizer(wxVERTICAL); - - wxBoxSizer* bSizer116; - bSizer116 = new wxBoxSizer(wxHORIZONTAL); - - m_htmlWin = new wxHtmlWindow(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxHW_SCROLLBAR_AUTO); - bSizer116->Add(m_htmlWin, 1, wxALL|wxEXPAND, 5); - - bSizer20->Add(bSizer116, 1, wxEXPAND, 5); - - wxBoxSizer* bSizer26; - bSizer26 = new wxBoxSizer(wxHORIZONTAL); - - m_buttonOK = new wxButton(this, wxID_OK, wxT("OK"), wxDefaultPosition, wxDefaultSize, 0); - m_buttonOK->SetMinSize(wxSize(85,25)); - - bSizer26->Add(m_buttonOK, 0, wxALL, 5); - - bSizer20->Add(bSizer26, 0, wxALIGN_RIGHT, 5); - - this->SetSizer(bSizer20); - this->Layout(); - - // Connect Events - m_buttonOK->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CViewOrderDialogBase::OnButtonOK), NULL, this); + this->SetSizeHints( wxDefaultSize, wxDefaultSize ); + this->SetBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_MENU ) ); + + wxBoxSizer* bSizer20; + bSizer20 = new wxBoxSizer( wxVERTICAL ); + + wxBoxSizer* bSizer116; + bSizer116 = new wxBoxSizer( wxHORIZONTAL ); + + m_htmlWin = new wxHtmlWindow( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxHW_SCROLLBAR_AUTO ); + bSizer116->Add( m_htmlWin, 1, wxALL|wxEXPAND, 5 ); + + bSizer20->Add( bSizer116, 1, wxEXPAND, 5 ); + + wxBoxSizer* bSizer26; + bSizer26 = new wxBoxSizer( wxHORIZONTAL ); + + m_buttonOK = new wxButton( this, wxID_OK, wxT("OK"), wxDefaultPosition, wxDefaultSize, 0 ); + m_buttonOK->SetMinSize( wxSize( 85,25 ) ); + + bSizer26->Add( m_buttonOK, 0, wxALL, 5 ); + + bSizer20->Add( bSizer26, 0, wxALIGN_RIGHT, 5 ); + + this->SetSizer( bSizer20 ); + this->Layout(); + + // Connect Events + m_buttonOK->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CViewOrderDialogBase::OnButtonOK ), NULL, this ); } CViewOrderDialogBase::~CViewOrderDialogBase() { - // Disconnect Events - m_buttonOK->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CViewOrderDialogBase::OnButtonOK), NULL, this); + // Disconnect Events + m_buttonOK->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CViewOrderDialogBase::OnButtonOK ), NULL, this ); } -CEditReviewDialogBase::CEditReviewDialogBase(wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style) : wxFrame(parent, id, title, pos, size, style) +CEditReviewDialogBase::CEditReviewDialogBase( 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_MENU)); - - wxBoxSizer* bSizer112; - bSizer112 = new wxBoxSizer(wxVERTICAL); - - - bSizer112->Add(0, 3, 0, 0, 5); - - m_staticTextSeller = new wxStaticText(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0); - m_staticTextSeller->Wrap(-1); - bSizer112->Add(m_staticTextSeller, 0, wxALL|wxEXPAND, 5); - - - bSizer112->Add(0, 3, 0, 0, 5); - - m_staticText110 = new wxStaticText(this, wxID_ANY, wxT("Rating"), wxDefaultPosition, wxDefaultSize, 0); - m_staticText110->Wrap(-1); - bSizer112->Add(m_staticText110, 0, wxTOP|wxRIGHT|wxLEFT, 5); - - wxString m_choiceStarsChoices[] = { wxT(" 1 star"), wxT(" 2 stars"), wxT(" 3 stars"), wxT(" 4 stars"), wxT(" 5 stars") }; - int m_choiceStarsNChoices = sizeof(m_choiceStarsChoices) / sizeof(wxString); - m_choiceStars = new wxChoice(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, m_choiceStarsNChoices, m_choiceStarsChoices, 0); - m_choiceStars->SetSelection(0); - bSizer112->Add(m_choiceStars, 0, wxALL, 5); - - m_staticText43 = new wxStaticText(this, wxID_ANY, wxT("Review"), wxDefaultPosition, wxDefaultSize, 0); - m_staticText43->Wrap(-1); - bSizer112->Add(m_staticText43, 0, wxTOP|wxRIGHT|wxLEFT, 5); - - m_textCtrlReview = new wxTextCtrl(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE); - bSizer112->Add(m_textCtrlReview, 1, wxALL|wxEXPAND, 5); - - wxBoxSizer* bSizer113; - bSizer113 = new wxBoxSizer(wxHORIZONTAL); - - m_buttonSubmit = new wxButton(this, wxID_SUBMIT, wxT("&Submit"), wxDefaultPosition, wxDefaultSize, 0); - m_buttonSubmit->SetMinSize(wxSize(85,25)); - - bSizer113->Add(m_buttonSubmit, 0, wxALL, 5); - - m_buttonCancel = new wxButton(this, wxID_CANCEL, wxT("Cancel"), wxDefaultPosition, wxDefaultSize, 0); - m_buttonCancel->SetMinSize(wxSize(85,25)); - - bSizer113->Add(m_buttonCancel, 0, wxALL, 5); - - bSizer112->Add(bSizer113, 0, wxALIGN_RIGHT, 5); - - this->SetSizer(bSizer112); - this->Layout(); - - // Connect Events - m_textCtrlReview->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditReviewDialogBase::OnKeyDown), NULL, this); - m_buttonSubmit->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditReviewDialogBase::OnButtonSubmit), NULL, this); - m_buttonCancel->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditReviewDialogBase::OnButtonCancel), NULL, this); + this->SetSizeHints( wxDefaultSize, wxDefaultSize ); + this->SetBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_MENU ) ); + + wxBoxSizer* bSizer112; + bSizer112 = new wxBoxSizer( wxVERTICAL ); + + + bSizer112->Add( 0, 3, 0, 0, 5 ); + + m_staticTextSeller = new wxStaticText( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); + m_staticTextSeller->Wrap( -1 ); + bSizer112->Add( m_staticTextSeller, 0, wxALL|wxEXPAND, 5 ); + + + bSizer112->Add( 0, 3, 0, 0, 5 ); + + m_staticText110 = new wxStaticText( this, wxID_ANY, wxT("Rating"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticText110->Wrap( -1 ); + bSizer112->Add( m_staticText110, 0, wxTOP|wxRIGHT|wxLEFT, 5 ); + + wxString m_choiceStarsChoices[] = { wxT(" 1 star"), wxT(" 2 stars"), wxT(" 3 stars"), wxT(" 4 stars"), wxT(" 5 stars") }; + int m_choiceStarsNChoices = sizeof( m_choiceStarsChoices ) / sizeof( wxString ); + m_choiceStars = new wxChoice( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, m_choiceStarsNChoices, m_choiceStarsChoices, 0 ); + m_choiceStars->SetSelection( 0 ); + bSizer112->Add( m_choiceStars, 0, wxALL, 5 ); + + m_staticText43 = new wxStaticText( this, wxID_ANY, wxT("Review"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticText43->Wrap( -1 ); + bSizer112->Add( m_staticText43, 0, wxTOP|wxRIGHT|wxLEFT, 5 ); + + m_textCtrlReview = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE ); + bSizer112->Add( m_textCtrlReview, 1, wxALL|wxEXPAND, 5 ); + + wxBoxSizer* bSizer113; + bSizer113 = new wxBoxSizer( wxHORIZONTAL ); + + m_buttonSubmit = new wxButton( this, wxID_SUBMIT, wxT("&Submit"), wxDefaultPosition, wxDefaultSize, 0 ); + m_buttonSubmit->SetMinSize( wxSize( 85,25 ) ); + + bSizer113->Add( m_buttonSubmit, 0, wxALL, 5 ); + + m_buttonCancel = new wxButton( this, wxID_CANCEL, wxT("Cancel"), wxDefaultPosition, wxDefaultSize, 0 ); + m_buttonCancel->SetMinSize( wxSize( 85,25 ) ); + + bSizer113->Add( m_buttonCancel, 0, wxALL, 5 ); + + bSizer112->Add( bSizer113, 0, wxALIGN_RIGHT, 5 ); + + this->SetSizer( bSizer112 ); + this->Layout(); + + // Connect Events + m_textCtrlReview->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditReviewDialogBase::OnKeyDown ), NULL, this ); + m_buttonSubmit->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditReviewDialogBase::OnButtonSubmit ), NULL, this ); + m_buttonCancel->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditReviewDialogBase::OnButtonCancel ), NULL, this ); } CEditReviewDialogBase::~CEditReviewDialogBase() { - // Disconnect Events - m_textCtrlReview->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditReviewDialogBase::OnKeyDown), NULL, this); - m_buttonSubmit->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditReviewDialogBase::OnButtonSubmit), NULL, this); - m_buttonCancel->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditReviewDialogBase::OnButtonCancel), NULL, this); + // Disconnect Events + m_textCtrlReview->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditReviewDialogBase::OnKeyDown ), NULL, this ); + m_buttonSubmit->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditReviewDialogBase::OnButtonSubmit ), NULL, this ); + m_buttonCancel->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditReviewDialogBase::OnButtonCancel ), NULL, this ); } -CPokerLobbyDialogBase::CPokerLobbyDialogBase(wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style) : wxFrame(parent, id, title, pos, size, style) +CPokerLobbyDialogBase::CPokerLobbyDialogBase( 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)); - - wxBoxSizer* bSizer156; - bSizer156 = new wxBoxSizer(wxHORIZONTAL); - - m_treeCtrl = new wxTreeCtrl(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTR_HAS_BUTTONS|wxTR_HIDE_ROOT|wxTR_LINES_AT_ROOT); - m_treeCtrl->SetMinSize(wxSize(130,-1)); - - bSizer156->Add(m_treeCtrl, 0, wxEXPAND|wxTOP|wxBOTTOM|wxLEFT, 5); - - wxBoxSizer* bSizer172; - bSizer172 = new wxBoxSizer(wxVERTICAL); - - m_listCtrl = new wxListCtrl(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_NO_SORT_HEADER|wxLC_REPORT); - bSizer172->Add(m_listCtrl, 1, wxEXPAND|wxALL, 5); - - m_buttonNewTable = new wxButton(this, wxID_OPENNEWTABLE, wxT("&Open New Table"), wxDefaultPosition, wxDefaultSize, 0); - bSizer172->Add(m_buttonNewTable, 0, wxALL, 5); - - bSizer156->Add(bSizer172, 1, wxEXPAND, 5); - - this->SetSizer(bSizer156); - this->Layout(); - - // Connect Events - m_treeCtrl->Connect(wxEVT_COMMAND_TREE_SEL_CHANGED, wxTreeEventHandler(CPokerLobbyDialogBase::OnTreeSelChanged), NULL, this); - m_listCtrl->Connect(wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler(CPokerLobbyDialogBase::OnListItemActivated), NULL, this); - m_listCtrl->Connect(wxEVT_COMMAND_LIST_ITEM_SELECTED, wxListEventHandler(CPokerLobbyDialogBase::OnListItemSelected), NULL, this); - m_buttonNewTable->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CPokerLobbyDialogBase::OnButtonNewTable), NULL, this); + this->SetSizeHints( wxDefaultSize, wxDefaultSize ); + this->SetBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_BTNFACE ) ); + + wxBoxSizer* bSizer156; + bSizer156 = new wxBoxSizer( wxHORIZONTAL ); + + m_treeCtrl = new wxTreeCtrl( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTR_HAS_BUTTONS|wxTR_HIDE_ROOT|wxTR_LINES_AT_ROOT ); + m_treeCtrl->SetMinSize( wxSize( 130,-1 ) ); + + bSizer156->Add( m_treeCtrl, 0, wxEXPAND|wxTOP|wxBOTTOM|wxLEFT, 5 ); + + wxBoxSizer* bSizer172; + bSizer172 = new wxBoxSizer( wxVERTICAL ); + + m_listCtrl = new wxListCtrl( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_NO_SORT_HEADER|wxLC_REPORT ); + bSizer172->Add( m_listCtrl, 1, wxEXPAND|wxALL, 5 ); + + m_buttonNewTable = new wxButton( this, wxID_OPENNEWTABLE, wxT("&Open New Table"), wxDefaultPosition, wxDefaultSize, 0 ); + bSizer172->Add( m_buttonNewTable, 0, wxALL, 5 ); + + bSizer156->Add( bSizer172, 1, wxEXPAND, 5 ); + + this->SetSizer( bSizer156 ); + this->Layout(); + + // Connect Events + m_treeCtrl->Connect( wxEVT_COMMAND_TREE_SEL_CHANGED, wxTreeEventHandler( CPokerLobbyDialogBase::OnTreeSelChanged ), NULL, this ); + m_listCtrl->Connect( wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler( CPokerLobbyDialogBase::OnListItemActivated ), NULL, this ); + m_listCtrl->Connect( wxEVT_COMMAND_LIST_ITEM_SELECTED, wxListEventHandler( CPokerLobbyDialogBase::OnListItemSelected ), NULL, this ); + m_buttonNewTable->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CPokerLobbyDialogBase::OnButtonNewTable ), NULL, this ); } CPokerLobbyDialogBase::~CPokerLobbyDialogBase() { - // Disconnect Events - m_treeCtrl->Disconnect(wxEVT_COMMAND_TREE_SEL_CHANGED, wxTreeEventHandler(CPokerLobbyDialogBase::OnTreeSelChanged), NULL, this); - m_listCtrl->Disconnect(wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler(CPokerLobbyDialogBase::OnListItemActivated), NULL, this); - m_listCtrl->Disconnect(wxEVT_COMMAND_LIST_ITEM_SELECTED, wxListEventHandler(CPokerLobbyDialogBase::OnListItemSelected), NULL, this); - m_buttonNewTable->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CPokerLobbyDialogBase::OnButtonNewTable), NULL, this); + // Disconnect Events + m_treeCtrl->Disconnect( wxEVT_COMMAND_TREE_SEL_CHANGED, wxTreeEventHandler( CPokerLobbyDialogBase::OnTreeSelChanged ), NULL, this ); + m_listCtrl->Disconnect( wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler( CPokerLobbyDialogBase::OnListItemActivated ), NULL, this ); + m_listCtrl->Disconnect( wxEVT_COMMAND_LIST_ITEM_SELECTED, wxListEventHandler( CPokerLobbyDialogBase::OnListItemSelected ), NULL, this ); + m_buttonNewTable->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CPokerLobbyDialogBase::OnButtonNewTable ), NULL, this ); } -CPokerDialogBase::CPokerDialogBase(wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style) : wxFrame(parent, id, title, pos, size, style) +CPokerDialogBase::CPokerDialogBase( 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); - - wxBoxSizer* bSizer174; - bSizer174 = new wxBoxSizer(wxVERTICAL); - - m_checkSitOut = new wxCheckBox(this, wxID_ANY, wxT("Deal Me Out"), wxDefaultPosition, wxDefaultSize, 0); - - bSizer174->Add(m_checkSitOut, 0, wxALL, 5); - - m_buttonDealHand = new wxButton(this, wxID_DEALHAND, wxT("&Deal Hand"), wxDefaultPosition, wxSize(150,25), 0); - bSizer174->Add(m_buttonDealHand, 0, wxALL, 5); - - m_buttonFold = new wxButton(this, wxID_FOLD, wxT("&Fold"), wxDefaultPosition, wxSize(80,25), 0); - bSizer174->Add(m_buttonFold, 0, wxALL, 5); - - m_buttonCall = new wxButton(this, wxID_CALL, wxT("&Call"), wxDefaultPosition, wxSize(80,25), 0); - bSizer174->Add(m_buttonCall, 0, wxALL, 5); - - m_buttonRaise = new wxButton(this, wxID_RAISE, wxT("&Raise"), wxDefaultPosition, wxSize(80,25), 0); - bSizer174->Add(m_buttonRaise, 0, wxALL, 5); - - m_buttonLeaveTable = new wxButton(this, wxID_LEAVETABLE, wxT("&Leave Table"), wxDefaultPosition, wxSize(90,25), 0); - bSizer174->Add(m_buttonLeaveTable, 0, wxALL, 5); - - m_textDitchPlayer = new wxTextCtrl(this, wxID_DITCHPLAYER, wxEmptyString, wxDefaultPosition, wxSize(45,-1), wxTE_PROCESS_ENTER); - bSizer174->Add(m_textDitchPlayer, 0, wxALL, 5); - - m_checkPreFold = new wxCheckBox(this, wxID_ANY, wxT("FOLD"), wxDefaultPosition, wxSize(100,-1), 0); - - bSizer174->Add(m_checkPreFold, 0, wxALL, 5); - - m_checkPreCall = new wxCheckBox(this, wxID_ANY, wxT("CALL"), wxDefaultPosition, wxSize(100,-1), 0); - - bSizer174->Add(m_checkPreCall, 0, wxALL, 5); - - m_checkPreCallAny = new wxCheckBox(this, wxID_ANY, wxT("CALL ANY"), wxDefaultPosition, wxSize(100,-1), 0); - - bSizer174->Add(m_checkPreCallAny, 0, wxALL, 5); - - m_checkPreRaise = new wxCheckBox(this, wxID_ANY, wxT("RAISE"), wxDefaultPosition, wxSize(100,-1), 0); - - bSizer174->Add(m_checkPreRaise, 0, wxALL, 5); - - m_checkPreRaiseAny = new wxCheckBox(this, wxID_ANY, wxT("RAISE ANY"), wxDefaultPosition, wxSize(100,-1), 0); - - bSizer174->Add(m_checkPreRaiseAny, 0, wxALL, 5); - - this->SetSizer(bSizer174); - this->Layout(); - m_statusBar = this->CreateStatusBar(1, wxST_SIZEGRIP, wxID_ANY); - - // Connect Events - this->Connect(wxEVT_CLOSE_WINDOW, wxCloseEventHandler(CPokerDialogBase::OnClose)); - this->Connect(wxEVT_LEFT_DOWN, wxMouseEventHandler(CPokerDialogBase::OnMouseEvents)); - this->Connect(wxEVT_LEFT_UP, wxMouseEventHandler(CPokerDialogBase::OnMouseEvents)); - this->Connect(wxEVT_MIDDLE_DOWN, wxMouseEventHandler(CPokerDialogBase::OnMouseEvents)); - this->Connect(wxEVT_MIDDLE_UP, wxMouseEventHandler(CPokerDialogBase::OnMouseEvents)); - this->Connect(wxEVT_RIGHT_DOWN, wxMouseEventHandler(CPokerDialogBase::OnMouseEvents)); - this->Connect(wxEVT_RIGHT_UP, wxMouseEventHandler(CPokerDialogBase::OnMouseEvents)); - this->Connect(wxEVT_MOTION, wxMouseEventHandler(CPokerDialogBase::OnMouseEvents)); - this->Connect(wxEVT_LEFT_DCLICK, wxMouseEventHandler(CPokerDialogBase::OnMouseEvents)); - this->Connect(wxEVT_MIDDLE_DCLICK, wxMouseEventHandler(CPokerDialogBase::OnMouseEvents)); - this->Connect(wxEVT_RIGHT_DCLICK, wxMouseEventHandler(CPokerDialogBase::OnMouseEvents)); - this->Connect(wxEVT_LEAVE_WINDOW, wxMouseEventHandler(CPokerDialogBase::OnMouseEvents)); - this->Connect(wxEVT_ENTER_WINDOW, wxMouseEventHandler(CPokerDialogBase::OnMouseEvents)); - this->Connect(wxEVT_MOUSEWHEEL, wxMouseEventHandler(CPokerDialogBase::OnMouseEvents)); - this->Connect(wxEVT_PAINT, wxPaintEventHandler(CPokerDialogBase::OnPaint)); - this->Connect(wxEVT_SIZE, wxSizeEventHandler(CPokerDialogBase::OnSize)); - m_checkSitOut->Connect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler(CPokerDialogBase::OnCheckSitOut), NULL, this); - m_buttonDealHand->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CPokerDialogBase::OnButtonDealHand), NULL, this); - m_buttonFold->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CPokerDialogBase::OnButtonFold), NULL, this); - m_buttonCall->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CPokerDialogBase::OnButtonCall), NULL, this); - m_buttonRaise->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CPokerDialogBase::OnButtonRaise), NULL, this); - m_buttonLeaveTable->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CPokerDialogBase::OnButtonLeaveTable), NULL, this); - m_textDitchPlayer->Connect(wxEVT_COMMAND_TEXT_ENTER, wxCommandEventHandler(CPokerDialogBase::OnDitchPlayer), NULL, this); - m_checkPreFold->Connect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler(CPokerDialogBase::OnCheckPreFold), NULL, this); - m_checkPreCall->Connect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler(CPokerDialogBase::OnCheckPreCall), NULL, this); - m_checkPreCallAny->Connect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler(CPokerDialogBase::OnCheckPreCallAny), NULL, this); - m_checkPreRaise->Connect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler(CPokerDialogBase::OnCheckPreRaise), NULL, this); - m_checkPreRaiseAny->Connect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler(CPokerDialogBase::OnCheckPreRaiseAny), NULL, this); + this->SetSizeHints( wxDefaultSize, wxDefaultSize ); + + wxBoxSizer* bSizer174; + bSizer174 = new wxBoxSizer( wxVERTICAL ); + + m_checkSitOut = new wxCheckBox( this, wxID_ANY, wxT("Deal Me Out"), wxDefaultPosition, wxDefaultSize, 0 ); + + bSizer174->Add( m_checkSitOut, 0, wxALL, 5 ); + + m_buttonDealHand = new wxButton( this, wxID_DEALHAND, wxT("&Deal Hand"), wxDefaultPosition, wxSize( 150,25 ), 0 ); + bSizer174->Add( m_buttonDealHand, 0, wxALL, 5 ); + + m_buttonFold = new wxButton( this, wxID_FOLD, wxT("&Fold"), wxDefaultPosition, wxSize( 80,25 ), 0 ); + bSizer174->Add( m_buttonFold, 0, wxALL, 5 ); + + m_buttonCall = new wxButton( this, wxID_CALL, wxT("&Call"), wxDefaultPosition, wxSize( 80,25 ), 0 ); + bSizer174->Add( m_buttonCall, 0, wxALL, 5 ); + + m_buttonRaise = new wxButton( this, wxID_RAISE, wxT("&Raise"), wxDefaultPosition, wxSize( 80,25 ), 0 ); + bSizer174->Add( m_buttonRaise, 0, wxALL, 5 ); + + m_buttonLeaveTable = new wxButton( this, wxID_LEAVETABLE, wxT("&Leave Table"), wxDefaultPosition, wxSize( 90,25 ), 0 ); + bSizer174->Add( m_buttonLeaveTable, 0, wxALL, 5 ); + + m_textDitchPlayer = new wxTextCtrl( this, wxID_DITCHPLAYER, wxEmptyString, wxDefaultPosition, wxSize( 45,-1 ), wxTE_PROCESS_ENTER ); + bSizer174->Add( m_textDitchPlayer, 0, wxALL, 5 ); + + m_checkPreFold = new wxCheckBox( this, wxID_ANY, wxT("FOLD"), wxDefaultPosition, wxSize( 100,-1 ), 0 ); + + bSizer174->Add( m_checkPreFold, 0, wxALL, 5 ); + + m_checkPreCall = new wxCheckBox( this, wxID_ANY, wxT("CALL"), wxDefaultPosition, wxSize( 100,-1 ), 0 ); + + bSizer174->Add( m_checkPreCall, 0, wxALL, 5 ); + + m_checkPreCallAny = new wxCheckBox( this, wxID_ANY, wxT("CALL ANY"), wxDefaultPosition, wxSize( 100,-1 ), 0 ); + + bSizer174->Add( m_checkPreCallAny, 0, wxALL, 5 ); + + m_checkPreRaise = new wxCheckBox( this, wxID_ANY, wxT("RAISE"), wxDefaultPosition, wxSize( 100,-1 ), 0 ); + + bSizer174->Add( m_checkPreRaise, 0, wxALL, 5 ); + + m_checkPreRaiseAny = new wxCheckBox( this, wxID_ANY, wxT("RAISE ANY"), wxDefaultPosition, wxSize( 100,-1 ), 0 ); + + bSizer174->Add( m_checkPreRaiseAny, 0, wxALL, 5 ); + + this->SetSizer( bSizer174 ); + this->Layout(); + m_statusBar = this->CreateStatusBar( 1, wxST_SIZEGRIP, wxID_ANY ); + + // Connect Events + this->Connect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( CPokerDialogBase::OnClose ) ); + this->Connect( wxEVT_LEFT_DOWN, wxMouseEventHandler( CPokerDialogBase::OnMouseEvents ) ); + this->Connect( wxEVT_LEFT_UP, wxMouseEventHandler( CPokerDialogBase::OnMouseEvents ) ); + this->Connect( wxEVT_MIDDLE_DOWN, wxMouseEventHandler( CPokerDialogBase::OnMouseEvents ) ); + this->Connect( wxEVT_MIDDLE_UP, wxMouseEventHandler( CPokerDialogBase::OnMouseEvents ) ); + this->Connect( wxEVT_RIGHT_DOWN, wxMouseEventHandler( CPokerDialogBase::OnMouseEvents ) ); + this->Connect( wxEVT_RIGHT_UP, wxMouseEventHandler( CPokerDialogBase::OnMouseEvents ) ); + this->Connect( wxEVT_MOTION, wxMouseEventHandler( CPokerDialogBase::OnMouseEvents ) ); + this->Connect( wxEVT_LEFT_DCLICK, wxMouseEventHandler( CPokerDialogBase::OnMouseEvents ) ); + this->Connect( wxEVT_MIDDLE_DCLICK, wxMouseEventHandler( CPokerDialogBase::OnMouseEvents ) ); + this->Connect( wxEVT_RIGHT_DCLICK, wxMouseEventHandler( CPokerDialogBase::OnMouseEvents ) ); + this->Connect( wxEVT_LEAVE_WINDOW, wxMouseEventHandler( CPokerDialogBase::OnMouseEvents ) ); + this->Connect( wxEVT_ENTER_WINDOW, wxMouseEventHandler( CPokerDialogBase::OnMouseEvents ) ); + this->Connect( wxEVT_MOUSEWHEEL, wxMouseEventHandler( CPokerDialogBase::OnMouseEvents ) ); + this->Connect( wxEVT_PAINT, wxPaintEventHandler( CPokerDialogBase::OnPaint ) ); + this->Connect( wxEVT_SIZE, wxSizeEventHandler( CPokerDialogBase::OnSize ) ); + m_checkSitOut->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( CPokerDialogBase::OnCheckSitOut ), NULL, this ); + m_buttonDealHand->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CPokerDialogBase::OnButtonDealHand ), NULL, this ); + m_buttonFold->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CPokerDialogBase::OnButtonFold ), NULL, this ); + m_buttonCall->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CPokerDialogBase::OnButtonCall ), NULL, this ); + m_buttonRaise->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CPokerDialogBase::OnButtonRaise ), NULL, this ); + m_buttonLeaveTable->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CPokerDialogBase::OnButtonLeaveTable ), NULL, this ); + m_textDitchPlayer->Connect( wxEVT_COMMAND_TEXT_ENTER, wxCommandEventHandler( CPokerDialogBase::OnDitchPlayer ), NULL, this ); + m_checkPreFold->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( CPokerDialogBase::OnCheckPreFold ), NULL, this ); + m_checkPreCall->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( CPokerDialogBase::OnCheckPreCall ), NULL, this ); + m_checkPreCallAny->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( CPokerDialogBase::OnCheckPreCallAny ), NULL, this ); + m_checkPreRaise->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( CPokerDialogBase::OnCheckPreRaise ), NULL, this ); + m_checkPreRaiseAny->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( CPokerDialogBase::OnCheckPreRaiseAny ), NULL, this ); } CPokerDialogBase::~CPokerDialogBase() { - // Disconnect Events - this->Disconnect(wxEVT_CLOSE_WINDOW, wxCloseEventHandler(CPokerDialogBase::OnClose)); - this->Disconnect(wxEVT_LEFT_DOWN, wxMouseEventHandler(CPokerDialogBase::OnMouseEvents)); - this->Disconnect(wxEVT_LEFT_UP, wxMouseEventHandler(CPokerDialogBase::OnMouseEvents)); - this->Disconnect(wxEVT_MIDDLE_DOWN, wxMouseEventHandler(CPokerDialogBase::OnMouseEvents)); - this->Disconnect(wxEVT_MIDDLE_UP, wxMouseEventHandler(CPokerDialogBase::OnMouseEvents)); - this->Disconnect(wxEVT_RIGHT_DOWN, wxMouseEventHandler(CPokerDialogBase::OnMouseEvents)); - this->Disconnect(wxEVT_RIGHT_UP, wxMouseEventHandler(CPokerDialogBase::OnMouseEvents)); - this->Disconnect(wxEVT_MOTION, wxMouseEventHandler(CPokerDialogBase::OnMouseEvents)); - this->Disconnect(wxEVT_LEFT_DCLICK, wxMouseEventHandler(CPokerDialogBase::OnMouseEvents)); - this->Disconnect(wxEVT_MIDDLE_DCLICK, wxMouseEventHandler(CPokerDialogBase::OnMouseEvents)); - this->Disconnect(wxEVT_RIGHT_DCLICK, wxMouseEventHandler(CPokerDialogBase::OnMouseEvents)); - this->Disconnect(wxEVT_LEAVE_WINDOW, wxMouseEventHandler(CPokerDialogBase::OnMouseEvents)); - this->Disconnect(wxEVT_ENTER_WINDOW, wxMouseEventHandler(CPokerDialogBase::OnMouseEvents)); - this->Disconnect(wxEVT_MOUSEWHEEL, wxMouseEventHandler(CPokerDialogBase::OnMouseEvents)); - this->Disconnect(wxEVT_PAINT, wxPaintEventHandler(CPokerDialogBase::OnPaint)); - this->Disconnect(wxEVT_SIZE, wxSizeEventHandler(CPokerDialogBase::OnSize)); - m_checkSitOut->Disconnect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler(CPokerDialogBase::OnCheckSitOut), NULL, this); - m_buttonDealHand->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CPokerDialogBase::OnButtonDealHand), NULL, this); - m_buttonFold->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CPokerDialogBase::OnButtonFold), NULL, this); - m_buttonCall->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CPokerDialogBase::OnButtonCall), NULL, this); - m_buttonRaise->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CPokerDialogBase::OnButtonRaise), NULL, this); - m_buttonLeaveTable->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CPokerDialogBase::OnButtonLeaveTable), NULL, this); - m_textDitchPlayer->Disconnect(wxEVT_COMMAND_TEXT_ENTER, wxCommandEventHandler(CPokerDialogBase::OnDitchPlayer), NULL, this); - m_checkPreFold->Disconnect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler(CPokerDialogBase::OnCheckPreFold), NULL, this); - m_checkPreCall->Disconnect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler(CPokerDialogBase::OnCheckPreCall), NULL, this); - m_checkPreCallAny->Disconnect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler(CPokerDialogBase::OnCheckPreCallAny), NULL, this); - m_checkPreRaise->Disconnect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler(CPokerDialogBase::OnCheckPreRaise), NULL, this); - m_checkPreRaiseAny->Disconnect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler(CPokerDialogBase::OnCheckPreRaiseAny), NULL, this); + // Disconnect Events + this->Disconnect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( CPokerDialogBase::OnClose ) ); + this->Disconnect( wxEVT_LEFT_DOWN, wxMouseEventHandler( CPokerDialogBase::OnMouseEvents ) ); + this->Disconnect( wxEVT_LEFT_UP, wxMouseEventHandler( CPokerDialogBase::OnMouseEvents ) ); + this->Disconnect( wxEVT_MIDDLE_DOWN, wxMouseEventHandler( CPokerDialogBase::OnMouseEvents ) ); + this->Disconnect( wxEVT_MIDDLE_UP, wxMouseEventHandler( CPokerDialogBase::OnMouseEvents ) ); + this->Disconnect( wxEVT_RIGHT_DOWN, wxMouseEventHandler( CPokerDialogBase::OnMouseEvents ) ); + this->Disconnect( wxEVT_RIGHT_UP, wxMouseEventHandler( CPokerDialogBase::OnMouseEvents ) ); + this->Disconnect( wxEVT_MOTION, wxMouseEventHandler( CPokerDialogBase::OnMouseEvents ) ); + this->Disconnect( wxEVT_LEFT_DCLICK, wxMouseEventHandler( CPokerDialogBase::OnMouseEvents ) ); + this->Disconnect( wxEVT_MIDDLE_DCLICK, wxMouseEventHandler( CPokerDialogBase::OnMouseEvents ) ); + this->Disconnect( wxEVT_RIGHT_DCLICK, wxMouseEventHandler( CPokerDialogBase::OnMouseEvents ) ); + this->Disconnect( wxEVT_LEAVE_WINDOW, wxMouseEventHandler( CPokerDialogBase::OnMouseEvents ) ); + this->Disconnect( wxEVT_ENTER_WINDOW, wxMouseEventHandler( CPokerDialogBase::OnMouseEvents ) ); + this->Disconnect( wxEVT_MOUSEWHEEL, wxMouseEventHandler( CPokerDialogBase::OnMouseEvents ) ); + this->Disconnect( wxEVT_PAINT, wxPaintEventHandler( CPokerDialogBase::OnPaint ) ); + this->Disconnect( wxEVT_SIZE, wxSizeEventHandler( CPokerDialogBase::OnSize ) ); + m_checkSitOut->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( CPokerDialogBase::OnCheckSitOut ), NULL, this ); + m_buttonDealHand->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CPokerDialogBase::OnButtonDealHand ), NULL, this ); + m_buttonFold->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CPokerDialogBase::OnButtonFold ), NULL, this ); + m_buttonCall->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CPokerDialogBase::OnButtonCall ), NULL, this ); + m_buttonRaise->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CPokerDialogBase::OnButtonRaise ), NULL, this ); + m_buttonLeaveTable->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CPokerDialogBase::OnButtonLeaveTable ), NULL, this ); + m_textDitchPlayer->Disconnect( wxEVT_COMMAND_TEXT_ENTER, wxCommandEventHandler( CPokerDialogBase::OnDitchPlayer ), NULL, this ); + m_checkPreFold->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( CPokerDialogBase::OnCheckPreFold ), NULL, this ); + m_checkPreCall->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( CPokerDialogBase::OnCheckPreCall ), NULL, this ); + m_checkPreCallAny->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( CPokerDialogBase::OnCheckPreCallAny ), NULL, this ); + m_checkPreRaise->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( CPokerDialogBase::OnCheckPreRaise ), NULL, this ); + m_checkPreRaiseAny->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( CPokerDialogBase::OnCheckPreRaiseAny ), 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) +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, wxT("OK"), wxDefaultPosition, wxSize(-1,-1), 0); - m_buttonOK->SetMinSize(wxSize(85,25)); - - bSizer80->Add(m_buttonOK, 0, wxALL, 5); - - m_buttonCancel = new wxButton(this, wxID_CANCEL, wxT("Cancel"), wxDefaultPosition, wxDefaultSize, 0); - m_buttonCancel->SetMinSize(wxSize(85,25)); + 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, wxT("OK"), wxDefaultPosition, wxSize( -1,-1 ), 0 ); + m_buttonOK->SetMinSize( wxSize( 85,25 ) ); + + bSizer80->Add( m_buttonOK, 0, wxALL, 5 ); + + m_buttonCancel = new wxButton( this, wxID_CANCEL, wxT("Cancel"), wxDefaultPosition, wxDefaultSize, 0 ); + m_buttonCancel->SetMinSize( wxSize( 85,25 ) ); + + bSizer80->Add( m_buttonCancel, 0, wxALL, 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 ); +} - bSizer80->Add(m_buttonCancel, 0, wxALL, 5); +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 ); +} - bSizer79->Add(bSizer80, 0, wxEXPAND, 5); +COptionsPanelBitcoinBase::COptionsPanelBitcoinBase( wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style ) : wxPanel( parent, id, pos, size, style ) +{ + wxBoxSizer* bSizer62; + bSizer62 = new wxBoxSizer( wxVERTICAL ); + + + bSizer62->Add( 0, 20, 0, wxEXPAND, 5 ); + + m_staticText32 = new wxStaticText( this, wxID_ANY, wxT("Optional transaction fee you give to the nodes that process your transactions."), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticText32->Wrap( -1 ); + bSizer62->Add( m_staticText32, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 ); + + wxBoxSizer* bSizer56; + bSizer56 = new wxBoxSizer( wxHORIZONTAL ); + + m_staticText31 = new wxStaticText( this, wxID_ANY, wxT("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( this, wxID_TRANSACTIONFEE, wxEmptyString, wxDefaultPosition, wxSize( 70,-1 ), 0 ); + bSizer56->Add( m_textCtrlTransactionFee, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); + + bSizer62->Add( bSizer56, 0, wxEXPAND, 5 ); + + this->SetSizer( bSizer62 ); + this->Layout(); + bSizer62->Fit( this ); + + // Connect Events + m_textCtrlTransactionFee->Connect( wxEVT_KILL_FOCUS, wxFocusEventHandler( COptionsPanelBitcoinBase::OnKillFocusTransactionFee ), NULL, this ); +} - this->SetSizer(bSizer79); - this->Layout(); +COptionsPanelBitcoinBase::~COptionsPanelBitcoinBase() +{ + // Disconnect Events + m_textCtrlTransactionFee->Disconnect( wxEVT_KILL_FOCUS, wxFocusEventHandler( COptionsPanelBitcoinBase::OnKillFocusTransactionFee ), NULL, this ); +} - // 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); +COptionsPanelUIBase::COptionsPanelUIBase( wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style ) : wxPanel( parent, id, pos, size, style ) +{ + wxBoxSizer* bSizer57; + bSizer57 = new wxBoxSizer( wxVERTICAL ); + + + bSizer57->Add( 0, 20, 1, wxEXPAND, 5 ); + + m_checkMinToTray = new wxCheckBox( this, wxID_MINTOTRAY, wxT("Minimize to tray"), wxDefaultPosition, wxDefaultSize, 0 ); + + bSizer57->Add( m_checkMinToTray, 0, wxALL, 5 ); + + m_checkCloseToTray = new wxCheckBox( this, wxID_ANY, wxT("Close to tray"), wxDefaultPosition, wxDefaultSize, 0 ); + + bSizer57->Add( m_checkCloseToTray, 0, wxALL, 5 ); + + m_checkStartOnSysBoot = new wxCheckBox( this, wxID_ANY, wxT("Start on system boot"), wxDefaultPosition, wxDefaultSize, 0 ); + + bSizer57->Add( m_checkStartOnSysBoot, 0, wxALL, 5 ); + + m_checkAskBeforeClosing = new wxCheckBox( this, wxID_ANY, wxT("Ask before closing"), wxDefaultPosition, wxDefaultSize, 0 ); + + bSizer57->Add( m_checkAskBeforeClosing, 0, wxALL, 5 ); + + m_checkAlwaysShowTray = new wxCheckBox( this, wxID_ANY, wxT("Always show tray icon"), wxDefaultPosition, wxDefaultSize, 0 ); + + bSizer57->Add( m_checkAlwaysShowTray, 0, wxALL, 5 ); + + this->SetSizer( bSizer57 ); + this->Layout(); + bSizer57->Fit( this ); } -CGetTextFromUserDialogBase::~CGetTextFromUserDialogBase() +COptionsPanelUIBase::~COptionsPanelUIBase() { - // 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/uibase.h b/uibase.h index bfcd8eccb8..61e0552283 100644 --- a/uibase.h +++ b/uibase.h @@ -1,7 +1,3 @@ -// Copyright (c) 2009 Satoshi Nakamoto -// Distributed under the MIT/X11 software license, see the accompanying -// file license.txt or http://www.opensource.org/licenses/mit-license.php. - /////////////////////////////////////////////////////////////////////////// // C++ code generated with wxFormBuilder (version Apr 16 2008) // http://www.wxformbuilder.org/ @@ -34,11 +30,12 @@ #include #include #include +#include +#include #include #include #include #include -#include #include /////////////////////////////////////////////////////////////////////////// @@ -50,674 +47,721 @@ #define wxID_TEXTCTRLADDRESS 1004 #define wxID_BUTTONCOPY 1005 #define wxID_BUTTONCHANGE 1006 -#define wxID_TRANSACTIONFEE 1007 -#define wxID_TEXTCTRLPAYTO 1008 -#define wxID_BUTTONPASTE 1009 -#define wxID_BUTTONADDRESSBOOK 1010 -#define wxID_TEXTCTRLAMOUNT 1011 -#define wxID_CHOICETRANSFERTYPE 1012 -#define wxID_LISTCTRL 1013 -#define wxID_BUTTONRENAME 1014 -#define wxID_BUTTONNEW 1015 -#define wxID_BUTTONEDIT 1016 -#define wxID_BUTTONDELETE 1017 -#define wxID_DEL0 1018 -#define wxID_DEL1 1019 -#define wxID_DEL2 1020 -#define wxID_DEL3 1021 -#define wxID_DEL4 1022 -#define wxID_DEL5 1023 -#define wxID_DEL6 1024 -#define wxID_DEL7 1025 -#define wxID_DEL8 1026 -#define wxID_DEL9 1027 -#define wxID_DEL10 1028 -#define wxID_DEL11 1029 -#define wxID_DEL12 1030 -#define wxID_DEL13 1031 -#define wxID_DEL14 1032 -#define wxID_DEL15 1033 -#define wxID_DEL16 1034 -#define wxID_DEL17 1035 -#define wxID_DEL18 1036 -#define wxID_DEL19 1037 -#define wxID_BUTTONPREVIEW 1038 -#define wxID_BUTTONSAMPLE 1039 -#define wxID_CANCEL2 1040 -#define wxID_BUTTONBACK 1041 -#define wxID_BUTTONNEXT 1042 -#define wxID_SUBMIT 1043 -#define wxID_OPENNEWTABLE 1044 -#define wxID_DEALHAND 1045 -#define wxID_FOLD 1046 -#define wxID_CALL 1047 -#define wxID_RAISE 1048 -#define wxID_LEAVETABLE 1049 -#define wxID_DITCHPLAYER 1050 -#define wxID_TEXTCTRL 1051 +#define wxID_TEXTCTRLPAYTO 1007 +#define wxID_BUTTONPASTE 1008 +#define wxID_BUTTONADDRESSBOOK 1009 +#define wxID_TEXTCTRLAMOUNT 1010 +#define wxID_CHOICETRANSFERTYPE 1011 +#define wxID_LISTCTRL 1012 +#define wxID_BUTTONRENAME 1013 +#define wxID_BUTTONNEW 1014 +#define wxID_BUTTONEDIT 1015 +#define wxID_BUTTONDELETE 1016 +#define wxID_DEL0 1017 +#define wxID_DEL1 1018 +#define wxID_DEL2 1019 +#define wxID_DEL3 1020 +#define wxID_DEL4 1021 +#define wxID_DEL5 1022 +#define wxID_DEL6 1023 +#define wxID_DEL7 1024 +#define wxID_DEL8 1025 +#define wxID_DEL9 1026 +#define wxID_DEL10 1027 +#define wxID_DEL11 1028 +#define wxID_DEL12 1029 +#define wxID_DEL13 1030 +#define wxID_DEL14 1031 +#define wxID_DEL15 1032 +#define wxID_DEL16 1033 +#define wxID_DEL17 1034 +#define wxID_DEL18 1035 +#define wxID_DEL19 1036 +#define wxID_BUTTONPREVIEW 1037 +#define wxID_BUTTONSAMPLE 1038 +#define wxID_CANCEL2 1039 +#define wxID_BUTTONBACK 1040 +#define wxID_BUTTONNEXT 1041 +#define wxID_SUBMIT 1042 +#define wxID_OPENNEWTABLE 1043 +#define wxID_DEALHAND 1044 +#define wxID_FOLD 1045 +#define wxID_CALL 1046 +#define wxID_RAISE 1047 +#define wxID_LEAVETABLE 1048 +#define wxID_DITCHPLAYER 1049 +#define wxID_TEXTCTRL 1050 +#define wxID_TRANSACTIONFEE 1051 +#define wxID_MINTOTRAY 1052 /////////////////////////////////////////////////////////////////////////////// /// Class CMainFrameBase /////////////////////////////////////////////////////////////////////////////// -class CMainFrameBase : public wxFrame +class CMainFrameBase : public wxFrame { -private: - -protected: - wxMenuBar* m_menubar; - wxMenu* m_menuFile; - wxMenu* m_menuHelp; - wxToolBar* m_toolBar; - wxStatusBar* m_statusBar; - - wxStaticText* m_staticText32; - wxTextCtrl* m_textCtrlAddress; - wxButton* m_buttonCopy; - wxButton* m_button91; - - wxPanel* m_panel14; - wxStaticText* m_staticText41; - wxStaticText* m_staticTextBalance; - - wxChoice* m_choiceFilter; - wxNotebook* m_notebook; - wxPanel* m_panel7; - wxPanel* m_panel9; - wxPanel* m_panel8; - wxPanel* m_panel10; - wxPanel* m_panel11; - - // Virtual event handlers, overide them in your derived class - virtual void OnClose(wxCloseEvent& 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 OnMenuOptionsGenerate(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 OnButtonCopy(wxCommandEvent& event){ event.Skip(); } - virtual void OnButtonChange(wxCommandEvent& event){ event.Skip(); } - virtual void OnListColBeginDrag(wxListEvent& event){ event.Skip(); } - virtual void OnListItemActivatedAllTransactions(wxListEvent& event){ event.Skip(); } - virtual void OnPaintListCtrl(wxPaintEvent& event){ event.Skip(); } - virtual void OnListItemActivatedOrdersSent(wxListEvent& event){ event.Skip(); } - virtual void OnListItemActivatedProductsSent(wxListEvent& event){ event.Skip(); } - virtual void OnListItemActivatedOrdersReceived(wxListEvent& event){ event.Skip(); } - - -public: - wxMenu* m_menuOptions; - wxListCtrl* m_listCtrl; - wxListCtrl* m_listCtrlEscrows; - wxListCtrl* m_listCtrlOrdersSent; - wxListCtrl* m_listCtrlProductsSent; - wxListCtrl* m_listCtrlOrdersReceived; - CMainFrameBase(wxWindow* parent, wxWindowID id = wxID_MAINFRAME, const wxString& title = wxT("Bitcoin"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize(705,484), long style = wxDEFAULT_FRAME_STYLE|wxRESIZE_BORDER|wxTAB_TRAVERSAL); - ~CMainFrameBase(); - + private: + + protected: + wxMenuBar* m_menubar; + wxMenu* m_menuFile; + wxMenu* m_menuHelp; + wxToolBar* m_toolBar; + wxStatusBar* m_statusBar; + + wxStaticText* m_staticText32; + wxTextCtrl* m_textCtrlAddress; + wxButton* m_buttonCopy; + wxButton* m_button91; + + wxPanel* m_panel14; + wxStaticText* m_staticText41; + wxStaticText* m_staticTextBalance; + + wxChoice* m_choiceFilter; + wxNotebook* m_notebook; + wxPanel* m_panel7; + wxPanel* m_panel9; + wxPanel* m_panel8; + wxPanel* m_panel10; + wxPanel* m_panel11; + + // 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 OnMenuOptionsGenerate( wxCommandEvent& event ){ event.Skip(); } + virtual void OnUpdateMenuGenerate( wxUpdateUIEvent& 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 OnButtonCopy( wxCommandEvent& event ){ event.Skip(); } + virtual void OnButtonChange( wxCommandEvent& event ){ event.Skip(); } + virtual void OnListColBeginDrag( wxListEvent& event ){ event.Skip(); } + virtual void OnListItemActivatedAllTransactions( wxListEvent& event ){ event.Skip(); } + virtual void OnPaintListCtrl( wxPaintEvent& event ){ event.Skip(); } + virtual void OnListItemActivatedOrdersSent( wxListEvent& event ){ event.Skip(); } + virtual void OnListItemActivatedProductsSent( wxListEvent& event ){ event.Skip(); } + virtual void OnListItemActivatedOrdersReceived( wxListEvent& event ){ event.Skip(); } + + + public: + wxMenu* m_menuOptions; + wxListCtrl* m_listCtrl; + wxListCtrl* m_listCtrlEscrows; + wxListCtrl* m_listCtrlOrdersSent; + wxListCtrl* m_listCtrlProductsSent; + wxListCtrl* m_listCtrlOrdersReceived; + CMainFrameBase( wxWindow* parent, wxWindowID id = wxID_MAINFRAME, const wxString& title = wxT("Bitcoin"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 705,484 ), long style = wxDEFAULT_FRAME_STYLE|wxRESIZE_BORDER|wxTAB_TRAVERSAL ); + ~CMainFrameBase(); + }; /////////////////////////////////////////////////////////////////////////////// /// Class CTxDetailsDialogBase /////////////////////////////////////////////////////////////////////////////// -class CTxDetailsDialogBase : public wxDialog +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 = wxT("Transaction Details"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize(620,450), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER); - ~CTxDetailsDialogBase(); - + 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 = wxT("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 +class COptionsDialogBase : public wxDialog { -private: - -protected: - - wxStaticText* m_staticText32; - wxStaticText* m_staticText31; - wxTextCtrl* m_textCtrlTransactionFee; - wxButton* m_buttonOK; - wxButton* m_buttonCancel; - - // Virtual event handlers, overide them in your derived class - virtual void OnKillFocusTransactionFee(wxFocusEvent& event){ event.Skip(); } - virtual void OnButtonOK(wxCommandEvent& event){ event.Skip(); } - virtual void OnButtonCancel(wxCommandEvent& event){ event.Skip(); } - - -public: - COptionsDialogBase(wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxT("Options"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize(500,261), long style = wxDEFAULT_DIALOG_STYLE); - ~COptionsDialogBase(); - + private: + + protected: + wxBoxSizer* panelSizer; + wxTreeCtrl* m_treeCtrl; + wxStaticLine* m_staticline1; + wxButton* m_buttonOK; + wxButton* m_buttonCancel; + wxButton* m_buttonApply; + + // Virtual event handlers, overide them in your derived class + virtual void MenuSelChanged( wxTreeEvent& event ){ event.Skip(); } + virtual void OnButtonOK( wxCommandEvent& event ){ event.Skip(); } + virtual void OnButtonCancel( wxCommandEvent& event ){ event.Skip(); } + + + public: + COptionsDialogBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxT("Options"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 555,377 ), long style = wxDEFAULT_DIALOG_STYLE ); + ~COptionsDialogBase(); + }; /////////////////////////////////////////////////////////////////////////////// /// Class CAboutDialogBase /////////////////////////////////////////////////////////////////////////////// -class CAboutDialogBase : public wxDialog +class CAboutDialogBase : public wxDialog { -private: - -protected: - - - 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 = wxT("About Bitcoin"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize(507,298), long style = wxDEFAULT_DIALOG_STYLE); - ~CAboutDialogBase(); - + private: + + protected: + + + 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 = wxT("About Bitcoin"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 507,298 ), long style = wxDEFAULT_DIALOG_STYLE ); + ~CAboutDialogBase(); + }; /////////////////////////////////////////////////////////////////////////////// /// Class CSendDialogBase /////////////////////////////////////////////////////////////////////////////// -class CSendDialogBase : public wxDialog +class CSendDialogBase : public wxDialog { -private: - -protected: - - - wxStaticText* m_staticText14; - - 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; - - - wxStaticText* m_staticTextFrom; - wxTextCtrl* m_textCtrlFrom; - wxStaticText* m_staticTextMessage; - wxTextCtrl* m_textCtrlMessage; - - 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 = wxT("Send Coins"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize(675,312), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER); - ~CSendDialogBase(); - + private: + + protected: + + + wxStaticText* m_staticText14; + + 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; + + + wxStaticText* m_staticTextFrom; + wxTextCtrl* m_textCtrlFrom; + wxStaticText* m_staticTextMessage; + wxTextCtrl* m_textCtrlMessage; + + 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 = wxT("Send Coins"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 675,312 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER ); + ~CSendDialogBase(); + }; /////////////////////////////////////////////////////////////////////////////// /// Class CSendingDialogBase /////////////////////////////////////////////////////////////////////////////// -class CSendingDialogBase : public wxDialog +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 = wxT("Sending..."), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize(442,151), long style = wxDEFAULT_DIALOG_STYLE); - ~CSendingDialogBase(); - + 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 = wxT("Sending..."), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 442,151 ), long style = wxDEFAULT_DIALOG_STYLE ); + ~CSendingDialogBase(); + }; /////////////////////////////////////////////////////////////////////////////// /// Class CYourAddressDialogBase /////////////////////////////////////////////////////////////////////////////// -class CYourAddressDialogBase : public wxDialog +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 = wxT("Your Bitcoin Addresses"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize(610,390), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER); - ~CYourAddressDialogBase(); - + 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 = wxT("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 +class CAddressBookDialogBase : public wxDialog { -private: - -protected: - - wxStaticText* m_staticText55; - wxListCtrl* m_listCtrl; - - wxButton* m_buttonEdit; - wxButton* m_buttonNew; - wxButton* m_buttonDelete; - wxButton* m_buttonOK; - - // 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 OnButtonEdit(wxCommandEvent& event){ event.Skip(); } - virtual void OnButtonNew(wxCommandEvent& event){ event.Skip(); } - virtual void OnButtonDelete(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 = wxT("Address Book"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize(610,390), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER); - ~CAddressBookDialogBase(); - + private: + + protected: + + wxStaticText* m_staticText55; + wxListCtrl* m_listCtrl; + + wxButton* m_buttonEdit; + wxButton* m_buttonNew; + wxButton* m_buttonDelete; + wxButton* m_buttonOK; + + // 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 OnButtonEdit( wxCommandEvent& event ){ event.Skip(); } + virtual void OnButtonNew( wxCommandEvent& event ){ event.Skip(); } + virtual void OnButtonDelete( 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 = wxT("Address Book"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 610,390 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER ); + ~CAddressBookDialogBase(); + }; /////////////////////////////////////////////////////////////////////////////// /// Class CProductsDialogBase /////////////////////////////////////////////////////////////////////////////// -class CProductsDialogBase : public wxDialog +class CProductsDialogBase : public wxDialog { -private: - -protected: - wxComboBox* m_comboBoxCategory; - wxTextCtrl* m_textCtrlSearch; - wxButton* m_buttonSearch; - wxListCtrl* m_listCtrl; - - // Virtual event handlers, overide them in your derived class - virtual void OnCombobox(wxCommandEvent& event){ event.Skip(); } - virtual void OnKeyDown(wxKeyEvent& event){ event.Skip(); } - virtual void OnButtonSearch(wxCommandEvent& event){ event.Skip(); } - virtual void OnListItemActivated(wxListEvent& event){ event.Skip(); } - - -public: - CProductsDialogBase(wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxT("Marketplace"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize(708,535), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER); - ~CProductsDialogBase(); - + private: + + protected: + wxComboBox* m_comboBoxCategory; + wxTextCtrl* m_textCtrlSearch; + wxButton* m_buttonSearch; + wxListCtrl* m_listCtrl; + + // Virtual event handlers, overide them in your derived class + virtual void OnCombobox( wxCommandEvent& event ){ event.Skip(); } + virtual void OnKeyDown( wxKeyEvent& event ){ event.Skip(); } + virtual void OnButtonSearch( wxCommandEvent& event ){ event.Skip(); } + virtual void OnListItemActivated( wxListEvent& event ){ event.Skip(); } + + + public: + CProductsDialogBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxT("Marketplace"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 708,535 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER ); + ~CProductsDialogBase(); + }; /////////////////////////////////////////////////////////////////////////////// /// Class CEditProductDialogBase /////////////////////////////////////////////////////////////////////////////// -class CEditProductDialogBase : public wxFrame +class CEditProductDialogBase : public wxFrame { -private: - -protected: - wxScrolledWindow* m_scrolledWindow; - wxStaticText* m_staticText106; - wxComboBox* m_comboBoxCategory; - wxStaticText* m_staticText108; - wxTextCtrl* m_textCtrlTitle; - wxStaticText* m_staticText107; - wxTextCtrl* m_textCtrlPrice; - wxStaticText* m_staticText22; - wxTextCtrl* m_textCtrlDescription; - wxStaticText* m_staticText23; - wxTextCtrl* m_textCtrlInstructions; - wxStaticText* m_staticText24; - wxStaticText* m_staticText25; - - wxTextCtrl* m_textCtrlLabel0; - wxTextCtrl* m_textCtrlField0; - wxButton* m_buttonDel0; - wxTextCtrl* m_textCtrlLabel1; - wxTextCtrl* m_textCtrlField1; - wxButton* m_buttonDel1; - wxTextCtrl* m_textCtrlLabel2; - wxTextCtrl* m_textCtrlField2; - wxButton* m_buttonDel2; - wxTextCtrl* m_textCtrlLabel3; - wxTextCtrl* m_textCtrlField3; - wxButton* m_buttonDel3; - wxTextCtrl* m_textCtrlLabel4; - wxTextCtrl* m_textCtrlField4; - wxButton* m_buttonDel4; - wxTextCtrl* m_textCtrlLabel5; - wxTextCtrl* m_textCtrlField5; - wxButton* m_buttonDel5; - wxTextCtrl* m_textCtrlLabel6; - wxTextCtrl* m_textCtrlField6; - wxButton* m_buttonDel6; - wxTextCtrl* m_textCtrlLabel7; - wxTextCtrl* m_textCtrlField7; - wxButton* m_buttonDel7; - wxTextCtrl* m_textCtrlLabel8; - wxTextCtrl* m_textCtrlField8; - wxButton* m_buttonDel8; - wxTextCtrl* m_textCtrlLabel9; - wxTextCtrl* m_textCtrlField9; - wxButton* m_buttonDel9; - wxTextCtrl* m_textCtrlLabel10; - wxTextCtrl* m_textCtrlField10; - wxButton* m_buttonDel10; - wxTextCtrl* m_textCtrlLabel11; - wxTextCtrl* m_textCtrlField11; - wxButton* m_buttonDel11; - wxTextCtrl* m_textCtrlLabel12; - wxTextCtrl* m_textCtrlField12; - wxButton* m_buttonDel12; - wxTextCtrl* m_textCtrlLabel13; - wxTextCtrl* m_textCtrlField13; - wxButton* m_buttonDel13; - wxTextCtrl* m_textCtrlLabel14; - wxTextCtrl* m_textCtrlField14; - wxButton* m_buttonDel14; - wxTextCtrl* m_textCtrlLabel15; - wxTextCtrl* m_textCtrlField15; - wxButton* m_buttonDel15; - wxTextCtrl* m_textCtrlLabel16; - wxTextCtrl* m_textCtrlField16; - wxButton* m_buttonDel16; - wxTextCtrl* m_textCtrlLabel17; - wxTextCtrl* m_textCtrlField17; - wxButton* m_buttonDel17; - wxTextCtrl* m_textCtrlLabel18; - wxTextCtrl* m_textCtrlField18; - wxButton* m_buttonDel18; - wxTextCtrl* m_textCtrlLabel19; - wxTextCtrl* m_textCtrlField19; - wxButton* m_buttonDel19; - wxButton* m_buttonAddField; - wxButton* m_buttonOK; - wxButton* m_buttonPreview; - wxButton* m_buttonCancel; - - // Virtual event handlers, overide them in your derived class - virtual void OnKeyDown(wxKeyEvent& event){ event.Skip(); } - virtual void OnButtonDel0(wxCommandEvent& event){ event.Skip(); } - virtual void OnButtonDel1(wxCommandEvent& event){ event.Skip(); } - virtual void OnButtonDel2(wxCommandEvent& event){ event.Skip(); } - virtual void OnButtonDel3(wxCommandEvent& event){ event.Skip(); } - virtual void OnButtonDel4(wxCommandEvent& event){ event.Skip(); } - virtual void OnButtonDel5(wxCommandEvent& event){ event.Skip(); } - virtual void OnButtonDel6(wxCommandEvent& event){ event.Skip(); } - virtual void OnButtonDel7(wxCommandEvent& event){ event.Skip(); } - virtual void OnButtonDel8(wxCommandEvent& event){ event.Skip(); } - virtual void OnButtonDel9(wxCommandEvent& event){ event.Skip(); } - virtual void OnButtonDel10(wxCommandEvent& event){ event.Skip(); } - virtual void OnButtonDel11(wxCommandEvent& event){ event.Skip(); } - virtual void OnButtonDel12(wxCommandEvent& event){ event.Skip(); } - virtual void OnButtonDel13(wxCommandEvent& event){ event.Skip(); } - virtual void OnButtonDel14(wxCommandEvent& event){ event.Skip(); } - virtual void OnButtonDel15(wxCommandEvent& event){ event.Skip(); } - virtual void OnButtonDel16(wxCommandEvent& event){ event.Skip(); } - virtual void OnButtonDel17(wxCommandEvent& event){ event.Skip(); } - virtual void OnButtonDel18(wxCommandEvent& event){ event.Skip(); } - virtual void OnButtonDel19(wxCommandEvent& event){ event.Skip(); } - virtual void OnButtonAddField(wxCommandEvent& event){ event.Skip(); } - virtual void OnButtonSend(wxCommandEvent& event){ event.Skip(); } - virtual void OnButtonPreview(wxCommandEvent& event){ event.Skip(); } - virtual void OnButtonCancel(wxCommandEvent& event){ event.Skip(); } - - -public: - wxFlexGridSizer* fgSizer5; - CEditProductDialogBase(wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxT("Edit Product"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize(660,640), long style = wxDEFAULT_FRAME_STYLE|wxRESIZE_BORDER|wxTAB_TRAVERSAL); - ~CEditProductDialogBase(); - + private: + + protected: + wxScrolledWindow* m_scrolledWindow; + wxStaticText* m_staticText106; + wxComboBox* m_comboBoxCategory; + wxStaticText* m_staticText108; + wxTextCtrl* m_textCtrlTitle; + wxStaticText* m_staticText107; + wxTextCtrl* m_textCtrlPrice; + wxStaticText* m_staticText22; + wxTextCtrl* m_textCtrlDescription; + wxStaticText* m_staticText23; + wxTextCtrl* m_textCtrlInstructions; + wxStaticText* m_staticText24; + wxStaticText* m_staticText25; + + wxTextCtrl* m_textCtrlLabel0; + wxTextCtrl* m_textCtrlField0; + wxButton* m_buttonDel0; + wxTextCtrl* m_textCtrlLabel1; + wxTextCtrl* m_textCtrlField1; + wxButton* m_buttonDel1; + wxTextCtrl* m_textCtrlLabel2; + wxTextCtrl* m_textCtrlField2; + wxButton* m_buttonDel2; + wxTextCtrl* m_textCtrlLabel3; + wxTextCtrl* m_textCtrlField3; + wxButton* m_buttonDel3; + wxTextCtrl* m_textCtrlLabel4; + wxTextCtrl* m_textCtrlField4; + wxButton* m_buttonDel4; + wxTextCtrl* m_textCtrlLabel5; + wxTextCtrl* m_textCtrlField5; + wxButton* m_buttonDel5; + wxTextCtrl* m_textCtrlLabel6; + wxTextCtrl* m_textCtrlField6; + wxButton* m_buttonDel6; + wxTextCtrl* m_textCtrlLabel7; + wxTextCtrl* m_textCtrlField7; + wxButton* m_buttonDel7; + wxTextCtrl* m_textCtrlLabel8; + wxTextCtrl* m_textCtrlField8; + wxButton* m_buttonDel8; + wxTextCtrl* m_textCtrlLabel9; + wxTextCtrl* m_textCtrlField9; + wxButton* m_buttonDel9; + wxTextCtrl* m_textCtrlLabel10; + wxTextCtrl* m_textCtrlField10; + wxButton* m_buttonDel10; + wxTextCtrl* m_textCtrlLabel11; + wxTextCtrl* m_textCtrlField11; + wxButton* m_buttonDel11; + wxTextCtrl* m_textCtrlLabel12; + wxTextCtrl* m_textCtrlField12; + wxButton* m_buttonDel12; + wxTextCtrl* m_textCtrlLabel13; + wxTextCtrl* m_textCtrlField13; + wxButton* m_buttonDel13; + wxTextCtrl* m_textCtrlLabel14; + wxTextCtrl* m_textCtrlField14; + wxButton* m_buttonDel14; + wxTextCtrl* m_textCtrlLabel15; + wxTextCtrl* m_textCtrlField15; + wxButton* m_buttonDel15; + wxTextCtrl* m_textCtrlLabel16; + wxTextCtrl* m_textCtrlField16; + wxButton* m_buttonDel16; + wxTextCtrl* m_textCtrlLabel17; + wxTextCtrl* m_textCtrlField17; + wxButton* m_buttonDel17; + wxTextCtrl* m_textCtrlLabel18; + wxTextCtrl* m_textCtrlField18; + wxButton* m_buttonDel18; + wxTextCtrl* m_textCtrlLabel19; + wxTextCtrl* m_textCtrlField19; + wxButton* m_buttonDel19; + wxButton* m_buttonAddField; + wxButton* m_buttonOK; + wxButton* m_buttonPreview; + wxButton* m_buttonCancel; + + // Virtual event handlers, overide them in your derived class + virtual void OnKeyDown( wxKeyEvent& event ){ event.Skip(); } + virtual void OnButtonDel0( wxCommandEvent& event ){ event.Skip(); } + virtual void OnButtonDel1( wxCommandEvent& event ){ event.Skip(); } + virtual void OnButtonDel2( wxCommandEvent& event ){ event.Skip(); } + virtual void OnButtonDel3( wxCommandEvent& event ){ event.Skip(); } + virtual void OnButtonDel4( wxCommandEvent& event ){ event.Skip(); } + virtual void OnButtonDel5( wxCommandEvent& event ){ event.Skip(); } + virtual void OnButtonDel6( wxCommandEvent& event ){ event.Skip(); } + virtual void OnButtonDel7( wxCommandEvent& event ){ event.Skip(); } + virtual void OnButtonDel8( wxCommandEvent& event ){ event.Skip(); } + virtual void OnButtonDel9( wxCommandEvent& event ){ event.Skip(); } + virtual void OnButtonDel10( wxCommandEvent& event ){ event.Skip(); } + virtual void OnButtonDel11( wxCommandEvent& event ){ event.Skip(); } + virtual void OnButtonDel12( wxCommandEvent& event ){ event.Skip(); } + virtual void OnButtonDel13( wxCommandEvent& event ){ event.Skip(); } + virtual void OnButtonDel14( wxCommandEvent& event ){ event.Skip(); } + virtual void OnButtonDel15( wxCommandEvent& event ){ event.Skip(); } + virtual void OnButtonDel16( wxCommandEvent& event ){ event.Skip(); } + virtual void OnButtonDel17( wxCommandEvent& event ){ event.Skip(); } + virtual void OnButtonDel18( wxCommandEvent& event ){ event.Skip(); } + virtual void OnButtonDel19( wxCommandEvent& event ){ event.Skip(); } + virtual void OnButtonAddField( wxCommandEvent& event ){ event.Skip(); } + virtual void OnButtonSend( wxCommandEvent& event ){ event.Skip(); } + virtual void OnButtonPreview( wxCommandEvent& event ){ event.Skip(); } + virtual void OnButtonCancel( wxCommandEvent& event ){ event.Skip(); } + + + public: + wxFlexGridSizer* fgSizer5; + CEditProductDialogBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxT("Edit Product"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 660,640 ), long style = wxDEFAULT_FRAME_STYLE|wxRESIZE_BORDER|wxTAB_TRAVERSAL ); + ~CEditProductDialogBase(); + }; /////////////////////////////////////////////////////////////////////////////// /// Class CViewProductDialogBase /////////////////////////////////////////////////////////////////////////////// -class CViewProductDialogBase : public wxFrame +class CViewProductDialogBase : public wxFrame { -private: - -protected: - wxHtmlWindow* m_htmlWinReviews; - wxScrolledWindow* m_scrolledWindow; - wxRichTextCtrl* m_richTextHeading; - wxStaticText* m_staticTextInstructions; - wxButton* m_buttonSubmitForm; - wxButton* m_buttonCancelForm; - wxButton* m_buttonBack; - wxButton* m_buttonNext; - wxButton* m_buttonCancel; - - // Virtual event handlers, overide them in your derived class - virtual void OnButtonSubmitForm(wxCommandEvent& event){ event.Skip(); } - virtual void OnButtonCancelForm(wxCommandEvent& event){ event.Skip(); } - virtual void OnButtonBack(wxCommandEvent& event){ event.Skip(); } - virtual void OnButtonNext(wxCommandEvent& event){ event.Skip(); } - virtual void OnButtonCancel(wxCommandEvent& event){ event.Skip(); } - - -public: - CViewProductDialogBase(wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxT("Order Form"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize(630,520), long style = wxDEFAULT_FRAME_STYLE|wxRESIZE_BORDER|wxTAB_TRAVERSAL); - ~CViewProductDialogBase(); - + private: + + protected: + wxHtmlWindow* m_htmlWinReviews; + wxScrolledWindow* m_scrolledWindow; + wxRichTextCtrl* m_richTextHeading; + wxStaticText* m_staticTextInstructions; + wxButton* m_buttonSubmitForm; + wxButton* m_buttonCancelForm; + wxButton* m_buttonBack; + wxButton* m_buttonNext; + wxButton* m_buttonCancel; + + // Virtual event handlers, overide them in your derived class + virtual void OnButtonSubmitForm( wxCommandEvent& event ){ event.Skip(); } + virtual void OnButtonCancelForm( wxCommandEvent& event ){ event.Skip(); } + virtual void OnButtonBack( wxCommandEvent& event ){ event.Skip(); } + virtual void OnButtonNext( wxCommandEvent& event ){ event.Skip(); } + virtual void OnButtonCancel( wxCommandEvent& event ){ event.Skip(); } + + + public: + CViewProductDialogBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxT("Order Form"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 630,520 ), long style = wxDEFAULT_FRAME_STYLE|wxRESIZE_BORDER|wxTAB_TRAVERSAL ); + ~CViewProductDialogBase(); + }; /////////////////////////////////////////////////////////////////////////////// /// Class CViewOrderDialogBase /////////////////////////////////////////////////////////////////////////////// -class CViewOrderDialogBase : public wxFrame +class CViewOrderDialogBase : public wxFrame { -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: - CViewOrderDialogBase(wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxT("View Order"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize(630,520), long style = wxDEFAULT_FRAME_STYLE|wxRESIZE_BORDER|wxTAB_TRAVERSAL); - ~CViewOrderDialogBase(); - + 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: + CViewOrderDialogBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxT("View Order"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 630,520 ), long style = wxDEFAULT_FRAME_STYLE|wxRESIZE_BORDER|wxTAB_TRAVERSAL ); + ~CViewOrderDialogBase(); + }; /////////////////////////////////////////////////////////////////////////////// /// Class CEditReviewDialogBase /////////////////////////////////////////////////////////////////////////////// -class CEditReviewDialogBase : public wxFrame +class CEditReviewDialogBase : public wxFrame { -private: - -protected: - - wxStaticText* m_staticTextSeller; - - wxStaticText* m_staticText110; - wxChoice* m_choiceStars; - wxStaticText* m_staticText43; - wxTextCtrl* m_textCtrlReview; - wxButton* m_buttonSubmit; - wxButton* m_buttonCancel; - - // Virtual event handlers, overide them in your derived class - virtual void OnKeyDown(wxKeyEvent& event){ event.Skip(); } - virtual void OnButtonSubmit(wxCommandEvent& event){ event.Skip(); } - virtual void OnButtonCancel(wxCommandEvent& event){ event.Skip(); } - - -public: - CEditReviewDialogBase(wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxT("Enter Review"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize(630,440), long style = wxDEFAULT_FRAME_STYLE|wxRESIZE_BORDER|wxTAB_TRAVERSAL); - ~CEditReviewDialogBase(); - + private: + + protected: + + wxStaticText* m_staticTextSeller; + + wxStaticText* m_staticText110; + wxChoice* m_choiceStars; + wxStaticText* m_staticText43; + wxTextCtrl* m_textCtrlReview; + wxButton* m_buttonSubmit; + wxButton* m_buttonCancel; + + // Virtual event handlers, overide them in your derived class + virtual void OnKeyDown( wxKeyEvent& event ){ event.Skip(); } + virtual void OnButtonSubmit( wxCommandEvent& event ){ event.Skip(); } + virtual void OnButtonCancel( wxCommandEvent& event ){ event.Skip(); } + + + public: + CEditReviewDialogBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxT("Enter Review"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 630,440 ), long style = wxDEFAULT_FRAME_STYLE|wxRESIZE_BORDER|wxTAB_TRAVERSAL ); + ~CEditReviewDialogBase(); + }; /////////////////////////////////////////////////////////////////////////////// /// Class CPokerLobbyDialogBase /////////////////////////////////////////////////////////////////////////////// -class CPokerLobbyDialogBase : public wxFrame +class CPokerLobbyDialogBase : public wxFrame { -private: - -protected: - wxTreeCtrl* m_treeCtrl; - wxListCtrl* m_listCtrl; - wxButton* m_buttonNewTable; - - // Virtual event handlers, overide them in your derived class - virtual void OnTreeSelChanged(wxTreeEvent& event){ event.Skip(); } - virtual void OnListItemActivated(wxListEvent& event){ event.Skip(); } - virtual void OnListItemSelected(wxListEvent& event){ event.Skip(); } - virtual void OnButtonNewTable(wxCommandEvent& event){ event.Skip(); } - - -public: - CPokerLobbyDialogBase(wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxT("Poker Lobby"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize(586,457), long style = wxDEFAULT_FRAME_STYLE|wxTAB_TRAVERSAL); - ~CPokerLobbyDialogBase(); - + private: + + protected: + wxTreeCtrl* m_treeCtrl; + wxListCtrl* m_listCtrl; + wxButton* m_buttonNewTable; + + // Virtual event handlers, overide them in your derived class + virtual void OnTreeSelChanged( wxTreeEvent& event ){ event.Skip(); } + virtual void OnListItemActivated( wxListEvent& event ){ event.Skip(); } + virtual void OnListItemSelected( wxListEvent& event ){ event.Skip(); } + virtual void OnButtonNewTable( wxCommandEvent& event ){ event.Skip(); } + + + public: + CPokerLobbyDialogBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxT("Poker Lobby"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 586,457 ), long style = wxDEFAULT_FRAME_STYLE|wxTAB_TRAVERSAL ); + ~CPokerLobbyDialogBase(); + }; /////////////////////////////////////////////////////////////////////////////// /// Class CPokerDialogBase /////////////////////////////////////////////////////////////////////////////// -class CPokerDialogBase : public wxFrame +class CPokerDialogBase : public wxFrame { -private: - -protected: - wxButton* m_buttonDealHand; - wxButton* m_buttonFold; - wxButton* m_buttonCall; - wxButton* m_buttonRaise; - wxButton* m_buttonLeaveTable; - wxTextCtrl* m_textDitchPlayer; - - // Virtual event handlers, overide them in your derived class - virtual void OnClose(wxCloseEvent& event){ event.Skip(); } - virtual void OnMouseEvents(wxMouseEvent& event){ event.Skip(); } - virtual void OnPaint(wxPaintEvent& event){ event.Skip(); } - virtual void OnSize(wxSizeEvent& event){ event.Skip(); } - virtual void OnCheckSitOut(wxCommandEvent& event){ event.Skip(); } - virtual void OnButtonDealHand(wxCommandEvent& event){ event.Skip(); } - virtual void OnButtonFold(wxCommandEvent& event){ event.Skip(); } - virtual void OnButtonCall(wxCommandEvent& event){ event.Skip(); } - virtual void OnButtonRaise(wxCommandEvent& event){ event.Skip(); } - virtual void OnButtonLeaveTable(wxCommandEvent& event){ event.Skip(); } - virtual void OnDitchPlayer(wxCommandEvent& event){ event.Skip(); } - virtual void OnCheckPreFold(wxCommandEvent& event){ event.Skip(); } - virtual void OnCheckPreCall(wxCommandEvent& event){ event.Skip(); } - virtual void OnCheckPreCallAny(wxCommandEvent& event){ event.Skip(); } - virtual void OnCheckPreRaise(wxCommandEvent& event){ event.Skip(); } - virtual void OnCheckPreRaiseAny(wxCommandEvent& event){ event.Skip(); } - - -public: - wxCheckBox* m_checkSitOut; - wxCheckBox* m_checkPreFold; - wxCheckBox* m_checkPreCall; - wxCheckBox* m_checkPreCallAny; - wxCheckBox* m_checkPreRaise; - wxCheckBox* m_checkPreRaiseAny; - wxStatusBar* m_statusBar; - CPokerDialogBase(wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxT("Poker"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize(806,550), long style = wxDEFAULT_FRAME_STYLE|wxFRAME_NO_TASKBAR|wxFULL_REPAINT_ON_RESIZE|wxTAB_TRAVERSAL); - ~CPokerDialogBase(); - + private: + + protected: + wxButton* m_buttonDealHand; + wxButton* m_buttonFold; + wxButton* m_buttonCall; + wxButton* m_buttonRaise; + wxButton* m_buttonLeaveTable; + wxTextCtrl* m_textDitchPlayer; + + // Virtual event handlers, overide them in your derived class + virtual void OnClose( wxCloseEvent& event ){ event.Skip(); } + virtual void OnMouseEvents( wxMouseEvent& event ){ event.Skip(); } + virtual void OnPaint( wxPaintEvent& event ){ event.Skip(); } + virtual void OnSize( wxSizeEvent& event ){ event.Skip(); } + virtual void OnCheckSitOut( wxCommandEvent& event ){ event.Skip(); } + virtual void OnButtonDealHand( wxCommandEvent& event ){ event.Skip(); } + virtual void OnButtonFold( wxCommandEvent& event ){ event.Skip(); } + virtual void OnButtonCall( wxCommandEvent& event ){ event.Skip(); } + virtual void OnButtonRaise( wxCommandEvent& event ){ event.Skip(); } + virtual void OnButtonLeaveTable( wxCommandEvent& event ){ event.Skip(); } + virtual void OnDitchPlayer( wxCommandEvent& event ){ event.Skip(); } + virtual void OnCheckPreFold( wxCommandEvent& event ){ event.Skip(); } + virtual void OnCheckPreCall( wxCommandEvent& event ){ event.Skip(); } + virtual void OnCheckPreCallAny( wxCommandEvent& event ){ event.Skip(); } + virtual void OnCheckPreRaise( wxCommandEvent& event ){ event.Skip(); } + virtual void OnCheckPreRaiseAny( wxCommandEvent& event ){ event.Skip(); } + + + public: + wxCheckBox* m_checkSitOut; + wxCheckBox* m_checkPreFold; + wxCheckBox* m_checkPreCall; + wxCheckBox* m_checkPreCallAny; + wxCheckBox* m_checkPreRaise; + wxCheckBox* m_checkPreRaiseAny; + wxStatusBar* m_statusBar; + CPokerDialogBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxT("Poker"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 806,550 ), long style = wxDEFAULT_FRAME_STYLE|wxFRAME_NO_TASKBAR|wxFULL_REPAINT_ON_RESIZE|wxTAB_TRAVERSAL ); + ~CPokerDialogBase(); + }; /////////////////////////////////////////////////////////////////////////////// /// Class CGetTextFromUserDialogBase /////////////////////////////////////////////////////////////////////////////// -class CGetTextFromUserDialogBase : public wxDialog +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(); } - + 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( 403,138 ), long style = wxDEFAULT_DIALOG_STYLE ); + ~CGetTextFromUserDialogBase(); + +}; -public: - CGetTextFromUserDialogBase(wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxEmptyString, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize(403,138), long style = wxDEFAULT_DIALOG_STYLE); - ~CGetTextFromUserDialogBase(); +/////////////////////////////////////////////////////////////////////////////// +/// Class COptionsPanelBitcoinBase +/////////////////////////////////////////////////////////////////////////////// +class COptionsPanelBitcoinBase : public wxPanel +{ + private: + + protected: + + wxStaticText* m_staticText32; + wxStaticText* m_staticText31; + + // Virtual event handlers, overide them in your derived class + virtual void OnKillFocusTransactionFee( wxFocusEvent& event ){ event.Skip(); } + + + public: + wxTextCtrl* m_textCtrlTransactionFee; + COptionsPanelBitcoinBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxTAB_TRAVERSAL ); + ~COptionsPanelBitcoinBase(); + +}; +/////////////////////////////////////////////////////////////////////////////// +/// Class COptionsPanelUIBase +/////////////////////////////////////////////////////////////////////////////// +class COptionsPanelUIBase : public wxPanel +{ + private: + + protected: + + + public: + wxCheckBox* m_checkMinToTray; + wxCheckBox* m_checkCloseToTray; + wxCheckBox* m_checkStartOnSysBoot; + wxCheckBox* m_checkAskBeforeClosing; + wxCheckBox* m_checkAlwaysShowTray; + COptionsPanelUIBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxTAB_TRAVERSAL ); + ~COptionsPanelUIBase(); + }; #endif //__uibase__ diff --git a/uiproject.fbp b/uiproject.fbp index 49b1fefaaf..ccd8b2222f 100644 --- a/uiproject.fbp +++ b/uiproject.fbp @@ -18,7 +18,7 @@ 1 0 0 - + wxSYS_COLOUR_BTNFACE @@ -48,7 +48,7 @@ - + OnIconize OnIdle @@ -151,7 +151,7 @@ OnMenuOptionsGenerate - + OnUpdateMenuGenerate @@ -1665,7 +1665,7 @@ - + @@ -1679,7 +1679,7 @@ COptionsDialogBase - 500,261 + 555,377 wxDEFAULT_DIALOG_STYLE Options @@ -1724,28 +1724,18 @@ none 5 - wxEXPAND|wxLEFT + wxEXPAND 1 - bSizer57 - wxVERTICAL - none - - 5 - wxEXPAND - 0 - - 20 - protected - 0 - - + panelSizer + wxHORIZONTAL + protected 5 - wxALIGN_CENTER_VERTICAL|wxALL + wxALL|wxEXPAND 0 - + 1 @@ -1753,20 +1743,18 @@ 0 wxID_ANY - Optional transaction fee you give to the nodes that process your transactions. - m_staticText32 + m_treeCtrl protected - - + 100,-1 + wxTR_HAS_BUTTONS|wxTR_HIDE_ROOT|wxTR_LINES_AT_ROOT - -1 @@ -1789,126 +1777,79 @@ + + + + + + + + + + + + + + + + + + MenuSelChanged + + + - - 5 - wxEXPAND - 0 - - - bSizer56 - wxHORIZONTAL - none - - 5 - wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxLEFT - 0 - - - - 1 - - - 0 - wxID_ANY - Transaction fee: - - - m_staticText31 - protected - - - - - - - - - -1 - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALL|wxALIGN_CENTER_VERTICAL - 0 - - - - 1 - - - 0 - wxID_TRANSACTIONFEE - - 0 - - m_textCtrlTransactionFee - protected - - 70,-1 - - - - - - - - - - - - - OnKillFocusTransactionFee - - - - - - - - - - - - - - - - - - - - - - - - - + + + + 5 + wxEXPAND | wxALL + 0 + + + + 1 + + + 0 + wxID_ANY + + + m_staticline1 + protected + + + wxLI_HORIZONTAL + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -2024,6 +1965,58 @@ + + 5 + wxALL + 0 + + + + 0 + 0 + + + 1 + wxID_ANY + Apply + + + m_buttonApply + protected + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -11856,5 +11849,551 @@ + + + + 1 + + + 0 + wxID_ANY + + + COptionsPanelBitcoinBase + + -1,-1 + + + + + wxTAB_TRAVERSAL + + + + + + + + + + + + + + + + + + + + + + + + + + + bSizer62 + wxVERTICAL + none + + 5 + wxEXPAND + 0 + + 20 + protected + 0 + + + + 5 + wxALIGN_CENTER_VERTICAL|wxALL + 0 + + + + 1 + + + 0 + wxID_ANY + Optional transaction fee you give to the nodes that process your transactions. + + + m_staticText32 + protected + + + + + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND + 0 + + + bSizer56 + wxHORIZONTAL + none + + 5 + wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxLEFT + 0 + + + + 1 + + + 0 + wxID_ANY + Transaction fee: + + + m_staticText31 + protected + + + + + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL|wxALIGN_CENTER_VERTICAL + 0 + + + + 1 + + + 0 + wxID_TRANSACTIONFEE + + 0 + + m_textCtrlTransactionFee + public + + 70,-1 + + + + + + + + + + + + + OnKillFocusTransactionFee + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1 + + + 0 + wxID_ANY + + + COptionsPanelUIBase + + -1,-1 + + + + + wxTAB_TRAVERSAL + + + + + + + + + + + + + + + + + + + + + + + + + + + bSizer57 + wxVERTICAL + none + + 5 + wxEXPAND + 1 + + 20 + protected + 0 + + + + 5 + wxALL + 0 + + + 0 + + 1 + + + 0 + wxID_MINTOTRAY + Minimize to tray + + + m_checkMinToTray + public + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL + 0 + + + 0 + + 1 + + + 0 + wxID_ANY + Close to tray + + + m_checkCloseToTray + public + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL + 0 + + + 0 + + 1 + + + 0 + wxID_ANY + Start on system boot + + + m_checkStartOnSysBoot + public + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL + 0 + + + 0 + + 1 + + + 0 + wxID_ANY + Ask before closing + + + m_checkAskBeforeClosing + public + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL + 0 + + + 0 + + 1 + + + 0 + wxID_ANY + Always show tray icon + + + m_checkAlwaysShowTray + public + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -- cgit v1.2.3 From dba0fd9b6a76897bbb42b2b6dcfb3b84b8558936 Mon Sep 17 00:00:00 2001 From: sirius-m Date: Thu, 24 Sep 2009 04:09:56 +0000 Subject: tray icon + ask before closing git-svn-id: https://bitcoin.svn.sourceforge.net/svnroot/bitcoin/trunk@10 1a98c847-1fd6-4fd8-948a-caf3550aa51b --- bugs.txt | 4 + changelog.txt | 4 + db.cpp | 5 + headers.h | 8 +- main.cpp | 3 - main.h | 1 - makefile | 4 +- ui.cpp | 229 +++- ui.h | 61 +- uibase.cpp | 3467 +++++++++++++++++++++++++++++---------------------------- uibase.h | 1196 ++++++++++---------- uiproject.fbp | 825 +++++++++++--- 12 files changed, 3362 insertions(+), 2445 deletions(-) create mode 100644 bugs.txt diff --git a/bugs.txt b/bugs.txt new file mode 100644 index 0000000000..348c359e8a --- /dev/null +++ b/bugs.txt @@ -0,0 +1,4 @@ +Known bugs: +- For some reason, CreateHardLink doesn't add a shortcut to the startup folder +- When the program is minimized to tray, double clicking the icon only restores it to the task bar +- Window flickers when blocks are added (problem with repainting?) \ No newline at end of file diff --git a/changelog.txt b/changelog.txt index 19120c3e4b..685eb6292b 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,2 +1,6 @@ Changes after 0.1.5: -------------------- ++ Options dialog layout changed - added the UI options panel ++ Minimize to tray feature ++ Startup on system boot feature ++ Ask before closing \ No newline at end of file diff --git a/db.cpp b/db.cpp index f38f3ffad8..6607ff5961 100644 --- a/db.cpp +++ b/db.cpp @@ -575,6 +575,11 @@ bool CWalletDB::LoadWallet(vector& vchDefaultKeyRet) if (strKey == "fGenerateBitcoins") ssValue >> fGenerateBitcoins; if (strKey == "nTransactionFee") ssValue >> nTransactionFee; if (strKey == "addrIncoming") ssValue >> addrIncoming; + if (strKey == "minimizeToTray") ssValue >> minimizeToTray; + if (strKey == "closeToTray") ssValue >> closeToTray; + if (strKey == "startOnSysBoot") ssValue >> startOnSysBoot; + if (strKey == "askBeforeClosing") ssValue >> askBeforeClosing; + if (strKey == "alwaysShowTrayIcon") ssValue >> alwaysShowTrayIcon; } } } diff --git a/headers.h b/headers.h index 7bd68a1994..92911505b8 100644 --- a/headers.h +++ b/headers.h @@ -10,11 +10,16 @@ #ifdef _WIN32_WINNT #undef _WIN32_WINNT #endif -#define _WIN32_WINNT 0x0400 +#define _WIN32_WINNT 0x0500 +#ifdef _WIN32_IE +#undef _WIN32_IE +#endif +#define _WIN32_IE 0x0500 #define WIN32_LEAN_AND_MEAN 1 #include #include #include +#include #include #include #include @@ -32,6 +37,7 @@ #include #include #include +#include #include #define BOUNDSCHECK 1 #include diff --git a/main.cpp b/main.cpp index 97000db381..ebf9d727cb 100644 --- a/main.cpp +++ b/main.cpp @@ -54,9 +54,6 @@ CAddress addrIncoming; - - - ////////////////////////////////////////////////////////////////////////////// // // mapKeys diff --git a/main.h b/main.h index 3432b316e7..9dd29bb6a9 100644 --- a/main.h +++ b/main.h @@ -47,7 +47,6 @@ extern CAddress addrIncoming; - string GetAppDir(); bool CheckDiskSpace(int64 nAdditionalBytes=0); FILE* OpenBlockFile(unsigned int nFile, unsigned int nBlockPos, const char* pszMode="rb"); diff --git a/makefile b/makefile index 534eb521e8..221684e8a9 100644 --- a/makefile +++ b/makefile @@ -12,7 +12,7 @@ ifeq "$(BUILD)" "debug" D=d # note: gcc 3.x profile doesn't work #DEBUGFLAGS=-O0 -g -pg -D__WXDEBUG__ -DEBUGFLAGS=-g -D__WXDEBUG__ +DEBUGFLAGS=-g -D__WXDEBUG__ -Wall -Wextra endif @@ -22,7 +22,7 @@ LIBPATHS=-L"/DB/build_unix" -L"/OpenSSL/out" -L"/wxWidgets/lib/gcc_lib" LIBS= \ -l db_cxx \ -l eay32 \ - -l wxmsw28$(D)_richtext -l wxmsw28$(D)_html -l wxmsw28$(D)_core -l wxbase28$(D) -l wxtiff$(D) -l wxjpeg$(D) -l wxpng$(D) -l wxzlib$(D) -l wxregex$(D) -l wxexpat$(D) \ + -l wxmsw28$(D)_richtext -l wxmsw28$(D)_html -l wxmsw28$(D)_core -l wxmsw28$(D)_adv -l wxbase28$(D) -l wxtiff$(D) -l wxjpeg$(D) -l wxpng$(D) -l wxzlib$(D) -l wxregex$(D) -l wxexpat$(D) \ -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 WXDEFS=-DWIN32 -D__WXMSW__ -D_WINDOWS -DNOPCH CFLAGS=-mthreads -O0 -w -Wno-invalid-offsetof -Wformat $(DEBUGFLAGS) $(WXDEFS) $(INCLUDEPATHS) diff --git a/ui.cpp b/ui.cpp index 96c5a83d58..751a50be68 100644 --- a/ui.cpp +++ b/ui.cpp @@ -7,8 +7,6 @@ #include #endif - - DEFINE_EVENT_TYPE(wxEVT_CROSSTHREADCALL) DEFINE_EVENT_TYPE(wxEVT_REPLY1) DEFINE_EVENT_TYPE(wxEVT_REPLY2) @@ -19,6 +17,7 @@ DEFINE_EVENT_TYPE(wxEVT_TABLEDELETED) CMainFrame* pframeMain = NULL; map mapAddressBook; +CBitcoinTBIcon* taskBarIcon = NULL; // Tray icon void ThreadRequestProductDetails(void* parg); @@ -27,8 +26,12 @@ bool fRandSendTest = false; void RandSend(); extern int g_isPainting; - - +// UI settings and their default values +int minimizeToTray = 1; +int closeToTray = 1; +int startOnSysBoot = 1; +int askBeforeClosing = 1; +int alwaysShowTrayIcon = 1; @@ -359,8 +362,28 @@ void Shutdown(void* parg) void CMainFrame::OnClose(wxCloseEvent& event) { - Destroy(); - _beginthread(Shutdown, 0, NULL); + if (closeToTray && event.CanVeto()) { + event.Veto(); + SendToTray(); + } + else if (!event.CanVeto() || !askBeforeClosing || wxMessageBox("Quit program?", "Confirm", wxYES_NO, this) == wxYES) { + delete taskBarIcon; + Destroy(); + _beginthread(Shutdown, 0, NULL); + } +} + +void CMainFrame::OnIconize(wxIconizeEvent& event) +{ + if (minimizeToTray) { + SendToTray(); + } +} + +void CMainFrame::SendToTray() +{ + Hide(); + taskBarIcon->Show(); } void CMainFrame::OnMouseEvents(wxMouseEvent& event) @@ -836,16 +859,22 @@ void CMainFrame::OnMenuFileExit(wxCommandEvent& event) Close(true); } -void CMainFrame::OnMenuOptionsGenerate(wxCommandEvent& event) +void GenerateBitcoins(bool flag) { - fGenerateBitcoins = event.IsChecked(); + fGenerateBitcoins = flag; nTransactionsUpdated++; CWalletDB().WriteSetting("fGenerateBitcoins", fGenerateBitcoins); - if (fGenerateBitcoins) if (_beginthread(ThreadBitcoinMiner, 0, NULL) == -1) printf("Error: _beginthread(ThreadBitcoinMiner) failed\n"); + taskBarIcon->UpdateTooltip(); +} + +void CMainFrame::OnMenuOptionsGenerate(wxCommandEvent& event) +{ + GenerateBitcoins(event.IsChecked()); + Refresh(); wxPaintEvent eventPaint; AddPendingEvent(eventPaint); @@ -868,6 +897,10 @@ void CMainFrame::OnMenuHelpAbout(wxCommandEvent& event) dialog.ShowModal(); } +void CMainFrame::OnUpdateMenuGenerate( wxUpdateUIEvent& event ) { + event.Check(fGenerateBitcoins); +} + void CMainFrame::OnButtonSend(wxCommandEvent& event) { /// debug test @@ -1231,23 +1264,57 @@ void CTxDetailsDialog::OnButtonOK(wxCommandEvent& event) COptionsDialog::COptionsDialog(wxWindow* parent) : COptionsDialogBase(parent) { - m_textCtrlTransactionFee->SetValue(FormatMoney(nTransactionFee)); m_buttonOK->SetFocus(); + m_treeCtrl->AddRoot(wxT("Settings")); + m_treeCtrl->AppendItem(m_treeCtrl->GetRootItem(), wxT("Bitcoin")); + m_treeCtrl->AppendItem(m_treeCtrl->GetRootItem(), wxT("UI")); + + panelUI = new COptionsPanelUI(this); + panelBitcoin = new COptionsPanelBitcoin(this); + currentPanel = panelBitcoin; + + panelSizer->Add(panelUI); + panelSizer->Hide(panelUI); + panelSizer->Add(panelBitcoin); + panelSizer->Layout(); + } -void COptionsDialog::OnKillFocusTransactionFee(wxFocusEvent& event) +void COptionsDialog::MenuSelChanged( wxTreeEvent& event ) { - int64 nTmp = nTransactionFee; - ParseMoney(m_textCtrlTransactionFee->GetValue(), nTmp); - m_textCtrlTransactionFee->SetValue(FormatMoney(nTmp)); + panelSizer->Hide(currentPanel); + wxString text = m_treeCtrl->GetItemText(event.GetItem()); + if (text == "Bitcoin") { + panelSizer->Show(panelBitcoin); + currentPanel = panelBitcoin; + } + else { + panelSizer->Show(panelUI); + currentPanel = panelUI; + } + panelSizer->Layout(); } void COptionsDialog::OnButtonOK(wxCommandEvent& event) { // nTransactionFee int64 nPrevTransactionFee = nTransactionFee; - if (ParseMoney(m_textCtrlTransactionFee->GetValue(), nTransactionFee) && nTransactionFee != nPrevTransactionFee) - CWalletDB().WriteSetting("nTransactionFee", nTransactionFee); + if (ParseMoney(panelBitcoin->m_textCtrlTransactionFee->GetValue(), nTransactionFee) && nTransactionFee != nPrevTransactionFee) + CWalletDB().WriteSetting("transactionFee", nTransactionFee); + + minimizeToTray = panelUI->m_checkMinToTray->IsChecked(); + closeToTray = panelUI->m_checkCloseToTray->IsChecked(); + startOnSysBoot = panelUI->m_checkStartOnSysBoot->IsChecked(); + askBeforeClosing = panelUI->m_checkAskBeforeClosing->IsChecked(); + alwaysShowTrayIcon = panelUI->m_checkAlwaysShowTray->IsChecked(); + + CWalletDB().WriteSetting("minimizeToTray", minimizeToTray); + CWalletDB().WriteSetting("closeToTray", closeToTray); + CWalletDB().WriteSetting("startOnSysBoot", startOnSysBoot); + CWalletDB().WriteSetting("askBeforeClosing", askBeforeClosing); + CWalletDB().WriteSetting("alwaysShowTrayIcon", alwaysShowTrayIcon); + + ApplyUISettings(); Close(); } @@ -1259,6 +1326,39 @@ void COptionsDialog::OnButtonCancel(wxCommandEvent& event) +////////////////////////////////////////////////////////////////////////////// +// +// COptionsPanelBitcoin +// + +COptionsPanelBitcoin::COptionsPanelBitcoin(wxWindow* parent) : COptionsPanelBitcoinBase(parent) +{ + m_textCtrlTransactionFee->SetValue(FormatMoney(nTransactionFee)); +} + +void COptionsPanelBitcoin::OnKillFocusTransactionFee(wxFocusEvent& event) +{ + int64 nTmp = nTransactionFee; + ParseMoney(m_textCtrlTransactionFee->GetValue(), nTmp); + m_textCtrlTransactionFee->SetValue(FormatMoney(nTmp)); +} + + +////////////////////////////////////////////////////////////////////////////// +// +// COptionsPanelUI +// + +COptionsPanelUI::COptionsPanelUI(wxWindow* parent) : COptionsPanelUIBase(parent) +{ + m_checkMinToTray->SetValue(minimizeToTray); + m_checkCloseToTray->SetValue(closeToTray); + m_checkStartOnSysBoot->SetValue(startOnSysBoot); + m_checkAskBeforeClosing->SetValue(askBeforeClosing); + m_checkAlwaysShowTray->SetValue(alwaysShowTrayIcon); +} + + @@ -2862,10 +2962,79 @@ void CEditReviewDialog::GetReview(CReview& review) +////////////////////////////////////////////////////////////////////////////// +// +// BitcoinTBIcon +// + +enum { + PU_RESTORE = 10001, + PU_GENERATE, + PU_EXIT, +}; +BEGIN_EVENT_TABLE(CBitcoinTBIcon, wxTaskBarIcon) + EVT_TASKBAR_LEFT_DCLICK (CBitcoinTBIcon::OnLeftButtonDClick) + EVT_MENU(PU_RESTORE, CBitcoinTBIcon::OnMenuRestore) + EVT_MENU(PU_GENERATE, CBitcoinTBIcon::OnMenuGenerate) + EVT_MENU(PU_EXIT, CBitcoinTBIcon::OnMenuExit) +END_EVENT_TABLE() +void CBitcoinTBIcon::Show() +{ + string tooltip = "Bitcoin"; + tooltip += fGenerateBitcoins ? " - Generating" : ""; + SetIcon(wxICON(bitcoin), tooltip); +} +void CBitcoinTBIcon::Hide() +{ + RemoveIcon(); +} +void CBitcoinTBIcon::OnLeftButtonDClick(wxTaskBarIconEvent&) +{ + Restore(); +} + +void CBitcoinTBIcon::OnMenuExit(wxCommandEvent&) +{ + pframeMain->Close(true); +} + +void CBitcoinTBIcon::OnMenuGenerate(wxCommandEvent& event) +{ + GenerateBitcoins(event.IsChecked()); + pframeMain->Refresh(); +} + +void CBitcoinTBIcon::OnMenuRestore(wxCommandEvent&) { + Restore(); +} + +void CBitcoinTBIcon::Restore() { + pframeMain->Show(); + pframeMain->Raise(); + if (!alwaysShowTrayIcon) + Hide(); +} + +void CBitcoinTBIcon::UpdateTooltip() { + if (IsIconInstalled()) + Show(); +} + +wxMenu *CBitcoinTBIcon::CreatePopupMenu() +{ + wxMenu *menu = new wxMenu; + wxMenuItem* generateCheck = menu->AppendCheckItem(PU_GENERATE, _T("Generate Coins")); + menu->Append(PU_RESTORE, _T("Open Bitcoin")); + menu->Append(PU_EXIT, _T("Exit")); + + generateCheck->Check(fGenerateBitcoins); + + return menu; +} @@ -3137,6 +3306,9 @@ bool CMyApp::OnInit2() } } + taskBarIcon = new CBitcoinTBIcon(); + ApplyUISettings(); + return true; } @@ -3214,6 +3386,31 @@ void MainFrameRepaint() +void ApplyUISettings() { + // Show the tray icon? + if (alwaysShowTrayIcon) + taskBarIcon->Show(); + else + taskBarIcon->Hide(); + + // Autostart on system startup? + if (startOnSysBoot) { + // Get the startup folder path + char targetPath[ MAX_PATH ]; + SHGetSpecialFolderPath(0, targetPath, CSIDL_STARTUP, 0); + strcat(targetPath, "\\bitcoin.lnk"); + + // And the current executable path + char currentPath[ MAX_PATH ]; + GetModuleFileName(NULL, currentPath, _MAX_PATH + 1); + + // Create the shortcut + CreateHardLink(targetPath, currentPath, NULL); + } +} + + + diff --git a/ui.h b/ui.h index 163554a599..5f3897c1be 100644 --- a/ui.h +++ b/ui.h @@ -27,9 +27,14 @@ extern string FormatTxStatus(const CWalletTx& wtx); extern void CrossThreadCall(int nID, void* pdata); extern void MainFrameRepaint(); extern void Shutdown(void* parg); +void ApplyUISettings(); - - +// UI settings +extern int minimizeToTray; +extern int closeToTray; +extern int startOnSysBoot; +extern int askBeforeClosing; +extern int alwaysShowTrayIcon; @@ -38,6 +43,7 @@ class CMainFrame : public CMainFrameBase protected: // Event handlers void OnClose(wxCloseEvent& event); + void OnIconize( wxIconizeEvent& event ); void OnMouseEvents(wxMouseEvent& event); void OnKeyDown(wxKeyEvent& event) { HandleCtrlA(event); } void OnIdle(wxIdleEvent& event); @@ -59,6 +65,7 @@ protected: void OnListItemActivatedProductsSent(wxListEvent& event); void OnListItemActivatedOrdersSent(wxListEvent& event); void OnListItemActivatedOrdersReceived(wxListEvent& event); + void OnUpdateMenuGenerate( wxUpdateUIEvent& event ); public: /** Constructor */ @@ -77,6 +84,7 @@ public: void InsertTransaction(const CWalletTx& wtx, bool fNew, int nIndex=-1); void RefreshListCtrl(); void RefreshStatus(); + void SendToTray(); }; @@ -98,14 +106,44 @@ public: +class COptionsPanelBitcoin : public COptionsPanelBitcoinBase +{ +protected: + // Event handlers + void OnKillFocusTransactionFee( wxFocusEvent& event ); + +public: + /** Constructor */ + COptionsPanelBitcoin(wxWindow* parent); +}; + + + +class COptionsPanelUI : public COptionsPanelUIBase +{ +protected: + // Event handlers + void OnOptionsChanged( wxCommandEvent& event ); + +public: + /** Constructor */ + COptionsPanelUI(wxWindow* parent); +}; + + + class COptionsDialog : public COptionsDialogBase { protected: // Event handlers - void OnKillFocusTransactionFee(wxFocusEvent& event); + void MenuSelChanged( wxTreeEvent& event ); void OnButtonOK(wxCommandEvent& event); void OnButtonCancel(wxCommandEvent& event); + // Panels + COptionsPanelBitcoin* panelBitcoin; + COptionsPanelUI* panelUI; + wxPanel* currentPanel; public: /** Constructor */ COptionsDialog(wxWindow* parent); @@ -416,5 +454,22 @@ public: +class CBitcoinTBIcon : public wxTaskBarIcon +{ +protected: + void Restore(); + + // Event handlers + void OnLeftButtonDClick(wxTaskBarIconEvent&); + void OnMenuExit(wxCommandEvent&); + void OnMenuGenerate(wxCommandEvent&); + void OnMenuRestore(wxCommandEvent&); +public: + void Show(); + void Hide(); + void UpdateTooltip(); + virtual wxMenu *CreatePopupMenu(); +DECLARE_EVENT_TABLE() +}; diff --git a/uibase.cpp b/uibase.cpp index 2972e9af3b..dcaa697588 100644 --- a/uibase.cpp +++ b/uibase.cpp @@ -1,7 +1,3 @@ -// Copyright (c) 2009 Satoshi Nakamoto -// Distributed under the MIT/X11 software license, see the accompanying -// file license.txt or http://www.opensource.org/licenses/mit-license.php. - /////////////////////////////////////////////////////////////////////////// // C++ code generated with wxFormBuilder (version Apr 16 2008) // http://www.wxformbuilder.org/ @@ -13,1813 +9,1884 @@ /////////////////////////////////////////////////////////////////////////// -CMainFrameBase::CMainFrameBase(wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style) : wxFrame(parent, id, title, pos, size, style) +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_menubar->SetBackgroundColour(wxColour(240, 240, 240)); - - m_menuFile = new wxMenu(); - wxMenuItem* m_menuFileExit; - m_menuFileExit = new wxMenuItem(m_menuFile, wxID_ANY, wxString(wxT("E&xit")) , wxEmptyString, wxITEM_NORMAL); - m_menuFile->Append(m_menuFileExit); - - m_menubar->Append(m_menuFile, wxT("&File")); - - m_menuOptions = new wxMenu(); - wxMenuItem* m_menuOptionsGenerateBitcoins; - m_menuOptionsGenerateBitcoins = new wxMenuItem(m_menuOptions, wxID_OPTIONSGENERATEBITCOINS, wxString(wxT("&Generate Coins")) , wxEmptyString, wxITEM_CHECK); - m_menuOptions->Append(m_menuOptionsGenerateBitcoins); - - wxMenuItem* m_menuChangeYourAddress; - m_menuChangeYourAddress = new wxMenuItem(m_menuOptions, wxID_ANY, wxString(wxT("&Change Your Address...")) , wxEmptyString, wxITEM_NORMAL); - m_menuOptions->Append(m_menuChangeYourAddress); - - wxMenuItem* m_menuOptionsOptions; - m_menuOptionsOptions = new wxMenuItem(m_menuOptions, wxID_ANY, wxString(wxT("&Options...")) , wxEmptyString, wxITEM_NORMAL); - m_menuOptions->Append(m_menuOptionsOptions); - - m_menubar->Append(m_menuOptions, wxT("&Options")); - - m_menuHelp = new wxMenu(); - wxMenuItem* m_menuHelpAbout; - m_menuHelpAbout = new wxMenuItem(m_menuHelp, wxID_ANY, wxString(wxT("&About...")) , wxEmptyString, wxITEM_NORMAL); - m_menuHelp->Append(m_menuHelpAbout); - - m_menubar->Append(m_menuHelp, wxT("&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, wxT("&Send Coins"), wxBitmap(wxT("send20"), wxBITMAP_TYPE_RESOURCE), wxNullBitmap, wxITEM_NORMAL, wxEmptyString, wxEmptyString); - m_toolBar->AddTool(wxID_BUTTONRECEIVE, wxT("&Address Book"), wxBitmap(wxT("addressbook20"), wxBITMAP_TYPE_RESOURCE), wxNullBitmap, wxITEM_NORMAL, wxEmptyString, wxEmptyString); - m_toolBar->Realize(); - - m_statusBar = this->CreateStatusBar(1, wxST_SIZEGRIP, wxID_ANY); - m_statusBar->SetBackgroundColour(wxColour(240, 240, 240)); - - 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, wxT("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(250,-1), wxTE_READONLY); - m_textCtrlAddress->SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_MENU)); - - bSizer85->Add(m_textCtrlAddress, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5); - - m_buttonCopy = new wxButton(this, wxID_BUTTONCOPY, wxT("&Copy to Clipboard"), wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT); - bSizer85->Add(m_buttonCopy, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 5); - - m_button91 = new wxButton(this, wxID_BUTTONCHANGE, wxT("C&hange..."), wxDefaultPosition, wxDefaultSize, 0); - m_button91->Hide(); - - bSizer85->Add(m_button91, 0, wxRIGHT, 5); - - - bSizer85->Add(0, 0, 0, wxEXPAND, 5); - - bSizer2->Add(bSizer85, 0, wxEXPAND|wxRIGHT|wxLEFT, 5); - - wxBoxSizer* bSizer3; - bSizer3 = new wxBoxSizer(wxHORIZONTAL); - - m_panel14 = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL); - wxBoxSizer* bSizer66; - bSizer66 = new wxBoxSizer(wxHORIZONTAL); - - m_staticText41 = new wxStaticText(m_panel14, wxID_ANY, wxT("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(m_panel14, 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(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW)); - - bSizer66->Add(m_staticTextBalance, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5); - - m_panel14->SetSizer(bSizer66); - m_panel14->Layout(); - bSizer66->Fit(m_panel14); - bSizer3->Add(m_panel14, 1, wxEXPAND|wxALIGN_BOTTOM|wxALL, 5); - - - bSizer3->Add(0, 0, 0, wxEXPAND, 5); - - wxString m_choiceFilterChoices[] = { wxT(" All"), wxT(" Sent"), wxT(" Received"), wxT(" 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_panel7 = new wxPanel(m_notebook, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL); - wxBoxSizer* bSizer157; - bSizer157 = new wxBoxSizer(wxVERTICAL); - - m_listCtrl = new wxListCtrl(m_panel7, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_NO_SORT_HEADER|wxLC_REPORT|wxLC_SORT_DESCENDING|wxALWAYS_SHOW_SB); - bSizer157->Add(m_listCtrl, 1, wxEXPAND|wxALL, 5); - - m_panel7->SetSizer(bSizer157); - m_panel7->Layout(); - bSizer157->Fit(m_panel7); - m_notebook->AddPage(m_panel7, wxT("All Transactions"), false); - - bSizer2->Add(m_notebook, 1, wxEXPAND, 5); - - wxBoxSizer* bSizer_TabsForFutureUse; - bSizer_TabsForFutureUse = new wxBoxSizer(wxVERTICAL); - - m_panel9 = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL); - m_panel9->Hide(); - - wxBoxSizer* bSizer159; - bSizer159 = new wxBoxSizer(wxVERTICAL); - - m_listCtrlEscrows = new wxListCtrl(m_panel9, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_NO_SORT_HEADER|wxLC_REPORT); - bSizer159->Add(m_listCtrlEscrows, 1, wxALL|wxEXPAND, 5); - - m_panel9->SetSizer(bSizer159); - m_panel9->Layout(); - bSizer159->Fit(m_panel9); - bSizer_TabsForFutureUse->Add(m_panel9, 1, wxEXPAND | wxALL, 5); - - m_panel8 = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL); - m_panel8->Hide(); - - wxBoxSizer* bSizer158; - bSizer158 = new wxBoxSizer(wxVERTICAL); - - m_listCtrlOrdersSent = new wxListCtrl(m_panel8, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_NO_SORT_HEADER|wxLC_REPORT); - bSizer158->Add(m_listCtrlOrdersSent, 1, wxALL|wxEXPAND, 5); - - m_panel8->SetSizer(bSizer158); - m_panel8->Layout(); - bSizer158->Fit(m_panel8); - bSizer_TabsForFutureUse->Add(m_panel8, 1, wxEXPAND | wxALL, 5); - - m_panel10 = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL); - m_panel10->Hide(); - - wxBoxSizer* bSizer160; - bSizer160 = new wxBoxSizer(wxVERTICAL); - - m_listCtrlProductsSent = new wxListCtrl(m_panel10, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_NO_SORT_HEADER|wxLC_REPORT); - bSizer160->Add(m_listCtrlProductsSent, 1, wxALL|wxEXPAND, 5); - - m_panel10->SetSizer(bSizer160); - m_panel10->Layout(); - bSizer160->Fit(m_panel10); - bSizer_TabsForFutureUse->Add(m_panel10, 1, wxEXPAND | wxALL, 5); - - m_panel11 = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL); - m_panel11->Hide(); - - wxBoxSizer* bSizer161; - bSizer161 = new wxBoxSizer(wxVERTICAL); - - m_listCtrlOrdersReceived = new wxListCtrl(m_panel11, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_NO_SORT_HEADER|wxLC_REPORT); - bSizer161->Add(m_listCtrlOrdersReceived, 1, wxALL|wxEXPAND, 5); - - m_panel11->SetSizer(bSizer161); - m_panel11->Layout(); - bSizer161->Fit(m_panel11); - bSizer_TabsForFutureUse->Add(m_panel11, 1, wxEXPAND | wxALL, 5); - - bSizer2->Add(bSizer_TabsForFutureUse, 1, wxEXPAND, 5); - - this->SetSizer(bSizer2); - this->Layout(); - - // Connect Events - this->Connect(wxEVT_CLOSE_WINDOW, wxCloseEventHandler(CMainFrameBase::OnClose)); - 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_menuOptionsGenerateBitcoins->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(CMainFrameBase::OnMenuOptionsGenerate)); - this->Connect(m_menuChangeYourAddress->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_buttonCopy->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CMainFrameBase::OnButtonCopy), NULL, this); - m_button91->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CMainFrameBase::OnButtonChange), NULL, this); - m_listCtrl->Connect(wxEVT_COMMAND_LIST_COL_BEGIN_DRAG, wxListEventHandler(CMainFrameBase::OnListColBeginDrag), NULL, this); - m_listCtrl->Connect(wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler(CMainFrameBase::OnListItemActivatedAllTransactions), NULL, this); - m_listCtrl->Connect(wxEVT_PAINT, wxPaintEventHandler(CMainFrameBase::OnPaintListCtrl), NULL, this); - m_listCtrlOrdersSent->Connect(wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler(CMainFrameBase::OnListItemActivatedOrdersSent), NULL, this); - m_listCtrlProductsSent->Connect(wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler(CMainFrameBase::OnListItemActivatedProductsSent), NULL, this); - m_listCtrlOrdersReceived->Connect(wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler(CMainFrameBase::OnListItemActivatedOrdersReceived), NULL, this); + this->SetSizeHints( wxDefaultSize, wxDefaultSize ); + this->SetBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_BTNFACE ) ); + + m_menubar = new wxMenuBar( 0 ); + m_menubar->SetBackgroundColour( wxColour( 240, 240, 240 ) ); + + m_menuFile = new wxMenu(); + wxMenuItem* m_menuFileExit; + m_menuFileExit = new wxMenuItem( m_menuFile, wxID_ANY, wxString( wxT("E&xit") ) , wxEmptyString, wxITEM_NORMAL ); + m_menuFile->Append( m_menuFileExit ); + + m_menubar->Append( m_menuFile, wxT("&File") ); + + m_menuOptions = new wxMenu(); + wxMenuItem* m_menuOptionsGenerateBitcoins; + m_menuOptionsGenerateBitcoins = new wxMenuItem( m_menuOptions, wxID_OPTIONSGENERATEBITCOINS, wxString( wxT("&Generate Coins") ) , wxEmptyString, wxITEM_CHECK ); + m_menuOptions->Append( m_menuOptionsGenerateBitcoins ); + + wxMenuItem* m_menuChangeYourAddress; + m_menuChangeYourAddress = new wxMenuItem( m_menuOptions, wxID_ANY, wxString( wxT("&Change Your Address...") ) , wxEmptyString, wxITEM_NORMAL ); + m_menuOptions->Append( m_menuChangeYourAddress ); + + wxMenuItem* m_menuOptionsOptions; + m_menuOptionsOptions = new wxMenuItem( m_menuOptions, wxID_ANY, wxString( wxT("&Options...") ) , wxEmptyString, wxITEM_NORMAL ); + m_menuOptions->Append( m_menuOptionsOptions ); + + m_menubar->Append( m_menuOptions, wxT("&Options") ); + + m_menuHelp = new wxMenu(); + wxMenuItem* m_menuHelpAbout; + m_menuHelpAbout = new wxMenuItem( m_menuHelp, wxID_ANY, wxString( wxT("&About...") ) , wxEmptyString, wxITEM_NORMAL ); + m_menuHelp->Append( m_menuHelpAbout ); + + m_menubar->Append( m_menuHelp, wxT("&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, wxT("&Send Coins"), wxBitmap( wxT("send20"), wxBITMAP_TYPE_RESOURCE ), wxNullBitmap, wxITEM_NORMAL, wxEmptyString, wxEmptyString ); + m_toolBar->AddTool( wxID_BUTTONRECEIVE, wxT("&Address Book"), wxBitmap( wxT("addressbook20"), wxBITMAP_TYPE_RESOURCE ), wxNullBitmap, wxITEM_NORMAL, wxEmptyString, wxEmptyString ); + m_toolBar->Realize(); + + m_statusBar = this->CreateStatusBar( 1, wxST_SIZEGRIP, wxID_ANY ); + m_statusBar->SetBackgroundColour( wxColour( 240, 240, 240 ) ); + + 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, wxT("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( 250,-1 ), wxTE_READONLY ); + m_textCtrlAddress->SetBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_MENU ) ); + + bSizer85->Add( m_textCtrlAddress, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 ); + + m_buttonCopy = new wxButton( this, wxID_BUTTONCOPY, wxT("&Copy to Clipboard"), wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT ); + bSizer85->Add( m_buttonCopy, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 5 ); + + m_button91 = new wxButton( this, wxID_BUTTONCHANGE, wxT("C&hange..."), wxDefaultPosition, wxDefaultSize, 0 ); + m_button91->Hide(); + + bSizer85->Add( m_button91, 0, wxRIGHT, 5 ); + + + bSizer85->Add( 0, 0, 0, wxEXPAND, 5 ); + + bSizer2->Add( bSizer85, 0, wxEXPAND|wxRIGHT|wxLEFT, 5 ); + + wxBoxSizer* bSizer3; + bSizer3 = new wxBoxSizer( wxHORIZONTAL ); + + m_panel14 = new wxPanel( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL ); + wxBoxSizer* bSizer66; + bSizer66 = new wxBoxSizer( wxHORIZONTAL ); + + m_staticText41 = new wxStaticText( m_panel14, wxID_ANY, wxT("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( m_panel14, 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( wxSystemSettings::GetColour( wxSYS_COLOUR_WINDOW ) ); + + bSizer66->Add( m_staticTextBalance, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 ); + + m_panel14->SetSizer( bSizer66 ); + m_panel14->Layout(); + bSizer66->Fit( m_panel14 ); + bSizer3->Add( m_panel14, 1, wxEXPAND|wxALIGN_BOTTOM|wxALL, 5 ); + + + bSizer3->Add( 0, 0, 0, wxEXPAND, 5 ); + + wxString m_choiceFilterChoices[] = { wxT(" All"), wxT(" Sent"), wxT(" Received"), wxT(" 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_panel7 = new wxPanel( m_notebook, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL ); + wxBoxSizer* bSizer157; + bSizer157 = new wxBoxSizer( wxVERTICAL ); + + m_listCtrl = new wxListCtrl( m_panel7, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_NO_SORT_HEADER|wxLC_REPORT|wxLC_SORT_DESCENDING|wxALWAYS_SHOW_SB ); + bSizer157->Add( m_listCtrl, 1, wxEXPAND|wxALL, 5 ); + + m_panel7->SetSizer( bSizer157 ); + m_panel7->Layout(); + bSizer157->Fit( m_panel7 ); + m_notebook->AddPage( m_panel7, wxT("All Transactions"), false ); + + bSizer2->Add( m_notebook, 1, wxEXPAND, 5 ); + + wxBoxSizer* bSizer_TabsForFutureUse; + bSizer_TabsForFutureUse = new wxBoxSizer( wxVERTICAL ); + + m_panel9 = new wxPanel( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL ); + m_panel9->Hide(); + + wxBoxSizer* bSizer159; + bSizer159 = new wxBoxSizer( wxVERTICAL ); + + m_listCtrlEscrows = new wxListCtrl( m_panel9, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_NO_SORT_HEADER|wxLC_REPORT ); + bSizer159->Add( m_listCtrlEscrows, 1, wxALL|wxEXPAND, 5 ); + + m_panel9->SetSizer( bSizer159 ); + m_panel9->Layout(); + bSizer159->Fit( m_panel9 ); + bSizer_TabsForFutureUse->Add( m_panel9, 1, wxEXPAND | wxALL, 5 ); + + m_panel8 = new wxPanel( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL ); + m_panel8->Hide(); + + wxBoxSizer* bSizer158; + bSizer158 = new wxBoxSizer( wxVERTICAL ); + + m_listCtrlOrdersSent = new wxListCtrl( m_panel8, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_NO_SORT_HEADER|wxLC_REPORT ); + bSizer158->Add( m_listCtrlOrdersSent, 1, wxALL|wxEXPAND, 5 ); + + m_panel8->SetSizer( bSizer158 ); + m_panel8->Layout(); + bSizer158->Fit( m_panel8 ); + bSizer_TabsForFutureUse->Add( m_panel8, 1, wxEXPAND | wxALL, 5 ); + + m_panel10 = new wxPanel( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL ); + m_panel10->Hide(); + + wxBoxSizer* bSizer160; + bSizer160 = new wxBoxSizer( wxVERTICAL ); + + m_listCtrlProductsSent = new wxListCtrl( m_panel10, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_NO_SORT_HEADER|wxLC_REPORT ); + bSizer160->Add( m_listCtrlProductsSent, 1, wxALL|wxEXPAND, 5 ); + + m_panel10->SetSizer( bSizer160 ); + m_panel10->Layout(); + bSizer160->Fit( m_panel10 ); + bSizer_TabsForFutureUse->Add( m_panel10, 1, wxEXPAND | wxALL, 5 ); + + m_panel11 = new wxPanel( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL ); + m_panel11->Hide(); + + wxBoxSizer* bSizer161; + bSizer161 = new wxBoxSizer( wxVERTICAL ); + + m_listCtrlOrdersReceived = new wxListCtrl( m_panel11, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_NO_SORT_HEADER|wxLC_REPORT ); + bSizer161->Add( m_listCtrlOrdersReceived, 1, wxALL|wxEXPAND, 5 ); + + m_panel11->SetSizer( bSizer161 ); + m_panel11->Layout(); + bSizer161->Fit( m_panel11 ); + bSizer_TabsForFutureUse->Add( m_panel11, 1, wxEXPAND | wxALL, 5 ); + + bSizer2->Add( bSizer_TabsForFutureUse, 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_menuOptionsGenerateBitcoins->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( CMainFrameBase::OnMenuOptionsGenerate ) ); + this->Connect( m_menuOptionsGenerateBitcoins->GetId(), wxEVT_UPDATE_UI, wxUpdateUIEventHandler( CMainFrameBase::OnUpdateMenuGenerate ) ); + this->Connect( m_menuChangeYourAddress->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_buttonCopy->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CMainFrameBase::OnButtonCopy ), NULL, this ); + m_button91->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CMainFrameBase::OnButtonChange ), NULL, this ); + m_listCtrl->Connect( wxEVT_COMMAND_LIST_COL_BEGIN_DRAG, wxListEventHandler( CMainFrameBase::OnListColBeginDrag ), NULL, this ); + m_listCtrl->Connect( wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler( CMainFrameBase::OnListItemActivatedAllTransactions ), NULL, this ); + m_listCtrl->Connect( wxEVT_PAINT, wxPaintEventHandler( CMainFrameBase::OnPaintListCtrl ), NULL, this ); + m_listCtrlOrdersSent->Connect( wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler( CMainFrameBase::OnListItemActivatedOrdersSent ), NULL, this ); + m_listCtrlProductsSent->Connect( wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler( CMainFrameBase::OnListItemActivatedProductsSent ), NULL, this ); + m_listCtrlOrdersReceived->Connect( wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler( CMainFrameBase::OnListItemActivatedOrdersReceived ), NULL, this ); } CMainFrameBase::~CMainFrameBase() { - // Disconnect Events - this->Disconnect(wxEVT_CLOSE_WINDOW, wxCloseEventHandler(CMainFrameBase::OnClose)); - 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::OnMenuOptionsGenerate)); - 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_buttonCopy->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CMainFrameBase::OnButtonCopy), NULL, this); - m_button91->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CMainFrameBase::OnButtonChange), NULL, this); - m_listCtrl->Disconnect(wxEVT_COMMAND_LIST_COL_BEGIN_DRAG, wxListEventHandler(CMainFrameBase::OnListColBeginDrag), NULL, this); - m_listCtrl->Disconnect(wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler(CMainFrameBase::OnListItemActivatedAllTransactions), NULL, this); - m_listCtrl->Disconnect(wxEVT_PAINT, wxPaintEventHandler(CMainFrameBase::OnPaintListCtrl), NULL, this); - m_listCtrlOrdersSent->Disconnect(wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler(CMainFrameBase::OnListItemActivatedOrdersSent), NULL, this); - m_listCtrlProductsSent->Disconnect(wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler(CMainFrameBase::OnListItemActivatedProductsSent), NULL, this); - m_listCtrlOrdersReceived->Disconnect(wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler(CMainFrameBase::OnListItemActivatedOrdersReceived), NULL, this); + // 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::OnMenuOptionsGenerate ) ); + this->Disconnect( wxID_ANY, wxEVT_UPDATE_UI, wxUpdateUIEventHandler( CMainFrameBase::OnUpdateMenuGenerate ) ); + 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_buttonCopy->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CMainFrameBase::OnButtonCopy ), NULL, this ); + m_button91->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CMainFrameBase::OnButtonChange ), NULL, this ); + m_listCtrl->Disconnect( wxEVT_COMMAND_LIST_COL_BEGIN_DRAG, wxListEventHandler( CMainFrameBase::OnListColBeginDrag ), NULL, this ); + m_listCtrl->Disconnect( wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler( CMainFrameBase::OnListItemActivatedAllTransactions ), NULL, this ); + m_listCtrl->Disconnect( wxEVT_PAINT, wxPaintEventHandler( CMainFrameBase::OnPaintListCtrl ), NULL, this ); + m_listCtrlOrdersSent->Disconnect( wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler( CMainFrameBase::OnListItemActivatedOrdersSent ), NULL, this ); + m_listCtrlProductsSent->Disconnect( wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler( CMainFrameBase::OnListItemActivatedProductsSent ), NULL, this ); + m_listCtrlOrdersReceived->Disconnect( wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler( CMainFrameBase::OnListItemActivatedOrdersReceived ), 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) +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(wxVERTICAL); - - m_buttonOK = new wxButton(this, wxID_OK, wxT("OK"), wxDefaultPosition, wxSize(85,25), 0); - bSizer65->Add(m_buttonOK, 0, wxALL, 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); + 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( wxVERTICAL ); + + m_buttonOK = new wxButton( this, wxID_OK, wxT("OK"), wxDefaultPosition, wxSize( 85,25 ), 0 ); + bSizer65->Add( m_buttonOK, 0, wxALL, 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); + // 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) +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* bSizer57; - bSizer57 = new wxBoxSizer(wxVERTICAL); - - - bSizer57->Add(0, 20, 0, wxEXPAND, 5); - - m_staticText32 = new wxStaticText(this, wxID_ANY, wxT("Optional transaction fee you give to the nodes that process your transactions."), wxDefaultPosition, wxDefaultSize, 0); - m_staticText32->Wrap(-1); - bSizer57->Add(m_staticText32, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5); - - wxBoxSizer* bSizer56; - bSizer56 = new wxBoxSizer(wxHORIZONTAL); - - m_staticText31 = new wxStaticText(this, wxID_ANY, wxT("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(this, wxID_TRANSACTIONFEE, wxEmptyString, wxDefaultPosition, wxSize(70,-1), 0); - bSizer56->Add(m_textCtrlTransactionFee, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5); - - bSizer57->Add(bSizer56, 0, wxEXPAND, 5); - - bSizer55->Add(bSizer57, 1, wxEXPAND|wxLEFT, 5); - - wxBoxSizer* bSizer58; - bSizer58 = new wxBoxSizer(wxHORIZONTAL); - - m_buttonOK = new wxButton(this, wxID_OK, wxT("OK"), wxDefaultPosition, wxSize(85,25), 0); - bSizer58->Add(m_buttonOK, 0, wxALL, 5); - - m_buttonCancel = new wxButton(this, wxID_CANCEL, wxT("Cancel"), wxDefaultPosition, wxSize(-1,-1), 0); - m_buttonCancel->SetMinSize(wxSize(85,25)); - - bSizer58->Add(m_buttonCancel, 0, wxALL, 5); - - bSizer55->Add(bSizer58, 0, wxALIGN_RIGHT, 5); - - this->SetSizer(bSizer55); - this->Layout(); - - // Connect Events - 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); + this->SetSizeHints( wxDefaultSize, wxDefaultSize ); + + wxBoxSizer* bSizer55; + bSizer55 = new wxBoxSizer( wxVERTICAL ); + + panelSizer = new wxBoxSizer( wxHORIZONTAL ); + + m_treeCtrl = new wxTreeCtrl( this, wxID_ANY, wxDefaultPosition, wxSize( 100,-1 ), wxTR_HAS_BUTTONS|wxTR_HIDE_ROOT|wxTR_LINES_AT_ROOT ); + panelSizer->Add( m_treeCtrl, 0, wxALL|wxEXPAND, 5 ); + + bSizer55->Add( panelSizer, 1, wxEXPAND, 5 ); + + m_staticline1 = new wxStaticLine( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL ); + bSizer55->Add( m_staticline1, 0, wxEXPAND | wxALL, 5 ); + + wxBoxSizer* bSizer58; + bSizer58 = new wxBoxSizer( wxHORIZONTAL ); + + m_buttonOK = new wxButton( this, wxID_OK, wxT("OK"), wxDefaultPosition, wxSize( 85,25 ), 0 ); + bSizer58->Add( m_buttonOK, 0, wxALL, 5 ); + + m_buttonCancel = new wxButton( this, wxID_CANCEL, wxT("Cancel"), wxDefaultPosition, wxSize( -1,-1 ), 0 ); + m_buttonCancel->SetMinSize( wxSize( 85,25 ) ); + + bSizer58->Add( m_buttonCancel, 0, wxALL, 5 ); + + m_buttonApply = new wxButton( this, wxID_ANY, wxT("Apply"), wxDefaultPosition, wxDefaultSize, 0 ); + m_buttonApply->Enable( false ); + m_buttonApply->Hide(); + + bSizer58->Add( m_buttonApply, 0, wxALL, 5 ); + + bSizer55->Add( bSizer58, 0, wxALIGN_RIGHT, 5 ); + + this->SetSizer( bSizer55 ); + this->Layout(); + + // Connect Events + m_treeCtrl->Connect( wxEVT_COMMAND_TREE_SEL_CHANGED, wxTreeEventHandler( COptionsDialogBase::MenuSelChanged ), 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 ); } COptionsDialogBase::~COptionsDialogBase() { - // Disconnect Events - 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); + // Disconnect Events + m_treeCtrl->Disconnect( wxEVT_COMMAND_TREE_SEL_CHANGED, wxTreeEventHandler( COptionsDialogBase::MenuSelChanged ), 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 ); } -CAboutDialogBase::CAboutDialogBase(wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style) : wxDialog(parent, id, title, pos, size, style) +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* bSizer60; - bSizer60 = new wxBoxSizer(wxVERTICAL); - - wxBoxSizer* bSizer62; - bSizer62 = new wxBoxSizer(wxHORIZONTAL); - - - bSizer62->Add(60, 0, 0, wxEXPAND, 5); - - wxBoxSizer* bSizer63; - bSizer63 = new wxBoxSizer(wxVERTICAL); - - - bSizer63->Add(0, 50, 0, wxEXPAND, 5); - - wxBoxSizer* bSizer64; - bSizer64 = new wxBoxSizer(wxHORIZONTAL); - - m_staticText40 = new wxStaticText(this, wxID_ANY, wxT("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, wxT("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); - - bSizer63->Add(bSizer64, 0, wxEXPAND, 5); - - - bSizer63->Add(0, 4, 0, wxEXPAND, 5); - - m_staticTextMain = new wxStaticText(this, wxID_ANY, wxT("Copyright © 2009 Satoshi Nakamoto.\n\nThis is experimental software. Do not rely on it for actual financial transactions.\n\nDistributed under the MIT/X11 software license, see the accompanying file license.txt or http://www.opensource.org/licenses/mit-license.php.\n\nThis 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)."), wxDefaultPosition, wxDefaultSize, 0); - m_staticTextMain->Wrap(400); - bSizer63->Add(m_staticTextMain, 0, wxALL, 5); - - - bSizer63->Add(0, 0, 1, wxEXPAND, 5); - - bSizer62->Add(bSizer63, 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, wxT("OK"), wxDefaultPosition, wxSize(85,25), 0); - bSizer61->Add(m_buttonOK, 0, wxALL, 5); - - bSizer60->Add(bSizer61, 0, wxALIGN_RIGHT|wxEXPAND, 5); - - this->SetSizer(bSizer60); - this->Layout(); - - // Connect Events - m_buttonOK->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CAboutDialogBase::OnButtonOK), NULL, this); + this->SetSizeHints( wxDefaultSize, wxDefaultSize ); + + wxBoxSizer* bSizer60; + bSizer60 = new wxBoxSizer( wxVERTICAL ); + + wxBoxSizer* bSizer62; + bSizer62 = new wxBoxSizer( wxHORIZONTAL ); + + + bSizer62->Add( 60, 0, 0, wxEXPAND, 5 ); + + wxBoxSizer* bSizer63; + bSizer63 = new wxBoxSizer( wxVERTICAL ); + + + bSizer63->Add( 0, 50, 0, wxEXPAND, 5 ); + + wxBoxSizer* bSizer64; + bSizer64 = new wxBoxSizer( wxHORIZONTAL ); + + m_staticText40 = new wxStaticText( this, wxID_ANY, wxT("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, wxT("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 ); + + bSizer63->Add( bSizer64, 0, wxEXPAND, 5 ); + + + bSizer63->Add( 0, 4, 0, wxEXPAND, 5 ); + + m_staticTextMain = new wxStaticText( this, wxID_ANY, wxT("Copyright © 2009 Satoshi Nakamoto.\n\nThis is experimental software. Do not rely on it for actual financial transactions.\n\nDistributed under the MIT/X11 software license, see the accompanying file license.txt or http://www.opensource.org/licenses/mit-license.php.\n\nThis 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)."), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticTextMain->Wrap( 400 ); + bSizer63->Add( m_staticTextMain, 0, wxALL, 5 ); + + + bSizer63->Add( 0, 0, 1, wxEXPAND, 5 ); + + bSizer62->Add( bSizer63, 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, wxT("OK"), wxDefaultPosition, wxSize( 85,25 ), 0 ); + bSizer61->Add( m_buttonOK, 0, wxALL, 5 ); + + bSizer60->Add( bSizer61, 0, wxALIGN_RIGHT|wxEXPAND, 5 ); + + this->SetSizer( bSizer60 ); + 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); + // 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) +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(3, 2, 0, 0); - fgSizer1->AddGrowableCol(1); - fgSizer1->SetFlexibleDirection(wxBOTH); - fgSizer1->SetNonFlexibleGrowMode(wxFLEX_GROWMODE_SPECIFIED); - - - fgSizer1->Add(0, 0, 0, wxEXPAND, 5); - - m_staticText14 = new wxStaticText(this, wxID_ANY, wxT("Enter the recipient's IP address (e.g. 123.45.6.7) for online transfer with comments and confirmation, \nor Bitcoin address (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJED9L) if recipient is not online."), wxDefaultPosition, wxDefaultSize, 0); - m_staticText14->Wrap(-1); - fgSizer1->Add(m_staticText14, 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, wxICON(check), wxDefaultPosition, wxSize(16,16), 0); - bSizer47->Add(m_bitmapCheckMark, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5); - - m_staticText36 = new wxStaticText(this, wxID_ANY, wxT("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); - - m_buttonPaste = new wxButton(this, wxID_BUTTONPASTE, wxT("&Paste"), wxDefaultPosition, wxSize(-1,-1), wxBU_EXACTFIT); - bSizer19->Add(m_buttonPaste, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 5); - - m_buttonAddress = new wxButton(this, wxID_BUTTONADDRESSBOOK, wxT(" Address &Book..."), wxDefaultPosition, wxDefaultSize, 0); - bSizer19->Add(m_buttonAddress, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 5); - - fgSizer1->Add(bSizer19, 1, wxEXPAND|wxRIGHT, 5); - - m_staticText19 = new wxStaticText(this, wxID_ANY, wxT("&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, wxT("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[] = { wxT(" 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); - - wxBoxSizer* bSizer681; - bSizer681 = new wxBoxSizer(wxVERTICAL); - - m_staticTextFrom = new wxStaticText(this, wxID_ANY, wxT("&From:"), wxDefaultPosition, wxDefaultSize, 0); - m_staticTextFrom->Wrap(-1); - bSizer681->Add(m_staticTextFrom, 0, wxBOTTOM|wxLEFT, 5); - - m_textCtrlFrom = new wxTextCtrl(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(-1,-1), 0); - bSizer681->Add(m_textCtrlFrom, 0, wxLEFT|wxEXPAND, 5); - - bSizer672->Add(bSizer681, 1, wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT, 5); - - bSizer21->Add(bSizer672, 0, wxEXPAND, 5); - - wxBoxSizer* bSizer67; - bSizer67 = new wxBoxSizer(wxHORIZONTAL); - - wxBoxSizer* bSizer68; - bSizer68 = new wxBoxSizer(wxVERTICAL); - - m_staticTextMessage = new wxStaticText(this, wxID_ANY, wxT("&Message:"), wxDefaultPosition, wxDefaultSize, 0); - m_staticTextMessage->Wrap(-1); - bSizer68->Add(m_staticTextMessage, 0, wxTOP|wxBOTTOM|wxLEFT, 5); - - m_textCtrlMessage = new wxTextCtrl(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE); - bSizer68->Add(m_textCtrlMessage, 1, wxEXPAND|wxLEFT, 5); - - bSizer67->Add(bSizer68, 1, wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT, 5); - - bSizer21->Add(bSizer67, 1, wxEXPAND, 5); - - wxBoxSizer* bSizer23; - bSizer23 = new wxBoxSizer(wxHORIZONTAL); - - - bSizer23->Add(0, 0, 1, wxEXPAND, 5); - - m_buttonSend = new wxButton(this, wxID_BUTTONSEND, wxT("&Send"), wxDefaultPosition, wxSize(-1,-1), 0); - m_buttonSend->SetFont(wxFont(wxNORMAL_FONT->GetPointSize(), 70, 90, 90, false, wxEmptyString)); - m_buttonSend->SetMinSize(wxSize(85,25)); - - bSizer23->Add(m_buttonSend, 0, wxALL, 5); - - m_buttonCancel = new wxButton(this, wxID_CANCEL, wxT("Cancel"), wxDefaultPosition, wxSize(-1,-1), 0); - m_buttonCancel->SetMinSize(wxSize(85,25)); - - bSizer23->Add(m_buttonCancel, 0, wxALL, 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_textCtrlFrom->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CSendDialogBase::OnKeyDown), NULL, this); - m_textCtrlMessage->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CSendDialogBase::OnKeyDown), 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); + this->SetSizeHints( wxDefaultSize, wxDefaultSize ); + + wxBoxSizer* bSizer21; + bSizer21 = new wxBoxSizer( wxVERTICAL ); + + + bSizer21->Add( 0, 5, 0, wxEXPAND, 5 ); + + wxFlexGridSizer* fgSizer1; + fgSizer1 = new wxFlexGridSizer( 3, 2, 0, 0 ); + fgSizer1->AddGrowableCol( 1 ); + fgSizer1->SetFlexibleDirection( wxBOTH ); + fgSizer1->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED ); + + + fgSizer1->Add( 0, 0, 0, wxEXPAND, 5 ); + + m_staticText14 = new wxStaticText( this, wxID_ANY, wxT("Enter the recipient's IP address (e.g. 123.45.6.7) for online transfer with comments and confirmation, \nor Bitcoin address (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJED9L) if recipient is not online."), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticText14->Wrap( -1 ); + fgSizer1->Add( m_staticText14, 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, wxICON( check ), wxDefaultPosition, wxSize( 16,16 ), 0 ); + bSizer47->Add( m_bitmapCheckMark, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); + + m_staticText36 = new wxStaticText( this, wxID_ANY, wxT("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 ); + + m_buttonPaste = new wxButton( this, wxID_BUTTONPASTE, wxT("&Paste"), wxDefaultPosition, wxSize( -1,-1 ), wxBU_EXACTFIT ); + bSizer19->Add( m_buttonPaste, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 5 ); + + m_buttonAddress = new wxButton( this, wxID_BUTTONADDRESSBOOK, wxT(" Address &Book..."), wxDefaultPosition, wxDefaultSize, 0 ); + bSizer19->Add( m_buttonAddress, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 5 ); + + fgSizer1->Add( bSizer19, 1, wxEXPAND|wxRIGHT, 5 ); + + m_staticText19 = new wxStaticText( this, wxID_ANY, wxT("&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, wxT("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[] = { wxT(" 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 ); + + wxBoxSizer* bSizer681; + bSizer681 = new wxBoxSizer( wxVERTICAL ); + + m_staticTextFrom = new wxStaticText( this, wxID_ANY, wxT("&From:"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticTextFrom->Wrap( -1 ); + bSizer681->Add( m_staticTextFrom, 0, wxBOTTOM|wxLEFT, 5 ); + + m_textCtrlFrom = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize( -1,-1 ), 0 ); + bSizer681->Add( m_textCtrlFrom, 0, wxLEFT|wxEXPAND, 5 ); + + bSizer672->Add( bSizer681, 1, wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT, 5 ); + + bSizer21->Add( bSizer672, 0, wxEXPAND, 5 ); + + wxBoxSizer* bSizer67; + bSizer67 = new wxBoxSizer( wxHORIZONTAL ); + + wxBoxSizer* bSizer68; + bSizer68 = new wxBoxSizer( wxVERTICAL ); + + m_staticTextMessage = new wxStaticText( this, wxID_ANY, wxT("&Message:"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticTextMessage->Wrap( -1 ); + bSizer68->Add( m_staticTextMessage, 0, wxTOP|wxBOTTOM|wxLEFT, 5 ); + + m_textCtrlMessage = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE ); + bSizer68->Add( m_textCtrlMessage, 1, wxEXPAND|wxLEFT, 5 ); + + bSizer67->Add( bSizer68, 1, wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT, 5 ); + + bSizer21->Add( bSizer67, 1, wxEXPAND, 5 ); + + wxBoxSizer* bSizer23; + bSizer23 = new wxBoxSizer( wxHORIZONTAL ); + + + bSizer23->Add( 0, 0, 1, wxEXPAND, 5 ); + + m_buttonSend = new wxButton( this, wxID_BUTTONSEND, wxT("&Send"), wxDefaultPosition, wxSize( -1,-1 ), 0 ); + m_buttonSend->SetFont( wxFont( wxNORMAL_FONT->GetPointSize(), 70, 90, 90, false, wxEmptyString ) ); + m_buttonSend->SetMinSize( wxSize( 85,25 ) ); + + bSizer23->Add( m_buttonSend, 0, wxALL, 5 ); + + m_buttonCancel = new wxButton( this, wxID_CANCEL, wxT("Cancel"), wxDefaultPosition, wxSize( -1,-1 ), 0 ); + m_buttonCancel->SetMinSize( wxSize( 85,25 ) ); + + bSizer23->Add( m_buttonCancel, 0, wxALL, 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_textCtrlFrom->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CSendDialogBase::OnKeyDown ), NULL, this ); + m_textCtrlMessage->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CSendDialogBase::OnKeyDown ), 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_textCtrlFrom->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CSendDialogBase::OnKeyDown), NULL, this); - m_textCtrlMessage->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CSendDialogBase::OnKeyDown), 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); + // 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_textCtrlFrom->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CSendDialogBase::OnKeyDown ), NULL, this ); + m_textCtrlMessage->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CSendDialogBase::OnKeyDown ), 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) +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, wxT("\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, wxT("OK"), wxDefaultPosition, wxDefaultSize, 0); - m_buttonOK->Enable(false); - m_buttonOK->SetMinSize(wxSize(85,25)); - - bSizer69->Add(m_buttonOK, 0, wxALL, 5); - - m_buttonCancel = new wxButton(this, wxID_CANCEL, wxT("Cancel"), wxDefaultPosition, wxSize(-1,-1), 0); - m_buttonCancel->SetMinSize(wxSize(85,25)); - - bSizer69->Add(m_buttonCancel, 0, wxALL, 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); + 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, wxT("\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, wxT("OK"), wxDefaultPosition, wxDefaultSize, 0 ); + m_buttonOK->Enable( false ); + m_buttonOK->SetMinSize( wxSize( 85,25 ) ); + + bSizer69->Add( m_buttonOK, 0, wxALL, 5 ); + + m_buttonCancel = new wxButton( this, wxID_CANCEL, wxT("Cancel"), wxDefaultPosition, wxSize( -1,-1 ), 0 ); + m_buttonCancel->SetMinSize( wxSize( 85,25 ) ); + + bSizer69->Add( m_buttonCancel, 0, wxALL, 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); + // 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) +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, wxT("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, wxT("&Edit..."), wxDefaultPosition, wxDefaultSize, 0); - m_buttonRename->SetMinSize(wxSize(85,25)); - - bSizer69->Add(m_buttonRename, 0, wxALL, 5); - - m_buttonNew = new wxButton(this, wxID_BUTTONNEW, wxT("&New Address..."), wxDefaultPosition, wxSize(-1,-1), 0); - m_buttonNew->SetMinSize(wxSize(110,25)); - - bSizer69->Add(m_buttonNew, 0, wxALL, 5); - - m_buttonCopy = new wxButton(this, wxID_BUTTONCOPY, wxT("&Copy to Clipboard"), wxDefaultPosition, wxSize(-1,-1), 0); - m_buttonCopy->SetMinSize(wxSize(120,25)); - - bSizer69->Add(m_buttonCopy, 0, wxALL, 5); - - m_buttonOK = new wxButton(this, wxID_OK, wxT("OK"), wxDefaultPosition, wxDefaultSize, 0); - m_buttonOK->SetMinSize(wxSize(85,25)); - - bSizer69->Add(m_buttonOK, 0, wxALL, 5); - - m_buttonCancel = new wxButton(this, wxID_CANCEL, wxT("Cancel"), wxDefaultPosition, wxSize(-1,-1), 0); - m_buttonCancel->Hide(); - m_buttonCancel->SetMinSize(wxSize(85,25)); - - bSizer69->Add(m_buttonCancel, 0, wxALL, 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); + this->SetSizeHints( wxDefaultSize, wxDefaultSize ); + + wxBoxSizer* bSizer68; + bSizer68 = new wxBoxSizer( wxVERTICAL ); + + + bSizer68->Add( 0, 5, 0, wxEXPAND, 5 ); + + m_staticText45 = new wxStaticText( this, wxID_ANY, wxT("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, wxT("&Edit..."), wxDefaultPosition, wxDefaultSize, 0 ); + m_buttonRename->SetMinSize( wxSize( 85,25 ) ); + + bSizer69->Add( m_buttonRename, 0, wxALL, 5 ); + + m_buttonNew = new wxButton( this, wxID_BUTTONNEW, wxT("&New Address..."), wxDefaultPosition, wxSize( -1,-1 ), 0 ); + m_buttonNew->SetMinSize( wxSize( 110,25 ) ); + + bSizer69->Add( m_buttonNew, 0, wxALL, 5 ); + + m_buttonCopy = new wxButton( this, wxID_BUTTONCOPY, wxT("&Copy to Clipboard"), wxDefaultPosition, wxSize( -1,-1 ), 0 ); + m_buttonCopy->SetMinSize( wxSize( 120,25 ) ); + + bSizer69->Add( m_buttonCopy, 0, wxALL, 5 ); + + m_buttonOK = new wxButton( this, wxID_OK, wxT("OK"), wxDefaultPosition, wxDefaultSize, 0 ); + m_buttonOK->SetMinSize( wxSize( 85,25 ) ); + + bSizer69->Add( m_buttonOK, 0, wxALL, 5 ); + + m_buttonCancel = new wxButton( this, wxID_CANCEL, wxT("Cancel"), wxDefaultPosition, wxSize( -1,-1 ), 0 ); + m_buttonCancel->Hide(); + m_buttonCancel->SetMinSize( wxSize( 85,25 ) ); + + bSizer69->Add( m_buttonCancel, 0, wxALL, 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); + // 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) +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* bSizer68; - bSizer68 = new wxBoxSizer(wxVERTICAL); - - - bSizer68->Add(0, 5, 0, wxEXPAND, 5); - - m_staticText55 = new wxStaticText(this, wxID_ANY, wxT("Bitcoin Address"), wxDefaultPosition, wxDefaultSize, 0); - m_staticText55->Wrap(-1); - m_staticText55->Hide(); - - bSizer68->Add(m_staticText55, 0, wxTOP|wxRIGHT|wxLEFT, 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_buttonEdit = new wxButton(this, wxID_BUTTONEDIT, wxT("&Edit..."), wxDefaultPosition, wxDefaultSize, 0); - m_buttonEdit->SetMinSize(wxSize(85,25)); - - bSizer69->Add(m_buttonEdit, 0, wxALL, 5); - - m_buttonNew = new wxButton(this, wxID_BUTTONNEW, wxT("&New Address..."), wxDefaultPosition, wxDefaultSize, 0); - m_buttonNew->SetMinSize(wxSize(110,25)); - - bSizer69->Add(m_buttonNew, 0, wxALL, 5); - - m_buttonDelete = new wxButton(this, wxID_BUTTONDELETE, wxT("&Delete"), wxDefaultPosition, wxDefaultSize, 0); - m_buttonDelete->SetMinSize(wxSize(85,25)); - - bSizer69->Add(m_buttonDelete, 0, wxALL, 5); - - m_buttonOK = new wxButton(this, wxID_OK, wxT("OK"), wxDefaultPosition, wxSize(-1,-1), 0); - m_buttonOK->SetMinSize(wxSize(85,25)); - - bSizer69->Add(m_buttonOK, 0, wxALL, 5); - - m_buttonCancel = new wxButton(this, wxID_CANCEL, wxT("Cancel"), wxDefaultPosition, wxSize(-1,-1), 0); - m_buttonCancel->SetMinSize(wxSize(85,25)); - - bSizer69->Add(m_buttonCancel, 0, wxALL, 5); - - bSizer68->Add(bSizer69, 0, wxEXPAND, 5); - - this->SetSizer(bSizer68); - this->Layout(); - - // Connect Events - this->Connect(wxEVT_CLOSE_WINDOW, wxCloseEventHandler(CAddressBookDialogBase::OnClose)); - m_listCtrl->Connect(wxEVT_COMMAND_LIST_END_LABEL_EDIT, wxListEventHandler(CAddressBookDialogBase::OnListEndLabelEdit), NULL, this); - m_listCtrl->Connect(wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler(CAddressBookDialogBase::OnListItemActivated), NULL, this); - m_listCtrl->Connect(wxEVT_COMMAND_LIST_ITEM_SELECTED, wxListEventHandler(CAddressBookDialogBase::OnListItemSelected), 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_buttonDelete->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CAddressBookDialogBase::OnButtonDelete), 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); + this->SetSizeHints( wxDefaultSize, wxDefaultSize ); + + wxBoxSizer* bSizer68; + bSizer68 = new wxBoxSizer( wxVERTICAL ); + + + bSizer68->Add( 0, 5, 0, wxEXPAND, 5 ); + + m_staticText55 = new wxStaticText( this, wxID_ANY, wxT("Bitcoin Address"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticText55->Wrap( -1 ); + m_staticText55->Hide(); + + bSizer68->Add( m_staticText55, 0, wxTOP|wxRIGHT|wxLEFT, 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_buttonEdit = new wxButton( this, wxID_BUTTONEDIT, wxT("&Edit..."), wxDefaultPosition, wxDefaultSize, 0 ); + m_buttonEdit->SetMinSize( wxSize( 85,25 ) ); + + bSizer69->Add( m_buttonEdit, 0, wxALL, 5 ); + + m_buttonNew = new wxButton( this, wxID_BUTTONNEW, wxT("&New Address..."), wxDefaultPosition, wxDefaultSize, 0 ); + m_buttonNew->SetMinSize( wxSize( 110,25 ) ); + + bSizer69->Add( m_buttonNew, 0, wxALL, 5 ); + + m_buttonDelete = new wxButton( this, wxID_BUTTONDELETE, wxT("&Delete"), wxDefaultPosition, wxDefaultSize, 0 ); + m_buttonDelete->SetMinSize( wxSize( 85,25 ) ); + + bSizer69->Add( m_buttonDelete, 0, wxALL, 5 ); + + m_buttonOK = new wxButton( this, wxID_OK, wxT("OK"), wxDefaultPosition, wxSize( -1,-1 ), 0 ); + m_buttonOK->SetMinSize( wxSize( 85,25 ) ); + + bSizer69->Add( m_buttonOK, 0, wxALL, 5 ); + + m_buttonCancel = new wxButton( this, wxID_CANCEL, wxT("Cancel"), wxDefaultPosition, wxSize( -1,-1 ), 0 ); + m_buttonCancel->SetMinSize( wxSize( 85,25 ) ); + + bSizer69->Add( m_buttonCancel, 0, wxALL, 5 ); + + bSizer68->Add( bSizer69, 0, wxEXPAND, 5 ); + + this->SetSizer( bSizer68 ); + this->Layout(); + + // Connect Events + this->Connect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( CAddressBookDialogBase::OnClose ) ); + m_listCtrl->Connect( wxEVT_COMMAND_LIST_END_LABEL_EDIT, wxListEventHandler( CAddressBookDialogBase::OnListEndLabelEdit ), NULL, this ); + m_listCtrl->Connect( wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler( CAddressBookDialogBase::OnListItemActivated ), NULL, this ); + m_listCtrl->Connect( wxEVT_COMMAND_LIST_ITEM_SELECTED, wxListEventHandler( CAddressBookDialogBase::OnListItemSelected ), 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_buttonDelete->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CAddressBookDialogBase::OnButtonDelete ), 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_listCtrl->Disconnect(wxEVT_COMMAND_LIST_END_LABEL_EDIT, wxListEventHandler(CAddressBookDialogBase::OnListEndLabelEdit), NULL, this); - m_listCtrl->Disconnect(wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler(CAddressBookDialogBase::OnListItemActivated), NULL, this); - m_listCtrl->Disconnect(wxEVT_COMMAND_LIST_ITEM_SELECTED, wxListEventHandler(CAddressBookDialogBase::OnListItemSelected), 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_buttonDelete->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CAddressBookDialogBase::OnButtonDelete), 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); + // Disconnect Events + this->Disconnect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( CAddressBookDialogBase::OnClose ) ); + m_listCtrl->Disconnect( wxEVT_COMMAND_LIST_END_LABEL_EDIT, wxListEventHandler( CAddressBookDialogBase::OnListEndLabelEdit ), NULL, this ); + m_listCtrl->Disconnect( wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler( CAddressBookDialogBase::OnListItemActivated ), NULL, this ); + m_listCtrl->Disconnect( wxEVT_COMMAND_LIST_ITEM_SELECTED, wxListEventHandler( CAddressBookDialogBase::OnListItemSelected ), 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_buttonDelete->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CAddressBookDialogBase::OnButtonDelete ), 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 ); } -CProductsDialogBase::CProductsDialogBase(wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style) : wxDialog(parent, id, title, pos, size, style) +CProductsDialogBase::CProductsDialogBase( 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* bSizer22; - bSizer22 = new wxBoxSizer(wxVERTICAL); - - wxBoxSizer* bSizer23; - bSizer23 = new wxBoxSizer(wxHORIZONTAL); - - m_comboBoxCategory = new wxComboBox(this, wxID_ANY, wxT("(Any Category)"), wxDefaultPosition, wxSize(150,-1), 0, NULL, 0); - m_comboBoxCategory->Append(wxT("(Any Category)")); - bSizer23->Add(m_comboBoxCategory, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5); - - m_textCtrlSearch = new wxTextCtrl(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0); - bSizer23->Add(m_textCtrlSearch, 1, wxALL|wxALIGN_CENTER_VERTICAL, 5); - - m_buttonSearch = new wxButton(this, wxID_ANY, wxT("&Search"), wxDefaultPosition, wxDefaultSize, 0); - bSizer23->Add(m_buttonSearch, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5); - - bSizer22->Add(bSizer23, 0, wxEXPAND|wxTOP|wxBOTTOM|wxRIGHT, 5); - - m_listCtrl = new wxListCtrl(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_NO_SORT_HEADER|wxLC_REPORT); - bSizer22->Add(m_listCtrl, 1, wxALL|wxEXPAND, 5); - - this->SetSizer(bSizer22); - this->Layout(); - - // Connect Events - m_comboBoxCategory->Connect(wxEVT_COMMAND_COMBOBOX_SELECTED, wxCommandEventHandler(CProductsDialogBase::OnCombobox), NULL, this); - m_textCtrlSearch->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CProductsDialogBase::OnKeyDown), NULL, this); - m_buttonSearch->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CProductsDialogBase::OnButtonSearch), NULL, this); - m_listCtrl->Connect(wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler(CProductsDialogBase::OnListItemActivated), NULL, this); + this->SetSizeHints( wxDefaultSize, wxDefaultSize ); + + wxBoxSizer* bSizer22; + bSizer22 = new wxBoxSizer( wxVERTICAL ); + + wxBoxSizer* bSizer23; + bSizer23 = new wxBoxSizer( wxHORIZONTAL ); + + m_comboBoxCategory = new wxComboBox( this, wxID_ANY, wxT("(Any Category)"), wxDefaultPosition, wxSize( 150,-1 ), 0, NULL, 0 ); + m_comboBoxCategory->Append( wxT("(Any Category)") ); + bSizer23->Add( m_comboBoxCategory, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); + + m_textCtrlSearch = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); + bSizer23->Add( m_textCtrlSearch, 1, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); + + m_buttonSearch = new wxButton( this, wxID_ANY, wxT("&Search"), wxDefaultPosition, wxDefaultSize, 0 ); + bSizer23->Add( m_buttonSearch, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); + + bSizer22->Add( bSizer23, 0, wxEXPAND|wxTOP|wxBOTTOM|wxRIGHT, 5 ); + + m_listCtrl = new wxListCtrl( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_NO_SORT_HEADER|wxLC_REPORT ); + bSizer22->Add( m_listCtrl, 1, wxALL|wxEXPAND, 5 ); + + this->SetSizer( bSizer22 ); + this->Layout(); + + // Connect Events + m_comboBoxCategory->Connect( wxEVT_COMMAND_COMBOBOX_SELECTED, wxCommandEventHandler( CProductsDialogBase::OnCombobox ), NULL, this ); + m_textCtrlSearch->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CProductsDialogBase::OnKeyDown ), NULL, this ); + m_buttonSearch->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CProductsDialogBase::OnButtonSearch ), NULL, this ); + m_listCtrl->Connect( wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler( CProductsDialogBase::OnListItemActivated ), NULL, this ); } CProductsDialogBase::~CProductsDialogBase() { - // Disconnect Events - m_comboBoxCategory->Disconnect(wxEVT_COMMAND_COMBOBOX_SELECTED, wxCommandEventHandler(CProductsDialogBase::OnCombobox), NULL, this); - m_textCtrlSearch->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CProductsDialogBase::OnKeyDown), NULL, this); - m_buttonSearch->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CProductsDialogBase::OnButtonSearch), NULL, this); - m_listCtrl->Disconnect(wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler(CProductsDialogBase::OnListItemActivated), NULL, this); + // Disconnect Events + m_comboBoxCategory->Disconnect( wxEVT_COMMAND_COMBOBOX_SELECTED, wxCommandEventHandler( CProductsDialogBase::OnCombobox ), NULL, this ); + m_textCtrlSearch->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CProductsDialogBase::OnKeyDown ), NULL, this ); + m_buttonSearch->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CProductsDialogBase::OnButtonSearch ), NULL, this ); + m_listCtrl->Disconnect( wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler( CProductsDialogBase::OnListItemActivated ), NULL, this ); } -CEditProductDialogBase::CEditProductDialogBase(wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style) : wxFrame(parent, id, title, pos, size, style) +CEditProductDialogBase::CEditProductDialogBase( 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_MENU)); - - wxBoxSizer* bSizer20; - bSizer20 = new wxBoxSizer(wxVERTICAL); - - m_scrolledWindow = new wxScrolledWindow(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxHSCROLL|wxTAB_TRAVERSAL|wxVSCROLL); - m_scrolledWindow->SetScrollRate(5, 5); - m_scrolledWindow->SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW)); - - wxBoxSizer* bSizer21; - bSizer21 = new wxBoxSizer(wxVERTICAL); - - wxFlexGridSizer* fgSizer8; - fgSizer8 = new wxFlexGridSizer(0, 2, 0, 0); - fgSizer8->AddGrowableCol(1); - fgSizer8->SetFlexibleDirection(wxBOTH); - fgSizer8->SetNonFlexibleGrowMode(wxFLEX_GROWMODE_SPECIFIED); - - m_staticText106 = new wxStaticText(m_scrolledWindow, wxID_ANY, wxT("Category"), wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT); - m_staticText106->Wrap(-1); - fgSizer8->Add(m_staticText106, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxTOP|wxBOTTOM|wxLEFT, 5); - - m_comboBoxCategory = new wxComboBox(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0, NULL, 0); - m_comboBoxCategory->SetMinSize(wxSize(180,-1)); - - fgSizer8->Add(m_comboBoxCategory, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5); - - m_staticText108 = new wxStaticText(m_scrolledWindow, wxID_ANY, wxT("Title"), wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT); - m_staticText108->Wrap(-1); - fgSizer8->Add(m_staticText108, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxTOP|wxBOTTOM|wxLEFT, 5); - - m_textCtrlTitle = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0); - fgSizer8->Add(m_textCtrlTitle, 1, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5); - - m_staticText107 = new wxStaticText(m_scrolledWindow, wxID_ANY, wxT("Price"), wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT); - m_staticText107->Wrap(-1); - fgSizer8->Add(m_staticText107, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxTOP|wxBOTTOM|wxLEFT, 5); - - m_textCtrlPrice = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0); - m_textCtrlPrice->SetMinSize(wxSize(105,-1)); - - fgSizer8->Add(m_textCtrlPrice, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5); - - bSizer21->Add(fgSizer8, 0, wxEXPAND|wxTOP|wxRIGHT|wxLEFT, 5); - - m_staticText22 = new wxStaticText(m_scrolledWindow, wxID_ANY, wxT("Page 1: Description"), wxDefaultPosition, wxDefaultSize, 0); - m_staticText22->Wrap(-1); - bSizer21->Add(m_staticText22, 0, wxTOP|wxRIGHT|wxLEFT, 5); - - m_textCtrlDescription = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE); - m_textCtrlDescription->SetMinSize(wxSize(-1,170)); - - bSizer21->Add(m_textCtrlDescription, 0, wxALL|wxEXPAND, 5); - - m_staticText23 = new wxStaticText(m_scrolledWindow, wxID_ANY, wxT("Page 2: Order Form"), wxDefaultPosition, wxDefaultSize, 0); - m_staticText23->Wrap(-1); - bSizer21->Add(m_staticText23, 0, wxTOP|wxRIGHT|wxLEFT, 5); - - m_textCtrlInstructions = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE); - m_textCtrlInstructions->SetMinSize(wxSize(-1,120)); - - bSizer21->Add(m_textCtrlInstructions, 0, wxEXPAND|wxALL, 5); - - fgSizer5 = new wxFlexGridSizer(0, 3, 0, 0); - fgSizer5->AddGrowableCol(1); - fgSizer5->SetFlexibleDirection(wxBOTH); - fgSizer5->SetNonFlexibleGrowMode(wxFLEX_GROWMODE_SPECIFIED); - - m_staticText24 = new wxStaticText(m_scrolledWindow, wxID_ANY, wxT("Label"), wxDefaultPosition, wxDefaultSize, 0); - m_staticText24->Wrap(-1); - fgSizer5->Add(m_staticText24, 0, wxALIGN_CENTER_VERTICAL|wxTOP|wxRIGHT|wxLEFT, 5); - - m_staticText25 = new wxStaticText(m_scrolledWindow, wxID_ANY, wxT("Comma separated list of choices, or leave blank for text field"), wxDefaultPosition, wxDefaultSize, 0); - m_staticText25->Wrap(-1); - fgSizer5->Add(m_staticText25, 0, wxALIGN_CENTER_VERTICAL|wxTOP|wxRIGHT|wxLEFT, 5); - - - fgSizer5->Add(0, 0, 1, wxEXPAND, 5); - - m_textCtrlLabel0 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0); - m_textCtrlLabel0->SetMinSize(wxSize(150,-1)); - - fgSizer5->Add(m_textCtrlLabel0, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5); - - m_textCtrlField0 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(-1,-1), 0); - fgSizer5->Add(m_textCtrlField0, 0, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5); - - m_buttonDel0 = new wxButton(m_scrolledWindow, wxID_DEL0, wxT("Delete"), wxDefaultPosition, wxSize(60,20), 0); - fgSizer5->Add(m_buttonDel0, 0, wxRIGHT|wxLEFT|wxALIGN_CENTER_VERTICAL, 5); - - m_textCtrlLabel1 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0); - m_textCtrlLabel1->SetMinSize(wxSize(150,-1)); - - fgSizer5->Add(m_textCtrlLabel1, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5); - - m_textCtrlField1 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(-1,-1), 0); - fgSizer5->Add(m_textCtrlField1, 0, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5); - - m_buttonDel1 = new wxButton(m_scrolledWindow, wxID_DEL1, wxT("Delete"), wxDefaultPosition, wxSize(60,20), 0); - fgSizer5->Add(m_buttonDel1, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5); - - m_textCtrlLabel2 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0); - m_textCtrlLabel2->SetMinSize(wxSize(150,-1)); - - fgSizer5->Add(m_textCtrlLabel2, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5); - - m_textCtrlField2 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(-1,-1), 0); - fgSizer5->Add(m_textCtrlField2, 0, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5); - - m_buttonDel2 = new wxButton(m_scrolledWindow, wxID_DEL2, wxT("Delete"), wxDefaultPosition, wxSize(60,20), 0); - fgSizer5->Add(m_buttonDel2, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5); - - m_textCtrlLabel3 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0); - m_textCtrlLabel3->SetMinSize(wxSize(150,-1)); - - fgSizer5->Add(m_textCtrlLabel3, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5); - - m_textCtrlField3 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(-1,-1), 0); - fgSizer5->Add(m_textCtrlField3, 0, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5); - - m_buttonDel3 = new wxButton(m_scrolledWindow, wxID_DEL3, wxT("Delete"), wxDefaultPosition, wxSize(60,20), 0); - fgSizer5->Add(m_buttonDel3, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5); - - m_textCtrlLabel4 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0); - m_textCtrlLabel4->SetMinSize(wxSize(150,-1)); - - fgSizer5->Add(m_textCtrlLabel4, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5); - - m_textCtrlField4 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(-1,-1), 0); - fgSizer5->Add(m_textCtrlField4, 0, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5); - - m_buttonDel4 = new wxButton(m_scrolledWindow, wxID_DEL4, wxT("Delete"), wxDefaultPosition, wxSize(60,20), 0); - fgSizer5->Add(m_buttonDel4, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5); - - m_textCtrlLabel5 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0); - m_textCtrlLabel5->SetMinSize(wxSize(150,-1)); - - fgSizer5->Add(m_textCtrlLabel5, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5); - - m_textCtrlField5 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(-1,-1), 0); - fgSizer5->Add(m_textCtrlField5, 0, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5); - - m_buttonDel5 = new wxButton(m_scrolledWindow, wxID_DEL5, wxT("Delete"), wxDefaultPosition, wxSize(60,20), 0); - fgSizer5->Add(m_buttonDel5, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5); - - m_textCtrlLabel6 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0); - m_textCtrlLabel6->SetMinSize(wxSize(150,-1)); - - fgSizer5->Add(m_textCtrlLabel6, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5); - - m_textCtrlField6 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(-1,-1), 0); - fgSizer5->Add(m_textCtrlField6, 0, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5); - - m_buttonDel6 = new wxButton(m_scrolledWindow, wxID_DEL6, wxT("Delete"), wxDefaultPosition, wxSize(60,20), 0); - fgSizer5->Add(m_buttonDel6, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5); - - m_textCtrlLabel7 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0); - m_textCtrlLabel7->SetMinSize(wxSize(150,-1)); - - fgSizer5->Add(m_textCtrlLabel7, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5); - - m_textCtrlField7 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(-1,-1), 0); - fgSizer5->Add(m_textCtrlField7, 0, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5); - - m_buttonDel7 = new wxButton(m_scrolledWindow, wxID_DEL7, wxT("Delete"), wxDefaultPosition, wxSize(60,20), 0); - fgSizer5->Add(m_buttonDel7, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5); - - m_textCtrlLabel8 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0); - m_textCtrlLabel8->SetMinSize(wxSize(150,-1)); - - fgSizer5->Add(m_textCtrlLabel8, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5); - - m_textCtrlField8 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(-1,-1), 0); - fgSizer5->Add(m_textCtrlField8, 0, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5); - - m_buttonDel8 = new wxButton(m_scrolledWindow, wxID_DEL8, wxT("Delete"), wxDefaultPosition, wxSize(60,20), 0); - fgSizer5->Add(m_buttonDel8, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5); - - m_textCtrlLabel9 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0); - m_textCtrlLabel9->SetMinSize(wxSize(150,-1)); - - fgSizer5->Add(m_textCtrlLabel9, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5); - - m_textCtrlField9 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(-1,-1), 0); - fgSizer5->Add(m_textCtrlField9, 0, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5); - - m_buttonDel9 = new wxButton(m_scrolledWindow, wxID_DEL9, wxT("Delete"), wxDefaultPosition, wxSize(60,20), 0); - fgSizer5->Add(m_buttonDel9, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5); - - m_textCtrlLabel10 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0); - m_textCtrlLabel10->SetMinSize(wxSize(150,-1)); - - fgSizer5->Add(m_textCtrlLabel10, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5); - - m_textCtrlField10 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(-1,-1), 0); - fgSizer5->Add(m_textCtrlField10, 0, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5); - - m_buttonDel10 = new wxButton(m_scrolledWindow, wxID_DEL10, wxT("Delete"), wxDefaultPosition, wxSize(60,20), 0); - fgSizer5->Add(m_buttonDel10, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5); - - m_textCtrlLabel11 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0); - m_textCtrlLabel11->SetMinSize(wxSize(150,-1)); - - fgSizer5->Add(m_textCtrlLabel11, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5); - - m_textCtrlField11 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(-1,-1), 0); - fgSizer5->Add(m_textCtrlField11, 0, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5); - - m_buttonDel11 = new wxButton(m_scrolledWindow, wxID_DEL11, wxT("Delete"), wxDefaultPosition, wxSize(60,20), 0); - fgSizer5->Add(m_buttonDel11, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5); - - m_textCtrlLabel12 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0); - m_textCtrlLabel12->SetMinSize(wxSize(150,-1)); - - fgSizer5->Add(m_textCtrlLabel12, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5); - - m_textCtrlField12 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(-1,-1), 0); - fgSizer5->Add(m_textCtrlField12, 0, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5); - - m_buttonDel12 = new wxButton(m_scrolledWindow, wxID_DEL12, wxT("Delete"), wxDefaultPosition, wxSize(60,20), 0); - fgSizer5->Add(m_buttonDel12, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5); - - m_textCtrlLabel13 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0); - m_textCtrlLabel13->SetMinSize(wxSize(150,-1)); - - fgSizer5->Add(m_textCtrlLabel13, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5); - - m_textCtrlField13 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(-1,-1), 0); - fgSizer5->Add(m_textCtrlField13, 0, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5); - - m_buttonDel13 = new wxButton(m_scrolledWindow, wxID_DEL13, wxT("Delete"), wxDefaultPosition, wxSize(60,20), 0); - fgSizer5->Add(m_buttonDel13, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5); - - m_textCtrlLabel14 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0); - m_textCtrlLabel14->SetMinSize(wxSize(150,-1)); - - fgSizer5->Add(m_textCtrlLabel14, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5); - - m_textCtrlField14 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(-1,-1), 0); - fgSizer5->Add(m_textCtrlField14, 0, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5); - - m_buttonDel14 = new wxButton(m_scrolledWindow, wxID_DEL14, wxT("Delete"), wxDefaultPosition, wxSize(60,20), 0); - fgSizer5->Add(m_buttonDel14, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5); - - m_textCtrlLabel15 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0); - m_textCtrlLabel15->SetMinSize(wxSize(150,-1)); - - fgSizer5->Add(m_textCtrlLabel15, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5); - - m_textCtrlField15 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(-1,-1), 0); - fgSizer5->Add(m_textCtrlField15, 0, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5); - - m_buttonDel15 = new wxButton(m_scrolledWindow, wxID_DEL15, wxT("Delete"), wxDefaultPosition, wxSize(60,20), 0); - fgSizer5->Add(m_buttonDel15, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5); - - m_textCtrlLabel16 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0); - m_textCtrlLabel16->SetMinSize(wxSize(150,-1)); - - fgSizer5->Add(m_textCtrlLabel16, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5); - - m_textCtrlField16 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(-1,-1), 0); - fgSizer5->Add(m_textCtrlField16, 0, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5); - - m_buttonDel16 = new wxButton(m_scrolledWindow, wxID_DEL16, wxT("Delete"), wxDefaultPosition, wxSize(60,20), 0); - fgSizer5->Add(m_buttonDel16, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5); - - m_textCtrlLabel17 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0); - m_textCtrlLabel17->SetMinSize(wxSize(150,-1)); - - fgSizer5->Add(m_textCtrlLabel17, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5); - - m_textCtrlField17 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(-1,-1), 0); - fgSizer5->Add(m_textCtrlField17, 0, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5); - - m_buttonDel17 = new wxButton(m_scrolledWindow, wxID_DEL17, wxT("Delete"), wxDefaultPosition, wxSize(60,20), 0); - fgSizer5->Add(m_buttonDel17, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5); - - m_textCtrlLabel18 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0); - m_textCtrlLabel18->SetMinSize(wxSize(150,-1)); - - fgSizer5->Add(m_textCtrlLabel18, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5); - - m_textCtrlField18 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(-1,-1), 0); - fgSizer5->Add(m_textCtrlField18, 0, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5); - - m_buttonDel18 = new wxButton(m_scrolledWindow, wxID_DEL18, wxT("Delete"), wxDefaultPosition, wxSize(60,20), 0); - fgSizer5->Add(m_buttonDel18, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5); - - m_textCtrlLabel19 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0); - m_textCtrlLabel19->SetMinSize(wxSize(150,-1)); - - fgSizer5->Add(m_textCtrlLabel19, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5); - - m_textCtrlField19 = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(-1,-1), 0); - fgSizer5->Add(m_textCtrlField19, 0, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5); - - m_buttonDel19 = new wxButton(m_scrolledWindow, wxID_DEL19, wxT("Delete"), wxDefaultPosition, wxSize(60,20), 0); - fgSizer5->Add(m_buttonDel19, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5); - - bSizer21->Add(fgSizer5, 0, wxEXPAND, 5); - - wxBoxSizer* bSizer25; - bSizer25 = new wxBoxSizer(wxHORIZONTAL); - - m_buttonAddField = new wxButton(m_scrolledWindow, wxID_ANY, wxT("&Add Field"), wxDefaultPosition, wxDefaultSize, 0); - bSizer25->Add(m_buttonAddField, 0, wxALL, 5); - - bSizer21->Add(bSizer25, 0, wxALIGN_CENTER_HORIZONTAL, 5); - - m_scrolledWindow->SetSizer(bSizer21); - m_scrolledWindow->Layout(); - bSizer21->Fit(m_scrolledWindow); - bSizer20->Add(m_scrolledWindow, 1, wxEXPAND|wxALL, 5); - - wxBoxSizer* bSizer26; - bSizer26 = new wxBoxSizer(wxHORIZONTAL); - - m_buttonOK = new wxButton(this, wxID_BUTTONSEND, wxT("&Send"), wxDefaultPosition, wxDefaultSize, 0); - m_buttonOK->SetMinSize(wxSize(85,25)); - - bSizer26->Add(m_buttonOK, 0, wxALL, 5); - - m_buttonPreview = new wxButton(this, wxID_BUTTONPREVIEW, wxT("&Preview"), wxDefaultPosition, wxDefaultSize, 0); - m_buttonPreview->SetMinSize(wxSize(85,25)); - - bSizer26->Add(m_buttonPreview, 0, wxALL, 5); - - m_buttonCancel = new wxButton(this, wxID_CANCEL, wxT("Cancel"), wxDefaultPosition, wxDefaultSize, 0); - m_buttonCancel->SetMinSize(wxSize(85,25)); - - bSizer26->Add(m_buttonCancel, 0, wxALL, 5); - - bSizer20->Add(bSizer26, 0, wxALIGN_RIGHT, 5); - - this->SetSizer(bSizer20); - this->Layout(); - - // Connect Events - m_textCtrlTitle->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); - m_textCtrlPrice->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); - m_textCtrlDescription->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); - m_textCtrlInstructions->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); - m_textCtrlLabel0->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); - m_textCtrlField0->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); - m_buttonDel0->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel0), NULL, this); - m_textCtrlLabel1->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); - m_textCtrlField1->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); - m_buttonDel1->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel1), NULL, this); - m_textCtrlLabel2->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); - m_textCtrlField2->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); - m_buttonDel2->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel2), NULL, this); - m_textCtrlLabel3->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); - m_textCtrlField3->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); - m_buttonDel3->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel3), NULL, this); - m_textCtrlLabel4->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); - m_textCtrlField4->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); - m_buttonDel4->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel4), NULL, this); - m_textCtrlLabel5->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); - m_textCtrlField5->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); - m_buttonDel5->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel5), NULL, this); - m_textCtrlLabel6->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); - m_textCtrlField6->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); - m_buttonDel6->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel6), NULL, this); - m_textCtrlLabel7->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); - m_textCtrlField7->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); - m_buttonDel7->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel7), NULL, this); - m_textCtrlLabel8->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); - m_textCtrlField8->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); - m_buttonDel8->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel8), NULL, this); - m_textCtrlLabel9->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); - m_textCtrlField9->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); - m_buttonDel9->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel9), NULL, this); - m_textCtrlLabel10->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); - m_textCtrlField10->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); - m_buttonDel10->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel10), NULL, this); - m_textCtrlLabel11->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); - m_textCtrlField11->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); - m_buttonDel11->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel11), NULL, this); - m_textCtrlLabel12->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); - m_textCtrlField12->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); - m_buttonDel12->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel12), NULL, this); - m_textCtrlLabel13->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); - m_textCtrlField13->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); - m_buttonDel13->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel13), NULL, this); - m_textCtrlLabel14->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); - m_textCtrlField14->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); - m_buttonDel14->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel14), NULL, this); - m_textCtrlLabel15->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); - m_textCtrlField15->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); - m_buttonDel15->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel15), NULL, this); - m_textCtrlLabel16->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); - m_textCtrlField16->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); - m_buttonDel16->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel16), NULL, this); - m_textCtrlLabel17->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); - m_textCtrlField17->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); - m_buttonDel17->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel17), NULL, this); - m_textCtrlLabel18->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); - m_textCtrlField18->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); - m_buttonDel18->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel18), NULL, this); - m_textCtrlLabel19->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); - m_textCtrlField19->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); - m_buttonDel19->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel19), NULL, this); - m_buttonAddField->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonAddField), NULL, this); - m_buttonOK->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonSend), NULL, this); - m_buttonPreview->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonPreview), NULL, this); - m_buttonCancel->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonCancel), NULL, this); + this->SetSizeHints( wxDefaultSize, wxDefaultSize ); + this->SetBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_MENU ) ); + + wxBoxSizer* bSizer20; + bSizer20 = new wxBoxSizer( wxVERTICAL ); + + m_scrolledWindow = new wxScrolledWindow( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxHSCROLL|wxTAB_TRAVERSAL|wxVSCROLL ); + m_scrolledWindow->SetScrollRate( 5, 5 ); + m_scrolledWindow->SetBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_WINDOW ) ); + + wxBoxSizer* bSizer21; + bSizer21 = new wxBoxSizer( wxVERTICAL ); + + wxFlexGridSizer* fgSizer8; + fgSizer8 = new wxFlexGridSizer( 0, 2, 0, 0 ); + fgSizer8->AddGrowableCol( 1 ); + fgSizer8->SetFlexibleDirection( wxBOTH ); + fgSizer8->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED ); + + m_staticText106 = new wxStaticText( m_scrolledWindow, wxID_ANY, wxT("Category"), wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT ); + m_staticText106->Wrap( -1 ); + fgSizer8->Add( m_staticText106, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxTOP|wxBOTTOM|wxLEFT, 5 ); + + m_comboBoxCategory = new wxComboBox( m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0, NULL, 0 ); + m_comboBoxCategory->SetMinSize( wxSize( 180,-1 ) ); + + fgSizer8->Add( m_comboBoxCategory, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); + + m_staticText108 = new wxStaticText( m_scrolledWindow, wxID_ANY, wxT("Title"), wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT ); + m_staticText108->Wrap( -1 ); + fgSizer8->Add( m_staticText108, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxTOP|wxBOTTOM|wxLEFT, 5 ); + + m_textCtrlTitle = new wxTextCtrl( m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); + fgSizer8->Add( m_textCtrlTitle, 1, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); + + m_staticText107 = new wxStaticText( m_scrolledWindow, wxID_ANY, wxT("Price"), wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT ); + m_staticText107->Wrap( -1 ); + fgSizer8->Add( m_staticText107, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxTOP|wxBOTTOM|wxLEFT, 5 ); + + m_textCtrlPrice = new wxTextCtrl( m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); + m_textCtrlPrice->SetMinSize( wxSize( 105,-1 ) ); + + fgSizer8->Add( m_textCtrlPrice, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); + + bSizer21->Add( fgSizer8, 0, wxEXPAND|wxTOP|wxRIGHT|wxLEFT, 5 ); + + m_staticText22 = new wxStaticText( m_scrolledWindow, wxID_ANY, wxT("Page 1: Description"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticText22->Wrap( -1 ); + bSizer21->Add( m_staticText22, 0, wxTOP|wxRIGHT|wxLEFT, 5 ); + + m_textCtrlDescription = new wxTextCtrl( m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE ); + m_textCtrlDescription->SetMinSize( wxSize( -1,170 ) ); + + bSizer21->Add( m_textCtrlDescription, 0, wxALL|wxEXPAND, 5 ); + + m_staticText23 = new wxStaticText( m_scrolledWindow, wxID_ANY, wxT("Page 2: Order Form"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticText23->Wrap( -1 ); + bSizer21->Add( m_staticText23, 0, wxTOP|wxRIGHT|wxLEFT, 5 ); + + m_textCtrlInstructions = new wxTextCtrl( m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE ); + m_textCtrlInstructions->SetMinSize( wxSize( -1,120 ) ); + + bSizer21->Add( m_textCtrlInstructions, 0, wxEXPAND|wxALL, 5 ); + + fgSizer5 = new wxFlexGridSizer( 0, 3, 0, 0 ); + fgSizer5->AddGrowableCol( 1 ); + fgSizer5->SetFlexibleDirection( wxBOTH ); + fgSizer5->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED ); + + m_staticText24 = new wxStaticText( m_scrolledWindow, wxID_ANY, wxT("Label"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticText24->Wrap( -1 ); + fgSizer5->Add( m_staticText24, 0, wxALIGN_CENTER_VERTICAL|wxTOP|wxRIGHT|wxLEFT, 5 ); + + m_staticText25 = new wxStaticText( m_scrolledWindow, wxID_ANY, wxT("Comma separated list of choices, or leave blank for text field"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticText25->Wrap( -1 ); + fgSizer5->Add( m_staticText25, 0, wxALIGN_CENTER_VERTICAL|wxTOP|wxRIGHT|wxLEFT, 5 ); + + + fgSizer5->Add( 0, 0, 1, wxEXPAND, 5 ); + + m_textCtrlLabel0 = new wxTextCtrl( m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); + m_textCtrlLabel0->SetMinSize( wxSize( 150,-1 ) ); + + fgSizer5->Add( m_textCtrlLabel0, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); + + m_textCtrlField0 = new wxTextCtrl( m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize( -1,-1 ), 0 ); + fgSizer5->Add( m_textCtrlField0, 0, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5 ); + + m_buttonDel0 = new wxButton( m_scrolledWindow, wxID_DEL0, wxT("Delete"), wxDefaultPosition, wxSize( 60,20 ), 0 ); + fgSizer5->Add( m_buttonDel0, 0, wxRIGHT|wxLEFT|wxALIGN_CENTER_VERTICAL, 5 ); + + m_textCtrlLabel1 = new wxTextCtrl( m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); + m_textCtrlLabel1->SetMinSize( wxSize( 150,-1 ) ); + + fgSizer5->Add( m_textCtrlLabel1, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); + + m_textCtrlField1 = new wxTextCtrl( m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize( -1,-1 ), 0 ); + fgSizer5->Add( m_textCtrlField1, 0, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5 ); + + m_buttonDel1 = new wxButton( m_scrolledWindow, wxID_DEL1, wxT("Delete"), wxDefaultPosition, wxSize( 60,20 ), 0 ); + fgSizer5->Add( m_buttonDel1, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 ); + + m_textCtrlLabel2 = new wxTextCtrl( m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); + m_textCtrlLabel2->SetMinSize( wxSize( 150,-1 ) ); + + fgSizer5->Add( m_textCtrlLabel2, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); + + m_textCtrlField2 = new wxTextCtrl( m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize( -1,-1 ), 0 ); + fgSizer5->Add( m_textCtrlField2, 0, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5 ); + + m_buttonDel2 = new wxButton( m_scrolledWindow, wxID_DEL2, wxT("Delete"), wxDefaultPosition, wxSize( 60,20 ), 0 ); + fgSizer5->Add( m_buttonDel2, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 ); + + m_textCtrlLabel3 = new wxTextCtrl( m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); + m_textCtrlLabel3->SetMinSize( wxSize( 150,-1 ) ); + + fgSizer5->Add( m_textCtrlLabel3, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); + + m_textCtrlField3 = new wxTextCtrl( m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize( -1,-1 ), 0 ); + fgSizer5->Add( m_textCtrlField3, 0, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5 ); + + m_buttonDel3 = new wxButton( m_scrolledWindow, wxID_DEL3, wxT("Delete"), wxDefaultPosition, wxSize( 60,20 ), 0 ); + fgSizer5->Add( m_buttonDel3, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 ); + + m_textCtrlLabel4 = new wxTextCtrl( m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); + m_textCtrlLabel4->SetMinSize( wxSize( 150,-1 ) ); + + fgSizer5->Add( m_textCtrlLabel4, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); + + m_textCtrlField4 = new wxTextCtrl( m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize( -1,-1 ), 0 ); + fgSizer5->Add( m_textCtrlField4, 0, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5 ); + + m_buttonDel4 = new wxButton( m_scrolledWindow, wxID_DEL4, wxT("Delete"), wxDefaultPosition, wxSize( 60,20 ), 0 ); + fgSizer5->Add( m_buttonDel4, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 ); + + m_textCtrlLabel5 = new wxTextCtrl( m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); + m_textCtrlLabel5->SetMinSize( wxSize( 150,-1 ) ); + + fgSizer5->Add( m_textCtrlLabel5, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); + + m_textCtrlField5 = new wxTextCtrl( m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize( -1,-1 ), 0 ); + fgSizer5->Add( m_textCtrlField5, 0, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5 ); + + m_buttonDel5 = new wxButton( m_scrolledWindow, wxID_DEL5, wxT("Delete"), wxDefaultPosition, wxSize( 60,20 ), 0 ); + fgSizer5->Add( m_buttonDel5, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 ); + + m_textCtrlLabel6 = new wxTextCtrl( m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); + m_textCtrlLabel6->SetMinSize( wxSize( 150,-1 ) ); + + fgSizer5->Add( m_textCtrlLabel6, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); + + m_textCtrlField6 = new wxTextCtrl( m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize( -1,-1 ), 0 ); + fgSizer5->Add( m_textCtrlField6, 0, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5 ); + + m_buttonDel6 = new wxButton( m_scrolledWindow, wxID_DEL6, wxT("Delete"), wxDefaultPosition, wxSize( 60,20 ), 0 ); + fgSizer5->Add( m_buttonDel6, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 ); + + m_textCtrlLabel7 = new wxTextCtrl( m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); + m_textCtrlLabel7->SetMinSize( wxSize( 150,-1 ) ); + + fgSizer5->Add( m_textCtrlLabel7, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); + + m_textCtrlField7 = new wxTextCtrl( m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize( -1,-1 ), 0 ); + fgSizer5->Add( m_textCtrlField7, 0, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5 ); + + m_buttonDel7 = new wxButton( m_scrolledWindow, wxID_DEL7, wxT("Delete"), wxDefaultPosition, wxSize( 60,20 ), 0 ); + fgSizer5->Add( m_buttonDel7, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 ); + + m_textCtrlLabel8 = new wxTextCtrl( m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); + m_textCtrlLabel8->SetMinSize( wxSize( 150,-1 ) ); + + fgSizer5->Add( m_textCtrlLabel8, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); + + m_textCtrlField8 = new wxTextCtrl( m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize( -1,-1 ), 0 ); + fgSizer5->Add( m_textCtrlField8, 0, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5 ); + + m_buttonDel8 = new wxButton( m_scrolledWindow, wxID_DEL8, wxT("Delete"), wxDefaultPosition, wxSize( 60,20 ), 0 ); + fgSizer5->Add( m_buttonDel8, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 ); + + m_textCtrlLabel9 = new wxTextCtrl( m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); + m_textCtrlLabel9->SetMinSize( wxSize( 150,-1 ) ); + + fgSizer5->Add( m_textCtrlLabel9, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); + + m_textCtrlField9 = new wxTextCtrl( m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize( -1,-1 ), 0 ); + fgSizer5->Add( m_textCtrlField9, 0, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5 ); + + m_buttonDel9 = new wxButton( m_scrolledWindow, wxID_DEL9, wxT("Delete"), wxDefaultPosition, wxSize( 60,20 ), 0 ); + fgSizer5->Add( m_buttonDel9, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 ); + + m_textCtrlLabel10 = new wxTextCtrl( m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); + m_textCtrlLabel10->SetMinSize( wxSize( 150,-1 ) ); + + fgSizer5->Add( m_textCtrlLabel10, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); + + m_textCtrlField10 = new wxTextCtrl( m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize( -1,-1 ), 0 ); + fgSizer5->Add( m_textCtrlField10, 0, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5 ); + + m_buttonDel10 = new wxButton( m_scrolledWindow, wxID_DEL10, wxT("Delete"), wxDefaultPosition, wxSize( 60,20 ), 0 ); + fgSizer5->Add( m_buttonDel10, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 ); + + m_textCtrlLabel11 = new wxTextCtrl( m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); + m_textCtrlLabel11->SetMinSize( wxSize( 150,-1 ) ); + + fgSizer5->Add( m_textCtrlLabel11, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); + + m_textCtrlField11 = new wxTextCtrl( m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize( -1,-1 ), 0 ); + fgSizer5->Add( m_textCtrlField11, 0, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5 ); + + m_buttonDel11 = new wxButton( m_scrolledWindow, wxID_DEL11, wxT("Delete"), wxDefaultPosition, wxSize( 60,20 ), 0 ); + fgSizer5->Add( m_buttonDel11, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 ); + + m_textCtrlLabel12 = new wxTextCtrl( m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); + m_textCtrlLabel12->SetMinSize( wxSize( 150,-1 ) ); + + fgSizer5->Add( m_textCtrlLabel12, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); + + m_textCtrlField12 = new wxTextCtrl( m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize( -1,-1 ), 0 ); + fgSizer5->Add( m_textCtrlField12, 0, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5 ); + + m_buttonDel12 = new wxButton( m_scrolledWindow, wxID_DEL12, wxT("Delete"), wxDefaultPosition, wxSize( 60,20 ), 0 ); + fgSizer5->Add( m_buttonDel12, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 ); + + m_textCtrlLabel13 = new wxTextCtrl( m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); + m_textCtrlLabel13->SetMinSize( wxSize( 150,-1 ) ); + + fgSizer5->Add( m_textCtrlLabel13, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); + + m_textCtrlField13 = new wxTextCtrl( m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize( -1,-1 ), 0 ); + fgSizer5->Add( m_textCtrlField13, 0, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5 ); + + m_buttonDel13 = new wxButton( m_scrolledWindow, wxID_DEL13, wxT("Delete"), wxDefaultPosition, wxSize( 60,20 ), 0 ); + fgSizer5->Add( m_buttonDel13, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 ); + + m_textCtrlLabel14 = new wxTextCtrl( m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); + m_textCtrlLabel14->SetMinSize( wxSize( 150,-1 ) ); + + fgSizer5->Add( m_textCtrlLabel14, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); + + m_textCtrlField14 = new wxTextCtrl( m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize( -1,-1 ), 0 ); + fgSizer5->Add( m_textCtrlField14, 0, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5 ); + + m_buttonDel14 = new wxButton( m_scrolledWindow, wxID_DEL14, wxT("Delete"), wxDefaultPosition, wxSize( 60,20 ), 0 ); + fgSizer5->Add( m_buttonDel14, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 ); + + m_textCtrlLabel15 = new wxTextCtrl( m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); + m_textCtrlLabel15->SetMinSize( wxSize( 150,-1 ) ); + + fgSizer5->Add( m_textCtrlLabel15, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); + + m_textCtrlField15 = new wxTextCtrl( m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize( -1,-1 ), 0 ); + fgSizer5->Add( m_textCtrlField15, 0, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5 ); + + m_buttonDel15 = new wxButton( m_scrolledWindow, wxID_DEL15, wxT("Delete"), wxDefaultPosition, wxSize( 60,20 ), 0 ); + fgSizer5->Add( m_buttonDel15, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 ); + + m_textCtrlLabel16 = new wxTextCtrl( m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); + m_textCtrlLabel16->SetMinSize( wxSize( 150,-1 ) ); + + fgSizer5->Add( m_textCtrlLabel16, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); + + m_textCtrlField16 = new wxTextCtrl( m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize( -1,-1 ), 0 ); + fgSizer5->Add( m_textCtrlField16, 0, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5 ); + + m_buttonDel16 = new wxButton( m_scrolledWindow, wxID_DEL16, wxT("Delete"), wxDefaultPosition, wxSize( 60,20 ), 0 ); + fgSizer5->Add( m_buttonDel16, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 ); + + m_textCtrlLabel17 = new wxTextCtrl( m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); + m_textCtrlLabel17->SetMinSize( wxSize( 150,-1 ) ); + + fgSizer5->Add( m_textCtrlLabel17, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); + + m_textCtrlField17 = new wxTextCtrl( m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize( -1,-1 ), 0 ); + fgSizer5->Add( m_textCtrlField17, 0, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5 ); + + m_buttonDel17 = new wxButton( m_scrolledWindow, wxID_DEL17, wxT("Delete"), wxDefaultPosition, wxSize( 60,20 ), 0 ); + fgSizer5->Add( m_buttonDel17, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 ); + + m_textCtrlLabel18 = new wxTextCtrl( m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); + m_textCtrlLabel18->SetMinSize( wxSize( 150,-1 ) ); + + fgSizer5->Add( m_textCtrlLabel18, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); + + m_textCtrlField18 = new wxTextCtrl( m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize( -1,-1 ), 0 ); + fgSizer5->Add( m_textCtrlField18, 0, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5 ); + + m_buttonDel18 = new wxButton( m_scrolledWindow, wxID_DEL18, wxT("Delete"), wxDefaultPosition, wxSize( 60,20 ), 0 ); + fgSizer5->Add( m_buttonDel18, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 ); + + m_textCtrlLabel19 = new wxTextCtrl( m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); + m_textCtrlLabel19->SetMinSize( wxSize( 150,-1 ) ); + + fgSizer5->Add( m_textCtrlLabel19, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); + + m_textCtrlField19 = new wxTextCtrl( m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize( -1,-1 ), 0 ); + fgSizer5->Add( m_textCtrlField19, 0, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5 ); + + m_buttonDel19 = new wxButton( m_scrolledWindow, wxID_DEL19, wxT("Delete"), wxDefaultPosition, wxSize( 60,20 ), 0 ); + fgSizer5->Add( m_buttonDel19, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 ); + + bSizer21->Add( fgSizer5, 0, wxEXPAND, 5 ); + + wxBoxSizer* bSizer25; + bSizer25 = new wxBoxSizer( wxHORIZONTAL ); + + m_buttonAddField = new wxButton( m_scrolledWindow, wxID_ANY, wxT("&Add Field"), wxDefaultPosition, wxDefaultSize, 0 ); + bSizer25->Add( m_buttonAddField, 0, wxALL, 5 ); + + bSizer21->Add( bSizer25, 0, wxALIGN_CENTER_HORIZONTAL, 5 ); + + m_scrolledWindow->SetSizer( bSizer21 ); + m_scrolledWindow->Layout(); + bSizer21->Fit( m_scrolledWindow ); + bSizer20->Add( m_scrolledWindow, 1, wxEXPAND|wxALL, 5 ); + + wxBoxSizer* bSizer26; + bSizer26 = new wxBoxSizer( wxHORIZONTAL ); + + m_buttonOK = new wxButton( this, wxID_BUTTONSEND, wxT("&Send"), wxDefaultPosition, wxDefaultSize, 0 ); + m_buttonOK->SetMinSize( wxSize( 85,25 ) ); + + bSizer26->Add( m_buttonOK, 0, wxALL, 5 ); + + m_buttonPreview = new wxButton( this, wxID_BUTTONPREVIEW, wxT("&Preview"), wxDefaultPosition, wxDefaultSize, 0 ); + m_buttonPreview->SetMinSize( wxSize( 85,25 ) ); + + bSizer26->Add( m_buttonPreview, 0, wxALL, 5 ); + + m_buttonCancel = new wxButton( this, wxID_CANCEL, wxT("Cancel"), wxDefaultPosition, wxDefaultSize, 0 ); + m_buttonCancel->SetMinSize( wxSize( 85,25 ) ); + + bSizer26->Add( m_buttonCancel, 0, wxALL, 5 ); + + bSizer20->Add( bSizer26, 0, wxALIGN_RIGHT, 5 ); + + this->SetSizer( bSizer20 ); + this->Layout(); + + // Connect Events + m_textCtrlTitle->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); + m_textCtrlPrice->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); + m_textCtrlDescription->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); + m_textCtrlInstructions->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); + m_textCtrlLabel0->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); + m_textCtrlField0->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); + m_buttonDel0->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditProductDialogBase::OnButtonDel0 ), NULL, this ); + m_textCtrlLabel1->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); + m_textCtrlField1->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); + m_buttonDel1->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditProductDialogBase::OnButtonDel1 ), NULL, this ); + m_textCtrlLabel2->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); + m_textCtrlField2->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); + m_buttonDel2->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditProductDialogBase::OnButtonDel2 ), NULL, this ); + m_textCtrlLabel3->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); + m_textCtrlField3->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); + m_buttonDel3->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditProductDialogBase::OnButtonDel3 ), NULL, this ); + m_textCtrlLabel4->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); + m_textCtrlField4->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); + m_buttonDel4->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditProductDialogBase::OnButtonDel4 ), NULL, this ); + m_textCtrlLabel5->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); + m_textCtrlField5->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); + m_buttonDel5->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditProductDialogBase::OnButtonDel5 ), NULL, this ); + m_textCtrlLabel6->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); + m_textCtrlField6->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); + m_buttonDel6->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditProductDialogBase::OnButtonDel6 ), NULL, this ); + m_textCtrlLabel7->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); + m_textCtrlField7->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); + m_buttonDel7->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditProductDialogBase::OnButtonDel7 ), NULL, this ); + m_textCtrlLabel8->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); + m_textCtrlField8->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); + m_buttonDel8->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditProductDialogBase::OnButtonDel8 ), NULL, this ); + m_textCtrlLabel9->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); + m_textCtrlField9->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); + m_buttonDel9->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditProductDialogBase::OnButtonDel9 ), NULL, this ); + m_textCtrlLabel10->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); + m_textCtrlField10->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); + m_buttonDel10->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditProductDialogBase::OnButtonDel10 ), NULL, this ); + m_textCtrlLabel11->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); + m_textCtrlField11->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); + m_buttonDel11->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditProductDialogBase::OnButtonDel11 ), NULL, this ); + m_textCtrlLabel12->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); + m_textCtrlField12->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); + m_buttonDel12->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditProductDialogBase::OnButtonDel12 ), NULL, this ); + m_textCtrlLabel13->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); + m_textCtrlField13->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); + m_buttonDel13->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditProductDialogBase::OnButtonDel13 ), NULL, this ); + m_textCtrlLabel14->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); + m_textCtrlField14->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); + m_buttonDel14->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditProductDialogBase::OnButtonDel14 ), NULL, this ); + m_textCtrlLabel15->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); + m_textCtrlField15->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); + m_buttonDel15->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditProductDialogBase::OnButtonDel15 ), NULL, this ); + m_textCtrlLabel16->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); + m_textCtrlField16->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); + m_buttonDel16->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditProductDialogBase::OnButtonDel16 ), NULL, this ); + m_textCtrlLabel17->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); + m_textCtrlField17->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); + m_buttonDel17->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditProductDialogBase::OnButtonDel17 ), NULL, this ); + m_textCtrlLabel18->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); + m_textCtrlField18->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); + m_buttonDel18->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditProductDialogBase::OnButtonDel18 ), NULL, this ); + m_textCtrlLabel19->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); + m_textCtrlField19->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); + m_buttonDel19->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditProductDialogBase::OnButtonDel19 ), NULL, this ); + m_buttonAddField->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditProductDialogBase::OnButtonAddField ), NULL, this ); + m_buttonOK->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditProductDialogBase::OnButtonSend ), NULL, this ); + m_buttonPreview->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditProductDialogBase::OnButtonPreview ), NULL, this ); + m_buttonCancel->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditProductDialogBase::OnButtonCancel ), NULL, this ); } CEditProductDialogBase::~CEditProductDialogBase() { - // Disconnect Events - m_textCtrlTitle->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); - m_textCtrlPrice->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); - m_textCtrlDescription->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); - m_textCtrlInstructions->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); - m_textCtrlLabel0->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); - m_textCtrlField0->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); - m_buttonDel0->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel0), NULL, this); - m_textCtrlLabel1->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); - m_textCtrlField1->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); - m_buttonDel1->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel1), NULL, this); - m_textCtrlLabel2->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); - m_textCtrlField2->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); - m_buttonDel2->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel2), NULL, this); - m_textCtrlLabel3->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); - m_textCtrlField3->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); - m_buttonDel3->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel3), NULL, this); - m_textCtrlLabel4->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); - m_textCtrlField4->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); - m_buttonDel4->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel4), NULL, this); - m_textCtrlLabel5->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); - m_textCtrlField5->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); - m_buttonDel5->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel5), NULL, this); - m_textCtrlLabel6->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); - m_textCtrlField6->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); - m_buttonDel6->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel6), NULL, this); - m_textCtrlLabel7->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); - m_textCtrlField7->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); - m_buttonDel7->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel7), NULL, this); - m_textCtrlLabel8->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); - m_textCtrlField8->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); - m_buttonDel8->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel8), NULL, this); - m_textCtrlLabel9->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); - m_textCtrlField9->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); - m_buttonDel9->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel9), NULL, this); - m_textCtrlLabel10->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); - m_textCtrlField10->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); - m_buttonDel10->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel10), NULL, this); - m_textCtrlLabel11->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); - m_textCtrlField11->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); - m_buttonDel11->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel11), NULL, this); - m_textCtrlLabel12->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); - m_textCtrlField12->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); - m_buttonDel12->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel12), NULL, this); - m_textCtrlLabel13->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); - m_textCtrlField13->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); - m_buttonDel13->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel13), NULL, this); - m_textCtrlLabel14->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); - m_textCtrlField14->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); - m_buttonDel14->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel14), NULL, this); - m_textCtrlLabel15->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); - m_textCtrlField15->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); - m_buttonDel15->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel15), NULL, this); - m_textCtrlLabel16->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); - m_textCtrlField16->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); - m_buttonDel16->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel16), NULL, this); - m_textCtrlLabel17->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); - m_textCtrlField17->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); - m_buttonDel17->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel17), NULL, this); - m_textCtrlLabel18->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); - m_textCtrlField18->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); - m_buttonDel18->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel18), NULL, this); - m_textCtrlLabel19->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); - m_textCtrlField19->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditProductDialogBase::OnKeyDown), NULL, this); - m_buttonDel19->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonDel19), NULL, this); - m_buttonAddField->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonAddField), NULL, this); - m_buttonOK->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonSend), NULL, this); - m_buttonPreview->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonPreview), NULL, this); - m_buttonCancel->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditProductDialogBase::OnButtonCancel), NULL, this); + // Disconnect Events + m_textCtrlTitle->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); + m_textCtrlPrice->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); + m_textCtrlDescription->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); + m_textCtrlInstructions->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); + m_textCtrlLabel0->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); + m_textCtrlField0->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); + m_buttonDel0->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditProductDialogBase::OnButtonDel0 ), NULL, this ); + m_textCtrlLabel1->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); + m_textCtrlField1->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); + m_buttonDel1->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditProductDialogBase::OnButtonDel1 ), NULL, this ); + m_textCtrlLabel2->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); + m_textCtrlField2->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); + m_buttonDel2->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditProductDialogBase::OnButtonDel2 ), NULL, this ); + m_textCtrlLabel3->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); + m_textCtrlField3->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); + m_buttonDel3->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditProductDialogBase::OnButtonDel3 ), NULL, this ); + m_textCtrlLabel4->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); + m_textCtrlField4->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); + m_buttonDel4->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditProductDialogBase::OnButtonDel4 ), NULL, this ); + m_textCtrlLabel5->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); + m_textCtrlField5->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); + m_buttonDel5->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditProductDialogBase::OnButtonDel5 ), NULL, this ); + m_textCtrlLabel6->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); + m_textCtrlField6->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); + m_buttonDel6->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditProductDialogBase::OnButtonDel6 ), NULL, this ); + m_textCtrlLabel7->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); + m_textCtrlField7->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); + m_buttonDel7->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditProductDialogBase::OnButtonDel7 ), NULL, this ); + m_textCtrlLabel8->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); + m_textCtrlField8->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); + m_buttonDel8->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditProductDialogBase::OnButtonDel8 ), NULL, this ); + m_textCtrlLabel9->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); + m_textCtrlField9->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); + m_buttonDel9->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditProductDialogBase::OnButtonDel9 ), NULL, this ); + m_textCtrlLabel10->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); + m_textCtrlField10->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); + m_buttonDel10->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditProductDialogBase::OnButtonDel10 ), NULL, this ); + m_textCtrlLabel11->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); + m_textCtrlField11->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); + m_buttonDel11->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditProductDialogBase::OnButtonDel11 ), NULL, this ); + m_textCtrlLabel12->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); + m_textCtrlField12->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); + m_buttonDel12->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditProductDialogBase::OnButtonDel12 ), NULL, this ); + m_textCtrlLabel13->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); + m_textCtrlField13->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); + m_buttonDel13->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditProductDialogBase::OnButtonDel13 ), NULL, this ); + m_textCtrlLabel14->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); + m_textCtrlField14->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); + m_buttonDel14->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditProductDialogBase::OnButtonDel14 ), NULL, this ); + m_textCtrlLabel15->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); + m_textCtrlField15->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); + m_buttonDel15->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditProductDialogBase::OnButtonDel15 ), NULL, this ); + m_textCtrlLabel16->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); + m_textCtrlField16->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); + m_buttonDel16->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditProductDialogBase::OnButtonDel16 ), NULL, this ); + m_textCtrlLabel17->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); + m_textCtrlField17->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); + m_buttonDel17->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditProductDialogBase::OnButtonDel17 ), NULL, this ); + m_textCtrlLabel18->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); + m_textCtrlField18->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); + m_buttonDel18->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditProductDialogBase::OnButtonDel18 ), NULL, this ); + m_textCtrlLabel19->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); + m_textCtrlField19->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); + m_buttonDel19->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditProductDialogBase::OnButtonDel19 ), NULL, this ); + m_buttonAddField->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditProductDialogBase::OnButtonAddField ), NULL, this ); + m_buttonOK->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditProductDialogBase::OnButtonSend ), NULL, this ); + m_buttonPreview->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditProductDialogBase::OnButtonPreview ), NULL, this ); + m_buttonCancel->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditProductDialogBase::OnButtonCancel ), NULL, this ); } -CViewProductDialogBase::CViewProductDialogBase(wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style) : wxFrame(parent, id, title, pos, size, style) +CViewProductDialogBase::CViewProductDialogBase( 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_MENU)); - - wxBoxSizer* bSizer20; - bSizer20 = new wxBoxSizer(wxVERTICAL); - - wxBoxSizer* bSizer116; - bSizer116 = new wxBoxSizer(wxHORIZONTAL); - - m_htmlWinReviews = new wxHtmlWindow(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxHW_SCROLLBAR_AUTO); - m_htmlWinReviews->Hide(); - - bSizer116->Add(m_htmlWinReviews, 1, wxALL|wxEXPAND, 5); - - m_scrolledWindow = new wxScrolledWindow(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxHSCROLL|wxTAB_TRAVERSAL|wxVSCROLL); - m_scrolledWindow->SetScrollRate(5, 5); - m_scrolledWindow->SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW)); - - wxBoxSizer* bSizer21; - bSizer21 = new wxBoxSizer(wxVERTICAL); - - m_richTextHeading = new wxRichTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(-1,50), wxTE_READONLY|wxNO_BORDER); - bSizer21->Add(m_richTextHeading, 0, wxEXPAND, 5); - - m_staticTextInstructions = new wxStaticText(m_scrolledWindow, wxID_ANY, wxT("Order Form instructions here\nmultiple lines\n1\n2\n3\n4\n5\n6"), wxDefaultPosition, wxDefaultSize, 0); - m_staticTextInstructions->Wrap(-1); - bSizer21->Add(m_staticTextInstructions, 0, wxALL|wxEXPAND, 5); - - wxBoxSizer* bSizer25; - bSizer25 = new wxBoxSizer(wxHORIZONTAL); - - m_buttonSubmitForm = new wxButton(m_scrolledWindow, wxID_BUTTONSAMPLE, wxT("&Submit"), wxDefaultPosition, wxDefaultSize, 0); - bSizer25->Add(m_buttonSubmitForm, 0, wxALL, 5); - - m_buttonCancelForm = new wxButton(m_scrolledWindow, wxID_CANCEL2, wxT("Cancel"), wxDefaultPosition, wxDefaultSize, 0); - bSizer25->Add(m_buttonCancelForm, 0, wxALL, 5); - - bSizer21->Add(bSizer25, 0, wxALIGN_CENTER_HORIZONTAL, 5); - - m_scrolledWindow->SetSizer(bSizer21); - m_scrolledWindow->Layout(); - bSizer21->Fit(m_scrolledWindow); - bSizer116->Add(m_scrolledWindow, 1, wxEXPAND|wxALL, 5); - - bSizer20->Add(bSizer116, 1, wxEXPAND, 5); - - wxBoxSizer* bSizer26; - bSizer26 = new wxBoxSizer(wxHORIZONTAL); - - m_buttonBack = new wxButton(this, wxID_BUTTONBACK, wxT("< &Back "), wxDefaultPosition, wxDefaultSize, 0); - m_buttonBack->Enable(false); - m_buttonBack->SetMinSize(wxSize(85,25)); - - bSizer26->Add(m_buttonBack, 0, wxALL, 5); - - m_buttonNext = new wxButton(this, wxID_BUTTONNEXT, wxT(" &Next >"), wxDefaultPosition, wxDefaultSize, 0); - m_buttonNext->SetMinSize(wxSize(85,25)); - - bSizer26->Add(m_buttonNext, 0, wxALL, 5); - - m_buttonCancel = new wxButton(this, wxID_CANCEL, wxT("Cancel"), wxDefaultPosition, wxDefaultSize, 0); - m_buttonCancel->SetMinSize(wxSize(85,25)); - - bSizer26->Add(m_buttonCancel, 0, wxALL, 5); - - bSizer20->Add(bSizer26, 0, wxALIGN_RIGHT, 5); - - this->SetSizer(bSizer20); - this->Layout(); - - // Connect Events - m_buttonSubmitForm->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CViewProductDialogBase::OnButtonSubmitForm), NULL, this); - m_buttonCancelForm->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CViewProductDialogBase::OnButtonCancelForm), NULL, this); - m_buttonBack->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CViewProductDialogBase::OnButtonBack), NULL, this); - m_buttonNext->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CViewProductDialogBase::OnButtonNext), NULL, this); - m_buttonCancel->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CViewProductDialogBase::OnButtonCancel), NULL, this); + this->SetSizeHints( wxDefaultSize, wxDefaultSize ); + this->SetBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_MENU ) ); + + wxBoxSizer* bSizer20; + bSizer20 = new wxBoxSizer( wxVERTICAL ); + + wxBoxSizer* bSizer116; + bSizer116 = new wxBoxSizer( wxHORIZONTAL ); + + m_htmlWinReviews = new wxHtmlWindow( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxHW_SCROLLBAR_AUTO ); + m_htmlWinReviews->Hide(); + + bSizer116->Add( m_htmlWinReviews, 1, wxALL|wxEXPAND, 5 ); + + m_scrolledWindow = new wxScrolledWindow( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxHSCROLL|wxTAB_TRAVERSAL|wxVSCROLL ); + m_scrolledWindow->SetScrollRate( 5, 5 ); + m_scrolledWindow->SetBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_WINDOW ) ); + + wxBoxSizer* bSizer21; + bSizer21 = new wxBoxSizer( wxVERTICAL ); + + m_richTextHeading = new wxRichTextCtrl( m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize( -1,50 ), wxTE_READONLY|wxNO_BORDER ); + bSizer21->Add( m_richTextHeading, 0, wxEXPAND, 5 ); + + m_staticTextInstructions = new wxStaticText( m_scrolledWindow, wxID_ANY, wxT("Order Form instructions here\nmultiple lines\n1\n2\n3\n4\n5\n6"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticTextInstructions->Wrap( -1 ); + bSizer21->Add( m_staticTextInstructions, 0, wxALL|wxEXPAND, 5 ); + + wxBoxSizer* bSizer25; + bSizer25 = new wxBoxSizer( wxHORIZONTAL ); + + m_buttonSubmitForm = new wxButton( m_scrolledWindow, wxID_BUTTONSAMPLE, wxT("&Submit"), wxDefaultPosition, wxDefaultSize, 0 ); + bSizer25->Add( m_buttonSubmitForm, 0, wxALL, 5 ); + + m_buttonCancelForm = new wxButton( m_scrolledWindow, wxID_CANCEL2, wxT("Cancel"), wxDefaultPosition, wxDefaultSize, 0 ); + bSizer25->Add( m_buttonCancelForm, 0, wxALL, 5 ); + + bSizer21->Add( bSizer25, 0, wxALIGN_CENTER_HORIZONTAL, 5 ); + + m_scrolledWindow->SetSizer( bSizer21 ); + m_scrolledWindow->Layout(); + bSizer21->Fit( m_scrolledWindow ); + bSizer116->Add( m_scrolledWindow, 1, wxEXPAND|wxALL, 5 ); + + bSizer20->Add( bSizer116, 1, wxEXPAND, 5 ); + + wxBoxSizer* bSizer26; + bSizer26 = new wxBoxSizer( wxHORIZONTAL ); + + m_buttonBack = new wxButton( this, wxID_BUTTONBACK, wxT("< &Back "), wxDefaultPosition, wxDefaultSize, 0 ); + m_buttonBack->Enable( false ); + m_buttonBack->SetMinSize( wxSize( 85,25 ) ); + + bSizer26->Add( m_buttonBack, 0, wxALL, 5 ); + + m_buttonNext = new wxButton( this, wxID_BUTTONNEXT, wxT(" &Next >"), wxDefaultPosition, wxDefaultSize, 0 ); + m_buttonNext->SetMinSize( wxSize( 85,25 ) ); + + bSizer26->Add( m_buttonNext, 0, wxALL, 5 ); + + m_buttonCancel = new wxButton( this, wxID_CANCEL, wxT("Cancel"), wxDefaultPosition, wxDefaultSize, 0 ); + m_buttonCancel->SetMinSize( wxSize( 85,25 ) ); + + bSizer26->Add( m_buttonCancel, 0, wxALL, 5 ); + + bSizer20->Add( bSizer26, 0, wxALIGN_RIGHT, 5 ); + + this->SetSizer( bSizer20 ); + this->Layout(); + + // Connect Events + m_buttonSubmitForm->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CViewProductDialogBase::OnButtonSubmitForm ), NULL, this ); + m_buttonCancelForm->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CViewProductDialogBase::OnButtonCancelForm ), NULL, this ); + m_buttonBack->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CViewProductDialogBase::OnButtonBack ), NULL, this ); + m_buttonNext->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CViewProductDialogBase::OnButtonNext ), NULL, this ); + m_buttonCancel->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CViewProductDialogBase::OnButtonCancel ), NULL, this ); } CViewProductDialogBase::~CViewProductDialogBase() { - // Disconnect Events - m_buttonSubmitForm->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CViewProductDialogBase::OnButtonSubmitForm), NULL, this); - m_buttonCancelForm->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CViewProductDialogBase::OnButtonCancelForm), NULL, this); - m_buttonBack->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CViewProductDialogBase::OnButtonBack), NULL, this); - m_buttonNext->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CViewProductDialogBase::OnButtonNext), NULL, this); - m_buttonCancel->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CViewProductDialogBase::OnButtonCancel), NULL, this); + // Disconnect Events + m_buttonSubmitForm->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CViewProductDialogBase::OnButtonSubmitForm ), NULL, this ); + m_buttonCancelForm->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CViewProductDialogBase::OnButtonCancelForm ), NULL, this ); + m_buttonBack->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CViewProductDialogBase::OnButtonBack ), NULL, this ); + m_buttonNext->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CViewProductDialogBase::OnButtonNext ), NULL, this ); + m_buttonCancel->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CViewProductDialogBase::OnButtonCancel ), NULL, this ); } -CViewOrderDialogBase::CViewOrderDialogBase(wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style) : wxFrame(parent, id, title, pos, size, style) +CViewOrderDialogBase::CViewOrderDialogBase( 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_MENU)); - - wxBoxSizer* bSizer20; - bSizer20 = new wxBoxSizer(wxVERTICAL); - - wxBoxSizer* bSizer116; - bSizer116 = new wxBoxSizer(wxHORIZONTAL); - - m_htmlWin = new wxHtmlWindow(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxHW_SCROLLBAR_AUTO); - bSizer116->Add(m_htmlWin, 1, wxALL|wxEXPAND, 5); - - bSizer20->Add(bSizer116, 1, wxEXPAND, 5); - - wxBoxSizer* bSizer26; - bSizer26 = new wxBoxSizer(wxHORIZONTAL); - - m_buttonOK = new wxButton(this, wxID_OK, wxT("OK"), wxDefaultPosition, wxDefaultSize, 0); - m_buttonOK->SetMinSize(wxSize(85,25)); - - bSizer26->Add(m_buttonOK, 0, wxALL, 5); - - bSizer20->Add(bSizer26, 0, wxALIGN_RIGHT, 5); - - this->SetSizer(bSizer20); - this->Layout(); - - // Connect Events - m_buttonOK->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CViewOrderDialogBase::OnButtonOK), NULL, this); + this->SetSizeHints( wxDefaultSize, wxDefaultSize ); + this->SetBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_MENU ) ); + + wxBoxSizer* bSizer20; + bSizer20 = new wxBoxSizer( wxVERTICAL ); + + wxBoxSizer* bSizer116; + bSizer116 = new wxBoxSizer( wxHORIZONTAL ); + + m_htmlWin = new wxHtmlWindow( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxHW_SCROLLBAR_AUTO ); + bSizer116->Add( m_htmlWin, 1, wxALL|wxEXPAND, 5 ); + + bSizer20->Add( bSizer116, 1, wxEXPAND, 5 ); + + wxBoxSizer* bSizer26; + bSizer26 = new wxBoxSizer( wxHORIZONTAL ); + + m_buttonOK = new wxButton( this, wxID_OK, wxT("OK"), wxDefaultPosition, wxDefaultSize, 0 ); + m_buttonOK->SetMinSize( wxSize( 85,25 ) ); + + bSizer26->Add( m_buttonOK, 0, wxALL, 5 ); + + bSizer20->Add( bSizer26, 0, wxALIGN_RIGHT, 5 ); + + this->SetSizer( bSizer20 ); + this->Layout(); + + // Connect Events + m_buttonOK->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CViewOrderDialogBase::OnButtonOK ), NULL, this ); } CViewOrderDialogBase::~CViewOrderDialogBase() { - // Disconnect Events - m_buttonOK->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CViewOrderDialogBase::OnButtonOK), NULL, this); + // Disconnect Events + m_buttonOK->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CViewOrderDialogBase::OnButtonOK ), NULL, this ); } -CEditReviewDialogBase::CEditReviewDialogBase(wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style) : wxFrame(parent, id, title, pos, size, style) +CEditReviewDialogBase::CEditReviewDialogBase( 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_MENU)); - - wxBoxSizer* bSizer112; - bSizer112 = new wxBoxSizer(wxVERTICAL); - - - bSizer112->Add(0, 3, 0, 0, 5); - - m_staticTextSeller = new wxStaticText(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0); - m_staticTextSeller->Wrap(-1); - bSizer112->Add(m_staticTextSeller, 0, wxALL|wxEXPAND, 5); - - - bSizer112->Add(0, 3, 0, 0, 5); - - m_staticText110 = new wxStaticText(this, wxID_ANY, wxT("Rating"), wxDefaultPosition, wxDefaultSize, 0); - m_staticText110->Wrap(-1); - bSizer112->Add(m_staticText110, 0, wxTOP|wxRIGHT|wxLEFT, 5); - - wxString m_choiceStarsChoices[] = { wxT(" 1 star"), wxT(" 2 stars"), wxT(" 3 stars"), wxT(" 4 stars"), wxT(" 5 stars") }; - int m_choiceStarsNChoices = sizeof(m_choiceStarsChoices) / sizeof(wxString); - m_choiceStars = new wxChoice(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, m_choiceStarsNChoices, m_choiceStarsChoices, 0); - m_choiceStars->SetSelection(0); - bSizer112->Add(m_choiceStars, 0, wxALL, 5); - - m_staticText43 = new wxStaticText(this, wxID_ANY, wxT("Review"), wxDefaultPosition, wxDefaultSize, 0); - m_staticText43->Wrap(-1); - bSizer112->Add(m_staticText43, 0, wxTOP|wxRIGHT|wxLEFT, 5); - - m_textCtrlReview = new wxTextCtrl(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE); - bSizer112->Add(m_textCtrlReview, 1, wxALL|wxEXPAND, 5); - - wxBoxSizer* bSizer113; - bSizer113 = new wxBoxSizer(wxHORIZONTAL); - - m_buttonSubmit = new wxButton(this, wxID_SUBMIT, wxT("&Submit"), wxDefaultPosition, wxDefaultSize, 0); - m_buttonSubmit->SetMinSize(wxSize(85,25)); - - bSizer113->Add(m_buttonSubmit, 0, wxALL, 5); - - m_buttonCancel = new wxButton(this, wxID_CANCEL, wxT("Cancel"), wxDefaultPosition, wxDefaultSize, 0); - m_buttonCancel->SetMinSize(wxSize(85,25)); - - bSizer113->Add(m_buttonCancel, 0, wxALL, 5); - - bSizer112->Add(bSizer113, 0, wxALIGN_RIGHT, 5); - - this->SetSizer(bSizer112); - this->Layout(); - - // Connect Events - m_textCtrlReview->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditReviewDialogBase::OnKeyDown), NULL, this); - m_buttonSubmit->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditReviewDialogBase::OnButtonSubmit), NULL, this); - m_buttonCancel->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditReviewDialogBase::OnButtonCancel), NULL, this); + this->SetSizeHints( wxDefaultSize, wxDefaultSize ); + this->SetBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_MENU ) ); + + wxBoxSizer* bSizer112; + bSizer112 = new wxBoxSizer( wxVERTICAL ); + + + bSizer112->Add( 0, 3, 0, 0, 5 ); + + m_staticTextSeller = new wxStaticText( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); + m_staticTextSeller->Wrap( -1 ); + bSizer112->Add( m_staticTextSeller, 0, wxALL|wxEXPAND, 5 ); + + + bSizer112->Add( 0, 3, 0, 0, 5 ); + + m_staticText110 = new wxStaticText( this, wxID_ANY, wxT("Rating"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticText110->Wrap( -1 ); + bSizer112->Add( m_staticText110, 0, wxTOP|wxRIGHT|wxLEFT, 5 ); + + wxString m_choiceStarsChoices[] = { wxT(" 1 star"), wxT(" 2 stars"), wxT(" 3 stars"), wxT(" 4 stars"), wxT(" 5 stars") }; + int m_choiceStarsNChoices = sizeof( m_choiceStarsChoices ) / sizeof( wxString ); + m_choiceStars = new wxChoice( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, m_choiceStarsNChoices, m_choiceStarsChoices, 0 ); + m_choiceStars->SetSelection( 0 ); + bSizer112->Add( m_choiceStars, 0, wxALL, 5 ); + + m_staticText43 = new wxStaticText( this, wxID_ANY, wxT("Review"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticText43->Wrap( -1 ); + bSizer112->Add( m_staticText43, 0, wxTOP|wxRIGHT|wxLEFT, 5 ); + + m_textCtrlReview = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE ); + bSizer112->Add( m_textCtrlReview, 1, wxALL|wxEXPAND, 5 ); + + wxBoxSizer* bSizer113; + bSizer113 = new wxBoxSizer( wxHORIZONTAL ); + + m_buttonSubmit = new wxButton( this, wxID_SUBMIT, wxT("&Submit"), wxDefaultPosition, wxDefaultSize, 0 ); + m_buttonSubmit->SetMinSize( wxSize( 85,25 ) ); + + bSizer113->Add( m_buttonSubmit, 0, wxALL, 5 ); + + m_buttonCancel = new wxButton( this, wxID_CANCEL, wxT("Cancel"), wxDefaultPosition, wxDefaultSize, 0 ); + m_buttonCancel->SetMinSize( wxSize( 85,25 ) ); + + bSizer113->Add( m_buttonCancel, 0, wxALL, 5 ); + + bSizer112->Add( bSizer113, 0, wxALIGN_RIGHT, 5 ); + + this->SetSizer( bSizer112 ); + this->Layout(); + + // Connect Events + m_textCtrlReview->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditReviewDialogBase::OnKeyDown ), NULL, this ); + m_buttonSubmit->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditReviewDialogBase::OnButtonSubmit ), NULL, this ); + m_buttonCancel->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditReviewDialogBase::OnButtonCancel ), NULL, this ); } CEditReviewDialogBase::~CEditReviewDialogBase() { - // Disconnect Events - m_textCtrlReview->Disconnect(wxEVT_KEY_DOWN, wxKeyEventHandler(CEditReviewDialogBase::OnKeyDown), NULL, this); - m_buttonSubmit->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditReviewDialogBase::OnButtonSubmit), NULL, this); - m_buttonCancel->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CEditReviewDialogBase::OnButtonCancel), NULL, this); + // Disconnect Events + m_textCtrlReview->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditReviewDialogBase::OnKeyDown ), NULL, this ); + m_buttonSubmit->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditReviewDialogBase::OnButtonSubmit ), NULL, this ); + m_buttonCancel->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditReviewDialogBase::OnButtonCancel ), NULL, this ); } -CPokerLobbyDialogBase::CPokerLobbyDialogBase(wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style) : wxFrame(parent, id, title, pos, size, style) +CPokerLobbyDialogBase::CPokerLobbyDialogBase( 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)); - - wxBoxSizer* bSizer156; - bSizer156 = new wxBoxSizer(wxHORIZONTAL); - - m_treeCtrl = new wxTreeCtrl(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTR_HAS_BUTTONS|wxTR_HIDE_ROOT|wxTR_LINES_AT_ROOT); - m_treeCtrl->SetMinSize(wxSize(130,-1)); - - bSizer156->Add(m_treeCtrl, 0, wxEXPAND|wxTOP|wxBOTTOM|wxLEFT, 5); - - wxBoxSizer* bSizer172; - bSizer172 = new wxBoxSizer(wxVERTICAL); - - m_listCtrl = new wxListCtrl(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_NO_SORT_HEADER|wxLC_REPORT); - bSizer172->Add(m_listCtrl, 1, wxEXPAND|wxALL, 5); - - m_buttonNewTable = new wxButton(this, wxID_OPENNEWTABLE, wxT("&Open New Table"), wxDefaultPosition, wxDefaultSize, 0); - bSizer172->Add(m_buttonNewTable, 0, wxALL, 5); - - bSizer156->Add(bSizer172, 1, wxEXPAND, 5); - - this->SetSizer(bSizer156); - this->Layout(); - - // Connect Events - m_treeCtrl->Connect(wxEVT_COMMAND_TREE_SEL_CHANGED, wxTreeEventHandler(CPokerLobbyDialogBase::OnTreeSelChanged), NULL, this); - m_listCtrl->Connect(wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler(CPokerLobbyDialogBase::OnListItemActivated), NULL, this); - m_listCtrl->Connect(wxEVT_COMMAND_LIST_ITEM_SELECTED, wxListEventHandler(CPokerLobbyDialogBase::OnListItemSelected), NULL, this); - m_buttonNewTable->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CPokerLobbyDialogBase::OnButtonNewTable), NULL, this); + this->SetSizeHints( wxDefaultSize, wxDefaultSize ); + this->SetBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_BTNFACE ) ); + + wxBoxSizer* bSizer156; + bSizer156 = new wxBoxSizer( wxHORIZONTAL ); + + m_treeCtrl = new wxTreeCtrl( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTR_HAS_BUTTONS|wxTR_HIDE_ROOT|wxTR_LINES_AT_ROOT ); + m_treeCtrl->SetMinSize( wxSize( 130,-1 ) ); + + bSizer156->Add( m_treeCtrl, 0, wxEXPAND|wxTOP|wxBOTTOM|wxLEFT, 5 ); + + wxBoxSizer* bSizer172; + bSizer172 = new wxBoxSizer( wxVERTICAL ); + + m_listCtrl = new wxListCtrl( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_NO_SORT_HEADER|wxLC_REPORT ); + bSizer172->Add( m_listCtrl, 1, wxEXPAND|wxALL, 5 ); + + m_buttonNewTable = new wxButton( this, wxID_OPENNEWTABLE, wxT("&Open New Table"), wxDefaultPosition, wxDefaultSize, 0 ); + bSizer172->Add( m_buttonNewTable, 0, wxALL, 5 ); + + bSizer156->Add( bSizer172, 1, wxEXPAND, 5 ); + + this->SetSizer( bSizer156 ); + this->Layout(); + + // Connect Events + m_treeCtrl->Connect( wxEVT_COMMAND_TREE_SEL_CHANGED, wxTreeEventHandler( CPokerLobbyDialogBase::OnTreeSelChanged ), NULL, this ); + m_listCtrl->Connect( wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler( CPokerLobbyDialogBase::OnListItemActivated ), NULL, this ); + m_listCtrl->Connect( wxEVT_COMMAND_LIST_ITEM_SELECTED, wxListEventHandler( CPokerLobbyDialogBase::OnListItemSelected ), NULL, this ); + m_buttonNewTable->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CPokerLobbyDialogBase::OnButtonNewTable ), NULL, this ); } CPokerLobbyDialogBase::~CPokerLobbyDialogBase() { - // Disconnect Events - m_treeCtrl->Disconnect(wxEVT_COMMAND_TREE_SEL_CHANGED, wxTreeEventHandler(CPokerLobbyDialogBase::OnTreeSelChanged), NULL, this); - m_listCtrl->Disconnect(wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler(CPokerLobbyDialogBase::OnListItemActivated), NULL, this); - m_listCtrl->Disconnect(wxEVT_COMMAND_LIST_ITEM_SELECTED, wxListEventHandler(CPokerLobbyDialogBase::OnListItemSelected), NULL, this); - m_buttonNewTable->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CPokerLobbyDialogBase::OnButtonNewTable), NULL, this); + // Disconnect Events + m_treeCtrl->Disconnect( wxEVT_COMMAND_TREE_SEL_CHANGED, wxTreeEventHandler( CPokerLobbyDialogBase::OnTreeSelChanged ), NULL, this ); + m_listCtrl->Disconnect( wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler( CPokerLobbyDialogBase::OnListItemActivated ), NULL, this ); + m_listCtrl->Disconnect( wxEVT_COMMAND_LIST_ITEM_SELECTED, wxListEventHandler( CPokerLobbyDialogBase::OnListItemSelected ), NULL, this ); + m_buttonNewTable->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CPokerLobbyDialogBase::OnButtonNewTable ), NULL, this ); } -CPokerDialogBase::CPokerDialogBase(wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style) : wxFrame(parent, id, title, pos, size, style) +CPokerDialogBase::CPokerDialogBase( 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); - - wxBoxSizer* bSizer174; - bSizer174 = new wxBoxSizer(wxVERTICAL); - - m_checkSitOut = new wxCheckBox(this, wxID_ANY, wxT("Deal Me Out"), wxDefaultPosition, wxDefaultSize, 0); - - bSizer174->Add(m_checkSitOut, 0, wxALL, 5); - - m_buttonDealHand = new wxButton(this, wxID_DEALHAND, wxT("&Deal Hand"), wxDefaultPosition, wxSize(150,25), 0); - bSizer174->Add(m_buttonDealHand, 0, wxALL, 5); - - m_buttonFold = new wxButton(this, wxID_FOLD, wxT("&Fold"), wxDefaultPosition, wxSize(80,25), 0); - bSizer174->Add(m_buttonFold, 0, wxALL, 5); - - m_buttonCall = new wxButton(this, wxID_CALL, wxT("&Call"), wxDefaultPosition, wxSize(80,25), 0); - bSizer174->Add(m_buttonCall, 0, wxALL, 5); - - m_buttonRaise = new wxButton(this, wxID_RAISE, wxT("&Raise"), wxDefaultPosition, wxSize(80,25), 0); - bSizer174->Add(m_buttonRaise, 0, wxALL, 5); - - m_buttonLeaveTable = new wxButton(this, wxID_LEAVETABLE, wxT("&Leave Table"), wxDefaultPosition, wxSize(90,25), 0); - bSizer174->Add(m_buttonLeaveTable, 0, wxALL, 5); - - m_textDitchPlayer = new wxTextCtrl(this, wxID_DITCHPLAYER, wxEmptyString, wxDefaultPosition, wxSize(45,-1), wxTE_PROCESS_ENTER); - bSizer174->Add(m_textDitchPlayer, 0, wxALL, 5); - - m_checkPreFold = new wxCheckBox(this, wxID_ANY, wxT("FOLD"), wxDefaultPosition, wxSize(100,-1), 0); - - bSizer174->Add(m_checkPreFold, 0, wxALL, 5); - - m_checkPreCall = new wxCheckBox(this, wxID_ANY, wxT("CALL"), wxDefaultPosition, wxSize(100,-1), 0); - - bSizer174->Add(m_checkPreCall, 0, wxALL, 5); - - m_checkPreCallAny = new wxCheckBox(this, wxID_ANY, wxT("CALL ANY"), wxDefaultPosition, wxSize(100,-1), 0); - - bSizer174->Add(m_checkPreCallAny, 0, wxALL, 5); - - m_checkPreRaise = new wxCheckBox(this, wxID_ANY, wxT("RAISE"), wxDefaultPosition, wxSize(100,-1), 0); - - bSizer174->Add(m_checkPreRaise, 0, wxALL, 5); - - m_checkPreRaiseAny = new wxCheckBox(this, wxID_ANY, wxT("RAISE ANY"), wxDefaultPosition, wxSize(100,-1), 0); - - bSizer174->Add(m_checkPreRaiseAny, 0, wxALL, 5); - - this->SetSizer(bSizer174); - this->Layout(); - m_statusBar = this->CreateStatusBar(1, wxST_SIZEGRIP, wxID_ANY); - - // Connect Events - this->Connect(wxEVT_CLOSE_WINDOW, wxCloseEventHandler(CPokerDialogBase::OnClose)); - this->Connect(wxEVT_LEFT_DOWN, wxMouseEventHandler(CPokerDialogBase::OnMouseEvents)); - this->Connect(wxEVT_LEFT_UP, wxMouseEventHandler(CPokerDialogBase::OnMouseEvents)); - this->Connect(wxEVT_MIDDLE_DOWN, wxMouseEventHandler(CPokerDialogBase::OnMouseEvents)); - this->Connect(wxEVT_MIDDLE_UP, wxMouseEventHandler(CPokerDialogBase::OnMouseEvents)); - this->Connect(wxEVT_RIGHT_DOWN, wxMouseEventHandler(CPokerDialogBase::OnMouseEvents)); - this->Connect(wxEVT_RIGHT_UP, wxMouseEventHandler(CPokerDialogBase::OnMouseEvents)); - this->Connect(wxEVT_MOTION, wxMouseEventHandler(CPokerDialogBase::OnMouseEvents)); - this->Connect(wxEVT_LEFT_DCLICK, wxMouseEventHandler(CPokerDialogBase::OnMouseEvents)); - this->Connect(wxEVT_MIDDLE_DCLICK, wxMouseEventHandler(CPokerDialogBase::OnMouseEvents)); - this->Connect(wxEVT_RIGHT_DCLICK, wxMouseEventHandler(CPokerDialogBase::OnMouseEvents)); - this->Connect(wxEVT_LEAVE_WINDOW, wxMouseEventHandler(CPokerDialogBase::OnMouseEvents)); - this->Connect(wxEVT_ENTER_WINDOW, wxMouseEventHandler(CPokerDialogBase::OnMouseEvents)); - this->Connect(wxEVT_MOUSEWHEEL, wxMouseEventHandler(CPokerDialogBase::OnMouseEvents)); - this->Connect(wxEVT_PAINT, wxPaintEventHandler(CPokerDialogBase::OnPaint)); - this->Connect(wxEVT_SIZE, wxSizeEventHandler(CPokerDialogBase::OnSize)); - m_checkSitOut->Connect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler(CPokerDialogBase::OnCheckSitOut), NULL, this); - m_buttonDealHand->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CPokerDialogBase::OnButtonDealHand), NULL, this); - m_buttonFold->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CPokerDialogBase::OnButtonFold), NULL, this); - m_buttonCall->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CPokerDialogBase::OnButtonCall), NULL, this); - m_buttonRaise->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CPokerDialogBase::OnButtonRaise), NULL, this); - m_buttonLeaveTable->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CPokerDialogBase::OnButtonLeaveTable), NULL, this); - m_textDitchPlayer->Connect(wxEVT_COMMAND_TEXT_ENTER, wxCommandEventHandler(CPokerDialogBase::OnDitchPlayer), NULL, this); - m_checkPreFold->Connect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler(CPokerDialogBase::OnCheckPreFold), NULL, this); - m_checkPreCall->Connect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler(CPokerDialogBase::OnCheckPreCall), NULL, this); - m_checkPreCallAny->Connect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler(CPokerDialogBase::OnCheckPreCallAny), NULL, this); - m_checkPreRaise->Connect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler(CPokerDialogBase::OnCheckPreRaise), NULL, this); - m_checkPreRaiseAny->Connect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler(CPokerDialogBase::OnCheckPreRaiseAny), NULL, this); + this->SetSizeHints( wxDefaultSize, wxDefaultSize ); + + wxBoxSizer* bSizer174; + bSizer174 = new wxBoxSizer( wxVERTICAL ); + + m_checkSitOut = new wxCheckBox( this, wxID_ANY, wxT("Deal Me Out"), wxDefaultPosition, wxDefaultSize, 0 ); + + bSizer174->Add( m_checkSitOut, 0, wxALL, 5 ); + + m_buttonDealHand = new wxButton( this, wxID_DEALHAND, wxT("&Deal Hand"), wxDefaultPosition, wxSize( 150,25 ), 0 ); + bSizer174->Add( m_buttonDealHand, 0, wxALL, 5 ); + + m_buttonFold = new wxButton( this, wxID_FOLD, wxT("&Fold"), wxDefaultPosition, wxSize( 80,25 ), 0 ); + bSizer174->Add( m_buttonFold, 0, wxALL, 5 ); + + m_buttonCall = new wxButton( this, wxID_CALL, wxT("&Call"), wxDefaultPosition, wxSize( 80,25 ), 0 ); + bSizer174->Add( m_buttonCall, 0, wxALL, 5 ); + + m_buttonRaise = new wxButton( this, wxID_RAISE, wxT("&Raise"), wxDefaultPosition, wxSize( 80,25 ), 0 ); + bSizer174->Add( m_buttonRaise, 0, wxALL, 5 ); + + m_buttonLeaveTable = new wxButton( this, wxID_LEAVETABLE, wxT("&Leave Table"), wxDefaultPosition, wxSize( 90,25 ), 0 ); + bSizer174->Add( m_buttonLeaveTable, 0, wxALL, 5 ); + + m_textDitchPlayer = new wxTextCtrl( this, wxID_DITCHPLAYER, wxEmptyString, wxDefaultPosition, wxSize( 45,-1 ), wxTE_PROCESS_ENTER ); + bSizer174->Add( m_textDitchPlayer, 0, wxALL, 5 ); + + m_checkPreFold = new wxCheckBox( this, wxID_ANY, wxT("FOLD"), wxDefaultPosition, wxSize( 100,-1 ), 0 ); + + bSizer174->Add( m_checkPreFold, 0, wxALL, 5 ); + + m_checkPreCall = new wxCheckBox( this, wxID_ANY, wxT("CALL"), wxDefaultPosition, wxSize( 100,-1 ), 0 ); + + bSizer174->Add( m_checkPreCall, 0, wxALL, 5 ); + + m_checkPreCallAny = new wxCheckBox( this, wxID_ANY, wxT("CALL ANY"), wxDefaultPosition, wxSize( 100,-1 ), 0 ); + + bSizer174->Add( m_checkPreCallAny, 0, wxALL, 5 ); + + m_checkPreRaise = new wxCheckBox( this, wxID_ANY, wxT("RAISE"), wxDefaultPosition, wxSize( 100,-1 ), 0 ); + + bSizer174->Add( m_checkPreRaise, 0, wxALL, 5 ); + + m_checkPreRaiseAny = new wxCheckBox( this, wxID_ANY, wxT("RAISE ANY"), wxDefaultPosition, wxSize( 100,-1 ), 0 ); + + bSizer174->Add( m_checkPreRaiseAny, 0, wxALL, 5 ); + + this->SetSizer( bSizer174 ); + this->Layout(); + m_statusBar = this->CreateStatusBar( 1, wxST_SIZEGRIP, wxID_ANY ); + + // Connect Events + this->Connect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( CPokerDialogBase::OnClose ) ); + this->Connect( wxEVT_LEFT_DOWN, wxMouseEventHandler( CPokerDialogBase::OnMouseEvents ) ); + this->Connect( wxEVT_LEFT_UP, wxMouseEventHandler( CPokerDialogBase::OnMouseEvents ) ); + this->Connect( wxEVT_MIDDLE_DOWN, wxMouseEventHandler( CPokerDialogBase::OnMouseEvents ) ); + this->Connect( wxEVT_MIDDLE_UP, wxMouseEventHandler( CPokerDialogBase::OnMouseEvents ) ); + this->Connect( wxEVT_RIGHT_DOWN, wxMouseEventHandler( CPokerDialogBase::OnMouseEvents ) ); + this->Connect( wxEVT_RIGHT_UP, wxMouseEventHandler( CPokerDialogBase::OnMouseEvents ) ); + this->Connect( wxEVT_MOTION, wxMouseEventHandler( CPokerDialogBase::OnMouseEvents ) ); + this->Connect( wxEVT_LEFT_DCLICK, wxMouseEventHandler( CPokerDialogBase::OnMouseEvents ) ); + this->Connect( wxEVT_MIDDLE_DCLICK, wxMouseEventHandler( CPokerDialogBase::OnMouseEvents ) ); + this->Connect( wxEVT_RIGHT_DCLICK, wxMouseEventHandler( CPokerDialogBase::OnMouseEvents ) ); + this->Connect( wxEVT_LEAVE_WINDOW, wxMouseEventHandler( CPokerDialogBase::OnMouseEvents ) ); + this->Connect( wxEVT_ENTER_WINDOW, wxMouseEventHandler( CPokerDialogBase::OnMouseEvents ) ); + this->Connect( wxEVT_MOUSEWHEEL, wxMouseEventHandler( CPokerDialogBase::OnMouseEvents ) ); + this->Connect( wxEVT_PAINT, wxPaintEventHandler( CPokerDialogBase::OnPaint ) ); + this->Connect( wxEVT_SIZE, wxSizeEventHandler( CPokerDialogBase::OnSize ) ); + m_checkSitOut->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( CPokerDialogBase::OnCheckSitOut ), NULL, this ); + m_buttonDealHand->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CPokerDialogBase::OnButtonDealHand ), NULL, this ); + m_buttonFold->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CPokerDialogBase::OnButtonFold ), NULL, this ); + m_buttonCall->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CPokerDialogBase::OnButtonCall ), NULL, this ); + m_buttonRaise->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CPokerDialogBase::OnButtonRaise ), NULL, this ); + m_buttonLeaveTable->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CPokerDialogBase::OnButtonLeaveTable ), NULL, this ); + m_textDitchPlayer->Connect( wxEVT_COMMAND_TEXT_ENTER, wxCommandEventHandler( CPokerDialogBase::OnDitchPlayer ), NULL, this ); + m_checkPreFold->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( CPokerDialogBase::OnCheckPreFold ), NULL, this ); + m_checkPreCall->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( CPokerDialogBase::OnCheckPreCall ), NULL, this ); + m_checkPreCallAny->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( CPokerDialogBase::OnCheckPreCallAny ), NULL, this ); + m_checkPreRaise->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( CPokerDialogBase::OnCheckPreRaise ), NULL, this ); + m_checkPreRaiseAny->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( CPokerDialogBase::OnCheckPreRaiseAny ), NULL, this ); } CPokerDialogBase::~CPokerDialogBase() { - // Disconnect Events - this->Disconnect(wxEVT_CLOSE_WINDOW, wxCloseEventHandler(CPokerDialogBase::OnClose)); - this->Disconnect(wxEVT_LEFT_DOWN, wxMouseEventHandler(CPokerDialogBase::OnMouseEvents)); - this->Disconnect(wxEVT_LEFT_UP, wxMouseEventHandler(CPokerDialogBase::OnMouseEvents)); - this->Disconnect(wxEVT_MIDDLE_DOWN, wxMouseEventHandler(CPokerDialogBase::OnMouseEvents)); - this->Disconnect(wxEVT_MIDDLE_UP, wxMouseEventHandler(CPokerDialogBase::OnMouseEvents)); - this->Disconnect(wxEVT_RIGHT_DOWN, wxMouseEventHandler(CPokerDialogBase::OnMouseEvents)); - this->Disconnect(wxEVT_RIGHT_UP, wxMouseEventHandler(CPokerDialogBase::OnMouseEvents)); - this->Disconnect(wxEVT_MOTION, wxMouseEventHandler(CPokerDialogBase::OnMouseEvents)); - this->Disconnect(wxEVT_LEFT_DCLICK, wxMouseEventHandler(CPokerDialogBase::OnMouseEvents)); - this->Disconnect(wxEVT_MIDDLE_DCLICK, wxMouseEventHandler(CPokerDialogBase::OnMouseEvents)); - this->Disconnect(wxEVT_RIGHT_DCLICK, wxMouseEventHandler(CPokerDialogBase::OnMouseEvents)); - this->Disconnect(wxEVT_LEAVE_WINDOW, wxMouseEventHandler(CPokerDialogBase::OnMouseEvents)); - this->Disconnect(wxEVT_ENTER_WINDOW, wxMouseEventHandler(CPokerDialogBase::OnMouseEvents)); - this->Disconnect(wxEVT_MOUSEWHEEL, wxMouseEventHandler(CPokerDialogBase::OnMouseEvents)); - this->Disconnect(wxEVT_PAINT, wxPaintEventHandler(CPokerDialogBase::OnPaint)); - this->Disconnect(wxEVT_SIZE, wxSizeEventHandler(CPokerDialogBase::OnSize)); - m_checkSitOut->Disconnect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler(CPokerDialogBase::OnCheckSitOut), NULL, this); - m_buttonDealHand->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CPokerDialogBase::OnButtonDealHand), NULL, this); - m_buttonFold->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CPokerDialogBase::OnButtonFold), NULL, this); - m_buttonCall->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CPokerDialogBase::OnButtonCall), NULL, this); - m_buttonRaise->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CPokerDialogBase::OnButtonRaise), NULL, this); - m_buttonLeaveTable->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(CPokerDialogBase::OnButtonLeaveTable), NULL, this); - m_textDitchPlayer->Disconnect(wxEVT_COMMAND_TEXT_ENTER, wxCommandEventHandler(CPokerDialogBase::OnDitchPlayer), NULL, this); - m_checkPreFold->Disconnect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler(CPokerDialogBase::OnCheckPreFold), NULL, this); - m_checkPreCall->Disconnect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler(CPokerDialogBase::OnCheckPreCall), NULL, this); - m_checkPreCallAny->Disconnect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler(CPokerDialogBase::OnCheckPreCallAny), NULL, this); - m_checkPreRaise->Disconnect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler(CPokerDialogBase::OnCheckPreRaise), NULL, this); - m_checkPreRaiseAny->Disconnect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler(CPokerDialogBase::OnCheckPreRaiseAny), NULL, this); + // Disconnect Events + this->Disconnect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( CPokerDialogBase::OnClose ) ); + this->Disconnect( wxEVT_LEFT_DOWN, wxMouseEventHandler( CPokerDialogBase::OnMouseEvents ) ); + this->Disconnect( wxEVT_LEFT_UP, wxMouseEventHandler( CPokerDialogBase::OnMouseEvents ) ); + this->Disconnect( wxEVT_MIDDLE_DOWN, wxMouseEventHandler( CPokerDialogBase::OnMouseEvents ) ); + this->Disconnect( wxEVT_MIDDLE_UP, wxMouseEventHandler( CPokerDialogBase::OnMouseEvents ) ); + this->Disconnect( wxEVT_RIGHT_DOWN, wxMouseEventHandler( CPokerDialogBase::OnMouseEvents ) ); + this->Disconnect( wxEVT_RIGHT_UP, wxMouseEventHandler( CPokerDialogBase::OnMouseEvents ) ); + this->Disconnect( wxEVT_MOTION, wxMouseEventHandler( CPokerDialogBase::OnMouseEvents ) ); + this->Disconnect( wxEVT_LEFT_DCLICK, wxMouseEventHandler( CPokerDialogBase::OnMouseEvents ) ); + this->Disconnect( wxEVT_MIDDLE_DCLICK, wxMouseEventHandler( CPokerDialogBase::OnMouseEvents ) ); + this->Disconnect( wxEVT_RIGHT_DCLICK, wxMouseEventHandler( CPokerDialogBase::OnMouseEvents ) ); + this->Disconnect( wxEVT_LEAVE_WINDOW, wxMouseEventHandler( CPokerDialogBase::OnMouseEvents ) ); + this->Disconnect( wxEVT_ENTER_WINDOW, wxMouseEventHandler( CPokerDialogBase::OnMouseEvents ) ); + this->Disconnect( wxEVT_MOUSEWHEEL, wxMouseEventHandler( CPokerDialogBase::OnMouseEvents ) ); + this->Disconnect( wxEVT_PAINT, wxPaintEventHandler( CPokerDialogBase::OnPaint ) ); + this->Disconnect( wxEVT_SIZE, wxSizeEventHandler( CPokerDialogBase::OnSize ) ); + m_checkSitOut->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( CPokerDialogBase::OnCheckSitOut ), NULL, this ); + m_buttonDealHand->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CPokerDialogBase::OnButtonDealHand ), NULL, this ); + m_buttonFold->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CPokerDialogBase::OnButtonFold ), NULL, this ); + m_buttonCall->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CPokerDialogBase::OnButtonCall ), NULL, this ); + m_buttonRaise->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CPokerDialogBase::OnButtonRaise ), NULL, this ); + m_buttonLeaveTable->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CPokerDialogBase::OnButtonLeaveTable ), NULL, this ); + m_textDitchPlayer->Disconnect( wxEVT_COMMAND_TEXT_ENTER, wxCommandEventHandler( CPokerDialogBase::OnDitchPlayer ), NULL, this ); + m_checkPreFold->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( CPokerDialogBase::OnCheckPreFold ), NULL, this ); + m_checkPreCall->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( CPokerDialogBase::OnCheckPreCall ), NULL, this ); + m_checkPreCallAny->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( CPokerDialogBase::OnCheckPreCallAny ), NULL, this ); + m_checkPreRaise->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( CPokerDialogBase::OnCheckPreRaise ), NULL, this ); + m_checkPreRaiseAny->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( CPokerDialogBase::OnCheckPreRaiseAny ), 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) +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, wxT("OK"), wxDefaultPosition, wxSize(-1,-1), 0); - m_buttonOK->SetMinSize(wxSize(85,25)); - - bSizer80->Add(m_buttonOK, 0, wxALL, 5); - - m_buttonCancel = new wxButton(this, wxID_CANCEL, wxT("Cancel"), wxDefaultPosition, wxDefaultSize, 0); - m_buttonCancel->SetMinSize(wxSize(85,25)); + 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, wxT("OK"), wxDefaultPosition, wxSize( -1,-1 ), 0 ); + m_buttonOK->SetMinSize( wxSize( 85,25 ) ); + + bSizer80->Add( m_buttonOK, 0, wxALL, 5 ); + + m_buttonCancel = new wxButton( this, wxID_CANCEL, wxT("Cancel"), wxDefaultPosition, wxDefaultSize, 0 ); + m_buttonCancel->SetMinSize( wxSize( 85,25 ) ); + + bSizer80->Add( m_buttonCancel, 0, wxALL, 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 ); +} - bSizer80->Add(m_buttonCancel, 0, wxALL, 5); +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 ); +} - bSizer79->Add(bSizer80, 0, wxEXPAND, 5); +COptionsPanelBitcoinBase::COptionsPanelBitcoinBase( wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style ) : wxPanel( parent, id, pos, size, style ) +{ + wxBoxSizer* bSizer62; + bSizer62 = new wxBoxSizer( wxVERTICAL ); + + + bSizer62->Add( 0, 20, 0, wxEXPAND, 5 ); + + m_staticText32 = new wxStaticText( this, wxID_ANY, wxT("Optional transaction fee you give to the nodes that process your transactions."), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticText32->Wrap( -1 ); + bSizer62->Add( m_staticText32, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 ); + + wxBoxSizer* bSizer56; + bSizer56 = new wxBoxSizer( wxHORIZONTAL ); + + m_staticText31 = new wxStaticText( this, wxID_ANY, wxT("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( this, wxID_TRANSACTIONFEE, wxEmptyString, wxDefaultPosition, wxSize( 70,-1 ), 0 ); + bSizer56->Add( m_textCtrlTransactionFee, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); + + bSizer62->Add( bSizer56, 0, wxEXPAND, 5 ); + + this->SetSizer( bSizer62 ); + this->Layout(); + bSizer62->Fit( this ); + + // Connect Events + m_textCtrlTransactionFee->Connect( wxEVT_KILL_FOCUS, wxFocusEventHandler( COptionsPanelBitcoinBase::OnKillFocusTransactionFee ), NULL, this ); +} - this->SetSizer(bSizer79); - this->Layout(); +COptionsPanelBitcoinBase::~COptionsPanelBitcoinBase() +{ + // Disconnect Events + m_textCtrlTransactionFee->Disconnect( wxEVT_KILL_FOCUS, wxFocusEventHandler( COptionsPanelBitcoinBase::OnKillFocusTransactionFee ), NULL, this ); +} - // 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); +COptionsPanelUIBase::COptionsPanelUIBase( wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style ) : wxPanel( parent, id, pos, size, style ) +{ + wxBoxSizer* bSizer57; + bSizer57 = new wxBoxSizer( wxVERTICAL ); + + + bSizer57->Add( 0, 20, 1, wxEXPAND, 5 ); + + m_checkMinToTray = new wxCheckBox( this, wxID_MINTOTRAY, wxT("Minimize to tray"), wxDefaultPosition, wxDefaultSize, 0 ); + + bSizer57->Add( m_checkMinToTray, 0, wxALL, 5 ); + + m_checkCloseToTray = new wxCheckBox( this, wxID_ANY, wxT("Close to tray"), wxDefaultPosition, wxDefaultSize, 0 ); + + bSizer57->Add( m_checkCloseToTray, 0, wxALL, 5 ); + + m_checkStartOnSysBoot = new wxCheckBox( this, wxID_ANY, wxT("Start on system boot"), wxDefaultPosition, wxDefaultSize, 0 ); + + bSizer57->Add( m_checkStartOnSysBoot, 0, wxALL, 5 ); + + m_checkAskBeforeClosing = new wxCheckBox( this, wxID_ANY, wxT("Ask before closing"), wxDefaultPosition, wxDefaultSize, 0 ); + + bSizer57->Add( m_checkAskBeforeClosing, 0, wxALL, 5 ); + + m_checkAlwaysShowTray = new wxCheckBox( this, wxID_ANY, wxT("Always show tray icon"), wxDefaultPosition, wxDefaultSize, 0 ); + + bSizer57->Add( m_checkAlwaysShowTray, 0, wxALL, 5 ); + + this->SetSizer( bSizer57 ); + this->Layout(); + bSizer57->Fit( this ); } -CGetTextFromUserDialogBase::~CGetTextFromUserDialogBase() +COptionsPanelUIBase::~COptionsPanelUIBase() { - // 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/uibase.h b/uibase.h index bfcd8eccb8..61e0552283 100644 --- a/uibase.h +++ b/uibase.h @@ -1,7 +1,3 @@ -// Copyright (c) 2009 Satoshi Nakamoto -// Distributed under the MIT/X11 software license, see the accompanying -// file license.txt or http://www.opensource.org/licenses/mit-license.php. - /////////////////////////////////////////////////////////////////////////// // C++ code generated with wxFormBuilder (version Apr 16 2008) // http://www.wxformbuilder.org/ @@ -34,11 +30,12 @@ #include #include #include +#include +#include #include #include #include #include -#include #include /////////////////////////////////////////////////////////////////////////// @@ -50,674 +47,721 @@ #define wxID_TEXTCTRLADDRESS 1004 #define wxID_BUTTONCOPY 1005 #define wxID_BUTTONCHANGE 1006 -#define wxID_TRANSACTIONFEE 1007 -#define wxID_TEXTCTRLPAYTO 1008 -#define wxID_BUTTONPASTE 1009 -#define wxID_BUTTONADDRESSBOOK 1010 -#define wxID_TEXTCTRLAMOUNT 1011 -#define wxID_CHOICETRANSFERTYPE 1012 -#define wxID_LISTCTRL 1013 -#define wxID_BUTTONRENAME 1014 -#define wxID_BUTTONNEW 1015 -#define wxID_BUTTONEDIT 1016 -#define wxID_BUTTONDELETE 1017 -#define wxID_DEL0 1018 -#define wxID_DEL1 1019 -#define wxID_DEL2 1020 -#define wxID_DEL3 1021 -#define wxID_DEL4 1022 -#define wxID_DEL5 1023 -#define wxID_DEL6 1024 -#define wxID_DEL7 1025 -#define wxID_DEL8 1026 -#define wxID_DEL9 1027 -#define wxID_DEL10 1028 -#define wxID_DEL11 1029 -#define wxID_DEL12 1030 -#define wxID_DEL13 1031 -#define wxID_DEL14 1032 -#define wxID_DEL15 1033 -#define wxID_DEL16 1034 -#define wxID_DEL17 1035 -#define wxID_DEL18 1036 -#define wxID_DEL19 1037 -#define wxID_BUTTONPREVIEW 1038 -#define wxID_BUTTONSAMPLE 1039 -#define wxID_CANCEL2 1040 -#define wxID_BUTTONBACK 1041 -#define wxID_BUTTONNEXT 1042 -#define wxID_SUBMIT 1043 -#define wxID_OPENNEWTABLE 1044 -#define wxID_DEALHAND 1045 -#define wxID_FOLD 1046 -#define wxID_CALL 1047 -#define wxID_RAISE 1048 -#define wxID_LEAVETABLE 1049 -#define wxID_DITCHPLAYER 1050 -#define wxID_TEXTCTRL 1051 +#define wxID_TEXTCTRLPAYTO 1007 +#define wxID_BUTTONPASTE 1008 +#define wxID_BUTTONADDRESSBOOK 1009 +#define wxID_TEXTCTRLAMOUNT 1010 +#define wxID_CHOICETRANSFERTYPE 1011 +#define wxID_LISTCTRL 1012 +#define wxID_BUTTONRENAME 1013 +#define wxID_BUTTONNEW 1014 +#define wxID_BUTTONEDIT 1015 +#define wxID_BUTTONDELETE 1016 +#define wxID_DEL0 1017 +#define wxID_DEL1 1018 +#define wxID_DEL2 1019 +#define wxID_DEL3 1020 +#define wxID_DEL4 1021 +#define wxID_DEL5 1022 +#define wxID_DEL6 1023 +#define wxID_DEL7 1024 +#define wxID_DEL8 1025 +#define wxID_DEL9 1026 +#define wxID_DEL10 1027 +#define wxID_DEL11 1028 +#define wxID_DEL12 1029 +#define wxID_DEL13 1030 +#define wxID_DEL14 1031 +#define wxID_DEL15 1032 +#define wxID_DEL16 1033 +#define wxID_DEL17 1034 +#define wxID_DEL18 1035 +#define wxID_DEL19 1036 +#define wxID_BUTTONPREVIEW 1037 +#define wxID_BUTTONSAMPLE 1038 +#define wxID_CANCEL2 1039 +#define wxID_BUTTONBACK 1040 +#define wxID_BUTTONNEXT 1041 +#define wxID_SUBMIT 1042 +#define wxID_OPENNEWTABLE 1043 +#define wxID_DEALHAND 1044 +#define wxID_FOLD 1045 +#define wxID_CALL 1046 +#define wxID_RAISE 1047 +#define wxID_LEAVETABLE 1048 +#define wxID_DITCHPLAYER 1049 +#define wxID_TEXTCTRL 1050 +#define wxID_TRANSACTIONFEE 1051 +#define wxID_MINTOTRAY 1052 /////////////////////////////////////////////////////////////////////////////// /// Class CMainFrameBase /////////////////////////////////////////////////////////////////////////////// -class CMainFrameBase : public wxFrame +class CMainFrameBase : public wxFrame { -private: - -protected: - wxMenuBar* m_menubar; - wxMenu* m_menuFile; - wxMenu* m_menuHelp; - wxToolBar* m_toolBar; - wxStatusBar* m_statusBar; - - wxStaticText* m_staticText32; - wxTextCtrl* m_textCtrlAddress; - wxButton* m_buttonCopy; - wxButton* m_button91; - - wxPanel* m_panel14; - wxStaticText* m_staticText41; - wxStaticText* m_staticTextBalance; - - wxChoice* m_choiceFilter; - wxNotebook* m_notebook; - wxPanel* m_panel7; - wxPanel* m_panel9; - wxPanel* m_panel8; - wxPanel* m_panel10; - wxPanel* m_panel11; - - // Virtual event handlers, overide them in your derived class - virtual void OnClose(wxCloseEvent& 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 OnMenuOptionsGenerate(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 OnButtonCopy(wxCommandEvent& event){ event.Skip(); } - virtual void OnButtonChange(wxCommandEvent& event){ event.Skip(); } - virtual void OnListColBeginDrag(wxListEvent& event){ event.Skip(); } - virtual void OnListItemActivatedAllTransactions(wxListEvent& event){ event.Skip(); } - virtual void OnPaintListCtrl(wxPaintEvent& event){ event.Skip(); } - virtual void OnListItemActivatedOrdersSent(wxListEvent& event){ event.Skip(); } - virtual void OnListItemActivatedProductsSent(wxListEvent& event){ event.Skip(); } - virtual void OnListItemActivatedOrdersReceived(wxListEvent& event){ event.Skip(); } - - -public: - wxMenu* m_menuOptions; - wxListCtrl* m_listCtrl; - wxListCtrl* m_listCtrlEscrows; - wxListCtrl* m_listCtrlOrdersSent; - wxListCtrl* m_listCtrlProductsSent; - wxListCtrl* m_listCtrlOrdersReceived; - CMainFrameBase(wxWindow* parent, wxWindowID id = wxID_MAINFRAME, const wxString& title = wxT("Bitcoin"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize(705,484), long style = wxDEFAULT_FRAME_STYLE|wxRESIZE_BORDER|wxTAB_TRAVERSAL); - ~CMainFrameBase(); - + private: + + protected: + wxMenuBar* m_menubar; + wxMenu* m_menuFile; + wxMenu* m_menuHelp; + wxToolBar* m_toolBar; + wxStatusBar* m_statusBar; + + wxStaticText* m_staticText32; + wxTextCtrl* m_textCtrlAddress; + wxButton* m_buttonCopy; + wxButton* m_button91; + + wxPanel* m_panel14; + wxStaticText* m_staticText41; + wxStaticText* m_staticTextBalance; + + wxChoice* m_choiceFilter; + wxNotebook* m_notebook; + wxPanel* m_panel7; + wxPanel* m_panel9; + wxPanel* m_panel8; + wxPanel* m_panel10; + wxPanel* m_panel11; + + // 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 OnMenuOptionsGenerate( wxCommandEvent& event ){ event.Skip(); } + virtual void OnUpdateMenuGenerate( wxUpdateUIEvent& 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 OnButtonCopy( wxCommandEvent& event ){ event.Skip(); } + virtual void OnButtonChange( wxCommandEvent& event ){ event.Skip(); } + virtual void OnListColBeginDrag( wxListEvent& event ){ event.Skip(); } + virtual void OnListItemActivatedAllTransactions( wxListEvent& event ){ event.Skip(); } + virtual void OnPaintListCtrl( wxPaintEvent& event ){ event.Skip(); } + virtual void OnListItemActivatedOrdersSent( wxListEvent& event ){ event.Skip(); } + virtual void OnListItemActivatedProductsSent( wxListEvent& event ){ event.Skip(); } + virtual void OnListItemActivatedOrdersReceived( wxListEvent& event ){ event.Skip(); } + + + public: + wxMenu* m_menuOptions; + wxListCtrl* m_listCtrl; + wxListCtrl* m_listCtrlEscrows; + wxListCtrl* m_listCtrlOrdersSent; + wxListCtrl* m_listCtrlProductsSent; + wxListCtrl* m_listCtrlOrdersReceived; + CMainFrameBase( wxWindow* parent, wxWindowID id = wxID_MAINFRAME, const wxString& title = wxT("Bitcoin"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 705,484 ), long style = wxDEFAULT_FRAME_STYLE|wxRESIZE_BORDER|wxTAB_TRAVERSAL ); + ~CMainFrameBase(); + }; /////////////////////////////////////////////////////////////////////////////// /// Class CTxDetailsDialogBase /////////////////////////////////////////////////////////////////////////////// -class CTxDetailsDialogBase : public wxDialog +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 = wxT("Transaction Details"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize(620,450), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER); - ~CTxDetailsDialogBase(); - + 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 = wxT("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 +class COptionsDialogBase : public wxDialog { -private: - -protected: - - wxStaticText* m_staticText32; - wxStaticText* m_staticText31; - wxTextCtrl* m_textCtrlTransactionFee; - wxButton* m_buttonOK; - wxButton* m_buttonCancel; - - // Virtual event handlers, overide them in your derived class - virtual void OnKillFocusTransactionFee(wxFocusEvent& event){ event.Skip(); } - virtual void OnButtonOK(wxCommandEvent& event){ event.Skip(); } - virtual void OnButtonCancel(wxCommandEvent& event){ event.Skip(); } - - -public: - COptionsDialogBase(wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxT("Options"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize(500,261), long style = wxDEFAULT_DIALOG_STYLE); - ~COptionsDialogBase(); - + private: + + protected: + wxBoxSizer* panelSizer; + wxTreeCtrl* m_treeCtrl; + wxStaticLine* m_staticline1; + wxButton* m_buttonOK; + wxButton* m_buttonCancel; + wxButton* m_buttonApply; + + // Virtual event handlers, overide them in your derived class + virtual void MenuSelChanged( wxTreeEvent& event ){ event.Skip(); } + virtual void OnButtonOK( wxCommandEvent& event ){ event.Skip(); } + virtual void OnButtonCancel( wxCommandEvent& event ){ event.Skip(); } + + + public: + COptionsDialogBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxT("Options"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 555,377 ), long style = wxDEFAULT_DIALOG_STYLE ); + ~COptionsDialogBase(); + }; /////////////////////////////////////////////////////////////////////////////// /// Class CAboutDialogBase /////////////////////////////////////////////////////////////////////////////// -class CAboutDialogBase : public wxDialog +class CAboutDialogBase : public wxDialog { -private: - -protected: - - - 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 = wxT("About Bitcoin"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize(507,298), long style = wxDEFAULT_DIALOG_STYLE); - ~CAboutDialogBase(); - + private: + + protected: + + + 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 = wxT("About Bitcoin"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 507,298 ), long style = wxDEFAULT_DIALOG_STYLE ); + ~CAboutDialogBase(); + }; /////////////////////////////////////////////////////////////////////////////// /// Class CSendDialogBase /////////////////////////////////////////////////////////////////////////////// -class CSendDialogBase : public wxDialog +class CSendDialogBase : public wxDialog { -private: - -protected: - - - wxStaticText* m_staticText14; - - 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; - - - wxStaticText* m_staticTextFrom; - wxTextCtrl* m_textCtrlFrom; - wxStaticText* m_staticTextMessage; - wxTextCtrl* m_textCtrlMessage; - - 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 = wxT("Send Coins"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize(675,312), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER); - ~CSendDialogBase(); - + private: + + protected: + + + wxStaticText* m_staticText14; + + 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; + + + wxStaticText* m_staticTextFrom; + wxTextCtrl* m_textCtrlFrom; + wxStaticText* m_staticTextMessage; + wxTextCtrl* m_textCtrlMessage; + + 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 = wxT("Send Coins"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 675,312 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER ); + ~CSendDialogBase(); + }; /////////////////////////////////////////////////////////////////////////////// /// Class CSendingDialogBase /////////////////////////////////////////////////////////////////////////////// -class CSendingDialogBase : public wxDialog +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 = wxT("Sending..."), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize(442,151), long style = wxDEFAULT_DIALOG_STYLE); - ~CSendingDialogBase(); - + 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 = wxT("Sending..."), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 442,151 ), long style = wxDEFAULT_DIALOG_STYLE ); + ~CSendingDialogBase(); + }; /////////////////////////////////////////////////////////////////////////////// /// Class CYourAddressDialogBase /////////////////////////////////////////////////////////////////////////////// -class CYourAddressDialogBase : public wxDialog +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 = wxT("Your Bitcoin Addresses"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize(610,390), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER); - ~CYourAddressDialogBase(); - + 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 = wxT("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 +class CAddressBookDialogBase : public wxDialog { -private: - -protected: - - wxStaticText* m_staticText55; - wxListCtrl* m_listCtrl; - - wxButton* m_buttonEdit; - wxButton* m_buttonNew; - wxButton* m_buttonDelete; - wxButton* m_buttonOK; - - // 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 OnButtonEdit(wxCommandEvent& event){ event.Skip(); } - virtual void OnButtonNew(wxCommandEvent& event){ event.Skip(); } - virtual void OnButtonDelete(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 = wxT("Address Book"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize(610,390), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER); - ~CAddressBookDialogBase(); - + private: + + protected: + + wxStaticText* m_staticText55; + wxListCtrl* m_listCtrl; + + wxButton* m_buttonEdit; + wxButton* m_buttonNew; + wxButton* m_buttonDelete; + wxButton* m_buttonOK; + + // 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 OnButtonEdit( wxCommandEvent& event ){ event.Skip(); } + virtual void OnButtonNew( wxCommandEvent& event ){ event.Skip(); } + virtual void OnButtonDelete( 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 = wxT("Address Book"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 610,390 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER ); + ~CAddressBookDialogBase(); + }; /////////////////////////////////////////////////////////////////////////////// /// Class CProductsDialogBase /////////////////////////////////////////////////////////////////////////////// -class CProductsDialogBase : public wxDialog +class CProductsDialogBase : public wxDialog { -private: - -protected: - wxComboBox* m_comboBoxCategory; - wxTextCtrl* m_textCtrlSearch; - wxButton* m_buttonSearch; - wxListCtrl* m_listCtrl; - - // Virtual event handlers, overide them in your derived class - virtual void OnCombobox(wxCommandEvent& event){ event.Skip(); } - virtual void OnKeyDown(wxKeyEvent& event){ event.Skip(); } - virtual void OnButtonSearch(wxCommandEvent& event){ event.Skip(); } - virtual void OnListItemActivated(wxListEvent& event){ event.Skip(); } - - -public: - CProductsDialogBase(wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxT("Marketplace"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize(708,535), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER); - ~CProductsDialogBase(); - + private: + + protected: + wxComboBox* m_comboBoxCategory; + wxTextCtrl* m_textCtrlSearch; + wxButton* m_buttonSearch; + wxListCtrl* m_listCtrl; + + // Virtual event handlers, overide them in your derived class + virtual void OnCombobox( wxCommandEvent& event ){ event.Skip(); } + virtual void OnKeyDown( wxKeyEvent& event ){ event.Skip(); } + virtual void OnButtonSearch( wxCommandEvent& event ){ event.Skip(); } + virtual void OnListItemActivated( wxListEvent& event ){ event.Skip(); } + + + public: + CProductsDialogBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxT("Marketplace"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 708,535 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER ); + ~CProductsDialogBase(); + }; /////////////////////////////////////////////////////////////////////////////// /// Class CEditProductDialogBase /////////////////////////////////////////////////////////////////////////////// -class CEditProductDialogBase : public wxFrame +class CEditProductDialogBase : public wxFrame { -private: - -protected: - wxScrolledWindow* m_scrolledWindow; - wxStaticText* m_staticText106; - wxComboBox* m_comboBoxCategory; - wxStaticText* m_staticText108; - wxTextCtrl* m_textCtrlTitle; - wxStaticText* m_staticText107; - wxTextCtrl* m_textCtrlPrice; - wxStaticText* m_staticText22; - wxTextCtrl* m_textCtrlDescription; - wxStaticText* m_staticText23; - wxTextCtrl* m_textCtrlInstructions; - wxStaticText* m_staticText24; - wxStaticText* m_staticText25; - - wxTextCtrl* m_textCtrlLabel0; - wxTextCtrl* m_textCtrlField0; - wxButton* m_buttonDel0; - wxTextCtrl* m_textCtrlLabel1; - wxTextCtrl* m_textCtrlField1; - wxButton* m_buttonDel1; - wxTextCtrl* m_textCtrlLabel2; - wxTextCtrl* m_textCtrlField2; - wxButton* m_buttonDel2; - wxTextCtrl* m_textCtrlLabel3; - wxTextCtrl* m_textCtrlField3; - wxButton* m_buttonDel3; - wxTextCtrl* m_textCtrlLabel4; - wxTextCtrl* m_textCtrlField4; - wxButton* m_buttonDel4; - wxTextCtrl* m_textCtrlLabel5; - wxTextCtrl* m_textCtrlField5; - wxButton* m_buttonDel5; - wxTextCtrl* m_textCtrlLabel6; - wxTextCtrl* m_textCtrlField6; - wxButton* m_buttonDel6; - wxTextCtrl* m_textCtrlLabel7; - wxTextCtrl* m_textCtrlField7; - wxButton* m_buttonDel7; - wxTextCtrl* m_textCtrlLabel8; - wxTextCtrl* m_textCtrlField8; - wxButton* m_buttonDel8; - wxTextCtrl* m_textCtrlLabel9; - wxTextCtrl* m_textCtrlField9; - wxButton* m_buttonDel9; - wxTextCtrl* m_textCtrlLabel10; - wxTextCtrl* m_textCtrlField10; - wxButton* m_buttonDel10; - wxTextCtrl* m_textCtrlLabel11; - wxTextCtrl* m_textCtrlField11; - wxButton* m_buttonDel11; - wxTextCtrl* m_textCtrlLabel12; - wxTextCtrl* m_textCtrlField12; - wxButton* m_buttonDel12; - wxTextCtrl* m_textCtrlLabel13; - wxTextCtrl* m_textCtrlField13; - wxButton* m_buttonDel13; - wxTextCtrl* m_textCtrlLabel14; - wxTextCtrl* m_textCtrlField14; - wxButton* m_buttonDel14; - wxTextCtrl* m_textCtrlLabel15; - wxTextCtrl* m_textCtrlField15; - wxButton* m_buttonDel15; - wxTextCtrl* m_textCtrlLabel16; - wxTextCtrl* m_textCtrlField16; - wxButton* m_buttonDel16; - wxTextCtrl* m_textCtrlLabel17; - wxTextCtrl* m_textCtrlField17; - wxButton* m_buttonDel17; - wxTextCtrl* m_textCtrlLabel18; - wxTextCtrl* m_textCtrlField18; - wxButton* m_buttonDel18; - wxTextCtrl* m_textCtrlLabel19; - wxTextCtrl* m_textCtrlField19; - wxButton* m_buttonDel19; - wxButton* m_buttonAddField; - wxButton* m_buttonOK; - wxButton* m_buttonPreview; - wxButton* m_buttonCancel; - - // Virtual event handlers, overide them in your derived class - virtual void OnKeyDown(wxKeyEvent& event){ event.Skip(); } - virtual void OnButtonDel0(wxCommandEvent& event){ event.Skip(); } - virtual void OnButtonDel1(wxCommandEvent& event){ event.Skip(); } - virtual void OnButtonDel2(wxCommandEvent& event){ event.Skip(); } - virtual void OnButtonDel3(wxCommandEvent& event){ event.Skip(); } - virtual void OnButtonDel4(wxCommandEvent& event){ event.Skip(); } - virtual void OnButtonDel5(wxCommandEvent& event){ event.Skip(); } - virtual void OnButtonDel6(wxCommandEvent& event){ event.Skip(); } - virtual void OnButtonDel7(wxCommandEvent& event){ event.Skip(); } - virtual void OnButtonDel8(wxCommandEvent& event){ event.Skip(); } - virtual void OnButtonDel9(wxCommandEvent& event){ event.Skip(); } - virtual void OnButtonDel10(wxCommandEvent& event){ event.Skip(); } - virtual void OnButtonDel11(wxCommandEvent& event){ event.Skip(); } - virtual void OnButtonDel12(wxCommandEvent& event){ event.Skip(); } - virtual void OnButtonDel13(wxCommandEvent& event){ event.Skip(); } - virtual void OnButtonDel14(wxCommandEvent& event){ event.Skip(); } - virtual void OnButtonDel15(wxCommandEvent& event){ event.Skip(); } - virtual void OnButtonDel16(wxCommandEvent& event){ event.Skip(); } - virtual void OnButtonDel17(wxCommandEvent& event){ event.Skip(); } - virtual void OnButtonDel18(wxCommandEvent& event){ event.Skip(); } - virtual void OnButtonDel19(wxCommandEvent& event){ event.Skip(); } - virtual void OnButtonAddField(wxCommandEvent& event){ event.Skip(); } - virtual void OnButtonSend(wxCommandEvent& event){ event.Skip(); } - virtual void OnButtonPreview(wxCommandEvent& event){ event.Skip(); } - virtual void OnButtonCancel(wxCommandEvent& event){ event.Skip(); } - - -public: - wxFlexGridSizer* fgSizer5; - CEditProductDialogBase(wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxT("Edit Product"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize(660,640), long style = wxDEFAULT_FRAME_STYLE|wxRESIZE_BORDER|wxTAB_TRAVERSAL); - ~CEditProductDialogBase(); - + private: + + protected: + wxScrolledWindow* m_scrolledWindow; + wxStaticText* m_staticText106; + wxComboBox* m_comboBoxCategory; + wxStaticText* m_staticText108; + wxTextCtrl* m_textCtrlTitle; + wxStaticText* m_staticText107; + wxTextCtrl* m_textCtrlPrice; + wxStaticText* m_staticText22; + wxTextCtrl* m_textCtrlDescription; + wxStaticText* m_staticText23; + wxTextCtrl* m_textCtrlInstructions; + wxStaticText* m_staticText24; + wxStaticText* m_staticText25; + + wxTextCtrl* m_textCtrlLabel0; + wxTextCtrl* m_textCtrlField0; + wxButton* m_buttonDel0; + wxTextCtrl* m_textCtrlLabel1; + wxTextCtrl* m_textCtrlField1; + wxButton* m_buttonDel1; + wxTextCtrl* m_textCtrlLabel2; + wxTextCtrl* m_textCtrlField2; + wxButton* m_buttonDel2; + wxTextCtrl* m_textCtrlLabel3; + wxTextCtrl* m_textCtrlField3; + wxButton* m_buttonDel3; + wxTextCtrl* m_textCtrlLabel4; + wxTextCtrl* m_textCtrlField4; + wxButton* m_buttonDel4; + wxTextCtrl* m_textCtrlLabel5; + wxTextCtrl* m_textCtrlField5; + wxButton* m_buttonDel5; + wxTextCtrl* m_textCtrlLabel6; + wxTextCtrl* m_textCtrlField6; + wxButton* m_buttonDel6; + wxTextCtrl* m_textCtrlLabel7; + wxTextCtrl* m_textCtrlField7; + wxButton* m_buttonDel7; + wxTextCtrl* m_textCtrlLabel8; + wxTextCtrl* m_textCtrlField8; + wxButton* m_buttonDel8; + wxTextCtrl* m_textCtrlLabel9; + wxTextCtrl* m_textCtrlField9; + wxButton* m_buttonDel9; + wxTextCtrl* m_textCtrlLabel10; + wxTextCtrl* m_textCtrlField10; + wxButton* m_buttonDel10; + wxTextCtrl* m_textCtrlLabel11; + wxTextCtrl* m_textCtrlField11; + wxButton* m_buttonDel11; + wxTextCtrl* m_textCtrlLabel12; + wxTextCtrl* m_textCtrlField12; + wxButton* m_buttonDel12; + wxTextCtrl* m_textCtrlLabel13; + wxTextCtrl* m_textCtrlField13; + wxButton* m_buttonDel13; + wxTextCtrl* m_textCtrlLabel14; + wxTextCtrl* m_textCtrlField14; + wxButton* m_buttonDel14; + wxTextCtrl* m_textCtrlLabel15; + wxTextCtrl* m_textCtrlField15; + wxButton* m_buttonDel15; + wxTextCtrl* m_textCtrlLabel16; + wxTextCtrl* m_textCtrlField16; + wxButton* m_buttonDel16; + wxTextCtrl* m_textCtrlLabel17; + wxTextCtrl* m_textCtrlField17; + wxButton* m_buttonDel17; + wxTextCtrl* m_textCtrlLabel18; + wxTextCtrl* m_textCtrlField18; + wxButton* m_buttonDel18; + wxTextCtrl* m_textCtrlLabel19; + wxTextCtrl* m_textCtrlField19; + wxButton* m_buttonDel19; + wxButton* m_buttonAddField; + wxButton* m_buttonOK; + wxButton* m_buttonPreview; + wxButton* m_buttonCancel; + + // Virtual event handlers, overide them in your derived class + virtual void OnKeyDown( wxKeyEvent& event ){ event.Skip(); } + virtual void OnButtonDel0( wxCommandEvent& event ){ event.Skip(); } + virtual void OnButtonDel1( wxCommandEvent& event ){ event.Skip(); } + virtual void OnButtonDel2( wxCommandEvent& event ){ event.Skip(); } + virtual void OnButtonDel3( wxCommandEvent& event ){ event.Skip(); } + virtual void OnButtonDel4( wxCommandEvent& event ){ event.Skip(); } + virtual void OnButtonDel5( wxCommandEvent& event ){ event.Skip(); } + virtual void OnButtonDel6( wxCommandEvent& event ){ event.Skip(); } + virtual void OnButtonDel7( wxCommandEvent& event ){ event.Skip(); } + virtual void OnButtonDel8( wxCommandEvent& event ){ event.Skip(); } + virtual void OnButtonDel9( wxCommandEvent& event ){ event.Skip(); } + virtual void OnButtonDel10( wxCommandEvent& event ){ event.Skip(); } + virtual void OnButtonDel11( wxCommandEvent& event ){ event.Skip(); } + virtual void OnButtonDel12( wxCommandEvent& event ){ event.Skip(); } + virtual void OnButtonDel13( wxCommandEvent& event ){ event.Skip(); } + virtual void OnButtonDel14( wxCommandEvent& event ){ event.Skip(); } + virtual void OnButtonDel15( wxCommandEvent& event ){ event.Skip(); } + virtual void OnButtonDel16( wxCommandEvent& event ){ event.Skip(); } + virtual void OnButtonDel17( wxCommandEvent& event ){ event.Skip(); } + virtual void OnButtonDel18( wxCommandEvent& event ){ event.Skip(); } + virtual void OnButtonDel19( wxCommandEvent& event ){ event.Skip(); } + virtual void OnButtonAddField( wxCommandEvent& event ){ event.Skip(); } + virtual void OnButtonSend( wxCommandEvent& event ){ event.Skip(); } + virtual void OnButtonPreview( wxCommandEvent& event ){ event.Skip(); } + virtual void OnButtonCancel( wxCommandEvent& event ){ event.Skip(); } + + + public: + wxFlexGridSizer* fgSizer5; + CEditProductDialogBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxT("Edit Product"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 660,640 ), long style = wxDEFAULT_FRAME_STYLE|wxRESIZE_BORDER|wxTAB_TRAVERSAL ); + ~CEditProductDialogBase(); + }; /////////////////////////////////////////////////////////////////////////////// /// Class CViewProductDialogBase /////////////////////////////////////////////////////////////////////////////// -class CViewProductDialogBase : public wxFrame +class CViewProductDialogBase : public wxFrame { -private: - -protected: - wxHtmlWindow* m_htmlWinReviews; - wxScrolledWindow* m_scrolledWindow; - wxRichTextCtrl* m_richTextHeading; - wxStaticText* m_staticTextInstructions; - wxButton* m_buttonSubmitForm; - wxButton* m_buttonCancelForm; - wxButton* m_buttonBack; - wxButton* m_buttonNext; - wxButton* m_buttonCancel; - - // Virtual event handlers, overide them in your derived class - virtual void OnButtonSubmitForm(wxCommandEvent& event){ event.Skip(); } - virtual void OnButtonCancelForm(wxCommandEvent& event){ event.Skip(); } - virtual void OnButtonBack(wxCommandEvent& event){ event.Skip(); } - virtual void OnButtonNext(wxCommandEvent& event){ event.Skip(); } - virtual void OnButtonCancel(wxCommandEvent& event){ event.Skip(); } - - -public: - CViewProductDialogBase(wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxT("Order Form"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize(630,520), long style = wxDEFAULT_FRAME_STYLE|wxRESIZE_BORDER|wxTAB_TRAVERSAL); - ~CViewProductDialogBase(); - + private: + + protected: + wxHtmlWindow* m_htmlWinReviews; + wxScrolledWindow* m_scrolledWindow; + wxRichTextCtrl* m_richTextHeading; + wxStaticText* m_staticTextInstructions; + wxButton* m_buttonSubmitForm; + wxButton* m_buttonCancelForm; + wxButton* m_buttonBack; + wxButton* m_buttonNext; + wxButton* m_buttonCancel; + + // Virtual event handlers, overide them in your derived class + virtual void OnButtonSubmitForm( wxCommandEvent& event ){ event.Skip(); } + virtual void OnButtonCancelForm( wxCommandEvent& event ){ event.Skip(); } + virtual void OnButtonBack( wxCommandEvent& event ){ event.Skip(); } + virtual void OnButtonNext( wxCommandEvent& event ){ event.Skip(); } + virtual void OnButtonCancel( wxCommandEvent& event ){ event.Skip(); } + + + public: + CViewProductDialogBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxT("Order Form"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 630,520 ), long style = wxDEFAULT_FRAME_STYLE|wxRESIZE_BORDER|wxTAB_TRAVERSAL ); + ~CViewProductDialogBase(); + }; /////////////////////////////////////////////////////////////////////////////// /// Class CViewOrderDialogBase /////////////////////////////////////////////////////////////////////////////// -class CViewOrderDialogBase : public wxFrame +class CViewOrderDialogBase : public wxFrame { -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: - CViewOrderDialogBase(wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxT("View Order"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize(630,520), long style = wxDEFAULT_FRAME_STYLE|wxRESIZE_BORDER|wxTAB_TRAVERSAL); - ~CViewOrderDialogBase(); - + 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: + CViewOrderDialogBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxT("View Order"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 630,520 ), long style = wxDEFAULT_FRAME_STYLE|wxRESIZE_BORDER|wxTAB_TRAVERSAL ); + ~CViewOrderDialogBase(); + }; /////////////////////////////////////////////////////////////////////////////// /// Class CEditReviewDialogBase /////////////////////////////////////////////////////////////////////////////// -class CEditReviewDialogBase : public wxFrame +class CEditReviewDialogBase : public wxFrame { -private: - -protected: - - wxStaticText* m_staticTextSeller; - - wxStaticText* m_staticText110; - wxChoice* m_choiceStars; - wxStaticText* m_staticText43; - wxTextCtrl* m_textCtrlReview; - wxButton* m_buttonSubmit; - wxButton* m_buttonCancel; - - // Virtual event handlers, overide them in your derived class - virtual void OnKeyDown(wxKeyEvent& event){ event.Skip(); } - virtual void OnButtonSubmit(wxCommandEvent& event){ event.Skip(); } - virtual void OnButtonCancel(wxCommandEvent& event){ event.Skip(); } - - -public: - CEditReviewDialogBase(wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxT("Enter Review"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize(630,440), long style = wxDEFAULT_FRAME_STYLE|wxRESIZE_BORDER|wxTAB_TRAVERSAL); - ~CEditReviewDialogBase(); - + private: + + protected: + + wxStaticText* m_staticTextSeller; + + wxStaticText* m_staticText110; + wxChoice* m_choiceStars; + wxStaticText* m_staticText43; + wxTextCtrl* m_textCtrlReview; + wxButton* m_buttonSubmit; + wxButton* m_buttonCancel; + + // Virtual event handlers, overide them in your derived class + virtual void OnKeyDown( wxKeyEvent& event ){ event.Skip(); } + virtual void OnButtonSubmit( wxCommandEvent& event ){ event.Skip(); } + virtual void OnButtonCancel( wxCommandEvent& event ){ event.Skip(); } + + + public: + CEditReviewDialogBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxT("Enter Review"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 630,440 ), long style = wxDEFAULT_FRAME_STYLE|wxRESIZE_BORDER|wxTAB_TRAVERSAL ); + ~CEditReviewDialogBase(); + }; /////////////////////////////////////////////////////////////////////////////// /// Class CPokerLobbyDialogBase /////////////////////////////////////////////////////////////////////////////// -class CPokerLobbyDialogBase : public wxFrame +class CPokerLobbyDialogBase : public wxFrame { -private: - -protected: - wxTreeCtrl* m_treeCtrl; - wxListCtrl* m_listCtrl; - wxButton* m_buttonNewTable; - - // Virtual event handlers, overide them in your derived class - virtual void OnTreeSelChanged(wxTreeEvent& event){ event.Skip(); } - virtual void OnListItemActivated(wxListEvent& event){ event.Skip(); } - virtual void OnListItemSelected(wxListEvent& event){ event.Skip(); } - virtual void OnButtonNewTable(wxCommandEvent& event){ event.Skip(); } - - -public: - CPokerLobbyDialogBase(wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxT("Poker Lobby"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize(586,457), long style = wxDEFAULT_FRAME_STYLE|wxTAB_TRAVERSAL); - ~CPokerLobbyDialogBase(); - + private: + + protected: + wxTreeCtrl* m_treeCtrl; + wxListCtrl* m_listCtrl; + wxButton* m_buttonNewTable; + + // Virtual event handlers, overide them in your derived class + virtual void OnTreeSelChanged( wxTreeEvent& event ){ event.Skip(); } + virtual void OnListItemActivated( wxListEvent& event ){ event.Skip(); } + virtual void OnListItemSelected( wxListEvent& event ){ event.Skip(); } + virtual void OnButtonNewTable( wxCommandEvent& event ){ event.Skip(); } + + + public: + CPokerLobbyDialogBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxT("Poker Lobby"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 586,457 ), long style = wxDEFAULT_FRAME_STYLE|wxTAB_TRAVERSAL ); + ~CPokerLobbyDialogBase(); + }; /////////////////////////////////////////////////////////////////////////////// /// Class CPokerDialogBase /////////////////////////////////////////////////////////////////////////////// -class CPokerDialogBase : public wxFrame +class CPokerDialogBase : public wxFrame { -private: - -protected: - wxButton* m_buttonDealHand; - wxButton* m_buttonFold; - wxButton* m_buttonCall; - wxButton* m_buttonRaise; - wxButton* m_buttonLeaveTable; - wxTextCtrl* m_textDitchPlayer; - - // Virtual event handlers, overide them in your derived class - virtual void OnClose(wxCloseEvent& event){ event.Skip(); } - virtual void OnMouseEvents(wxMouseEvent& event){ event.Skip(); } - virtual void OnPaint(wxPaintEvent& event){ event.Skip(); } - virtual void OnSize(wxSizeEvent& event){ event.Skip(); } - virtual void OnCheckSitOut(wxCommandEvent& event){ event.Skip(); } - virtual void OnButtonDealHand(wxCommandEvent& event){ event.Skip(); } - virtual void OnButtonFold(wxCommandEvent& event){ event.Skip(); } - virtual void OnButtonCall(wxCommandEvent& event){ event.Skip(); } - virtual void OnButtonRaise(wxCommandEvent& event){ event.Skip(); } - virtual void OnButtonLeaveTable(wxCommandEvent& event){ event.Skip(); } - virtual void OnDitchPlayer(wxCommandEvent& event){ event.Skip(); } - virtual void OnCheckPreFold(wxCommandEvent& event){ event.Skip(); } - virtual void OnCheckPreCall(wxCommandEvent& event){ event.Skip(); } - virtual void OnCheckPreCallAny(wxCommandEvent& event){ event.Skip(); } - virtual void OnCheckPreRaise(wxCommandEvent& event){ event.Skip(); } - virtual void OnCheckPreRaiseAny(wxCommandEvent& event){ event.Skip(); } - - -public: - wxCheckBox* m_checkSitOut; - wxCheckBox* m_checkPreFold; - wxCheckBox* m_checkPreCall; - wxCheckBox* m_checkPreCallAny; - wxCheckBox* m_checkPreRaise; - wxCheckBox* m_checkPreRaiseAny; - wxStatusBar* m_statusBar; - CPokerDialogBase(wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxT("Poker"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize(806,550), long style = wxDEFAULT_FRAME_STYLE|wxFRAME_NO_TASKBAR|wxFULL_REPAINT_ON_RESIZE|wxTAB_TRAVERSAL); - ~CPokerDialogBase(); - + private: + + protected: + wxButton* m_buttonDealHand; + wxButton* m_buttonFold; + wxButton* m_buttonCall; + wxButton* m_buttonRaise; + wxButton* m_buttonLeaveTable; + wxTextCtrl* m_textDitchPlayer; + + // Virtual event handlers, overide them in your derived class + virtual void OnClose( wxCloseEvent& event ){ event.Skip(); } + virtual void OnMouseEvents( wxMouseEvent& event ){ event.Skip(); } + virtual void OnPaint( wxPaintEvent& event ){ event.Skip(); } + virtual void OnSize( wxSizeEvent& event ){ event.Skip(); } + virtual void OnCheckSitOut( wxCommandEvent& event ){ event.Skip(); } + virtual void OnButtonDealHand( wxCommandEvent& event ){ event.Skip(); } + virtual void OnButtonFold( wxCommandEvent& event ){ event.Skip(); } + virtual void OnButtonCall( wxCommandEvent& event ){ event.Skip(); } + virtual void OnButtonRaise( wxCommandEvent& event ){ event.Skip(); } + virtual void OnButtonLeaveTable( wxCommandEvent& event ){ event.Skip(); } + virtual void OnDitchPlayer( wxCommandEvent& event ){ event.Skip(); } + virtual void OnCheckPreFold( wxCommandEvent& event ){ event.Skip(); } + virtual void OnCheckPreCall( wxCommandEvent& event ){ event.Skip(); } + virtual void OnCheckPreCallAny( wxCommandEvent& event ){ event.Skip(); } + virtual void OnCheckPreRaise( wxCommandEvent& event ){ event.Skip(); } + virtual void OnCheckPreRaiseAny( wxCommandEvent& event ){ event.Skip(); } + + + public: + wxCheckBox* m_checkSitOut; + wxCheckBox* m_checkPreFold; + wxCheckBox* m_checkPreCall; + wxCheckBox* m_checkPreCallAny; + wxCheckBox* m_checkPreRaise; + wxCheckBox* m_checkPreRaiseAny; + wxStatusBar* m_statusBar; + CPokerDialogBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxT("Poker"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 806,550 ), long style = wxDEFAULT_FRAME_STYLE|wxFRAME_NO_TASKBAR|wxFULL_REPAINT_ON_RESIZE|wxTAB_TRAVERSAL ); + ~CPokerDialogBase(); + }; /////////////////////////////////////////////////////////////////////////////// /// Class CGetTextFromUserDialogBase /////////////////////////////////////////////////////////////////////////////// -class CGetTextFromUserDialogBase : public wxDialog +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(); } - + 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( 403,138 ), long style = wxDEFAULT_DIALOG_STYLE ); + ~CGetTextFromUserDialogBase(); + +}; -public: - CGetTextFromUserDialogBase(wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxEmptyString, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize(403,138), long style = wxDEFAULT_DIALOG_STYLE); - ~CGetTextFromUserDialogBase(); +/////////////////////////////////////////////////////////////////////////////// +/// Class COptionsPanelBitcoinBase +/////////////////////////////////////////////////////////////////////////////// +class COptionsPanelBitcoinBase : public wxPanel +{ + private: + + protected: + + wxStaticText* m_staticText32; + wxStaticText* m_staticText31; + + // Virtual event handlers, overide them in your derived class + virtual void OnKillFocusTransactionFee( wxFocusEvent& event ){ event.Skip(); } + + + public: + wxTextCtrl* m_textCtrlTransactionFee; + COptionsPanelBitcoinBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxTAB_TRAVERSAL ); + ~COptionsPanelBitcoinBase(); + +}; +/////////////////////////////////////////////////////////////////////////////// +/// Class COptionsPanelUIBase +/////////////////////////////////////////////////////////////////////////////// +class COptionsPanelUIBase : public wxPanel +{ + private: + + protected: + + + public: + wxCheckBox* m_checkMinToTray; + wxCheckBox* m_checkCloseToTray; + wxCheckBox* m_checkStartOnSysBoot; + wxCheckBox* m_checkAskBeforeClosing; + wxCheckBox* m_checkAlwaysShowTray; + COptionsPanelUIBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxTAB_TRAVERSAL ); + ~COptionsPanelUIBase(); + }; #endif //__uibase__ diff --git a/uiproject.fbp b/uiproject.fbp index 49b1fefaaf..ccd8b2222f 100644 --- a/uiproject.fbp +++ b/uiproject.fbp @@ -18,7 +18,7 @@ 1 0 0 - + wxSYS_COLOUR_BTNFACE @@ -48,7 +48,7 @@ - + OnIconize OnIdle @@ -151,7 +151,7 @@ OnMenuOptionsGenerate - + OnUpdateMenuGenerate @@ -1665,7 +1665,7 @@ - + @@ -1679,7 +1679,7 @@ COptionsDialogBase - 500,261 + 555,377 wxDEFAULT_DIALOG_STYLE Options @@ -1724,28 +1724,18 @@ none 5 - wxEXPAND|wxLEFT + wxEXPAND 1 - bSizer57 - wxVERTICAL - none - - 5 - wxEXPAND - 0 - - 20 - protected - 0 - - + panelSizer + wxHORIZONTAL + protected 5 - wxALIGN_CENTER_VERTICAL|wxALL + wxALL|wxEXPAND 0 - + 1 @@ -1753,20 +1743,18 @@ 0 wxID_ANY - Optional transaction fee you give to the nodes that process your transactions. - m_staticText32 + m_treeCtrl protected - - + 100,-1 + wxTR_HAS_BUTTONS|wxTR_HIDE_ROOT|wxTR_LINES_AT_ROOT - -1 @@ -1789,126 +1777,79 @@ + + + + + + + + + + + + + + + + + + MenuSelChanged + + + - - 5 - wxEXPAND - 0 - - - bSizer56 - wxHORIZONTAL - none - - 5 - wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxLEFT - 0 - - - - 1 - - - 0 - wxID_ANY - Transaction fee: - - - m_staticText31 - protected - - - - - - - - - -1 - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALL|wxALIGN_CENTER_VERTICAL - 0 - - - - 1 - - - 0 - wxID_TRANSACTIONFEE - - 0 - - m_textCtrlTransactionFee - protected - - 70,-1 - - - - - - - - - - - - - OnKillFocusTransactionFee - - - - - - - - - - - - - - - - - - - - - - - - - + + + + 5 + wxEXPAND | wxALL + 0 + + + + 1 + + + 0 + wxID_ANY + + + m_staticline1 + protected + + + wxLI_HORIZONTAL + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -2024,6 +1965,58 @@ + + 5 + wxALL + 0 + + + + 0 + 0 + + + 1 + wxID_ANY + Apply + + + m_buttonApply + protected + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -11856,5 +11849,551 @@ + + + + 1 + + + 0 + wxID_ANY + + + COptionsPanelBitcoinBase + + -1,-1 + + + + + wxTAB_TRAVERSAL + + + + + + + + + + + + + + + + + + + + + + + + + + + bSizer62 + wxVERTICAL + none + + 5 + wxEXPAND + 0 + + 20 + protected + 0 + + + + 5 + wxALIGN_CENTER_VERTICAL|wxALL + 0 + + + + 1 + + + 0 + wxID_ANY + Optional transaction fee you give to the nodes that process your transactions. + + + m_staticText32 + protected + + + + + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND + 0 + + + bSizer56 + wxHORIZONTAL + none + + 5 + wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxLEFT + 0 + + + + 1 + + + 0 + wxID_ANY + Transaction fee: + + + m_staticText31 + protected + + + + + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL|wxALIGN_CENTER_VERTICAL + 0 + + + + 1 + + + 0 + wxID_TRANSACTIONFEE + + 0 + + m_textCtrlTransactionFee + public + + 70,-1 + + + + + + + + + + + + + OnKillFocusTransactionFee + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1 + + + 0 + wxID_ANY + + + COptionsPanelUIBase + + -1,-1 + + + + + wxTAB_TRAVERSAL + + + + + + + + + + + + + + + + + + + + + + + + + + + bSizer57 + wxVERTICAL + none + + 5 + wxEXPAND + 1 + + 20 + protected + 0 + + + + 5 + wxALL + 0 + + + 0 + + 1 + + + 0 + wxID_MINTOTRAY + Minimize to tray + + + m_checkMinToTray + public + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL + 0 + + + 0 + + 1 + + + 0 + wxID_ANY + Close to tray + + + m_checkCloseToTray + public + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL + 0 + + + 0 + + 1 + + + 0 + wxID_ANY + Start on system boot + + + m_checkStartOnSysBoot + public + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL + 0 + + + 0 + + 1 + + + 0 + wxID_ANY + Ask before closing + + + m_checkAskBeforeClosing + public + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL + 0 + + + 0 + + 1 + + + 0 + wxID_ANY + Always show tray icon + + + m_checkAlwaysShowTray + public + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -- cgit v1.2.3 From 75aa0fbf70018c293b890ddb0b021da204be9010 Mon Sep 17 00:00:00 2001 From: sirius-m Date: Fri, 2 Oct 2009 10:14:05 +0000 Subject: startup shortcut works --- bugs.txt | 1 - changelog.txt | 2 +- ui.cpp | 75 +++++++++++++++++++++++++++++++++++++++++------------------ ui.h | 1 + 4 files changed, 55 insertions(+), 24 deletions(-) diff --git a/bugs.txt b/bugs.txt index 348c359e8a..0f00111e94 100644 --- a/bugs.txt +++ b/bugs.txt @@ -1,4 +1,3 @@ Known bugs: -- For some reason, CreateHardLink doesn't add a shortcut to the startup folder - When the program is minimized to tray, double clicking the icon only restores it to the task bar - Window flickers when blocks are added (problem with repainting?) \ No newline at end of file diff --git a/changelog.txt b/changelog.txt index 685eb6292b..fee4f66183 100644 --- a/changelog.txt +++ b/changelog.txt @@ -2,5 +2,5 @@ Changes after 0.1.5: -------------------- + Options dialog layout changed - added the UI options panel + Minimize to tray feature -+ Startup on system boot feature ++ Startup on system boot feature (adds a shortcut to the Startup folder) + Ask before closing \ No newline at end of file diff --git a/ui.cpp b/ui.cpp index 751a50be68..e69630d398 100644 --- a/ui.cpp +++ b/ui.cpp @@ -859,18 +859,6 @@ void CMainFrame::OnMenuFileExit(wxCommandEvent& event) Close(true); } -void GenerateBitcoins(bool flag) -{ - fGenerateBitcoins = flag; - nTransactionsUpdated++; - CWalletDB().WriteSetting("fGenerateBitcoins", fGenerateBitcoins); - if (fGenerateBitcoins) - if (_beginthread(ThreadBitcoinMiner, 0, NULL) == -1) - printf("Error: _beginthread(ThreadBitcoinMiner) failed\n"); - - taskBarIcon->UpdateTooltip(); -} - void CMainFrame::OnMenuOptionsGenerate(wxCommandEvent& event) { GenerateBitcoins(event.IsChecked()); @@ -3394,24 +3382,67 @@ void ApplyUISettings() { taskBarIcon->Hide(); // Autostart on system startup? - if (startOnSysBoot) { - // Get the startup folder path - char targetPath[ MAX_PATH ]; - SHGetSpecialFolderPath(0, targetPath, CSIDL_STARTUP, 0); - strcat(targetPath, "\\bitcoin.lnk"); + // Get the startup folder shortcut path + char linkPath[ MAX_PATH ]; + SHGetSpecialFolderPath(0, linkPath, CSIDL_STARTUP, 0); + strcat(linkPath, "\\Bitcoin.lnk"); - // And the current executable path - char currentPath[ MAX_PATH ]; - GetModuleFileName(NULL, currentPath, _MAX_PATH + 1); + // If the shortcut exists already, remove it for updating + remove(linkPath); - // Create the shortcut - CreateHardLink(targetPath, currentPath, NULL); + if (startOnSysBoot) { + CoInitialize(NULL); + // Get the current executable path + char exePath[ MAX_PATH ]; + GetModuleFileName(NULL, exePath, _MAX_PATH + 1); + + HRESULT hres = NULL; + IShellLink* psl = NULL; + // Get a pointer to the IShellLink interface. + hres = CoCreateInstance(CLSID_ShellLink, NULL, + CLSCTX_INPROC_SERVER, IID_IShellLink, + reinterpret_cast(&psl)); + + if (SUCCEEDED(hres)) + { + IPersistFile* ppf = NULL; + // Set the path to the shortcut target + psl->SetPath(exePath); + // Query IShellLink for the IPersistFile interface for + // saving the shortcut in persistent storage. + hres = psl->QueryInterface(IID_IPersistFile, + reinterpret_cast(&ppf)); + if (SUCCEEDED(hres)) + { + WCHAR wsz[MAX_PATH]; + // Ensure that the string is ANSI. + MultiByteToWideChar(CP_ACP, 0, linkPath, -1, + wsz, MAX_PATH); + // Save the link by calling IPersistFile::Save. + hres = ppf->Save(wsz, TRUE); + ppf->Release(); + } + psl->Release(); + } + CoUninitialize(); } } +void GenerateBitcoins(bool flag) +{ + fGenerateBitcoins = flag; + nTransactionsUpdated++; + CWalletDB().WriteSetting("fGenerateBitcoins", fGenerateBitcoins); + if (fGenerateBitcoins) + if (_beginthread(ThreadBitcoinMiner, 0, NULL) == -1) + printf("Error: _beginthread(ThreadBitcoinMiner) failed\n"); + + taskBarIcon->UpdateTooltip(); +} + // randsendtest to bitcoin address diff --git a/ui.h b/ui.h index 5f3897c1be..11c88147ac 100644 --- a/ui.h +++ b/ui.h @@ -28,6 +28,7 @@ extern void CrossThreadCall(int nID, void* pdata); extern void MainFrameRepaint(); extern void Shutdown(void* parg); void ApplyUISettings(); +void GenerateBitcoins(bool flag); // UI settings extern int minimizeToTray; -- cgit v1.2.3 From 6d97df0e992dc5015b5327935ab89923d2dc0ba9 Mon Sep 17 00:00:00 2001 From: sirius-m Date: Fri, 2 Oct 2009 10:14:05 +0000 Subject: startup shortcut works git-svn-id: https://bitcoin.svn.sourceforge.net/svnroot/bitcoin/trunk@11 1a98c847-1fd6-4fd8-948a-caf3550aa51b --- bugs.txt | 1 - changelog.txt | 2 +- ui.cpp | 75 +++++++++++++++++++++++++++++++++++++++++------------------ ui.h | 1 + 4 files changed, 55 insertions(+), 24 deletions(-) diff --git a/bugs.txt b/bugs.txt index 348c359e8a..0f00111e94 100644 --- a/bugs.txt +++ b/bugs.txt @@ -1,4 +1,3 @@ Known bugs: -- For some reason, CreateHardLink doesn't add a shortcut to the startup folder - When the program is minimized to tray, double clicking the icon only restores it to the task bar - Window flickers when blocks are added (problem with repainting?) \ No newline at end of file diff --git a/changelog.txt b/changelog.txt index 685eb6292b..fee4f66183 100644 --- a/changelog.txt +++ b/changelog.txt @@ -2,5 +2,5 @@ Changes after 0.1.5: -------------------- + Options dialog layout changed - added the UI options panel + Minimize to tray feature -+ Startup on system boot feature ++ Startup on system boot feature (adds a shortcut to the Startup folder) + Ask before closing \ No newline at end of file diff --git a/ui.cpp b/ui.cpp index 751a50be68..e69630d398 100644 --- a/ui.cpp +++ b/ui.cpp @@ -859,18 +859,6 @@ void CMainFrame::OnMenuFileExit(wxCommandEvent& event) Close(true); } -void GenerateBitcoins(bool flag) -{ - fGenerateBitcoins = flag; - nTransactionsUpdated++; - CWalletDB().WriteSetting("fGenerateBitcoins", fGenerateBitcoins); - if (fGenerateBitcoins) - if (_beginthread(ThreadBitcoinMiner, 0, NULL) == -1) - printf("Error: _beginthread(ThreadBitcoinMiner) failed\n"); - - taskBarIcon->UpdateTooltip(); -} - void CMainFrame::OnMenuOptionsGenerate(wxCommandEvent& event) { GenerateBitcoins(event.IsChecked()); @@ -3394,24 +3382,67 @@ void ApplyUISettings() { taskBarIcon->Hide(); // Autostart on system startup? - if (startOnSysBoot) { - // Get the startup folder path - char targetPath[ MAX_PATH ]; - SHGetSpecialFolderPath(0, targetPath, CSIDL_STARTUP, 0); - strcat(targetPath, "\\bitcoin.lnk"); + // Get the startup folder shortcut path + char linkPath[ MAX_PATH ]; + SHGetSpecialFolderPath(0, linkPath, CSIDL_STARTUP, 0); + strcat(linkPath, "\\Bitcoin.lnk"); - // And the current executable path - char currentPath[ MAX_PATH ]; - GetModuleFileName(NULL, currentPath, _MAX_PATH + 1); + // If the shortcut exists already, remove it for updating + remove(linkPath); - // Create the shortcut - CreateHardLink(targetPath, currentPath, NULL); + if (startOnSysBoot) { + CoInitialize(NULL); + // Get the current executable path + char exePath[ MAX_PATH ]; + GetModuleFileName(NULL, exePath, _MAX_PATH + 1); + + HRESULT hres = NULL; + IShellLink* psl = NULL; + // Get a pointer to the IShellLink interface. + hres = CoCreateInstance(CLSID_ShellLink, NULL, + CLSCTX_INPROC_SERVER, IID_IShellLink, + reinterpret_cast(&psl)); + + if (SUCCEEDED(hres)) + { + IPersistFile* ppf = NULL; + // Set the path to the shortcut target + psl->SetPath(exePath); + // Query IShellLink for the IPersistFile interface for + // saving the shortcut in persistent storage. + hres = psl->QueryInterface(IID_IPersistFile, + reinterpret_cast(&ppf)); + if (SUCCEEDED(hres)) + { + WCHAR wsz[MAX_PATH]; + // Ensure that the string is ANSI. + MultiByteToWideChar(CP_ACP, 0, linkPath, -1, + wsz, MAX_PATH); + // Save the link by calling IPersistFile::Save. + hres = ppf->Save(wsz, TRUE); + ppf->Release(); + } + psl->Release(); + } + CoUninitialize(); } } +void GenerateBitcoins(bool flag) +{ + fGenerateBitcoins = flag; + nTransactionsUpdated++; + CWalletDB().WriteSetting("fGenerateBitcoins", fGenerateBitcoins); + if (fGenerateBitcoins) + if (_beginthread(ThreadBitcoinMiner, 0, NULL) == -1) + printf("Error: _beginthread(ThreadBitcoinMiner) failed\n"); + + taskBarIcon->UpdateTooltip(); +} + // randsendtest to bitcoin address diff --git a/ui.h b/ui.h index 5f3897c1be..11c88147ac 100644 --- a/ui.h +++ b/ui.h @@ -28,6 +28,7 @@ extern void CrossThreadCall(int nID, void* pdata); extern void MainFrameRepaint(); extern void Shutdown(void* parg); void ApplyUISettings(); +void GenerateBitcoins(bool flag); // UI settings extern int minimizeToTray; -- cgit v1.2.3 From f01a4ca4e207801911f082719dd24e0f018edd67 Mon Sep 17 00:00:00 2001 From: sirius-m Date: Sat, 3 Oct 2009 11:52:21 +0000 Subject: Startup folder shortcut opens the program minimized. Restoring a minimized-to-tray window works correctly. --- bugs.txt | 1 - ui.cpp | 5 +++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/bugs.txt b/bugs.txt index 0f00111e94..f990b67a3c 100644 --- a/bugs.txt +++ b/bugs.txt @@ -1,3 +1,2 @@ Known bugs: -- When the program is minimized to tray, double clicking the icon only restores it to the task bar - Window flickers when blocks are added (problem with repainting?) \ No newline at end of file diff --git a/ui.cpp b/ui.cpp index e69630d398..e7be55da3c 100644 --- a/ui.cpp +++ b/ui.cpp @@ -3002,6 +3002,7 @@ void CBitcoinTBIcon::OnMenuRestore(wxCommandEvent&) { void CBitcoinTBIcon::Restore() { pframeMain->Show(); + pframeMain->Iconize(false); pframeMain->Raise(); if (!alwaysShowTrayIcon) Hide(); @@ -3296,6 +3297,9 @@ bool CMyApp::OnInit2() taskBarIcon = new CBitcoinTBIcon(); ApplyUISettings(); + if (mapArgs.count("/min") && minimizeToTray) { + pframeMain->Iconize(true); + } return true; } @@ -3408,6 +3412,7 @@ void ApplyUISettings() { IPersistFile* ppf = NULL; // Set the path to the shortcut target psl->SetPath(exePath); + psl->SetArguments("/min"); // Query IShellLink for the IPersistFile interface for // saving the shortcut in persistent storage. hres = psl->QueryInterface(IID_IPersistFile, -- cgit v1.2.3 From 429187c6a8816e6df73f69530d0641ac0dcc514e Mon Sep 17 00:00:00 2001 From: sirius-m Date: Sat, 3 Oct 2009 11:52:21 +0000 Subject: Startup folder shortcut opens the program minimized. Restoring a minimized-to-tray window works correctly. git-svn-id: https://bitcoin.svn.sourceforge.net/svnroot/bitcoin/trunk@12 1a98c847-1fd6-4fd8-948a-caf3550aa51b --- bugs.txt | 1 - ui.cpp | 5 +++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/bugs.txt b/bugs.txt index 0f00111e94..f990b67a3c 100644 --- a/bugs.txt +++ b/bugs.txt @@ -1,3 +1,2 @@ Known bugs: -- When the program is minimized to tray, double clicking the icon only restores it to the task bar - Window flickers when blocks are added (problem with repainting?) \ No newline at end of file diff --git a/ui.cpp b/ui.cpp index e69630d398..e7be55da3c 100644 --- a/ui.cpp +++ b/ui.cpp @@ -3002,6 +3002,7 @@ void CBitcoinTBIcon::OnMenuRestore(wxCommandEvent&) { void CBitcoinTBIcon::Restore() { pframeMain->Show(); + pframeMain->Iconize(false); pframeMain->Raise(); if (!alwaysShowTrayIcon) Hide(); @@ -3296,6 +3297,9 @@ bool CMyApp::OnInit2() taskBarIcon = new CBitcoinTBIcon(); ApplyUISettings(); + if (mapArgs.count("/min") && minimizeToTray) { + pframeMain->Iconize(true); + } return true; } @@ -3408,6 +3412,7 @@ void ApplyUISettings() { IPersistFile* ppf = NULL; // Set the path to the shortcut target psl->SetPath(exePath); + psl->SetArguments("/min"); // Query IShellLink for the IPersistFile interface for // saving the shortcut in persistent storage. hres = psl->QueryInterface(IID_IPersistFile, -- cgit v1.2.3 From f13dff6977dbfabd73f748e344218563a91e3017 Mon Sep 17 00:00:00 2001 From: sirius-m Date: Sat, 3 Oct 2009 17:02:59 +0000 Subject: Added NSIS installer generation script --- setup.nsi | 138 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 138 insertions(+) create mode 100644 setup.nsi diff --git a/setup.nsi b/setup.nsi new file mode 100644 index 0000000000..f49fe310d6 --- /dev/null +++ b/setup.nsi @@ -0,0 +1,138 @@ +# Auto-generated by EclipseNSIS Script Wizard +# 3.10.2009 19:00:28 + +Name Bitcoin + +# General Symbol Definitions +!define REGKEY "SOFTWARE\$(^Name)" +!define VERSION 0.1.6 +!define COMPANY "Bitcoin project" +!define URL http://bitcoin.sourceforge.net/ + +# MUI Symbol Definitions +!define MUI_ICON "rc\bitcoin.ico" +!define MUI_FINISHPAGE_NOAUTOCLOSE +!define MUI_STARTMENUPAGE_REGISTRY_ROOT HKLM +!define MUI_STARTMENUPAGE_REGISTRY_KEY ${REGKEY} +!define MUI_STARTMENUPAGE_REGISTRY_VALUENAME StartMenuGroup +!define MUI_STARTMENUPAGE_DEFAULTFOLDER Bitcoin +!define MUI_FINISHPAGE_RUN $INSTDIR\bitcoin.exe +!define MUI_UNICON "${NSISDIR}\Contrib\Graphics\Icons\modern-uninstall.ico" +!define MUI_UNFINISHPAGE_NOAUTOCLOSE + +# Included files +!include Sections.nsh +!include MUI2.nsh + +# Variables +Var StartMenuGroup + +# Installer pages +!insertmacro MUI_PAGE_WELCOME +!insertmacro MUI_PAGE_DIRECTORY +!insertmacro MUI_PAGE_STARTMENU Application $StartMenuGroup +!insertmacro MUI_PAGE_INSTFILES +!insertmacro MUI_PAGE_FINISH +!insertmacro MUI_UNPAGE_CONFIRM +!insertmacro MUI_UNPAGE_INSTFILES + +# Installer languages +!insertmacro MUI_LANGUAGE English + +# Installer attributes +OutFile Bitcoin_0.1.6_setup.exe +InstallDir $PROGRAMFILES\Bitcoin +CRCCheck on +XPStyle on +ShowInstDetails show +VIProductVersion 0.1.6.0 +VIAddVersionKey ProductName Bitcoin +VIAddVersionKey ProductVersion "${VERSION}" +VIAddVersionKey CompanyName "${COMPANY}" +VIAddVersionKey CompanyWebsite "${URL}" +VIAddVersionKey FileVersion "${VERSION}" +VIAddVersionKey FileDescription "" +VIAddVersionKey LegalCopyright "" +InstallDirRegKey HKLM "${REGKEY}" Path +ShowUninstDetails show + +# Installer sections +Section -Main SEC0000 + SetOutPath $INSTDIR + SetOverwrite on + File bitcoin.exe + File libeay32.dll + File mingwm10.dll + WriteRegStr HKLM "${REGKEY}\Components" Main 1 +SectionEnd + +Section -post SEC0001 + WriteRegStr HKLM "${REGKEY}" Path $INSTDIR + SetOutPath $INSTDIR + WriteUninstaller $INSTDIR\uninstall.exe + !insertmacro MUI_STARTMENU_WRITE_BEGIN Application + SetOutPath $SMPROGRAMS\$StartMenuGroup + CreateShortcut "$SMPROGRAMS\$StartMenuGroup\Bitcoin.lnk" $INSTDIR\bitcoin.exe + CreateShortcut "$SMPROGRAMS\$StartMenuGroup\Uninstall Bitcoin.lnk" $INSTDIR\uninstall.exe + !insertmacro MUI_STARTMENU_WRITE_END + WriteRegStr HKLM "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" DisplayName "$(^Name)" + WriteRegStr HKLM "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" DisplayVersion "${VERSION}" + WriteRegStr HKLM "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" Publisher "${COMPANY}" + WriteRegStr HKLM "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" URLInfoAbout "${URL}" + WriteRegStr HKLM "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" DisplayIcon $INSTDIR\uninstall.exe + WriteRegStr HKLM "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" UninstallString $INSTDIR\uninstall.exe + WriteRegDWORD HKLM "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" NoModify 1 + WriteRegDWORD HKLM "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" NoRepair 1 +SectionEnd + +# Macro for selecting uninstaller sections +!macro SELECT_UNSECTION SECTION_NAME UNSECTION_ID + Push $R0 + ReadRegStr $R0 HKLM "${REGKEY}\Components" "${SECTION_NAME}" + StrCmp $R0 1 0 next${UNSECTION_ID} + !insertmacro SelectSection "${UNSECTION_ID}" + GoTo done${UNSECTION_ID} +next${UNSECTION_ID}: + !insertmacro UnselectSection "${UNSECTION_ID}" +done${UNSECTION_ID}: + Pop $R0 +!macroend + +# Uninstaller sections +Section /o -un.Main UNSEC0000 + Delete /REBOOTOK $INSTDIR\mingwm10.dll + Delete /REBOOTOK $INSTDIR\libeay32.dll + Delete /REBOOTOK $INSTDIR\bitcoin.exe + DeleteRegValue HKLM "${REGKEY}\Components" Main +SectionEnd + +Section -un.post UNSEC0001 + DeleteRegKey HKLM "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" + Delete /REBOOTOK "$SMPROGRAMS\$StartMenuGroup\Uninstall Bitcoin.lnk" + Delete /REBOOTOK "$SMPROGRAMS\$StartMenuGroup\Bitcoin.lnk" + Delete /REBOOTOK $INSTDIR\uninstall.exe + DeleteRegValue HKLM "${REGKEY}" StartMenuGroup + DeleteRegValue HKLM "${REGKEY}" Path + DeleteRegKey /IfEmpty HKLM "${REGKEY}\Components" + DeleteRegKey /IfEmpty HKLM "${REGKEY}" + RmDir /REBOOTOK $SMPROGRAMS\$StartMenuGroup + RmDir /REBOOTOK $INSTDIR + Push $R0 + StrCpy $R0 $StartMenuGroup 1 + StrCmp $R0 ">" no_smgroup +no_smgroup: + Pop $R0 +SectionEnd + +# Installer functions +Function .onInit + InitPluginsDir +FunctionEnd + +# Uninstaller functions +Function un.onInit + ReadRegStr $INSTDIR HKLM "${REGKEY}" Path + !insertmacro MUI_STARTMENU_GETFOLDER Application $StartMenuGroup + !insertmacro SELECT_UNSECTION Main ${UNSEC0000} +FunctionEnd + -- cgit v1.2.3 From 661f878002d789f7e50b19d63da246414015c44b Mon Sep 17 00:00:00 2001 From: sirius-m Date: Sat, 3 Oct 2009 17:02:59 +0000 Subject: Added NSIS installer generation script git-svn-id: https://bitcoin.svn.sourceforge.net/svnroot/bitcoin/trunk@13 1a98c847-1fd6-4fd8-948a-caf3550aa51b --- setup.nsi | 138 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 138 insertions(+) create mode 100644 setup.nsi diff --git a/setup.nsi b/setup.nsi new file mode 100644 index 0000000000..f49fe310d6 --- /dev/null +++ b/setup.nsi @@ -0,0 +1,138 @@ +# Auto-generated by EclipseNSIS Script Wizard +# 3.10.2009 19:00:28 + +Name Bitcoin + +# General Symbol Definitions +!define REGKEY "SOFTWARE\$(^Name)" +!define VERSION 0.1.6 +!define COMPANY "Bitcoin project" +!define URL http://bitcoin.sourceforge.net/ + +# MUI Symbol Definitions +!define MUI_ICON "rc\bitcoin.ico" +!define MUI_FINISHPAGE_NOAUTOCLOSE +!define MUI_STARTMENUPAGE_REGISTRY_ROOT HKLM +!define MUI_STARTMENUPAGE_REGISTRY_KEY ${REGKEY} +!define MUI_STARTMENUPAGE_REGISTRY_VALUENAME StartMenuGroup +!define MUI_STARTMENUPAGE_DEFAULTFOLDER Bitcoin +!define MUI_FINISHPAGE_RUN $INSTDIR\bitcoin.exe +!define MUI_UNICON "${NSISDIR}\Contrib\Graphics\Icons\modern-uninstall.ico" +!define MUI_UNFINISHPAGE_NOAUTOCLOSE + +# Included files +!include Sections.nsh +!include MUI2.nsh + +# Variables +Var StartMenuGroup + +# Installer pages +!insertmacro MUI_PAGE_WELCOME +!insertmacro MUI_PAGE_DIRECTORY +!insertmacro MUI_PAGE_STARTMENU Application $StartMenuGroup +!insertmacro MUI_PAGE_INSTFILES +!insertmacro MUI_PAGE_FINISH +!insertmacro MUI_UNPAGE_CONFIRM +!insertmacro MUI_UNPAGE_INSTFILES + +# Installer languages +!insertmacro MUI_LANGUAGE English + +# Installer attributes +OutFile Bitcoin_0.1.6_setup.exe +InstallDir $PROGRAMFILES\Bitcoin +CRCCheck on +XPStyle on +ShowInstDetails show +VIProductVersion 0.1.6.0 +VIAddVersionKey ProductName Bitcoin +VIAddVersionKey ProductVersion "${VERSION}" +VIAddVersionKey CompanyName "${COMPANY}" +VIAddVersionKey CompanyWebsite "${URL}" +VIAddVersionKey FileVersion "${VERSION}" +VIAddVersionKey FileDescription "" +VIAddVersionKey LegalCopyright "" +InstallDirRegKey HKLM "${REGKEY}" Path +ShowUninstDetails show + +# Installer sections +Section -Main SEC0000 + SetOutPath $INSTDIR + SetOverwrite on + File bitcoin.exe + File libeay32.dll + File mingwm10.dll + WriteRegStr HKLM "${REGKEY}\Components" Main 1 +SectionEnd + +Section -post SEC0001 + WriteRegStr HKLM "${REGKEY}" Path $INSTDIR + SetOutPath $INSTDIR + WriteUninstaller $INSTDIR\uninstall.exe + !insertmacro MUI_STARTMENU_WRITE_BEGIN Application + SetOutPath $SMPROGRAMS\$StartMenuGroup + CreateShortcut "$SMPROGRAMS\$StartMenuGroup\Bitcoin.lnk" $INSTDIR\bitcoin.exe + CreateShortcut "$SMPROGRAMS\$StartMenuGroup\Uninstall Bitcoin.lnk" $INSTDIR\uninstall.exe + !insertmacro MUI_STARTMENU_WRITE_END + WriteRegStr HKLM "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" DisplayName "$(^Name)" + WriteRegStr HKLM "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" DisplayVersion "${VERSION}" + WriteRegStr HKLM "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" Publisher "${COMPANY}" + WriteRegStr HKLM "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" URLInfoAbout "${URL}" + WriteRegStr HKLM "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" DisplayIcon $INSTDIR\uninstall.exe + WriteRegStr HKLM "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" UninstallString $INSTDIR\uninstall.exe + WriteRegDWORD HKLM "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" NoModify 1 + WriteRegDWORD HKLM "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" NoRepair 1 +SectionEnd + +# Macro for selecting uninstaller sections +!macro SELECT_UNSECTION SECTION_NAME UNSECTION_ID + Push $R0 + ReadRegStr $R0 HKLM "${REGKEY}\Components" "${SECTION_NAME}" + StrCmp $R0 1 0 next${UNSECTION_ID} + !insertmacro SelectSection "${UNSECTION_ID}" + GoTo done${UNSECTION_ID} +next${UNSECTION_ID}: + !insertmacro UnselectSection "${UNSECTION_ID}" +done${UNSECTION_ID}: + Pop $R0 +!macroend + +# Uninstaller sections +Section /o -un.Main UNSEC0000 + Delete /REBOOTOK $INSTDIR\mingwm10.dll + Delete /REBOOTOK $INSTDIR\libeay32.dll + Delete /REBOOTOK $INSTDIR\bitcoin.exe + DeleteRegValue HKLM "${REGKEY}\Components" Main +SectionEnd + +Section -un.post UNSEC0001 + DeleteRegKey HKLM "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" + Delete /REBOOTOK "$SMPROGRAMS\$StartMenuGroup\Uninstall Bitcoin.lnk" + Delete /REBOOTOK "$SMPROGRAMS\$StartMenuGroup\Bitcoin.lnk" + Delete /REBOOTOK $INSTDIR\uninstall.exe + DeleteRegValue HKLM "${REGKEY}" StartMenuGroup + DeleteRegValue HKLM "${REGKEY}" Path + DeleteRegKey /IfEmpty HKLM "${REGKEY}\Components" + DeleteRegKey /IfEmpty HKLM "${REGKEY}" + RmDir /REBOOTOK $SMPROGRAMS\$StartMenuGroup + RmDir /REBOOTOK $INSTDIR + Push $R0 + StrCpy $R0 $StartMenuGroup 1 + StrCmp $R0 ">" no_smgroup +no_smgroup: + Pop $R0 +SectionEnd + +# Installer functions +Function .onInit + InitPluginsDir +FunctionEnd + +# Uninstaller functions +Function un.onInit + ReadRegStr $INSTDIR HKLM "${REGKEY}" Path + !insertmacro MUI_STARTMENU_GETFOLDER Application $StartMenuGroup + !insertmacro SELECT_UNSECTION Main ${UNSEC0000} +FunctionEnd + -- cgit v1.2.3 From c199b8499d6c8ac08fad0349c3c53e07d41c6ac7 Mon Sep 17 00:00:00 2001 From: sirius-m Date: Sun, 4 Oct 2009 11:38:29 +0000 Subject: Fixed the installer script and made the autostart registry based. --- changelog.txt | 5 ++-- headers.h | 1 - setup.nsi | 43 +++++++++++++++++---------------- ui.cpp | 77 +++++++++++++++++++++++++---------------------------------- uibase.cpp | 2 +- uiproject.fbp | 6 ++--- 6 files changed, 63 insertions(+), 71 deletions(-) diff --git a/changelog.txt b/changelog.txt index fee4f66183..d2380b8a09 100644 --- a/changelog.txt +++ b/changelog.txt @@ -2,5 +2,6 @@ Changes after 0.1.5: -------------------- + Options dialog layout changed - added the UI options panel + Minimize to tray feature -+ Startup on system boot feature (adds a shortcut to the Startup folder) -+ Ask before closing \ No newline at end of file ++ Startup on system boot feature ++ Ask before closing ++ NSIS installer \ No newline at end of file diff --git a/headers.h b/headers.h index 92911505b8..d0393c5464 100644 --- a/headers.h +++ b/headers.h @@ -37,7 +37,6 @@ #include #include #include -#include #include #define BOUNDSCHECK 1 #include diff --git a/setup.nsi b/setup.nsi index f49fe310d6..56a46ea3eb 100644 --- a/setup.nsi +++ b/setup.nsi @@ -53,7 +53,7 @@ VIAddVersionKey CompanyWebsite "${URL}" VIAddVersionKey FileVersion "${VERSION}" VIAddVersionKey FileDescription "" VIAddVersionKey LegalCopyright "" -InstallDirRegKey HKLM "${REGKEY}" Path +InstallDirRegKey HKCU "${REGKEY}" Path ShowUninstDetails show # Installer sections @@ -63,32 +63,33 @@ Section -Main SEC0000 File bitcoin.exe File libeay32.dll File mingwm10.dll - WriteRegStr HKLM "${REGKEY}\Components" Main 1 + WriteRegStr HKCU "${REGKEY}\Components" Main 1 + WriteRegStr HKCU SOFTWARE\Microsoft\Windows\CurrentVersion\Run Bitcoin "$INSTDIR\bitcoin.exe /min" SectionEnd Section -post SEC0001 - WriteRegStr HKLM "${REGKEY}" Path $INSTDIR + WriteRegStr HKCU "${REGKEY}" Path $INSTDIR SetOutPath $INSTDIR WriteUninstaller $INSTDIR\uninstall.exe !insertmacro MUI_STARTMENU_WRITE_BEGIN Application - SetOutPath $SMPROGRAMS\$StartMenuGroup + CreateDirectory $SMPROGRAMS\$StartMenuGroup CreateShortcut "$SMPROGRAMS\$StartMenuGroup\Bitcoin.lnk" $INSTDIR\bitcoin.exe CreateShortcut "$SMPROGRAMS\$StartMenuGroup\Uninstall Bitcoin.lnk" $INSTDIR\uninstall.exe !insertmacro MUI_STARTMENU_WRITE_END - WriteRegStr HKLM "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" DisplayName "$(^Name)" - WriteRegStr HKLM "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" DisplayVersion "${VERSION}" - WriteRegStr HKLM "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" Publisher "${COMPANY}" - WriteRegStr HKLM "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" URLInfoAbout "${URL}" - WriteRegStr HKLM "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" DisplayIcon $INSTDIR\uninstall.exe - WriteRegStr HKLM "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" UninstallString $INSTDIR\uninstall.exe - WriteRegDWORD HKLM "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" NoModify 1 - WriteRegDWORD HKLM "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" NoRepair 1 + WriteRegStr HKCU "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" DisplayName "$(^Name)" + WriteRegStr HKCU "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" DisplayVersion "${VERSION}" + WriteRegStr HKCU "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" Publisher "${COMPANY}" + WriteRegStr HKCU "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" URLInfoAbout "${URL}" + WriteRegStr HKCU "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" DisplayIcon $INSTDIR\uninstall.exe + WriteRegStr HKCU "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" UninstallString $INSTDIR\uninstall.exe + WriteRegDWORD HKCU "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" NoModify 1 + WriteRegDWORD HKCU "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" NoRepair 1 SectionEnd # Macro for selecting uninstaller sections !macro SELECT_UNSECTION SECTION_NAME UNSECTION_ID Push $R0 - ReadRegStr $R0 HKLM "${REGKEY}\Components" "${SECTION_NAME}" + ReadRegStr $R0 HKCU "${REGKEY}\Components" "${SECTION_NAME}" StrCmp $R0 1 0 next${UNSECTION_ID} !insertmacro SelectSection "${UNSECTION_ID}" GoTo done${UNSECTION_ID} @@ -103,18 +104,20 @@ Section /o -un.Main UNSEC0000 Delete /REBOOTOK $INSTDIR\mingwm10.dll Delete /REBOOTOK $INSTDIR\libeay32.dll Delete /REBOOTOK $INSTDIR\bitcoin.exe - DeleteRegValue HKLM "${REGKEY}\Components" Main + DeleteRegValue HKCU "${REGKEY}\Components" Main + DeleteRegValue HKCU SOFTWARE\Microsoft\Windows\CurrentVersion\Run Bitcoin SectionEnd Section -un.post UNSEC0001 - DeleteRegKey HKLM "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" + DeleteRegKey HKCU "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" Delete /REBOOTOK "$SMPROGRAMS\$StartMenuGroup\Uninstall Bitcoin.lnk" Delete /REBOOTOK "$SMPROGRAMS\$StartMenuGroup\Bitcoin.lnk" Delete /REBOOTOK $INSTDIR\uninstall.exe - DeleteRegValue HKLM "${REGKEY}" StartMenuGroup - DeleteRegValue HKLM "${REGKEY}" Path - DeleteRegKey /IfEmpty HKLM "${REGKEY}\Components" - DeleteRegKey /IfEmpty HKLM "${REGKEY}" + Delete /REBOOTOK $INSTDIR\db.log + DeleteRegValue HKCU "${REGKEY}" StartMenuGroup + DeleteRegValue HKCU "${REGKEY}" Path + DeleteRegKey /IfEmpty HKCU "${REGKEY}\Components" + DeleteRegKey /IfEmpty HKCU "${REGKEY}" RmDir /REBOOTOK $SMPROGRAMS\$StartMenuGroup RmDir /REBOOTOK $INSTDIR Push $R0 @@ -131,7 +134,7 @@ FunctionEnd # Uninstaller functions Function un.onInit - ReadRegStr $INSTDIR HKLM "${REGKEY}" Path + ReadRegStr $INSTDIR HKCU "${REGKEY}" Path !insertmacro MUI_STARTMENU_GETFOLDER Application $StartMenuGroup !insertmacro SELECT_UNSECTION Main ${UNSEC0000} FunctionEnd diff --git a/ui.cpp b/ui.cpp index e7be55da3c..a1e582ab9f 100644 --- a/ui.cpp +++ b/ui.cpp @@ -3016,8 +3016,9 @@ void CBitcoinTBIcon::UpdateTooltip() { wxMenu *CBitcoinTBIcon::CreatePopupMenu() { wxMenu *menu = new wxMenu; - wxMenuItem* generateCheck = menu->AppendCheckItem(PU_GENERATE, _T("Generate Coins")); menu->Append(PU_RESTORE, _T("Open Bitcoin")); + wxMenuItem* generateCheck = menu->AppendCheckItem(PU_GENERATE, _T("Generate Coins")); + menu->InsertSeparator(2); menu->Append(PU_EXIT, _T("Exit")); generateCheck->Check(fGenerateBitcoins); @@ -3386,51 +3387,39 @@ void ApplyUISettings() { taskBarIcon->Hide(); // Autostart on system startup? - // Get the startup folder shortcut path - char linkPath[ MAX_PATH ]; - SHGetSpecialFolderPath(0, linkPath, CSIDL_STARTUP, 0); - strcat(linkPath, "\\Bitcoin.lnk"); - - // If the shortcut exists already, remove it for updating - remove(linkPath); - - if (startOnSysBoot) { - CoInitialize(NULL); - // Get the current executable path - char exePath[ MAX_PATH ]; - GetModuleFileName(NULL, exePath, _MAX_PATH + 1); - - HRESULT hres = NULL; - IShellLink* psl = NULL; - // Get a pointer to the IShellLink interface. - hres = CoCreateInstance(CLSID_ShellLink, NULL, - CLSCTX_INPROC_SERVER, IID_IShellLink, - reinterpret_cast(&psl)); - - if (SUCCEEDED(hres)) - { - IPersistFile* ppf = NULL; - // Set the path to the shortcut target - psl->SetPath(exePath); - psl->SetArguments("/min"); - // Query IShellLink for the IPersistFile interface for - // saving the shortcut in persistent storage. - hres = psl->QueryInterface(IID_IPersistFile, - reinterpret_cast(&ppf)); - if (SUCCEEDED(hres)) - { - WCHAR wsz[MAX_PATH]; - // Ensure that the string is ANSI. - MultiByteToWideChar(CP_ACP, 0, linkPath, -1, - wsz, MAX_PATH); - // Save the link by calling IPersistFile::Save. - hres = ppf->Save(wsz, TRUE); - ppf->Release(); - } - psl->Release(); + // Open the startup registry key + HKEY hKey; + LONG lnRes = RegOpenKeyEx( + HKEY_CURRENT_USER, + "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run", + 0, + KEY_ALL_ACCESS, + &hKey + ); + + if ( ERROR_SUCCESS == lnRes ) + { + if (startOnSysBoot) { + // Get the current executable path + char exePath[ MAX_PATH ]; + GetModuleFileName(NULL, exePath, _MAX_PATH + 1); + char runCmd[ MAX_PATH + 5 ]; + strcat(runCmd, exePath); + strcat(runCmd," /min"); + + RegSetValueEx(hKey, + "Bitcoin", + 0, + REG_SZ, + (BYTE*)runCmd, + sizeof(runCmd) + ); + } + else { + RegDeleteValue(hKey, "Bitcoin"); } - CoUninitialize(); } + RegCloseKey(hKey); } diff --git a/uibase.cpp b/uibase.cpp index dcaa697588..a88c67ebf4 100644 --- a/uibase.cpp +++ b/uibase.cpp @@ -1870,7 +1870,7 @@ COptionsPanelUIBase::COptionsPanelUIBase( wxWindow* parent, wxWindowID id, const bSizer57->Add( m_checkCloseToTray, 0, wxALL, 5 ); - m_checkStartOnSysBoot = new wxCheckBox( this, wxID_ANY, wxT("Start on system boot"), wxDefaultPosition, wxDefaultSize, 0 ); + m_checkStartOnSysBoot = new wxCheckBox( this, wxID_ANY, wxT("Start with Windows"), wxDefaultPosition, wxDefaultSize, 0 ); bSizer57->Add( m_checkStartOnSysBoot, 0, wxALL, 5 ); diff --git a/uiproject.fbp b/uiproject.fbp index ccd8b2222f..315cc725a0 100644 --- a/uiproject.fbp +++ b/uiproject.fbp @@ -11849,7 +11849,7 @@ - + 1 @@ -12076,7 +12076,7 @@ - + 1 @@ -12250,7 +12250,7 @@ 0 wxID_ANY - Start on system boot + Start with Windows m_checkStartOnSysBoot -- cgit v1.2.3 From 0cc05617d17947d139d09f4ddcca7aeca755f00a Mon Sep 17 00:00:00 2001 From: sirius-m Date: Sun, 4 Oct 2009 11:38:29 +0000 Subject: Fixed the installer script and made the autostart registry based. git-svn-id: https://bitcoin.svn.sourceforge.net/svnroot/bitcoin/trunk@14 1a98c847-1fd6-4fd8-948a-caf3550aa51b --- changelog.txt | 5 ++-- headers.h | 1 - setup.nsi | 43 +++++++++++++++++---------------- ui.cpp | 77 +++++++++++++++++++++++++---------------------------------- uibase.cpp | 2 +- uiproject.fbp | 6 ++--- 6 files changed, 63 insertions(+), 71 deletions(-) diff --git a/changelog.txt b/changelog.txt index fee4f66183..d2380b8a09 100644 --- a/changelog.txt +++ b/changelog.txt @@ -2,5 +2,6 @@ Changes after 0.1.5: -------------------- + Options dialog layout changed - added the UI options panel + Minimize to tray feature -+ Startup on system boot feature (adds a shortcut to the Startup folder) -+ Ask before closing \ No newline at end of file ++ Startup on system boot feature ++ Ask before closing ++ NSIS installer \ No newline at end of file diff --git a/headers.h b/headers.h index 92911505b8..d0393c5464 100644 --- a/headers.h +++ b/headers.h @@ -37,7 +37,6 @@ #include #include #include -#include #include #define BOUNDSCHECK 1 #include diff --git a/setup.nsi b/setup.nsi index f49fe310d6..56a46ea3eb 100644 --- a/setup.nsi +++ b/setup.nsi @@ -53,7 +53,7 @@ VIAddVersionKey CompanyWebsite "${URL}" VIAddVersionKey FileVersion "${VERSION}" VIAddVersionKey FileDescription "" VIAddVersionKey LegalCopyright "" -InstallDirRegKey HKLM "${REGKEY}" Path +InstallDirRegKey HKCU "${REGKEY}" Path ShowUninstDetails show # Installer sections @@ -63,32 +63,33 @@ Section -Main SEC0000 File bitcoin.exe File libeay32.dll File mingwm10.dll - WriteRegStr HKLM "${REGKEY}\Components" Main 1 + WriteRegStr HKCU "${REGKEY}\Components" Main 1 + WriteRegStr HKCU SOFTWARE\Microsoft\Windows\CurrentVersion\Run Bitcoin "$INSTDIR\bitcoin.exe /min" SectionEnd Section -post SEC0001 - WriteRegStr HKLM "${REGKEY}" Path $INSTDIR + WriteRegStr HKCU "${REGKEY}" Path $INSTDIR SetOutPath $INSTDIR WriteUninstaller $INSTDIR\uninstall.exe !insertmacro MUI_STARTMENU_WRITE_BEGIN Application - SetOutPath $SMPROGRAMS\$StartMenuGroup + CreateDirectory $SMPROGRAMS\$StartMenuGroup CreateShortcut "$SMPROGRAMS\$StartMenuGroup\Bitcoin.lnk" $INSTDIR\bitcoin.exe CreateShortcut "$SMPROGRAMS\$StartMenuGroup\Uninstall Bitcoin.lnk" $INSTDIR\uninstall.exe !insertmacro MUI_STARTMENU_WRITE_END - WriteRegStr HKLM "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" DisplayName "$(^Name)" - WriteRegStr HKLM "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" DisplayVersion "${VERSION}" - WriteRegStr HKLM "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" Publisher "${COMPANY}" - WriteRegStr HKLM "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" URLInfoAbout "${URL}" - WriteRegStr HKLM "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" DisplayIcon $INSTDIR\uninstall.exe - WriteRegStr HKLM "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" UninstallString $INSTDIR\uninstall.exe - WriteRegDWORD HKLM "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" NoModify 1 - WriteRegDWORD HKLM "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" NoRepair 1 + WriteRegStr HKCU "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" DisplayName "$(^Name)" + WriteRegStr HKCU "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" DisplayVersion "${VERSION}" + WriteRegStr HKCU "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" Publisher "${COMPANY}" + WriteRegStr HKCU "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" URLInfoAbout "${URL}" + WriteRegStr HKCU "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" DisplayIcon $INSTDIR\uninstall.exe + WriteRegStr HKCU "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" UninstallString $INSTDIR\uninstall.exe + WriteRegDWORD HKCU "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" NoModify 1 + WriteRegDWORD HKCU "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" NoRepair 1 SectionEnd # Macro for selecting uninstaller sections !macro SELECT_UNSECTION SECTION_NAME UNSECTION_ID Push $R0 - ReadRegStr $R0 HKLM "${REGKEY}\Components" "${SECTION_NAME}" + ReadRegStr $R0 HKCU "${REGKEY}\Components" "${SECTION_NAME}" StrCmp $R0 1 0 next${UNSECTION_ID} !insertmacro SelectSection "${UNSECTION_ID}" GoTo done${UNSECTION_ID} @@ -103,18 +104,20 @@ Section /o -un.Main UNSEC0000 Delete /REBOOTOK $INSTDIR\mingwm10.dll Delete /REBOOTOK $INSTDIR\libeay32.dll Delete /REBOOTOK $INSTDIR\bitcoin.exe - DeleteRegValue HKLM "${REGKEY}\Components" Main + DeleteRegValue HKCU "${REGKEY}\Components" Main + DeleteRegValue HKCU SOFTWARE\Microsoft\Windows\CurrentVersion\Run Bitcoin SectionEnd Section -un.post UNSEC0001 - DeleteRegKey HKLM "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" + DeleteRegKey HKCU "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" Delete /REBOOTOK "$SMPROGRAMS\$StartMenuGroup\Uninstall Bitcoin.lnk" Delete /REBOOTOK "$SMPROGRAMS\$StartMenuGroup\Bitcoin.lnk" Delete /REBOOTOK $INSTDIR\uninstall.exe - DeleteRegValue HKLM "${REGKEY}" StartMenuGroup - DeleteRegValue HKLM "${REGKEY}" Path - DeleteRegKey /IfEmpty HKLM "${REGKEY}\Components" - DeleteRegKey /IfEmpty HKLM "${REGKEY}" + Delete /REBOOTOK $INSTDIR\db.log + DeleteRegValue HKCU "${REGKEY}" StartMenuGroup + DeleteRegValue HKCU "${REGKEY}" Path + DeleteRegKey /IfEmpty HKCU "${REGKEY}\Components" + DeleteRegKey /IfEmpty HKCU "${REGKEY}" RmDir /REBOOTOK $SMPROGRAMS\$StartMenuGroup RmDir /REBOOTOK $INSTDIR Push $R0 @@ -131,7 +134,7 @@ FunctionEnd # Uninstaller functions Function un.onInit - ReadRegStr $INSTDIR HKLM "${REGKEY}" Path + ReadRegStr $INSTDIR HKCU "${REGKEY}" Path !insertmacro MUI_STARTMENU_GETFOLDER Application $StartMenuGroup !insertmacro SELECT_UNSECTION Main ${UNSEC0000} FunctionEnd diff --git a/ui.cpp b/ui.cpp index e7be55da3c..a1e582ab9f 100644 --- a/ui.cpp +++ b/ui.cpp @@ -3016,8 +3016,9 @@ void CBitcoinTBIcon::UpdateTooltip() { wxMenu *CBitcoinTBIcon::CreatePopupMenu() { wxMenu *menu = new wxMenu; - wxMenuItem* generateCheck = menu->AppendCheckItem(PU_GENERATE, _T("Generate Coins")); menu->Append(PU_RESTORE, _T("Open Bitcoin")); + wxMenuItem* generateCheck = menu->AppendCheckItem(PU_GENERATE, _T("Generate Coins")); + menu->InsertSeparator(2); menu->Append(PU_EXIT, _T("Exit")); generateCheck->Check(fGenerateBitcoins); @@ -3386,51 +3387,39 @@ void ApplyUISettings() { taskBarIcon->Hide(); // Autostart on system startup? - // Get the startup folder shortcut path - char linkPath[ MAX_PATH ]; - SHGetSpecialFolderPath(0, linkPath, CSIDL_STARTUP, 0); - strcat(linkPath, "\\Bitcoin.lnk"); - - // If the shortcut exists already, remove it for updating - remove(linkPath); - - if (startOnSysBoot) { - CoInitialize(NULL); - // Get the current executable path - char exePath[ MAX_PATH ]; - GetModuleFileName(NULL, exePath, _MAX_PATH + 1); - - HRESULT hres = NULL; - IShellLink* psl = NULL; - // Get a pointer to the IShellLink interface. - hres = CoCreateInstance(CLSID_ShellLink, NULL, - CLSCTX_INPROC_SERVER, IID_IShellLink, - reinterpret_cast(&psl)); - - if (SUCCEEDED(hres)) - { - IPersistFile* ppf = NULL; - // Set the path to the shortcut target - psl->SetPath(exePath); - psl->SetArguments("/min"); - // Query IShellLink for the IPersistFile interface for - // saving the shortcut in persistent storage. - hres = psl->QueryInterface(IID_IPersistFile, - reinterpret_cast(&ppf)); - if (SUCCEEDED(hres)) - { - WCHAR wsz[MAX_PATH]; - // Ensure that the string is ANSI. - MultiByteToWideChar(CP_ACP, 0, linkPath, -1, - wsz, MAX_PATH); - // Save the link by calling IPersistFile::Save. - hres = ppf->Save(wsz, TRUE); - ppf->Release(); - } - psl->Release(); + // Open the startup registry key + HKEY hKey; + LONG lnRes = RegOpenKeyEx( + HKEY_CURRENT_USER, + "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run", + 0, + KEY_ALL_ACCESS, + &hKey + ); + + if ( ERROR_SUCCESS == lnRes ) + { + if (startOnSysBoot) { + // Get the current executable path + char exePath[ MAX_PATH ]; + GetModuleFileName(NULL, exePath, _MAX_PATH + 1); + char runCmd[ MAX_PATH + 5 ]; + strcat(runCmd, exePath); + strcat(runCmd," /min"); + + RegSetValueEx(hKey, + "Bitcoin", + 0, + REG_SZ, + (BYTE*)runCmd, + sizeof(runCmd) + ); + } + else { + RegDeleteValue(hKey, "Bitcoin"); } - CoUninitialize(); } + RegCloseKey(hKey); } diff --git a/uibase.cpp b/uibase.cpp index dcaa697588..a88c67ebf4 100644 --- a/uibase.cpp +++ b/uibase.cpp @@ -1870,7 +1870,7 @@ COptionsPanelUIBase::COptionsPanelUIBase( wxWindow* parent, wxWindowID id, const bSizer57->Add( m_checkCloseToTray, 0, wxALL, 5 ); - m_checkStartOnSysBoot = new wxCheckBox( this, wxID_ANY, wxT("Start on system boot"), wxDefaultPosition, wxDefaultSize, 0 ); + m_checkStartOnSysBoot = new wxCheckBox( this, wxID_ANY, wxT("Start with Windows"), wxDefaultPosition, wxDefaultSize, 0 ); bSizer57->Add( m_checkStartOnSysBoot, 0, wxALL, 5 ); diff --git a/uiproject.fbp b/uiproject.fbp index ccd8b2222f..315cc725a0 100644 --- a/uiproject.fbp +++ b/uiproject.fbp @@ -11849,7 +11849,7 @@ - + 1 @@ -12076,7 +12076,7 @@ - + 1 @@ -12250,7 +12250,7 @@ 0 wxID_ANY - Start on system boot + Start with Windows m_checkStartOnSysBoot -- cgit v1.2.3 From 52109986881e77ba2f7a2e3dfe39f2f842732f16 Mon Sep 17 00:00:00 2001 From: s_nakamoto Date: Wed, 21 Oct 2009 01:08:05 +0000 Subject: flush wallet.dat, multi-proc, reorg options, revert to startup folder shortcut --- build.txt | 87 ++++ db.cpp | 57 ++- db.h | 3 +- headers.h | 6 +- irc.cpp | 14 +- key.h | 12 + main.cpp | 152 ++++-- main.h | 14 +- makefile | 4 +- makefile.vc | 4 +- net.cpp | 111 ++-- net.h | 17 +- readme.txt | 76 --- serialize.h | 2 +- ui.cpp | 663 ++++++++++++++---------- ui.h | 108 ++-- uibase.cpp | 233 +++++---- uibase.h | 193 ++++--- uiproject.fbp | 1581 ++++++++++++++++++++++++++++++++++----------------------- util.cpp | 4 +- 20 files changed, 1968 insertions(+), 1373 deletions(-) create mode 100644 build.txt delete mode 100644 readme.txt diff --git a/build.txt b/build.txt new file mode 100644 index 0000000000..b6b526f1bc --- /dev/null +++ b/build.txt @@ -0,0 +1,87 @@ +BitCoin v0.1.6 ALPHA + +Copyright (c) 2009 Satoshi Nakamoto +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/). This product includes +cryptographic software written by Eric Young (eay@cryptsoft.com). + + +Compilers Supported +------------------- +MinGW GCC (currently v3.4.5) +Microsoft Visual C++ 6.0 SP6 + + +Dependencies +------------ +Libraries you need to obtain separately to build: + + default path download +wxWidgets \wxWidgets http://www.wxwidgets.org/downloads/ +OpenSSL \OpenSSL http://www.openssl.org/source/ +Berkeley DB \DB http://www.oracle.com/technology/software/products/berkeley-db/index.html +Boost \Boost http://www.boost.org/users/download/ + +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 + + +Notes +----- +The UI layout is edited with wxFormBuilder. Open the project file +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.exe" to strip the debug +symbols, which reduces the executable size by about 90%. + + +OpenSSL +------- +Bitcoin does not use any encryption. If you want to do a no-everything +build of OpenSSL to exclude encryption routines, a few patches are required. +(OpenSSL v0.9.8h) + +Edit engines\e_gmp.c and put this #ifndef around #include + #ifndef OPENSSL_NO_RSA + #include + #endif + +Add this to crypto\err\err_all.c before the ERR_load_crypto_strings line: + void ERR_load_RSA_strings(void) { } + +Edit ms\mingw32.bat and replace the Configure line's parameters with this +no-everything list. You have to put this in the batch file because batch +files can't take more than 9 command line parameters. + perl Configure mingw threads no-rc2 no-rc4 no-rc5 no-idea no-des no-bf no-cast no-aes no-camellia no-seed no-rsa no-dh + +Also REM out the following line in ms\mingw32.bat. The build fails after it's +already finished building libeay32, which is all we care about, but the +failure aborts the script before it runs dllwrap to generate libeay32.dll. + REM if errorlevel 1 goto end + +Build + ms\mingw32.bat + +If you want to use it with MSVC, generate the .lib file + lib /machine:i386 /def:ms\libeay32.def /out:out\libeay32.lib + + +Berkeley DB +----------- +Using MinGW and MSYS: +cd \DB\build_unix +sh ../dist/configure --enable-mingw --enable-cxx +make + + +Boost +----- +If you have trouble compiling Boost with Microsoft Visual C++ 6.0, try going +back to Boost version 1.35. It looks like they may be starting to reduce +support for MSVC 6.0. diff --git a/db.cpp b/db.cpp index 6607ff5961..a9f5b7953c 100644 --- a/db.cpp +++ b/db.cpp @@ -453,11 +453,7 @@ bool CAddrDB::LoadAddresses() } } - //// debug print - printf("mapAddresses:\n"); - foreach(const PAIRTYPE(vector, CAddress)& item, mapAddresses) - item.second.print(); - printf("-----\n"); + printf("Loaded %d addresses\n", mapAddresses.size()); // Fix for possible bug that manifests in mapAddresses.count in irc.cpp, // just need to call count here and it doesn't happen there. The bug was the @@ -501,6 +497,26 @@ bool CReviewDB::WriteReviews(uint256 hash, const vector& vReviews) // CWalletDB // +CWalletDB::~CWalletDB() +{ + // Flush whenever all handles to wallet.dat are closed + Close(); + CRITICAL_BLOCK(cs_db) + { + map::iterator mi = mapFileUseCount.find(strFile); + if (mi != mapFileUseCount.end()) + { + int nRefCount = (*mi).second; + if (nRefCount == 0) + { + dbenv.txn_checkpoint(0, 0, 0); + dbenv.lsn_reset(strFile.c_str(), 0); + mapFileUseCount.erase(mi++); + } + } + } +} + bool CWalletDB::LoadWallet(vector& vchDefaultKeyRet) { vchDefaultKeyRet.clear(); @@ -568,34 +584,51 @@ bool CWalletDB::LoadWallet(vector& vchDefaultKeyRet) { ssValue >> vchDefaultKeyRet; } - else if (strType == "setting") /// or settings or option or options or config? + else if (strType == "setting") { string strKey; ssKey >> strKey; + + // Menu state + if (strKey == "fShowGenerated") ssValue >> fShowGenerated; if (strKey == "fGenerateBitcoins") ssValue >> fGenerateBitcoins; + + // Options if (strKey == "nTransactionFee") ssValue >> nTransactionFee; if (strKey == "addrIncoming") ssValue >> addrIncoming; - if (strKey == "minimizeToTray") ssValue >> minimizeToTray; - if (strKey == "closeToTray") ssValue >> closeToTray; - if (strKey == "startOnSysBoot") ssValue >> startOnSysBoot; - if (strKey == "askBeforeClosing") ssValue >> askBeforeClosing; - if (strKey == "alwaysShowTrayIcon") ssValue >> alwaysShowTrayIcon; + if (strKey == "fLimitProcessors") ssValue >> fLimitProcessors; + if (strKey == "nLimitProcessors") ssValue >> nLimitProcessors; + if (strKey == "fMinimizeToTray") ssValue >> fMinimizeToTray; + if (strKey == "fMinimizeOnClose") ssValue >> fMinimizeOnClose; } } } + printf("fShowGenerated = %d\n", fShowGenerated); printf("fGenerateBitcoins = %d\n", fGenerateBitcoins); printf("nTransactionFee = %I64d\n", nTransactionFee); printf("addrIncoming = %s\n", addrIncoming.ToString().c_str()); + printf("fMinimizeToTray = %d\n", fMinimizeToTray); + printf("fMinimizeOnClose = %d\n", fMinimizeOnClose); + + // The transaction fee setting won't be needed for many years to come. + // Setting it to zero here in case they set it to something in an earlier version. + if (nTransactionFee != 0) + { + nTransactionFee = 0; + WriteSetting("nTransactionFee", nTransactionFee); + } return true; } -bool LoadWallet() +bool LoadWallet(bool& fFirstRunRet) { + fFirstRunRet = false; vector vchDefaultKey; if (!CWalletDB("cr").LoadWallet(vchDefaultKey)) return false; + fFirstRunRet = vchDefaultKey.empty(); if (mapKeys.count(vchDefaultKey)) { diff --git a/db.h b/db.h index 1139f7686c..4961468759 100644 --- a/db.h +++ b/db.h @@ -338,6 +338,7 @@ class CWalletDB : public CDB { public: CWalletDB(const char* pszMode="r+", bool fTxn=false) : CDB("wallet.dat", pszMode, fTxn) { } + ~CWalletDB(); private: CWalletDB(const CWalletDB&); void operator=(const CWalletDB&); @@ -412,7 +413,7 @@ public: bool LoadWallet(vector& vchDefaultKeyRet); }; -bool LoadWallet(); +bool LoadWallet(bool& fFirstRunRet); inline bool SetAddressBookName(const string& strAddress, const string& strName) { diff --git a/headers.h b/headers.h index d0393c5464..f7e88e0c67 100644 --- a/headers.h +++ b/headers.h @@ -10,11 +10,11 @@ #ifdef _WIN32_WINNT #undef _WIN32_WINNT #endif -#define _WIN32_WINNT 0x0500 +#define _WIN32_WINNT 0x0400 #ifdef _WIN32_IE #undef _WIN32_IE #endif -#define _WIN32_IE 0x0500 +#define _WIN32_IE 0x0400 #define WIN32_LEAN_AND_MEAN 1 #include #include @@ -28,6 +28,8 @@ #include #include #include +#include +#include #include #include #include diff --git a/irc.cpp b/irc.cpp index 3518df2491..cfc9464aa7 100644 --- a/irc.cpp +++ b/irc.cpp @@ -52,7 +52,7 @@ bool DecodeAddress(string str, CAddress& addr) static bool Send(SOCKET hSocket, const char* pszSend) { if (strstr(pszSend, "PONG") != pszSend) - printf("SENDING: %s\n", pszSend); + printf("IRC SENDING: %s\n", pszSend); const char* psz = pszSend; const char* pszEnd = psz + strlen(psz); while (psz < pszEnd) @@ -145,7 +145,7 @@ bool Wait(int nSeconds) { if (fShutdown) return false; - printf("Waiting %d seconds to reconnect to IRC\n", nSeconds); + printf("IRC waiting %d seconds to reconnect\n", nSeconds); for (int i = 0; i < nSeconds; i++) { if (fShutdown) @@ -220,7 +220,6 @@ void ThreadIRCSeed(void* parg) { if (strLine.empty() || strLine.size() > 900 || strLine[0] != ':') continue; - printf("IRC %s\n", strLine.c_str()); vector vWords; ParseString(strLine, ' ', vWords); @@ -235,7 +234,7 @@ void ThreadIRCSeed(void* parg) // index 7 is limited to 16 characters // could get full length name at index 10, but would be different from join messages strcpy(pszName, vWords[7].c_str()); - printf("GOT WHO: [%s] ", pszName); + printf("IRC got who\n"); } if (vWords[1] == "JOIN" && vWords[0].size() > 1) @@ -244,7 +243,7 @@ void ThreadIRCSeed(void* parg) strcpy(pszName, vWords[0].c_str() + 1); if (strchr(pszName, '!')) *strchr(pszName, '!') = '\0'; - printf("GOT JOIN: [%s] ", pszName); + printf("IRC got join\n"); } if (pszName[0] == 'u') @@ -254,7 +253,7 @@ void ThreadIRCSeed(void* parg) { CAddrDB addrdb; if (AddAddress(addrdb, addr)) - printf("new "); + printf("IRC got new address\n"); else { // make it try connecting again @@ -262,14 +261,13 @@ void ThreadIRCSeed(void* parg) if (mapAddresses.count(addr.GetKey())) mapAddresses[addr.GetKey()].nLastFailed = 0; } - addr.print(); CRITICAL_BLOCK(cs_mapIRCAddresses) mapIRCAddresses.insert(make_pair(addr.GetKey(), addr)); } else { - printf("decode failed\n"); + printf("IRC decode failed\n"); } } } diff --git a/key.h b/key.h index 8b0b54e4b3..39ca86d317 100644 --- a/key.h +++ b/key.h @@ -44,6 +44,7 @@ class CKey { protected: EC_KEY* pkey; + bool fSet; public: CKey() @@ -51,6 +52,7 @@ public: pkey = EC_KEY_new_by_curve_name(NID_secp256k1); if (pkey == NULL) throw key_error("CKey::CKey() : EC_KEY_new_by_curve_name failed"); + fSet = false; } CKey(const CKey& b) @@ -58,12 +60,14 @@ public: pkey = EC_KEY_dup(b.pkey); if (pkey == NULL) throw key_error("CKey::CKey(const CKey&) : EC_KEY_dup failed"); + fSet = b.fSet; } CKey& operator=(const CKey& b) { if (!EC_KEY_copy(pkey, b.pkey)) throw key_error("CKey::operator=(const CKey&) : EC_KEY_copy failed"); + fSet = b.fSet; return (*this); } @@ -72,10 +76,16 @@ public: EC_KEY_free(pkey); } + bool IsNull() const + { + return !fSet; + } + void MakeNewKey() { if (!EC_KEY_generate_key(pkey)) throw key_error("CKey::MakeNewKey() : EC_KEY_generate_key failed"); + fSet = true; } bool SetPrivKey(const CPrivKey& vchPrivKey) @@ -83,6 +93,7 @@ public: const unsigned char* pbegin = &vchPrivKey[0]; if (!d2i_ECPrivateKey(&pkey, &pbegin, vchPrivKey.size())) return false; + fSet = true; return true; } @@ -103,6 +114,7 @@ public: const unsigned char* pbegin = &vchPubKey[0]; if (!o2i_ECPublicKey(&pkey, &pbegin, vchPubKey.size())) return false; + fSet = true; return true; } diff --git a/main.cpp b/main.cpp index ebf9d727cb..de5a5939e1 100644 --- a/main.cpp +++ b/main.cpp @@ -34,7 +34,7 @@ map mapOrphanTransactions; multimap mapOrphanTransactionsByPrev; map mapWallet; -vector > vWalletUpdated; +vector vWalletUpdated; CCriticalSection cs_mapWallet; map, CPrivKey> mapKeys; @@ -46,9 +46,12 @@ string strSetDataDir; int nDropMessagesTest = 0; // Settings -int fGenerateBitcoins; +int fGenerateBitcoins = false; int64 nTransactionFee = 0; CAddress addrIncoming; +int fLimitProcessors = false; +int nLimitProcessors = 1; + @@ -135,7 +138,7 @@ bool AddToWallet(const CWalletTx& wtxIn) return false; // Notify UI - vWalletUpdated.push_back(make_pair(hash, fInsertedNew)); + vWalletUpdated.push_back(hash); } // Refresh UI @@ -1126,6 +1129,9 @@ bool CBlock::AddToBlockIndex(unsigned int nFile, unsigned int nBlockPos) } } + // Notify UI to update prev block coinbase if it was ours + vWalletUpdated.push_back(hashBestChain); + // New best link hashBestChain = hash; pindexBest = pindexNew; @@ -1702,7 +1708,7 @@ bool ProcessMessages(CNode* pfrom) } CATCH_PRINT_EXCEPTION("ProcessMessage()") if (!fRet) - printf("ProcessMessage(%s, %d bytes) from %s to %s FAILED\n", strCommand.c_str(), nMessageSize, pfrom->addr.ToString().c_str(), addrLocalHost.ToString().c_str()); + printf("ProcessMessage(%s, %d bytes) FAILED\n", strCommand.c_str(), nMessageSize); } vRecv.Compact(); @@ -1715,10 +1721,7 @@ bool ProcessMessages(CNode* pfrom) bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) { static map > mapReuseKey; - printf("received: %-12s (%d bytes) ", strCommand.c_str(), vRecv.size()); - for (int i = 0; i < min(vRecv.size(), (unsigned int)20); i++) - printf("%02x ", vRecv[i] & 0xff); - printf("\n"); + printf("received: %-12s (%d bytes)\n", strCommand.c_str(), vRecv.size()); if (nDropMessagesTest > 0 && GetRand(nDropMessagesTest) == 0) { printf("dropmessages DROPPING RECV MESSAGE\n"); @@ -1759,7 +1762,7 @@ bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) pfrom->PushMessage("getblocks", CBlockLocator(pindexBest), uint256(0)); } - printf("version message: %s has version %d, addrMe=%s\n", pfrom->addr.ToString().c_str(), pfrom->nVersion, addrMe.ToString().c_str()); + printf("version message: version %d\n", pfrom->nVersion); } @@ -1775,13 +1778,24 @@ bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) vector vAddr; vRecv >> vAddr; + // Clear addrknown lists periodically to allow refresh broadcasts + static int64 nLastClearedAddrKnown; + if (nLastClearedAddrKnown < GetAdjustedTime() - 24 * 60 * 60) + { + nLastClearedAddrKnown = GetAdjustedTime(); + CRITICAL_BLOCK(cs_vNodes) + foreach(CNode* pnode, vNodes) + pnode->setAddrKnown.clear(); + } + // Store the new addresses CAddrDB addrdb; foreach(const CAddress& addr, vAddr) { if (fShutdown) return true; - if (AddAddress(addrdb, addr)) + AddAddress(addrdb, addr); + if (addr.IsRoutable() && addr.ip != addrLocalHost.ip) { // Put on lists to send to other nodes pfrom->setAddrKnown.insert(addr); @@ -1989,8 +2003,6 @@ bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) if (fShutdown) return true; const CAddress& addr = item.second; - //// will need this if we lose IRC - //if (addr.nTime > nSince || (rand() % nSize) < 500) if (addr.nTime > nSince) pfrom->vAddrToSend.push_back(addr); } @@ -2132,9 +2144,11 @@ bool SendMessages(CNode* pto) while (!pto->mapAskFor.empty() && (*pto->mapAskFor.begin()).first <= nNow) { const CInv& inv = (*pto->mapAskFor.begin()).second; - printf("sending getdata: %s\n", inv.ToString().c_str()); if (!AlreadyHave(txdb, inv)) + { + printf("sending getdata: %s\n", inv.ToString().c_str()); vAskFor.push_back(inv); + } pto->mapAskFor.erase(pto->mapAskFor.begin()); } if (!vAskFor.empty()) @@ -2162,6 +2176,49 @@ bool SendMessages(CNode* pto) // BitcoinMiner // +void GenerateBitcoins(bool fGenerate) +{ + if (fGenerateBitcoins != fGenerate) + { + fGenerateBitcoins = fGenerate; + CWalletDB().WriteSetting("fGenerateBitcoins", fGenerateBitcoins); + MainFrameRepaint(); + } + if (fGenerateBitcoins) + { + int nProcessors = atoi(getenv("NUMBER_OF_PROCESSORS")); + printf("%d processors\n", nProcessors); + if (nProcessors < 1) + nProcessors = 1; + if (fLimitProcessors && nProcessors > nLimitProcessors) + nProcessors = nLimitProcessors; + int nAddThreads = nProcessors - vnThreadsRunning[3]; + printf("starting %d bitcoinminer threads\n", nAddThreads); + for (int i = 0; i < nAddThreads; i++) + if (_beginthread(ThreadBitcoinMiner, 0, NULL) == -1) + printf("Error: _beginthread(ThreadBitcoinMiner) failed\n"); + } +} + +void ThreadBitcoinMiner(void* parg) +{ + vnThreadsRunning[3]++; + CheckForShutdown(3); + try + { + bool fRet = BitcoinMiner(); + printf("BitcoinMiner returned %s\n\n\n", fRet ? "true" : "false"); + vnThreadsRunning[3]--; + } + catch (std::exception& e) { + vnThreadsRunning[3]--; + PrintException(&e, "ThreadBitcoinMiner()"); + } catch (...) { + vnThreadsRunning[3]--; + PrintException(NULL, "ThreadBitcoinMiner()"); + } +} + int FormatHashBlocks(void* pbuffer, unsigned int len) { unsigned char* pdata = (unsigned char*)pbuffer; @@ -2210,13 +2267,13 @@ void BlockSHA256(const void* pin, unsigned int nBlocks, void* pout) bool BitcoinMiner() { printf("BitcoinMiner started\n"); - SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_LOWEST); CKey key; key.MakeNewKey(); CBigNum bnExtraNonce = 0; while (fGenerateBitcoins) { + SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_LOWEST); Sleep(50); CheckForShutdown(3); while (vNodes.empty()) @@ -2338,7 +2395,6 @@ bool BitcoinMiner() BlockSHA256(&tmp.block, nBlocks0, &tmp.hash1); BlockSHA256(&tmp.hash1, nBlocks1, &hash); - if (hash <= hashTarget) { pblock->nNonce = tmp.block.nNonce; @@ -2352,6 +2408,12 @@ bool BitcoinMiner() SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_NORMAL); CRITICAL_BLOCK(cs_main) { + if (pindexPrev != pindexBest) + { + SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_LOWEST); + break; + } + // Save key if (!AddKey(key)) return false; @@ -2368,7 +2430,7 @@ bool BitcoinMiner() } // Update nTime every few seconds - if ((++tmp.block.nNonce & 0x3ffff) == 0) + if ((++tmp.block.nNonce & 0xffff) == 0) { CheckForShutdown(3); if (tmp.block.nNonce == 0) @@ -2379,6 +2441,8 @@ bool BitcoinMiner() break; if (!fGenerateBitcoins) break; + if (fLimitProcessors && vnThreadsRunning[3] > nLimitProcessors) + return true; tmp.block.nTime = pblock->nTime = max(pindexPrev->GetMedianTimePast()+1, GetAdjustedTime()); } } @@ -2538,7 +2602,7 @@ bool SelectCoins(int64 nTargetValue, set& setCoinsRet) -bool CreateTransaction(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew, int64& nFeeRequiredRet) +bool CreateTransaction(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew, CKey& keyRet, int64& nFeeRequiredRet) { nFeeRequiredRet = 0; CRITICAL_BLOCK(cs_main) @@ -2565,30 +2629,28 @@ bool CreateTransaction(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew, in foreach(CWalletTx* pcoin, setCoins) nValueIn += pcoin->GetCredit(); - // Fill vout[0] to the payee - wtxNew.vout.push_back(CTxOut(nValueOut, scriptPubKey)); + // Fill a vout to the payee + bool fChangeFirst = GetRand(2); + if (!fChangeFirst) + wtxNew.vout.push_back(CTxOut(nValueOut, scriptPubKey)); - // Fill vout[1] back to self with any change + // Fill a vout back to self with any change if (nValueIn > nValue) { - /// todo: for privacy, should randomize the order of outputs, - // would also have to use a new key for the change. - // Use the same key as one of the coins - vector vchPubKey; - CTransaction& txFirst = *(*setCoins.begin()); - foreach(const CTxOut& txout, txFirst.vout) - if (txout.IsMine()) - if (ExtractPubKey(txout.scriptPubKey, true, vchPubKey)) - break; - if (vchPubKey.empty()) - return false; + // New private key + if (keyRet.IsNull()) + keyRet.MakeNewKey(); - // Fill vout[1] to ourself + // Fill a vout to ourself CScript scriptPubKey; - scriptPubKey << vchPubKey << OP_CHECKSIG; + scriptPubKey << keyRet.GetPubKey() << OP_CHECKSIG; wtxNew.vout.push_back(CTxOut(nValueIn - nValue, scriptPubKey)); } + // Fill a vout to the payee + if (fChangeFirst) + wtxNew.vout.push_back(CTxOut(nValueOut, scriptPubKey)); + // Fill vin foreach(CWalletTx* pcoin, setCoins) for (int nOut = 0; nOut < pcoin->vout.size(); nOut++) @@ -2621,13 +2683,24 @@ bool CreateTransaction(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew, in } // Call after CreateTransaction unless you want to abort -bool CommitTransactionSpent(const CWalletTx& wtxNew) +bool CommitTransactionSpent(const CWalletTx& wtxNew, const CKey& key) { CRITICAL_BLOCK(cs_main) CRITICAL_BLOCK(cs_mapWallet) { - //// todo: make this transactional, never want to add a transaction - //// without marking spent transactions + //// todo: eventually should make this transactional, never want to add a + //// transaction without marking spent transactions, although the risk of + //// interruption during this step is remote. + + // 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 + // maybe makes sense; please don't do it anywhere else. Keeping databases + // open longer than necessary can create deadlocks. + CWalletDB walletdb("r"); + + // Add the change's private key to wallet + if (!key.IsNull() && !AddKey(key)) + throw runtime_error("CommitTransactionSpent() : AddKey failed\n"); // Add tx to wallet, because if it has change it's also ours, // otherwise just for transaction history. @@ -2641,7 +2714,7 @@ bool CommitTransactionSpent(const CWalletTx& wtxNew) { pcoin->fSpent = true; pcoin->WriteToDisk(); - vWalletUpdated.push_back(make_pair(pcoin->GetHash(), false)); + vWalletUpdated.push_back(pcoin->GetHash()); } } MainFrameRepaint(); @@ -2655,8 +2728,9 @@ bool SendMoney(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew) { CRITICAL_BLOCK(cs_main) { + CKey key; int64 nFeeRequired; - if (!CreateTransaction(scriptPubKey, nValue, wtxNew, nFeeRequired)) + if (!CreateTransaction(scriptPubKey, nValue, wtxNew, key, nFeeRequired)) { string strError; if (nValue + nFeeRequired > GetBalance()) @@ -2666,7 +2740,7 @@ bool SendMoney(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew) wxMessageBox(strError, "Sending..."); return error("SendMoney() : %s\n", strError.c_str()); } - if (!CommitTransactionSpent(wtxNew)) + if (!CommitTransactionSpent(wtxNew, key)) { wxMessageBox("Error finalizing transaction ", "Sending..."); return error("SendMoney() : Error finalizing transaction"); diff --git a/main.h b/main.h index 9dd29bb6a9..6b11285e5e 100644 --- a/main.h +++ b/main.h @@ -41,6 +41,9 @@ extern int nDropMessagesTest; extern int fGenerateBitcoins; extern int64 nTransactionFee; extern CAddress addrIncoming; +extern int fLimitProcessors; +extern int nLimitProcessors; + @@ -58,14 +61,17 @@ void ReacceptWalletTransactions(); void RelayWalletTransactions(); bool LoadBlockIndex(bool fAllowNew=true); void PrintBlockTree(); -bool BitcoinMiner(); bool ProcessMessages(CNode* pfrom); bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv); bool SendMessages(CNode* pto); int64 GetBalance(); -bool CreateTransaction(CScript scriptPubKey, int64 nValue, CWalletTx& txNew, int64& nFeeRequiredRet); -bool CommitTransactionSpent(const CWalletTx& wtxNew); +bool CreateTransaction(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew, CKey& keyRet, int64& nFeeRequiredRet); +bool CommitTransactionSpent(const CWalletTx& wtxNew, const CKey& key); bool SendMoney(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew); +void GenerateBitcoins(bool fGenerate); +void ThreadBitcoinMiner(void* parg); +bool BitcoinMiner(); + @@ -1320,7 +1326,7 @@ public: extern map mapTransactions; extern map mapWallet; -extern vector > vWalletUpdated; +extern vector vWalletUpdated; extern CCriticalSection cs_mapWallet; extern map, CPrivKey> mapKeys; extern map > mapPubKeys; diff --git a/makefile b/makefile index 221684e8a9..64bb773047 100644 --- a/makefile +++ b/makefile @@ -12,7 +12,7 @@ ifeq "$(BUILD)" "debug" D=d # note: gcc 3.x profile doesn't work #DEBUGFLAGS=-O0 -g -pg -D__WXDEBUG__ -DEBUGFLAGS=-g -D__WXDEBUG__ -Wall -Wextra +DEBUGFLAGS=-g -D__WXDEBUG__ endif @@ -23,7 +23,7 @@ LIBS= \ -l db_cxx \ -l eay32 \ -l wxmsw28$(D)_richtext -l wxmsw28$(D)_html -l wxmsw28$(D)_core -l wxmsw28$(D)_adv -l wxbase28$(D) -l wxtiff$(D) -l wxjpeg$(D) -l wxpng$(D) -l wxzlib$(D) -l wxregex$(D) -l wxexpat$(D) \ - -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 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 WXDEFS=-DWIN32 -D__WXMSW__ -D_WINDOWS -DNOPCH CFLAGS=-mthreads -O0 -w -Wno-invalid-offsetof -Wformat $(DEBUGFLAGS) $(WXDEFS) $(INCLUDEPATHS) HEADERS=headers.h util.h main.h serialize.h uint256.h key.h bignum.h script.h db.h base58.h diff --git a/makefile.vc b/makefile.vc index bf7e9bc580..c3bd0c4bcd 100644 --- a/makefile.vc +++ b/makefile.vc @@ -18,8 +18,8 @@ LIBPATHS=/LIBPATH:"/DB/build_windows/$(BUILD)" /LIBPATH:"/OpenSSL/out" /LIBPATH: LIBS= \ libdb47s$(D).lib \ libeay32.lib \ - wxmsw28$(D)_richtext.lib wxmsw28$(D)_html.lib wxmsw28$(D)_core.lib wxbase28$(D).lib wxtiff$(D).lib wxjpeg$(D).lib wxpng$(D).lib wxzlib$(D).lib wxregex$(D).lib wxexpat$(D).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 + wxmsw28$(D)_richtext.lib wxmsw28$(D)_html.lib wxmsw28$(D)_core.lib wxmsw28$(D)_adv.lib wxbase28$(D).lib wxtiff$(D).lib wxjpeg$(D).lib wxpng$(D).lib wxzlib$(D).lib wxregex$(D).lib wxexpat$(D).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 WXDEFS=/DWIN32 /D__WXMSW__ /D_WINDOWS /DNOPCH CFLAGS=/c /nologo /Ob0 /MD$(D) /EHsc /GR /Zm300 /YX /Fpobj/headers.pch $(DEBUGFLAGS) $(WXDEFS) $(INCLUDEPATHS) HEADERS=headers.h util.h main.h serialize.h uint256.h key.h bignum.h script.h db.h base58.h diff --git a/net.cpp b/net.cpp index b8d96006fc..db138e13a5 100644 --- a/net.cpp +++ b/net.cpp @@ -23,7 +23,8 @@ CAddress addrLocalHost(0, DEFAULT_PORT, nLocalServices); CNode nodeLocalHost(INVALID_SOCKET, CAddress("127.0.0.1", nLocalServices)); CNode* pnodeLocalHost = &nodeLocalHost; bool fShutdown = false; -array vfThreadRunning; +array vnThreadsRunning; + vector vNodes; CCriticalSection cs_vNodes; map, CAddress> mapAddresses; @@ -57,7 +58,7 @@ bool ConnectSocket(const CAddress& addrConnect, SOCKET& hSocketRet) if (fProxy) { - printf("Proxy connecting to %s\n", addrConnect.ToString().c_str()); + printf("Proxy connecting %s\n", addrConnect.ToStringLog().c_str()); char pszSocks4IP[] = "\4\1\0\0\0\0\0\0user"; memcpy(pszSocks4IP + 2, &addrConnect.port, 2); memcpy(pszSocks4IP + 4, &addrConnect.ip, 4); @@ -81,7 +82,7 @@ bool ConnectSocket(const CAddress& addrConnect, SOCKET& hSocketRet) closesocket(hSocket); return error("Proxy returned error %d\n", pchRet[1]); } - printf("Proxy connection established %s\n", addrConnect.ToString().c_str()); + printf("Proxy connection established %s\n", addrConnect.ToStringLog().c_str()); } hSocketRet = hSocket; @@ -219,6 +220,13 @@ bool AddAddress(CAddrDB& addrdb, const CAddress& addr) addrdb.WriteAddress(addrFound); return true; } + else if (addrFound.nTime < GetAdjustedTime() - 24 * 60 * 60) + { + // Periodically update most recently seen time + addrFound.nTime = GetAdjustedTime(); + addrdb.WriteAddress(addrFound); + return false; + } } } return false; @@ -373,14 +381,14 @@ CNode* ConnectNode(CAddress addrConnect, int64 nTimeout) } /// debug print - printf("trying %s\n", addrConnect.ToString().c_str()); + printf("trying connection %s\n", addrConnect.ToStringLog().c_str()); // Connect SOCKET hSocket; if (ConnectSocket(addrConnect, hSocket)) { /// debug print - printf("connected %s\n", addrConnect.ToString().c_str()); + printf("connected %s\n", addrConnect.ToStringLog().c_str()); // Set to nonblocking u_long nOne = 1; @@ -410,7 +418,7 @@ CNode* ConnectNode(CAddress addrConnect, int64 nTimeout) void CNode::Disconnect() { - printf("disconnecting node %s\n", addr.ToString().c_str()); + printf("disconnecting node %s\n", addr.ToStringLog().c_str()); closesocket(hSocket); @@ -450,14 +458,20 @@ void ThreadSocketHandler(void* parg) loop { - vfThreadRunning[0] = true; + vnThreadsRunning[0] = true; CheckForShutdown(0); try { ThreadSocketHandler2(parg); + vnThreadsRunning[0] = false; + } + catch (std::exception& e) { + vnThreadsRunning[0] = false; + PrintException(&e, "ThreadSocketHandler()"); + } catch (...) { + vnThreadsRunning[0] = false; + PrintException(NULL, "ThreadSocketHandler()"); } - CATCH_PRINT_EXCEPTION("ThreadSocketHandler()") - vfThreadRunning[0] = false; Sleep(5000); } } @@ -548,9 +562,9 @@ void ThreadSocketHandler2(void* parg) } } - vfThreadRunning[0] = false; + vnThreadsRunning[0] = false; int nSelect = select(hSocketMax + 1, &fdsetRecv, &fdsetSend, NULL, &timeout); - vfThreadRunning[0] = true; + vnThreadsRunning[0] = true; CheckForShutdown(0); if (nSelect == SOCKET_ERROR) { @@ -590,7 +604,7 @@ void ThreadSocketHandler2(void* parg) } else { - printf("accepted connection from %s\n", addr.ToString().c_str()); + printf("accepted connection %s\n", addr.ToStringLog().c_str()); CNode* pnode = new CNode(hSocket, addr, true); pnode->AddRef(); CRITICAL_BLOCK(cs_vNodes) @@ -697,14 +711,20 @@ void ThreadOpenConnections(void* parg) loop { - vfThreadRunning[1] = true; + vnThreadsRunning[1] = true; CheckForShutdown(1); try { ThreadOpenConnections2(parg); + vnThreadsRunning[1] = false; + } + catch (std::exception& e) { + vnThreadsRunning[1] = false; + PrintException(&e, "ThreadOpenConnections()"); + } catch (...) { + vnThreadsRunning[1] = false; + PrintException(NULL, "ThreadOpenConnections()"); } - CATCH_PRINT_EXCEPTION("ThreadOpenConnections()") - vfThreadRunning[1] = false; Sleep(5000); } } @@ -720,14 +740,14 @@ void ThreadOpenConnections2(void* parg) loop { // Wait - vfThreadRunning[1] = false; + vnThreadsRunning[1] = false; Sleep(500); while (vNodes.size() >= nMaxConnections || vNodes.size() >= mapAddresses.size()) { CheckForShutdown(1); Sleep(2000); } - vfThreadRunning[1] = true; + vnThreadsRunning[1] = true; CheckForShutdown(1); @@ -823,9 +843,9 @@ void ThreadOpenConnections2(void* parg) if (addrConnect.ip == addrLocalHost.ip || !addrConnect.IsIPv4() || FindNode(addrConnect.ip)) continue; - vfThreadRunning[1] = false; + vnThreadsRunning[1] = false; CNode* pnode = ConnectNode(addrConnect); - vfThreadRunning[1] = true; + vnThreadsRunning[1] = true; CheckForShutdown(1); if (!pnode) continue; @@ -867,14 +887,20 @@ void ThreadMessageHandler(void* parg) loop { - vfThreadRunning[2] = true; + vnThreadsRunning[2] = true; CheckForShutdown(2); try { ThreadMessageHandler2(parg); + vnThreadsRunning[2] = false; + } + catch (std::exception& e) { + vnThreadsRunning[2] = false; + PrintException(&e, "ThreadMessageHandler()"); + } catch (...) { + vnThreadsRunning[2] = false; + PrintException(NULL, "ThreadMessageHandler()"); } - CATCH_PRINT_EXCEPTION("ThreadMessageHandler()") - vfThreadRunning[2] = false; Sleep(5000); } } @@ -905,9 +931,9 @@ void ThreadMessageHandler2(void* parg) } // Wait and allow messages to bunch up - vfThreadRunning[2] = false; + vnThreadsRunning[2] = false; Sleep(100); - vfThreadRunning[2] = true; + vnThreadsRunning[2] = true; CheckForShutdown(2); } } @@ -920,29 +946,6 @@ void ThreadMessageHandler2(void* parg) -//// todo: start one thread per processor, use getenv("NUMBER_OF_PROCESSORS") -void ThreadBitcoinMiner(void* parg) -{ - vfThreadRunning[3] = true; - CheckForShutdown(3); - try - { - bool fRet = BitcoinMiner(); - printf("BitcoinMiner returned %s\n\n\n", fRet ? "true" : "false"); - } - CATCH_PRINT_EXCEPTION("BitcoinMiner()") - vfThreadRunning[3] = false; -} - - - - - - - - - - bool StartNode(string& strError) { @@ -1067,17 +1070,17 @@ bool StopNode() fShutdown = true; nTransactionsUpdated++; int64 nStart = GetTime(); - while (vfThreadRunning[0] || vfThreadRunning[2] || vfThreadRunning[3]) + while (vnThreadsRunning[0] || vnThreadsRunning[2] || vnThreadsRunning[3]) { if (GetTime() - nStart > 15) break; Sleep(20); } - if (vfThreadRunning[0]) printf("ThreadSocketHandler still running\n"); - if (vfThreadRunning[1]) printf("ThreadOpenConnections still running\n"); - if (vfThreadRunning[2]) printf("ThreadMessageHandler still running\n"); - if (vfThreadRunning[3]) printf("ThreadBitcoinMiner still running\n"); - while (vfThreadRunning[2]) + if (vnThreadsRunning[0]) printf("ThreadSocketHandler still running\n"); + if (vnThreadsRunning[1]) printf("ThreadOpenConnections still running\n"); + if (vnThreadsRunning[2]) printf("ThreadMessageHandler still running\n"); + if (vnThreadsRunning[3]) printf("ThreadBitcoinMiner still running\n"); + while (vnThreadsRunning[2]) Sleep(20); Sleep(50); @@ -1091,7 +1094,7 @@ void CheckForShutdown(int n) if (fShutdown) { if (n != -1) - vfThreadRunning[n] = false; + vnThreadsRunning[n] = false; if (n == 0) foreach(CNode* pnode, vNodes) closesocket(pnode->hSocket); diff --git a/net.h b/net.h index cd311fc502..334100422f 100644 --- a/net.h +++ b/net.h @@ -20,8 +20,6 @@ enum - - bool ConnectSocket(const CAddress& addrConnect, SOCKET& hSocketRet); bool GetMyExternalIP(unsigned int& ipRet); bool AddAddress(CAddrDB& addrdb, const CAddress& addr); @@ -29,7 +27,6 @@ CNode* FindNode(unsigned int ip); CNode* ConnectNode(CAddress addrConnect, int64 nTimeout=0); void AbandonRequests(void (*fn)(void*, CDataStream&), void* param1); bool AnySubscribed(unsigned int nChannel); -void ThreadBitcoinMiner(void* parg); bool StartNode(string& strError=REF(string())); bool StopNode(); void CheckForShutdown(int n); @@ -206,7 +203,7 @@ public: READWRITE(nTime); } READWRITE(nServices); - READWRITE(FLATDATA(pchReserved)); + READWRITE(FLATDATA(pchReserved)); // for IPv6 READWRITE(ip); READWRITE(port); ) @@ -280,10 +277,14 @@ public: return strprintf("%u.%u.%u.%u", GetByte(3), GetByte(2), GetByte(1), GetByte(0)); } + string ToStringLog() const + { + return ""; + } + string ToString() const { return strprintf("%u.%u.%u.%u:%u", GetByte(3), GetByte(2), GetByte(1), GetByte(0), ntohs(port)); - //return strprintf("%u.%u.%u.%u", GetByte(3), GetByte(2), GetByte(1), GetByte(0)); } void print() const @@ -416,7 +417,7 @@ extern uint64 nLocalServices; extern CAddress addrLocalHost; extern CNode* pnodeLocalHost; extern bool fShutdown; -extern array vfThreadRunning; +extern array vnThreadsRunning; extern vector vNodes; extern CCriticalSection cs_vNodes; extern map, CAddress> mapAddresses; @@ -599,9 +600,7 @@ public: unsigned int nSize = vSend.size() - nPushPos - sizeof(CMessageHeader); memcpy((char*)&vSend[nPushPos] + offsetof(CMessageHeader, nMessageSize), &nSize, sizeof(nSize)); - printf("(%d bytes) ", nSize); - //for (int i = nPushPos+sizeof(CMessageHeader); i < min(vSend.size(), nPushPos+sizeof(CMessageHeader)+20U); i++) - // printf("%02x ", vSend[i] & 0xff); + printf("(%d bytes) ", nSize); printf("\n"); nPushPos = -1; diff --git a/readme.txt b/readme.txt deleted file mode 100644 index 7615e6fd83..0000000000 --- a/readme.txt +++ /dev/null @@ -1,76 +0,0 @@ -BitCoin v0.1.5 ALPHA - -Copyright (c) 2009 Satoshi Nakamoto -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/). This product includes -cryptographic software written by Eric Young (eay@cryptsoft.com). - - -Compilers Supported -------------------- -MinGW GCC (v3.4.5) -Microsoft Visual C++ 6.0 SP6 - - -Dependencies ------------- -Libraries you need to obtain separately to build: - - default path download -wxWidgets \wxWidgets http://www.wxwidgets.org/downloads/ -OpenSSL \OpenSSL http://www.openssl.org/source/ -Berkeley DB \DB http://www.oracle.com/technology/software/products/berkeley-db/index.html -Boost \Boost http://www.boost.org/users/download/ - -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 - - -OpenSSL -------- -Bitcoin does not use any encryption. If you want to do a no-everything -build of OpenSSL to exclude encryption routines, a few patches are required. -(OpenSSL v0.9.8h) - -Edit engines\e_gmp.c and put this #ifndef around #include - #ifndef OPENSSL_NO_RSA - #include - #endif - -Add this to crypto\err\err_all.c before the ERR_load_crypto_strings line: - void ERR_load_RSA_strings(void) { } - -Edit ms\mingw32.bat and replace the Configure line's parameters with this -no-everything list. You have to put this in the batch file because batch -files can't handle more than 9 parameters. - perl Configure mingw threads no-rc2 no-rc4 no-rc5 no-idea no-des no-bf no-cast no-aes no-camellia no-seed no-rsa no-dh - -Also REM out the following line in ms\mingw32.bat. The build fails after it's -already finished building libeay32, which is all we care about, but the -failure aborts the script before it runs dllwrap to generate libeay32.dll. - REM if errorlevel 1 goto end - -Build - ms\mingw32.bat - -If you want to use it with MSVC, generate the .lib file - lib /machine:i386 /def:ms\libeay32.def /out:out\libeay32.lib - - -Berkeley DB ------------ -MinGW with MSYS: -cd \DB\build_unix -sh ../dist/configure --enable-mingw --enable-cxx -make - - -Boost ------ -You may need Boost version 1.35 to build with MSVC 6.0. I couldn't get -version 1.37 to compile with MSVC 6.0. diff --git a/serialize.h b/serialize.h index b7ab86d22a..9b20e2a0f6 100644 --- a/serialize.h +++ b/serialize.h @@ -19,7 +19,7 @@ class CScript; class CDataStream; class CAutoFile; -static const int VERSION = 105; +static const int VERSION = 106; diff --git a/ui.cpp b/ui.cpp index a1e582ab9f..ce43a786c8 100644 --- a/ui.cpp +++ b/ui.cpp @@ -7,6 +7,13 @@ #include #endif +void ThreadRequestProductDetails(void* parg); +void ThreadRandSendTest(void* parg); +bool GetStartOnSystemStartup(); +void SetStartOnSystemStartup(bool fAutoStart); + + + DEFINE_EVENT_TYPE(wxEVT_CROSSTHREADCALL) DEFINE_EVENT_TYPE(wxEVT_REPLY1) DEFINE_EVENT_TYPE(wxEVT_REPLY2) @@ -16,22 +23,21 @@ DEFINE_EVENT_TYPE(wxEVT_TABLEUPDATED) DEFINE_EVENT_TYPE(wxEVT_TABLEDELETED) CMainFrame* pframeMain = NULL; +CMyTaskBarIcon* ptaskbaricon = NULL; map mapAddressBook; -CBitcoinTBIcon* taskBarIcon = NULL; // Tray icon - - -void ThreadRequestProductDetails(void* parg); -void ThreadRandSendTest(void* parg); +map mapArgs; bool fRandSendTest = false; void RandSend(); extern int g_isPainting; -// UI settings and their default values -int minimizeToTray = 1; -int closeToTray = 1; -int startOnSysBoot = 1; -int askBeforeClosing = 1; -int alwaysShowTrayIcon = 1; +// Settings +int fShowGenerated = true; +int fMinimizeToTray = true; +int fMinimizeOnClose = true; + + + + @@ -282,7 +288,7 @@ CMainFrame::CMainFrame(wxWindow* parent) : CMainFrameBase(parent) m_staticTextBalance->SetLabel(FormatMoney(GetBalance()) + " "); m_listCtrl->SetFocus(); SetIcon(wxICON(bitcoin)); - m_menuOptions->Check(wxID_OPTIONSGENERATEBITCOINS, fGenerateBitcoins); + ptaskbaricon = new CMyTaskBarIcon(); // Init toolbar with transparency masked bitmaps m_toolBar->ClearTools(); @@ -327,7 +333,7 @@ CMainFrame::CMainFrame(wxWindow* parent) : CMainFrameBase(parent) //m_listCtrlOrdersReceived->InsertColumn(4, "", wxLIST_FORMAT_LEFT, 100); // Init status bar - int pnWidths[3] = { -100, 81, 286 }; + int pnWidths[3] = { -100, 88, 290 }; m_statusBar->SetFieldsCount(3, pnWidths); // Fill your address text box @@ -342,6 +348,8 @@ CMainFrame::CMainFrame(wxWindow* parent) : CMainFrameBase(parent) CMainFrame::~CMainFrame() { pframeMain = NULL; + delete ptaskbaricon; + ptaskbaricon = NULL; } void Shutdown(void* parg) @@ -362,28 +370,24 @@ void Shutdown(void* parg) void CMainFrame::OnClose(wxCloseEvent& event) { - if (closeToTray && event.CanVeto()) { - event.Veto(); - SendToTray(); - } - else if (!event.CanVeto() || !askBeforeClosing || wxMessageBox("Quit program?", "Confirm", wxYES_NO, this) == wxYES) { - delete taskBarIcon; - Destroy(); - _beginthread(Shutdown, 0, NULL); - } + if (fMinimizeToTray && fMinimizeOnClose && event.CanVeto() && !IsIconized()) + { + // Divert close to minimize + event.Veto(); + Iconize(true); + } + else + { + Destroy(); + _beginthread(Shutdown, 0, NULL); + } } void CMainFrame::OnIconize(wxIconizeEvent& event) { - if (minimizeToTray) { - SendToTray(); - } -} - -void CMainFrame::SendToTray() -{ - Hide(); - taskBarIcon->Show(); + // Hide the task bar button when minimized. + // Event is sent when the frame is minimized or restored. + Show(!fMinimizeToTray || !event.Iconized()); } void CMainFrame::OnMouseEvents(wxMouseEvent& event) @@ -405,25 +409,21 @@ void CMainFrame::InsertLine(bool fNew, int nIndex, uint256 hashKey, string strSo string str0 = strSort; long nData = *(long*)&hashKey; - if (fNew) + // Find item + if (!fNew && nIndex == -1) + { + while ((nIndex = m_listCtrl->FindItem(nIndex, nData)) != -1) + if (GetItemText(m_listCtrl, nIndex, 1) == hashKey.ToString()) + break; + } + + // fNew is for blind insert, only use if you're sure it's new + if (fNew || nIndex == -1) { nIndex = m_listCtrl->InsertItem(0, str0); } else { - if (nIndex == -1) - { - // Find item - while ((nIndex = m_listCtrl->FindItem(nIndex, nData)) != -1) - if (GetItemText(m_listCtrl, nIndex, 1) == hashKey.ToString()) - break; - if (nIndex == -1) - { - printf("CMainFrame::InsertLine : Couldn't find item to be updated\n"); - return; - } - } - // If sort key changed, must delete and reinsert to make it relocate if (GetItemText(m_listCtrl, nIndex, 0) != str0) { @@ -484,6 +484,28 @@ void CMainFrame::InsertTransaction(const CWalletTx& wtx, bool fNew, int nIndex) string strStatus = FormatTxStatus(wtx); map mapValue = wtx.mapValue; + // Filter + if (wtx.IsCoinBase()) + { + // View->Show Generated + if (!fShowGenerated) + return; + + // 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; + } + // Find the block the tx is in CBlockIndex* pindex = NULL; map::iterator mi = mapBlockIndex.find(wtx.hashBlock); @@ -785,16 +807,11 @@ void CMainFrame::OnPaintListCtrl(wxPaintEvent& event) { TRY_CRITICAL_BLOCK(cs_mapWallet) { - pair item; - foreach(item, vWalletUpdated) + foreach(uint256 hash, vWalletUpdated) { - bool fNew = item.second; - map::iterator mi = mapWallet.find(item.first); + map::iterator mi = mapWallet.find(hash); if (mi != mapWallet.end()) - { - printf("vWalletUpdated: %s %s\n", (*mi).second.GetHash().ToString().substr(0,6).c_str(), fNew ? "new" : ""); - InsertTransaction((*mi).second, fNew); - } + InsertTransaction((*mi).second, false); } m_listCtrl->ScrollList(0, INT_MAX); vWalletUpdated.clear(); @@ -807,7 +824,7 @@ void CMainFrame::OnPaintListCtrl(wxPaintEvent& event) // Update status bar string strGen = ""; if (fGenerateBitcoins) - strGen = " Generating"; + strGen = " Generating"; if (fGenerateBitcoins && vNodes.empty()) strGen = "(not connected)"; m_statusBar->SetStatusText(strGen, 1); @@ -856,39 +873,54 @@ void CMainFrame::OnCrossThreadCall(wxCommandEvent& event) void CMainFrame::OnMenuFileExit(wxCommandEvent& event) { + // File->Exit Close(true); } +void CMainFrame::OnMenuViewShowGenerated(wxCommandEvent& event) +{ + // View->Show Generated + fShowGenerated = event.IsChecked(); + CWalletDB().WriteSetting("fShowGenerated", fShowGenerated); + RefreshListCtrl(); +} + +void CMainFrame::OnUpdateUIViewShowGenerated(wxUpdateUIEvent& event) +{ + event.Check(fShowGenerated); +} + void CMainFrame::OnMenuOptionsGenerate(wxCommandEvent& event) { + // Options->Generate Coins GenerateBitcoins(event.IsChecked()); +} - Refresh(); - wxPaintEvent eventPaint; - AddPendingEvent(eventPaint); +void CMainFrame::OnUpdateUIOptionsGenerate(wxUpdateUIEvent& event) +{ + event.Check(fGenerateBitcoins); } void CMainFrame::OnMenuOptionsChangeYourAddress(wxCommandEvent& event) { + // Options->Change Your Address OnButtonChange(event); } 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::OnUpdateMenuGenerate( wxUpdateUIEvent& event ) { - event.Check(fGenerateBitcoins); -} - void CMainFrame::OnButtonSend(wxCommandEvent& event) { /// debug test @@ -1252,58 +1284,74 @@ void CTxDetailsDialog::OnButtonOK(wxCommandEvent& event) 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); + + // Init values + m_textCtrlTransactionFee->SetValue(FormatMoney(nTransactionFee)); + m_checkBoxLimitProcessors->SetValue(fLimitProcessors); + m_spinCtrlLimitProcessors->Enable(fLimitProcessors); + m_spinCtrlLimitProcessors->SetValue(nLimitProcessors); + int nProcessors = atoi(getenv("NUMBER_OF_PROCESSORS")); + if (nProcessors < 1) + nProcessors = 999; + m_spinCtrlLimitProcessors->SetRange(1, nProcessors); + m_checkBoxStartOnSystemStartup->SetValue(fTmpStartOnSystemStartup = GetStartOnSystemStartup()); + m_checkBoxMinimizeToTray->SetValue(fMinimizeToTray); + m_checkBoxMinimizeOnClose->Enable(fMinimizeToTray); + m_checkBoxMinimizeOnClose->SetValue(fMinimizeToTray && fMinimizeOnClose); + fTmpMinimizeOnClose = fMinimizeOnClose; m_buttonOK->SetFocus(); - m_treeCtrl->AddRoot(wxT("Settings")); - m_treeCtrl->AppendItem(m_treeCtrl->GetRootItem(), wxT("Bitcoin")); - m_treeCtrl->AppendItem(m_treeCtrl->GetRootItem(), wxT("UI")); +} - panelUI = new COptionsPanelUI(this); - panelBitcoin = new COptionsPanelBitcoin(this); - currentPanel = panelBitcoin; +void COptionsDialog::SelectPage(int nPage) +{ + m_panelMain->Show(nPage == 0); + m_panelTest2->Show(nPage == 1); - panelSizer->Add(panelUI); - panelSizer->Hide(panelUI); - panelSizer->Add(panelBitcoin); - panelSizer->Layout(); + m_scrolledWindow->Layout(); + m_scrolledWindow->SetScrollbars(0, 0, 0, 0, 0, 0); +} +void COptionsDialog::OnListBox(wxCommandEvent& event) +{ + SelectPage(event.GetSelection()); } -void COptionsDialog::MenuSelChanged( wxTreeEvent& event ) +void COptionsDialog::OnKillFocusTransactionFee(wxFocusEvent& event) { - panelSizer->Hide(currentPanel); - wxString text = m_treeCtrl->GetItemText(event.GetItem()); - if (text == "Bitcoin") { - panelSizer->Show(panelBitcoin); - currentPanel = panelBitcoin; - } - else { - panelSizer->Show(panelUI); - currentPanel = panelUI; - } - panelSizer->Layout(); + int64 nTmp = nTransactionFee; + ParseMoney(m_textCtrlTransactionFee->GetValue(), nTmp); + m_textCtrlTransactionFee->SetValue(FormatMoney(nTmp)); } -void COptionsDialog::OnButtonOK(wxCommandEvent& event) +void COptionsDialog::OnCheckBoxLimitProcessors(wxCommandEvent& event) { - // nTransactionFee - int64 nPrevTransactionFee = nTransactionFee; - if (ParseMoney(panelBitcoin->m_textCtrlTransactionFee->GetValue(), nTransactionFee) && nTransactionFee != nPrevTransactionFee) - CWalletDB().WriteSetting("transactionFee", nTransactionFee); + m_spinCtrlLimitProcessors->Enable(event.IsChecked()); +} - minimizeToTray = panelUI->m_checkMinToTray->IsChecked(); - closeToTray = panelUI->m_checkCloseToTray->IsChecked(); - startOnSysBoot = panelUI->m_checkStartOnSysBoot->IsChecked(); - askBeforeClosing = panelUI->m_checkAskBeforeClosing->IsChecked(); - alwaysShowTrayIcon = panelUI->m_checkAlwaysShowTray->IsChecked(); +void COptionsDialog::OnCheckBoxMinimizeToTray(wxCommandEvent& event) +{ + m_checkBoxMinimizeOnClose->Enable(event.IsChecked()); - CWalletDB().WriteSetting("minimizeToTray", minimizeToTray); - CWalletDB().WriteSetting("closeToTray", closeToTray); - CWalletDB().WriteSetting("startOnSysBoot", startOnSysBoot); - CWalletDB().WriteSetting("askBeforeClosing", askBeforeClosing); - CWalletDB().WriteSetting("alwaysShowTrayIcon", alwaysShowTrayIcon); + // Save the value in fTmpMinimizeOnClose so we can + // show the checkbox unchecked when its parent is unchecked + if (event.IsChecked()) + m_checkBoxMinimizeOnClose->SetValue(fTmpMinimizeOnClose); + else + { + fTmpMinimizeOnClose = m_checkBoxMinimizeOnClose->GetValue(); + m_checkBoxMinimizeOnClose->SetValue(false); + } - ApplyUISettings(); +} +void COptionsDialog::OnButtonOK(wxCommandEvent& event) +{ + OnButtonApply(event); Close(); } @@ -1312,44 +1360,53 @@ void COptionsDialog::OnButtonCancel(wxCommandEvent& event) Close(); } - - -////////////////////////////////////////////////////////////////////////////// -// -// COptionsPanelBitcoin -// - -COptionsPanelBitcoin::COptionsPanelBitcoin(wxWindow* parent) : COptionsPanelBitcoinBase(parent) +void COptionsDialog::OnButtonApply(wxCommandEvent& event) { - m_textCtrlTransactionFee->SetValue(FormatMoney(nTransactionFee)); -} + CWalletDB walletdb; -void COptionsPanelBitcoin::OnKillFocusTransactionFee(wxFocusEvent& event) -{ - int64 nTmp = nTransactionFee; - ParseMoney(m_textCtrlTransactionFee->GetValue(), nTmp); - m_textCtrlTransactionFee->SetValue(FormatMoney(nTmp)); -} + int64 nPrevTransactionFee = nTransactionFee; + if (ParseMoney(m_textCtrlTransactionFee->GetValue(), nTransactionFee) && nTransactionFee != nPrevTransactionFee) + walletdb.WriteSetting("nTransactionFee", nTransactionFee); + int nPrevMaxProc = (fLimitProcessors ? nLimitProcessors : INT_MAX); + if (fLimitProcessors != m_checkBoxLimitProcessors->GetValue()) + { + fLimitProcessors = m_checkBoxLimitProcessors->GetValue(); + walletdb.WriteSetting("fLimitProcessors", fLimitProcessors); + } + if (nLimitProcessors != m_spinCtrlLimitProcessors->GetValue()) + { + nLimitProcessors = m_spinCtrlLimitProcessors->GetValue(); + walletdb.WriteSetting("nLimitProcessors", nLimitProcessors); + } + if (fGenerateBitcoins && (fLimitProcessors ? nLimitProcessors : INT_MAX) > nPrevMaxProc) + GenerateBitcoins(fGenerateBitcoins); -////////////////////////////////////////////////////////////////////////////// -// -// COptionsPanelUI -// + if (fTmpStartOnSystemStartup != m_checkBoxStartOnSystemStartup->GetValue()) + { + fTmpStartOnSystemStartup = m_checkBoxStartOnSystemStartup->GetValue(); + SetStartOnSystemStartup(fTmpStartOnSystemStartup); + } -COptionsPanelUI::COptionsPanelUI(wxWindow* parent) : COptionsPanelUIBase(parent) -{ - m_checkMinToTray->SetValue(minimizeToTray); - m_checkCloseToTray->SetValue(closeToTray); - m_checkStartOnSysBoot->SetValue(startOnSysBoot); - m_checkAskBeforeClosing->SetValue(askBeforeClosing); - m_checkAlwaysShowTray->SetValue(alwaysShowTrayIcon); + if (fMinimizeToTray != m_checkBoxMinimizeToTray->GetValue()) + { + fMinimizeToTray = m_checkBoxMinimizeToTray->GetValue(); + walletdb.WriteSetting("fMinimizeToTray", fMinimizeToTray); + ptaskbaricon->Show(fMinimizeToTray); + } + + if (fMinimizeOnClose != (fMinimizeToTray ? m_checkBoxMinimizeOnClose->GetValue() : fTmpMinimizeOnClose)) + { + fMinimizeOnClose = (fMinimizeToTray ? m_checkBoxMinimizeOnClose->GetValue() : fTmpMinimizeOnClose); + walletdb.WriteSetting("fMinimizeOnClose", fMinimizeOnClose); + } } + ////////////////////////////////////////////////////////////////////////////// // // CAboutDialog @@ -1387,6 +1444,7 @@ CSendDialog::CSendDialog(wxWindow* parent, const wxString& strAddress) : CSendDi m_textCtrlAddress->SetValue(strAddress); m_choiceTransferType->SetSelection(0); m_bitmapCheckMark->Show(false); + fEnabledPrev = true; //// todo: should add a display of your balance for convenience // Set Icon @@ -1418,6 +1476,19 @@ void CSendDialog::OnTextAddress(wxCommandEvent& event) m_staticTextMessage->Enable(fEnable); m_textCtrlMessage->Enable(fEnable); m_textCtrlMessage->SetBackgroundColour(wxSystemSettings::GetColour(fEnable ? wxSYS_COLOUR_WINDOW : wxSYS_COLOUR_BTNFACE)); + if (!fEnable && fEnabledPrev) + { + strFromSave = m_textCtrlFrom->GetValue(); + strMessageSave = m_textCtrlMessage->GetValue(); + m_textCtrlFrom->SetValue("Will appear as \"From: Unknown\""); + m_textCtrlMessage->SetValue("Can't include a message when sending to a Bitcoin address"); + } + else if (fEnable && !fEnabledPrev) + { + m_textCtrlFrom->SetValue(strFromSave); + m_textCtrlMessage->SetValue(strMessageSave); + } + fEnabledPrev = fEnable; } void CSendDialog::OnKillFocusAmount(wxFocusEvent& event) @@ -1773,8 +1844,9 @@ void CSendingDialog::OnReply2(CDataStream& vRecv) Error("You don't have enough money"); return; } + CKey key; int64 nFeeRequired; - if (!CreateTransaction(scriptPubKey, nPrice, wtx, nFeeRequired)) + if (!CreateTransaction(scriptPubKey, nPrice, wtx, key, nFeeRequired)) { if (nPrice + nFeeRequired > GetBalance()) Error(strprintf("This is an oversized transaction that requires a transaction fee of %s", FormatMoney(nFeeRequired).c_str())); @@ -1799,7 +1871,7 @@ void CSendingDialog::OnReply2(CDataStream& vRecv) return; // Commit - if (!CommitTransactionSpent(wtx)) + if (!CommitTransactionSpent(wtx, key)) { Error("Error finalizing payment"); return; @@ -2950,84 +3022,112 @@ void CEditReviewDialog::GetReview(CReview& review) + + ////////////////////////////////////////////////////////////////////////////// // -// BitcoinTBIcon +// CMyTaskBarIcon // -enum { - PU_RESTORE = 10001, - PU_GENERATE, - PU_EXIT, +enum +{ + ID_TASKBAR_RESTORE = 10001, + ID_TASKBAR_GENERATE, + ID_TASKBAR_EXIT, }; -BEGIN_EVENT_TABLE(CBitcoinTBIcon, wxTaskBarIcon) - EVT_TASKBAR_LEFT_DCLICK (CBitcoinTBIcon::OnLeftButtonDClick) - EVT_MENU(PU_RESTORE, CBitcoinTBIcon::OnMenuRestore) - EVT_MENU(PU_GENERATE, CBitcoinTBIcon::OnMenuGenerate) - EVT_MENU(PU_EXIT, CBitcoinTBIcon::OnMenuExit) +BEGIN_EVENT_TABLE(CMyTaskBarIcon, wxTaskBarIcon) + EVT_TASKBAR_LEFT_DCLICK(CMyTaskBarIcon::OnLeftButtonDClick) + EVT_MENU(ID_TASKBAR_RESTORE, CMyTaskBarIcon::OnMenuRestore) + EVT_MENU(ID_TASKBAR_GENERATE, CMyTaskBarIcon::OnMenuGenerate) + EVT_UPDATE_UI(ID_TASKBAR_GENERATE, CMyTaskBarIcon::OnUpdateUIGenerate) + EVT_MENU(ID_TASKBAR_EXIT, CMyTaskBarIcon::OnMenuExit) END_EVENT_TABLE() -void CBitcoinTBIcon::Show() +void CMyTaskBarIcon::Show(bool fShow) { - string tooltip = "Bitcoin"; - tooltip += fGenerateBitcoins ? " - Generating" : ""; - SetIcon(wxICON(bitcoin), tooltip); + if (fShow) + { + string strTooltip = "Bitcoin"; + if (fGenerateBitcoins) + strTooltip = "Bitcoin - Generating"; + if (fGenerateBitcoins && vNodes.empty()) + strTooltip = "Bitcoin - (not connected)"; + SetIcon(wxICON(bitcoin), strTooltip); + } + else + { + RemoveIcon(); + } } -void CBitcoinTBIcon::Hide() +void CMyTaskBarIcon::Hide() { - RemoveIcon(); + Show(false); } -void CBitcoinTBIcon::OnLeftButtonDClick(wxTaskBarIconEvent&) +void CMyTaskBarIcon::OnLeftButtonDClick(wxTaskBarIconEvent& event) { - Restore(); + Restore(); } -void CBitcoinTBIcon::OnMenuExit(wxCommandEvent&) +void CMyTaskBarIcon::OnMenuRestore(wxCommandEvent& event) { - pframeMain->Close(true); + Restore(); } -void CBitcoinTBIcon::OnMenuGenerate(wxCommandEvent& event) +void CMyTaskBarIcon::Restore() { - GenerateBitcoins(event.IsChecked()); - pframeMain->Refresh(); -} - -void CBitcoinTBIcon::OnMenuRestore(wxCommandEvent&) { - Restore(); -} - -void CBitcoinTBIcon::Restore() { pframeMain->Show(); pframeMain->Iconize(false); pframeMain->Raise(); - if (!alwaysShowTrayIcon) - Hide(); } -void CBitcoinTBIcon::UpdateTooltip() { - if (IsIconInstalled()) - Show(); +void CMyTaskBarIcon::OnMenuGenerate(wxCommandEvent& event) +{ + GenerateBitcoins(event.IsChecked()); +} + +void CMyTaskBarIcon::OnUpdateUIGenerate(wxUpdateUIEvent& event) +{ + event.Check(fGenerateBitcoins); } -wxMenu *CBitcoinTBIcon::CreatePopupMenu() +void CMyTaskBarIcon::OnMenuExit(wxCommandEvent& event) { - wxMenu *menu = new wxMenu; - menu->Append(PU_RESTORE, _T("Open Bitcoin")); - wxMenuItem* generateCheck = menu->AppendCheckItem(PU_GENERATE, _T("Generate Coins")); - menu->InsertSeparator(2); - menu->Append(PU_EXIT, _T("Exit")); + pframeMain->Close(true); +} - generateCheck->Check(fGenerateBitcoins); +void CMyTaskBarIcon::UpdateTooltip() +{ + if (IsIconInstalled()) + Show(true); +} - return menu; +wxMenu* CMyTaskBarIcon::CreatePopupMenu() +{ + wxMenu* pmenu = new wxMenu; + pmenu->Append(ID_TASKBAR_RESTORE, "&Open Bitcoin"); + pmenu->AppendCheckItem(ID_TASKBAR_GENERATE, "&Generate Coins")->Check(fGenerateBitcoins); +#ifndef __WXMAC_OSX__ // Mac has built-in quit menu + pmenu->AppendSeparator(); + pmenu->Append(ID_TASKBAR_EXIT, "E&xit"); +#endif + return pmenu; } + + + + + + + + + + ////////////////////////////////////////////////////////////////////////////// // // CMyApp @@ -3150,7 +3250,7 @@ bool CMyApp::OnInit2() // Parameters // wxImage::AddHandler(new wxPNGHandler); - map mapArgs = ParseParameters(argc, argv); + mapArgs = ParseParameters(argc, argv); if (mapArgs.count("/datadir")) strSetDataDir = mapArgs["/datadir"]; @@ -3179,6 +3279,7 @@ bool CMyApp::OnInit2() // // Load data files // + bool fFirstRun; string strErrors; int64 nStart, nEnd; @@ -3198,7 +3299,7 @@ bool CMyApp::OnInit2() printf("Loading wallet...\n"); QueryPerformanceCounter((LARGE_INTEGER*)&nStart); - if (!LoadWallet()) + if (!LoadWallet(fFirstRun)) strErrors += "Error loading wallet.dat \n"; QueryPerformanceCounter((LARGE_INTEGER*)&nEnd); printf(" wallet %20I64d\n", nEnd - nStart); @@ -3244,62 +3345,60 @@ bool CMyApp::OnInit2() // // Create the main frame window // + pframeMain = new CMainFrame(NULL); + if (mapArgs.count("/min")) + pframeMain->Iconize(true); + pframeMain->Show(true); // have to show first to get taskbar button to hide + pframeMain->Show(!fMinimizeToTray || !pframeMain->IsIconized()); + ptaskbaricon->Show(fMinimizeToTray); + + if (!CheckDiskSpace()) { - pframeMain = new CMainFrame(NULL); - pframeMain->Show(); + OnExit(); + return false; + } - if (!CheckDiskSpace()) - { - OnExit(); - return false; - } + if (!StartNode(strErrors)) + wxMessageBox(strErrors, "Bitcoin"); - if (!StartNode(strErrors)) - wxMessageBox(strErrors, "Bitcoin"); + GenerateBitcoins(fGenerateBitcoins); - if (fGenerateBitcoins) - if (_beginthread(ThreadBitcoinMiner, 0, NULL) == -1) - printf("Error: _beginthread(ThreadBitcoinMiner) failed\n"); + if (fFirstRun) + SetStartOnSystemStartup(true); - // - // Tests - // - if (argc >= 2 && stricmp(argv[1], "/send") == 0) - { - int64 nValue = 1; - if (argc >= 3) - ParseMoney(argv[2], nValue); - - string strAddress; - if (argc >= 4) - strAddress = argv[3]; - CAddress addr(strAddress.c_str()); - - CWalletTx wtx; - wtx.mapValue["to"] = strAddress; - wtx.mapValue["from"] = addrLocalHost.ToString(); - wtx.mapValue["message"] = "command line send"; - - // Send to IP address - CSendingDialog* pdialog = new CSendingDialog(pframeMain, addr, nValue, wtx); - if (!pdialog->ShowModal()) - return false; - } - if (mapArgs.count("/randsendtest")) - { - if (!mapArgs["/randsendtest"].empty()) - _beginthread(ThreadRandSendTest, 0, new string(mapArgs["/randsendtest"])); - else - fRandSendTest = true; - fDebug = true; - } + // + // Tests + // + if (argc >= 2 && stricmp(argv[1], "/send") == 0) + { + int64 nValue = 1; + if (argc >= 3) + ParseMoney(argv[2], nValue); + + string strAddress; + if (argc >= 4) + strAddress = argv[3]; + CAddress addr(strAddress.c_str()); + + CWalletTx wtx; + wtx.mapValue["to"] = strAddress; + wtx.mapValue["from"] = addrLocalHost.ToString(); + wtx.mapValue["message"] = "command line send"; + + // Send to IP address + CSendingDialog* pdialog = new CSendingDialog(pframeMain, addr, nValue, wtx); + if (!pdialog->ShowModal()) + return false; } - taskBarIcon = new CBitcoinTBIcon(); - ApplyUISettings(); - if (mapArgs.count("/min") && minimizeToTray) { - pframeMain->Iconize(true); + if (mapArgs.count("/randsendtest")) + { + if (!mapArgs["/randsendtest"].empty()) + _beginthread(ThreadRandSendTest, 0, new string(mapArgs["/randsendtest"])); + else + fRandSendTest = true; + fDebug = true; } return true; @@ -3320,14 +3419,14 @@ bool CMyApp::OnExceptionInMainLoop() catch (std::exception& e) { PrintException(&e, "CMyApp::OnExceptionInMainLoop()"); - wxLogWarning(_T("Exception %s %s"), typeid(e).name(), e.what()); + wxLogWarning("Exception %s %s", typeid(e).name(), e.what()); Sleep(1000); throw; } catch (...) { PrintException(NULL, "CMyApp::OnExceptionInMainLoop()"); - wxLogWarning(_T("Unknown exception")); + wxLogWarning("Unknown exception"); Sleep(1000); throw; } @@ -3345,14 +3444,14 @@ void CMyApp::OnUnhandledException() catch (std::exception& e) { PrintException(&e, "CMyApp::OnUnhandledException()"); - wxLogWarning(_T("Exception %s %s"), typeid(e).name(), e.what()); + wxLogWarning("Exception %s %s", typeid(e).name(), e.what()); Sleep(1000); throw; } catch (...) { PrintException(NULL, "CMyApp::OnUnhandledException()"); - wxLogWarning(_T("Unknown exception")); + wxLogWarning("Unknown exception"); Sleep(1000); throw; } @@ -3367,6 +3466,8 @@ void CMyApp::OnFatalException() void MainFrameRepaint() { + // This is called by network code that shouldn't access pframeMain and ptaskbaricon + // directly because it could still be running after the UI is closed. if (pframeMain) { printf("MainFrameRepaint()\n"); @@ -3374,68 +3475,84 @@ void MainFrameRepaint() pframeMain->Refresh(); pframeMain->AddPendingEvent(event); } + if (ptaskbaricon) + ptaskbaricon->UpdateTooltip(); } +string StartupShortcutPath() +{ + // Get the startup folder shortcut path + char pszLinkPath[MAX_PATH+100]; + pszLinkPath[0] = '\0'; + SHGetSpecialFolderPath(0, pszLinkPath, CSIDL_STARTUP, 0); + strcat(pszLinkPath, "\\Bitcoin.lnk"); + return pszLinkPath; +} + +bool GetStartOnSystemStartup() +{ + return FileExists(StartupShortcutPath().c_str()); +} -void ApplyUISettings() { - // Show the tray icon? - if (alwaysShowTrayIcon) - taskBarIcon->Show(); - else - taskBarIcon->Hide(); +void SetStartOnSystemStartup(bool fAutoStart) +{ + // If the shortcut exists already, remove it for updating + remove(StartupShortcutPath().c_str()); - // Autostart on system startup? - // Open the startup registry key - HKEY hKey; - LONG lnRes = RegOpenKeyEx( - HKEY_CURRENT_USER, - "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run", - 0, - KEY_ALL_ACCESS, - &hKey - ); + if (fAutoStart) + { + CoInitialize(NULL); - if ( ERROR_SUCCESS == lnRes ) - { - if (startOnSysBoot) { - // Get the current executable path - char exePath[ MAX_PATH ]; - GetModuleFileName(NULL, exePath, _MAX_PATH + 1); - char runCmd[ MAX_PATH + 5 ]; - strcat(runCmd, exePath); - strcat(runCmd," /min"); + // Get a pointer to the IShellLink interface. + HRESULT hres = NULL; + IShellLink* psl = NULL; + hres = CoCreateInstance(CLSID_ShellLink, NULL, + CLSCTX_INPROC_SERVER, IID_IShellLink, + reinterpret_cast(&psl)); - RegSetValueEx(hKey, - "Bitcoin", - 0, - REG_SZ, - (BYTE*)runCmd, - sizeof(runCmd) - ); - } - else { - RegDeleteValue(hKey, "Bitcoin"); - } - } - RegCloseKey(hKey); + if (SUCCEEDED(hres)) + { + // Get the current executable path + char pszExePath[MAX_PATH]; + GetModuleFileName(NULL, pszExePath, sizeof(pszExePath)); + _strlwr(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(&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(); + } } -void GenerateBitcoins(bool flag) -{ - fGenerateBitcoins = flag; - nTransactionsUpdated++; - CWalletDB().WriteSetting("fGenerateBitcoins", fGenerateBitcoins); - if (fGenerateBitcoins) - if (_beginthread(ThreadBitcoinMiner, 0, NULL) == -1) - printf("Error: _beginthread(ThreadBitcoinMiner) failed\n"); - taskBarIcon->UpdateTooltip(); -} + + + + diff --git a/ui.h b/ui.h index 11c88147ac..f89456bf3f 100644 --- a/ui.h +++ b/ui.h @@ -21,21 +21,25 @@ enum + +extern map mapArgs; + +// Settings +extern int fShowGenerated; +extern int fMinimizeToTray; +extern int fMinimizeOnClose; + + + extern void HandleCtrlA(wxKeyEvent& event); extern string DateTimeStr(int64 nTime); extern string FormatTxStatus(const CWalletTx& wtx); extern void CrossThreadCall(int nID, void* pdata); extern void MainFrameRepaint(); extern void Shutdown(void* parg); -void ApplyUISettings(); -void GenerateBitcoins(bool flag); -// UI settings -extern int minimizeToTray; -extern int closeToTray; -extern int startOnSysBoot; -extern int askBeforeClosing; -extern int alwaysShowTrayIcon; + + @@ -44,14 +48,17 @@ class CMainFrame : public CMainFrameBase protected: // Event handlers void OnClose(wxCloseEvent& event); - void OnIconize( wxIconizeEvent& 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 OnMenuViewShowGenerated(wxCommandEvent& event); + void OnUpdateUIViewShowGenerated(wxUpdateUIEvent& event); void OnMenuOptionsGenerate(wxCommandEvent& event); + void OnUpdateUIOptionsGenerate(wxUpdateUIEvent& event); void OnMenuOptionsChangeYourAddress(wxCommandEvent& event); void OnMenuOptionsOptions(wxCommandEvent& event); void OnMenuHelpAbout(wxCommandEvent& event); @@ -66,7 +73,6 @@ protected: void OnListItemActivatedProductsSent(wxListEvent& event); void OnListItemActivatedOrdersSent(wxListEvent& event); void OnListItemActivatedOrdersReceived(wxListEvent& event); - void OnUpdateMenuGenerate( wxUpdateUIEvent& event ); public: /** Constructor */ @@ -85,7 +91,6 @@ public: void InsertTransaction(const CWalletTx& wtx, bool fNew, int nIndex=-1); void RefreshListCtrl(); void RefreshStatus(); - void SendToTray(); }; @@ -107,47 +112,26 @@ public: -class COptionsPanelBitcoin : public COptionsPanelBitcoinBase -{ -protected: - // Event handlers - void OnKillFocusTransactionFee( wxFocusEvent& event ); - -public: - /** Constructor */ - COptionsPanelBitcoin(wxWindow* parent); -}; - - - -class COptionsPanelUI : public COptionsPanelUIBase -{ -protected: - // Event handlers - void OnOptionsChanged( wxCommandEvent& event ); - -public: - /** Constructor */ - COptionsPanelUI(wxWindow* parent); -}; - - - class COptionsDialog : public COptionsDialogBase { protected: // Event handlers - void MenuSelChanged( wxTreeEvent& event ); + void OnListBox(wxCommandEvent& event); + void OnKillFocusTransactionFee(wxFocusEvent& event); + void OnCheckBoxLimitProcessors(wxCommandEvent& event); + void OnCheckBoxMinimizeToTray(wxCommandEvent& event); void OnButtonOK(wxCommandEvent& event); void OnButtonCancel(wxCommandEvent& event); + void OnButtonApply(wxCommandEvent& event); - // Panels - COptionsPanelBitcoin* panelBitcoin; - COptionsPanelUI* panelUI; - wxPanel* currentPanel; public: /** Constructor */ COptionsDialog(wxWindow* parent); + + // Custom + bool fTmpStartOnSystemStartup; + bool fTmpMinimizeOnClose; + void SelectPage(int nPage); }; @@ -180,6 +164,11 @@ protected: public: /** Constructor */ CSendDialog(wxWindow* parent, const wxString& strAddress=""); + + // Custom + bool fEnabledPrev; + string strFromSave; + string strMessageSave; }; @@ -455,22 +444,33 @@ public: -class CBitcoinTBIcon : public wxTaskBarIcon +class CMyTaskBarIcon : public wxTaskBarIcon { protected: - void Restore(); - - // Event handlers - void OnLeftButtonDClick(wxTaskBarIconEvent&); - void OnMenuExit(wxCommandEvent&); - void OnMenuGenerate(wxCommandEvent&); - void OnMenuRestore(wxCommandEvent&); + // Event handlers + void OnLeftButtonDClick(wxTaskBarIconEvent& event); + void OnMenuRestore(wxCommandEvent& event); + void OnUpdateUIGenerate(wxUpdateUIEvent& event); + void OnMenuGenerate(wxCommandEvent& event); + void OnMenuExit(wxCommandEvent& event); public: - void Show(); - void Hide(); - void UpdateTooltip(); - virtual wxMenu *CreatePopupMenu(); + CMyTaskBarIcon() : wxTaskBarIcon() + { + Show(true); + } + + void Show(bool fShow=true); + void Hide(); + void Restore(); + void UpdateTooltip(); + virtual wxMenu* CreatePopupMenu(); DECLARE_EVENT_TABLE() }; + + + + + + diff --git a/uibase.cpp b/uibase.cpp index a88c67ebf4..0f9e22c528 100644 --- a/uibase.cpp +++ b/uibase.cpp @@ -24,14 +24,21 @@ CMainFrameBase::CMainFrameBase( wxWindow* parent, wxWindowID id, const wxString& m_menubar->Append( m_menuFile, wxT("&File") ); + m_menuView = new wxMenu(); + wxMenuItem* m_menuViewShowGenerated; + m_menuViewShowGenerated = new wxMenuItem( m_menuView, wxID_VIEWSHOWGENERATED, wxString( wxT("&Show Generated Coins") ) , wxEmptyString, wxITEM_CHECK ); + m_menuView->Append( m_menuViewShowGenerated ); + + m_menubar->Append( m_menuView, wxT("&View") ); + m_menuOptions = new wxMenu(); wxMenuItem* m_menuOptionsGenerateBitcoins; m_menuOptionsGenerateBitcoins = new wxMenuItem( m_menuOptions, wxID_OPTIONSGENERATEBITCOINS, wxString( wxT("&Generate Coins") ) , wxEmptyString, wxITEM_CHECK ); m_menuOptions->Append( m_menuOptionsGenerateBitcoins ); - wxMenuItem* m_menuChangeYourAddress; - m_menuChangeYourAddress = new wxMenuItem( m_menuOptions, wxID_ANY, wxString( wxT("&Change Your Address...") ) , wxEmptyString, wxITEM_NORMAL ); - m_menuOptions->Append( m_menuChangeYourAddress ); + wxMenuItem* m_menuOptionsChangeYourAddress; + m_menuOptionsChangeYourAddress = new wxMenuItem( m_menuOptions, wxID_ANY, wxString( wxT("&Change Your Address...") ) , wxEmptyString, wxITEM_NORMAL ); + m_menuOptions->Append( m_menuOptionsChangeYourAddress ); wxMenuItem* m_menuOptionsOptions; m_menuOptionsOptions = new wxMenuItem( m_menuOptions, wxID_ANY, wxString( wxT("&Options...") ) , wxEmptyString, wxITEM_NORMAL ); @@ -225,9 +232,11 @@ CMainFrameBase::CMainFrameBase( wxWindow* parent, wxWindowID id, const wxString& 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_menuViewShowGenerated->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( CMainFrameBase::OnMenuViewShowGenerated ) ); + this->Connect( m_menuViewShowGenerated->GetId(), wxEVT_UPDATE_UI, wxUpdateUIEventHandler( CMainFrameBase::OnUpdateUIViewShowGenerated ) ); this->Connect( m_menuOptionsGenerateBitcoins->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( CMainFrameBase::OnMenuOptionsGenerate ) ); - this->Connect( m_menuOptionsGenerateBitcoins->GetId(), wxEVT_UPDATE_UI, wxUpdateUIEventHandler( CMainFrameBase::OnUpdateMenuGenerate ) ); - this->Connect( m_menuChangeYourAddress->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( CMainFrameBase::OnMenuOptionsChangeYourAddress ) ); + this->Connect( m_menuOptionsGenerateBitcoins->GetId(), wxEVT_UPDATE_UI, wxUpdateUIEventHandler( CMainFrameBase::OnUpdateUIOptionsGenerate ) ); + 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 ) ); @@ -278,8 +287,10 @@ CMainFrameBase::~CMainFrameBase() 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::OnMenuViewShowGenerated ) ); + this->Disconnect( wxID_ANY, wxEVT_UPDATE_UI, wxUpdateUIEventHandler( CMainFrameBase::OnUpdateUIViewShowGenerated ) ); this->Disconnect( wxID_ANY, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( CMainFrameBase::OnMenuOptionsGenerate ) ); - this->Disconnect( wxID_ANY, wxEVT_UPDATE_UI, wxUpdateUIEventHandler( CMainFrameBase::OnUpdateMenuGenerate ) ); + this->Disconnect( wxID_ANY, wxEVT_UPDATE_UI, wxUpdateUIEventHandler( CMainFrameBase::OnUpdateUIOptionsGenerate ) ); 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 ) ); @@ -353,15 +364,121 @@ COptionsDialogBase::COptionsDialogBase( wxWindow* parent, wxWindowID id, const w wxBoxSizer* bSizer55; bSizer55 = new wxBoxSizer( wxVERTICAL ); - panelSizer = new wxBoxSizer( wxHORIZONTAL ); + 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, 14, 0, wxEXPAND, 5 ); + + m_staticText32 = new wxStaticText( m_panelMain, wxID_ANY, wxT("Optional transaction fee you give to the nodes that process your transactions."), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticText32->Wrap( -1 ); + m_staticText32->Hide(); + + bSizer69->Add( m_staticText32, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 ); + + wxBoxSizer* bSizer56; + bSizer56 = new wxBoxSizer( wxHORIZONTAL ); + + m_staticText31 = new wxStaticText( m_panelMain, wxID_ANY, wxT("Transaction fee:"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticText31->Wrap( -1 ); + m_staticText31->Hide(); + + 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 ); + m_textCtrlTransactionFee->Hide(); + + bSizer56->Add( m_textCtrlTransactionFee, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); + + bSizer69->Add( bSizer56, 0, wxEXPAND, 5 ); + + wxBoxSizer* bSizer71; + bSizer71 = new wxBoxSizer( wxHORIZONTAL ); + + m_checkBoxLimitProcessors = new wxCheckBox( m_panelMain, wxID_ANY, wxT("&Limit coin generation to"), wxDefaultPosition, wxDefaultSize, 0 ); + + bSizer71->Add( m_checkBoxLimitProcessors, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 ); + + m_spinCtrlLimitProcessors = new wxSpinCtrl( m_panelMain, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize( 48,-1 ), wxSP_ARROW_KEYS, 1, 999, 1 ); + bSizer71->Add( m_spinCtrlLimitProcessors, 0, wxTOP|wxBOTTOM, 5 ); + + m_staticText35 = new wxStaticText( m_panelMain, wxID_ANY, wxT("processors"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticText35->Wrap( -1 ); + bSizer71->Add( m_staticText35, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 ); + + bSizer69->Add( bSizer71, 0, 0, 5 ); + + m_checkBoxStartOnSystemStartup = new wxCheckBox( m_panelMain, wxID_ANY, wxT("&Start Bitcoin on system startup"), wxDefaultPosition, wxDefaultSize, 0 ); + + bSizer69->Add( m_checkBoxStartOnSystemStartup, 0, wxALL, 5 ); + + m_checkBoxMinimizeToTray = new wxCheckBox( m_panelMain, wxID_ANY, wxT("&Minimize to the system tray instead of the taskbar"), wxDefaultPosition, wxDefaultSize, 0 ); + + bSizer69->Add( m_checkBoxMinimizeToTray, 0, wxALL, 5 ); + + wxBoxSizer* bSizer101; + bSizer101 = new wxBoxSizer( wxHORIZONTAL ); + + + bSizer101->Add( 16, 0, 0, 0, 5 ); + + m_checkBoxMinimizeOnClose = new wxCheckBox( m_panelMain, wxID_ANY, wxT("M&inimize to system tray on close"), wxDefaultPosition, wxDefaultSize, 0 ); + + bSizer101->Add( m_checkBoxMinimizeOnClose, 0, wxALL, 5 ); + + bSizer69->Add( bSizer101, 1, 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, 14, 0, wxEXPAND, 5 ); + + m_staticText321 = new wxStaticText( m_panelTest2, wxID_ANY, wxT("Test panel 2 for future expansion"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticText321->Wrap( -1 ); + bSizer64->Add( m_staticText321, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 ); - m_treeCtrl = new wxTreeCtrl( this, wxID_ANY, wxDefaultPosition, wxSize( 100,-1 ), wxTR_HAS_BUTTONS|wxTR_HIDE_ROOT|wxTR_LINES_AT_ROOT ); - panelSizer->Add( m_treeCtrl, 0, wxALL|wxEXPAND, 5 ); + m_staticText69 = new wxStaticText( m_panelTest2, wxID_ANY, wxT("MyLabel"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticText69->Wrap( -1 ); + bSizer64->Add( m_staticText69, 0, wxALL, 5 ); - bSizer55->Add( panelSizer, 1, wxEXPAND, 5 ); + m_staticText70 = new wxStaticText( m_panelTest2, wxID_ANY, wxT("MyLabel"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticText70->Wrap( -1 ); + bSizer64->Add( m_staticText70, 0, wxALL, 5 ); - m_staticline1 = new wxStaticLine( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL ); - bSizer55->Add( m_staticline1, 0, wxEXPAND | wxALL, 5 ); + m_staticText71 = new wxStaticText( m_panelTest2, wxID_ANY, wxT("MyLabel"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticText71->Wrap( -1 ); + bSizer64->Add( m_staticText71, 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 ); @@ -374,9 +491,8 @@ COptionsDialogBase::COptionsDialogBase( wxWindow* parent, wxWindowID id, const w bSizer58->Add( m_buttonCancel, 0, wxALL, 5 ); - m_buttonApply = new wxButton( this, wxID_ANY, wxT("Apply"), wxDefaultPosition, wxDefaultSize, 0 ); - m_buttonApply->Enable( false ); - m_buttonApply->Hide(); + m_buttonApply = new wxButton( this, wxID_APPLY, wxT("&Apply"), wxDefaultPosition, wxSize( -1,-1 ), 0 ); + m_buttonApply->SetMinSize( wxSize( 85,25 ) ); bSizer58->Add( m_buttonApply, 0, wxALL, 5 ); @@ -386,17 +502,25 @@ COptionsDialogBase::COptionsDialogBase( wxWindow* parent, wxWindowID id, const w this->Layout(); // Connect Events - m_treeCtrl->Connect( wxEVT_COMMAND_TREE_SEL_CHANGED, wxTreeEventHandler( COptionsDialogBase::MenuSelChanged ), NULL, this ); + m_listBox->Connect( wxEVT_COMMAND_LISTBOX_SELECTED, wxCommandEventHandler( COptionsDialogBase::OnListBox ), NULL, this ); + m_textCtrlTransactionFee->Connect( wxEVT_KILL_FOCUS, wxFocusEventHandler( COptionsDialogBase::OnKillFocusTransactionFee ), NULL, this ); + m_checkBoxLimitProcessors->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( COptionsDialogBase::OnCheckBoxLimitProcessors ), NULL, this ); + m_checkBoxMinimizeToTray->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( COptionsDialogBase::OnCheckBoxMinimizeToTray ), 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_treeCtrl->Disconnect( wxEVT_COMMAND_TREE_SEL_CHANGED, wxTreeEventHandler( COptionsDialogBase::MenuSelChanged ), NULL, this ); + m_listBox->Disconnect( wxEVT_COMMAND_LISTBOX_SELECTED, wxCommandEventHandler( COptionsDialogBase::OnListBox ), NULL, this ); + m_textCtrlTransactionFee->Disconnect( wxEVT_KILL_FOCUS, wxFocusEventHandler( COptionsDialogBase::OnKillFocusTransactionFee ), NULL, this ); + m_checkBoxLimitProcessors->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( COptionsDialogBase::OnCheckBoxLimitProcessors ), NULL, this ); + m_checkBoxMinimizeToTray->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( COptionsDialogBase::OnCheckBoxMinimizeToTray ), 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 ) @@ -1815,78 +1939,3 @@ CGetTextFromUserDialogBase::~CGetTextFromUserDialogBase() m_buttonOK->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CGetTextFromUserDialogBase::OnButtonOK ), NULL, this ); m_buttonCancel->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CGetTextFromUserDialogBase::OnButtonCancel ), NULL, this ); } - -COptionsPanelBitcoinBase::COptionsPanelBitcoinBase( wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style ) : wxPanel( parent, id, pos, size, style ) -{ - wxBoxSizer* bSizer62; - bSizer62 = new wxBoxSizer( wxVERTICAL ); - - - bSizer62->Add( 0, 20, 0, wxEXPAND, 5 ); - - m_staticText32 = new wxStaticText( this, wxID_ANY, wxT("Optional transaction fee you give to the nodes that process your transactions."), wxDefaultPosition, wxDefaultSize, 0 ); - m_staticText32->Wrap( -1 ); - bSizer62->Add( m_staticText32, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 ); - - wxBoxSizer* bSizer56; - bSizer56 = new wxBoxSizer( wxHORIZONTAL ); - - m_staticText31 = new wxStaticText( this, wxID_ANY, wxT("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( this, wxID_TRANSACTIONFEE, wxEmptyString, wxDefaultPosition, wxSize( 70,-1 ), 0 ); - bSizer56->Add( m_textCtrlTransactionFee, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); - - bSizer62->Add( bSizer56, 0, wxEXPAND, 5 ); - - this->SetSizer( bSizer62 ); - this->Layout(); - bSizer62->Fit( this ); - - // Connect Events - m_textCtrlTransactionFee->Connect( wxEVT_KILL_FOCUS, wxFocusEventHandler( COptionsPanelBitcoinBase::OnKillFocusTransactionFee ), NULL, this ); -} - -COptionsPanelBitcoinBase::~COptionsPanelBitcoinBase() -{ - // Disconnect Events - m_textCtrlTransactionFee->Disconnect( wxEVT_KILL_FOCUS, wxFocusEventHandler( COptionsPanelBitcoinBase::OnKillFocusTransactionFee ), NULL, this ); -} - -COptionsPanelUIBase::COptionsPanelUIBase( wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style ) : wxPanel( parent, id, pos, size, style ) -{ - wxBoxSizer* bSizer57; - bSizer57 = new wxBoxSizer( wxVERTICAL ); - - - bSizer57->Add( 0, 20, 1, wxEXPAND, 5 ); - - m_checkMinToTray = new wxCheckBox( this, wxID_MINTOTRAY, wxT("Minimize to tray"), wxDefaultPosition, wxDefaultSize, 0 ); - - bSizer57->Add( m_checkMinToTray, 0, wxALL, 5 ); - - m_checkCloseToTray = new wxCheckBox( this, wxID_ANY, wxT("Close to tray"), wxDefaultPosition, wxDefaultSize, 0 ); - - bSizer57->Add( m_checkCloseToTray, 0, wxALL, 5 ); - - m_checkStartOnSysBoot = new wxCheckBox( this, wxID_ANY, wxT("Start with Windows"), wxDefaultPosition, wxDefaultSize, 0 ); - - bSizer57->Add( m_checkStartOnSysBoot, 0, wxALL, 5 ); - - m_checkAskBeforeClosing = new wxCheckBox( this, wxID_ANY, wxT("Ask before closing"), wxDefaultPosition, wxDefaultSize, 0 ); - - bSizer57->Add( m_checkAskBeforeClosing, 0, wxALL, 5 ); - - m_checkAlwaysShowTray = new wxCheckBox( this, wxID_ANY, wxT("Always show tray icon"), wxDefaultPosition, wxDefaultSize, 0 ); - - bSizer57->Add( m_checkAlwaysShowTray, 0, wxALL, 5 ); - - this->SetSizer( bSizer57 ); - this->Layout(); - bSizer57->Fit( this ); -} - -COptionsPanelUIBase::~COptionsPanelUIBase() -{ -} diff --git a/uibase.h b/uibase.h index 61e0552283..e262a3dcb6 100644 --- a/uibase.h +++ b/uibase.h @@ -30,69 +30,70 @@ #include #include #include -#include -#include +#include +#include +#include +#include #include #include -#include #include -#include +#include /////////////////////////////////////////////////////////////////////////// #define wxID_MAINFRAME 1000 -#define wxID_OPTIONSGENERATEBITCOINS 1001 -#define wxID_BUTTONSEND 1002 -#define wxID_BUTTONRECEIVE 1003 -#define wxID_TEXTCTRLADDRESS 1004 -#define wxID_BUTTONCOPY 1005 -#define wxID_BUTTONCHANGE 1006 -#define wxID_TEXTCTRLPAYTO 1007 -#define wxID_BUTTONPASTE 1008 -#define wxID_BUTTONADDRESSBOOK 1009 -#define wxID_TEXTCTRLAMOUNT 1010 -#define wxID_CHOICETRANSFERTYPE 1011 -#define wxID_LISTCTRL 1012 -#define wxID_BUTTONRENAME 1013 -#define wxID_BUTTONNEW 1014 -#define wxID_BUTTONEDIT 1015 -#define wxID_BUTTONDELETE 1016 -#define wxID_DEL0 1017 -#define wxID_DEL1 1018 -#define wxID_DEL2 1019 -#define wxID_DEL3 1020 -#define wxID_DEL4 1021 -#define wxID_DEL5 1022 -#define wxID_DEL6 1023 -#define wxID_DEL7 1024 -#define wxID_DEL8 1025 -#define wxID_DEL9 1026 -#define wxID_DEL10 1027 -#define wxID_DEL11 1028 -#define wxID_DEL12 1029 -#define wxID_DEL13 1030 -#define wxID_DEL14 1031 -#define wxID_DEL15 1032 -#define wxID_DEL16 1033 -#define wxID_DEL17 1034 -#define wxID_DEL18 1035 -#define wxID_DEL19 1036 -#define wxID_BUTTONPREVIEW 1037 -#define wxID_BUTTONSAMPLE 1038 -#define wxID_CANCEL2 1039 -#define wxID_BUTTONBACK 1040 -#define wxID_BUTTONNEXT 1041 -#define wxID_SUBMIT 1042 -#define wxID_OPENNEWTABLE 1043 -#define wxID_DEALHAND 1044 -#define wxID_FOLD 1045 -#define wxID_CALL 1046 -#define wxID_RAISE 1047 -#define wxID_LEAVETABLE 1048 -#define wxID_DITCHPLAYER 1049 -#define wxID_TEXTCTRL 1050 -#define wxID_TRANSACTIONFEE 1051 -#define wxID_MINTOTRAY 1052 +#define wxID_VIEWSHOWGENERATED 1001 +#define wxID_OPTIONSGENERATEBITCOINS 1002 +#define wxID_BUTTONSEND 1003 +#define wxID_BUTTONRECEIVE 1004 +#define wxID_TEXTCTRLADDRESS 1005 +#define wxID_BUTTONCOPY 1006 +#define wxID_BUTTONCHANGE 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_BUTTONNEW 1016 +#define wxID_BUTTONEDIT 1017 +#define wxID_BUTTONDELETE 1018 +#define wxID_DEL0 1019 +#define wxID_DEL1 1020 +#define wxID_DEL2 1021 +#define wxID_DEL3 1022 +#define wxID_DEL4 1023 +#define wxID_DEL5 1024 +#define wxID_DEL6 1025 +#define wxID_DEL7 1026 +#define wxID_DEL8 1027 +#define wxID_DEL9 1028 +#define wxID_DEL10 1029 +#define wxID_DEL11 1030 +#define wxID_DEL12 1031 +#define wxID_DEL13 1032 +#define wxID_DEL14 1033 +#define wxID_DEL15 1034 +#define wxID_DEL16 1035 +#define wxID_DEL17 1036 +#define wxID_DEL18 1037 +#define wxID_DEL19 1038 +#define wxID_BUTTONPREVIEW 1039 +#define wxID_BUTTONSAMPLE 1040 +#define wxID_CANCEL2 1041 +#define wxID_BUTTONBACK 1042 +#define wxID_BUTTONNEXT 1043 +#define wxID_SUBMIT 1044 +#define wxID_OPENNEWTABLE 1045 +#define wxID_DEALHAND 1046 +#define wxID_FOLD 1047 +#define wxID_CALL 1048 +#define wxID_RAISE 1049 +#define wxID_LEAVETABLE 1050 +#define wxID_DITCHPLAYER 1051 +#define wxID_TEXTCTRL 1052 /////////////////////////////////////////////////////////////////////////////// /// Class CMainFrameBase @@ -104,6 +105,7 @@ class CMainFrameBase : public wxFrame protected: wxMenuBar* m_menubar; wxMenu* m_menuFile; + wxMenu* m_menuView; wxMenu* m_menuHelp; wxToolBar* m_toolBar; wxStatusBar* m_statusBar; @@ -132,8 +134,10 @@ class CMainFrameBase : public wxFrame virtual void OnMouseEvents( wxMouseEvent& event ){ event.Skip(); } virtual void OnPaint( wxPaintEvent& event ){ event.Skip(); } virtual void OnMenuFileExit( wxCommandEvent& event ){ event.Skip(); } + virtual void OnMenuViewShowGenerated( wxCommandEvent& event ){ event.Skip(); } + virtual void OnUpdateUIViewShowGenerated( wxUpdateUIEvent& event ){ event.Skip(); } virtual void OnMenuOptionsGenerate( wxCommandEvent& event ){ event.Skip(); } - virtual void OnUpdateMenuGenerate( wxUpdateUIEvent& event ){ event.Skip(); } + virtual void OnUpdateUIOptionsGenerate( wxUpdateUIEvent& event ){ event.Skip(); } virtual void OnMenuOptionsChangeYourAddress( wxCommandEvent& event ){ event.Skip(); } virtual void OnMenuOptionsOptions( wxCommandEvent& event ){ event.Skip(); } virtual void OnMenuHelpAbout( wxCommandEvent& event ){ event.Skip(); } @@ -193,21 +197,42 @@ class COptionsDialogBase : public wxDialog private: protected: - wxBoxSizer* panelSizer; - wxTreeCtrl* m_treeCtrl; - wxStaticLine* m_staticline1; + wxListBox* m_listBox; + wxScrolledWindow* m_scrolledWindow; + wxPanel* m_panelMain; + + wxStaticText* m_staticText32; + wxStaticText* m_staticText31; + wxTextCtrl* m_textCtrlTransactionFee; + wxCheckBox* m_checkBoxLimitProcessors; + wxSpinCtrl* m_spinCtrlLimitProcessors; + wxStaticText* m_staticText35; + wxCheckBox* m_checkBoxStartOnSystemStartup; + wxCheckBox* m_checkBoxMinimizeToTray; + + wxCheckBox* m_checkBoxMinimizeOnClose; + wxPanel* m_panelTest2; + + wxStaticText* m_staticText321; + wxStaticText* m_staticText69; + wxStaticText* m_staticText70; + wxStaticText* m_staticText71; wxButton* m_buttonOK; wxButton* m_buttonCancel; wxButton* m_buttonApply; // Virtual event handlers, overide them in your derived class - virtual void MenuSelChanged( wxTreeEvent& event ){ event.Skip(); } + virtual void OnListBox( wxCommandEvent& event ){ event.Skip(); } + virtual void OnKillFocusTransactionFee( wxFocusEvent& event ){ event.Skip(); } + virtual void OnCheckBoxLimitProcessors( wxCommandEvent& event ){ event.Skip(); } + virtual void OnCheckBoxMinimizeToTray( wxCommandEvent& 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 = wxT("Options"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 555,377 ), long style = wxDEFAULT_DIALOG_STYLE ); + COptionsDialogBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxT("Options"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 540,360 ), long style = wxDEFAULT_DIALOG_STYLE ); ~COptionsDialogBase(); }; @@ -720,48 +745,4 @@ class CGetTextFromUserDialogBase : public wxDialog }; -/////////////////////////////////////////////////////////////////////////////// -/// Class COptionsPanelBitcoinBase -/////////////////////////////////////////////////////////////////////////////// -class COptionsPanelBitcoinBase : public wxPanel -{ - private: - - protected: - - wxStaticText* m_staticText32; - wxStaticText* m_staticText31; - - // Virtual event handlers, overide them in your derived class - virtual void OnKillFocusTransactionFee( wxFocusEvent& event ){ event.Skip(); } - - - public: - wxTextCtrl* m_textCtrlTransactionFee; - COptionsPanelBitcoinBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxTAB_TRAVERSAL ); - ~COptionsPanelBitcoinBase(); - -}; - -/////////////////////////////////////////////////////////////////////////////// -/// Class COptionsPanelUIBase -/////////////////////////////////////////////////////////////////////////////// -class COptionsPanelUIBase : public wxPanel -{ - private: - - protected: - - - public: - wxCheckBox* m_checkMinToTray; - wxCheckBox* m_checkCloseToTray; - wxCheckBox* m_checkStartOnSysBoot; - wxCheckBox* m_checkAskBeforeClosing; - wxCheckBox* m_checkAlwaysShowTray; - COptionsPanelUIBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxTAB_TRAVERSAL ); - ~COptionsPanelUIBase(); - -}; - #endif //__uibase__ diff --git a/uiproject.fbp b/uiproject.fbp index 315cc725a0..af5876b4ab 100644 --- a/uiproject.fbp +++ b/uiproject.fbp @@ -18,7 +18,7 @@ 1 0 0 - + wxSYS_COLOUR_BTNFACE @@ -134,6 +134,26 @@ + + &View + m_menuView + protected + + + 0 + 1 + + wxID_VIEWSHOWGENERATED + wxITEM_CHECK + &Show Generated Coins + m_menuViewShowGenerated + none + + + OnMenuViewShowGenerated + OnUpdateUIViewShowGenerated + + &Options m_menuOptions @@ -151,7 +171,7 @@ OnMenuOptionsGenerate - OnUpdateMenuGenerate + OnUpdateUIOptionsGenerate @@ -161,7 +181,7 @@ wxID_ANY wxITEM_NORMAL &Change Your Address... - m_menuChangeYourAddress + m_menuOptionsChangeYourAddress none @@ -1679,7 +1699,7 @@ COptionsDialogBase - 555,377 + 540,360 wxDEFAULT_DIALOG_STYLE Options @@ -1723,20 +1743,21 @@ wxVERTICAL none - 5 - wxEXPAND + 9 + wxEXPAND|wxALL 1 - panelSizer + bSizer66 wxHORIZONTAL - protected + none 5 - wxALL|wxEXPAND + wxEXPAND|wxRIGHT 0 - + + 1 @@ -1745,11 +1766,11 @@ wxID_ANY - m_treeCtrl + m_listBox protected - 100,-1 - wxTR_HAS_BUTTONS|wxTR_HIDE_ROOT|wxTR_LINES_AT_ROOT + 110,-1 + wxLB_NEEDED_SB|wxLB_SINGLE @@ -1765,6 +1786,8 @@ + OnListBox + @@ -1777,79 +1800,911 @@ - - - - - - - - - - - - - - - - - - MenuSelChanged - - - - - - - 5 - wxEXPAND | wxALL - 0 - - - - 1 - - - 0 - wxID_ANY - - - m_staticline1 - protected - - - wxLI_HORIZONTAL - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + 5 + wxEXPAND|wxLEFT + 1 + + + + 1 + + + 0 + wxID_ANY + + + m_scrolledWindow + protected + + 5 + 5 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + bSizer63 + wxVERTICAL + none + + 5 + wxEXPAND + 0 + + + + 1 + + + 0 + wxID_ANY + + + m_panelMain + protected + + + + + + + wxTAB_TRAVERSAL + + + + + + + + + + + + + + + + + + + + + + + + + + bSizer69 + wxVERTICAL + none + + 5 + wxEXPAND + 0 + + 14 + protected + 0 + + + + 5 + wxALIGN_CENTER_VERTICAL|wxALL + 0 + + + + 1 + + + 1 + wxID_ANY + Optional transaction fee you give to the nodes that process your transactions. + + + m_staticText32 + protected + + + + + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND + 0 + + + bSizer56 + wxHORIZONTAL + none + + 5 + wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxLEFT + 0 + + + + 1 + + + 1 + wxID_ANY + Transaction fee: + + + m_staticText31 + protected + + + + + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL|wxALIGN_CENTER_VERTICAL + 0 + + + + 1 + + + 1 + wxID_TRANSACTIONFEE + + 0 + + m_textCtrlTransactionFee + protected + + 70,-1 + + + + + + + + + + + + + OnKillFocusTransactionFee + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + + 0 + + + bSizer71 + wxHORIZONTAL + none + + 5 + wxALIGN_CENTER_VERTICAL|wxALL + 0 + + + 0 + + 1 + + + 0 + wxID_ANY + &Limit coin generation to + + + m_checkBoxLimitProcessors + protected + + + + + + + + + + OnCheckBoxLimitProcessors + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxTOP|wxBOTTOM + 0 + + + + 1 + + + 0 + wxID_ANY + 1 + 999 + + 1 + + m_spinCtrlLimitProcessors + protected + + 48,-1 + wxSP_ARROW_KEYS + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALIGN_CENTER_VERTICAL|wxALL + 0 + + + + 1 + + + 0 + wxID_ANY + processors + + + m_staticText35 + protected + + + + + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL + 0 + + + 0 + + 1 + + + 0 + wxID_ANY + &Start Bitcoin on system startup + + + m_checkBoxStartOnSystemStartup + protected + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL + 0 + + + 0 + + 1 + + + 0 + wxID_ANY + &Minimize to the system tray instead of the taskbar + + + m_checkBoxMinimizeToTray + protected + + + + + + + + + + OnCheckBoxMinimizeToTray + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND + 1 + + + bSizer101 + wxHORIZONTAL + none + + 5 + + 0 + + 0 + protected + 16 + + + + 5 + wxALL + 0 + + + 0 + + 1 + + + 0 + wxID_ANY + M&inimize to system tray on close + + + m_checkBoxMinimizeOnClose + protected + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND + 0 + + + + 1 + + + 0 + wxID_ANY + + + m_panelTest2 + protected + + + + + + + wxTAB_TRAVERSAL + + + + + + + + + + + + + + + + + + + + + + + + + + bSizer64 + wxVERTICAL + none + + 5 + wxEXPAND + 0 + + 14 + protected + 0 + + + + 5 + wxALIGN_CENTER_VERTICAL|wxALL + 0 + + + + 1 + + + 0 + wxID_ANY + Test panel 2 for future expansion + + + m_staticText321 + protected + + + + + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL + 0 + + + + 1 + + + 0 + wxID_ANY + MyLabel + + + m_staticText69 + protected + + + + + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL + 0 + + + + 1 + + + 0 + wxID_ANY + MyLabel + + + m_staticText70 + protected + + + + + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL + 0 + + + + 1 + + + 0 + wxID_ANY + MyLabel + + + m_staticText71 + protected + + + + + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -1973,25 +2828,25 @@ 0 - 0 + 1 - 1 - wxID_ANY - Apply + 0 + wxID_APPLY + &Apply - + 85,25 m_buttonApply protected - + -1,-1 - + OnButtonApply @@ -11849,551 +12704,5 @@ - - - - 1 - - - 0 - wxID_ANY - - - COptionsPanelBitcoinBase - - -1,-1 - - - - - wxTAB_TRAVERSAL - - - - - - - - - - - - - - - - - - - - - - - - - - - bSizer62 - wxVERTICAL - none - - 5 - wxEXPAND - 0 - - 20 - protected - 0 - - - - 5 - wxALIGN_CENTER_VERTICAL|wxALL - 0 - - - - 1 - - - 0 - wxID_ANY - Optional transaction fee you give to the nodes that process your transactions. - - - m_staticText32 - protected - - - - - - - - - -1 - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxEXPAND - 0 - - - bSizer56 - wxHORIZONTAL - none - - 5 - wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxLEFT - 0 - - - - 1 - - - 0 - wxID_ANY - Transaction fee: - - - m_staticText31 - protected - - - - - - - - - -1 - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALL|wxALIGN_CENTER_VERTICAL - 0 - - - - 1 - - - 0 - wxID_TRANSACTIONFEE - - 0 - - m_textCtrlTransactionFee - public - - 70,-1 - - - - - - - - - - - - - OnKillFocusTransactionFee - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1 - - - 0 - wxID_ANY - - - COptionsPanelUIBase - - -1,-1 - - - - - wxTAB_TRAVERSAL - - - - - - - - - - - - - - - - - - - - - - - - - - - bSizer57 - wxVERTICAL - none - - 5 - wxEXPAND - 1 - - 20 - protected - 0 - - - - 5 - wxALL - 0 - - - 0 - - 1 - - - 0 - wxID_MINTOTRAY - Minimize to tray - - - m_checkMinToTray - public - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALL - 0 - - - 0 - - 1 - - - 0 - wxID_ANY - Close to tray - - - m_checkCloseToTray - public - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALL - 0 - - - 0 - - 1 - - - 0 - wxID_ANY - Start with Windows - - - m_checkStartOnSysBoot - public - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALL - 0 - - - 0 - - 1 - - - 0 - wxID_ANY - Ask before closing - - - m_checkAskBeforeClosing - public - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALL - 0 - - - 0 - - 1 - - - 0 - wxID_ANY - Always show tray icon - - - m_checkAlwaysShowTray - public - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/util.cpp b/util.cpp index 9c0ab142e1..8271474eee 100644 --- a/util.cpp +++ b/util.cpp @@ -86,7 +86,7 @@ void RandAddSeed(bool fPerfmon) struct tm* ptmTime = gmtime(&nTime); char pszTime[200]; strftime(pszTime, sizeof(pszTime), "%x %H:%M:%S", ptmTime); - printf("%s RandAddSeed() got %d bytes of performance data\n", pszTime, nSize); + printf("%s RandAddSeed() %d bytes\n", pszTime, nSize); } } } @@ -174,7 +174,7 @@ bool error(const char* format, ...) void PrintException(std::exception* pex, const char* pszThread) { - char pszModule[260]; + char pszModule[MAX_PATH]; pszModule[0] = '\0'; GetModuleFileName(NULL, pszModule, sizeof(pszModule)); _strlwr(pszModule); -- cgit v1.2.3 From 99cef996c788755af95a0a614d7154a30928d4b9 Mon Sep 17 00:00:00 2001 From: s_nakamoto Date: Wed, 21 Oct 2009 01:08:05 +0000 Subject: flush wallet.dat, multi-proc, reorg options, revert to startup folder shortcut git-svn-id: https://bitcoin.svn.sourceforge.net/svnroot/bitcoin/trunk@15 1a98c847-1fd6-4fd8-948a-caf3550aa51b --- build.txt | 87 ++++ db.cpp | 57 ++- db.h | 3 +- headers.h | 6 +- irc.cpp | 14 +- key.h | 12 + main.cpp | 152 ++++-- main.h | 14 +- makefile | 4 +- makefile.vc | 4 +- net.cpp | 111 ++-- net.h | 17 +- readme.txt | 76 --- serialize.h | 2 +- ui.cpp | 663 ++++++++++++++---------- ui.h | 108 ++-- uibase.cpp | 233 +++++---- uibase.h | 193 ++++--- uiproject.fbp | 1581 ++++++++++++++++++++++++++++++++++----------------------- util.cpp | 4 +- 20 files changed, 1968 insertions(+), 1373 deletions(-) create mode 100644 build.txt delete mode 100644 readme.txt diff --git a/build.txt b/build.txt new file mode 100644 index 0000000000..b6b526f1bc --- /dev/null +++ b/build.txt @@ -0,0 +1,87 @@ +BitCoin v0.1.6 ALPHA + +Copyright (c) 2009 Satoshi Nakamoto +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/). This product includes +cryptographic software written by Eric Young (eay@cryptsoft.com). + + +Compilers Supported +------------------- +MinGW GCC (currently v3.4.5) +Microsoft Visual C++ 6.0 SP6 + + +Dependencies +------------ +Libraries you need to obtain separately to build: + + default path download +wxWidgets \wxWidgets http://www.wxwidgets.org/downloads/ +OpenSSL \OpenSSL http://www.openssl.org/source/ +Berkeley DB \DB http://www.oracle.com/technology/software/products/berkeley-db/index.html +Boost \Boost http://www.boost.org/users/download/ + +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 + + +Notes +----- +The UI layout is edited with wxFormBuilder. Open the project file +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.exe" to strip the debug +symbols, which reduces the executable size by about 90%. + + +OpenSSL +------- +Bitcoin does not use any encryption. If you want to do a no-everything +build of OpenSSL to exclude encryption routines, a few patches are required. +(OpenSSL v0.9.8h) + +Edit engines\e_gmp.c and put this #ifndef around #include + #ifndef OPENSSL_NO_RSA + #include + #endif + +Add this to crypto\err\err_all.c before the ERR_load_crypto_strings line: + void ERR_load_RSA_strings(void) { } + +Edit ms\mingw32.bat and replace the Configure line's parameters with this +no-everything list. You have to put this in the batch file because batch +files can't take more than 9 command line parameters. + perl Configure mingw threads no-rc2 no-rc4 no-rc5 no-idea no-des no-bf no-cast no-aes no-camellia no-seed no-rsa no-dh + +Also REM out the following line in ms\mingw32.bat. The build fails after it's +already finished building libeay32, which is all we care about, but the +failure aborts the script before it runs dllwrap to generate libeay32.dll. + REM if errorlevel 1 goto end + +Build + ms\mingw32.bat + +If you want to use it with MSVC, generate the .lib file + lib /machine:i386 /def:ms\libeay32.def /out:out\libeay32.lib + + +Berkeley DB +----------- +Using MinGW and MSYS: +cd \DB\build_unix +sh ../dist/configure --enable-mingw --enable-cxx +make + + +Boost +----- +If you have trouble compiling Boost with Microsoft Visual C++ 6.0, try going +back to Boost version 1.35. It looks like they may be starting to reduce +support for MSVC 6.0. diff --git a/db.cpp b/db.cpp index 6607ff5961..a9f5b7953c 100644 --- a/db.cpp +++ b/db.cpp @@ -453,11 +453,7 @@ bool CAddrDB::LoadAddresses() } } - //// debug print - printf("mapAddresses:\n"); - foreach(const PAIRTYPE(vector, CAddress)& item, mapAddresses) - item.second.print(); - printf("-----\n"); + printf("Loaded %d addresses\n", mapAddresses.size()); // Fix for possible bug that manifests in mapAddresses.count in irc.cpp, // just need to call count here and it doesn't happen there. The bug was the @@ -501,6 +497,26 @@ bool CReviewDB::WriteReviews(uint256 hash, const vector& vReviews) // CWalletDB // +CWalletDB::~CWalletDB() +{ + // Flush whenever all handles to wallet.dat are closed + Close(); + CRITICAL_BLOCK(cs_db) + { + map::iterator mi = mapFileUseCount.find(strFile); + if (mi != mapFileUseCount.end()) + { + int nRefCount = (*mi).second; + if (nRefCount == 0) + { + dbenv.txn_checkpoint(0, 0, 0); + dbenv.lsn_reset(strFile.c_str(), 0); + mapFileUseCount.erase(mi++); + } + } + } +} + bool CWalletDB::LoadWallet(vector& vchDefaultKeyRet) { vchDefaultKeyRet.clear(); @@ -568,34 +584,51 @@ bool CWalletDB::LoadWallet(vector& vchDefaultKeyRet) { ssValue >> vchDefaultKeyRet; } - else if (strType == "setting") /// or settings or option or options or config? + else if (strType == "setting") { string strKey; ssKey >> strKey; + + // Menu state + if (strKey == "fShowGenerated") ssValue >> fShowGenerated; if (strKey == "fGenerateBitcoins") ssValue >> fGenerateBitcoins; + + // Options if (strKey == "nTransactionFee") ssValue >> nTransactionFee; if (strKey == "addrIncoming") ssValue >> addrIncoming; - if (strKey == "minimizeToTray") ssValue >> minimizeToTray; - if (strKey == "closeToTray") ssValue >> closeToTray; - if (strKey == "startOnSysBoot") ssValue >> startOnSysBoot; - if (strKey == "askBeforeClosing") ssValue >> askBeforeClosing; - if (strKey == "alwaysShowTrayIcon") ssValue >> alwaysShowTrayIcon; + if (strKey == "fLimitProcessors") ssValue >> fLimitProcessors; + if (strKey == "nLimitProcessors") ssValue >> nLimitProcessors; + if (strKey == "fMinimizeToTray") ssValue >> fMinimizeToTray; + if (strKey == "fMinimizeOnClose") ssValue >> fMinimizeOnClose; } } } + printf("fShowGenerated = %d\n", fShowGenerated); printf("fGenerateBitcoins = %d\n", fGenerateBitcoins); printf("nTransactionFee = %I64d\n", nTransactionFee); printf("addrIncoming = %s\n", addrIncoming.ToString().c_str()); + printf("fMinimizeToTray = %d\n", fMinimizeToTray); + printf("fMinimizeOnClose = %d\n", fMinimizeOnClose); + + // The transaction fee setting won't be needed for many years to come. + // Setting it to zero here in case they set it to something in an earlier version. + if (nTransactionFee != 0) + { + nTransactionFee = 0; + WriteSetting("nTransactionFee", nTransactionFee); + } return true; } -bool LoadWallet() +bool LoadWallet(bool& fFirstRunRet) { + fFirstRunRet = false; vector vchDefaultKey; if (!CWalletDB("cr").LoadWallet(vchDefaultKey)) return false; + fFirstRunRet = vchDefaultKey.empty(); if (mapKeys.count(vchDefaultKey)) { diff --git a/db.h b/db.h index 1139f7686c..4961468759 100644 --- a/db.h +++ b/db.h @@ -338,6 +338,7 @@ class CWalletDB : public CDB { public: CWalletDB(const char* pszMode="r+", bool fTxn=false) : CDB("wallet.dat", pszMode, fTxn) { } + ~CWalletDB(); private: CWalletDB(const CWalletDB&); void operator=(const CWalletDB&); @@ -412,7 +413,7 @@ public: bool LoadWallet(vector& vchDefaultKeyRet); }; -bool LoadWallet(); +bool LoadWallet(bool& fFirstRunRet); inline bool SetAddressBookName(const string& strAddress, const string& strName) { diff --git a/headers.h b/headers.h index d0393c5464..f7e88e0c67 100644 --- a/headers.h +++ b/headers.h @@ -10,11 +10,11 @@ #ifdef _WIN32_WINNT #undef _WIN32_WINNT #endif -#define _WIN32_WINNT 0x0500 +#define _WIN32_WINNT 0x0400 #ifdef _WIN32_IE #undef _WIN32_IE #endif -#define _WIN32_IE 0x0500 +#define _WIN32_IE 0x0400 #define WIN32_LEAN_AND_MEAN 1 #include #include @@ -28,6 +28,8 @@ #include #include #include +#include +#include #include #include #include diff --git a/irc.cpp b/irc.cpp index 3518df2491..cfc9464aa7 100644 --- a/irc.cpp +++ b/irc.cpp @@ -52,7 +52,7 @@ bool DecodeAddress(string str, CAddress& addr) static bool Send(SOCKET hSocket, const char* pszSend) { if (strstr(pszSend, "PONG") != pszSend) - printf("SENDING: %s\n", pszSend); + printf("IRC SENDING: %s\n", pszSend); const char* psz = pszSend; const char* pszEnd = psz + strlen(psz); while (psz < pszEnd) @@ -145,7 +145,7 @@ bool Wait(int nSeconds) { if (fShutdown) return false; - printf("Waiting %d seconds to reconnect to IRC\n", nSeconds); + printf("IRC waiting %d seconds to reconnect\n", nSeconds); for (int i = 0; i < nSeconds; i++) { if (fShutdown) @@ -220,7 +220,6 @@ void ThreadIRCSeed(void* parg) { if (strLine.empty() || strLine.size() > 900 || strLine[0] != ':') continue; - printf("IRC %s\n", strLine.c_str()); vector vWords; ParseString(strLine, ' ', vWords); @@ -235,7 +234,7 @@ void ThreadIRCSeed(void* parg) // index 7 is limited to 16 characters // could get full length name at index 10, but would be different from join messages strcpy(pszName, vWords[7].c_str()); - printf("GOT WHO: [%s] ", pszName); + printf("IRC got who\n"); } if (vWords[1] == "JOIN" && vWords[0].size() > 1) @@ -244,7 +243,7 @@ void ThreadIRCSeed(void* parg) strcpy(pszName, vWords[0].c_str() + 1); if (strchr(pszName, '!')) *strchr(pszName, '!') = '\0'; - printf("GOT JOIN: [%s] ", pszName); + printf("IRC got join\n"); } if (pszName[0] == 'u') @@ -254,7 +253,7 @@ void ThreadIRCSeed(void* parg) { CAddrDB addrdb; if (AddAddress(addrdb, addr)) - printf("new "); + printf("IRC got new address\n"); else { // make it try connecting again @@ -262,14 +261,13 @@ void ThreadIRCSeed(void* parg) if (mapAddresses.count(addr.GetKey())) mapAddresses[addr.GetKey()].nLastFailed = 0; } - addr.print(); CRITICAL_BLOCK(cs_mapIRCAddresses) mapIRCAddresses.insert(make_pair(addr.GetKey(), addr)); } else { - printf("decode failed\n"); + printf("IRC decode failed\n"); } } } diff --git a/key.h b/key.h index 8b0b54e4b3..39ca86d317 100644 --- a/key.h +++ b/key.h @@ -44,6 +44,7 @@ class CKey { protected: EC_KEY* pkey; + bool fSet; public: CKey() @@ -51,6 +52,7 @@ public: pkey = EC_KEY_new_by_curve_name(NID_secp256k1); if (pkey == NULL) throw key_error("CKey::CKey() : EC_KEY_new_by_curve_name failed"); + fSet = false; } CKey(const CKey& b) @@ -58,12 +60,14 @@ public: pkey = EC_KEY_dup(b.pkey); if (pkey == NULL) throw key_error("CKey::CKey(const CKey&) : EC_KEY_dup failed"); + fSet = b.fSet; } CKey& operator=(const CKey& b) { if (!EC_KEY_copy(pkey, b.pkey)) throw key_error("CKey::operator=(const CKey&) : EC_KEY_copy failed"); + fSet = b.fSet; return (*this); } @@ -72,10 +76,16 @@ public: EC_KEY_free(pkey); } + bool IsNull() const + { + return !fSet; + } + void MakeNewKey() { if (!EC_KEY_generate_key(pkey)) throw key_error("CKey::MakeNewKey() : EC_KEY_generate_key failed"); + fSet = true; } bool SetPrivKey(const CPrivKey& vchPrivKey) @@ -83,6 +93,7 @@ public: const unsigned char* pbegin = &vchPrivKey[0]; if (!d2i_ECPrivateKey(&pkey, &pbegin, vchPrivKey.size())) return false; + fSet = true; return true; } @@ -103,6 +114,7 @@ public: const unsigned char* pbegin = &vchPubKey[0]; if (!o2i_ECPublicKey(&pkey, &pbegin, vchPubKey.size())) return false; + fSet = true; return true; } diff --git a/main.cpp b/main.cpp index ebf9d727cb..de5a5939e1 100644 --- a/main.cpp +++ b/main.cpp @@ -34,7 +34,7 @@ map mapOrphanTransactions; multimap mapOrphanTransactionsByPrev; map mapWallet; -vector > vWalletUpdated; +vector vWalletUpdated; CCriticalSection cs_mapWallet; map, CPrivKey> mapKeys; @@ -46,9 +46,12 @@ string strSetDataDir; int nDropMessagesTest = 0; // Settings -int fGenerateBitcoins; +int fGenerateBitcoins = false; int64 nTransactionFee = 0; CAddress addrIncoming; +int fLimitProcessors = false; +int nLimitProcessors = 1; + @@ -135,7 +138,7 @@ bool AddToWallet(const CWalletTx& wtxIn) return false; // Notify UI - vWalletUpdated.push_back(make_pair(hash, fInsertedNew)); + vWalletUpdated.push_back(hash); } // Refresh UI @@ -1126,6 +1129,9 @@ bool CBlock::AddToBlockIndex(unsigned int nFile, unsigned int nBlockPos) } } + // Notify UI to update prev block coinbase if it was ours + vWalletUpdated.push_back(hashBestChain); + // New best link hashBestChain = hash; pindexBest = pindexNew; @@ -1702,7 +1708,7 @@ bool ProcessMessages(CNode* pfrom) } CATCH_PRINT_EXCEPTION("ProcessMessage()") if (!fRet) - printf("ProcessMessage(%s, %d bytes) from %s to %s FAILED\n", strCommand.c_str(), nMessageSize, pfrom->addr.ToString().c_str(), addrLocalHost.ToString().c_str()); + printf("ProcessMessage(%s, %d bytes) FAILED\n", strCommand.c_str(), nMessageSize); } vRecv.Compact(); @@ -1715,10 +1721,7 @@ bool ProcessMessages(CNode* pfrom) bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) { static map > mapReuseKey; - printf("received: %-12s (%d bytes) ", strCommand.c_str(), vRecv.size()); - for (int i = 0; i < min(vRecv.size(), (unsigned int)20); i++) - printf("%02x ", vRecv[i] & 0xff); - printf("\n"); + printf("received: %-12s (%d bytes)\n", strCommand.c_str(), vRecv.size()); if (nDropMessagesTest > 0 && GetRand(nDropMessagesTest) == 0) { printf("dropmessages DROPPING RECV MESSAGE\n"); @@ -1759,7 +1762,7 @@ bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) pfrom->PushMessage("getblocks", CBlockLocator(pindexBest), uint256(0)); } - printf("version message: %s has version %d, addrMe=%s\n", pfrom->addr.ToString().c_str(), pfrom->nVersion, addrMe.ToString().c_str()); + printf("version message: version %d\n", pfrom->nVersion); } @@ -1775,13 +1778,24 @@ bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) vector vAddr; vRecv >> vAddr; + // Clear addrknown lists periodically to allow refresh broadcasts + static int64 nLastClearedAddrKnown; + if (nLastClearedAddrKnown < GetAdjustedTime() - 24 * 60 * 60) + { + nLastClearedAddrKnown = GetAdjustedTime(); + CRITICAL_BLOCK(cs_vNodes) + foreach(CNode* pnode, vNodes) + pnode->setAddrKnown.clear(); + } + // Store the new addresses CAddrDB addrdb; foreach(const CAddress& addr, vAddr) { if (fShutdown) return true; - if (AddAddress(addrdb, addr)) + AddAddress(addrdb, addr); + if (addr.IsRoutable() && addr.ip != addrLocalHost.ip) { // Put on lists to send to other nodes pfrom->setAddrKnown.insert(addr); @@ -1989,8 +2003,6 @@ bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) if (fShutdown) return true; const CAddress& addr = item.second; - //// will need this if we lose IRC - //if (addr.nTime > nSince || (rand() % nSize) < 500) if (addr.nTime > nSince) pfrom->vAddrToSend.push_back(addr); } @@ -2132,9 +2144,11 @@ bool SendMessages(CNode* pto) while (!pto->mapAskFor.empty() && (*pto->mapAskFor.begin()).first <= nNow) { const CInv& inv = (*pto->mapAskFor.begin()).second; - printf("sending getdata: %s\n", inv.ToString().c_str()); if (!AlreadyHave(txdb, inv)) + { + printf("sending getdata: %s\n", inv.ToString().c_str()); vAskFor.push_back(inv); + } pto->mapAskFor.erase(pto->mapAskFor.begin()); } if (!vAskFor.empty()) @@ -2162,6 +2176,49 @@ bool SendMessages(CNode* pto) // BitcoinMiner // +void GenerateBitcoins(bool fGenerate) +{ + if (fGenerateBitcoins != fGenerate) + { + fGenerateBitcoins = fGenerate; + CWalletDB().WriteSetting("fGenerateBitcoins", fGenerateBitcoins); + MainFrameRepaint(); + } + if (fGenerateBitcoins) + { + int nProcessors = atoi(getenv("NUMBER_OF_PROCESSORS")); + printf("%d processors\n", nProcessors); + if (nProcessors < 1) + nProcessors = 1; + if (fLimitProcessors && nProcessors > nLimitProcessors) + nProcessors = nLimitProcessors; + int nAddThreads = nProcessors - vnThreadsRunning[3]; + printf("starting %d bitcoinminer threads\n", nAddThreads); + for (int i = 0; i < nAddThreads; i++) + if (_beginthread(ThreadBitcoinMiner, 0, NULL) == -1) + printf("Error: _beginthread(ThreadBitcoinMiner) failed\n"); + } +} + +void ThreadBitcoinMiner(void* parg) +{ + vnThreadsRunning[3]++; + CheckForShutdown(3); + try + { + bool fRet = BitcoinMiner(); + printf("BitcoinMiner returned %s\n\n\n", fRet ? "true" : "false"); + vnThreadsRunning[3]--; + } + catch (std::exception& e) { + vnThreadsRunning[3]--; + PrintException(&e, "ThreadBitcoinMiner()"); + } catch (...) { + vnThreadsRunning[3]--; + PrintException(NULL, "ThreadBitcoinMiner()"); + } +} + int FormatHashBlocks(void* pbuffer, unsigned int len) { unsigned char* pdata = (unsigned char*)pbuffer; @@ -2210,13 +2267,13 @@ void BlockSHA256(const void* pin, unsigned int nBlocks, void* pout) bool BitcoinMiner() { printf("BitcoinMiner started\n"); - SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_LOWEST); CKey key; key.MakeNewKey(); CBigNum bnExtraNonce = 0; while (fGenerateBitcoins) { + SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_LOWEST); Sleep(50); CheckForShutdown(3); while (vNodes.empty()) @@ -2338,7 +2395,6 @@ bool BitcoinMiner() BlockSHA256(&tmp.block, nBlocks0, &tmp.hash1); BlockSHA256(&tmp.hash1, nBlocks1, &hash); - if (hash <= hashTarget) { pblock->nNonce = tmp.block.nNonce; @@ -2352,6 +2408,12 @@ bool BitcoinMiner() SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_NORMAL); CRITICAL_BLOCK(cs_main) { + if (pindexPrev != pindexBest) + { + SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_LOWEST); + break; + } + // Save key if (!AddKey(key)) return false; @@ -2368,7 +2430,7 @@ bool BitcoinMiner() } // Update nTime every few seconds - if ((++tmp.block.nNonce & 0x3ffff) == 0) + if ((++tmp.block.nNonce & 0xffff) == 0) { CheckForShutdown(3); if (tmp.block.nNonce == 0) @@ -2379,6 +2441,8 @@ bool BitcoinMiner() break; if (!fGenerateBitcoins) break; + if (fLimitProcessors && vnThreadsRunning[3] > nLimitProcessors) + return true; tmp.block.nTime = pblock->nTime = max(pindexPrev->GetMedianTimePast()+1, GetAdjustedTime()); } } @@ -2538,7 +2602,7 @@ bool SelectCoins(int64 nTargetValue, set& setCoinsRet) -bool CreateTransaction(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew, int64& nFeeRequiredRet) +bool CreateTransaction(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew, CKey& keyRet, int64& nFeeRequiredRet) { nFeeRequiredRet = 0; CRITICAL_BLOCK(cs_main) @@ -2565,30 +2629,28 @@ bool CreateTransaction(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew, in foreach(CWalletTx* pcoin, setCoins) nValueIn += pcoin->GetCredit(); - // Fill vout[0] to the payee - wtxNew.vout.push_back(CTxOut(nValueOut, scriptPubKey)); + // Fill a vout to the payee + bool fChangeFirst = GetRand(2); + if (!fChangeFirst) + wtxNew.vout.push_back(CTxOut(nValueOut, scriptPubKey)); - // Fill vout[1] back to self with any change + // Fill a vout back to self with any change if (nValueIn > nValue) { - /// todo: for privacy, should randomize the order of outputs, - // would also have to use a new key for the change. - // Use the same key as one of the coins - vector vchPubKey; - CTransaction& txFirst = *(*setCoins.begin()); - foreach(const CTxOut& txout, txFirst.vout) - if (txout.IsMine()) - if (ExtractPubKey(txout.scriptPubKey, true, vchPubKey)) - break; - if (vchPubKey.empty()) - return false; + // New private key + if (keyRet.IsNull()) + keyRet.MakeNewKey(); - // Fill vout[1] to ourself + // Fill a vout to ourself CScript scriptPubKey; - scriptPubKey << vchPubKey << OP_CHECKSIG; + scriptPubKey << keyRet.GetPubKey() << OP_CHECKSIG; wtxNew.vout.push_back(CTxOut(nValueIn - nValue, scriptPubKey)); } + // Fill a vout to the payee + if (fChangeFirst) + wtxNew.vout.push_back(CTxOut(nValueOut, scriptPubKey)); + // Fill vin foreach(CWalletTx* pcoin, setCoins) for (int nOut = 0; nOut < pcoin->vout.size(); nOut++) @@ -2621,13 +2683,24 @@ bool CreateTransaction(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew, in } // Call after CreateTransaction unless you want to abort -bool CommitTransactionSpent(const CWalletTx& wtxNew) +bool CommitTransactionSpent(const CWalletTx& wtxNew, const CKey& key) { CRITICAL_BLOCK(cs_main) CRITICAL_BLOCK(cs_mapWallet) { - //// todo: make this transactional, never want to add a transaction - //// without marking spent transactions + //// todo: eventually should make this transactional, never want to add a + //// transaction without marking spent transactions, although the risk of + //// interruption during this step is remote. + + // 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 + // maybe makes sense; please don't do it anywhere else. Keeping databases + // open longer than necessary can create deadlocks. + CWalletDB walletdb("r"); + + // Add the change's private key to wallet + if (!key.IsNull() && !AddKey(key)) + throw runtime_error("CommitTransactionSpent() : AddKey failed\n"); // Add tx to wallet, because if it has change it's also ours, // otherwise just for transaction history. @@ -2641,7 +2714,7 @@ bool CommitTransactionSpent(const CWalletTx& wtxNew) { pcoin->fSpent = true; pcoin->WriteToDisk(); - vWalletUpdated.push_back(make_pair(pcoin->GetHash(), false)); + vWalletUpdated.push_back(pcoin->GetHash()); } } MainFrameRepaint(); @@ -2655,8 +2728,9 @@ bool SendMoney(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew) { CRITICAL_BLOCK(cs_main) { + CKey key; int64 nFeeRequired; - if (!CreateTransaction(scriptPubKey, nValue, wtxNew, nFeeRequired)) + if (!CreateTransaction(scriptPubKey, nValue, wtxNew, key, nFeeRequired)) { string strError; if (nValue + nFeeRequired > GetBalance()) @@ -2666,7 +2740,7 @@ bool SendMoney(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew) wxMessageBox(strError, "Sending..."); return error("SendMoney() : %s\n", strError.c_str()); } - if (!CommitTransactionSpent(wtxNew)) + if (!CommitTransactionSpent(wtxNew, key)) { wxMessageBox("Error finalizing transaction ", "Sending..."); return error("SendMoney() : Error finalizing transaction"); diff --git a/main.h b/main.h index 9dd29bb6a9..6b11285e5e 100644 --- a/main.h +++ b/main.h @@ -41,6 +41,9 @@ extern int nDropMessagesTest; extern int fGenerateBitcoins; extern int64 nTransactionFee; extern CAddress addrIncoming; +extern int fLimitProcessors; +extern int nLimitProcessors; + @@ -58,14 +61,17 @@ void ReacceptWalletTransactions(); void RelayWalletTransactions(); bool LoadBlockIndex(bool fAllowNew=true); void PrintBlockTree(); -bool BitcoinMiner(); bool ProcessMessages(CNode* pfrom); bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv); bool SendMessages(CNode* pto); int64 GetBalance(); -bool CreateTransaction(CScript scriptPubKey, int64 nValue, CWalletTx& txNew, int64& nFeeRequiredRet); -bool CommitTransactionSpent(const CWalletTx& wtxNew); +bool CreateTransaction(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew, CKey& keyRet, int64& nFeeRequiredRet); +bool CommitTransactionSpent(const CWalletTx& wtxNew, const CKey& key); bool SendMoney(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew); +void GenerateBitcoins(bool fGenerate); +void ThreadBitcoinMiner(void* parg); +bool BitcoinMiner(); + @@ -1320,7 +1326,7 @@ public: extern map mapTransactions; extern map mapWallet; -extern vector > vWalletUpdated; +extern vector vWalletUpdated; extern CCriticalSection cs_mapWallet; extern map, CPrivKey> mapKeys; extern map > mapPubKeys; diff --git a/makefile b/makefile index 221684e8a9..64bb773047 100644 --- a/makefile +++ b/makefile @@ -12,7 +12,7 @@ ifeq "$(BUILD)" "debug" D=d # note: gcc 3.x profile doesn't work #DEBUGFLAGS=-O0 -g -pg -D__WXDEBUG__ -DEBUGFLAGS=-g -D__WXDEBUG__ -Wall -Wextra +DEBUGFLAGS=-g -D__WXDEBUG__ endif @@ -23,7 +23,7 @@ LIBS= \ -l db_cxx \ -l eay32 \ -l wxmsw28$(D)_richtext -l wxmsw28$(D)_html -l wxmsw28$(D)_core -l wxmsw28$(D)_adv -l wxbase28$(D) -l wxtiff$(D) -l wxjpeg$(D) -l wxpng$(D) -l wxzlib$(D) -l wxregex$(D) -l wxexpat$(D) \ - -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 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 WXDEFS=-DWIN32 -D__WXMSW__ -D_WINDOWS -DNOPCH CFLAGS=-mthreads -O0 -w -Wno-invalid-offsetof -Wformat $(DEBUGFLAGS) $(WXDEFS) $(INCLUDEPATHS) HEADERS=headers.h util.h main.h serialize.h uint256.h key.h bignum.h script.h db.h base58.h diff --git a/makefile.vc b/makefile.vc index bf7e9bc580..c3bd0c4bcd 100644 --- a/makefile.vc +++ b/makefile.vc @@ -18,8 +18,8 @@ LIBPATHS=/LIBPATH:"/DB/build_windows/$(BUILD)" /LIBPATH:"/OpenSSL/out" /LIBPATH: LIBS= \ libdb47s$(D).lib \ libeay32.lib \ - wxmsw28$(D)_richtext.lib wxmsw28$(D)_html.lib wxmsw28$(D)_core.lib wxbase28$(D).lib wxtiff$(D).lib wxjpeg$(D).lib wxpng$(D).lib wxzlib$(D).lib wxregex$(D).lib wxexpat$(D).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 + wxmsw28$(D)_richtext.lib wxmsw28$(D)_html.lib wxmsw28$(D)_core.lib wxmsw28$(D)_adv.lib wxbase28$(D).lib wxtiff$(D).lib wxjpeg$(D).lib wxpng$(D).lib wxzlib$(D).lib wxregex$(D).lib wxexpat$(D).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 WXDEFS=/DWIN32 /D__WXMSW__ /D_WINDOWS /DNOPCH CFLAGS=/c /nologo /Ob0 /MD$(D) /EHsc /GR /Zm300 /YX /Fpobj/headers.pch $(DEBUGFLAGS) $(WXDEFS) $(INCLUDEPATHS) HEADERS=headers.h util.h main.h serialize.h uint256.h key.h bignum.h script.h db.h base58.h diff --git a/net.cpp b/net.cpp index b8d96006fc..db138e13a5 100644 --- a/net.cpp +++ b/net.cpp @@ -23,7 +23,8 @@ CAddress addrLocalHost(0, DEFAULT_PORT, nLocalServices); CNode nodeLocalHost(INVALID_SOCKET, CAddress("127.0.0.1", nLocalServices)); CNode* pnodeLocalHost = &nodeLocalHost; bool fShutdown = false; -array vfThreadRunning; +array vnThreadsRunning; + vector vNodes; CCriticalSection cs_vNodes; map, CAddress> mapAddresses; @@ -57,7 +58,7 @@ bool ConnectSocket(const CAddress& addrConnect, SOCKET& hSocketRet) if (fProxy) { - printf("Proxy connecting to %s\n", addrConnect.ToString().c_str()); + printf("Proxy connecting %s\n", addrConnect.ToStringLog().c_str()); char pszSocks4IP[] = "\4\1\0\0\0\0\0\0user"; memcpy(pszSocks4IP + 2, &addrConnect.port, 2); memcpy(pszSocks4IP + 4, &addrConnect.ip, 4); @@ -81,7 +82,7 @@ bool ConnectSocket(const CAddress& addrConnect, SOCKET& hSocketRet) closesocket(hSocket); return error("Proxy returned error %d\n", pchRet[1]); } - printf("Proxy connection established %s\n", addrConnect.ToString().c_str()); + printf("Proxy connection established %s\n", addrConnect.ToStringLog().c_str()); } hSocketRet = hSocket; @@ -219,6 +220,13 @@ bool AddAddress(CAddrDB& addrdb, const CAddress& addr) addrdb.WriteAddress(addrFound); return true; } + else if (addrFound.nTime < GetAdjustedTime() - 24 * 60 * 60) + { + // Periodically update most recently seen time + addrFound.nTime = GetAdjustedTime(); + addrdb.WriteAddress(addrFound); + return false; + } } } return false; @@ -373,14 +381,14 @@ CNode* ConnectNode(CAddress addrConnect, int64 nTimeout) } /// debug print - printf("trying %s\n", addrConnect.ToString().c_str()); + printf("trying connection %s\n", addrConnect.ToStringLog().c_str()); // Connect SOCKET hSocket; if (ConnectSocket(addrConnect, hSocket)) { /// debug print - printf("connected %s\n", addrConnect.ToString().c_str()); + printf("connected %s\n", addrConnect.ToStringLog().c_str()); // Set to nonblocking u_long nOne = 1; @@ -410,7 +418,7 @@ CNode* ConnectNode(CAddress addrConnect, int64 nTimeout) void CNode::Disconnect() { - printf("disconnecting node %s\n", addr.ToString().c_str()); + printf("disconnecting node %s\n", addr.ToStringLog().c_str()); closesocket(hSocket); @@ -450,14 +458,20 @@ void ThreadSocketHandler(void* parg) loop { - vfThreadRunning[0] = true; + vnThreadsRunning[0] = true; CheckForShutdown(0); try { ThreadSocketHandler2(parg); + vnThreadsRunning[0] = false; + } + catch (std::exception& e) { + vnThreadsRunning[0] = false; + PrintException(&e, "ThreadSocketHandler()"); + } catch (...) { + vnThreadsRunning[0] = false; + PrintException(NULL, "ThreadSocketHandler()"); } - CATCH_PRINT_EXCEPTION("ThreadSocketHandler()") - vfThreadRunning[0] = false; Sleep(5000); } } @@ -548,9 +562,9 @@ void ThreadSocketHandler2(void* parg) } } - vfThreadRunning[0] = false; + vnThreadsRunning[0] = false; int nSelect = select(hSocketMax + 1, &fdsetRecv, &fdsetSend, NULL, &timeout); - vfThreadRunning[0] = true; + vnThreadsRunning[0] = true; CheckForShutdown(0); if (nSelect == SOCKET_ERROR) { @@ -590,7 +604,7 @@ void ThreadSocketHandler2(void* parg) } else { - printf("accepted connection from %s\n", addr.ToString().c_str()); + printf("accepted connection %s\n", addr.ToStringLog().c_str()); CNode* pnode = new CNode(hSocket, addr, true); pnode->AddRef(); CRITICAL_BLOCK(cs_vNodes) @@ -697,14 +711,20 @@ void ThreadOpenConnections(void* parg) loop { - vfThreadRunning[1] = true; + vnThreadsRunning[1] = true; CheckForShutdown(1); try { ThreadOpenConnections2(parg); + vnThreadsRunning[1] = false; + } + catch (std::exception& e) { + vnThreadsRunning[1] = false; + PrintException(&e, "ThreadOpenConnections()"); + } catch (...) { + vnThreadsRunning[1] = false; + PrintException(NULL, "ThreadOpenConnections()"); } - CATCH_PRINT_EXCEPTION("ThreadOpenConnections()") - vfThreadRunning[1] = false; Sleep(5000); } } @@ -720,14 +740,14 @@ void ThreadOpenConnections2(void* parg) loop { // Wait - vfThreadRunning[1] = false; + vnThreadsRunning[1] = false; Sleep(500); while (vNodes.size() >= nMaxConnections || vNodes.size() >= mapAddresses.size()) { CheckForShutdown(1); Sleep(2000); } - vfThreadRunning[1] = true; + vnThreadsRunning[1] = true; CheckForShutdown(1); @@ -823,9 +843,9 @@ void ThreadOpenConnections2(void* parg) if (addrConnect.ip == addrLocalHost.ip || !addrConnect.IsIPv4() || FindNode(addrConnect.ip)) continue; - vfThreadRunning[1] = false; + vnThreadsRunning[1] = false; CNode* pnode = ConnectNode(addrConnect); - vfThreadRunning[1] = true; + vnThreadsRunning[1] = true; CheckForShutdown(1); if (!pnode) continue; @@ -867,14 +887,20 @@ void ThreadMessageHandler(void* parg) loop { - vfThreadRunning[2] = true; + vnThreadsRunning[2] = true; CheckForShutdown(2); try { ThreadMessageHandler2(parg); + vnThreadsRunning[2] = false; + } + catch (std::exception& e) { + vnThreadsRunning[2] = false; + PrintException(&e, "ThreadMessageHandler()"); + } catch (...) { + vnThreadsRunning[2] = false; + PrintException(NULL, "ThreadMessageHandler()"); } - CATCH_PRINT_EXCEPTION("ThreadMessageHandler()") - vfThreadRunning[2] = false; Sleep(5000); } } @@ -905,9 +931,9 @@ void ThreadMessageHandler2(void* parg) } // Wait and allow messages to bunch up - vfThreadRunning[2] = false; + vnThreadsRunning[2] = false; Sleep(100); - vfThreadRunning[2] = true; + vnThreadsRunning[2] = true; CheckForShutdown(2); } } @@ -920,29 +946,6 @@ void ThreadMessageHandler2(void* parg) -//// todo: start one thread per processor, use getenv("NUMBER_OF_PROCESSORS") -void ThreadBitcoinMiner(void* parg) -{ - vfThreadRunning[3] = true; - CheckForShutdown(3); - try - { - bool fRet = BitcoinMiner(); - printf("BitcoinMiner returned %s\n\n\n", fRet ? "true" : "false"); - } - CATCH_PRINT_EXCEPTION("BitcoinMiner()") - vfThreadRunning[3] = false; -} - - - - - - - - - - bool StartNode(string& strError) { @@ -1067,17 +1070,17 @@ bool StopNode() fShutdown = true; nTransactionsUpdated++; int64 nStart = GetTime(); - while (vfThreadRunning[0] || vfThreadRunning[2] || vfThreadRunning[3]) + while (vnThreadsRunning[0] || vnThreadsRunning[2] || vnThreadsRunning[3]) { if (GetTime() - nStart > 15) break; Sleep(20); } - if (vfThreadRunning[0]) printf("ThreadSocketHandler still running\n"); - if (vfThreadRunning[1]) printf("ThreadOpenConnections still running\n"); - if (vfThreadRunning[2]) printf("ThreadMessageHandler still running\n"); - if (vfThreadRunning[3]) printf("ThreadBitcoinMiner still running\n"); - while (vfThreadRunning[2]) + if (vnThreadsRunning[0]) printf("ThreadSocketHandler still running\n"); + if (vnThreadsRunning[1]) printf("ThreadOpenConnections still running\n"); + if (vnThreadsRunning[2]) printf("ThreadMessageHandler still running\n"); + if (vnThreadsRunning[3]) printf("ThreadBitcoinMiner still running\n"); + while (vnThreadsRunning[2]) Sleep(20); Sleep(50); @@ -1091,7 +1094,7 @@ void CheckForShutdown(int n) if (fShutdown) { if (n != -1) - vfThreadRunning[n] = false; + vnThreadsRunning[n] = false; if (n == 0) foreach(CNode* pnode, vNodes) closesocket(pnode->hSocket); diff --git a/net.h b/net.h index cd311fc502..334100422f 100644 --- a/net.h +++ b/net.h @@ -20,8 +20,6 @@ enum - - bool ConnectSocket(const CAddress& addrConnect, SOCKET& hSocketRet); bool GetMyExternalIP(unsigned int& ipRet); bool AddAddress(CAddrDB& addrdb, const CAddress& addr); @@ -29,7 +27,6 @@ CNode* FindNode(unsigned int ip); CNode* ConnectNode(CAddress addrConnect, int64 nTimeout=0); void AbandonRequests(void (*fn)(void*, CDataStream&), void* param1); bool AnySubscribed(unsigned int nChannel); -void ThreadBitcoinMiner(void* parg); bool StartNode(string& strError=REF(string())); bool StopNode(); void CheckForShutdown(int n); @@ -206,7 +203,7 @@ public: READWRITE(nTime); } READWRITE(nServices); - READWRITE(FLATDATA(pchReserved)); + READWRITE(FLATDATA(pchReserved)); // for IPv6 READWRITE(ip); READWRITE(port); ) @@ -280,10 +277,14 @@ public: return strprintf("%u.%u.%u.%u", GetByte(3), GetByte(2), GetByte(1), GetByte(0)); } + string ToStringLog() const + { + return ""; + } + string ToString() const { return strprintf("%u.%u.%u.%u:%u", GetByte(3), GetByte(2), GetByte(1), GetByte(0), ntohs(port)); - //return strprintf("%u.%u.%u.%u", GetByte(3), GetByte(2), GetByte(1), GetByte(0)); } void print() const @@ -416,7 +417,7 @@ extern uint64 nLocalServices; extern CAddress addrLocalHost; extern CNode* pnodeLocalHost; extern bool fShutdown; -extern array vfThreadRunning; +extern array vnThreadsRunning; extern vector vNodes; extern CCriticalSection cs_vNodes; extern map, CAddress> mapAddresses; @@ -599,9 +600,7 @@ public: unsigned int nSize = vSend.size() - nPushPos - sizeof(CMessageHeader); memcpy((char*)&vSend[nPushPos] + offsetof(CMessageHeader, nMessageSize), &nSize, sizeof(nSize)); - printf("(%d bytes) ", nSize); - //for (int i = nPushPos+sizeof(CMessageHeader); i < min(vSend.size(), nPushPos+sizeof(CMessageHeader)+20U); i++) - // printf("%02x ", vSend[i] & 0xff); + printf("(%d bytes) ", nSize); printf("\n"); nPushPos = -1; diff --git a/readme.txt b/readme.txt deleted file mode 100644 index 7615e6fd83..0000000000 --- a/readme.txt +++ /dev/null @@ -1,76 +0,0 @@ -BitCoin v0.1.5 ALPHA - -Copyright (c) 2009 Satoshi Nakamoto -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/). This product includes -cryptographic software written by Eric Young (eay@cryptsoft.com). - - -Compilers Supported -------------------- -MinGW GCC (v3.4.5) -Microsoft Visual C++ 6.0 SP6 - - -Dependencies ------------- -Libraries you need to obtain separately to build: - - default path download -wxWidgets \wxWidgets http://www.wxwidgets.org/downloads/ -OpenSSL \OpenSSL http://www.openssl.org/source/ -Berkeley DB \DB http://www.oracle.com/technology/software/products/berkeley-db/index.html -Boost \Boost http://www.boost.org/users/download/ - -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 - - -OpenSSL -------- -Bitcoin does not use any encryption. If you want to do a no-everything -build of OpenSSL to exclude encryption routines, a few patches are required. -(OpenSSL v0.9.8h) - -Edit engines\e_gmp.c and put this #ifndef around #include - #ifndef OPENSSL_NO_RSA - #include - #endif - -Add this to crypto\err\err_all.c before the ERR_load_crypto_strings line: - void ERR_load_RSA_strings(void) { } - -Edit ms\mingw32.bat and replace the Configure line's parameters with this -no-everything list. You have to put this in the batch file because batch -files can't handle more than 9 parameters. - perl Configure mingw threads no-rc2 no-rc4 no-rc5 no-idea no-des no-bf no-cast no-aes no-camellia no-seed no-rsa no-dh - -Also REM out the following line in ms\mingw32.bat. The build fails after it's -already finished building libeay32, which is all we care about, but the -failure aborts the script before it runs dllwrap to generate libeay32.dll. - REM if errorlevel 1 goto end - -Build - ms\mingw32.bat - -If you want to use it with MSVC, generate the .lib file - lib /machine:i386 /def:ms\libeay32.def /out:out\libeay32.lib - - -Berkeley DB ------------ -MinGW with MSYS: -cd \DB\build_unix -sh ../dist/configure --enable-mingw --enable-cxx -make - - -Boost ------ -You may need Boost version 1.35 to build with MSVC 6.0. I couldn't get -version 1.37 to compile with MSVC 6.0. diff --git a/serialize.h b/serialize.h index b7ab86d22a..9b20e2a0f6 100644 --- a/serialize.h +++ b/serialize.h @@ -19,7 +19,7 @@ class CScript; class CDataStream; class CAutoFile; -static const int VERSION = 105; +static const int VERSION = 106; diff --git a/ui.cpp b/ui.cpp index a1e582ab9f..ce43a786c8 100644 --- a/ui.cpp +++ b/ui.cpp @@ -7,6 +7,13 @@ #include #endif +void ThreadRequestProductDetails(void* parg); +void ThreadRandSendTest(void* parg); +bool GetStartOnSystemStartup(); +void SetStartOnSystemStartup(bool fAutoStart); + + + DEFINE_EVENT_TYPE(wxEVT_CROSSTHREADCALL) DEFINE_EVENT_TYPE(wxEVT_REPLY1) DEFINE_EVENT_TYPE(wxEVT_REPLY2) @@ -16,22 +23,21 @@ DEFINE_EVENT_TYPE(wxEVT_TABLEUPDATED) DEFINE_EVENT_TYPE(wxEVT_TABLEDELETED) CMainFrame* pframeMain = NULL; +CMyTaskBarIcon* ptaskbaricon = NULL; map mapAddressBook; -CBitcoinTBIcon* taskBarIcon = NULL; // Tray icon - - -void ThreadRequestProductDetails(void* parg); -void ThreadRandSendTest(void* parg); +map mapArgs; bool fRandSendTest = false; void RandSend(); extern int g_isPainting; -// UI settings and their default values -int minimizeToTray = 1; -int closeToTray = 1; -int startOnSysBoot = 1; -int askBeforeClosing = 1; -int alwaysShowTrayIcon = 1; +// Settings +int fShowGenerated = true; +int fMinimizeToTray = true; +int fMinimizeOnClose = true; + + + + @@ -282,7 +288,7 @@ CMainFrame::CMainFrame(wxWindow* parent) : CMainFrameBase(parent) m_staticTextBalance->SetLabel(FormatMoney(GetBalance()) + " "); m_listCtrl->SetFocus(); SetIcon(wxICON(bitcoin)); - m_menuOptions->Check(wxID_OPTIONSGENERATEBITCOINS, fGenerateBitcoins); + ptaskbaricon = new CMyTaskBarIcon(); // Init toolbar with transparency masked bitmaps m_toolBar->ClearTools(); @@ -327,7 +333,7 @@ CMainFrame::CMainFrame(wxWindow* parent) : CMainFrameBase(parent) //m_listCtrlOrdersReceived->InsertColumn(4, "", wxLIST_FORMAT_LEFT, 100); // Init status bar - int pnWidths[3] = { -100, 81, 286 }; + int pnWidths[3] = { -100, 88, 290 }; m_statusBar->SetFieldsCount(3, pnWidths); // Fill your address text box @@ -342,6 +348,8 @@ CMainFrame::CMainFrame(wxWindow* parent) : CMainFrameBase(parent) CMainFrame::~CMainFrame() { pframeMain = NULL; + delete ptaskbaricon; + ptaskbaricon = NULL; } void Shutdown(void* parg) @@ -362,28 +370,24 @@ void Shutdown(void* parg) void CMainFrame::OnClose(wxCloseEvent& event) { - if (closeToTray && event.CanVeto()) { - event.Veto(); - SendToTray(); - } - else if (!event.CanVeto() || !askBeforeClosing || wxMessageBox("Quit program?", "Confirm", wxYES_NO, this) == wxYES) { - delete taskBarIcon; - Destroy(); - _beginthread(Shutdown, 0, NULL); - } + if (fMinimizeToTray && fMinimizeOnClose && event.CanVeto() && !IsIconized()) + { + // Divert close to minimize + event.Veto(); + Iconize(true); + } + else + { + Destroy(); + _beginthread(Shutdown, 0, NULL); + } } void CMainFrame::OnIconize(wxIconizeEvent& event) { - if (minimizeToTray) { - SendToTray(); - } -} - -void CMainFrame::SendToTray() -{ - Hide(); - taskBarIcon->Show(); + // Hide the task bar button when minimized. + // Event is sent when the frame is minimized or restored. + Show(!fMinimizeToTray || !event.Iconized()); } void CMainFrame::OnMouseEvents(wxMouseEvent& event) @@ -405,25 +409,21 @@ void CMainFrame::InsertLine(bool fNew, int nIndex, uint256 hashKey, string strSo string str0 = strSort; long nData = *(long*)&hashKey; - if (fNew) + // Find item + if (!fNew && nIndex == -1) + { + while ((nIndex = m_listCtrl->FindItem(nIndex, nData)) != -1) + if (GetItemText(m_listCtrl, nIndex, 1) == hashKey.ToString()) + break; + } + + // fNew is for blind insert, only use if you're sure it's new + if (fNew || nIndex == -1) { nIndex = m_listCtrl->InsertItem(0, str0); } else { - if (nIndex == -1) - { - // Find item - while ((nIndex = m_listCtrl->FindItem(nIndex, nData)) != -1) - if (GetItemText(m_listCtrl, nIndex, 1) == hashKey.ToString()) - break; - if (nIndex == -1) - { - printf("CMainFrame::InsertLine : Couldn't find item to be updated\n"); - return; - } - } - // If sort key changed, must delete and reinsert to make it relocate if (GetItemText(m_listCtrl, nIndex, 0) != str0) { @@ -484,6 +484,28 @@ void CMainFrame::InsertTransaction(const CWalletTx& wtx, bool fNew, int nIndex) string strStatus = FormatTxStatus(wtx); map mapValue = wtx.mapValue; + // Filter + if (wtx.IsCoinBase()) + { + // View->Show Generated + if (!fShowGenerated) + return; + + // 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; + } + // Find the block the tx is in CBlockIndex* pindex = NULL; map::iterator mi = mapBlockIndex.find(wtx.hashBlock); @@ -785,16 +807,11 @@ void CMainFrame::OnPaintListCtrl(wxPaintEvent& event) { TRY_CRITICAL_BLOCK(cs_mapWallet) { - pair item; - foreach(item, vWalletUpdated) + foreach(uint256 hash, vWalletUpdated) { - bool fNew = item.second; - map::iterator mi = mapWallet.find(item.first); + map::iterator mi = mapWallet.find(hash); if (mi != mapWallet.end()) - { - printf("vWalletUpdated: %s %s\n", (*mi).second.GetHash().ToString().substr(0,6).c_str(), fNew ? "new" : ""); - InsertTransaction((*mi).second, fNew); - } + InsertTransaction((*mi).second, false); } m_listCtrl->ScrollList(0, INT_MAX); vWalletUpdated.clear(); @@ -807,7 +824,7 @@ void CMainFrame::OnPaintListCtrl(wxPaintEvent& event) // Update status bar string strGen = ""; if (fGenerateBitcoins) - strGen = " Generating"; + strGen = " Generating"; if (fGenerateBitcoins && vNodes.empty()) strGen = "(not connected)"; m_statusBar->SetStatusText(strGen, 1); @@ -856,39 +873,54 @@ void CMainFrame::OnCrossThreadCall(wxCommandEvent& event) void CMainFrame::OnMenuFileExit(wxCommandEvent& event) { + // File->Exit Close(true); } +void CMainFrame::OnMenuViewShowGenerated(wxCommandEvent& event) +{ + // View->Show Generated + fShowGenerated = event.IsChecked(); + CWalletDB().WriteSetting("fShowGenerated", fShowGenerated); + RefreshListCtrl(); +} + +void CMainFrame::OnUpdateUIViewShowGenerated(wxUpdateUIEvent& event) +{ + event.Check(fShowGenerated); +} + void CMainFrame::OnMenuOptionsGenerate(wxCommandEvent& event) { + // Options->Generate Coins GenerateBitcoins(event.IsChecked()); +} - Refresh(); - wxPaintEvent eventPaint; - AddPendingEvent(eventPaint); +void CMainFrame::OnUpdateUIOptionsGenerate(wxUpdateUIEvent& event) +{ + event.Check(fGenerateBitcoins); } void CMainFrame::OnMenuOptionsChangeYourAddress(wxCommandEvent& event) { + // Options->Change Your Address OnButtonChange(event); } 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::OnUpdateMenuGenerate( wxUpdateUIEvent& event ) { - event.Check(fGenerateBitcoins); -} - void CMainFrame::OnButtonSend(wxCommandEvent& event) { /// debug test @@ -1252,58 +1284,74 @@ void CTxDetailsDialog::OnButtonOK(wxCommandEvent& event) 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); + + // Init values + m_textCtrlTransactionFee->SetValue(FormatMoney(nTransactionFee)); + m_checkBoxLimitProcessors->SetValue(fLimitProcessors); + m_spinCtrlLimitProcessors->Enable(fLimitProcessors); + m_spinCtrlLimitProcessors->SetValue(nLimitProcessors); + int nProcessors = atoi(getenv("NUMBER_OF_PROCESSORS")); + if (nProcessors < 1) + nProcessors = 999; + m_spinCtrlLimitProcessors->SetRange(1, nProcessors); + m_checkBoxStartOnSystemStartup->SetValue(fTmpStartOnSystemStartup = GetStartOnSystemStartup()); + m_checkBoxMinimizeToTray->SetValue(fMinimizeToTray); + m_checkBoxMinimizeOnClose->Enable(fMinimizeToTray); + m_checkBoxMinimizeOnClose->SetValue(fMinimizeToTray && fMinimizeOnClose); + fTmpMinimizeOnClose = fMinimizeOnClose; m_buttonOK->SetFocus(); - m_treeCtrl->AddRoot(wxT("Settings")); - m_treeCtrl->AppendItem(m_treeCtrl->GetRootItem(), wxT("Bitcoin")); - m_treeCtrl->AppendItem(m_treeCtrl->GetRootItem(), wxT("UI")); +} - panelUI = new COptionsPanelUI(this); - panelBitcoin = new COptionsPanelBitcoin(this); - currentPanel = panelBitcoin; +void COptionsDialog::SelectPage(int nPage) +{ + m_panelMain->Show(nPage == 0); + m_panelTest2->Show(nPage == 1); - panelSizer->Add(panelUI); - panelSizer->Hide(panelUI); - panelSizer->Add(panelBitcoin); - panelSizer->Layout(); + m_scrolledWindow->Layout(); + m_scrolledWindow->SetScrollbars(0, 0, 0, 0, 0, 0); +} +void COptionsDialog::OnListBox(wxCommandEvent& event) +{ + SelectPage(event.GetSelection()); } -void COptionsDialog::MenuSelChanged( wxTreeEvent& event ) +void COptionsDialog::OnKillFocusTransactionFee(wxFocusEvent& event) { - panelSizer->Hide(currentPanel); - wxString text = m_treeCtrl->GetItemText(event.GetItem()); - if (text == "Bitcoin") { - panelSizer->Show(panelBitcoin); - currentPanel = panelBitcoin; - } - else { - panelSizer->Show(panelUI); - currentPanel = panelUI; - } - panelSizer->Layout(); + int64 nTmp = nTransactionFee; + ParseMoney(m_textCtrlTransactionFee->GetValue(), nTmp); + m_textCtrlTransactionFee->SetValue(FormatMoney(nTmp)); } -void COptionsDialog::OnButtonOK(wxCommandEvent& event) +void COptionsDialog::OnCheckBoxLimitProcessors(wxCommandEvent& event) { - // nTransactionFee - int64 nPrevTransactionFee = nTransactionFee; - if (ParseMoney(panelBitcoin->m_textCtrlTransactionFee->GetValue(), nTransactionFee) && nTransactionFee != nPrevTransactionFee) - CWalletDB().WriteSetting("transactionFee", nTransactionFee); + m_spinCtrlLimitProcessors->Enable(event.IsChecked()); +} - minimizeToTray = panelUI->m_checkMinToTray->IsChecked(); - closeToTray = panelUI->m_checkCloseToTray->IsChecked(); - startOnSysBoot = panelUI->m_checkStartOnSysBoot->IsChecked(); - askBeforeClosing = panelUI->m_checkAskBeforeClosing->IsChecked(); - alwaysShowTrayIcon = panelUI->m_checkAlwaysShowTray->IsChecked(); +void COptionsDialog::OnCheckBoxMinimizeToTray(wxCommandEvent& event) +{ + m_checkBoxMinimizeOnClose->Enable(event.IsChecked()); - CWalletDB().WriteSetting("minimizeToTray", minimizeToTray); - CWalletDB().WriteSetting("closeToTray", closeToTray); - CWalletDB().WriteSetting("startOnSysBoot", startOnSysBoot); - CWalletDB().WriteSetting("askBeforeClosing", askBeforeClosing); - CWalletDB().WriteSetting("alwaysShowTrayIcon", alwaysShowTrayIcon); + // Save the value in fTmpMinimizeOnClose so we can + // show the checkbox unchecked when its parent is unchecked + if (event.IsChecked()) + m_checkBoxMinimizeOnClose->SetValue(fTmpMinimizeOnClose); + else + { + fTmpMinimizeOnClose = m_checkBoxMinimizeOnClose->GetValue(); + m_checkBoxMinimizeOnClose->SetValue(false); + } - ApplyUISettings(); +} +void COptionsDialog::OnButtonOK(wxCommandEvent& event) +{ + OnButtonApply(event); Close(); } @@ -1312,44 +1360,53 @@ void COptionsDialog::OnButtonCancel(wxCommandEvent& event) Close(); } - - -////////////////////////////////////////////////////////////////////////////// -// -// COptionsPanelBitcoin -// - -COptionsPanelBitcoin::COptionsPanelBitcoin(wxWindow* parent) : COptionsPanelBitcoinBase(parent) +void COptionsDialog::OnButtonApply(wxCommandEvent& event) { - m_textCtrlTransactionFee->SetValue(FormatMoney(nTransactionFee)); -} + CWalletDB walletdb; -void COptionsPanelBitcoin::OnKillFocusTransactionFee(wxFocusEvent& event) -{ - int64 nTmp = nTransactionFee; - ParseMoney(m_textCtrlTransactionFee->GetValue(), nTmp); - m_textCtrlTransactionFee->SetValue(FormatMoney(nTmp)); -} + int64 nPrevTransactionFee = nTransactionFee; + if (ParseMoney(m_textCtrlTransactionFee->GetValue(), nTransactionFee) && nTransactionFee != nPrevTransactionFee) + walletdb.WriteSetting("nTransactionFee", nTransactionFee); + int nPrevMaxProc = (fLimitProcessors ? nLimitProcessors : INT_MAX); + if (fLimitProcessors != m_checkBoxLimitProcessors->GetValue()) + { + fLimitProcessors = m_checkBoxLimitProcessors->GetValue(); + walletdb.WriteSetting("fLimitProcessors", fLimitProcessors); + } + if (nLimitProcessors != m_spinCtrlLimitProcessors->GetValue()) + { + nLimitProcessors = m_spinCtrlLimitProcessors->GetValue(); + walletdb.WriteSetting("nLimitProcessors", nLimitProcessors); + } + if (fGenerateBitcoins && (fLimitProcessors ? nLimitProcessors : INT_MAX) > nPrevMaxProc) + GenerateBitcoins(fGenerateBitcoins); -////////////////////////////////////////////////////////////////////////////// -// -// COptionsPanelUI -// + if (fTmpStartOnSystemStartup != m_checkBoxStartOnSystemStartup->GetValue()) + { + fTmpStartOnSystemStartup = m_checkBoxStartOnSystemStartup->GetValue(); + SetStartOnSystemStartup(fTmpStartOnSystemStartup); + } -COptionsPanelUI::COptionsPanelUI(wxWindow* parent) : COptionsPanelUIBase(parent) -{ - m_checkMinToTray->SetValue(minimizeToTray); - m_checkCloseToTray->SetValue(closeToTray); - m_checkStartOnSysBoot->SetValue(startOnSysBoot); - m_checkAskBeforeClosing->SetValue(askBeforeClosing); - m_checkAlwaysShowTray->SetValue(alwaysShowTrayIcon); + if (fMinimizeToTray != m_checkBoxMinimizeToTray->GetValue()) + { + fMinimizeToTray = m_checkBoxMinimizeToTray->GetValue(); + walletdb.WriteSetting("fMinimizeToTray", fMinimizeToTray); + ptaskbaricon->Show(fMinimizeToTray); + } + + if (fMinimizeOnClose != (fMinimizeToTray ? m_checkBoxMinimizeOnClose->GetValue() : fTmpMinimizeOnClose)) + { + fMinimizeOnClose = (fMinimizeToTray ? m_checkBoxMinimizeOnClose->GetValue() : fTmpMinimizeOnClose); + walletdb.WriteSetting("fMinimizeOnClose", fMinimizeOnClose); + } } + ////////////////////////////////////////////////////////////////////////////// // // CAboutDialog @@ -1387,6 +1444,7 @@ CSendDialog::CSendDialog(wxWindow* parent, const wxString& strAddress) : CSendDi m_textCtrlAddress->SetValue(strAddress); m_choiceTransferType->SetSelection(0); m_bitmapCheckMark->Show(false); + fEnabledPrev = true; //// todo: should add a display of your balance for convenience // Set Icon @@ -1418,6 +1476,19 @@ void CSendDialog::OnTextAddress(wxCommandEvent& event) m_staticTextMessage->Enable(fEnable); m_textCtrlMessage->Enable(fEnable); m_textCtrlMessage->SetBackgroundColour(wxSystemSettings::GetColour(fEnable ? wxSYS_COLOUR_WINDOW : wxSYS_COLOUR_BTNFACE)); + if (!fEnable && fEnabledPrev) + { + strFromSave = m_textCtrlFrom->GetValue(); + strMessageSave = m_textCtrlMessage->GetValue(); + m_textCtrlFrom->SetValue("Will appear as \"From: Unknown\""); + m_textCtrlMessage->SetValue("Can't include a message when sending to a Bitcoin address"); + } + else if (fEnable && !fEnabledPrev) + { + m_textCtrlFrom->SetValue(strFromSave); + m_textCtrlMessage->SetValue(strMessageSave); + } + fEnabledPrev = fEnable; } void CSendDialog::OnKillFocusAmount(wxFocusEvent& event) @@ -1773,8 +1844,9 @@ void CSendingDialog::OnReply2(CDataStream& vRecv) Error("You don't have enough money"); return; } + CKey key; int64 nFeeRequired; - if (!CreateTransaction(scriptPubKey, nPrice, wtx, nFeeRequired)) + if (!CreateTransaction(scriptPubKey, nPrice, wtx, key, nFeeRequired)) { if (nPrice + nFeeRequired > GetBalance()) Error(strprintf("This is an oversized transaction that requires a transaction fee of %s", FormatMoney(nFeeRequired).c_str())); @@ -1799,7 +1871,7 @@ void CSendingDialog::OnReply2(CDataStream& vRecv) return; // Commit - if (!CommitTransactionSpent(wtx)) + if (!CommitTransactionSpent(wtx, key)) { Error("Error finalizing payment"); return; @@ -2950,84 +3022,112 @@ void CEditReviewDialog::GetReview(CReview& review) + + ////////////////////////////////////////////////////////////////////////////// // -// BitcoinTBIcon +// CMyTaskBarIcon // -enum { - PU_RESTORE = 10001, - PU_GENERATE, - PU_EXIT, +enum +{ + ID_TASKBAR_RESTORE = 10001, + ID_TASKBAR_GENERATE, + ID_TASKBAR_EXIT, }; -BEGIN_EVENT_TABLE(CBitcoinTBIcon, wxTaskBarIcon) - EVT_TASKBAR_LEFT_DCLICK (CBitcoinTBIcon::OnLeftButtonDClick) - EVT_MENU(PU_RESTORE, CBitcoinTBIcon::OnMenuRestore) - EVT_MENU(PU_GENERATE, CBitcoinTBIcon::OnMenuGenerate) - EVT_MENU(PU_EXIT, CBitcoinTBIcon::OnMenuExit) +BEGIN_EVENT_TABLE(CMyTaskBarIcon, wxTaskBarIcon) + EVT_TASKBAR_LEFT_DCLICK(CMyTaskBarIcon::OnLeftButtonDClick) + EVT_MENU(ID_TASKBAR_RESTORE, CMyTaskBarIcon::OnMenuRestore) + EVT_MENU(ID_TASKBAR_GENERATE, CMyTaskBarIcon::OnMenuGenerate) + EVT_UPDATE_UI(ID_TASKBAR_GENERATE, CMyTaskBarIcon::OnUpdateUIGenerate) + EVT_MENU(ID_TASKBAR_EXIT, CMyTaskBarIcon::OnMenuExit) END_EVENT_TABLE() -void CBitcoinTBIcon::Show() +void CMyTaskBarIcon::Show(bool fShow) { - string tooltip = "Bitcoin"; - tooltip += fGenerateBitcoins ? " - Generating" : ""; - SetIcon(wxICON(bitcoin), tooltip); + if (fShow) + { + string strTooltip = "Bitcoin"; + if (fGenerateBitcoins) + strTooltip = "Bitcoin - Generating"; + if (fGenerateBitcoins && vNodes.empty()) + strTooltip = "Bitcoin - (not connected)"; + SetIcon(wxICON(bitcoin), strTooltip); + } + else + { + RemoveIcon(); + } } -void CBitcoinTBIcon::Hide() +void CMyTaskBarIcon::Hide() { - RemoveIcon(); + Show(false); } -void CBitcoinTBIcon::OnLeftButtonDClick(wxTaskBarIconEvent&) +void CMyTaskBarIcon::OnLeftButtonDClick(wxTaskBarIconEvent& event) { - Restore(); + Restore(); } -void CBitcoinTBIcon::OnMenuExit(wxCommandEvent&) +void CMyTaskBarIcon::OnMenuRestore(wxCommandEvent& event) { - pframeMain->Close(true); + Restore(); } -void CBitcoinTBIcon::OnMenuGenerate(wxCommandEvent& event) +void CMyTaskBarIcon::Restore() { - GenerateBitcoins(event.IsChecked()); - pframeMain->Refresh(); -} - -void CBitcoinTBIcon::OnMenuRestore(wxCommandEvent&) { - Restore(); -} - -void CBitcoinTBIcon::Restore() { pframeMain->Show(); pframeMain->Iconize(false); pframeMain->Raise(); - if (!alwaysShowTrayIcon) - Hide(); } -void CBitcoinTBIcon::UpdateTooltip() { - if (IsIconInstalled()) - Show(); +void CMyTaskBarIcon::OnMenuGenerate(wxCommandEvent& event) +{ + GenerateBitcoins(event.IsChecked()); +} + +void CMyTaskBarIcon::OnUpdateUIGenerate(wxUpdateUIEvent& event) +{ + event.Check(fGenerateBitcoins); } -wxMenu *CBitcoinTBIcon::CreatePopupMenu() +void CMyTaskBarIcon::OnMenuExit(wxCommandEvent& event) { - wxMenu *menu = new wxMenu; - menu->Append(PU_RESTORE, _T("Open Bitcoin")); - wxMenuItem* generateCheck = menu->AppendCheckItem(PU_GENERATE, _T("Generate Coins")); - menu->InsertSeparator(2); - menu->Append(PU_EXIT, _T("Exit")); + pframeMain->Close(true); +} - generateCheck->Check(fGenerateBitcoins); +void CMyTaskBarIcon::UpdateTooltip() +{ + if (IsIconInstalled()) + Show(true); +} - return menu; +wxMenu* CMyTaskBarIcon::CreatePopupMenu() +{ + wxMenu* pmenu = new wxMenu; + pmenu->Append(ID_TASKBAR_RESTORE, "&Open Bitcoin"); + pmenu->AppendCheckItem(ID_TASKBAR_GENERATE, "&Generate Coins")->Check(fGenerateBitcoins); +#ifndef __WXMAC_OSX__ // Mac has built-in quit menu + pmenu->AppendSeparator(); + pmenu->Append(ID_TASKBAR_EXIT, "E&xit"); +#endif + return pmenu; } + + + + + + + + + + ////////////////////////////////////////////////////////////////////////////// // // CMyApp @@ -3150,7 +3250,7 @@ bool CMyApp::OnInit2() // Parameters // wxImage::AddHandler(new wxPNGHandler); - map mapArgs = ParseParameters(argc, argv); + mapArgs = ParseParameters(argc, argv); if (mapArgs.count("/datadir")) strSetDataDir = mapArgs["/datadir"]; @@ -3179,6 +3279,7 @@ bool CMyApp::OnInit2() // // Load data files // + bool fFirstRun; string strErrors; int64 nStart, nEnd; @@ -3198,7 +3299,7 @@ bool CMyApp::OnInit2() printf("Loading wallet...\n"); QueryPerformanceCounter((LARGE_INTEGER*)&nStart); - if (!LoadWallet()) + if (!LoadWallet(fFirstRun)) strErrors += "Error loading wallet.dat \n"; QueryPerformanceCounter((LARGE_INTEGER*)&nEnd); printf(" wallet %20I64d\n", nEnd - nStart); @@ -3244,62 +3345,60 @@ bool CMyApp::OnInit2() // // Create the main frame window // + pframeMain = new CMainFrame(NULL); + if (mapArgs.count("/min")) + pframeMain->Iconize(true); + pframeMain->Show(true); // have to show first to get taskbar button to hide + pframeMain->Show(!fMinimizeToTray || !pframeMain->IsIconized()); + ptaskbaricon->Show(fMinimizeToTray); + + if (!CheckDiskSpace()) { - pframeMain = new CMainFrame(NULL); - pframeMain->Show(); + OnExit(); + return false; + } - if (!CheckDiskSpace()) - { - OnExit(); - return false; - } + if (!StartNode(strErrors)) + wxMessageBox(strErrors, "Bitcoin"); - if (!StartNode(strErrors)) - wxMessageBox(strErrors, "Bitcoin"); + GenerateBitcoins(fGenerateBitcoins); - if (fGenerateBitcoins) - if (_beginthread(ThreadBitcoinMiner, 0, NULL) == -1) - printf("Error: _beginthread(ThreadBitcoinMiner) failed\n"); + if (fFirstRun) + SetStartOnSystemStartup(true); - // - // Tests - // - if (argc >= 2 && stricmp(argv[1], "/send") == 0) - { - int64 nValue = 1; - if (argc >= 3) - ParseMoney(argv[2], nValue); - - string strAddress; - if (argc >= 4) - strAddress = argv[3]; - CAddress addr(strAddress.c_str()); - - CWalletTx wtx; - wtx.mapValue["to"] = strAddress; - wtx.mapValue["from"] = addrLocalHost.ToString(); - wtx.mapValue["message"] = "command line send"; - - // Send to IP address - CSendingDialog* pdialog = new CSendingDialog(pframeMain, addr, nValue, wtx); - if (!pdialog->ShowModal()) - return false; - } - if (mapArgs.count("/randsendtest")) - { - if (!mapArgs["/randsendtest"].empty()) - _beginthread(ThreadRandSendTest, 0, new string(mapArgs["/randsendtest"])); - else - fRandSendTest = true; - fDebug = true; - } + // + // Tests + // + if (argc >= 2 && stricmp(argv[1], "/send") == 0) + { + int64 nValue = 1; + if (argc >= 3) + ParseMoney(argv[2], nValue); + + string strAddress; + if (argc >= 4) + strAddress = argv[3]; + CAddress addr(strAddress.c_str()); + + CWalletTx wtx; + wtx.mapValue["to"] = strAddress; + wtx.mapValue["from"] = addrLocalHost.ToString(); + wtx.mapValue["message"] = "command line send"; + + // Send to IP address + CSendingDialog* pdialog = new CSendingDialog(pframeMain, addr, nValue, wtx); + if (!pdialog->ShowModal()) + return false; } - taskBarIcon = new CBitcoinTBIcon(); - ApplyUISettings(); - if (mapArgs.count("/min") && minimizeToTray) { - pframeMain->Iconize(true); + if (mapArgs.count("/randsendtest")) + { + if (!mapArgs["/randsendtest"].empty()) + _beginthread(ThreadRandSendTest, 0, new string(mapArgs["/randsendtest"])); + else + fRandSendTest = true; + fDebug = true; } return true; @@ -3320,14 +3419,14 @@ bool CMyApp::OnExceptionInMainLoop() catch (std::exception& e) { PrintException(&e, "CMyApp::OnExceptionInMainLoop()"); - wxLogWarning(_T("Exception %s %s"), typeid(e).name(), e.what()); + wxLogWarning("Exception %s %s", typeid(e).name(), e.what()); Sleep(1000); throw; } catch (...) { PrintException(NULL, "CMyApp::OnExceptionInMainLoop()"); - wxLogWarning(_T("Unknown exception")); + wxLogWarning("Unknown exception"); Sleep(1000); throw; } @@ -3345,14 +3444,14 @@ void CMyApp::OnUnhandledException() catch (std::exception& e) { PrintException(&e, "CMyApp::OnUnhandledException()"); - wxLogWarning(_T("Exception %s %s"), typeid(e).name(), e.what()); + wxLogWarning("Exception %s %s", typeid(e).name(), e.what()); Sleep(1000); throw; } catch (...) { PrintException(NULL, "CMyApp::OnUnhandledException()"); - wxLogWarning(_T("Unknown exception")); + wxLogWarning("Unknown exception"); Sleep(1000); throw; } @@ -3367,6 +3466,8 @@ void CMyApp::OnFatalException() void MainFrameRepaint() { + // This is called by network code that shouldn't access pframeMain and ptaskbaricon + // directly because it could still be running after the UI is closed. if (pframeMain) { printf("MainFrameRepaint()\n"); @@ -3374,68 +3475,84 @@ void MainFrameRepaint() pframeMain->Refresh(); pframeMain->AddPendingEvent(event); } + if (ptaskbaricon) + ptaskbaricon->UpdateTooltip(); } +string StartupShortcutPath() +{ + // Get the startup folder shortcut path + char pszLinkPath[MAX_PATH+100]; + pszLinkPath[0] = '\0'; + SHGetSpecialFolderPath(0, pszLinkPath, CSIDL_STARTUP, 0); + strcat(pszLinkPath, "\\Bitcoin.lnk"); + return pszLinkPath; +} + +bool GetStartOnSystemStartup() +{ + return FileExists(StartupShortcutPath().c_str()); +} -void ApplyUISettings() { - // Show the tray icon? - if (alwaysShowTrayIcon) - taskBarIcon->Show(); - else - taskBarIcon->Hide(); +void SetStartOnSystemStartup(bool fAutoStart) +{ + // If the shortcut exists already, remove it for updating + remove(StartupShortcutPath().c_str()); - // Autostart on system startup? - // Open the startup registry key - HKEY hKey; - LONG lnRes = RegOpenKeyEx( - HKEY_CURRENT_USER, - "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run", - 0, - KEY_ALL_ACCESS, - &hKey - ); + if (fAutoStart) + { + CoInitialize(NULL); - if ( ERROR_SUCCESS == lnRes ) - { - if (startOnSysBoot) { - // Get the current executable path - char exePath[ MAX_PATH ]; - GetModuleFileName(NULL, exePath, _MAX_PATH + 1); - char runCmd[ MAX_PATH + 5 ]; - strcat(runCmd, exePath); - strcat(runCmd," /min"); + // Get a pointer to the IShellLink interface. + HRESULT hres = NULL; + IShellLink* psl = NULL; + hres = CoCreateInstance(CLSID_ShellLink, NULL, + CLSCTX_INPROC_SERVER, IID_IShellLink, + reinterpret_cast(&psl)); - RegSetValueEx(hKey, - "Bitcoin", - 0, - REG_SZ, - (BYTE*)runCmd, - sizeof(runCmd) - ); - } - else { - RegDeleteValue(hKey, "Bitcoin"); - } - } - RegCloseKey(hKey); + if (SUCCEEDED(hres)) + { + // Get the current executable path + char pszExePath[MAX_PATH]; + GetModuleFileName(NULL, pszExePath, sizeof(pszExePath)); + _strlwr(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(&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(); + } } -void GenerateBitcoins(bool flag) -{ - fGenerateBitcoins = flag; - nTransactionsUpdated++; - CWalletDB().WriteSetting("fGenerateBitcoins", fGenerateBitcoins); - if (fGenerateBitcoins) - if (_beginthread(ThreadBitcoinMiner, 0, NULL) == -1) - printf("Error: _beginthread(ThreadBitcoinMiner) failed\n"); - taskBarIcon->UpdateTooltip(); -} + + + + diff --git a/ui.h b/ui.h index 11c88147ac..f89456bf3f 100644 --- a/ui.h +++ b/ui.h @@ -21,21 +21,25 @@ enum + +extern map mapArgs; + +// Settings +extern int fShowGenerated; +extern int fMinimizeToTray; +extern int fMinimizeOnClose; + + + extern void HandleCtrlA(wxKeyEvent& event); extern string DateTimeStr(int64 nTime); extern string FormatTxStatus(const CWalletTx& wtx); extern void CrossThreadCall(int nID, void* pdata); extern void MainFrameRepaint(); extern void Shutdown(void* parg); -void ApplyUISettings(); -void GenerateBitcoins(bool flag); -// UI settings -extern int minimizeToTray; -extern int closeToTray; -extern int startOnSysBoot; -extern int askBeforeClosing; -extern int alwaysShowTrayIcon; + + @@ -44,14 +48,17 @@ class CMainFrame : public CMainFrameBase protected: // Event handlers void OnClose(wxCloseEvent& event); - void OnIconize( wxIconizeEvent& 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 OnMenuViewShowGenerated(wxCommandEvent& event); + void OnUpdateUIViewShowGenerated(wxUpdateUIEvent& event); void OnMenuOptionsGenerate(wxCommandEvent& event); + void OnUpdateUIOptionsGenerate(wxUpdateUIEvent& event); void OnMenuOptionsChangeYourAddress(wxCommandEvent& event); void OnMenuOptionsOptions(wxCommandEvent& event); void OnMenuHelpAbout(wxCommandEvent& event); @@ -66,7 +73,6 @@ protected: void OnListItemActivatedProductsSent(wxListEvent& event); void OnListItemActivatedOrdersSent(wxListEvent& event); void OnListItemActivatedOrdersReceived(wxListEvent& event); - void OnUpdateMenuGenerate( wxUpdateUIEvent& event ); public: /** Constructor */ @@ -85,7 +91,6 @@ public: void InsertTransaction(const CWalletTx& wtx, bool fNew, int nIndex=-1); void RefreshListCtrl(); void RefreshStatus(); - void SendToTray(); }; @@ -107,47 +112,26 @@ public: -class COptionsPanelBitcoin : public COptionsPanelBitcoinBase -{ -protected: - // Event handlers - void OnKillFocusTransactionFee( wxFocusEvent& event ); - -public: - /** Constructor */ - COptionsPanelBitcoin(wxWindow* parent); -}; - - - -class COptionsPanelUI : public COptionsPanelUIBase -{ -protected: - // Event handlers - void OnOptionsChanged( wxCommandEvent& event ); - -public: - /** Constructor */ - COptionsPanelUI(wxWindow* parent); -}; - - - class COptionsDialog : public COptionsDialogBase { protected: // Event handlers - void MenuSelChanged( wxTreeEvent& event ); + void OnListBox(wxCommandEvent& event); + void OnKillFocusTransactionFee(wxFocusEvent& event); + void OnCheckBoxLimitProcessors(wxCommandEvent& event); + void OnCheckBoxMinimizeToTray(wxCommandEvent& event); void OnButtonOK(wxCommandEvent& event); void OnButtonCancel(wxCommandEvent& event); + void OnButtonApply(wxCommandEvent& event); - // Panels - COptionsPanelBitcoin* panelBitcoin; - COptionsPanelUI* panelUI; - wxPanel* currentPanel; public: /** Constructor */ COptionsDialog(wxWindow* parent); + + // Custom + bool fTmpStartOnSystemStartup; + bool fTmpMinimizeOnClose; + void SelectPage(int nPage); }; @@ -180,6 +164,11 @@ protected: public: /** Constructor */ CSendDialog(wxWindow* parent, const wxString& strAddress=""); + + // Custom + bool fEnabledPrev; + string strFromSave; + string strMessageSave; }; @@ -455,22 +444,33 @@ public: -class CBitcoinTBIcon : public wxTaskBarIcon +class CMyTaskBarIcon : public wxTaskBarIcon { protected: - void Restore(); - - // Event handlers - void OnLeftButtonDClick(wxTaskBarIconEvent&); - void OnMenuExit(wxCommandEvent&); - void OnMenuGenerate(wxCommandEvent&); - void OnMenuRestore(wxCommandEvent&); + // Event handlers + void OnLeftButtonDClick(wxTaskBarIconEvent& event); + void OnMenuRestore(wxCommandEvent& event); + void OnUpdateUIGenerate(wxUpdateUIEvent& event); + void OnMenuGenerate(wxCommandEvent& event); + void OnMenuExit(wxCommandEvent& event); public: - void Show(); - void Hide(); - void UpdateTooltip(); - virtual wxMenu *CreatePopupMenu(); + CMyTaskBarIcon() : wxTaskBarIcon() + { + Show(true); + } + + void Show(bool fShow=true); + void Hide(); + void Restore(); + void UpdateTooltip(); + virtual wxMenu* CreatePopupMenu(); DECLARE_EVENT_TABLE() }; + + + + + + diff --git a/uibase.cpp b/uibase.cpp index a88c67ebf4..0f9e22c528 100644 --- a/uibase.cpp +++ b/uibase.cpp @@ -24,14 +24,21 @@ CMainFrameBase::CMainFrameBase( wxWindow* parent, wxWindowID id, const wxString& m_menubar->Append( m_menuFile, wxT("&File") ); + m_menuView = new wxMenu(); + wxMenuItem* m_menuViewShowGenerated; + m_menuViewShowGenerated = new wxMenuItem( m_menuView, wxID_VIEWSHOWGENERATED, wxString( wxT("&Show Generated Coins") ) , wxEmptyString, wxITEM_CHECK ); + m_menuView->Append( m_menuViewShowGenerated ); + + m_menubar->Append( m_menuView, wxT("&View") ); + m_menuOptions = new wxMenu(); wxMenuItem* m_menuOptionsGenerateBitcoins; m_menuOptionsGenerateBitcoins = new wxMenuItem( m_menuOptions, wxID_OPTIONSGENERATEBITCOINS, wxString( wxT("&Generate Coins") ) , wxEmptyString, wxITEM_CHECK ); m_menuOptions->Append( m_menuOptionsGenerateBitcoins ); - wxMenuItem* m_menuChangeYourAddress; - m_menuChangeYourAddress = new wxMenuItem( m_menuOptions, wxID_ANY, wxString( wxT("&Change Your Address...") ) , wxEmptyString, wxITEM_NORMAL ); - m_menuOptions->Append( m_menuChangeYourAddress ); + wxMenuItem* m_menuOptionsChangeYourAddress; + m_menuOptionsChangeYourAddress = new wxMenuItem( m_menuOptions, wxID_ANY, wxString( wxT("&Change Your Address...") ) , wxEmptyString, wxITEM_NORMAL ); + m_menuOptions->Append( m_menuOptionsChangeYourAddress ); wxMenuItem* m_menuOptionsOptions; m_menuOptionsOptions = new wxMenuItem( m_menuOptions, wxID_ANY, wxString( wxT("&Options...") ) , wxEmptyString, wxITEM_NORMAL ); @@ -225,9 +232,11 @@ CMainFrameBase::CMainFrameBase( wxWindow* parent, wxWindowID id, const wxString& 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_menuViewShowGenerated->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( CMainFrameBase::OnMenuViewShowGenerated ) ); + this->Connect( m_menuViewShowGenerated->GetId(), wxEVT_UPDATE_UI, wxUpdateUIEventHandler( CMainFrameBase::OnUpdateUIViewShowGenerated ) ); this->Connect( m_menuOptionsGenerateBitcoins->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( CMainFrameBase::OnMenuOptionsGenerate ) ); - this->Connect( m_menuOptionsGenerateBitcoins->GetId(), wxEVT_UPDATE_UI, wxUpdateUIEventHandler( CMainFrameBase::OnUpdateMenuGenerate ) ); - this->Connect( m_menuChangeYourAddress->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( CMainFrameBase::OnMenuOptionsChangeYourAddress ) ); + this->Connect( m_menuOptionsGenerateBitcoins->GetId(), wxEVT_UPDATE_UI, wxUpdateUIEventHandler( CMainFrameBase::OnUpdateUIOptionsGenerate ) ); + 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 ) ); @@ -278,8 +287,10 @@ CMainFrameBase::~CMainFrameBase() 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::OnMenuViewShowGenerated ) ); + this->Disconnect( wxID_ANY, wxEVT_UPDATE_UI, wxUpdateUIEventHandler( CMainFrameBase::OnUpdateUIViewShowGenerated ) ); this->Disconnect( wxID_ANY, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( CMainFrameBase::OnMenuOptionsGenerate ) ); - this->Disconnect( wxID_ANY, wxEVT_UPDATE_UI, wxUpdateUIEventHandler( CMainFrameBase::OnUpdateMenuGenerate ) ); + this->Disconnect( wxID_ANY, wxEVT_UPDATE_UI, wxUpdateUIEventHandler( CMainFrameBase::OnUpdateUIOptionsGenerate ) ); 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 ) ); @@ -353,15 +364,121 @@ COptionsDialogBase::COptionsDialogBase( wxWindow* parent, wxWindowID id, const w wxBoxSizer* bSizer55; bSizer55 = new wxBoxSizer( wxVERTICAL ); - panelSizer = new wxBoxSizer( wxHORIZONTAL ); + 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, 14, 0, wxEXPAND, 5 ); + + m_staticText32 = new wxStaticText( m_panelMain, wxID_ANY, wxT("Optional transaction fee you give to the nodes that process your transactions."), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticText32->Wrap( -1 ); + m_staticText32->Hide(); + + bSizer69->Add( m_staticText32, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 ); + + wxBoxSizer* bSizer56; + bSizer56 = new wxBoxSizer( wxHORIZONTAL ); + + m_staticText31 = new wxStaticText( m_panelMain, wxID_ANY, wxT("Transaction fee:"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticText31->Wrap( -1 ); + m_staticText31->Hide(); + + 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 ); + m_textCtrlTransactionFee->Hide(); + + bSizer56->Add( m_textCtrlTransactionFee, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); + + bSizer69->Add( bSizer56, 0, wxEXPAND, 5 ); + + wxBoxSizer* bSizer71; + bSizer71 = new wxBoxSizer( wxHORIZONTAL ); + + m_checkBoxLimitProcessors = new wxCheckBox( m_panelMain, wxID_ANY, wxT("&Limit coin generation to"), wxDefaultPosition, wxDefaultSize, 0 ); + + bSizer71->Add( m_checkBoxLimitProcessors, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 ); + + m_spinCtrlLimitProcessors = new wxSpinCtrl( m_panelMain, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize( 48,-1 ), wxSP_ARROW_KEYS, 1, 999, 1 ); + bSizer71->Add( m_spinCtrlLimitProcessors, 0, wxTOP|wxBOTTOM, 5 ); + + m_staticText35 = new wxStaticText( m_panelMain, wxID_ANY, wxT("processors"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticText35->Wrap( -1 ); + bSizer71->Add( m_staticText35, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 ); + + bSizer69->Add( bSizer71, 0, 0, 5 ); + + m_checkBoxStartOnSystemStartup = new wxCheckBox( m_panelMain, wxID_ANY, wxT("&Start Bitcoin on system startup"), wxDefaultPosition, wxDefaultSize, 0 ); + + bSizer69->Add( m_checkBoxStartOnSystemStartup, 0, wxALL, 5 ); + + m_checkBoxMinimizeToTray = new wxCheckBox( m_panelMain, wxID_ANY, wxT("&Minimize to the system tray instead of the taskbar"), wxDefaultPosition, wxDefaultSize, 0 ); + + bSizer69->Add( m_checkBoxMinimizeToTray, 0, wxALL, 5 ); + + wxBoxSizer* bSizer101; + bSizer101 = new wxBoxSizer( wxHORIZONTAL ); + + + bSizer101->Add( 16, 0, 0, 0, 5 ); + + m_checkBoxMinimizeOnClose = new wxCheckBox( m_panelMain, wxID_ANY, wxT("M&inimize to system tray on close"), wxDefaultPosition, wxDefaultSize, 0 ); + + bSizer101->Add( m_checkBoxMinimizeOnClose, 0, wxALL, 5 ); + + bSizer69->Add( bSizer101, 1, 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, 14, 0, wxEXPAND, 5 ); + + m_staticText321 = new wxStaticText( m_panelTest2, wxID_ANY, wxT("Test panel 2 for future expansion"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticText321->Wrap( -1 ); + bSizer64->Add( m_staticText321, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 ); - m_treeCtrl = new wxTreeCtrl( this, wxID_ANY, wxDefaultPosition, wxSize( 100,-1 ), wxTR_HAS_BUTTONS|wxTR_HIDE_ROOT|wxTR_LINES_AT_ROOT ); - panelSizer->Add( m_treeCtrl, 0, wxALL|wxEXPAND, 5 ); + m_staticText69 = new wxStaticText( m_panelTest2, wxID_ANY, wxT("MyLabel"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticText69->Wrap( -1 ); + bSizer64->Add( m_staticText69, 0, wxALL, 5 ); - bSizer55->Add( panelSizer, 1, wxEXPAND, 5 ); + m_staticText70 = new wxStaticText( m_panelTest2, wxID_ANY, wxT("MyLabel"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticText70->Wrap( -1 ); + bSizer64->Add( m_staticText70, 0, wxALL, 5 ); - m_staticline1 = new wxStaticLine( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL ); - bSizer55->Add( m_staticline1, 0, wxEXPAND | wxALL, 5 ); + m_staticText71 = new wxStaticText( m_panelTest2, wxID_ANY, wxT("MyLabel"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticText71->Wrap( -1 ); + bSizer64->Add( m_staticText71, 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 ); @@ -374,9 +491,8 @@ COptionsDialogBase::COptionsDialogBase( wxWindow* parent, wxWindowID id, const w bSizer58->Add( m_buttonCancel, 0, wxALL, 5 ); - m_buttonApply = new wxButton( this, wxID_ANY, wxT("Apply"), wxDefaultPosition, wxDefaultSize, 0 ); - m_buttonApply->Enable( false ); - m_buttonApply->Hide(); + m_buttonApply = new wxButton( this, wxID_APPLY, wxT("&Apply"), wxDefaultPosition, wxSize( -1,-1 ), 0 ); + m_buttonApply->SetMinSize( wxSize( 85,25 ) ); bSizer58->Add( m_buttonApply, 0, wxALL, 5 ); @@ -386,17 +502,25 @@ COptionsDialogBase::COptionsDialogBase( wxWindow* parent, wxWindowID id, const w this->Layout(); // Connect Events - m_treeCtrl->Connect( wxEVT_COMMAND_TREE_SEL_CHANGED, wxTreeEventHandler( COptionsDialogBase::MenuSelChanged ), NULL, this ); + m_listBox->Connect( wxEVT_COMMAND_LISTBOX_SELECTED, wxCommandEventHandler( COptionsDialogBase::OnListBox ), NULL, this ); + m_textCtrlTransactionFee->Connect( wxEVT_KILL_FOCUS, wxFocusEventHandler( COptionsDialogBase::OnKillFocusTransactionFee ), NULL, this ); + m_checkBoxLimitProcessors->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( COptionsDialogBase::OnCheckBoxLimitProcessors ), NULL, this ); + m_checkBoxMinimizeToTray->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( COptionsDialogBase::OnCheckBoxMinimizeToTray ), 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_treeCtrl->Disconnect( wxEVT_COMMAND_TREE_SEL_CHANGED, wxTreeEventHandler( COptionsDialogBase::MenuSelChanged ), NULL, this ); + m_listBox->Disconnect( wxEVT_COMMAND_LISTBOX_SELECTED, wxCommandEventHandler( COptionsDialogBase::OnListBox ), NULL, this ); + m_textCtrlTransactionFee->Disconnect( wxEVT_KILL_FOCUS, wxFocusEventHandler( COptionsDialogBase::OnKillFocusTransactionFee ), NULL, this ); + m_checkBoxLimitProcessors->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( COptionsDialogBase::OnCheckBoxLimitProcessors ), NULL, this ); + m_checkBoxMinimizeToTray->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( COptionsDialogBase::OnCheckBoxMinimizeToTray ), 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 ) @@ -1815,78 +1939,3 @@ CGetTextFromUserDialogBase::~CGetTextFromUserDialogBase() m_buttonOK->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CGetTextFromUserDialogBase::OnButtonOK ), NULL, this ); m_buttonCancel->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CGetTextFromUserDialogBase::OnButtonCancel ), NULL, this ); } - -COptionsPanelBitcoinBase::COptionsPanelBitcoinBase( wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style ) : wxPanel( parent, id, pos, size, style ) -{ - wxBoxSizer* bSizer62; - bSizer62 = new wxBoxSizer( wxVERTICAL ); - - - bSizer62->Add( 0, 20, 0, wxEXPAND, 5 ); - - m_staticText32 = new wxStaticText( this, wxID_ANY, wxT("Optional transaction fee you give to the nodes that process your transactions."), wxDefaultPosition, wxDefaultSize, 0 ); - m_staticText32->Wrap( -1 ); - bSizer62->Add( m_staticText32, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 ); - - wxBoxSizer* bSizer56; - bSizer56 = new wxBoxSizer( wxHORIZONTAL ); - - m_staticText31 = new wxStaticText( this, wxID_ANY, wxT("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( this, wxID_TRANSACTIONFEE, wxEmptyString, wxDefaultPosition, wxSize( 70,-1 ), 0 ); - bSizer56->Add( m_textCtrlTransactionFee, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); - - bSizer62->Add( bSizer56, 0, wxEXPAND, 5 ); - - this->SetSizer( bSizer62 ); - this->Layout(); - bSizer62->Fit( this ); - - // Connect Events - m_textCtrlTransactionFee->Connect( wxEVT_KILL_FOCUS, wxFocusEventHandler( COptionsPanelBitcoinBase::OnKillFocusTransactionFee ), NULL, this ); -} - -COptionsPanelBitcoinBase::~COptionsPanelBitcoinBase() -{ - // Disconnect Events - m_textCtrlTransactionFee->Disconnect( wxEVT_KILL_FOCUS, wxFocusEventHandler( COptionsPanelBitcoinBase::OnKillFocusTransactionFee ), NULL, this ); -} - -COptionsPanelUIBase::COptionsPanelUIBase( wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style ) : wxPanel( parent, id, pos, size, style ) -{ - wxBoxSizer* bSizer57; - bSizer57 = new wxBoxSizer( wxVERTICAL ); - - - bSizer57->Add( 0, 20, 1, wxEXPAND, 5 ); - - m_checkMinToTray = new wxCheckBox( this, wxID_MINTOTRAY, wxT("Minimize to tray"), wxDefaultPosition, wxDefaultSize, 0 ); - - bSizer57->Add( m_checkMinToTray, 0, wxALL, 5 ); - - m_checkCloseToTray = new wxCheckBox( this, wxID_ANY, wxT("Close to tray"), wxDefaultPosition, wxDefaultSize, 0 ); - - bSizer57->Add( m_checkCloseToTray, 0, wxALL, 5 ); - - m_checkStartOnSysBoot = new wxCheckBox( this, wxID_ANY, wxT("Start with Windows"), wxDefaultPosition, wxDefaultSize, 0 ); - - bSizer57->Add( m_checkStartOnSysBoot, 0, wxALL, 5 ); - - m_checkAskBeforeClosing = new wxCheckBox( this, wxID_ANY, wxT("Ask before closing"), wxDefaultPosition, wxDefaultSize, 0 ); - - bSizer57->Add( m_checkAskBeforeClosing, 0, wxALL, 5 ); - - m_checkAlwaysShowTray = new wxCheckBox( this, wxID_ANY, wxT("Always show tray icon"), wxDefaultPosition, wxDefaultSize, 0 ); - - bSizer57->Add( m_checkAlwaysShowTray, 0, wxALL, 5 ); - - this->SetSizer( bSizer57 ); - this->Layout(); - bSizer57->Fit( this ); -} - -COptionsPanelUIBase::~COptionsPanelUIBase() -{ -} diff --git a/uibase.h b/uibase.h index 61e0552283..e262a3dcb6 100644 --- a/uibase.h +++ b/uibase.h @@ -30,69 +30,70 @@ #include #include #include -#include -#include +#include +#include +#include +#include #include #include -#include #include -#include +#include /////////////////////////////////////////////////////////////////////////// #define wxID_MAINFRAME 1000 -#define wxID_OPTIONSGENERATEBITCOINS 1001 -#define wxID_BUTTONSEND 1002 -#define wxID_BUTTONRECEIVE 1003 -#define wxID_TEXTCTRLADDRESS 1004 -#define wxID_BUTTONCOPY 1005 -#define wxID_BUTTONCHANGE 1006 -#define wxID_TEXTCTRLPAYTO 1007 -#define wxID_BUTTONPASTE 1008 -#define wxID_BUTTONADDRESSBOOK 1009 -#define wxID_TEXTCTRLAMOUNT 1010 -#define wxID_CHOICETRANSFERTYPE 1011 -#define wxID_LISTCTRL 1012 -#define wxID_BUTTONRENAME 1013 -#define wxID_BUTTONNEW 1014 -#define wxID_BUTTONEDIT 1015 -#define wxID_BUTTONDELETE 1016 -#define wxID_DEL0 1017 -#define wxID_DEL1 1018 -#define wxID_DEL2 1019 -#define wxID_DEL3 1020 -#define wxID_DEL4 1021 -#define wxID_DEL5 1022 -#define wxID_DEL6 1023 -#define wxID_DEL7 1024 -#define wxID_DEL8 1025 -#define wxID_DEL9 1026 -#define wxID_DEL10 1027 -#define wxID_DEL11 1028 -#define wxID_DEL12 1029 -#define wxID_DEL13 1030 -#define wxID_DEL14 1031 -#define wxID_DEL15 1032 -#define wxID_DEL16 1033 -#define wxID_DEL17 1034 -#define wxID_DEL18 1035 -#define wxID_DEL19 1036 -#define wxID_BUTTONPREVIEW 1037 -#define wxID_BUTTONSAMPLE 1038 -#define wxID_CANCEL2 1039 -#define wxID_BUTTONBACK 1040 -#define wxID_BUTTONNEXT 1041 -#define wxID_SUBMIT 1042 -#define wxID_OPENNEWTABLE 1043 -#define wxID_DEALHAND 1044 -#define wxID_FOLD 1045 -#define wxID_CALL 1046 -#define wxID_RAISE 1047 -#define wxID_LEAVETABLE 1048 -#define wxID_DITCHPLAYER 1049 -#define wxID_TEXTCTRL 1050 -#define wxID_TRANSACTIONFEE 1051 -#define wxID_MINTOTRAY 1052 +#define wxID_VIEWSHOWGENERATED 1001 +#define wxID_OPTIONSGENERATEBITCOINS 1002 +#define wxID_BUTTONSEND 1003 +#define wxID_BUTTONRECEIVE 1004 +#define wxID_TEXTCTRLADDRESS 1005 +#define wxID_BUTTONCOPY 1006 +#define wxID_BUTTONCHANGE 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_BUTTONNEW 1016 +#define wxID_BUTTONEDIT 1017 +#define wxID_BUTTONDELETE 1018 +#define wxID_DEL0 1019 +#define wxID_DEL1 1020 +#define wxID_DEL2 1021 +#define wxID_DEL3 1022 +#define wxID_DEL4 1023 +#define wxID_DEL5 1024 +#define wxID_DEL6 1025 +#define wxID_DEL7 1026 +#define wxID_DEL8 1027 +#define wxID_DEL9 1028 +#define wxID_DEL10 1029 +#define wxID_DEL11 1030 +#define wxID_DEL12 1031 +#define wxID_DEL13 1032 +#define wxID_DEL14 1033 +#define wxID_DEL15 1034 +#define wxID_DEL16 1035 +#define wxID_DEL17 1036 +#define wxID_DEL18 1037 +#define wxID_DEL19 1038 +#define wxID_BUTTONPREVIEW 1039 +#define wxID_BUTTONSAMPLE 1040 +#define wxID_CANCEL2 1041 +#define wxID_BUTTONBACK 1042 +#define wxID_BUTTONNEXT 1043 +#define wxID_SUBMIT 1044 +#define wxID_OPENNEWTABLE 1045 +#define wxID_DEALHAND 1046 +#define wxID_FOLD 1047 +#define wxID_CALL 1048 +#define wxID_RAISE 1049 +#define wxID_LEAVETABLE 1050 +#define wxID_DITCHPLAYER 1051 +#define wxID_TEXTCTRL 1052 /////////////////////////////////////////////////////////////////////////////// /// Class CMainFrameBase @@ -104,6 +105,7 @@ class CMainFrameBase : public wxFrame protected: wxMenuBar* m_menubar; wxMenu* m_menuFile; + wxMenu* m_menuView; wxMenu* m_menuHelp; wxToolBar* m_toolBar; wxStatusBar* m_statusBar; @@ -132,8 +134,10 @@ class CMainFrameBase : public wxFrame virtual void OnMouseEvents( wxMouseEvent& event ){ event.Skip(); } virtual void OnPaint( wxPaintEvent& event ){ event.Skip(); } virtual void OnMenuFileExit( wxCommandEvent& event ){ event.Skip(); } + virtual void OnMenuViewShowGenerated( wxCommandEvent& event ){ event.Skip(); } + virtual void OnUpdateUIViewShowGenerated( wxUpdateUIEvent& event ){ event.Skip(); } virtual void OnMenuOptionsGenerate( wxCommandEvent& event ){ event.Skip(); } - virtual void OnUpdateMenuGenerate( wxUpdateUIEvent& event ){ event.Skip(); } + virtual void OnUpdateUIOptionsGenerate( wxUpdateUIEvent& event ){ event.Skip(); } virtual void OnMenuOptionsChangeYourAddress( wxCommandEvent& event ){ event.Skip(); } virtual void OnMenuOptionsOptions( wxCommandEvent& event ){ event.Skip(); } virtual void OnMenuHelpAbout( wxCommandEvent& event ){ event.Skip(); } @@ -193,21 +197,42 @@ class COptionsDialogBase : public wxDialog private: protected: - wxBoxSizer* panelSizer; - wxTreeCtrl* m_treeCtrl; - wxStaticLine* m_staticline1; + wxListBox* m_listBox; + wxScrolledWindow* m_scrolledWindow; + wxPanel* m_panelMain; + + wxStaticText* m_staticText32; + wxStaticText* m_staticText31; + wxTextCtrl* m_textCtrlTransactionFee; + wxCheckBox* m_checkBoxLimitProcessors; + wxSpinCtrl* m_spinCtrlLimitProcessors; + wxStaticText* m_staticText35; + wxCheckBox* m_checkBoxStartOnSystemStartup; + wxCheckBox* m_checkBoxMinimizeToTray; + + wxCheckBox* m_checkBoxMinimizeOnClose; + wxPanel* m_panelTest2; + + wxStaticText* m_staticText321; + wxStaticText* m_staticText69; + wxStaticText* m_staticText70; + wxStaticText* m_staticText71; wxButton* m_buttonOK; wxButton* m_buttonCancel; wxButton* m_buttonApply; // Virtual event handlers, overide them in your derived class - virtual void MenuSelChanged( wxTreeEvent& event ){ event.Skip(); } + virtual void OnListBox( wxCommandEvent& event ){ event.Skip(); } + virtual void OnKillFocusTransactionFee( wxFocusEvent& event ){ event.Skip(); } + virtual void OnCheckBoxLimitProcessors( wxCommandEvent& event ){ event.Skip(); } + virtual void OnCheckBoxMinimizeToTray( wxCommandEvent& 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 = wxT("Options"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 555,377 ), long style = wxDEFAULT_DIALOG_STYLE ); + COptionsDialogBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxT("Options"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 540,360 ), long style = wxDEFAULT_DIALOG_STYLE ); ~COptionsDialogBase(); }; @@ -720,48 +745,4 @@ class CGetTextFromUserDialogBase : public wxDialog }; -/////////////////////////////////////////////////////////////////////////////// -/// Class COptionsPanelBitcoinBase -/////////////////////////////////////////////////////////////////////////////// -class COptionsPanelBitcoinBase : public wxPanel -{ - private: - - protected: - - wxStaticText* m_staticText32; - wxStaticText* m_staticText31; - - // Virtual event handlers, overide them in your derived class - virtual void OnKillFocusTransactionFee( wxFocusEvent& event ){ event.Skip(); } - - - public: - wxTextCtrl* m_textCtrlTransactionFee; - COptionsPanelBitcoinBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxTAB_TRAVERSAL ); - ~COptionsPanelBitcoinBase(); - -}; - -/////////////////////////////////////////////////////////////////////////////// -/// Class COptionsPanelUIBase -/////////////////////////////////////////////////////////////////////////////// -class COptionsPanelUIBase : public wxPanel -{ - private: - - protected: - - - public: - wxCheckBox* m_checkMinToTray; - wxCheckBox* m_checkCloseToTray; - wxCheckBox* m_checkStartOnSysBoot; - wxCheckBox* m_checkAskBeforeClosing; - wxCheckBox* m_checkAlwaysShowTray; - COptionsPanelUIBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxTAB_TRAVERSAL ); - ~COptionsPanelUIBase(); - -}; - #endif //__uibase__ diff --git a/uiproject.fbp b/uiproject.fbp index 315cc725a0..af5876b4ab 100644 --- a/uiproject.fbp +++ b/uiproject.fbp @@ -18,7 +18,7 @@ 1 0 0 - + wxSYS_COLOUR_BTNFACE @@ -134,6 +134,26 @@ + + &View + m_menuView + protected + + + 0 + 1 + + wxID_VIEWSHOWGENERATED + wxITEM_CHECK + &Show Generated Coins + m_menuViewShowGenerated + none + + + OnMenuViewShowGenerated + OnUpdateUIViewShowGenerated + + &Options m_menuOptions @@ -151,7 +171,7 @@ OnMenuOptionsGenerate - OnUpdateMenuGenerate + OnUpdateUIOptionsGenerate @@ -161,7 +181,7 @@ wxID_ANY wxITEM_NORMAL &Change Your Address... - m_menuChangeYourAddress + m_menuOptionsChangeYourAddress none @@ -1679,7 +1699,7 @@ COptionsDialogBase - 555,377 + 540,360 wxDEFAULT_DIALOG_STYLE Options @@ -1723,20 +1743,21 @@ wxVERTICAL none - 5 - wxEXPAND + 9 + wxEXPAND|wxALL 1 - panelSizer + bSizer66 wxHORIZONTAL - protected + none 5 - wxALL|wxEXPAND + wxEXPAND|wxRIGHT 0 - + + 1 @@ -1745,11 +1766,11 @@ wxID_ANY - m_treeCtrl + m_listBox protected - 100,-1 - wxTR_HAS_BUTTONS|wxTR_HIDE_ROOT|wxTR_LINES_AT_ROOT + 110,-1 + wxLB_NEEDED_SB|wxLB_SINGLE @@ -1765,6 +1786,8 @@ + OnListBox + @@ -1777,79 +1800,911 @@ - - - - - - - - - - - - - - - - - - MenuSelChanged - - - - - - - 5 - wxEXPAND | wxALL - 0 - - - - 1 - - - 0 - wxID_ANY - - - m_staticline1 - protected - - - wxLI_HORIZONTAL - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + 5 + wxEXPAND|wxLEFT + 1 + + + + 1 + + + 0 + wxID_ANY + + + m_scrolledWindow + protected + + 5 + 5 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + bSizer63 + wxVERTICAL + none + + 5 + wxEXPAND + 0 + + + + 1 + + + 0 + wxID_ANY + + + m_panelMain + protected + + + + + + + wxTAB_TRAVERSAL + + + + + + + + + + + + + + + + + + + + + + + + + + bSizer69 + wxVERTICAL + none + + 5 + wxEXPAND + 0 + + 14 + protected + 0 + + + + 5 + wxALIGN_CENTER_VERTICAL|wxALL + 0 + + + + 1 + + + 1 + wxID_ANY + Optional transaction fee you give to the nodes that process your transactions. + + + m_staticText32 + protected + + + + + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND + 0 + + + bSizer56 + wxHORIZONTAL + none + + 5 + wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxLEFT + 0 + + + + 1 + + + 1 + wxID_ANY + Transaction fee: + + + m_staticText31 + protected + + + + + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL|wxALIGN_CENTER_VERTICAL + 0 + + + + 1 + + + 1 + wxID_TRANSACTIONFEE + + 0 + + m_textCtrlTransactionFee + protected + + 70,-1 + + + + + + + + + + + + + OnKillFocusTransactionFee + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + + 0 + + + bSizer71 + wxHORIZONTAL + none + + 5 + wxALIGN_CENTER_VERTICAL|wxALL + 0 + + + 0 + + 1 + + + 0 + wxID_ANY + &Limit coin generation to + + + m_checkBoxLimitProcessors + protected + + + + + + + + + + OnCheckBoxLimitProcessors + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxTOP|wxBOTTOM + 0 + + + + 1 + + + 0 + wxID_ANY + 1 + 999 + + 1 + + m_spinCtrlLimitProcessors + protected + + 48,-1 + wxSP_ARROW_KEYS + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALIGN_CENTER_VERTICAL|wxALL + 0 + + + + 1 + + + 0 + wxID_ANY + processors + + + m_staticText35 + protected + + + + + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL + 0 + + + 0 + + 1 + + + 0 + wxID_ANY + &Start Bitcoin on system startup + + + m_checkBoxStartOnSystemStartup + protected + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL + 0 + + + 0 + + 1 + + + 0 + wxID_ANY + &Minimize to the system tray instead of the taskbar + + + m_checkBoxMinimizeToTray + protected + + + + + + + + + + OnCheckBoxMinimizeToTray + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND + 1 + + + bSizer101 + wxHORIZONTAL + none + + 5 + + 0 + + 0 + protected + 16 + + + + 5 + wxALL + 0 + + + 0 + + 1 + + + 0 + wxID_ANY + M&inimize to system tray on close + + + m_checkBoxMinimizeOnClose + protected + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND + 0 + + + + 1 + + + 0 + wxID_ANY + + + m_panelTest2 + protected + + + + + + + wxTAB_TRAVERSAL + + + + + + + + + + + + + + + + + + + + + + + + + + bSizer64 + wxVERTICAL + none + + 5 + wxEXPAND + 0 + + 14 + protected + 0 + + + + 5 + wxALIGN_CENTER_VERTICAL|wxALL + 0 + + + + 1 + + + 0 + wxID_ANY + Test panel 2 for future expansion + + + m_staticText321 + protected + + + + + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL + 0 + + + + 1 + + + 0 + wxID_ANY + MyLabel + + + m_staticText69 + protected + + + + + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL + 0 + + + + 1 + + + 0 + wxID_ANY + MyLabel + + + m_staticText70 + protected + + + + + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL + 0 + + + + 1 + + + 0 + wxID_ANY + MyLabel + + + m_staticText71 + protected + + + + + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -1973,25 +2828,25 @@ 0 - 0 + 1 - 1 - wxID_ANY - Apply + 0 + wxID_APPLY + &Apply - + 85,25 m_buttonApply protected - + -1,-1 - + OnButtonApply @@ -11849,551 +12704,5 @@ - - - - 1 - - - 0 - wxID_ANY - - - COptionsPanelBitcoinBase - - -1,-1 - - - - - wxTAB_TRAVERSAL - - - - - - - - - - - - - - - - - - - - - - - - - - - bSizer62 - wxVERTICAL - none - - 5 - wxEXPAND - 0 - - 20 - protected - 0 - - - - 5 - wxALIGN_CENTER_VERTICAL|wxALL - 0 - - - - 1 - - - 0 - wxID_ANY - Optional transaction fee you give to the nodes that process your transactions. - - - m_staticText32 - protected - - - - - - - - - -1 - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxEXPAND - 0 - - - bSizer56 - wxHORIZONTAL - none - - 5 - wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxLEFT - 0 - - - - 1 - - - 0 - wxID_ANY - Transaction fee: - - - m_staticText31 - protected - - - - - - - - - -1 - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALL|wxALIGN_CENTER_VERTICAL - 0 - - - - 1 - - - 0 - wxID_TRANSACTIONFEE - - 0 - - m_textCtrlTransactionFee - public - - 70,-1 - - - - - - - - - - - - - OnKillFocusTransactionFee - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1 - - - 0 - wxID_ANY - - - COptionsPanelUIBase - - -1,-1 - - - - - wxTAB_TRAVERSAL - - - - - - - - - - - - - - - - - - - - - - - - - - - bSizer57 - wxVERTICAL - none - - 5 - wxEXPAND - 1 - - 20 - protected - 0 - - - - 5 - wxALL - 0 - - - 0 - - 1 - - - 0 - wxID_MINTOTRAY - Minimize to tray - - - m_checkMinToTray - public - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALL - 0 - - - 0 - - 1 - - - 0 - wxID_ANY - Close to tray - - - m_checkCloseToTray - public - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALL - 0 - - - 0 - - 1 - - - 0 - wxID_ANY - Start with Windows - - - m_checkStartOnSysBoot - public - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALL - 0 - - - 0 - - 1 - - - 0 - wxID_ANY - Ask before closing - - - m_checkAskBeforeClosing - public - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALL - 0 - - - 0 - - 1 - - - 0 - wxID_ANY - Always show tray icon - - - m_checkAlwaysShowTray - public - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/util.cpp b/util.cpp index 9c0ab142e1..8271474eee 100644 --- a/util.cpp +++ b/util.cpp @@ -86,7 +86,7 @@ void RandAddSeed(bool fPerfmon) struct tm* ptmTime = gmtime(&nTime); char pszTime[200]; strftime(pszTime, sizeof(pszTime), "%x %H:%M:%S", ptmTime); - printf("%s RandAddSeed() got %d bytes of performance data\n", pszTime, nSize); + printf("%s RandAddSeed() %d bytes\n", pszTime, nSize); } } } @@ -174,7 +174,7 @@ bool error(const char* format, ...) void PrintException(std::exception* pex, const char* pszThread) { - char pszModule[260]; + char pszModule[MAX_PATH]; pszModule[0] = '\0'; GetModuleFileName(NULL, pszModule, sizeof(pszModule)); _strlwr(pszModule); -- cgit v1.2.3 From 44e1254d1c5ba55c77bbc59c007e22e6e782947a Mon Sep 17 00:00:00 2001 From: sirius-m Date: Sat, 24 Oct 2009 16:50:39 +0000 Subject: Removed autorun regkey creation --- setup.nsi | 2 -- 1 file changed, 2 deletions(-) diff --git a/setup.nsi b/setup.nsi index 56a46ea3eb..023914fab9 100644 --- a/setup.nsi +++ b/setup.nsi @@ -64,7 +64,6 @@ Section -Main SEC0000 File libeay32.dll File mingwm10.dll WriteRegStr HKCU "${REGKEY}\Components" Main 1 - WriteRegStr HKCU SOFTWARE\Microsoft\Windows\CurrentVersion\Run Bitcoin "$INSTDIR\bitcoin.exe /min" SectionEnd Section -post SEC0001 @@ -105,7 +104,6 @@ Section /o -un.Main UNSEC0000 Delete /REBOOTOK $INSTDIR\libeay32.dll Delete /REBOOTOK $INSTDIR\bitcoin.exe DeleteRegValue HKCU "${REGKEY}\Components" Main - DeleteRegValue HKCU SOFTWARE\Microsoft\Windows\CurrentVersion\Run Bitcoin SectionEnd Section -un.post UNSEC0001 -- cgit v1.2.3 From e39dfe8ea64a360978db0239fbd6ea4ef24de55d Mon Sep 17 00:00:00 2001 From: sirius-m Date: Sat, 24 Oct 2009 16:50:39 +0000 Subject: Removed autorun regkey creation git-svn-id: https://bitcoin.svn.sourceforge.net/svnroot/bitcoin/trunk@16 1a98c847-1fd6-4fd8-948a-caf3550aa51b --- setup.nsi | 2 -- 1 file changed, 2 deletions(-) diff --git a/setup.nsi b/setup.nsi index 56a46ea3eb..023914fab9 100644 --- a/setup.nsi +++ b/setup.nsi @@ -64,7 +64,6 @@ Section -Main SEC0000 File libeay32.dll File mingwm10.dll WriteRegStr HKCU "${REGKEY}\Components" Main 1 - WriteRegStr HKCU SOFTWARE\Microsoft\Windows\CurrentVersion\Run Bitcoin "$INSTDIR\bitcoin.exe /min" SectionEnd Section -post SEC0001 @@ -105,7 +104,6 @@ Section /o -un.Main UNSEC0000 Delete /REBOOTOK $INSTDIR\libeay32.dll Delete /REBOOTOK $INSTDIR\bitcoin.exe DeleteRegValue HKCU "${REGKEY}\Components" Main - DeleteRegValue HKCU SOFTWARE\Microsoft\Windows\CurrentVersion\Run Bitcoin SectionEnd Section -un.post UNSEC0001 -- cgit v1.2.3 From 6ccefea62ae5644c9b318234c6a8a6c077d00922 Mon Sep 17 00:00:00 2001 From: s_nakamoto Date: Sun, 25 Oct 2009 04:35:01 +0000 Subject: fix display of new generated coins, fix assertion in bitcoinminer --- main.cpp | 45 ++++++++++++++++++++++----------------------- serialize.h | 2 +- ui.cpp | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++---- ui.h | 1 + 4 files changed, 75 insertions(+), 28 deletions(-) diff --git a/main.cpp b/main.cpp index de5a5939e1..dbdee70211 100644 --- a/main.cpp +++ b/main.cpp @@ -1129,9 +1129,6 @@ bool CBlock::AddToBlockIndex(unsigned int nFile, unsigned int nBlockPos) } } - // Notify UI to update prev block coinbase if it was ours - vWalletUpdated.push_back(hashBestChain); - // New best link hashBestChain = hash; pindexBest = pindexNew; @@ -1143,10 +1140,18 @@ bool CBlock::AddToBlockIndex(unsigned int nFile, unsigned int nBlockPos) txdb.TxnCommit(); txdb.Close(); - // Relay wallet transactions that haven't gotten in yet if (pindexNew == pindexBest) + { + // Relay wallet transactions that haven't gotten in yet RelayWalletTransactions(); + // Notify UI to display prev block's coinbase if it was ours + static uint256 hashPrevBestCoinBase; + CRITICAL_BLOCK(cs_mapWallet) + vWalletUpdated.push_back(hashPrevBestCoinBase); + hashPrevBestCoinBase = vtx[0].GetHash(); + } + MainFrameRepaint(); return true; } @@ -2074,13 +2079,8 @@ bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) else { // Ignore unknown commands for extensibility - printf("ProcessMessage(%s) : Ignored unknown message\n", strCommand.c_str()); } - - if (!vRecv.empty()) - printf("ProcessMessage(%s) : %d extra bytes\n", strCommand.c_str(), vRecv.size()); - return true; } @@ -2349,7 +2349,7 @@ bool BitcoinMiner() } pblock->nBits = nBits; pblock->vtx[0].vout[0].nValue = pblock->GetBlockValue(nFees); - printf("\n\nRunning BitcoinMiner with %d transactions in block\n", pblock->vtx.size()); + printf("Running BitcoinMiner with %d transactions in block\n", pblock->vtx.size()); // @@ -2408,20 +2408,17 @@ bool BitcoinMiner() SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_NORMAL); CRITICAL_BLOCK(cs_main) { - if (pindexPrev != pindexBest) + if (pindexPrev == pindexBest) { - SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_LOWEST); - break; + // Save key + if (!AddKey(key)) + return false; + key.MakeNewKey(); + + // Process this block the same as if we had received it from another node + if (!ProcessBlock(NULL, pblock.release())) + printf("ERROR in BitcoinMiner, ProcessBlock, block not accepted\n"); } - - // Save key - if (!AddKey(key)) - return false; - key.MakeNewKey(); - - // Process this block the same as if we had received it from another node - if (!ProcessBlock(NULL, pblock.release())) - printf("ERROR in BitcoinMiner, ProcessBlock, block not accepted\n"); } SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_LOWEST); @@ -2439,8 +2436,10 @@ bool BitcoinMiner() break; if (nTransactionsUpdated != nTransactionsUpdatedLast && GetTime() - nStart > 60) break; - if (!fGenerateBitcoins) + if (vNodes.empty()) break; + if (!fGenerateBitcoins) + return true; if (fLimitProcessors && vnThreadsRunning[3] > nLimitProcessors) return true; tmp.block.nTime = pblock->nTime = max(pindexPrev->GetMedianTimePast()+1, GetAdjustedTime()); diff --git a/serialize.h b/serialize.h index 9b20e2a0f6..b7ab86d22a 100644 --- a/serialize.h +++ b/serialize.h @@ -19,7 +19,7 @@ class CScript; class CDataStream; class CAutoFile; -static const int VERSION = 106; +static const int VERSION = 105; diff --git a/ui.cpp b/ui.cpp index ce43a786c8..428304796e 100644 --- a/ui.cpp +++ b/ui.cpp @@ -306,6 +306,8 @@ CMainFrame::CMainFrame(wxWindow* parent) : CMainFrameBase(parent) // Init column headers int nDateWidth = DateTimeStr(1229413914).size() * 6 + 8; + if (!strstr(DateTimeStr(1229413914).c_str(), "2008")) + nDateWidth += 12; m_listCtrl->InsertColumn(0, "", wxLIST_FORMAT_LEFT, 0); m_listCtrl->InsertColumn(1, "", wxLIST_FORMAT_LEFT, 0); m_listCtrl->InsertColumn(2, "Status", wxLIST_FORMAT_LEFT, 90); @@ -441,12 +443,33 @@ void CMainFrame::InsertLine(bool fNew, int nIndex, uint256 hashKey, string strSo m_listCtrl->SetItemData(nIndex, nData); } +bool CMainFrame::DeleteLine(uint256 hashKey) +{ + long nData = *(long*)&hashKey; + + // Find item + int nIndex = -1; + while ((nIndex = m_listCtrl->FindItem(nIndex, nData)) != -1) + if (GetItemText(m_listCtrl, nIndex, 1) == hashKey.ToString()) + break; + + if (nIndex != -1) + m_listCtrl->DeleteItem(nIndex); + + return nIndex != -1; +} + string FormatTxStatus(const CWalletTx& wtx) { // Status int nDepth = wtx.GetDepthInMainChain(); if (!wtx.IsFinal()) - return strprintf("Open for %d blocks", nBestHeight - wtx.nLockTime); + { + 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 if (nDepth < 6) return strprintf("%d/unconfirmed", nDepth); else @@ -503,7 +526,11 @@ void CMainFrame::InsertTransaction(const CWalletTx& wtx, bool fNew, int nIndex) // are special because if their block is not accepted, they are not valid. // if (wtx.GetDepthInMainChain() < 2) + { + // In case it was previously displayed + DeleteLine(hash); return; + } } // Find the block the tx is in @@ -800,6 +827,17 @@ void CMainFrame::OnPaint(wxPaintEvent& event) event.Skip(); } +void DelayedRepaint(void* parg) +{ + static bool fOneThread; + if (fOneThread) + return; + fOneThread = true; + Sleep(1000); + MainFrameRepaint(); + fOneThread = false; +} + void CMainFrame::OnPaintListCtrl(wxPaintEvent& event) { // Update listctrl contents @@ -824,7 +862,7 @@ void CMainFrame::OnPaintListCtrl(wxPaintEvent& event) // Update status bar string strGen = ""; if (fGenerateBitcoins) - strGen = " Generating"; + strGen = " Generating"; if (fGenerateBitcoins && vNodes.empty()) strGen = "(not connected)"; m_statusBar->SetStatusText(strGen, 1); @@ -833,8 +871,16 @@ void CMainFrame::OnPaintListCtrl(wxPaintEvent& event) m_statusBar->SetStatusText(strStatus, 2); // Balance total + bool fRefreshed = false; TRY_CRITICAL_BLOCK(cs_mapWallet) + { m_staticTextBalance->SetLabel(FormatMoney(GetBalance()) + " "); + fRefreshed = true; + } + + // mapWallet was locked, try again later + if (!vWalletUpdated.empty() || !fRefreshed) + _beginthread(DelayedRepaint, 0, NULL); m_listCtrl->OnPaint(event); } @@ -1414,7 +1460,7 @@ void COptionsDialog::OnButtonApply(wxCommandEvent& event) CAboutDialog::CAboutDialog(wxWindow* parent) : CAboutDialogBase(parent) { - m_staticTextVersion->SetLabel(strprintf("version 0.%d.%d Alpha", VERSION/100, VERSION%100)); + m_staticTextVersion->SetLabel(strprintf("version 0.%d.%d Beta", VERSION/100, VERSION%100)); // Workaround until upgrade to wxWidgets supporting UTF-8 wxString str = m_staticTextMain->GetLabel(); @@ -3358,6 +3404,8 @@ bool CMyApp::OnInit2() return false; } + //RandAddSeedPerfmon(); + if (!StartNode(strErrors)) wxMessageBox(strErrors, "Bitcoin"); @@ -3517,7 +3565,6 @@ void SetStartOnSystemStartup(bool fAutoStart) // Get the current executable path char pszExePath[MAX_PATH]; GetModuleFileName(NULL, pszExePath, sizeof(pszExePath)); - _strlwr(pszExePath); // Set the path to the shortcut target psl->SetPath(pszExePath); diff --git a/ui.h b/ui.h index f89456bf3f..f451d93565 100644 --- a/ui.h +++ b/ui.h @@ -88,6 +88,7 @@ public: void OnCrossThreadCall(wxCommandEvent& event); void InsertLine(bool fNew, int nIndex, uint256 hashKey, string strSort, const wxString& str1, const wxString& str2, const wxString& str3, const wxString& str4, const wxString& str5); + bool DeleteLine(uint256 hashKey); void InsertTransaction(const CWalletTx& wtx, bool fNew, int nIndex=-1); void RefreshListCtrl(); void RefreshStatus(); -- cgit v1.2.3 From fa2a0338d3f8b1c3a1d75bff39ff42e436cee0dc Mon Sep 17 00:00:00 2001 From: s_nakamoto Date: Sun, 25 Oct 2009 04:35:01 +0000 Subject: fix display of new generated coins, fix assertion in bitcoinminer git-svn-id: https://bitcoin.svn.sourceforge.net/svnroot/bitcoin/trunk@17 1a98c847-1fd6-4fd8-948a-caf3550aa51b --- main.cpp | 45 ++++++++++++++++++++++----------------------- serialize.h | 2 +- ui.cpp | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++---- ui.h | 1 + 4 files changed, 75 insertions(+), 28 deletions(-) diff --git a/main.cpp b/main.cpp index de5a5939e1..dbdee70211 100644 --- a/main.cpp +++ b/main.cpp @@ -1129,9 +1129,6 @@ bool CBlock::AddToBlockIndex(unsigned int nFile, unsigned int nBlockPos) } } - // Notify UI to update prev block coinbase if it was ours - vWalletUpdated.push_back(hashBestChain); - // New best link hashBestChain = hash; pindexBest = pindexNew; @@ -1143,10 +1140,18 @@ bool CBlock::AddToBlockIndex(unsigned int nFile, unsigned int nBlockPos) txdb.TxnCommit(); txdb.Close(); - // Relay wallet transactions that haven't gotten in yet if (pindexNew == pindexBest) + { + // Relay wallet transactions that haven't gotten in yet RelayWalletTransactions(); + // Notify UI to display prev block's coinbase if it was ours + static uint256 hashPrevBestCoinBase; + CRITICAL_BLOCK(cs_mapWallet) + vWalletUpdated.push_back(hashPrevBestCoinBase); + hashPrevBestCoinBase = vtx[0].GetHash(); + } + MainFrameRepaint(); return true; } @@ -2074,13 +2079,8 @@ bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) else { // Ignore unknown commands for extensibility - printf("ProcessMessage(%s) : Ignored unknown message\n", strCommand.c_str()); } - - if (!vRecv.empty()) - printf("ProcessMessage(%s) : %d extra bytes\n", strCommand.c_str(), vRecv.size()); - return true; } @@ -2349,7 +2349,7 @@ bool BitcoinMiner() } pblock->nBits = nBits; pblock->vtx[0].vout[0].nValue = pblock->GetBlockValue(nFees); - printf("\n\nRunning BitcoinMiner with %d transactions in block\n", pblock->vtx.size()); + printf("Running BitcoinMiner with %d transactions in block\n", pblock->vtx.size()); // @@ -2408,20 +2408,17 @@ bool BitcoinMiner() SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_NORMAL); CRITICAL_BLOCK(cs_main) { - if (pindexPrev != pindexBest) + if (pindexPrev == pindexBest) { - SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_LOWEST); - break; + // Save key + if (!AddKey(key)) + return false; + key.MakeNewKey(); + + // Process this block the same as if we had received it from another node + if (!ProcessBlock(NULL, pblock.release())) + printf("ERROR in BitcoinMiner, ProcessBlock, block not accepted\n"); } - - // Save key - if (!AddKey(key)) - return false; - key.MakeNewKey(); - - // Process this block the same as if we had received it from another node - if (!ProcessBlock(NULL, pblock.release())) - printf("ERROR in BitcoinMiner, ProcessBlock, block not accepted\n"); } SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_LOWEST); @@ -2439,8 +2436,10 @@ bool BitcoinMiner() break; if (nTransactionsUpdated != nTransactionsUpdatedLast && GetTime() - nStart > 60) break; - if (!fGenerateBitcoins) + if (vNodes.empty()) break; + if (!fGenerateBitcoins) + return true; if (fLimitProcessors && vnThreadsRunning[3] > nLimitProcessors) return true; tmp.block.nTime = pblock->nTime = max(pindexPrev->GetMedianTimePast()+1, GetAdjustedTime()); diff --git a/serialize.h b/serialize.h index 9b20e2a0f6..b7ab86d22a 100644 --- a/serialize.h +++ b/serialize.h @@ -19,7 +19,7 @@ class CScript; class CDataStream; class CAutoFile; -static const int VERSION = 106; +static const int VERSION = 105; diff --git a/ui.cpp b/ui.cpp index ce43a786c8..428304796e 100644 --- a/ui.cpp +++ b/ui.cpp @@ -306,6 +306,8 @@ CMainFrame::CMainFrame(wxWindow* parent) : CMainFrameBase(parent) // Init column headers int nDateWidth = DateTimeStr(1229413914).size() * 6 + 8; + if (!strstr(DateTimeStr(1229413914).c_str(), "2008")) + nDateWidth += 12; m_listCtrl->InsertColumn(0, "", wxLIST_FORMAT_LEFT, 0); m_listCtrl->InsertColumn(1, "", wxLIST_FORMAT_LEFT, 0); m_listCtrl->InsertColumn(2, "Status", wxLIST_FORMAT_LEFT, 90); @@ -441,12 +443,33 @@ void CMainFrame::InsertLine(bool fNew, int nIndex, uint256 hashKey, string strSo m_listCtrl->SetItemData(nIndex, nData); } +bool CMainFrame::DeleteLine(uint256 hashKey) +{ + long nData = *(long*)&hashKey; + + // Find item + int nIndex = -1; + while ((nIndex = m_listCtrl->FindItem(nIndex, nData)) != -1) + if (GetItemText(m_listCtrl, nIndex, 1) == hashKey.ToString()) + break; + + if (nIndex != -1) + m_listCtrl->DeleteItem(nIndex); + + return nIndex != -1; +} + string FormatTxStatus(const CWalletTx& wtx) { // Status int nDepth = wtx.GetDepthInMainChain(); if (!wtx.IsFinal()) - return strprintf("Open for %d blocks", nBestHeight - wtx.nLockTime); + { + 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 if (nDepth < 6) return strprintf("%d/unconfirmed", nDepth); else @@ -503,7 +526,11 @@ void CMainFrame::InsertTransaction(const CWalletTx& wtx, bool fNew, int nIndex) // are special because if their block is not accepted, they are not valid. // if (wtx.GetDepthInMainChain() < 2) + { + // In case it was previously displayed + DeleteLine(hash); return; + } } // Find the block the tx is in @@ -800,6 +827,17 @@ void CMainFrame::OnPaint(wxPaintEvent& event) event.Skip(); } +void DelayedRepaint(void* parg) +{ + static bool fOneThread; + if (fOneThread) + return; + fOneThread = true; + Sleep(1000); + MainFrameRepaint(); + fOneThread = false; +} + void CMainFrame::OnPaintListCtrl(wxPaintEvent& event) { // Update listctrl contents @@ -824,7 +862,7 @@ void CMainFrame::OnPaintListCtrl(wxPaintEvent& event) // Update status bar string strGen = ""; if (fGenerateBitcoins) - strGen = " Generating"; + strGen = " Generating"; if (fGenerateBitcoins && vNodes.empty()) strGen = "(not connected)"; m_statusBar->SetStatusText(strGen, 1); @@ -833,8 +871,16 @@ void CMainFrame::OnPaintListCtrl(wxPaintEvent& event) m_statusBar->SetStatusText(strStatus, 2); // Balance total + bool fRefreshed = false; TRY_CRITICAL_BLOCK(cs_mapWallet) + { m_staticTextBalance->SetLabel(FormatMoney(GetBalance()) + " "); + fRefreshed = true; + } + + // mapWallet was locked, try again later + if (!vWalletUpdated.empty() || !fRefreshed) + _beginthread(DelayedRepaint, 0, NULL); m_listCtrl->OnPaint(event); } @@ -1414,7 +1460,7 @@ void COptionsDialog::OnButtonApply(wxCommandEvent& event) CAboutDialog::CAboutDialog(wxWindow* parent) : CAboutDialogBase(parent) { - m_staticTextVersion->SetLabel(strprintf("version 0.%d.%d Alpha", VERSION/100, VERSION%100)); + m_staticTextVersion->SetLabel(strprintf("version 0.%d.%d Beta", VERSION/100, VERSION%100)); // Workaround until upgrade to wxWidgets supporting UTF-8 wxString str = m_staticTextMain->GetLabel(); @@ -3358,6 +3404,8 @@ bool CMyApp::OnInit2() return false; } + //RandAddSeedPerfmon(); + if (!StartNode(strErrors)) wxMessageBox(strErrors, "Bitcoin"); @@ -3517,7 +3565,6 @@ void SetStartOnSystemStartup(bool fAutoStart) // Get the current executable path char pszExePath[MAX_PATH]; GetModuleFileName(NULL, pszExePath, sizeof(pszExePath)); - _strlwr(pszExePath); // Set the path to the shortcut target psl->SetPath(pszExePath); diff --git a/ui.h b/ui.h index f89456bf3f..f451d93565 100644 --- a/ui.h +++ b/ui.h @@ -88,6 +88,7 @@ public: void OnCrossThreadCall(wxCommandEvent& event); void InsertLine(bool fNew, int nIndex, uint256 hashKey, string strSort, const wxString& str1, const wxString& str2, const wxString& str3, const wxString& str4, const wxString& str5); + bool DeleteLine(uint256 hashKey); void InsertTransaction(const CWalletTx& wtx, bool fNew, int nIndex=-1); void RefreshListCtrl(); void RefreshStatus(); -- cgit v1.2.3 From cc0b4c3b62367a2aebe5fc1f4d0ed4b97e9c2ac9 Mon Sep 17 00:00:00 2001 From: s_nakamoto Date: Thu, 29 Oct 2009 02:52:48 +0000 Subject: addr relaying fixes, proxy option and privacy patches, detect connect to self, non-final tx locktime changes, fix hide unconfirmed generated --- build.txt | 12 +-- db.cpp | 19 ++-- headers.h | 2 + irc.cpp | 10 +- key.h | 2 +- main.cpp | 71 +++++++++++--- main.h | 16 ++- makefile | 4 +- net.cpp | 173 +++++++++++++++++++-------------- net.h | 131 +++++++++++++++++++++++-- serialize.h | 2 +- strlcpy.h | 84 ++++++++++++++++ ui.cpp | 223 +++++++++++++++++++++++++++++++++--------- ui.h | 8 +- uibase.cpp | 51 ++++++++-- uibase.h | 98 ++++++++++--------- uiproject.fbp | 308 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-- util.cpp | 170 ++++++++++++++++++++++---------- util.h | 164 ++++++++++++++++++------------- 19 files changed, 1209 insertions(+), 339 deletions(-) create mode 100644 strlcpy.h diff --git a/build.txt b/build.txt index b6b526f1bc..f510055767 100644 --- a/build.txt +++ b/build.txt @@ -1,4 +1,4 @@ -BitCoin v0.1.6 ALPHA +BitCoin v0.1.6 BETA Copyright (c) 2009 Satoshi Nakamoto Distributed under the MIT/X11 software license, see the accompanying @@ -19,10 +19,10 @@ Dependencies Libraries you need to obtain separately to build: default path download -wxWidgets \wxWidgets http://www.wxwidgets.org/downloads/ -OpenSSL \OpenSSL http://www.openssl.org/source/ -Berkeley DB \DB http://www.oracle.com/technology/software/products/berkeley-db/index.html -Boost \Boost http://www.boost.org/users/download/ +wxWidgets \wxwidgets http://www.wxwidgets.org/downloads/ +OpenSSL \openssl http://www.openssl.org/source/ +Berkeley DB \db http://www.oracle.com/technology/software/products/berkeley-db/index.html +Boost \boost http://www.boost.org/users/download/ Their licenses: wxWidgets LGPL 2.1 with very liberal exceptions @@ -75,7 +75,7 @@ If you want to use it with MSVC, generate the .lib file Berkeley DB ----------- Using MinGW and MSYS: -cd \DB\build_unix +cd \db\build_unix sh ../dist/configure --enable-mingw --enable-cxx make diff --git a/db.cpp b/db.cpp index a9f5b7953c..315e93b73a 100644 --- a/db.cpp +++ b/db.cpp @@ -121,10 +121,12 @@ void CDB::Close() pdb->close(0); delete pdb; pdb = NULL; - dbenv.txn_checkpoint(0, 0, 0); CRITICAL_BLOCK(cs_db) + { + dbenv.txn_checkpoint(0, 0, 0); --mapFileUseCount[strFile]; + } RandAddSeed(); } @@ -376,11 +378,11 @@ bool CTxDB::LoadBlockIndex() { if (pindexGenesisBlock == NULL) return true; - return error("CTxDB::LoadBlockIndex() : hashBestChain not found\n"); + return error("CTxDB::LoadBlockIndex() : hashBestChain not found"); } if (!mapBlockIndex.count(hashBestChain)) - return error("CTxDB::LoadBlockIndex() : blockindex for hashBestChain not found\n"); + return error("CTxDB::LoadBlockIndex() : blockindex for hashBestChain not found"); pindexBest = mapBlockIndex[hashBestChain]; nBestHeight = pindexBest->nHeight; printf("LoadBlockIndex(): hashBestChain=%s height=%d\n", hashBestChain.ToString().substr(0,14).c_str(), nBestHeight); @@ -500,16 +502,15 @@ bool CReviewDB::WriteReviews(uint256 hash, const vector& vReviews) CWalletDB::~CWalletDB() { // Flush whenever all handles to wallet.dat are closed - Close(); CRITICAL_BLOCK(cs_db) { + Close(); // close includes a txn_checkpoint map::iterator mi = mapFileUseCount.find(strFile); if (mi != mapFileUseCount.end()) { int nRefCount = (*mi).second; if (nRefCount == 0) { - dbenv.txn_checkpoint(0, 0, 0); dbenv.lsn_reset(strFile.c_str(), 0); mapFileUseCount.erase(mi++); } @@ -600,6 +601,9 @@ bool CWalletDB::LoadWallet(vector& vchDefaultKeyRet) if (strKey == "nLimitProcessors") ssValue >> nLimitProcessors; if (strKey == "fMinimizeToTray") ssValue >> fMinimizeToTray; if (strKey == "fMinimizeOnClose") ssValue >> fMinimizeOnClose; + if (strKey == "fUseProxy") ssValue >> fUseProxy; + if (strKey == "addrProxy") ssValue >> addrProxy; + } } } @@ -610,6 +614,9 @@ bool CWalletDB::LoadWallet(vector& vchDefaultKeyRet) printf("addrIncoming = %s\n", addrIncoming.ToString().c_str()); printf("fMinimizeToTray = %d\n", fMinimizeToTray); printf("fMinimizeOnClose = %d\n", fMinimizeOnClose); + printf("fUseProxy = %d\n", fUseProxy); + printf("addrProxy = %s\n", addrProxy.ToString().c_str()); + // The transaction fee setting won't be needed for many years to come. // Setting it to zero here in case they set it to something in an earlier version. @@ -639,7 +646,7 @@ bool LoadWallet(bool& fFirstRunRet) else { // Create new keyUser and set as default key - RandAddSeed(true); + RandAddSeedPerfmon(); keyUser.MakeNewKey(); if (!AddKey(keyUser)) return false; diff --git a/headers.h b/headers.h index f7e88e0c67..29b16fb780 100644 --- a/headers.h +++ b/headers.h @@ -5,6 +5,7 @@ #ifdef _MSC_VER #pragma warning(disable:4786) #pragma warning(disable:4804) +#pragma warning(disable:4805) #pragma warning(disable:4717) #endif #ifdef _WIN32_WINNT @@ -62,6 +63,7 @@ using namespace boost; +#include "strlcpy.h" #include "serialize.h" #include "uint256.h" #include "util.h" diff --git a/irc.cpp b/irc.cpp index cfc9464aa7..707b4fe19f 100644 --- a/irc.cpp +++ b/irc.cpp @@ -163,6 +163,9 @@ void ThreadIRCSeed(void* parg) int nErrorWait = 10; int nRetryWait = 10; + if (fUseProxy && addrProxy.port == htons(9050)) + return; + while (!fShutdown) { CAddress addrConnect("216.155.130.130:6667"); @@ -191,9 +194,10 @@ void ThreadIRCSeed(void* parg) return; } - string strMyName = EncodeAddress(addrLocalHost); - - if (!addrLocalHost.IsRoutable()) + string strMyName; + if (addrLocalHost.IsRoutable() && !fUseProxy) + strMyName = EncodeAddress(addrLocalHost); + else strMyName = strprintf("x%u", GetRand(1000000000)); diff --git a/key.h b/key.h index 39ca86d317..71fce64a2a 100644 --- a/key.h +++ b/key.h @@ -35,7 +35,7 @@ public: }; -// secure_allocator is defined is serialize.h +// secure_allocator is defined in serialize.h typedef vector > CPrivKey; diff --git a/main.cpp b/main.cpp index dbdee70211..710b789200 100644 --- a/main.cpp +++ b/main.cpp @@ -415,6 +415,10 @@ bool CTransaction::AcceptTransaction(CTxDB& txdb, bool fCheckInputs, bool* pfMis if (!CheckTransaction()) return error("AcceptTransaction() : CheckTransaction failed"); + // To help v0.1.5 clients who would see it as negative number. please delete this later. + if (nLockTime > INT_MAX) + return error("AcceptTransaction() : not accepting nLockTime beyond 2038"); + // Do we already have it? uint256 hash = GetHash(); CRITICAL_BLOCK(cs_mapTransactions) @@ -1214,6 +1218,12 @@ bool CBlock::AcceptBlock() if (nTime <= pindexPrev->GetMedianTimePast()) return error("AcceptBlock() : block's timestamp is too early"); + // Check that all transactions are finalized (starting around 30 Nov 2009) + if (nBestHeight > 31000) // 25620 + 5320 + foreach(const CTransaction& tx, vtx) + if (!tx.IsFinal(nTime)) + return error("AcceptBlock() : contains a non-final transaction"); + // Check proof of work if (nBits != GetNextWorkRequired(pindexPrev)) return error("AcceptBlock() : incorrect proof of work"); @@ -1649,7 +1659,7 @@ bool ProcessMessages(CNode* pfrom) CDataStream& vRecv = pfrom->vRecv; if (vRecv.empty()) return true; - printf("ProcessMessages(%d bytes)\n", vRecv.size()); + //printf("ProcessMessages(%d bytes)\n", vRecv.size()); // // Message format @@ -1692,7 +1702,7 @@ bool ProcessMessages(CNode* pfrom) { // Rewind and wait for rest of message ///// need a mechanism to give up waiting for overlong message size error - printf("MESSAGE-BREAK\n"); + //printf("message-break\n"); vRecv.insert(vRecv.begin(), BEGIN(hdr), END(hdr)); Sleep(100); break; @@ -1711,7 +1721,20 @@ bool ProcessMessages(CNode* pfrom) fRet = ProcessMessage(pfrom, strCommand, vMsg); CheckForShutdown(2); } - CATCH_PRINT_EXCEPTION("ProcessMessage()") + catch (std::ios_base::failure& e) { + if (strstr(e.what(), "CDataStream::read() : end of data")) + { + // Allow exceptions from underlength message on vRecv + LogException(&e, "ProcessMessage()"); + } + else + PrintException(&e, "ProcessMessage()"); + } catch (std::exception& e) { + PrintException(&e, "ProcessMessage()"); + } catch (...) { + PrintException(NULL, "ProcessMessage()"); + } + if (!fRet) printf("ProcessMessage(%s, %d bytes) FAILED\n", strCommand.c_str(), nMessageSize); } @@ -1726,7 +1749,8 @@ bool ProcessMessages(CNode* pfrom) bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) { static map > mapReuseKey; - printf("received: %-12s (%d bytes)\n", strCommand.c_str(), vRecv.size()); + RandAddSeedPerfmon(); + printf("received: %s (%d bytes)\n", strCommand.c_str(), vRecv.size()); if (nDropMessagesTest > 0 && GetRand(nDropMessagesTest) == 0) { printf("dropmessages DROPPING RECV MESSAGE\n"); @@ -1735,18 +1759,32 @@ bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) + if (strCommand == "version") { - // Can only do this once + // Each connection can only send one version message if (pfrom->nVersion != 0) return false; int64 nTime; CAddress addrMe; + CAddress addrFrom; + uint64 nNonce = 1; vRecv >> pfrom->nVersion >> pfrom->nServices >> nTime >> addrMe; + if (pfrom->nVersion >= 106 && !vRecv.empty()) + vRecv >> addrFrom >> nNonce; if (pfrom->nVersion == 0) return false; + // Disconnect if we connected to ourself + if (nNonce == nLocalHostNonce) + { + pfrom->fDisconnect = true; + pfrom->vRecv.clear(); + pfrom->vSend.clear(); + return true; + } + pfrom->vSend.SetVersion(min(pfrom->nVersion, VERSION)); pfrom->vRecv.SetVersion(min(pfrom->nVersion, VERSION)); @@ -1767,6 +1805,8 @@ bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) pfrom->PushMessage("getblocks", CBlockLocator(pindexBest), uint256(0)); } + pfrom->fSuccessfullyConnected = true; + printf("version message: version %d\n", pfrom->nVersion); } @@ -1800,16 +1840,16 @@ bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) if (fShutdown) return true; AddAddress(addrdb, addr); - if (addr.IsRoutable() && addr.ip != addrLocalHost.ip) + pfrom->AddAddressKnown(addr); + if (!pfrom->fGetAddr && addr.IsRoutable()) { // Put on lists to send to other nodes - pfrom->setAddrKnown.insert(addr); CRITICAL_BLOCK(cs_vNodes) foreach(CNode* pnode, vNodes) - if (!pnode->setAddrKnown.count(addr)) - pnode->vAddrToSend.push_back(addr); + pnode->PushAddress(addr); } } + pfrom->fGetAddr = false; } @@ -2009,7 +2049,7 @@ bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) return true; const CAddress& addr = item.second; if (addr.nTime > nSince) - pfrom->vAddrToSend.push_back(addr); + pfrom->PushAddress(addr); } } } @@ -2108,8 +2148,11 @@ bool SendMessages(CNode* pto) vector vAddrToSend; vAddrToSend.reserve(pto->vAddrToSend.size()); foreach(const CAddress& addr, pto->vAddrToSend) - if (!pto->setAddrKnown.count(addr)) + { + // returns true if wasn't already contained in the set + if (pto->setAddrKnown.insert(addr).second) vAddrToSend.push_back(addr); + } pto->vAddrToSend.clear(); if (!vAddrToSend.empty()) pto->PushMessage("addr", vAddrToSend); @@ -2193,7 +2236,7 @@ void GenerateBitcoins(bool fGenerate) if (fLimitProcessors && nProcessors > nLimitProcessors) nProcessors = nLimitProcessors; int nAddThreads = nProcessors - vnThreadsRunning[3]; - printf("starting %d bitcoinminer threads\n", nAddThreads); + printf("Starting %d BitcoinMiner threads\n", nAddThreads); for (int i = 0; i < nAddThreads; i++) if (_beginthread(ThreadBitcoinMiner, 0, NULL) == -1) printf("Error: _beginthread(ThreadBitcoinMiner) failed\n"); @@ -2207,7 +2250,7 @@ void ThreadBitcoinMiner(void* parg) try { bool fRet = BitcoinMiner(); - printf("BitcoinMiner returned %s\n\n\n", fRet ? "true" : "false"); + printf("BitcoinMiner returned %s\n", fRet ? "true" : "false"); vnThreadsRunning[3]--; } catch (std::exception& e) { @@ -2737,7 +2780,7 @@ bool SendMoney(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew) else strError = "Error: Transaction creation failed "; wxMessageBox(strError, "Sending..."); - return error("SendMoney() : %s\n", strError.c_str()); + return error("SendMoney() : %s", strError.c_str()); } if (!CommitTransactionSpent(wtxNew, key)) { diff --git a/main.h b/main.h index 6b11285e5e..958f7a5f1c 100644 --- a/main.h +++ b/main.h @@ -366,7 +366,7 @@ public: int nVersion; vector vin; vector vout; - int nLockTime; + unsigned int nLockTime; CTransaction() @@ -401,9 +401,15 @@ public: return SerializeHash(*this); } - bool IsFinal() const + bool IsFinal(int64 nBlockTime=0) const { - if (nLockTime == 0 || nLockTime < nBestHeight) + // Time based nLockTime implemented in 0.1.6, + // do not use time based until most 0.1.5 nodes have upgraded. + if (nBlockTime == 0) + nBlockTime = GetAdjustedTime(); + if (nLockTime == 0) + return true; + if (nLockTime < (nLockTime < 500000000 ? nBestHeight : nBlockTime)) return true; foreach(const CTxIn& txin, vin) if (!txin.IsFinal()) @@ -686,8 +692,9 @@ public: char fSpent; //// probably need to sign the order info so know it came from payer - // memory only + // memory only UI hints mutable unsigned int nTimeDisplayed; + mutable int nLinesDisplayed; CWalletTx() @@ -712,6 +719,7 @@ public: fFromMe = false; fSpent = false; nTimeDisplayed = 0; + nLinesDisplayed = 0; } IMPLEMENT_SERIALIZE diff --git a/makefile b/makefile index 64bb773047..2d932f02cd 100644 --- a/makefile +++ b/makefile @@ -17,8 +17,8 @@ endif -INCLUDEPATHS=-I"/boost" -I"/DB/build_unix" -I"/OpenSSL/include" -I"/wxWidgets/lib/vc_lib/mswd" -I"/wxWidgets/include" -LIBPATHS=-L"/DB/build_unix" -L"/OpenSSL/out" -L"/wxWidgets/lib/gcc_lib" +INCLUDEPATHS=-I"/boost" -I"/db/build_unix" -I"/openssl/include" -I"/wxwidgets/lib/vc_lib/mswd" -I"/wxwidgets/include" +LIBPATHS=-L"/db/build_unix" -L"/openssl/out" -L"/wxwidgets/lib/gcc_lib" LIBS= \ -l db_cxx \ -l eay32 \ diff --git a/net.cpp b/net.cpp index db138e13a5..22b84f9dee 100644 --- a/net.cpp +++ b/net.cpp @@ -8,6 +8,7 @@ void ThreadMessageHandler2(void* parg); void ThreadSocketHandler2(void* parg); void ThreadOpenConnections2(void* parg); +bool OpenNetworkConnection(const CAddress& addrConnect); @@ -22,8 +23,10 @@ uint64 nLocalServices = (fClient ? 0 : NODE_NETWORK); CAddress addrLocalHost(0, DEFAULT_PORT, nLocalServices); CNode nodeLocalHost(INVALID_SOCKET, CAddress("127.0.0.1", nLocalServices)); CNode* pnodeLocalHost = &nodeLocalHost; +uint64 nLocalHostNonce = 0; bool fShutdown = false; array vnThreadsRunning; +SOCKET hListenSocket = INVALID_SOCKET; vector vNodes; CCriticalSection cs_vNodes; @@ -34,9 +37,11 @@ deque > vRelayExpiration; CCriticalSection cs_mapRelay; map mapAlreadyAskedFor; +// Settings +int fUseProxy = false; +CAddress addrProxy("127.0.0.1:9050"); -CAddress addrProxy; bool ConnectSocket(const CAddress& addrConnect, SOCKET& hSocketRet) { @@ -47,7 +52,7 @@ bool ConnectSocket(const CAddress& addrConnect, SOCKET& hSocketRet) return false; bool fRoutable = !(addrConnect.GetByte(3) == 10 || (addrConnect.GetByte(3) == 192 && addrConnect.GetByte(2) == 168)); - bool fProxy = (addrProxy.ip && fRoutable); + bool fProxy = (fUseProxy && fRoutable); struct sockaddr_in sockaddr = (fProxy ? addrProxy.GetSockAddr() : addrConnect.GetSockAddr()); if (connect(hSocket, (struct sockaddr*)&sockaddr, sizeof(sockaddr)) == SOCKET_ERROR) @@ -69,18 +74,18 @@ bool ConnectSocket(const CAddress& addrConnect, SOCKET& hSocketRet) if (ret != nSize) { closesocket(hSocket); - return error("Error sending to proxy\n"); + return error("Error sending to proxy"); } char pchRet[8]; if (recv(hSocket, pchRet, 8, 0) != 8) { closesocket(hSocket); - return error("Error reading proxy response\n"); + return error("Error reading proxy response"); } if (pchRet[1] != 0x5a) { closesocket(hSocket); - return error("Proxy returned error %d\n", pchRet[1]); + return error("Proxy returned error %d", pchRet[1]); } printf("Proxy connection established %s\n", addrConnect.ToStringLog().c_str()); } @@ -95,7 +100,7 @@ bool GetMyExternalIP2(const CAddress& addrConnect, const char* pszGet, const cha { SOCKET hSocket; if (!ConnectSocket(addrConnect, hSocket)) - return error("GetMyExternalIP() : connection to %s failed\n", addrConnect.ToString().c_str()); + return error("GetMyExternalIP() : connection to %s failed", addrConnect.ToString().c_str()); send(hSocket, pszGet, strlen(pszGet), 0); @@ -131,7 +136,7 @@ bool GetMyExternalIP2(const CAddress& addrConnect, const char* pszGet, const cha } } closesocket(hSocket); - return error("GetMyExternalIP() : connection closed\n"); + return error("GetMyExternalIP() : connection closed"); } @@ -141,6 +146,9 @@ bool GetMyExternalIP(unsigned int& ipRet) char* pszGet; char* pszKeyword; + if (fUseProxy) + return false; + for (int nLookup = 0; nLookup <= 1; nLookup++) for (int nHost = 1; nHost <= 2; nHost++) { @@ -416,14 +424,14 @@ CNode* ConnectNode(CAddress addrConnect, int64 nTimeout) } } -void CNode::Disconnect() +void CNode::DoDisconnect() { printf("disconnecting node %s\n", addr.ToStringLog().c_str()); closesocket(hSocket); // If outbound and never got version message, mark address as failed - if (!fInbound && nVersion == 0) + if (!fInbound && !fSuccessfullyConnected) CRITICAL_BLOCK(cs_mapAddresses) mapAddresses[addr.GetKey()].nLastFailed = GetTime(); @@ -458,18 +466,18 @@ void ThreadSocketHandler(void* parg) loop { - vnThreadsRunning[0] = true; + vnThreadsRunning[0]++; CheckForShutdown(0); try { ThreadSocketHandler2(parg); - vnThreadsRunning[0] = false; + vnThreadsRunning[0]--; } catch (std::exception& e) { - vnThreadsRunning[0] = false; + vnThreadsRunning[0]--; PrintException(&e, "ThreadSocketHandler()"); } catch (...) { - vnThreadsRunning[0] = false; + vnThreadsRunning[0]--; PrintException(NULL, "ThreadSocketHandler()"); } Sleep(5000); @@ -479,7 +487,6 @@ void ThreadSocketHandler(void* parg) void ThreadSocketHandler2(void* parg) { printf("ThreadSocketHandler started\n"); - SOCKET hListenSocket = *(SOCKET*)parg; list vNodesDisconnected; int nPrevNodeCount = 0; @@ -498,7 +505,7 @@ void ThreadSocketHandler2(void* parg) { // remove from vNodes vNodes.erase(remove(vNodes.begin(), vNodes.end(), pnode), vNodes.end()); - pnode->Disconnect(); + pnode->DoDisconnect(); // hold in disconnected pool until all refs are released pnode->nReleaseTime = max(pnode->nReleaseTime, GetTime() + 5 * 60); @@ -562,9 +569,9 @@ void ThreadSocketHandler2(void* parg) } } - vnThreadsRunning[0] = false; + vnThreadsRunning[0]--; int nSelect = select(hSocketMax + 1, &fdsetRecv, &fdsetSend, NULL, &timeout); - vnThreadsRunning[0] = true; + vnThreadsRunning[0]++; CheckForShutdown(0); if (nSelect == SOCKET_ERROR) { @@ -577,7 +584,6 @@ void ThreadSocketHandler2(void* parg) } Sleep(timeout.tv_usec/1000); } - RandAddSeed(); //// debug print //foreach(CNode* pnode, vNodes) @@ -711,18 +717,18 @@ void ThreadOpenConnections(void* parg) loop { - vnThreadsRunning[1] = true; + vnThreadsRunning[1]++; CheckForShutdown(1); try { ThreadOpenConnections2(parg); - vnThreadsRunning[1] = false; + vnThreadsRunning[1]--; } catch (std::exception& e) { - vnThreadsRunning[1] = false; + vnThreadsRunning[1]--; PrintException(&e, "ThreadOpenConnections()"); } catch (...) { - vnThreadsRunning[1] = false; + vnThreadsRunning[1]--; PrintException(NULL, "ThreadOpenConnections()"); } Sleep(5000); @@ -733,6 +739,13 @@ void ThreadOpenConnections2(void* parg) { printf("ThreadOpenConnections started\n"); + // Connect to one specified address + while (mapArgs.count("/connect")) + { + OpenNetworkConnection(CAddress(mapArgs["/connect"].c_str())); + Sleep(10000); + } + // Initiate network connections int nTry = 0; bool fIRCOnly = false; @@ -740,14 +753,14 @@ void ThreadOpenConnections2(void* parg) loop { // Wait - vnThreadsRunning[1] = false; + vnThreadsRunning[1]--; Sleep(500); while (vNodes.size() >= nMaxConnections || vNodes.size() >= mapAddresses.size()) { CheckForShutdown(1); Sleep(2000); } - vnThreadsRunning[1] = true; + vnThreadsRunning[1]++; CheckForShutdown(1); @@ -835,43 +848,48 @@ void ThreadOpenConnections2(void* parg) // Once we've chosen an IP, we'll try every given port before moving on foreach(const CAddress& addrConnect, (*mi).second) - { - // - // Initiate outbound network connection - // - CheckForShutdown(1); - if (addrConnect.ip == addrLocalHost.ip || !addrConnect.IsIPv4() || FindNode(addrConnect.ip)) - continue; + if (OpenNetworkConnection(addrConnect)) + break; + } +} - vnThreadsRunning[1] = false; - CNode* pnode = ConnectNode(addrConnect); - vnThreadsRunning[1] = true; - CheckForShutdown(1); - if (!pnode) - continue; - pnode->fNetworkNode = true; +bool OpenNetworkConnection(const CAddress& addrConnect) +{ + // + // Initiate outbound network connection + // + CheckForShutdown(1); + if (addrConnect.ip == addrLocalHost.ip || !addrConnect.IsIPv4() || FindNode(addrConnect.ip)) + return false; - if (addrLocalHost.IsRoutable()) - { - // Advertise our address - vector vAddrToSend; - vAddrToSend.push_back(addrLocalHost); - pnode->PushMessage("addr", vAddrToSend); - } + vnThreadsRunning[1]--; + CNode* pnode = ConnectNode(addrConnect); + vnThreadsRunning[1]++; + CheckForShutdown(1); + if (!pnode) + return false; + pnode->fNetworkNode = true; - // Get as many addresses as we can - pnode->PushMessage("getaddr"); + if (addrLocalHost.IsRoutable() && !fUseProxy) + { + // Advertise our address + vector vAddrToSend; + vAddrToSend.push_back(addrLocalHost); + pnode->PushMessage("addr", vAddrToSend); + } - ////// should the one on the receiving end do this too? - // Subscribe our local subscription list - const unsigned int nHops = 0; - for (unsigned int nChannel = 0; nChannel < pnodeLocalHost->vfSubscribe.size(); nChannel++) - if (pnodeLocalHost->vfSubscribe[nChannel]) - pnode->PushMessage("subscribe", nChannel, nHops); + // Get as many addresses as we can + pnode->PushMessage("getaddr"); + pnode->fGetAddr = true; // don't relay the results of the getaddr - break; - } - } + ////// should the one on the receiving end do this too? + // Subscribe our local subscription list + const unsigned int nHops = 0; + for (unsigned int nChannel = 0; nChannel < pnodeLocalHost->vfSubscribe.size(); nChannel++) + if (pnodeLocalHost->vfSubscribe[nChannel]) + pnode->PushMessage("subscribe", nChannel, nHops); + + return true; } @@ -887,18 +905,18 @@ void ThreadMessageHandler(void* parg) loop { - vnThreadsRunning[2] = true; + vnThreadsRunning[2]++; CheckForShutdown(2); try { ThreadMessageHandler2(parg); - vnThreadsRunning[2] = false; + vnThreadsRunning[2]--; } catch (std::exception& e) { - vnThreadsRunning[2] = false; + vnThreadsRunning[2]--; PrintException(&e, "ThreadMessageHandler()"); } catch (...) { - vnThreadsRunning[2] = false; + vnThreadsRunning[2]--; PrintException(NULL, "ThreadMessageHandler()"); } Sleep(5000); @@ -931,9 +949,9 @@ void ThreadMessageHandler2(void* parg) } // Wait and allow messages to bunch up - vnThreadsRunning[2] = false; + vnThreadsRunning[2]--; Sleep(100); - vnThreadsRunning[2] = true; + vnThreadsRunning[2]++; CheckForShutdown(2); } } @@ -982,7 +1000,7 @@ bool StartNode(string& strError) printf("addrLocalHost = %s\n", addrLocalHost.ToString().c_str()); // Create socket for listening for incoming connections - SOCKET hListenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + hListenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (hListenSocket == INVALID_SOCKET) { strError = strprintf("Error: Couldn't open socket for incoming connections (socket returned error %d)", WSAGetLastError()); @@ -1024,13 +1042,21 @@ bool StartNode(string& strError) } // Get our external IP address for incoming connections - if (addrIncoming.ip) - addrLocalHost.ip = addrIncoming.ip; - - if (GetMyExternalIP(addrLocalHost.ip)) + if (fUseProxy) { - addrIncoming = addrLocalHost; - CWalletDB().WriteSetting("addrIncoming", addrIncoming); + // Proxies can't take incoming connections + addrLocalHost.ip = CAddress("0.0.0.0").ip; + } + else + { + if (addrIncoming.ip) + addrLocalHost.ip = addrIncoming.ip; + + if (GetMyExternalIP(addrLocalHost.ip)) + { + addrIncoming = addrLocalHost; + CWalletDB().WriteSetting("addrIncoming", addrIncoming); + } } // Get addresses from IRC and advertise ours @@ -1040,7 +1066,7 @@ bool StartNode(string& strError) // // Start threads // - if (_beginthread(ThreadSocketHandler, 0, new SOCKET(hListenSocket)) == -1) + if (_beginthread(ThreadSocketHandler, 0, NULL) == -1) { strError = "Error: _beginthread(ThreadSocketHandler) failed"; printf("%s\n", strError.c_str()); @@ -1094,10 +1120,15 @@ void CheckForShutdown(int n) if (fShutdown) { if (n != -1) - vnThreadsRunning[n] = false; + if (--vnThreadsRunning[n] < 0) + vnThreadsRunning[n] = 0; if (n == 0) + { foreach(CNode* pnode, vNodes) closesocket(pnode->hSocket); + closesocket(hListenSocket); + } + printf("Thread %d exiting\n", n); _endthread(); } } diff --git a/net.h b/net.h index 334100422f..a0b2929daa 100644 --- a/net.h +++ b/net.h @@ -174,7 +174,7 @@ public: { nServices = nServicesIn; memcpy(pchReserved, pchIPv4, sizeof(pchReserved)); - ip = 0; + ip = INADDR_NONE; port = DEFAULT_PORT; nTime = GetAdjustedTime(); nLastFailed = 0; @@ -183,7 +183,7 @@ public: if (strlen(pszIn) > ARRAYLEN(psz)-1) return; strcpy(psz, pszIn); - unsigned int a, b, c, d, e; + unsigned int a=0, b=0, c=0, d=0, e=0; if (sscanf(psz, "%u.%u.%u.%u:%u", &a, &b, &c, &d, &e) < 4) return; char* pszPort = strchr(psz, ':'); @@ -191,6 +191,10 @@ public: { *pszPort++ = '\0'; port = htons(atoi(pszPort)); + if (atoi(pszPort) > USHRT_MAX) + port = htons(USHRT_MAX); + if (atoi(pszPort) < 0) + port = htons(0); } ip = inet_addr(psz); } @@ -215,6 +219,11 @@ public: 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)); @@ -277,6 +286,11 @@ public: return strprintf("%u.%u.%u.%u", GetByte(3), GetByte(2), GetByte(1), GetByte(0)); } + string ToStringPort() const + { + return strprintf("%u", ntohs(port)); + } + string ToStringLog() const { return ""; @@ -416,6 +430,7 @@ extern bool fClient; extern uint64 nLocalServices; extern CAddress addrLocalHost; extern CNode* pnodeLocalHost; +extern uint64 nLocalHostNonce; extern bool fShutdown; extern array vnThreadsRunning; extern vector vNodes; @@ -426,6 +441,9 @@ extern map mapRelay; extern deque > vRelayExpiration; extern CCriticalSection cs_mapRelay; extern map mapAlreadyAskedFor; + +// Settings +extern int fUseProxy; extern CAddress addrProxy; @@ -448,6 +466,7 @@ public: bool fClient; bool fInbound; bool fNetworkNode; + bool fSuccessfullyConnected; bool fDisconnect; protected: int nRefCount; @@ -459,6 +478,7 @@ public: // flood vector vAddrToSend; set setAddrKnown; + bool fGetAddr; // inventory based relay set setInventoryKnown; @@ -483,15 +503,20 @@ public: fClient = false; // set by version message fInbound = fInboundIn; fNetworkNode = false; + fSuccessfullyConnected = false; fDisconnect = false; nRefCount = 0; nReleaseTime = 0; + fGetAddr = false; vfSubscribe.assign(256, false); // Push a version message /// when NTP implemented, change to just nTime = GetAdjustedTime() int64 nTime = (fInbound ? GetAdjustedTime() : GetTime()); - PushMessage("version", VERSION, nLocalServices, nTime, addr); + CAddress addrYou = (fUseProxy ? CAddress("0.0.0.0") : addr); + CAddress addrMe = (fUseProxy ? CAddress("0.0.0.0") : addrLocalHost); + RAND_bytes((unsigned char*)&nLocalHostNonce, sizeof(nLocalHostNonce)); + PushMessage("version", VERSION, nLocalServices, nTime, addrYou, addrMe, nLocalHostNonce); } ~CNode() @@ -531,6 +556,21 @@ public: + void AddAddressKnown(const CAddress& addr) + { + setAddrKnown.insert(addr); + } + + void PushAddress(const CAddress& addr) + { + // Known checking here is only to save space from duplicates. + // SendMessages will filter it again for knowns that were added + // after addresses were pushed. + if (!setAddrKnown.count(addr)) + vAddrToSend.push_back(addr); + } + + void AddInventoryKnown(const CInv& inv) { CRITICAL_BLOCK(cs_inventory) @@ -562,7 +602,6 @@ public: } - void BeginMessage(const char* pszCommand) { EnterCriticalSection(&cs_vSend); @@ -570,7 +609,7 @@ public: AbortMessage(); nPushPos = vSend.size(); vSend << CMessageHeader(pszCommand, 0); - printf("sending: %-12s ", pszCommand); + printf("sending: %s ", pszCommand); } void AbortMessage() @@ -706,6 +745,86 @@ public: } } + template + void PushMessage(const char* pszCommand, const T1& a1, const T2& a2, const T3& a3, const T4& a4, const T5& a5) + { + try + { + BeginMessage(pszCommand); + vSend << a1 << a2 << a3 << a4 << a5; + EndMessage(); + } + catch (...) + { + AbortMessage(); + throw; + } + } + + template + void PushMessage(const char* pszCommand, const T1& a1, const T2& a2, const T3& a3, const T4& a4, const T5& a5, const T6& a6) + { + try + { + BeginMessage(pszCommand); + vSend << a1 << a2 << a3 << a4 << a5 << a6; + EndMessage(); + } + catch (...) + { + AbortMessage(); + throw; + } + } + + template + void PushMessage(const char* pszCommand, const T1& a1, const T2& a2, const T3& a3, const T4& a4, const T5& a5, const T6& a6, const T7& a7) + { + try + { + BeginMessage(pszCommand); + vSend << a1 << a2 << a3 << a4 << a5 << a6 << a7; + EndMessage(); + } + catch (...) + { + AbortMessage(); + throw; + } + } + + template + void PushMessage(const char* pszCommand, const T1& a1, const T2& a2, const T3& a3, const T4& a4, const T5& a5, const T6& a6, const T7& a7, const T8& a8) + { + try + { + BeginMessage(pszCommand); + vSend << a1 << a2 << a3 << a4 << a5 << a6 << a7 << a8; + EndMessage(); + } + catch (...) + { + AbortMessage(); + throw; + } + } + + template + void PushMessage(const char* pszCommand, const T1& a1, const T2& a2, const T3& a3, const T4& a4, const T5& a5, const T6& a6, const T7& a7, const T8& a8, const T9& a9) + { + try + { + BeginMessage(pszCommand); + vSend << a1 << a2 << a3 << a4 << a5 << a6 << a7 << a8 << a9; + EndMessage(); + } + catch (...) + { + AbortMessage(); + throw; + } + } + void PushRequest(const char* pszCommand, void (*fn)(void*, CDataStream&), void* param1) @@ -750,7 +869,7 @@ public: bool IsSubscribed(unsigned int nChannel); void Subscribe(unsigned int nChannel, unsigned int nHops=0); void CancelSubscribe(unsigned int nChannel); - void Disconnect(); + void DoDisconnect(); }; diff --git a/serialize.h b/serialize.h index b7ab86d22a..9b20e2a0f6 100644 --- a/serialize.h +++ b/serialize.h @@ -19,7 +19,7 @@ class CScript; class CDataStream; class CAutoFile; -static const int VERSION = 105; +static const int VERSION = 106; diff --git a/strlcpy.h b/strlcpy.h new file mode 100644 index 0000000000..a79ee1756c --- /dev/null +++ b/strlcpy.h @@ -0,0 +1,84 @@ +/* + * Copyright (c) 1998 Todd C. Miller + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * Copy src to string dst of size siz. At most siz-1 characters + * will be copied. Always NUL terminates (unless siz == 0). + * Returns strlen(src); if retval >= siz, truncation occurred. + */ +inline size_t strlcpy(char *dst, const char *src, size_t siz) +{ + char *d = dst; + const char *s = src; + size_t n = siz; + + /* Copy as many bytes as will fit */ + if (n != 0) + { + while (--n != 0) + { + if ((*d++ = *s++) == '\0') + break; + } + } + + /* Not enough room in dst, add NUL and traverse rest of src */ + if (n == 0) + { + if (siz != 0) + *d = '\0'; /* NUL-terminate dst */ + while (*s++) + ; + } + + return(s - src - 1); /* count does not include NUL */ +} + +/* + * Appends src to string dst of size siz (unlike strncat, siz is the + * full size of dst, not space left). At most siz-1 characters + * will be copied. Always NUL terminates (unless siz <= strlen(dst)). + * Returns strlen(src) + MIN(siz, strlen(initial dst)). + * If retval >= siz, truncation occurred. + */ +inline size_t strlcat(char *dst, const char *src, size_t siz) +{ + char *d = dst; + const char *s = src; + size_t n = siz; + size_t dlen; + + /* Find the end of dst and adjust bytes left but don't go past end */ + while (n-- != 0 && *d != '\0') + d++; + dlen = d - dst; + n = siz - dlen; + + if (n == 0) + return(dlen + strlen(s)); + while (*s != '\0') + { + if (n != 1) + { + *d++ = *s; + n--; + } + s++; + } + *d = '\0'; + + return(dlen + (s - src)); /* count does not include NUL */ +} diff --git a/ui.cpp b/ui.cpp index 428304796e..917c64b445 100644 --- a/ui.cpp +++ b/ui.cpp @@ -497,7 +497,7 @@ string SingleLine(const string& strIn) return strOut; } -void CMainFrame::InsertTransaction(const CWalletTx& wtx, bool fNew, int nIndex) +bool CMainFrame::InsertTransaction(const CWalletTx& wtx, bool fNew, int nIndex) { int64 nTime = wtx.nTimeDisplayed = wtx.GetTxTime(); int64 nCredit = wtx.GetCredit(); @@ -506,14 +506,11 @@ void CMainFrame::InsertTransaction(const CWalletTx& wtx, bool fNew, int nIndex) uint256 hash = wtx.GetHash(); string strStatus = FormatTxStatus(wtx); map mapValue = wtx.mapValue; + wtx.nLinesDisplayed = 1; // Filter if (wtx.IsCoinBase()) { - // View->Show Generated - if (!fShowGenerated) - return; - // 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. // @@ -527,10 +524,13 @@ void CMainFrame::InsertTransaction(const CWalletTx& wtx, bool fNew, int nIndex) // if (wtx.GetDepthInMainChain() < 2) { - // In case it was previously displayed - DeleteLine(hash); - return; + wtx.nLinesDisplayed = 0; + return false; } + + // View->Show Generated + if (!fShowGenerated) + return false; } // Find the block the tx is in @@ -644,6 +644,7 @@ void CMainFrame::InsertTransaction(const CWalletTx& wtx, bool fNew, int nIndex) // Debit // int64 nTxFee = nDebit - wtx.GetValueOut(); + wtx.nLinesDisplayed = 0; for (int nOut = 0; nOut < wtx.vout.size(); nOut++) { const CTxOut& txout = wtx.vout[nOut]; @@ -685,6 +686,7 @@ void CMainFrame::InsertTransaction(const CWalletTx& wtx, bool fNew, int nIndex) SingleLine(strDescription), FormatMoney(-nValue, true), ""); + wtx.nLinesDisplayed++; } } else @@ -706,12 +708,14 @@ void CMainFrame::InsertTransaction(const CWalletTx& wtx, bool fNew, int nIndex) ""); } } + + return true; } void CMainFrame::RefreshStatus() { static int nLastTop; - int nTop = m_listCtrl->GetTopItem(); + int nTop = max((int)m_listCtrl->GetTopItem(), 0); if (nTop == nLastTop && pindexBestLast == pindexBest) return; @@ -729,7 +733,7 @@ void CMainFrame::RefreshStatus() nLastTop = nTop; pindexBestLast = pindexBest; - for (int nIndex = nStart; nIndex < nEnd; nIndex++) + for (int nIndex = nStart; nIndex < min(nEnd, m_listCtrl->GetItemCount()); nIndex++) { uint256 hash((string)GetItemText(m_listCtrl, nIndex, 1)); map::iterator mi = mapWallet.find(hash); @@ -738,9 +742,12 @@ void CMainFrame::RefreshStatus() printf("CMainFrame::RefreshStatus() : tx not found in mapWallet\n"); continue; } - const CWalletTx& wtx = (*mi).second; + CWalletTx& wtx = (*mi).second; if (wtx.IsCoinBase() || wtx.GetTxTime() != wtx.nTimeDisplayed) - InsertTransaction(wtx, false, nIndex); + { + if (!InsertTransaction(wtx, false, nIndex)) + m_listCtrl->DeleteItem(nIndex--); + } else m_listCtrl->SetItem(nIndex, 2, FormatTxStatus(wtx)); } @@ -801,6 +808,9 @@ void CMainFrame::OnIdle(wxIdleEvent& event) } printf("RefreshListCtrl done\n"); + + // Update transaction total display + MainFrameRepaint(); } else { @@ -834,31 +844,54 @@ void DelayedRepaint(void* parg) return; fOneThread = true; Sleep(1000); + printf("DelayedRepaint()\n"); MainFrameRepaint(); fOneThread = false; } void CMainFrame::OnPaintListCtrl(wxPaintEvent& event) { + if (ptaskbaricon) + ptaskbaricon->UpdateTooltip(); + // Update listctrl contents if (!vWalletUpdated.empty()) { TRY_CRITICAL_BLOCK(cs_mapWallet) { + bool fInserted = false; foreach(uint256 hash, vWalletUpdated) { map::iterator mi = mapWallet.find(hash); if (mi != mapWallet.end()) - InsertTransaction((*mi).second, false); + fInserted |= InsertTransaction((*mi).second, false); } - m_listCtrl->ScrollList(0, INT_MAX); vWalletUpdated.clear(); + if (fInserted) + m_listCtrl->ScrollList(0, INT_MAX); } } // Update status column of visible items only RefreshStatus(); + // Balance total + bool fRefreshed = false; + static int nTransactionCount; + TRY_CRITICAL_BLOCK(cs_mapWallet) + { + fRefreshed = true; + m_staticTextBalance->SetLabel(FormatMoney(GetBalance()) + " "); + + // Count hidden and multi-line transactions + nTransactionCount = 0; + for (map::iterator it = mapWallet.begin(); it != mapWallet.end(); ++it) + { + CWalletTx& wtx = (*it).second; + nTransactionCount += wtx.nLinesDisplayed; + } + } + // Update status bar string strGen = ""; if (fGenerateBitcoins) @@ -867,17 +900,9 @@ void CMainFrame::OnPaintListCtrl(wxPaintEvent& event) strGen = "(not connected)"; m_statusBar->SetStatusText(strGen, 1); - string strStatus = strprintf(" %d connections %d blocks %d transactions", vNodes.size(), nBestHeight + 1, m_listCtrl->GetItemCount()); + string strStatus = strprintf(" %d connections %d blocks %d transactions", vNodes.size(), nBestHeight + 1, nTransactionCount); m_statusBar->SetStatusText(strStatus, 2); - // Balance total - bool fRefreshed = false; - TRY_CRITICAL_BLOCK(cs_mapWallet) - { - m_staticTextBalance->SetLabel(FormatMoney(GetBalance()) + " "); - fRefreshed = true; - } - // mapWallet was locked, try again later if (!vWalletUpdated.empty() || !fRefreshed) _beginthread(DelayedRepaint, 0, NULL); @@ -1350,6 +1375,14 @@ COptionsDialog::COptionsDialog(wxWindow* parent) : COptionsDialogBase(parent) m_checkBoxMinimizeOnClose->Enable(fMinimizeToTray); m_checkBoxMinimizeOnClose->SetValue(fMinimizeToTray && fMinimizeOnClose); fTmpMinimizeOnClose = fMinimizeOnClose; + 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(); } @@ -1395,6 +1428,34 @@ void COptionsDialog::OnCheckBoxMinimizeToTray(wxCommandEvent& event) } +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) +{ + m_textCtrlProxyIP->SetValue(GetProxyAddr().ToStringIP()); + m_textCtrlProxyPort->SetValue(GetProxyAddr().ToStringPort()); +} + + void COptionsDialog::OnButtonOK(wxCommandEvent& event) { OnButtonApply(event); @@ -1446,6 +1507,18 @@ void COptionsDialog::OnButtonApply(wxCommandEvent& event) fMinimizeOnClose = (fMinimizeToTray ? m_checkBoxMinimizeOnClose->GetValue() : fTmpMinimizeOnClose); walletdb.WriteSetting("fMinimizeOnClose", fMinimizeOnClose); } + + if (fUseProxy != m_checkBoxUseProxy->GetValue()) + { + fUseProxy = m_checkBoxUseProxy->GetValue(); + walletdb.WriteSetting("fUseProxy", fUseProxy); + } + + if (addrProxy != GetProxyAddr()) + { + addrProxy = GetProxyAddr(); + walletdb.WriteSetting("addrProxy", addrProxy); + } } @@ -1657,7 +1730,7 @@ CSendingDialog::CSendingDialog(wxWindow* parent, const CAddress& addrIn, int64 n nPrice = nPriceIn; wtx = wtxIn; start = wxDateTime::UNow(); - strStatus = ""; + memset(pszStatus, 0, sizeof(pszStatus)); fCanCancel = true; fAbort = false; fSuccess = false; @@ -1721,10 +1794,10 @@ void CSendingDialog::OnButtonCancel(wxCommandEvent& event) void CSendingDialog::OnPaint(wxPaintEvent& event) { - if (strStatus.size() > 130) - m_textCtrlStatus->SetValue(string("\n") + strStatus); + if (strlen(pszStatus) > 130) + m_textCtrlStatus->SetValue(string("\n") + pszStatus); else - m_textCtrlStatus->SetValue(string("\n\n") + strStatus); + m_textCtrlStatus->SetValue(string("\n\n") + pszStatus); m_staticTextSending->SetFocus(); if (!fCanCancel) m_buttonCancel->Enable(false); @@ -1736,7 +1809,7 @@ void CSendingDialog::OnPaint(wxPaintEvent& event) } if (fAbort && fCanCancel && IsShown()) { - strStatus = "CANCELLED"; + strcpy(pszStatus, "CANCELLED"); m_buttonOK->Enable(true); m_buttonOK->SetFocus(); m_buttonCancel->Enable(false); @@ -1777,7 +1850,8 @@ bool CSendingDialog::Status() } if (fAbort && fCanCancel) { - strStatus = "CANCELLED"; + memset(pszStatus, 0, 10); + strcpy(pszStatus, "CANCELLED"); Repaint(); fWorkDone = true; return false; @@ -1789,7 +1863,12 @@ bool CSendingDialog::Status(const string& str) { if (!Status()) return false; - strStatus = str; + + // 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; } @@ -1950,8 +2029,8 @@ void CSendingDialog::OnReply3(CDataStream& vRecv) 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 if it is valid,\n" - "but without comment information."); + "The transaction is recorded and will credit to the recipient,\n" + "but the comment information will be blank."); return; } } @@ -3092,6 +3171,7 @@ END_EVENT_TABLE() void CMyTaskBarIcon::Show(bool fShow) { + static char pszPrevTip[200]; if (fShow) { string strTooltip = "Bitcoin"; @@ -3099,10 +3179,17 @@ void CMyTaskBarIcon::Show(bool fShow) strTooltip = "Bitcoin - Generating"; if (fGenerateBitcoins && vNodes.empty()) strTooltip = "Bitcoin - (not connected)"; - SetIcon(wxICON(bitcoin), strTooltip); + + // 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)); + SetIcon(wxICON(bitcoin), strTooltip); + } } else { + strlcpy(pszPrevTip, "", sizeof(pszPrevTip)); RemoveIcon(); } } @@ -3301,12 +3388,12 @@ bool CMyApp::OnInit2() if (mapArgs.count("/datadir")) strSetDataDir = mapArgs["/datadir"]; - if (mapArgs.count("/proxy")) - addrProxy = CAddress(mapArgs["/proxy"].c_str()); - if (mapArgs.count("/debug")) fDebug = true; + if (mapArgs.count("/printtodebugger")) + fPrintToDebugger = true; + if (mapArgs.count("/dropmessages")) { nDropMessagesTest = atoi(mapArgs["/dropmessages"]); @@ -3380,6 +3467,20 @@ bool CMyApp::OnInit2() return false; } + if (mapArgs.count("/proxy")) + { + fUseProxy = true; + addrProxy = CAddress(mapArgs["/proxy"].c_str()); + if (addrProxy.ip == INADDR_NONE) + { + wxMessageBox("Invalid /proxy address", "Bitcoin"); + OnExit(); + } + CWalletDB walletdb; + walletdb.WriteSetting("fUseProxy", fUseProxy); + walletdb.WriteSetting("addrProxy", addrProxy); + } + if (mapArgs.count("/gen")) { if (mapArgs["/gen"].empty()) @@ -3404,7 +3505,7 @@ bool CMyApp::OnInit2() return false; } - //RandAddSeedPerfmon(); + RandAddSeedPerfmon(); if (!StartNode(strErrors)) wxMessageBox(strErrors, "Bitcoin"); @@ -3514,7 +3615,7 @@ void CMyApp::OnFatalException() void MainFrameRepaint() { - // This is called by network code that shouldn't access pframeMain and ptaskbaricon + // 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) { @@ -3523,20 +3624,47 @@ void MainFrameRepaint() pframeMain->Refresh(); pframeMain->AddPendingEvent(event); } - if (ptaskbaricon) - ptaskbaricon->UpdateTooltip(); } +typedef WINSHELLAPI BOOL WINAPI (*PSHGETSPECIALFOLDERPATHA)(HWND hwndOwner, LPSTR lpszPath, int nFolder, BOOL fCreate); + +string MyGetSpecialFolderPath(int nFolder, bool fCreate) +{ + char pszPath[MAX_PATH+100] = ""; + + // SHGetSpecialFolderPath is not usually available on NT 4.0 + HMODULE hShell32 = LoadLibrary("shell32.dll"); + if (hShell32) + { + PSHGETSPECIALFOLDERPATHA pSHGetSpecialFolderPath = + (PSHGETSPECIALFOLDERPATHA)GetProcAddress(hShell32, "SHGetSpecialFolderPathA"); + if (pSHGetSpecialFolderPath) + (*pSHGetSpecialFolderPath)(NULL, pszPath, nFolder, fCreate); + FreeModule(hShell32); + } + + // Backup option + if (pszPath[0] == '\0') + { + if (nFolder == CSIDL_STARTUP) + { + strcpy(pszPath, getenv("USERPROFILE")); + strcat(pszPath, "\\Start Menu\\Programs\\Startup"); + } + else if (nFolder == CSIDL_APPDATA) + { + strcpy(pszPath, getenv("APPDATA")); + } + } + + return pszPath; +} + string StartupShortcutPath() { - // Get the startup folder shortcut path - char pszLinkPath[MAX_PATH+100]; - pszLinkPath[0] = '\0'; - SHGetSpecialFolderPath(0, pszLinkPath, CSIDL_STARTUP, 0); - strcat(pszLinkPath, "\\Bitcoin.lnk"); - return pszLinkPath; + return MyGetSpecialFolderPath(CSIDL_STARTUP, true) + "\\Bitcoin.lnk"; } bool GetStartOnSystemStartup() @@ -3630,7 +3758,8 @@ void ThreadRandSendTest(void* parg) if (GetBalance() < nValue) { wxMessageBox("Out of money "); - return; + while (GetBalance() < 1000) + Sleep(1000); } nValue += (nRep % 100) * CENT; diff --git a/ui.h b/ui.h index f451d93565..9fc7e0ebe7 100644 --- a/ui.h +++ b/ui.h @@ -89,7 +89,7 @@ public: void OnCrossThreadCall(wxCommandEvent& event); void InsertLine(bool fNew, int nIndex, uint256 hashKey, string strSort, const wxString& str1, const wxString& str2, const wxString& str3, const wxString& str4, const wxString& str5); bool DeleteLine(uint256 hashKey); - void InsertTransaction(const CWalletTx& wtx, bool fNew, int nIndex=-1); + bool InsertTransaction(const CWalletTx& wtx, bool fNew, int nIndex=-1); void RefreshListCtrl(); void RefreshStatus(); }; @@ -121,6 +121,9 @@ protected: void OnKillFocusTransactionFee(wxFocusEvent& event); void OnCheckBoxLimitProcessors(wxCommandEvent& event); void OnCheckBoxMinimizeToTray(wxCommandEvent& event); + void OnCheckBoxUseProxy(wxCommandEvent& event); + void OnKillFocusProxy(wxFocusEvent& event); + void OnButtonOK(wxCommandEvent& event); void OnButtonCancel(wxCommandEvent& event); void OnButtonApply(wxCommandEvent& event); @@ -133,6 +136,7 @@ public: bool fTmpStartOnSystemStartup; bool fTmpMinimizeOnClose; void SelectPage(int nPage); + CAddress GetProxyAddr(); }; @@ -193,7 +197,7 @@ public: int64 nPrice; CWalletTx wtx; wxDateTime start; - string strStatus; + char pszStatus[10000]; bool fCanCancel; bool fAbort; bool fSuccess; diff --git a/uibase.cpp b/uibase.cpp index 0f9e22c528..b03e578bd8 100644 --- a/uibase.cpp +++ b/uibase.cpp @@ -380,7 +380,7 @@ COptionsDialogBase::COptionsDialogBase( wxWindow* parent, wxWindowID id, const w bSizer69 = new wxBoxSizer( wxVERTICAL ); - bSizer69->Add( 0, 14, 0, wxEXPAND, 5 ); + bSizer69->Add( 0, 16, 0, wxEXPAND, 5 ); m_staticText32 = new wxStaticText( m_panelMain, wxID_ANY, wxT("Optional transaction fee you give to the nodes that process your transactions."), wxDefaultPosition, wxDefaultSize, 0 ); m_staticText32->Wrap( -1 ); @@ -412,7 +412,7 @@ COptionsDialogBase::COptionsDialogBase( wxWindow* parent, wxWindowID id, const w bSizer71->Add( m_checkBoxLimitProcessors, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 ); m_spinCtrlLimitProcessors = new wxSpinCtrl( m_panelMain, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize( 48,-1 ), wxSP_ARROW_KEYS, 1, 999, 1 ); - bSizer71->Add( m_spinCtrlLimitProcessors, 0, wxTOP|wxBOTTOM, 5 ); + bSizer71->Add( m_spinCtrlLimitProcessors, 0, wxALIGN_CENTER_VERTICAL, 5 ); m_staticText35 = new wxStaticText( m_panelMain, wxID_ANY, wxT("processors"), wxDefaultPosition, wxDefaultSize, 0 ); m_staticText35->Wrap( -1 ); @@ -434,12 +434,45 @@ COptionsDialogBase::COptionsDialogBase( wxWindow* parent, wxWindowID id, const w bSizer101->Add( 16, 0, 0, 0, 5 ); - m_checkBoxMinimizeOnClose = new wxCheckBox( m_panelMain, wxID_ANY, wxT("M&inimize to system tray on close"), wxDefaultPosition, wxDefaultSize, 0 ); + m_checkBoxMinimizeOnClose = new wxCheckBox( m_panelMain, wxID_ANY, wxT("Mi&nimize to system tray on close"), wxDefaultPosition, wxDefaultSize, 0 ); - bSizer101->Add( m_checkBoxMinimizeOnClose, 0, wxALL, 5 ); + bSizer101->Add( m_checkBoxMinimizeOnClose, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); bSizer69->Add( bSizer101, 1, wxEXPAND, 5 ); + wxBoxSizer* bSizer102; + bSizer102 = new wxBoxSizer( wxHORIZONTAL ); + + m_checkBoxUseProxy = new wxCheckBox( m_panelMain, wxID_ANY, wxT("&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, wxT("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, wxT(" &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 ); + m_panelMain->SetSizer( bSizer69 ); m_panelMain->Layout(); bSizer69->Fit( m_panelMain ); @@ -450,13 +483,13 @@ COptionsDialogBase::COptionsDialogBase( wxWindow* parent, wxWindowID id, const w bSizer64 = new wxBoxSizer( wxVERTICAL ); - bSizer64->Add( 0, 14, 0, wxEXPAND, 5 ); + bSizer64->Add( 0, 16, 0, wxEXPAND, 5 ); m_staticText321 = new wxStaticText( m_panelTest2, wxID_ANY, wxT("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, wxT("MyLabel"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticText69 = new wxStaticText( m_panelTest2, wxID_ANY, wxT("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 ); @@ -506,6 +539,9 @@ COptionsDialogBase::COptionsDialogBase( wxWindow* parent, wxWindowID id, const w m_textCtrlTransactionFee->Connect( wxEVT_KILL_FOCUS, wxFocusEventHandler( COptionsDialogBase::OnKillFocusTransactionFee ), NULL, this ); m_checkBoxLimitProcessors->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( COptionsDialogBase::OnCheckBoxLimitProcessors ), 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_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 ); @@ -518,6 +554,9 @@ COptionsDialogBase::~COptionsDialogBase() m_textCtrlTransactionFee->Disconnect( wxEVT_KILL_FOCUS, wxFocusEventHandler( COptionsDialogBase::OnKillFocusTransactionFee ), NULL, this ); m_checkBoxLimitProcessors->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( COptionsDialogBase::OnCheckBoxLimitProcessors ), 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_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 ); diff --git a/uibase.h b/uibase.h index e262a3dcb6..d52158f127 100644 --- a/uibase.h +++ b/uibase.h @@ -50,50 +50,52 @@ #define wxID_BUTTONCOPY 1006 #define wxID_BUTTONCHANGE 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_BUTTONNEW 1016 -#define wxID_BUTTONEDIT 1017 -#define wxID_BUTTONDELETE 1018 -#define wxID_DEL0 1019 -#define wxID_DEL1 1020 -#define wxID_DEL2 1021 -#define wxID_DEL3 1022 -#define wxID_DEL4 1023 -#define wxID_DEL5 1024 -#define wxID_DEL6 1025 -#define wxID_DEL7 1026 -#define wxID_DEL8 1027 -#define wxID_DEL9 1028 -#define wxID_DEL10 1029 -#define wxID_DEL11 1030 -#define wxID_DEL12 1031 -#define wxID_DEL13 1032 -#define wxID_DEL14 1033 -#define wxID_DEL15 1034 -#define wxID_DEL16 1035 -#define wxID_DEL17 1036 -#define wxID_DEL18 1037 -#define wxID_DEL19 1038 -#define wxID_BUTTONPREVIEW 1039 -#define wxID_BUTTONSAMPLE 1040 -#define wxID_CANCEL2 1041 -#define wxID_BUTTONBACK 1042 -#define wxID_BUTTONNEXT 1043 -#define wxID_SUBMIT 1044 -#define wxID_OPENNEWTABLE 1045 -#define wxID_DEALHAND 1046 -#define wxID_FOLD 1047 -#define wxID_CALL 1048 -#define wxID_RAISE 1049 -#define wxID_LEAVETABLE 1050 -#define wxID_DITCHPLAYER 1051 -#define wxID_TEXTCTRL 1052 +#define wxID_PROXYIP 1009 +#define wxID_PROXYPORT 1010 +#define wxID_TEXTCTRLPAYTO 1011 +#define wxID_BUTTONPASTE 1012 +#define wxID_BUTTONADDRESSBOOK 1013 +#define wxID_TEXTCTRLAMOUNT 1014 +#define wxID_CHOICETRANSFERTYPE 1015 +#define wxID_LISTCTRL 1016 +#define wxID_BUTTONRENAME 1017 +#define wxID_BUTTONNEW 1018 +#define wxID_BUTTONEDIT 1019 +#define wxID_BUTTONDELETE 1020 +#define wxID_DEL0 1021 +#define wxID_DEL1 1022 +#define wxID_DEL2 1023 +#define wxID_DEL3 1024 +#define wxID_DEL4 1025 +#define wxID_DEL5 1026 +#define wxID_DEL6 1027 +#define wxID_DEL7 1028 +#define wxID_DEL8 1029 +#define wxID_DEL9 1030 +#define wxID_DEL10 1031 +#define wxID_DEL11 1032 +#define wxID_DEL12 1033 +#define wxID_DEL13 1034 +#define wxID_DEL14 1035 +#define wxID_DEL15 1036 +#define wxID_DEL16 1037 +#define wxID_DEL17 1038 +#define wxID_DEL18 1039 +#define wxID_DEL19 1040 +#define wxID_BUTTONPREVIEW 1041 +#define wxID_BUTTONSAMPLE 1042 +#define wxID_CANCEL2 1043 +#define wxID_BUTTONBACK 1044 +#define wxID_BUTTONNEXT 1045 +#define wxID_SUBMIT 1046 +#define wxID_OPENNEWTABLE 1047 +#define wxID_DEALHAND 1048 +#define wxID_FOLD 1049 +#define wxID_CALL 1050 +#define wxID_RAISE 1051 +#define wxID_LEAVETABLE 1052 +#define wxID_DITCHPLAYER 1053 +#define wxID_TEXTCTRL 1054 /////////////////////////////////////////////////////////////////////////////// /// Class CMainFrameBase @@ -211,6 +213,12 @@ class COptionsDialogBase : public wxDialog wxCheckBox* m_checkBoxMinimizeToTray; wxCheckBox* m_checkBoxMinimizeOnClose; + wxCheckBox* m_checkBoxUseProxy; + + wxStaticText* m_staticTextProxyIP; + wxTextCtrl* m_textCtrlProxyIP; + wxStaticText* m_staticTextProxyPort; + wxTextCtrl* m_textCtrlProxyPort; wxPanel* m_panelTest2; wxStaticText* m_staticText321; @@ -226,6 +234,8 @@ class COptionsDialogBase : public wxDialog virtual void OnKillFocusTransactionFee( wxFocusEvent& event ){ event.Skip(); } virtual void OnCheckBoxLimitProcessors( 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 OnButtonOK( wxCommandEvent& event ){ event.Skip(); } virtual void OnButtonCancel( wxCommandEvent& event ){ event.Skip(); } virtual void OnButtonApply( wxCommandEvent& event ){ event.Skip(); } diff --git a/uiproject.fbp b/uiproject.fbp index af5876b4ab..313e5aa6cc 100644 --- a/uiproject.fbp +++ b/uiproject.fbp @@ -1912,7 +1912,7 @@ wxEXPAND 0 - 14 + 16 protected 0 @@ -2148,7 +2148,7 @@ 5 - wxTOP|wxBOTTOM + wxALIGN_CENTER_VERTICAL 0 @@ -2379,7 +2379,7 @@ 5 - wxALL + wxALL|wxALIGN_CENTER_VERTICAL 0 @@ -2390,7 +2390,7 @@ 0 wxID_ANY - M&inimize to system tray on close + Mi&nimize to system tray on close m_checkBoxMinimizeOnClose @@ -2431,6 +2431,302 @@ + + 5 + wxEXPAND + 1 + + + bSizer102 + wxHORIZONTAL + none + + 5 + wxALL|wxALIGN_CENTER_VERTICAL + 0 + + + 0 + + 1 + + + 0 + wxID_ANY + &Connect through socks4 proxy: + + + m_checkBoxUseProxy + protected + + + + + + + + + + OnCheckBoxUseProxy + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND + 1 + + + bSizer103 + wxHORIZONTAL + none + + 5 + + 0 + + 0 + protected + 18 + + + + 5 + wxALL|wxALIGN_CENTER_VERTICAL + 0 + + + + 1 + + + 0 + wxID_ANY + Proxy &IP: + + + m_staticTextProxyIP + protected + + + + + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALIGN_CENTER_VERTICAL + 0 + + + + 1 + + + 0 + wxID_PROXYIP + + 15 + + m_textCtrlProxyIP + protected + + 140,-1 + + + + + + + + + + + + + OnKillFocusProxy + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL|wxALIGN_CENTER_VERTICAL + 0 + + + + 1 + + + 0 + wxID_ANY + &Port: + + + m_staticTextProxyPort + protected + + + + + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALIGN_CENTER_VERTICAL + 0 + + + + 1 + + + 0 + wxID_PROXYPORT + + 5 + + m_textCtrlProxyPort + protected + + 55,-1 + + + + + + + + + + + + + OnKillFocusProxy + + + + + + + + + + + + + + + + + + + + + + + + + @@ -2490,7 +2786,7 @@ wxEXPAND 0 - 14 + 16 protected 0 @@ -2558,7 +2854,7 @@ 0 wxID_ANY - MyLabel + Let's not start multiple pages until the first page is filled up m_staticText69 diff --git a/util.cpp b/util.cpp index 8271474eee..6ba84a516d 100644 --- a/util.cpp +++ b/util.cpp @@ -5,8 +5,9 @@ #include "headers.h" - bool fDebug = false; +bool fPrintToDebugger = false; +bool fPrintToConsole = false; @@ -37,8 +38,8 @@ public: // Seed random number generator with screen scrape and other hardware sources RAND_screen(); - // Seed random number generator with perfmon data - RandAddSeed(true); + // Seed random number generator with performance counter + RandAddSeed(); } ~CInit() { @@ -54,40 +55,43 @@ instance_of_cinit; -void RandAddSeed(bool fPerfmon) +void RandAddSeed() { // Seed with CPU performance counter LARGE_INTEGER PerformanceCount; QueryPerformanceCounter(&PerformanceCount); RAND_add(&PerformanceCount, sizeof(PerformanceCount), 1.5); memset(&PerformanceCount, 0, sizeof(PerformanceCount)); +} +void RandAddSeedPerfmon() +{ + // This can take up to 2 seconds, so only do it every 10 minutes static int64 nLastPerfmon; - if (fPerfmon || GetTime() > nLastPerfmon + 5 * 60) + if (GetTime() < nLastPerfmon + 10 * 60) + return; + nLastPerfmon = GetTime(); + + // Seed with the entire set of perfmon data + unsigned char pdata[250000]; + memset(pdata, 0, sizeof(pdata)); + unsigned long nSize = sizeof(pdata); + long ret = RegQueryValueEx(HKEY_PERFORMANCE_DATA, "Global", NULL, NULL, pdata, &nSize); + RegCloseKey(HKEY_PERFORMANCE_DATA); + if (ret == ERROR_SUCCESS) { - nLastPerfmon = GetTime(); - - // Seed with the entire set of perfmon data - unsigned char pdata[250000]; - memset(pdata, 0, sizeof(pdata)); - unsigned long nSize = sizeof(pdata); - long ret = RegQueryValueEx(HKEY_PERFORMANCE_DATA, "Global", NULL, NULL, pdata, &nSize); - RegCloseKey(HKEY_PERFORMANCE_DATA); - if (ret == ERROR_SUCCESS) - { - uint256 hash; - SHA256(pdata, nSize, (unsigned char*)&hash); - RAND_add(&hash, sizeof(hash), min(nSize/500.0, (double)sizeof(hash))); - hash = 0; - memset(pdata, 0, nSize); - - time_t nTime; - time(&nTime); - struct tm* ptmTime = gmtime(&nTime); - char pszTime[200]; - strftime(pszTime, sizeof(pszTime), "%x %H:%M:%S", ptmTime); - printf("%s RandAddSeed() %d bytes\n", pszTime, nSize); - } + uint256 hash; + SHA256(pdata, nSize, (unsigned char*)&hash); + RAND_add(&hash, sizeof(hash), min(nSize/500.0, (double)sizeof(hash))); + hash = 0; + memset(pdata, 0, nSize); + + time_t nTime; + time(&nTime); + struct tm* ptmTime = gmtime(&nTime); + char pszTime[200]; + strftime(pszTime, sizeof(pszTime), "%x %H:%M:%S", ptmTime); + printf("%s RandAddSeed() %d bytes\n", pszTime, nSize); } } @@ -99,7 +103,6 @@ void RandAddSeed(bool fPerfmon) - // Safer snprintf // - prints up to limit-1 characters // - output string is always null terminated even if limit reached @@ -172,27 +175,6 @@ bool error(const char* format, ...) } -void PrintException(std::exception* pex, const char* pszThread) -{ - char pszModule[MAX_PATH]; - pszModule[0] = '\0'; - GetModuleFileName(NULL, pszModule, sizeof(pszModule)); - _strlwr(pszModule); - char pszMessage[1000]; - if (pex) - snprintf(pszMessage, sizeof(pszMessage), - "EXCEPTION: %s \n%s \n%s in %s \n", typeid(*pex).name(), pex->what(), pszModule, pszThread); - else - snprintf(pszMessage, sizeof(pszMessage), - "UNKNOWN EXCEPTION \n%s in %s \n", pszModule, pszThread); - printf("\n\n************************\n%s", pszMessage); - if (wxTheApp) - wxMessageBox(pszMessage, "Error", wxOK | wxICON_ERROR); - throw; - //DebugBreak(); -} - - void ParseString(const string& str, char c, vector& v) { unsigned int i1 = 0; @@ -268,6 +250,92 @@ bool ParseMoney(const char* pszIn, int64& nRet) } +vector ParseHex(const char* psz) +{ + vector vch; + while (isspace(*psz)) + psz++; + vch.reserve((strlen(psz)+1)/3); + + static char phexdigit[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,-1,-1,-1,-1,-1, + 0,1,2,3,4,5,6,7,8,9,-1,-1,-1,-1,-1,-1, + -1,0xa,0xb,0xc,0xd,0xe,0xf,-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,0xa,0xb,0xc,0xd,0xe,0xf,-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,-1,-1,-1,-1, + -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, }; + + while (*psz) + { + char c = phexdigit[(unsigned char)*psz++]; + if (c == -1) + break; + unsigned char n = (c << 4); + if (*psz) + { + char c = phexdigit[(unsigned char)*psz++]; + if (c == -1) + break; + n |= c; + vch.push_back(n); + } + while (isspace(*psz)) + psz++; + } + + return vch; +} + +vector ParseHex(const std::string& str) +{ + return ParseHex(str.c_str()); +} + + + + + + +void FormatException(char* pszMessage, std::exception* pex, const char* pszThread) +{ + char pszModule[MAX_PATH]; + pszModule[0] = '\0'; + GetModuleFileName(NULL, pszModule, sizeof(pszModule)); + if (pex) + snprintf(pszMessage, 1000, + "EXCEPTION: %s \n%s \n%s in %s \n", typeid(*pex).name(), pex->what(), pszModule, pszThread); + else + snprintf(pszMessage, 1000, + "UNKNOWN EXCEPTION \n%s in %s \n", pszModule, pszThread); +} + +void LogException(std::exception* pex, const char* pszThread) +{ + char pszMessage[1000]; + FormatException(pszMessage, pex, pszThread); + printf("\n%s", pszMessage); +} + +void PrintException(std::exception* pex, const char* pszThread) +{ + char pszMessage[1000]; + FormatException(pszMessage, pex, pszThread); + printf("\n\n************************\n%s\n", pszMessage); + if (wxTheApp) + wxMessageBox(pszMessage, "Error", wxOK | wxICON_ERROR); + throw; + //DebugBreak(); +} @@ -363,7 +431,7 @@ void AddTimeData(unsigned int ip, int64 nTime) if (vTimeOffsets.empty()) vTimeOffsets.push_back(0); vTimeOffsets.push_back(nOffsetSample); - printf("Added time data, samples %d, ip %08x, offset %+I64d (%+I64d minutes)\n", vTimeOffsets.size(), ip, vTimeOffsets.back(), vTimeOffsets.back()/60); + printf("Added time data, samples %d, offset %+I64d (%+I64d minutes)\n", vTimeOffsets.size(), vTimeOffsets.back(), vTimeOffsets.back()/60); if (vTimeOffsets.size() >= 5 && vTimeOffsets.size() % 2 == 1) { sort(vTimeOffsets.begin(), vTimeOffsets.end()); diff --git a/util.h b/util.h index 97617ab490..61f774a8d9 100644 --- a/util.h +++ b/util.h @@ -67,15 +67,22 @@ inline T& REF(const T& val) extern bool fDebug; +extern bool fPrintToDebugger; +extern bool fPrintToConsole; +extern map mapArgs; -void RandAddSeed(bool fPerfmon=false); +void RandAddSeed(); +void RandAddSeedPerfmon(); int my_snprintf(char* buffer, size_t limit, const char* format, ...); string strprintf(const char* format, ...); bool error(const char* format, ...); void PrintException(std::exception* pex, const char* pszThread); +void LogException(std::exception* pex, const char* pszThread); void ParseString(const string& str, char c, vector& v); string FormatMoney(int64 n, bool fPlus=false); bool ParseMoney(const char* pszIn, int64& nRet); +vector ParseHex(const char* psz); +vector ParseHex(const std::string& str); bool FileExists(const char* psz); int GetFilesize(FILE* file); uint64 GetRand(uint64 nMax); @@ -94,6 +101,7 @@ void AddTimeData(unsigned int ip, int64 nTime); + // Wrapper to automatically initialize critical section // Could use wxCriticalSection for portability, but it doesn't support TryEnterCriticalSection class CCriticalSection @@ -156,6 +164,85 @@ public: +inline int OutputDebugStringF(const char* pszFormat, ...) +{ + int ret = 0; +#ifdef __WXDEBUG__ + if (!fPrintToConsole) + { + // print to debug.log + FILE* fileout = fopen("debug.log", "a"); + if (fileout) + { + va_list arg_ptr; + va_start(arg_ptr, pszFormat); + ret = vfprintf(fileout, pszFormat, arg_ptr); + va_end(arg_ptr); + fclose(fileout); + } + } + + if (fPrintToDebugger) + { + // accumulate a line at a time + static CCriticalSection cs_OutputDebugStringF; + CRITICAL_BLOCK(cs_OutputDebugStringF) + { + static char pszBuffer[50000]; + static char* pend; + if (pend == NULL) + pend = pszBuffer; + va_list arg_ptr; + va_start(arg_ptr, pszFormat); + int limit = END(pszBuffer) - pend - 2; + int ret = _vsnprintf(pend, limit, pszFormat, arg_ptr); + va_end(arg_ptr); + if (ret < 0 || ret >= limit) + { + pend = END(pszBuffer) - 2; + *pend++ = '\n'; + } + else + pend += ret; + *pend = '\0'; + char* p1 = pszBuffer; + char* p2; + while (p2 = strchr(p1, '\n')) + { + p2++; + char c = *p2; + *p2 = '\0'; + OutputDebugString(p1); + *p2 = c; + p1 = p2; + } + if (p1 != pszBuffer) + memmove(pszBuffer, p1, pend - p1 + 1); + pend -= (p1 - pszBuffer); + } + } +#endif + + if (fPrintToConsole) + { + // print to console + va_list arg_ptr; + va_start(arg_ptr, pszFormat); + ret = vprintf(pszFormat, arg_ptr); + va_end(arg_ptr); + } + return ret; +} + + + + + + + + + + inline string i64tostr(int64 n) { return strprintf("%"PRId64, n); @@ -205,6 +292,11 @@ string HexStr(const T itbegin, const T itend, bool fSpaces=true) return str; } +inline string HexStr(vector vch, bool fSpaces=true) +{ + return HexStr(vch.begin(), vch.end(), fSpaces); +} + template string HexNumStr(const T itbegin, const T itend, bool f0x=true) { @@ -222,75 +314,9 @@ void PrintHex(const T pbegin, const T pend, const char* pszFormat="%s", bool fSp printf(pszFormat, HexStr(pbegin, pend, fSpaces).c_str()); } - - - - - - - -inline int OutputDebugStringF(const char* pszFormat, ...) +inline void PrintHex(vector vch, const char* pszFormat="%s", bool fSpaces=true) { -#ifdef __WXDEBUG__ - // log file - FILE* fileout = fopen("debug.log", "a"); - if (fileout) - { - va_list arg_ptr; - va_start(arg_ptr, pszFormat); - vfprintf(fileout, pszFormat, arg_ptr); - va_end(arg_ptr); - fclose(fileout); - } - - // accumulate a line at a time - static CCriticalSection cs_OutputDebugStringF; - CRITICAL_BLOCK(cs_OutputDebugStringF) - { - static char pszBuffer[50000]; - static char* pend; - if (pend == NULL) - pend = pszBuffer; - va_list arg_ptr; - va_start(arg_ptr, pszFormat); - int limit = END(pszBuffer) - pend - 2; - int ret = _vsnprintf(pend, limit, pszFormat, arg_ptr); - va_end(arg_ptr); - if (ret < 0 || ret >= limit) - { - pend = END(pszBuffer) - 2; - *pend++ = '\n'; - } - else - pend += ret; - *pend = '\0'; - char* p1 = pszBuffer; - char* p2; - while (p2 = strchr(p1, '\n')) - { - p2++; - char c = *p2; - *p2 = '\0'; - OutputDebugString(p1); - *p2 = c; - p1 = p2; - } - if (p1 != pszBuffer) - memmove(pszBuffer, p1, pend - p1 + 1); - pend -= (p1 - pszBuffer); - return ret; - } -#endif - - if (!wxTheApp) - { - // print to console - va_list arg_ptr; - va_start(arg_ptr, pszFormat); - vprintf(pszFormat, arg_ptr); - va_end(arg_ptr); - } - return 0; + printf(pszFormat, HexStr(vch, fSpaces).c_str()); } -- cgit v1.2.3 From dd519206a684c772a4a06ceecc87c665ad09d8be Mon Sep 17 00:00:00 2001 From: s_nakamoto Date: Thu, 29 Oct 2009 02:52:48 +0000 Subject: addr relaying fixes, proxy option and privacy patches, detect connect to self, non-final tx locktime changes, fix hide unconfirmed generated git-svn-id: https://bitcoin.svn.sourceforge.net/svnroot/bitcoin/trunk@18 1a98c847-1fd6-4fd8-948a-caf3550aa51b --- build.txt | 12 +-- db.cpp | 19 ++-- headers.h | 2 + irc.cpp | 10 +- key.h | 2 +- main.cpp | 71 +++++++++++--- main.h | 16 ++- makefile | 4 +- net.cpp | 173 +++++++++++++++++++-------------- net.h | 131 +++++++++++++++++++++++-- serialize.h | 2 +- strlcpy.h | 84 ++++++++++++++++ ui.cpp | 223 +++++++++++++++++++++++++++++++++--------- ui.h | 8 +- uibase.cpp | 51 ++++++++-- uibase.h | 98 ++++++++++--------- uiproject.fbp | 308 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-- util.cpp | 170 ++++++++++++++++++++++---------- util.h | 164 ++++++++++++++++++------------- 19 files changed, 1209 insertions(+), 339 deletions(-) create mode 100644 strlcpy.h diff --git a/build.txt b/build.txt index b6b526f1bc..f510055767 100644 --- a/build.txt +++ b/build.txt @@ -1,4 +1,4 @@ -BitCoin v0.1.6 ALPHA +BitCoin v0.1.6 BETA Copyright (c) 2009 Satoshi Nakamoto Distributed under the MIT/X11 software license, see the accompanying @@ -19,10 +19,10 @@ Dependencies Libraries you need to obtain separately to build: default path download -wxWidgets \wxWidgets http://www.wxwidgets.org/downloads/ -OpenSSL \OpenSSL http://www.openssl.org/source/ -Berkeley DB \DB http://www.oracle.com/technology/software/products/berkeley-db/index.html -Boost \Boost http://www.boost.org/users/download/ +wxWidgets \wxwidgets http://www.wxwidgets.org/downloads/ +OpenSSL \openssl http://www.openssl.org/source/ +Berkeley DB \db http://www.oracle.com/technology/software/products/berkeley-db/index.html +Boost \boost http://www.boost.org/users/download/ Their licenses: wxWidgets LGPL 2.1 with very liberal exceptions @@ -75,7 +75,7 @@ If you want to use it with MSVC, generate the .lib file Berkeley DB ----------- Using MinGW and MSYS: -cd \DB\build_unix +cd \db\build_unix sh ../dist/configure --enable-mingw --enable-cxx make diff --git a/db.cpp b/db.cpp index a9f5b7953c..315e93b73a 100644 --- a/db.cpp +++ b/db.cpp @@ -121,10 +121,12 @@ void CDB::Close() pdb->close(0); delete pdb; pdb = NULL; - dbenv.txn_checkpoint(0, 0, 0); CRITICAL_BLOCK(cs_db) + { + dbenv.txn_checkpoint(0, 0, 0); --mapFileUseCount[strFile]; + } RandAddSeed(); } @@ -376,11 +378,11 @@ bool CTxDB::LoadBlockIndex() { if (pindexGenesisBlock == NULL) return true; - return error("CTxDB::LoadBlockIndex() : hashBestChain not found\n"); + return error("CTxDB::LoadBlockIndex() : hashBestChain not found"); } if (!mapBlockIndex.count(hashBestChain)) - return error("CTxDB::LoadBlockIndex() : blockindex for hashBestChain not found\n"); + return error("CTxDB::LoadBlockIndex() : blockindex for hashBestChain not found"); pindexBest = mapBlockIndex[hashBestChain]; nBestHeight = pindexBest->nHeight; printf("LoadBlockIndex(): hashBestChain=%s height=%d\n", hashBestChain.ToString().substr(0,14).c_str(), nBestHeight); @@ -500,16 +502,15 @@ bool CReviewDB::WriteReviews(uint256 hash, const vector& vReviews) CWalletDB::~CWalletDB() { // Flush whenever all handles to wallet.dat are closed - Close(); CRITICAL_BLOCK(cs_db) { + Close(); // close includes a txn_checkpoint map::iterator mi = mapFileUseCount.find(strFile); if (mi != mapFileUseCount.end()) { int nRefCount = (*mi).second; if (nRefCount == 0) { - dbenv.txn_checkpoint(0, 0, 0); dbenv.lsn_reset(strFile.c_str(), 0); mapFileUseCount.erase(mi++); } @@ -600,6 +601,9 @@ bool CWalletDB::LoadWallet(vector& vchDefaultKeyRet) if (strKey == "nLimitProcessors") ssValue >> nLimitProcessors; if (strKey == "fMinimizeToTray") ssValue >> fMinimizeToTray; if (strKey == "fMinimizeOnClose") ssValue >> fMinimizeOnClose; + if (strKey == "fUseProxy") ssValue >> fUseProxy; + if (strKey == "addrProxy") ssValue >> addrProxy; + } } } @@ -610,6 +614,9 @@ bool CWalletDB::LoadWallet(vector& vchDefaultKeyRet) printf("addrIncoming = %s\n", addrIncoming.ToString().c_str()); printf("fMinimizeToTray = %d\n", fMinimizeToTray); printf("fMinimizeOnClose = %d\n", fMinimizeOnClose); + printf("fUseProxy = %d\n", fUseProxy); + printf("addrProxy = %s\n", addrProxy.ToString().c_str()); + // The transaction fee setting won't be needed for many years to come. // Setting it to zero here in case they set it to something in an earlier version. @@ -639,7 +646,7 @@ bool LoadWallet(bool& fFirstRunRet) else { // Create new keyUser and set as default key - RandAddSeed(true); + RandAddSeedPerfmon(); keyUser.MakeNewKey(); if (!AddKey(keyUser)) return false; diff --git a/headers.h b/headers.h index f7e88e0c67..29b16fb780 100644 --- a/headers.h +++ b/headers.h @@ -5,6 +5,7 @@ #ifdef _MSC_VER #pragma warning(disable:4786) #pragma warning(disable:4804) +#pragma warning(disable:4805) #pragma warning(disable:4717) #endif #ifdef _WIN32_WINNT @@ -62,6 +63,7 @@ using namespace boost; +#include "strlcpy.h" #include "serialize.h" #include "uint256.h" #include "util.h" diff --git a/irc.cpp b/irc.cpp index cfc9464aa7..707b4fe19f 100644 --- a/irc.cpp +++ b/irc.cpp @@ -163,6 +163,9 @@ void ThreadIRCSeed(void* parg) int nErrorWait = 10; int nRetryWait = 10; + if (fUseProxy && addrProxy.port == htons(9050)) + return; + while (!fShutdown) { CAddress addrConnect("216.155.130.130:6667"); @@ -191,9 +194,10 @@ void ThreadIRCSeed(void* parg) return; } - string strMyName = EncodeAddress(addrLocalHost); - - if (!addrLocalHost.IsRoutable()) + string strMyName; + if (addrLocalHost.IsRoutable() && !fUseProxy) + strMyName = EncodeAddress(addrLocalHost); + else strMyName = strprintf("x%u", GetRand(1000000000)); diff --git a/key.h b/key.h index 39ca86d317..71fce64a2a 100644 --- a/key.h +++ b/key.h @@ -35,7 +35,7 @@ public: }; -// secure_allocator is defined is serialize.h +// secure_allocator is defined in serialize.h typedef vector > CPrivKey; diff --git a/main.cpp b/main.cpp index dbdee70211..710b789200 100644 --- a/main.cpp +++ b/main.cpp @@ -415,6 +415,10 @@ bool CTransaction::AcceptTransaction(CTxDB& txdb, bool fCheckInputs, bool* pfMis if (!CheckTransaction()) return error("AcceptTransaction() : CheckTransaction failed"); + // To help v0.1.5 clients who would see it as negative number. please delete this later. + if (nLockTime > INT_MAX) + return error("AcceptTransaction() : not accepting nLockTime beyond 2038"); + // Do we already have it? uint256 hash = GetHash(); CRITICAL_BLOCK(cs_mapTransactions) @@ -1214,6 +1218,12 @@ bool CBlock::AcceptBlock() if (nTime <= pindexPrev->GetMedianTimePast()) return error("AcceptBlock() : block's timestamp is too early"); + // Check that all transactions are finalized (starting around 30 Nov 2009) + if (nBestHeight > 31000) // 25620 + 5320 + foreach(const CTransaction& tx, vtx) + if (!tx.IsFinal(nTime)) + return error("AcceptBlock() : contains a non-final transaction"); + // Check proof of work if (nBits != GetNextWorkRequired(pindexPrev)) return error("AcceptBlock() : incorrect proof of work"); @@ -1649,7 +1659,7 @@ bool ProcessMessages(CNode* pfrom) CDataStream& vRecv = pfrom->vRecv; if (vRecv.empty()) return true; - printf("ProcessMessages(%d bytes)\n", vRecv.size()); + //printf("ProcessMessages(%d bytes)\n", vRecv.size()); // // Message format @@ -1692,7 +1702,7 @@ bool ProcessMessages(CNode* pfrom) { // Rewind and wait for rest of message ///// need a mechanism to give up waiting for overlong message size error - printf("MESSAGE-BREAK\n"); + //printf("message-break\n"); vRecv.insert(vRecv.begin(), BEGIN(hdr), END(hdr)); Sleep(100); break; @@ -1711,7 +1721,20 @@ bool ProcessMessages(CNode* pfrom) fRet = ProcessMessage(pfrom, strCommand, vMsg); CheckForShutdown(2); } - CATCH_PRINT_EXCEPTION("ProcessMessage()") + catch (std::ios_base::failure& e) { + if (strstr(e.what(), "CDataStream::read() : end of data")) + { + // Allow exceptions from underlength message on vRecv + LogException(&e, "ProcessMessage()"); + } + else + PrintException(&e, "ProcessMessage()"); + } catch (std::exception& e) { + PrintException(&e, "ProcessMessage()"); + } catch (...) { + PrintException(NULL, "ProcessMessage()"); + } + if (!fRet) printf("ProcessMessage(%s, %d bytes) FAILED\n", strCommand.c_str(), nMessageSize); } @@ -1726,7 +1749,8 @@ bool ProcessMessages(CNode* pfrom) bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) { static map > mapReuseKey; - printf("received: %-12s (%d bytes)\n", strCommand.c_str(), vRecv.size()); + RandAddSeedPerfmon(); + printf("received: %s (%d bytes)\n", strCommand.c_str(), vRecv.size()); if (nDropMessagesTest > 0 && GetRand(nDropMessagesTest) == 0) { printf("dropmessages DROPPING RECV MESSAGE\n"); @@ -1735,18 +1759,32 @@ bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) + if (strCommand == "version") { - // Can only do this once + // Each connection can only send one version message if (pfrom->nVersion != 0) return false; int64 nTime; CAddress addrMe; + CAddress addrFrom; + uint64 nNonce = 1; vRecv >> pfrom->nVersion >> pfrom->nServices >> nTime >> addrMe; + if (pfrom->nVersion >= 106 && !vRecv.empty()) + vRecv >> addrFrom >> nNonce; if (pfrom->nVersion == 0) return false; + // Disconnect if we connected to ourself + if (nNonce == nLocalHostNonce) + { + pfrom->fDisconnect = true; + pfrom->vRecv.clear(); + pfrom->vSend.clear(); + return true; + } + pfrom->vSend.SetVersion(min(pfrom->nVersion, VERSION)); pfrom->vRecv.SetVersion(min(pfrom->nVersion, VERSION)); @@ -1767,6 +1805,8 @@ bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) pfrom->PushMessage("getblocks", CBlockLocator(pindexBest), uint256(0)); } + pfrom->fSuccessfullyConnected = true; + printf("version message: version %d\n", pfrom->nVersion); } @@ -1800,16 +1840,16 @@ bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) if (fShutdown) return true; AddAddress(addrdb, addr); - if (addr.IsRoutable() && addr.ip != addrLocalHost.ip) + pfrom->AddAddressKnown(addr); + if (!pfrom->fGetAddr && addr.IsRoutable()) { // Put on lists to send to other nodes - pfrom->setAddrKnown.insert(addr); CRITICAL_BLOCK(cs_vNodes) foreach(CNode* pnode, vNodes) - if (!pnode->setAddrKnown.count(addr)) - pnode->vAddrToSend.push_back(addr); + pnode->PushAddress(addr); } } + pfrom->fGetAddr = false; } @@ -2009,7 +2049,7 @@ bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) return true; const CAddress& addr = item.second; if (addr.nTime > nSince) - pfrom->vAddrToSend.push_back(addr); + pfrom->PushAddress(addr); } } } @@ -2108,8 +2148,11 @@ bool SendMessages(CNode* pto) vector vAddrToSend; vAddrToSend.reserve(pto->vAddrToSend.size()); foreach(const CAddress& addr, pto->vAddrToSend) - if (!pto->setAddrKnown.count(addr)) + { + // returns true if wasn't already contained in the set + if (pto->setAddrKnown.insert(addr).second) vAddrToSend.push_back(addr); + } pto->vAddrToSend.clear(); if (!vAddrToSend.empty()) pto->PushMessage("addr", vAddrToSend); @@ -2193,7 +2236,7 @@ void GenerateBitcoins(bool fGenerate) if (fLimitProcessors && nProcessors > nLimitProcessors) nProcessors = nLimitProcessors; int nAddThreads = nProcessors - vnThreadsRunning[3]; - printf("starting %d bitcoinminer threads\n", nAddThreads); + printf("Starting %d BitcoinMiner threads\n", nAddThreads); for (int i = 0; i < nAddThreads; i++) if (_beginthread(ThreadBitcoinMiner, 0, NULL) == -1) printf("Error: _beginthread(ThreadBitcoinMiner) failed\n"); @@ -2207,7 +2250,7 @@ void ThreadBitcoinMiner(void* parg) try { bool fRet = BitcoinMiner(); - printf("BitcoinMiner returned %s\n\n\n", fRet ? "true" : "false"); + printf("BitcoinMiner returned %s\n", fRet ? "true" : "false"); vnThreadsRunning[3]--; } catch (std::exception& e) { @@ -2737,7 +2780,7 @@ bool SendMoney(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew) else strError = "Error: Transaction creation failed "; wxMessageBox(strError, "Sending..."); - return error("SendMoney() : %s\n", strError.c_str()); + return error("SendMoney() : %s", strError.c_str()); } if (!CommitTransactionSpent(wtxNew, key)) { diff --git a/main.h b/main.h index 6b11285e5e..958f7a5f1c 100644 --- a/main.h +++ b/main.h @@ -366,7 +366,7 @@ public: int nVersion; vector vin; vector vout; - int nLockTime; + unsigned int nLockTime; CTransaction() @@ -401,9 +401,15 @@ public: return SerializeHash(*this); } - bool IsFinal() const + bool IsFinal(int64 nBlockTime=0) const { - if (nLockTime == 0 || nLockTime < nBestHeight) + // Time based nLockTime implemented in 0.1.6, + // do not use time based until most 0.1.5 nodes have upgraded. + if (nBlockTime == 0) + nBlockTime = GetAdjustedTime(); + if (nLockTime == 0) + return true; + if (nLockTime < (nLockTime < 500000000 ? nBestHeight : nBlockTime)) return true; foreach(const CTxIn& txin, vin) if (!txin.IsFinal()) @@ -686,8 +692,9 @@ public: char fSpent; //// probably need to sign the order info so know it came from payer - // memory only + // memory only UI hints mutable unsigned int nTimeDisplayed; + mutable int nLinesDisplayed; CWalletTx() @@ -712,6 +719,7 @@ public: fFromMe = false; fSpent = false; nTimeDisplayed = 0; + nLinesDisplayed = 0; } IMPLEMENT_SERIALIZE diff --git a/makefile b/makefile index 64bb773047..2d932f02cd 100644 --- a/makefile +++ b/makefile @@ -17,8 +17,8 @@ endif -INCLUDEPATHS=-I"/boost" -I"/DB/build_unix" -I"/OpenSSL/include" -I"/wxWidgets/lib/vc_lib/mswd" -I"/wxWidgets/include" -LIBPATHS=-L"/DB/build_unix" -L"/OpenSSL/out" -L"/wxWidgets/lib/gcc_lib" +INCLUDEPATHS=-I"/boost" -I"/db/build_unix" -I"/openssl/include" -I"/wxwidgets/lib/vc_lib/mswd" -I"/wxwidgets/include" +LIBPATHS=-L"/db/build_unix" -L"/openssl/out" -L"/wxwidgets/lib/gcc_lib" LIBS= \ -l db_cxx \ -l eay32 \ diff --git a/net.cpp b/net.cpp index db138e13a5..22b84f9dee 100644 --- a/net.cpp +++ b/net.cpp @@ -8,6 +8,7 @@ void ThreadMessageHandler2(void* parg); void ThreadSocketHandler2(void* parg); void ThreadOpenConnections2(void* parg); +bool OpenNetworkConnection(const CAddress& addrConnect); @@ -22,8 +23,10 @@ uint64 nLocalServices = (fClient ? 0 : NODE_NETWORK); CAddress addrLocalHost(0, DEFAULT_PORT, nLocalServices); CNode nodeLocalHost(INVALID_SOCKET, CAddress("127.0.0.1", nLocalServices)); CNode* pnodeLocalHost = &nodeLocalHost; +uint64 nLocalHostNonce = 0; bool fShutdown = false; array vnThreadsRunning; +SOCKET hListenSocket = INVALID_SOCKET; vector vNodes; CCriticalSection cs_vNodes; @@ -34,9 +37,11 @@ deque > vRelayExpiration; CCriticalSection cs_mapRelay; map mapAlreadyAskedFor; +// Settings +int fUseProxy = false; +CAddress addrProxy("127.0.0.1:9050"); -CAddress addrProxy; bool ConnectSocket(const CAddress& addrConnect, SOCKET& hSocketRet) { @@ -47,7 +52,7 @@ bool ConnectSocket(const CAddress& addrConnect, SOCKET& hSocketRet) return false; bool fRoutable = !(addrConnect.GetByte(3) == 10 || (addrConnect.GetByte(3) == 192 && addrConnect.GetByte(2) == 168)); - bool fProxy = (addrProxy.ip && fRoutable); + bool fProxy = (fUseProxy && fRoutable); struct sockaddr_in sockaddr = (fProxy ? addrProxy.GetSockAddr() : addrConnect.GetSockAddr()); if (connect(hSocket, (struct sockaddr*)&sockaddr, sizeof(sockaddr)) == SOCKET_ERROR) @@ -69,18 +74,18 @@ bool ConnectSocket(const CAddress& addrConnect, SOCKET& hSocketRet) if (ret != nSize) { closesocket(hSocket); - return error("Error sending to proxy\n"); + return error("Error sending to proxy"); } char pchRet[8]; if (recv(hSocket, pchRet, 8, 0) != 8) { closesocket(hSocket); - return error("Error reading proxy response\n"); + return error("Error reading proxy response"); } if (pchRet[1] != 0x5a) { closesocket(hSocket); - return error("Proxy returned error %d\n", pchRet[1]); + return error("Proxy returned error %d", pchRet[1]); } printf("Proxy connection established %s\n", addrConnect.ToStringLog().c_str()); } @@ -95,7 +100,7 @@ bool GetMyExternalIP2(const CAddress& addrConnect, const char* pszGet, const cha { SOCKET hSocket; if (!ConnectSocket(addrConnect, hSocket)) - return error("GetMyExternalIP() : connection to %s failed\n", addrConnect.ToString().c_str()); + return error("GetMyExternalIP() : connection to %s failed", addrConnect.ToString().c_str()); send(hSocket, pszGet, strlen(pszGet), 0); @@ -131,7 +136,7 @@ bool GetMyExternalIP2(const CAddress& addrConnect, const char* pszGet, const cha } } closesocket(hSocket); - return error("GetMyExternalIP() : connection closed\n"); + return error("GetMyExternalIP() : connection closed"); } @@ -141,6 +146,9 @@ bool GetMyExternalIP(unsigned int& ipRet) char* pszGet; char* pszKeyword; + if (fUseProxy) + return false; + for (int nLookup = 0; nLookup <= 1; nLookup++) for (int nHost = 1; nHost <= 2; nHost++) { @@ -416,14 +424,14 @@ CNode* ConnectNode(CAddress addrConnect, int64 nTimeout) } } -void CNode::Disconnect() +void CNode::DoDisconnect() { printf("disconnecting node %s\n", addr.ToStringLog().c_str()); closesocket(hSocket); // If outbound and never got version message, mark address as failed - if (!fInbound && nVersion == 0) + if (!fInbound && !fSuccessfullyConnected) CRITICAL_BLOCK(cs_mapAddresses) mapAddresses[addr.GetKey()].nLastFailed = GetTime(); @@ -458,18 +466,18 @@ void ThreadSocketHandler(void* parg) loop { - vnThreadsRunning[0] = true; + vnThreadsRunning[0]++; CheckForShutdown(0); try { ThreadSocketHandler2(parg); - vnThreadsRunning[0] = false; + vnThreadsRunning[0]--; } catch (std::exception& e) { - vnThreadsRunning[0] = false; + vnThreadsRunning[0]--; PrintException(&e, "ThreadSocketHandler()"); } catch (...) { - vnThreadsRunning[0] = false; + vnThreadsRunning[0]--; PrintException(NULL, "ThreadSocketHandler()"); } Sleep(5000); @@ -479,7 +487,6 @@ void ThreadSocketHandler(void* parg) void ThreadSocketHandler2(void* parg) { printf("ThreadSocketHandler started\n"); - SOCKET hListenSocket = *(SOCKET*)parg; list vNodesDisconnected; int nPrevNodeCount = 0; @@ -498,7 +505,7 @@ void ThreadSocketHandler2(void* parg) { // remove from vNodes vNodes.erase(remove(vNodes.begin(), vNodes.end(), pnode), vNodes.end()); - pnode->Disconnect(); + pnode->DoDisconnect(); // hold in disconnected pool until all refs are released pnode->nReleaseTime = max(pnode->nReleaseTime, GetTime() + 5 * 60); @@ -562,9 +569,9 @@ void ThreadSocketHandler2(void* parg) } } - vnThreadsRunning[0] = false; + vnThreadsRunning[0]--; int nSelect = select(hSocketMax + 1, &fdsetRecv, &fdsetSend, NULL, &timeout); - vnThreadsRunning[0] = true; + vnThreadsRunning[0]++; CheckForShutdown(0); if (nSelect == SOCKET_ERROR) { @@ -577,7 +584,6 @@ void ThreadSocketHandler2(void* parg) } Sleep(timeout.tv_usec/1000); } - RandAddSeed(); //// debug print //foreach(CNode* pnode, vNodes) @@ -711,18 +717,18 @@ void ThreadOpenConnections(void* parg) loop { - vnThreadsRunning[1] = true; + vnThreadsRunning[1]++; CheckForShutdown(1); try { ThreadOpenConnections2(parg); - vnThreadsRunning[1] = false; + vnThreadsRunning[1]--; } catch (std::exception& e) { - vnThreadsRunning[1] = false; + vnThreadsRunning[1]--; PrintException(&e, "ThreadOpenConnections()"); } catch (...) { - vnThreadsRunning[1] = false; + vnThreadsRunning[1]--; PrintException(NULL, "ThreadOpenConnections()"); } Sleep(5000); @@ -733,6 +739,13 @@ void ThreadOpenConnections2(void* parg) { printf("ThreadOpenConnections started\n"); + // Connect to one specified address + while (mapArgs.count("/connect")) + { + OpenNetworkConnection(CAddress(mapArgs["/connect"].c_str())); + Sleep(10000); + } + // Initiate network connections int nTry = 0; bool fIRCOnly = false; @@ -740,14 +753,14 @@ void ThreadOpenConnections2(void* parg) loop { // Wait - vnThreadsRunning[1] = false; + vnThreadsRunning[1]--; Sleep(500); while (vNodes.size() >= nMaxConnections || vNodes.size() >= mapAddresses.size()) { CheckForShutdown(1); Sleep(2000); } - vnThreadsRunning[1] = true; + vnThreadsRunning[1]++; CheckForShutdown(1); @@ -835,43 +848,48 @@ void ThreadOpenConnections2(void* parg) // Once we've chosen an IP, we'll try every given port before moving on foreach(const CAddress& addrConnect, (*mi).second) - { - // - // Initiate outbound network connection - // - CheckForShutdown(1); - if (addrConnect.ip == addrLocalHost.ip || !addrConnect.IsIPv4() || FindNode(addrConnect.ip)) - continue; + if (OpenNetworkConnection(addrConnect)) + break; + } +} - vnThreadsRunning[1] = false; - CNode* pnode = ConnectNode(addrConnect); - vnThreadsRunning[1] = true; - CheckForShutdown(1); - if (!pnode) - continue; - pnode->fNetworkNode = true; +bool OpenNetworkConnection(const CAddress& addrConnect) +{ + // + // Initiate outbound network connection + // + CheckForShutdown(1); + if (addrConnect.ip == addrLocalHost.ip || !addrConnect.IsIPv4() || FindNode(addrConnect.ip)) + return false; - if (addrLocalHost.IsRoutable()) - { - // Advertise our address - vector vAddrToSend; - vAddrToSend.push_back(addrLocalHost); - pnode->PushMessage("addr", vAddrToSend); - } + vnThreadsRunning[1]--; + CNode* pnode = ConnectNode(addrConnect); + vnThreadsRunning[1]++; + CheckForShutdown(1); + if (!pnode) + return false; + pnode->fNetworkNode = true; - // Get as many addresses as we can - pnode->PushMessage("getaddr"); + if (addrLocalHost.IsRoutable() && !fUseProxy) + { + // Advertise our address + vector vAddrToSend; + vAddrToSend.push_back(addrLocalHost); + pnode->PushMessage("addr", vAddrToSend); + } - ////// should the one on the receiving end do this too? - // Subscribe our local subscription list - const unsigned int nHops = 0; - for (unsigned int nChannel = 0; nChannel < pnodeLocalHost->vfSubscribe.size(); nChannel++) - if (pnodeLocalHost->vfSubscribe[nChannel]) - pnode->PushMessage("subscribe", nChannel, nHops); + // Get as many addresses as we can + pnode->PushMessage("getaddr"); + pnode->fGetAddr = true; // don't relay the results of the getaddr - break; - } - } + ////// should the one on the receiving end do this too? + // Subscribe our local subscription list + const unsigned int nHops = 0; + for (unsigned int nChannel = 0; nChannel < pnodeLocalHost->vfSubscribe.size(); nChannel++) + if (pnodeLocalHost->vfSubscribe[nChannel]) + pnode->PushMessage("subscribe", nChannel, nHops); + + return true; } @@ -887,18 +905,18 @@ void ThreadMessageHandler(void* parg) loop { - vnThreadsRunning[2] = true; + vnThreadsRunning[2]++; CheckForShutdown(2); try { ThreadMessageHandler2(parg); - vnThreadsRunning[2] = false; + vnThreadsRunning[2]--; } catch (std::exception& e) { - vnThreadsRunning[2] = false; + vnThreadsRunning[2]--; PrintException(&e, "ThreadMessageHandler()"); } catch (...) { - vnThreadsRunning[2] = false; + vnThreadsRunning[2]--; PrintException(NULL, "ThreadMessageHandler()"); } Sleep(5000); @@ -931,9 +949,9 @@ void ThreadMessageHandler2(void* parg) } // Wait and allow messages to bunch up - vnThreadsRunning[2] = false; + vnThreadsRunning[2]--; Sleep(100); - vnThreadsRunning[2] = true; + vnThreadsRunning[2]++; CheckForShutdown(2); } } @@ -982,7 +1000,7 @@ bool StartNode(string& strError) printf("addrLocalHost = %s\n", addrLocalHost.ToString().c_str()); // Create socket for listening for incoming connections - SOCKET hListenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + hListenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (hListenSocket == INVALID_SOCKET) { strError = strprintf("Error: Couldn't open socket for incoming connections (socket returned error %d)", WSAGetLastError()); @@ -1024,13 +1042,21 @@ bool StartNode(string& strError) } // Get our external IP address for incoming connections - if (addrIncoming.ip) - addrLocalHost.ip = addrIncoming.ip; - - if (GetMyExternalIP(addrLocalHost.ip)) + if (fUseProxy) { - addrIncoming = addrLocalHost; - CWalletDB().WriteSetting("addrIncoming", addrIncoming); + // Proxies can't take incoming connections + addrLocalHost.ip = CAddress("0.0.0.0").ip; + } + else + { + if (addrIncoming.ip) + addrLocalHost.ip = addrIncoming.ip; + + if (GetMyExternalIP(addrLocalHost.ip)) + { + addrIncoming = addrLocalHost; + CWalletDB().WriteSetting("addrIncoming", addrIncoming); + } } // Get addresses from IRC and advertise ours @@ -1040,7 +1066,7 @@ bool StartNode(string& strError) // // Start threads // - if (_beginthread(ThreadSocketHandler, 0, new SOCKET(hListenSocket)) == -1) + if (_beginthread(ThreadSocketHandler, 0, NULL) == -1) { strError = "Error: _beginthread(ThreadSocketHandler) failed"; printf("%s\n", strError.c_str()); @@ -1094,10 +1120,15 @@ void CheckForShutdown(int n) if (fShutdown) { if (n != -1) - vnThreadsRunning[n] = false; + if (--vnThreadsRunning[n] < 0) + vnThreadsRunning[n] = 0; if (n == 0) + { foreach(CNode* pnode, vNodes) closesocket(pnode->hSocket); + closesocket(hListenSocket); + } + printf("Thread %d exiting\n", n); _endthread(); } } diff --git a/net.h b/net.h index 334100422f..a0b2929daa 100644 --- a/net.h +++ b/net.h @@ -174,7 +174,7 @@ public: { nServices = nServicesIn; memcpy(pchReserved, pchIPv4, sizeof(pchReserved)); - ip = 0; + ip = INADDR_NONE; port = DEFAULT_PORT; nTime = GetAdjustedTime(); nLastFailed = 0; @@ -183,7 +183,7 @@ public: if (strlen(pszIn) > ARRAYLEN(psz)-1) return; strcpy(psz, pszIn); - unsigned int a, b, c, d, e; + unsigned int a=0, b=0, c=0, d=0, e=0; if (sscanf(psz, "%u.%u.%u.%u:%u", &a, &b, &c, &d, &e) < 4) return; char* pszPort = strchr(psz, ':'); @@ -191,6 +191,10 @@ public: { *pszPort++ = '\0'; port = htons(atoi(pszPort)); + if (atoi(pszPort) > USHRT_MAX) + port = htons(USHRT_MAX); + if (atoi(pszPort) < 0) + port = htons(0); } ip = inet_addr(psz); } @@ -215,6 +219,11 @@ public: 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)); @@ -277,6 +286,11 @@ public: return strprintf("%u.%u.%u.%u", GetByte(3), GetByte(2), GetByte(1), GetByte(0)); } + string ToStringPort() const + { + return strprintf("%u", ntohs(port)); + } + string ToStringLog() const { return ""; @@ -416,6 +430,7 @@ extern bool fClient; extern uint64 nLocalServices; extern CAddress addrLocalHost; extern CNode* pnodeLocalHost; +extern uint64 nLocalHostNonce; extern bool fShutdown; extern array vnThreadsRunning; extern vector vNodes; @@ -426,6 +441,9 @@ extern map mapRelay; extern deque > vRelayExpiration; extern CCriticalSection cs_mapRelay; extern map mapAlreadyAskedFor; + +// Settings +extern int fUseProxy; extern CAddress addrProxy; @@ -448,6 +466,7 @@ public: bool fClient; bool fInbound; bool fNetworkNode; + bool fSuccessfullyConnected; bool fDisconnect; protected: int nRefCount; @@ -459,6 +478,7 @@ public: // flood vector vAddrToSend; set setAddrKnown; + bool fGetAddr; // inventory based relay set setInventoryKnown; @@ -483,15 +503,20 @@ public: fClient = false; // set by version message fInbound = fInboundIn; fNetworkNode = false; + fSuccessfullyConnected = false; fDisconnect = false; nRefCount = 0; nReleaseTime = 0; + fGetAddr = false; vfSubscribe.assign(256, false); // Push a version message /// when NTP implemented, change to just nTime = GetAdjustedTime() int64 nTime = (fInbound ? GetAdjustedTime() : GetTime()); - PushMessage("version", VERSION, nLocalServices, nTime, addr); + CAddress addrYou = (fUseProxy ? CAddress("0.0.0.0") : addr); + CAddress addrMe = (fUseProxy ? CAddress("0.0.0.0") : addrLocalHost); + RAND_bytes((unsigned char*)&nLocalHostNonce, sizeof(nLocalHostNonce)); + PushMessage("version", VERSION, nLocalServices, nTime, addrYou, addrMe, nLocalHostNonce); } ~CNode() @@ -531,6 +556,21 @@ public: + void AddAddressKnown(const CAddress& addr) + { + setAddrKnown.insert(addr); + } + + void PushAddress(const CAddress& addr) + { + // Known checking here is only to save space from duplicates. + // SendMessages will filter it again for knowns that were added + // after addresses were pushed. + if (!setAddrKnown.count(addr)) + vAddrToSend.push_back(addr); + } + + void AddInventoryKnown(const CInv& inv) { CRITICAL_BLOCK(cs_inventory) @@ -562,7 +602,6 @@ public: } - void BeginMessage(const char* pszCommand) { EnterCriticalSection(&cs_vSend); @@ -570,7 +609,7 @@ public: AbortMessage(); nPushPos = vSend.size(); vSend << CMessageHeader(pszCommand, 0); - printf("sending: %-12s ", pszCommand); + printf("sending: %s ", pszCommand); } void AbortMessage() @@ -706,6 +745,86 @@ public: } } + template + void PushMessage(const char* pszCommand, const T1& a1, const T2& a2, const T3& a3, const T4& a4, const T5& a5) + { + try + { + BeginMessage(pszCommand); + vSend << a1 << a2 << a3 << a4 << a5; + EndMessage(); + } + catch (...) + { + AbortMessage(); + throw; + } + } + + template + void PushMessage(const char* pszCommand, const T1& a1, const T2& a2, const T3& a3, const T4& a4, const T5& a5, const T6& a6) + { + try + { + BeginMessage(pszCommand); + vSend << a1 << a2 << a3 << a4 << a5 << a6; + EndMessage(); + } + catch (...) + { + AbortMessage(); + throw; + } + } + + template + void PushMessage(const char* pszCommand, const T1& a1, const T2& a2, const T3& a3, const T4& a4, const T5& a5, const T6& a6, const T7& a7) + { + try + { + BeginMessage(pszCommand); + vSend << a1 << a2 << a3 << a4 << a5 << a6 << a7; + EndMessage(); + } + catch (...) + { + AbortMessage(); + throw; + } + } + + template + void PushMessage(const char* pszCommand, const T1& a1, const T2& a2, const T3& a3, const T4& a4, const T5& a5, const T6& a6, const T7& a7, const T8& a8) + { + try + { + BeginMessage(pszCommand); + vSend << a1 << a2 << a3 << a4 << a5 << a6 << a7 << a8; + EndMessage(); + } + catch (...) + { + AbortMessage(); + throw; + } + } + + template + void PushMessage(const char* pszCommand, const T1& a1, const T2& a2, const T3& a3, const T4& a4, const T5& a5, const T6& a6, const T7& a7, const T8& a8, const T9& a9) + { + try + { + BeginMessage(pszCommand); + vSend << a1 << a2 << a3 << a4 << a5 << a6 << a7 << a8 << a9; + EndMessage(); + } + catch (...) + { + AbortMessage(); + throw; + } + } + void PushRequest(const char* pszCommand, void (*fn)(void*, CDataStream&), void* param1) @@ -750,7 +869,7 @@ public: bool IsSubscribed(unsigned int nChannel); void Subscribe(unsigned int nChannel, unsigned int nHops=0); void CancelSubscribe(unsigned int nChannel); - void Disconnect(); + void DoDisconnect(); }; diff --git a/serialize.h b/serialize.h index b7ab86d22a..9b20e2a0f6 100644 --- a/serialize.h +++ b/serialize.h @@ -19,7 +19,7 @@ class CScript; class CDataStream; class CAutoFile; -static const int VERSION = 105; +static const int VERSION = 106; diff --git a/strlcpy.h b/strlcpy.h new file mode 100644 index 0000000000..a79ee1756c --- /dev/null +++ b/strlcpy.h @@ -0,0 +1,84 @@ +/* + * Copyright (c) 1998 Todd C. Miller + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * Copy src to string dst of size siz. At most siz-1 characters + * will be copied. Always NUL terminates (unless siz == 0). + * Returns strlen(src); if retval >= siz, truncation occurred. + */ +inline size_t strlcpy(char *dst, const char *src, size_t siz) +{ + char *d = dst; + const char *s = src; + size_t n = siz; + + /* Copy as many bytes as will fit */ + if (n != 0) + { + while (--n != 0) + { + if ((*d++ = *s++) == '\0') + break; + } + } + + /* Not enough room in dst, add NUL and traverse rest of src */ + if (n == 0) + { + if (siz != 0) + *d = '\0'; /* NUL-terminate dst */ + while (*s++) + ; + } + + return(s - src - 1); /* count does not include NUL */ +} + +/* + * Appends src to string dst of size siz (unlike strncat, siz is the + * full size of dst, not space left). At most siz-1 characters + * will be copied. Always NUL terminates (unless siz <= strlen(dst)). + * Returns strlen(src) + MIN(siz, strlen(initial dst)). + * If retval >= siz, truncation occurred. + */ +inline size_t strlcat(char *dst, const char *src, size_t siz) +{ + char *d = dst; + const char *s = src; + size_t n = siz; + size_t dlen; + + /* Find the end of dst and adjust bytes left but don't go past end */ + while (n-- != 0 && *d != '\0') + d++; + dlen = d - dst; + n = siz - dlen; + + if (n == 0) + return(dlen + strlen(s)); + while (*s != '\0') + { + if (n != 1) + { + *d++ = *s; + n--; + } + s++; + } + *d = '\0'; + + return(dlen + (s - src)); /* count does not include NUL */ +} diff --git a/ui.cpp b/ui.cpp index 428304796e..917c64b445 100644 --- a/ui.cpp +++ b/ui.cpp @@ -497,7 +497,7 @@ string SingleLine(const string& strIn) return strOut; } -void CMainFrame::InsertTransaction(const CWalletTx& wtx, bool fNew, int nIndex) +bool CMainFrame::InsertTransaction(const CWalletTx& wtx, bool fNew, int nIndex) { int64 nTime = wtx.nTimeDisplayed = wtx.GetTxTime(); int64 nCredit = wtx.GetCredit(); @@ -506,14 +506,11 @@ void CMainFrame::InsertTransaction(const CWalletTx& wtx, bool fNew, int nIndex) uint256 hash = wtx.GetHash(); string strStatus = FormatTxStatus(wtx); map mapValue = wtx.mapValue; + wtx.nLinesDisplayed = 1; // Filter if (wtx.IsCoinBase()) { - // View->Show Generated - if (!fShowGenerated) - return; - // 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. // @@ -527,10 +524,13 @@ void CMainFrame::InsertTransaction(const CWalletTx& wtx, bool fNew, int nIndex) // if (wtx.GetDepthInMainChain() < 2) { - // In case it was previously displayed - DeleteLine(hash); - return; + wtx.nLinesDisplayed = 0; + return false; } + + // View->Show Generated + if (!fShowGenerated) + return false; } // Find the block the tx is in @@ -644,6 +644,7 @@ void CMainFrame::InsertTransaction(const CWalletTx& wtx, bool fNew, int nIndex) // Debit // int64 nTxFee = nDebit - wtx.GetValueOut(); + wtx.nLinesDisplayed = 0; for (int nOut = 0; nOut < wtx.vout.size(); nOut++) { const CTxOut& txout = wtx.vout[nOut]; @@ -685,6 +686,7 @@ void CMainFrame::InsertTransaction(const CWalletTx& wtx, bool fNew, int nIndex) SingleLine(strDescription), FormatMoney(-nValue, true), ""); + wtx.nLinesDisplayed++; } } else @@ -706,12 +708,14 @@ void CMainFrame::InsertTransaction(const CWalletTx& wtx, bool fNew, int nIndex) ""); } } + + return true; } void CMainFrame::RefreshStatus() { static int nLastTop; - int nTop = m_listCtrl->GetTopItem(); + int nTop = max((int)m_listCtrl->GetTopItem(), 0); if (nTop == nLastTop && pindexBestLast == pindexBest) return; @@ -729,7 +733,7 @@ void CMainFrame::RefreshStatus() nLastTop = nTop; pindexBestLast = pindexBest; - for (int nIndex = nStart; nIndex < nEnd; nIndex++) + for (int nIndex = nStart; nIndex < min(nEnd, m_listCtrl->GetItemCount()); nIndex++) { uint256 hash((string)GetItemText(m_listCtrl, nIndex, 1)); map::iterator mi = mapWallet.find(hash); @@ -738,9 +742,12 @@ void CMainFrame::RefreshStatus() printf("CMainFrame::RefreshStatus() : tx not found in mapWallet\n"); continue; } - const CWalletTx& wtx = (*mi).second; + CWalletTx& wtx = (*mi).second; if (wtx.IsCoinBase() || wtx.GetTxTime() != wtx.nTimeDisplayed) - InsertTransaction(wtx, false, nIndex); + { + if (!InsertTransaction(wtx, false, nIndex)) + m_listCtrl->DeleteItem(nIndex--); + } else m_listCtrl->SetItem(nIndex, 2, FormatTxStatus(wtx)); } @@ -801,6 +808,9 @@ void CMainFrame::OnIdle(wxIdleEvent& event) } printf("RefreshListCtrl done\n"); + + // Update transaction total display + MainFrameRepaint(); } else { @@ -834,31 +844,54 @@ void DelayedRepaint(void* parg) return; fOneThread = true; Sleep(1000); + printf("DelayedRepaint()\n"); MainFrameRepaint(); fOneThread = false; } void CMainFrame::OnPaintListCtrl(wxPaintEvent& event) { + if (ptaskbaricon) + ptaskbaricon->UpdateTooltip(); + // Update listctrl contents if (!vWalletUpdated.empty()) { TRY_CRITICAL_BLOCK(cs_mapWallet) { + bool fInserted = false; foreach(uint256 hash, vWalletUpdated) { map::iterator mi = mapWallet.find(hash); if (mi != mapWallet.end()) - InsertTransaction((*mi).second, false); + fInserted |= InsertTransaction((*mi).second, false); } - m_listCtrl->ScrollList(0, INT_MAX); vWalletUpdated.clear(); + if (fInserted) + m_listCtrl->ScrollList(0, INT_MAX); } } // Update status column of visible items only RefreshStatus(); + // Balance total + bool fRefreshed = false; + static int nTransactionCount; + TRY_CRITICAL_BLOCK(cs_mapWallet) + { + fRefreshed = true; + m_staticTextBalance->SetLabel(FormatMoney(GetBalance()) + " "); + + // Count hidden and multi-line transactions + nTransactionCount = 0; + for (map::iterator it = mapWallet.begin(); it != mapWallet.end(); ++it) + { + CWalletTx& wtx = (*it).second; + nTransactionCount += wtx.nLinesDisplayed; + } + } + // Update status bar string strGen = ""; if (fGenerateBitcoins) @@ -867,17 +900,9 @@ void CMainFrame::OnPaintListCtrl(wxPaintEvent& event) strGen = "(not connected)"; m_statusBar->SetStatusText(strGen, 1); - string strStatus = strprintf(" %d connections %d blocks %d transactions", vNodes.size(), nBestHeight + 1, m_listCtrl->GetItemCount()); + string strStatus = strprintf(" %d connections %d blocks %d transactions", vNodes.size(), nBestHeight + 1, nTransactionCount); m_statusBar->SetStatusText(strStatus, 2); - // Balance total - bool fRefreshed = false; - TRY_CRITICAL_BLOCK(cs_mapWallet) - { - m_staticTextBalance->SetLabel(FormatMoney(GetBalance()) + " "); - fRefreshed = true; - } - // mapWallet was locked, try again later if (!vWalletUpdated.empty() || !fRefreshed) _beginthread(DelayedRepaint, 0, NULL); @@ -1350,6 +1375,14 @@ COptionsDialog::COptionsDialog(wxWindow* parent) : COptionsDialogBase(parent) m_checkBoxMinimizeOnClose->Enable(fMinimizeToTray); m_checkBoxMinimizeOnClose->SetValue(fMinimizeToTray && fMinimizeOnClose); fTmpMinimizeOnClose = fMinimizeOnClose; + 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(); } @@ -1395,6 +1428,34 @@ void COptionsDialog::OnCheckBoxMinimizeToTray(wxCommandEvent& event) } +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) +{ + m_textCtrlProxyIP->SetValue(GetProxyAddr().ToStringIP()); + m_textCtrlProxyPort->SetValue(GetProxyAddr().ToStringPort()); +} + + void COptionsDialog::OnButtonOK(wxCommandEvent& event) { OnButtonApply(event); @@ -1446,6 +1507,18 @@ void COptionsDialog::OnButtonApply(wxCommandEvent& event) fMinimizeOnClose = (fMinimizeToTray ? m_checkBoxMinimizeOnClose->GetValue() : fTmpMinimizeOnClose); walletdb.WriteSetting("fMinimizeOnClose", fMinimizeOnClose); } + + if (fUseProxy != m_checkBoxUseProxy->GetValue()) + { + fUseProxy = m_checkBoxUseProxy->GetValue(); + walletdb.WriteSetting("fUseProxy", fUseProxy); + } + + if (addrProxy != GetProxyAddr()) + { + addrProxy = GetProxyAddr(); + walletdb.WriteSetting("addrProxy", addrProxy); + } } @@ -1657,7 +1730,7 @@ CSendingDialog::CSendingDialog(wxWindow* parent, const CAddress& addrIn, int64 n nPrice = nPriceIn; wtx = wtxIn; start = wxDateTime::UNow(); - strStatus = ""; + memset(pszStatus, 0, sizeof(pszStatus)); fCanCancel = true; fAbort = false; fSuccess = false; @@ -1721,10 +1794,10 @@ void CSendingDialog::OnButtonCancel(wxCommandEvent& event) void CSendingDialog::OnPaint(wxPaintEvent& event) { - if (strStatus.size() > 130) - m_textCtrlStatus->SetValue(string("\n") + strStatus); + if (strlen(pszStatus) > 130) + m_textCtrlStatus->SetValue(string("\n") + pszStatus); else - m_textCtrlStatus->SetValue(string("\n\n") + strStatus); + m_textCtrlStatus->SetValue(string("\n\n") + pszStatus); m_staticTextSending->SetFocus(); if (!fCanCancel) m_buttonCancel->Enable(false); @@ -1736,7 +1809,7 @@ void CSendingDialog::OnPaint(wxPaintEvent& event) } if (fAbort && fCanCancel && IsShown()) { - strStatus = "CANCELLED"; + strcpy(pszStatus, "CANCELLED"); m_buttonOK->Enable(true); m_buttonOK->SetFocus(); m_buttonCancel->Enable(false); @@ -1777,7 +1850,8 @@ bool CSendingDialog::Status() } if (fAbort && fCanCancel) { - strStatus = "CANCELLED"; + memset(pszStatus, 0, 10); + strcpy(pszStatus, "CANCELLED"); Repaint(); fWorkDone = true; return false; @@ -1789,7 +1863,12 @@ bool CSendingDialog::Status(const string& str) { if (!Status()) return false; - strStatus = str; + + // 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; } @@ -1950,8 +2029,8 @@ void CSendingDialog::OnReply3(CDataStream& vRecv) 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 if it is valid,\n" - "but without comment information."); + "The transaction is recorded and will credit to the recipient,\n" + "but the comment information will be blank."); return; } } @@ -3092,6 +3171,7 @@ END_EVENT_TABLE() void CMyTaskBarIcon::Show(bool fShow) { + static char pszPrevTip[200]; if (fShow) { string strTooltip = "Bitcoin"; @@ -3099,10 +3179,17 @@ void CMyTaskBarIcon::Show(bool fShow) strTooltip = "Bitcoin - Generating"; if (fGenerateBitcoins && vNodes.empty()) strTooltip = "Bitcoin - (not connected)"; - SetIcon(wxICON(bitcoin), strTooltip); + + // 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)); + SetIcon(wxICON(bitcoin), strTooltip); + } } else { + strlcpy(pszPrevTip, "", sizeof(pszPrevTip)); RemoveIcon(); } } @@ -3301,12 +3388,12 @@ bool CMyApp::OnInit2() if (mapArgs.count("/datadir")) strSetDataDir = mapArgs["/datadir"]; - if (mapArgs.count("/proxy")) - addrProxy = CAddress(mapArgs["/proxy"].c_str()); - if (mapArgs.count("/debug")) fDebug = true; + if (mapArgs.count("/printtodebugger")) + fPrintToDebugger = true; + if (mapArgs.count("/dropmessages")) { nDropMessagesTest = atoi(mapArgs["/dropmessages"]); @@ -3380,6 +3467,20 @@ bool CMyApp::OnInit2() return false; } + if (mapArgs.count("/proxy")) + { + fUseProxy = true; + addrProxy = CAddress(mapArgs["/proxy"].c_str()); + if (addrProxy.ip == INADDR_NONE) + { + wxMessageBox("Invalid /proxy address", "Bitcoin"); + OnExit(); + } + CWalletDB walletdb; + walletdb.WriteSetting("fUseProxy", fUseProxy); + walletdb.WriteSetting("addrProxy", addrProxy); + } + if (mapArgs.count("/gen")) { if (mapArgs["/gen"].empty()) @@ -3404,7 +3505,7 @@ bool CMyApp::OnInit2() return false; } - //RandAddSeedPerfmon(); + RandAddSeedPerfmon(); if (!StartNode(strErrors)) wxMessageBox(strErrors, "Bitcoin"); @@ -3514,7 +3615,7 @@ void CMyApp::OnFatalException() void MainFrameRepaint() { - // This is called by network code that shouldn't access pframeMain and ptaskbaricon + // 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) { @@ -3523,20 +3624,47 @@ void MainFrameRepaint() pframeMain->Refresh(); pframeMain->AddPendingEvent(event); } - if (ptaskbaricon) - ptaskbaricon->UpdateTooltip(); } +typedef WINSHELLAPI BOOL WINAPI (*PSHGETSPECIALFOLDERPATHA)(HWND hwndOwner, LPSTR lpszPath, int nFolder, BOOL fCreate); + +string MyGetSpecialFolderPath(int nFolder, bool fCreate) +{ + char pszPath[MAX_PATH+100] = ""; + + // SHGetSpecialFolderPath is not usually available on NT 4.0 + HMODULE hShell32 = LoadLibrary("shell32.dll"); + if (hShell32) + { + PSHGETSPECIALFOLDERPATHA pSHGetSpecialFolderPath = + (PSHGETSPECIALFOLDERPATHA)GetProcAddress(hShell32, "SHGetSpecialFolderPathA"); + if (pSHGetSpecialFolderPath) + (*pSHGetSpecialFolderPath)(NULL, pszPath, nFolder, fCreate); + FreeModule(hShell32); + } + + // Backup option + if (pszPath[0] == '\0') + { + if (nFolder == CSIDL_STARTUP) + { + strcpy(pszPath, getenv("USERPROFILE")); + strcat(pszPath, "\\Start Menu\\Programs\\Startup"); + } + else if (nFolder == CSIDL_APPDATA) + { + strcpy(pszPath, getenv("APPDATA")); + } + } + + return pszPath; +} + string StartupShortcutPath() { - // Get the startup folder shortcut path - char pszLinkPath[MAX_PATH+100]; - pszLinkPath[0] = '\0'; - SHGetSpecialFolderPath(0, pszLinkPath, CSIDL_STARTUP, 0); - strcat(pszLinkPath, "\\Bitcoin.lnk"); - return pszLinkPath; + return MyGetSpecialFolderPath(CSIDL_STARTUP, true) + "\\Bitcoin.lnk"; } bool GetStartOnSystemStartup() @@ -3630,7 +3758,8 @@ void ThreadRandSendTest(void* parg) if (GetBalance() < nValue) { wxMessageBox("Out of money "); - return; + while (GetBalance() < 1000) + Sleep(1000); } nValue += (nRep % 100) * CENT; diff --git a/ui.h b/ui.h index f451d93565..9fc7e0ebe7 100644 --- a/ui.h +++ b/ui.h @@ -89,7 +89,7 @@ public: void OnCrossThreadCall(wxCommandEvent& event); void InsertLine(bool fNew, int nIndex, uint256 hashKey, string strSort, const wxString& str1, const wxString& str2, const wxString& str3, const wxString& str4, const wxString& str5); bool DeleteLine(uint256 hashKey); - void InsertTransaction(const CWalletTx& wtx, bool fNew, int nIndex=-1); + bool InsertTransaction(const CWalletTx& wtx, bool fNew, int nIndex=-1); void RefreshListCtrl(); void RefreshStatus(); }; @@ -121,6 +121,9 @@ protected: void OnKillFocusTransactionFee(wxFocusEvent& event); void OnCheckBoxLimitProcessors(wxCommandEvent& event); void OnCheckBoxMinimizeToTray(wxCommandEvent& event); + void OnCheckBoxUseProxy(wxCommandEvent& event); + void OnKillFocusProxy(wxFocusEvent& event); + void OnButtonOK(wxCommandEvent& event); void OnButtonCancel(wxCommandEvent& event); void OnButtonApply(wxCommandEvent& event); @@ -133,6 +136,7 @@ public: bool fTmpStartOnSystemStartup; bool fTmpMinimizeOnClose; void SelectPage(int nPage); + CAddress GetProxyAddr(); }; @@ -193,7 +197,7 @@ public: int64 nPrice; CWalletTx wtx; wxDateTime start; - string strStatus; + char pszStatus[10000]; bool fCanCancel; bool fAbort; bool fSuccess; diff --git a/uibase.cpp b/uibase.cpp index 0f9e22c528..b03e578bd8 100644 --- a/uibase.cpp +++ b/uibase.cpp @@ -380,7 +380,7 @@ COptionsDialogBase::COptionsDialogBase( wxWindow* parent, wxWindowID id, const w bSizer69 = new wxBoxSizer( wxVERTICAL ); - bSizer69->Add( 0, 14, 0, wxEXPAND, 5 ); + bSizer69->Add( 0, 16, 0, wxEXPAND, 5 ); m_staticText32 = new wxStaticText( m_panelMain, wxID_ANY, wxT("Optional transaction fee you give to the nodes that process your transactions."), wxDefaultPosition, wxDefaultSize, 0 ); m_staticText32->Wrap( -1 ); @@ -412,7 +412,7 @@ COptionsDialogBase::COptionsDialogBase( wxWindow* parent, wxWindowID id, const w bSizer71->Add( m_checkBoxLimitProcessors, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 ); m_spinCtrlLimitProcessors = new wxSpinCtrl( m_panelMain, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize( 48,-1 ), wxSP_ARROW_KEYS, 1, 999, 1 ); - bSizer71->Add( m_spinCtrlLimitProcessors, 0, wxTOP|wxBOTTOM, 5 ); + bSizer71->Add( m_spinCtrlLimitProcessors, 0, wxALIGN_CENTER_VERTICAL, 5 ); m_staticText35 = new wxStaticText( m_panelMain, wxID_ANY, wxT("processors"), wxDefaultPosition, wxDefaultSize, 0 ); m_staticText35->Wrap( -1 ); @@ -434,12 +434,45 @@ COptionsDialogBase::COptionsDialogBase( wxWindow* parent, wxWindowID id, const w bSizer101->Add( 16, 0, 0, 0, 5 ); - m_checkBoxMinimizeOnClose = new wxCheckBox( m_panelMain, wxID_ANY, wxT("M&inimize to system tray on close"), wxDefaultPosition, wxDefaultSize, 0 ); + m_checkBoxMinimizeOnClose = new wxCheckBox( m_panelMain, wxID_ANY, wxT("Mi&nimize to system tray on close"), wxDefaultPosition, wxDefaultSize, 0 ); - bSizer101->Add( m_checkBoxMinimizeOnClose, 0, wxALL, 5 ); + bSizer101->Add( m_checkBoxMinimizeOnClose, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); bSizer69->Add( bSizer101, 1, wxEXPAND, 5 ); + wxBoxSizer* bSizer102; + bSizer102 = new wxBoxSizer( wxHORIZONTAL ); + + m_checkBoxUseProxy = new wxCheckBox( m_panelMain, wxID_ANY, wxT("&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, wxT("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, wxT(" &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 ); + m_panelMain->SetSizer( bSizer69 ); m_panelMain->Layout(); bSizer69->Fit( m_panelMain ); @@ -450,13 +483,13 @@ COptionsDialogBase::COptionsDialogBase( wxWindow* parent, wxWindowID id, const w bSizer64 = new wxBoxSizer( wxVERTICAL ); - bSizer64->Add( 0, 14, 0, wxEXPAND, 5 ); + bSizer64->Add( 0, 16, 0, wxEXPAND, 5 ); m_staticText321 = new wxStaticText( m_panelTest2, wxID_ANY, wxT("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, wxT("MyLabel"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticText69 = new wxStaticText( m_panelTest2, wxID_ANY, wxT("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 ); @@ -506,6 +539,9 @@ COptionsDialogBase::COptionsDialogBase( wxWindow* parent, wxWindowID id, const w m_textCtrlTransactionFee->Connect( wxEVT_KILL_FOCUS, wxFocusEventHandler( COptionsDialogBase::OnKillFocusTransactionFee ), NULL, this ); m_checkBoxLimitProcessors->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( COptionsDialogBase::OnCheckBoxLimitProcessors ), 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_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 ); @@ -518,6 +554,9 @@ COptionsDialogBase::~COptionsDialogBase() m_textCtrlTransactionFee->Disconnect( wxEVT_KILL_FOCUS, wxFocusEventHandler( COptionsDialogBase::OnKillFocusTransactionFee ), NULL, this ); m_checkBoxLimitProcessors->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( COptionsDialogBase::OnCheckBoxLimitProcessors ), 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_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 ); diff --git a/uibase.h b/uibase.h index e262a3dcb6..d52158f127 100644 --- a/uibase.h +++ b/uibase.h @@ -50,50 +50,52 @@ #define wxID_BUTTONCOPY 1006 #define wxID_BUTTONCHANGE 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_BUTTONNEW 1016 -#define wxID_BUTTONEDIT 1017 -#define wxID_BUTTONDELETE 1018 -#define wxID_DEL0 1019 -#define wxID_DEL1 1020 -#define wxID_DEL2 1021 -#define wxID_DEL3 1022 -#define wxID_DEL4 1023 -#define wxID_DEL5 1024 -#define wxID_DEL6 1025 -#define wxID_DEL7 1026 -#define wxID_DEL8 1027 -#define wxID_DEL9 1028 -#define wxID_DEL10 1029 -#define wxID_DEL11 1030 -#define wxID_DEL12 1031 -#define wxID_DEL13 1032 -#define wxID_DEL14 1033 -#define wxID_DEL15 1034 -#define wxID_DEL16 1035 -#define wxID_DEL17 1036 -#define wxID_DEL18 1037 -#define wxID_DEL19 1038 -#define wxID_BUTTONPREVIEW 1039 -#define wxID_BUTTONSAMPLE 1040 -#define wxID_CANCEL2 1041 -#define wxID_BUTTONBACK 1042 -#define wxID_BUTTONNEXT 1043 -#define wxID_SUBMIT 1044 -#define wxID_OPENNEWTABLE 1045 -#define wxID_DEALHAND 1046 -#define wxID_FOLD 1047 -#define wxID_CALL 1048 -#define wxID_RAISE 1049 -#define wxID_LEAVETABLE 1050 -#define wxID_DITCHPLAYER 1051 -#define wxID_TEXTCTRL 1052 +#define wxID_PROXYIP 1009 +#define wxID_PROXYPORT 1010 +#define wxID_TEXTCTRLPAYTO 1011 +#define wxID_BUTTONPASTE 1012 +#define wxID_BUTTONADDRESSBOOK 1013 +#define wxID_TEXTCTRLAMOUNT 1014 +#define wxID_CHOICETRANSFERTYPE 1015 +#define wxID_LISTCTRL 1016 +#define wxID_BUTTONRENAME 1017 +#define wxID_BUTTONNEW 1018 +#define wxID_BUTTONEDIT 1019 +#define wxID_BUTTONDELETE 1020 +#define wxID_DEL0 1021 +#define wxID_DEL1 1022 +#define wxID_DEL2 1023 +#define wxID_DEL3 1024 +#define wxID_DEL4 1025 +#define wxID_DEL5 1026 +#define wxID_DEL6 1027 +#define wxID_DEL7 1028 +#define wxID_DEL8 1029 +#define wxID_DEL9 1030 +#define wxID_DEL10 1031 +#define wxID_DEL11 1032 +#define wxID_DEL12 1033 +#define wxID_DEL13 1034 +#define wxID_DEL14 1035 +#define wxID_DEL15 1036 +#define wxID_DEL16 1037 +#define wxID_DEL17 1038 +#define wxID_DEL18 1039 +#define wxID_DEL19 1040 +#define wxID_BUTTONPREVIEW 1041 +#define wxID_BUTTONSAMPLE 1042 +#define wxID_CANCEL2 1043 +#define wxID_BUTTONBACK 1044 +#define wxID_BUTTONNEXT 1045 +#define wxID_SUBMIT 1046 +#define wxID_OPENNEWTABLE 1047 +#define wxID_DEALHAND 1048 +#define wxID_FOLD 1049 +#define wxID_CALL 1050 +#define wxID_RAISE 1051 +#define wxID_LEAVETABLE 1052 +#define wxID_DITCHPLAYER 1053 +#define wxID_TEXTCTRL 1054 /////////////////////////////////////////////////////////////////////////////// /// Class CMainFrameBase @@ -211,6 +213,12 @@ class COptionsDialogBase : public wxDialog wxCheckBox* m_checkBoxMinimizeToTray; wxCheckBox* m_checkBoxMinimizeOnClose; + wxCheckBox* m_checkBoxUseProxy; + + wxStaticText* m_staticTextProxyIP; + wxTextCtrl* m_textCtrlProxyIP; + wxStaticText* m_staticTextProxyPort; + wxTextCtrl* m_textCtrlProxyPort; wxPanel* m_panelTest2; wxStaticText* m_staticText321; @@ -226,6 +234,8 @@ class COptionsDialogBase : public wxDialog virtual void OnKillFocusTransactionFee( wxFocusEvent& event ){ event.Skip(); } virtual void OnCheckBoxLimitProcessors( 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 OnButtonOK( wxCommandEvent& event ){ event.Skip(); } virtual void OnButtonCancel( wxCommandEvent& event ){ event.Skip(); } virtual void OnButtonApply( wxCommandEvent& event ){ event.Skip(); } diff --git a/uiproject.fbp b/uiproject.fbp index af5876b4ab..313e5aa6cc 100644 --- a/uiproject.fbp +++ b/uiproject.fbp @@ -1912,7 +1912,7 @@ wxEXPAND 0 - 14 + 16 protected 0 @@ -2148,7 +2148,7 @@ 5 - wxTOP|wxBOTTOM + wxALIGN_CENTER_VERTICAL 0 @@ -2379,7 +2379,7 @@ 5 - wxALL + wxALL|wxALIGN_CENTER_VERTICAL 0 @@ -2390,7 +2390,7 @@ 0 wxID_ANY - M&inimize to system tray on close + Mi&nimize to system tray on close m_checkBoxMinimizeOnClose @@ -2431,6 +2431,302 @@ + + 5 + wxEXPAND + 1 + + + bSizer102 + wxHORIZONTAL + none + + 5 + wxALL|wxALIGN_CENTER_VERTICAL + 0 + + + 0 + + 1 + + + 0 + wxID_ANY + &Connect through socks4 proxy: + + + m_checkBoxUseProxy + protected + + + + + + + + + + OnCheckBoxUseProxy + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND + 1 + + + bSizer103 + wxHORIZONTAL + none + + 5 + + 0 + + 0 + protected + 18 + + + + 5 + wxALL|wxALIGN_CENTER_VERTICAL + 0 + + + + 1 + + + 0 + wxID_ANY + Proxy &IP: + + + m_staticTextProxyIP + protected + + + + + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALIGN_CENTER_VERTICAL + 0 + + + + 1 + + + 0 + wxID_PROXYIP + + 15 + + m_textCtrlProxyIP + protected + + 140,-1 + + + + + + + + + + + + + OnKillFocusProxy + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL|wxALIGN_CENTER_VERTICAL + 0 + + + + 1 + + + 0 + wxID_ANY + &Port: + + + m_staticTextProxyPort + protected + + + + + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALIGN_CENTER_VERTICAL + 0 + + + + 1 + + + 0 + wxID_PROXYPORT + + 5 + + m_textCtrlProxyPort + protected + + 55,-1 + + + + + + + + + + + + + OnKillFocusProxy + + + + + + + + + + + + + + + + + + + + + + + + + @@ -2490,7 +2786,7 @@ wxEXPAND 0 - 14 + 16 protected 0 @@ -2558,7 +2854,7 @@ 0 wxID_ANY - MyLabel + Let's not start multiple pages until the first page is filled up m_staticText69 diff --git a/util.cpp b/util.cpp index 8271474eee..6ba84a516d 100644 --- a/util.cpp +++ b/util.cpp @@ -5,8 +5,9 @@ #include "headers.h" - bool fDebug = false; +bool fPrintToDebugger = false; +bool fPrintToConsole = false; @@ -37,8 +38,8 @@ public: // Seed random number generator with screen scrape and other hardware sources RAND_screen(); - // Seed random number generator with perfmon data - RandAddSeed(true); + // Seed random number generator with performance counter + RandAddSeed(); } ~CInit() { @@ -54,40 +55,43 @@ instance_of_cinit; -void RandAddSeed(bool fPerfmon) +void RandAddSeed() { // Seed with CPU performance counter LARGE_INTEGER PerformanceCount; QueryPerformanceCounter(&PerformanceCount); RAND_add(&PerformanceCount, sizeof(PerformanceCount), 1.5); memset(&PerformanceCount, 0, sizeof(PerformanceCount)); +} +void RandAddSeedPerfmon() +{ + // This can take up to 2 seconds, so only do it every 10 minutes static int64 nLastPerfmon; - if (fPerfmon || GetTime() > nLastPerfmon + 5 * 60) + if (GetTime() < nLastPerfmon + 10 * 60) + return; + nLastPerfmon = GetTime(); + + // Seed with the entire set of perfmon data + unsigned char pdata[250000]; + memset(pdata, 0, sizeof(pdata)); + unsigned long nSize = sizeof(pdata); + long ret = RegQueryValueEx(HKEY_PERFORMANCE_DATA, "Global", NULL, NULL, pdata, &nSize); + RegCloseKey(HKEY_PERFORMANCE_DATA); + if (ret == ERROR_SUCCESS) { - nLastPerfmon = GetTime(); - - // Seed with the entire set of perfmon data - unsigned char pdata[250000]; - memset(pdata, 0, sizeof(pdata)); - unsigned long nSize = sizeof(pdata); - long ret = RegQueryValueEx(HKEY_PERFORMANCE_DATA, "Global", NULL, NULL, pdata, &nSize); - RegCloseKey(HKEY_PERFORMANCE_DATA); - if (ret == ERROR_SUCCESS) - { - uint256 hash; - SHA256(pdata, nSize, (unsigned char*)&hash); - RAND_add(&hash, sizeof(hash), min(nSize/500.0, (double)sizeof(hash))); - hash = 0; - memset(pdata, 0, nSize); - - time_t nTime; - time(&nTime); - struct tm* ptmTime = gmtime(&nTime); - char pszTime[200]; - strftime(pszTime, sizeof(pszTime), "%x %H:%M:%S", ptmTime); - printf("%s RandAddSeed() %d bytes\n", pszTime, nSize); - } + uint256 hash; + SHA256(pdata, nSize, (unsigned char*)&hash); + RAND_add(&hash, sizeof(hash), min(nSize/500.0, (double)sizeof(hash))); + hash = 0; + memset(pdata, 0, nSize); + + time_t nTime; + time(&nTime); + struct tm* ptmTime = gmtime(&nTime); + char pszTime[200]; + strftime(pszTime, sizeof(pszTime), "%x %H:%M:%S", ptmTime); + printf("%s RandAddSeed() %d bytes\n", pszTime, nSize); } } @@ -99,7 +103,6 @@ void RandAddSeed(bool fPerfmon) - // Safer snprintf // - prints up to limit-1 characters // - output string is always null terminated even if limit reached @@ -172,27 +175,6 @@ bool error(const char* format, ...) } -void PrintException(std::exception* pex, const char* pszThread) -{ - char pszModule[MAX_PATH]; - pszModule[0] = '\0'; - GetModuleFileName(NULL, pszModule, sizeof(pszModule)); - _strlwr(pszModule); - char pszMessage[1000]; - if (pex) - snprintf(pszMessage, sizeof(pszMessage), - "EXCEPTION: %s \n%s \n%s in %s \n", typeid(*pex).name(), pex->what(), pszModule, pszThread); - else - snprintf(pszMessage, sizeof(pszMessage), - "UNKNOWN EXCEPTION \n%s in %s \n", pszModule, pszThread); - printf("\n\n************************\n%s", pszMessage); - if (wxTheApp) - wxMessageBox(pszMessage, "Error", wxOK | wxICON_ERROR); - throw; - //DebugBreak(); -} - - void ParseString(const string& str, char c, vector& v) { unsigned int i1 = 0; @@ -268,6 +250,92 @@ bool ParseMoney(const char* pszIn, int64& nRet) } +vector ParseHex(const char* psz) +{ + vector vch; + while (isspace(*psz)) + psz++; + vch.reserve((strlen(psz)+1)/3); + + static char phexdigit[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,-1,-1,-1,-1,-1, + 0,1,2,3,4,5,6,7,8,9,-1,-1,-1,-1,-1,-1, + -1,0xa,0xb,0xc,0xd,0xe,0xf,-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,0xa,0xb,0xc,0xd,0xe,0xf,-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,-1,-1,-1,-1, + -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, }; + + while (*psz) + { + char c = phexdigit[(unsigned char)*psz++]; + if (c == -1) + break; + unsigned char n = (c << 4); + if (*psz) + { + char c = phexdigit[(unsigned char)*psz++]; + if (c == -1) + break; + n |= c; + vch.push_back(n); + } + while (isspace(*psz)) + psz++; + } + + return vch; +} + +vector ParseHex(const std::string& str) +{ + return ParseHex(str.c_str()); +} + + + + + + +void FormatException(char* pszMessage, std::exception* pex, const char* pszThread) +{ + char pszModule[MAX_PATH]; + pszModule[0] = '\0'; + GetModuleFileName(NULL, pszModule, sizeof(pszModule)); + if (pex) + snprintf(pszMessage, 1000, + "EXCEPTION: %s \n%s \n%s in %s \n", typeid(*pex).name(), pex->what(), pszModule, pszThread); + else + snprintf(pszMessage, 1000, + "UNKNOWN EXCEPTION \n%s in %s \n", pszModule, pszThread); +} + +void LogException(std::exception* pex, const char* pszThread) +{ + char pszMessage[1000]; + FormatException(pszMessage, pex, pszThread); + printf("\n%s", pszMessage); +} + +void PrintException(std::exception* pex, const char* pszThread) +{ + char pszMessage[1000]; + FormatException(pszMessage, pex, pszThread); + printf("\n\n************************\n%s\n", pszMessage); + if (wxTheApp) + wxMessageBox(pszMessage, "Error", wxOK | wxICON_ERROR); + throw; + //DebugBreak(); +} @@ -363,7 +431,7 @@ void AddTimeData(unsigned int ip, int64 nTime) if (vTimeOffsets.empty()) vTimeOffsets.push_back(0); vTimeOffsets.push_back(nOffsetSample); - printf("Added time data, samples %d, ip %08x, offset %+I64d (%+I64d minutes)\n", vTimeOffsets.size(), ip, vTimeOffsets.back(), vTimeOffsets.back()/60); + printf("Added time data, samples %d, offset %+I64d (%+I64d minutes)\n", vTimeOffsets.size(), vTimeOffsets.back(), vTimeOffsets.back()/60); if (vTimeOffsets.size() >= 5 && vTimeOffsets.size() % 2 == 1) { sort(vTimeOffsets.begin(), vTimeOffsets.end()); diff --git a/util.h b/util.h index 97617ab490..61f774a8d9 100644 --- a/util.h +++ b/util.h @@ -67,15 +67,22 @@ inline T& REF(const T& val) extern bool fDebug; +extern bool fPrintToDebugger; +extern bool fPrintToConsole; +extern map mapArgs; -void RandAddSeed(bool fPerfmon=false); +void RandAddSeed(); +void RandAddSeedPerfmon(); int my_snprintf(char* buffer, size_t limit, const char* format, ...); string strprintf(const char* format, ...); bool error(const char* format, ...); void PrintException(std::exception* pex, const char* pszThread); +void LogException(std::exception* pex, const char* pszThread); void ParseString(const string& str, char c, vector& v); string FormatMoney(int64 n, bool fPlus=false); bool ParseMoney(const char* pszIn, int64& nRet); +vector ParseHex(const char* psz); +vector ParseHex(const std::string& str); bool FileExists(const char* psz); int GetFilesize(FILE* file); uint64 GetRand(uint64 nMax); @@ -94,6 +101,7 @@ void AddTimeData(unsigned int ip, int64 nTime); + // Wrapper to automatically initialize critical section // Could use wxCriticalSection for portability, but it doesn't support TryEnterCriticalSection class CCriticalSection @@ -156,6 +164,85 @@ public: +inline int OutputDebugStringF(const char* pszFormat, ...) +{ + int ret = 0; +#ifdef __WXDEBUG__ + if (!fPrintToConsole) + { + // print to debug.log + FILE* fileout = fopen("debug.log", "a"); + if (fileout) + { + va_list arg_ptr; + va_start(arg_ptr, pszFormat); + ret = vfprintf(fileout, pszFormat, arg_ptr); + va_end(arg_ptr); + fclose(fileout); + } + } + + if (fPrintToDebugger) + { + // accumulate a line at a time + static CCriticalSection cs_OutputDebugStringF; + CRITICAL_BLOCK(cs_OutputDebugStringF) + { + static char pszBuffer[50000]; + static char* pend; + if (pend == NULL) + pend = pszBuffer; + va_list arg_ptr; + va_start(arg_ptr, pszFormat); + int limit = END(pszBuffer) - pend - 2; + int ret = _vsnprintf(pend, limit, pszFormat, arg_ptr); + va_end(arg_ptr); + if (ret < 0 || ret >= limit) + { + pend = END(pszBuffer) - 2; + *pend++ = '\n'; + } + else + pend += ret; + *pend = '\0'; + char* p1 = pszBuffer; + char* p2; + while (p2 = strchr(p1, '\n')) + { + p2++; + char c = *p2; + *p2 = '\0'; + OutputDebugString(p1); + *p2 = c; + p1 = p2; + } + if (p1 != pszBuffer) + memmove(pszBuffer, p1, pend - p1 + 1); + pend -= (p1 - pszBuffer); + } + } +#endif + + if (fPrintToConsole) + { + // print to console + va_list arg_ptr; + va_start(arg_ptr, pszFormat); + ret = vprintf(pszFormat, arg_ptr); + va_end(arg_ptr); + } + return ret; +} + + + + + + + + + + inline string i64tostr(int64 n) { return strprintf("%"PRId64, n); @@ -205,6 +292,11 @@ string HexStr(const T itbegin, const T itend, bool fSpaces=true) return str; } +inline string HexStr(vector vch, bool fSpaces=true) +{ + return HexStr(vch.begin(), vch.end(), fSpaces); +} + template string HexNumStr(const T itbegin, const T itend, bool f0x=true) { @@ -222,75 +314,9 @@ void PrintHex(const T pbegin, const T pend, const char* pszFormat="%s", bool fSp printf(pszFormat, HexStr(pbegin, pend, fSpaces).c_str()); } - - - - - - - -inline int OutputDebugStringF(const char* pszFormat, ...) +inline void PrintHex(vector vch, const char* pszFormat="%s", bool fSpaces=true) { -#ifdef __WXDEBUG__ - // log file - FILE* fileout = fopen("debug.log", "a"); - if (fileout) - { - va_list arg_ptr; - va_start(arg_ptr, pszFormat); - vfprintf(fileout, pszFormat, arg_ptr); - va_end(arg_ptr); - fclose(fileout); - } - - // accumulate a line at a time - static CCriticalSection cs_OutputDebugStringF; - CRITICAL_BLOCK(cs_OutputDebugStringF) - { - static char pszBuffer[50000]; - static char* pend; - if (pend == NULL) - pend = pszBuffer; - va_list arg_ptr; - va_start(arg_ptr, pszFormat); - int limit = END(pszBuffer) - pend - 2; - int ret = _vsnprintf(pend, limit, pszFormat, arg_ptr); - va_end(arg_ptr); - if (ret < 0 || ret >= limit) - { - pend = END(pszBuffer) - 2; - *pend++ = '\n'; - } - else - pend += ret; - *pend = '\0'; - char* p1 = pszBuffer; - char* p2; - while (p2 = strchr(p1, '\n')) - { - p2++; - char c = *p2; - *p2 = '\0'; - OutputDebugString(p1); - *p2 = c; - p1 = p2; - } - if (p1 != pszBuffer) - memmove(pszBuffer, p1, pend - p1 + 1); - pend -= (p1 - pszBuffer); - return ret; - } -#endif - - if (!wxTheApp) - { - // print to console - va_list arg_ptr; - va_start(arg_ptr, pszFormat); - vprintf(pszFormat, arg_ptr); - va_end(arg_ptr); - } - return 0; + printf(pszFormat, HexStr(vch, fSpaces).c_str()); } -- cgit v1.2.3 From fc0e97a70ee295da44096fa590a1f7674b936590 Mon Sep 17 00:00:00 2001 From: s_nakamoto Date: Thu, 29 Oct 2009 05:55:56 +0000 Subject: CCriticalSection using wxWidgets instead of Windows OS calls --- net.h | 6 +++--- util.cpp | 20 ++++++++++++-------- util.h | 31 ++++++++++++++++++++----------- 3 files changed, 35 insertions(+), 22 deletions(-) diff --git a/net.h b/net.h index a0b2929daa..5995ac3343 100644 --- a/net.h +++ b/net.h @@ -604,7 +604,7 @@ public: void BeginMessage(const char* pszCommand) { - EnterCriticalSection(&cs_vSend); + cs_vSend.Enter(); if (nPushPos != -1) AbortMessage(); nPushPos = vSend.size(); @@ -618,7 +618,7 @@ public: return; vSend.resize(nPushPos); nPushPos = -1; - LeaveCriticalSection(&cs_vSend); + cs_vSend.Leave(); printf("(aborted)\n"); } @@ -643,7 +643,7 @@ public: printf("\n"); nPushPos = -1; - LeaveCriticalSection(&cs_vSend); + cs_vSend.Leave(); } void EndMessageAbortIfEmpty() diff --git a/util.cpp b/util.cpp index 6ba84a516d..bdf899d78e 100644 --- a/util.cpp +++ b/util.cpp @@ -13,14 +13,14 @@ bool fPrintToConsole = false; // Init openssl library multithreading support -static HANDLE* lock_cs; +static wxMutex** ppmutexOpenSSL; -void win32_locking_callback(int mode, int type, const char* file, int line) +void win32_locking_callback(int mode, int i, const char* file, int line) { if (mode & CRYPTO_LOCK) - WaitForSingleObject(lock_cs[type], INFINITE); + ppmutexOpenSSL[i]->Lock(); else - ReleaseMutex(lock_cs[type]); + ppmutexOpenSSL[i]->Unlock(); } // Init @@ -30,9 +30,9 @@ public: CInit() { // Init openssl library multithreading support - lock_cs = (HANDLE*)OPENSSL_malloc(CRYPTO_num_locks() * sizeof(HANDLE)); + ppmutexOpenSSL = (wxMutex**)OPENSSL_malloc(CRYPTO_num_locks() * sizeof(wxMutex*)); for (int i = 0; i < CRYPTO_num_locks(); i++) - lock_cs[i] = CreateMutex(NULL,FALSE,NULL); + ppmutexOpenSSL[i] = new wxMutex(); CRYPTO_set_locking_callback(win32_locking_callback); // Seed random number generator with screen scrape and other hardware sources @@ -46,8 +46,8 @@ public: // Shutdown openssl library multithreading support CRYPTO_set_locking_callback(NULL); for (int i =0 ; i < CRYPTO_num_locks(); i++) - CloseHandle(lock_cs[i]); - OPENSSL_free(lock_cs); + delete ppmutexOpenSSL[i]; + OPENSSL_free(ppmutexOpenSSL); } } instance_of_cinit; @@ -55,6 +55,10 @@ instance_of_cinit; + + + + void RandAddSeed() { // Seed with CPU performance counter diff --git a/util.h b/util.h index 61f774a8d9..436281c90a 100644 --- a/util.h +++ b/util.h @@ -106,28 +106,38 @@ void AddTimeData(unsigned int ip, int64 nTime); // Could use wxCriticalSection for portability, but it doesn't support TryEnterCriticalSection class CCriticalSection { +#ifdef __WXMSW__ protected: CRITICAL_SECTION cs; public: - char* pszFile; - int nLine; explicit CCriticalSection() { InitializeCriticalSection(&cs); } ~CCriticalSection() { DeleteCriticalSection(&cs); } void Enter() { EnterCriticalSection(&cs); } void Leave() { LeaveCriticalSection(&cs); } bool TryEnter() { return TryEnterCriticalSection(&cs); } - CRITICAL_SECTION* operator&() { return &cs; } +#else +protected: + wxMutex mutex; +public: + explicit CCriticalSection() { } + ~CCriticalSection() { } + void Enter() { mutex.Lock(); } + void Leave() { mutex.Unlock(); } + bool TryEnter() { return mutex.TryLock() == wxMUTEX_NO_ERROR; } +#endif +public: + char* pszFile; + int nLine; }; // Automatically leave critical section when leaving block, needed for exception safety class CCriticalBlock { protected: - CRITICAL_SECTION* pcs; + CCriticalSection* pcs; public: - CCriticalBlock(CRITICAL_SECTION& csIn) { pcs = &csIn; EnterCriticalSection(pcs); } - CCriticalBlock(CCriticalSection& csIn) { pcs = &csIn; EnterCriticalSection(pcs); } - ~CCriticalBlock() { LeaveCriticalSection(pcs); } + CCriticalBlock(CCriticalSection& csIn) { pcs = &csIn; pcs->Enter(); } + ~CCriticalBlock() { pcs->Leave(); } }; // WARNING: This will catch continue and break! @@ -141,11 +151,10 @@ public: class CTryCriticalBlock { protected: - CRITICAL_SECTION* pcs; + CCriticalSection* pcs; public: - CTryCriticalBlock(CRITICAL_SECTION& csIn) { pcs = (TryEnterCriticalSection(&csIn) ? &csIn : NULL); } - CTryCriticalBlock(CCriticalSection& csIn) { pcs = (TryEnterCriticalSection(&csIn) ? &csIn : NULL); } - ~CTryCriticalBlock() { if (pcs) LeaveCriticalSection(pcs); } + CTryCriticalBlock(CCriticalSection& csIn) { pcs = (csIn.TryEnter() ? &csIn : NULL); } + ~CTryCriticalBlock() { if (pcs) pcs->Leave(); } bool Entered() { return pcs != NULL; } }; -- cgit v1.2.3 From dc73b326f97f2ed7ec7b7e8485ebc9eb46e05ddb Mon Sep 17 00:00:00 2001 From: s_nakamoto Date: Thu, 29 Oct 2009 05:55:56 +0000 Subject: CCriticalSection using wxWidgets instead of Windows OS calls git-svn-id: https://bitcoin.svn.sourceforge.net/svnroot/bitcoin/trunk@19 1a98c847-1fd6-4fd8-948a-caf3550aa51b --- net.h | 6 +++--- util.cpp | 20 ++++++++++++-------- util.h | 31 ++++++++++++++++++++----------- 3 files changed, 35 insertions(+), 22 deletions(-) diff --git a/net.h b/net.h index a0b2929daa..5995ac3343 100644 --- a/net.h +++ b/net.h @@ -604,7 +604,7 @@ public: void BeginMessage(const char* pszCommand) { - EnterCriticalSection(&cs_vSend); + cs_vSend.Enter(); if (nPushPos != -1) AbortMessage(); nPushPos = vSend.size(); @@ -618,7 +618,7 @@ public: return; vSend.resize(nPushPos); nPushPos = -1; - LeaveCriticalSection(&cs_vSend); + cs_vSend.Leave(); printf("(aborted)\n"); } @@ -643,7 +643,7 @@ public: printf("\n"); nPushPos = -1; - LeaveCriticalSection(&cs_vSend); + cs_vSend.Leave(); } void EndMessageAbortIfEmpty() diff --git a/util.cpp b/util.cpp index 6ba84a516d..bdf899d78e 100644 --- a/util.cpp +++ b/util.cpp @@ -13,14 +13,14 @@ bool fPrintToConsole = false; // Init openssl library multithreading support -static HANDLE* lock_cs; +static wxMutex** ppmutexOpenSSL; -void win32_locking_callback(int mode, int type, const char* file, int line) +void win32_locking_callback(int mode, int i, const char* file, int line) { if (mode & CRYPTO_LOCK) - WaitForSingleObject(lock_cs[type], INFINITE); + ppmutexOpenSSL[i]->Lock(); else - ReleaseMutex(lock_cs[type]); + ppmutexOpenSSL[i]->Unlock(); } // Init @@ -30,9 +30,9 @@ public: CInit() { // Init openssl library multithreading support - lock_cs = (HANDLE*)OPENSSL_malloc(CRYPTO_num_locks() * sizeof(HANDLE)); + ppmutexOpenSSL = (wxMutex**)OPENSSL_malloc(CRYPTO_num_locks() * sizeof(wxMutex*)); for (int i = 0; i < CRYPTO_num_locks(); i++) - lock_cs[i] = CreateMutex(NULL,FALSE,NULL); + ppmutexOpenSSL[i] = new wxMutex(); CRYPTO_set_locking_callback(win32_locking_callback); // Seed random number generator with screen scrape and other hardware sources @@ -46,8 +46,8 @@ public: // Shutdown openssl library multithreading support CRYPTO_set_locking_callback(NULL); for (int i =0 ; i < CRYPTO_num_locks(); i++) - CloseHandle(lock_cs[i]); - OPENSSL_free(lock_cs); + delete ppmutexOpenSSL[i]; + OPENSSL_free(ppmutexOpenSSL); } } instance_of_cinit; @@ -55,6 +55,10 @@ instance_of_cinit; + + + + void RandAddSeed() { // Seed with CPU performance counter diff --git a/util.h b/util.h index 61f774a8d9..436281c90a 100644 --- a/util.h +++ b/util.h @@ -106,28 +106,38 @@ void AddTimeData(unsigned int ip, int64 nTime); // Could use wxCriticalSection for portability, but it doesn't support TryEnterCriticalSection class CCriticalSection { +#ifdef __WXMSW__ protected: CRITICAL_SECTION cs; public: - char* pszFile; - int nLine; explicit CCriticalSection() { InitializeCriticalSection(&cs); } ~CCriticalSection() { DeleteCriticalSection(&cs); } void Enter() { EnterCriticalSection(&cs); } void Leave() { LeaveCriticalSection(&cs); } bool TryEnter() { return TryEnterCriticalSection(&cs); } - CRITICAL_SECTION* operator&() { return &cs; } +#else +protected: + wxMutex mutex; +public: + explicit CCriticalSection() { } + ~CCriticalSection() { } + void Enter() { mutex.Lock(); } + void Leave() { mutex.Unlock(); } + bool TryEnter() { return mutex.TryLock() == wxMUTEX_NO_ERROR; } +#endif +public: + char* pszFile; + int nLine; }; // Automatically leave critical section when leaving block, needed for exception safety class CCriticalBlock { protected: - CRITICAL_SECTION* pcs; + CCriticalSection* pcs; public: - CCriticalBlock(CRITICAL_SECTION& csIn) { pcs = &csIn; EnterCriticalSection(pcs); } - CCriticalBlock(CCriticalSection& csIn) { pcs = &csIn; EnterCriticalSection(pcs); } - ~CCriticalBlock() { LeaveCriticalSection(pcs); } + CCriticalBlock(CCriticalSection& csIn) { pcs = &csIn; pcs->Enter(); } + ~CCriticalBlock() { pcs->Leave(); } }; // WARNING: This will catch continue and break! @@ -141,11 +151,10 @@ public: class CTryCriticalBlock { protected: - CRITICAL_SECTION* pcs; + CCriticalSection* pcs; public: - CTryCriticalBlock(CRITICAL_SECTION& csIn) { pcs = (TryEnterCriticalSection(&csIn) ? &csIn : NULL); } - CTryCriticalBlock(CCriticalSection& csIn) { pcs = (TryEnterCriticalSection(&csIn) ? &csIn : NULL); } - ~CTryCriticalBlock() { if (pcs) LeaveCriticalSection(pcs); } + CTryCriticalBlock(CCriticalSection& csIn) { pcs = (csIn.TryEnter() ? &csIn : NULL); } + ~CTryCriticalBlock() { if (pcs) pcs->Leave(); } bool Entered() { return pcs != NULL; } }; -- cgit v1.2.3 From 7be46ce487e2f3c6e145b9bc56cc37d8de97df9e Mon Sep 17 00:00:00 2001 From: s_nakamoto Date: Thu, 29 Oct 2009 20:10:46 +0000 Subject: better wallet.dat flush, consolidated QueryPerformanceCounter, PRI64d printf portability --- build.txt | 3 ++- db.cpp | 76 ++++++++++++++++++++++++++++++++++++++++++------------------- db.h | 12 +++++++++- main.cpp | 6 ++--- main.h | 2 +- makefile.vc | 4 ++-- net.h | 2 +- ui.cpp | 26 ++++++++++----------- util.cpp | 22 ++++++++---------- util.h | 43 ++++++++++++++++++++-------------- 10 files changed, 121 insertions(+), 75 deletions(-) diff --git a/build.txt b/build.txt index f510055767..67b03fe24a 100644 --- a/build.txt +++ b/build.txt @@ -10,7 +10,7 @@ cryptographic software written by Eric Young (eay@cryptsoft.com). Compilers Supported ------------------- -MinGW GCC (currently v3.4.5) +MinGW GCC Microsoft Visual C++ 6.0 SP6 @@ -20,6 +20,7 @@ Libraries you need to obtain separately to build: default path download wxWidgets \wxwidgets http://www.wxwidgets.org/downloads/ + or prebuilt: http://wxpack.sourceforge.net OpenSSL \openssl http://www.openssl.org/source/ Berkeley DB \db http://www.oracle.com/technology/software/products/berkeley-db/index.html Boost \boost http://www.boost.org/users/download/ diff --git a/db.cpp b/db.cpp index 315e93b73a..699a94f2ea 100644 --- a/db.cpp +++ b/db.cpp @@ -4,8 +4,11 @@ #include "headers.h" +void ThreadFlushWalletDB(void* parg); +unsigned int nWalletDBUpdated; + @@ -56,6 +59,8 @@ CDB::CDB(const char* pszFile, const char* pszMode, bool fTxn) : pdb(NULL) { if (!fDbEnvInit) { + if (fShutdown) + return; string strAppDir = GetAppDir(); string strLogDir = strAppDir + "\\database"; _mkdir(strLogDir.c_str()); @@ -121,12 +126,10 @@ void CDB::Close() pdb->close(0); delete pdb; pdb = NULL; + dbenv.txn_checkpoint(0, 0, 0); CRITICAL_BLOCK(cs_db) - { - dbenv.txn_checkpoint(0, 0, 0); --mapFileUseCount[strFile]; - } RandAddSeed(); } @@ -499,25 +502,6 @@ bool CReviewDB::WriteReviews(uint256 hash, const vector& vReviews) // CWalletDB // -CWalletDB::~CWalletDB() -{ - // Flush whenever all handles to wallet.dat are closed - CRITICAL_BLOCK(cs_db) - { - Close(); // close includes a txn_checkpoint - map::iterator mi = mapFileUseCount.find(strFile); - if (mi != mapFileUseCount.end()) - { - int nRefCount = (*mi).second; - if (nRefCount == 0) - { - dbenv.lsn_reset(strFile.c_str(), 0); - mapFileUseCount.erase(mi++); - } - } - } -} - bool CWalletDB::LoadWallet(vector& vchDefaultKeyRet) { vchDefaultKeyRet.clear(); @@ -610,7 +594,7 @@ bool CWalletDB::LoadWallet(vector& vchDefaultKeyRet) printf("fShowGenerated = %d\n", fShowGenerated); printf("fGenerateBitcoins = %d\n", fGenerateBitcoins); - printf("nTransactionFee = %I64d\n", nTransactionFee); + printf("nTransactionFee = %"PRI64d"\n", nTransactionFee); printf("addrIncoming = %s\n", addrIncoming.ToString().c_str()); printf("fMinimizeToTray = %d\n", fMinimizeToTray); printf("fMinimizeOnClose = %d\n", fMinimizeOnClose); @@ -655,5 +639,51 @@ bool LoadWallet(bool& fFirstRunRet) CWalletDB().WriteDefaultKey(keyUser.GetPubKey()); } + _beginthread(ThreadFlushWalletDB, 0, NULL); return true; } + +void ThreadFlushWalletDB(void* parg) +{ + static bool fOneThread; + if (fOneThread) + return; + fOneThread = true; + + unsigned int nLastSeen = nWalletDBUpdated; + unsigned int nLastFlushed = nWalletDBUpdated; + int64 nLastWalletUpdate = GetTime(); + while (!fShutdown) + { + Sleep(500); + + if (nLastSeen != nWalletDBUpdated) + { + nLastSeen = nWalletDBUpdated; + nLastWalletUpdate = GetTime(); + } + + if (nLastFlushed != nWalletDBUpdated && nLastWalletUpdate < GetTime() - 1) + { + TRY_CRITICAL_BLOCK(cs_db) + { + string strFile = "wallet.dat"; + map::iterator mi = mapFileUseCount.find(strFile); + if (mi != mapFileUseCount.end()) + { + int nRefCount = (*mi).second; + if (nRefCount == 0 && !fShutdown) + { + // Flush wallet.dat so it's self contained + nLastFlushed == nWalletDBUpdated; + int64 nStart = PerformanceCounter(); + dbenv.txn_checkpoint(0, 0, 0); + dbenv.lsn_reset(strFile.c_str(), 0); + printf("Flushed wallet.dat %15"PRI64d"\n", PerformanceCounter() - nStart); + mapFileUseCount.erase(mi++); + } + } + } + } + } +} diff --git a/db.h b/db.h index 4961468759..d11b397eba 100644 --- a/db.h +++ b/db.h @@ -17,7 +17,10 @@ extern map mapAddressBook; extern bool fClient; +extern unsigned int nWalletDBUpdated; extern DbEnv dbenv; + + extern void DBFlush(bool fShutdown); @@ -334,11 +337,11 @@ bool LoadAddresses(); + class CWalletDB : public CDB { public: CWalletDB(const char* pszMode="r+", bool fTxn=false) : CDB("wallet.dat", pszMode, fTxn) { } - ~CWalletDB(); private: CWalletDB(const CWalletDB&); void operator=(const CWalletDB&); @@ -351,12 +354,14 @@ public: bool WriteName(const string& strAddress, const string& strName) { + nWalletDBUpdated++; mapAddressBook[strAddress] = strName; return Write(make_pair(string("name"), strAddress), strName); } bool EraseName(const string& strAddress) { + nWalletDBUpdated++; mapAddressBook.erase(strAddress); return Erase(make_pair(string("name"), strAddress)); } @@ -368,11 +373,13 @@ public: bool WriteTx(uint256 hash, const CWalletTx& wtx) { + nWalletDBUpdated++; return Write(make_pair(string("tx"), hash), wtx); } bool EraseTx(uint256 hash) { + nWalletDBUpdated++; return Erase(make_pair(string("tx"), hash)); } @@ -384,6 +391,7 @@ public: bool WriteKey(const vector& vchPubKey, const CPrivKey& vchPrivKey) { + nWalletDBUpdated++; return Write(make_pair(string("key"), vchPubKey), vchPrivKey, false); } @@ -395,6 +403,7 @@ public: bool WriteDefaultKey(const vector& vchPubKey) { + nWalletDBUpdated++; return Write(string("defaultkey"), vchPubKey); } @@ -407,6 +416,7 @@ public: template bool WriteSetting(const string& strKey, const T& value) { + nWalletDBUpdated++; return Write(make_pair(string("setting"), strKey), value); } diff --git a/main.cpp b/main.cpp index 710b789200..4194333d84 100644 --- a/main.cpp +++ b/main.cpp @@ -2518,8 +2518,7 @@ bool BitcoinMiner() int64 GetBalance() { - int64 nStart, nEnd; - QueryPerformanceCounter((LARGE_INTEGER*)&nStart); + int64 nStart = PerformanceCounter(); int64 nTotal = 0; CRITICAL_BLOCK(cs_mapWallet) @@ -2533,8 +2532,7 @@ int64 GetBalance() } } - QueryPerformanceCounter((LARGE_INTEGER*)&nEnd); - ///printf(" GetBalance() time = %16I64d\n", nEnd - nStart); + ///printf(" GetBalance() time = %15"PRI64d"\n", PerformanceCounter() - nStart); return nTotal; } diff --git a/main.h b/main.h index 958f7a5f1c..fcfd33d134 100644 --- a/main.h +++ b/main.h @@ -344,7 +344,7 @@ public: { if (scriptPubKey.size() < 6) return "CTxOut(error)"; - return strprintf("CTxOut(nValue=%I64d.%08I64d, scriptPubKey=%s)", nValue / COIN, nValue % COIN, scriptPubKey.ToString().substr(0,24).c_str()); + return strprintf("CTxOut(nValue=%"PRI64d".%08"PRI64d", scriptPubKey=%s)", nValue / COIN, nValue % COIN, scriptPubKey.ToString().substr(0,24).c_str()); } void print() const diff --git a/makefile.vc b/makefile.vc index c3bd0c4bcd..fb7f3086e3 100644 --- a/makefile.vc +++ b/makefile.vc @@ -13,8 +13,8 @@ DEBUGFLAGS=/Zi /Od /D__WXDEBUG__ -INCLUDEPATHS=/I"/boost" /I"/DB/build_windows" /I"/OpenSSL/include" /I"/wxWidgets/lib/vc_lib/mswd" /I"/wxWidgets/include" -LIBPATHS=/LIBPATH:"/DB/build_windows/$(BUILD)" /LIBPATH:"/OpenSSL/out" /LIBPATH:"/wxWidgets/lib/vc_lib" +INCLUDEPATHS=/I"/boost" /I"/db/build_windows" /I"/openssl/include" /I"/wxwidgets/lib/vc_lib/mswd" /I"/wxwidgets/include" +LIBPATHS=/LIBPATH:"/db/build_windows/$(BUILD)" /LIBPATH:"/openssl/out" /LIBPATH:"/wxwidgets/lib/vc_lib" LIBS= \ libdb47s$(D).lib \ libeay32.lib \ diff --git a/net.h b/net.h index 5995ac3343..4011a3ef75 100644 --- a/net.h +++ b/net.h @@ -589,7 +589,7 @@ public: // We're using mapAskFor as a priority queue, // the key is the earliest time the request can be sent int64& nRequestTime = mapAlreadyAskedFor[inv]; - printf("askfor %s %I64d\n", inv.ToString().c_str(), nRequestTime); + printf("askfor %s %"PRI64d"\n", inv.ToString().c_str(), nRequestTime); // Make sure not to reuse time indexes to keep things in the same order int64 nNow = (GetTime() - 1) * 1000000; diff --git a/ui.cpp b/ui.cpp index 917c64b445..ce287e3911 100644 --- a/ui.cpp +++ b/ui.cpp @@ -3414,28 +3414,25 @@ bool CMyApp::OnInit2() // bool fFirstRun; string strErrors; - int64 nStart, nEnd; + int64 nStart; printf("Loading addresses...\n"); - QueryPerformanceCounter((LARGE_INTEGER*)&nStart); + nStart = PerformanceCounter(); if (!LoadAddresses()) strErrors += "Error loading addr.dat \n"; - QueryPerformanceCounter((LARGE_INTEGER*)&nEnd); - printf(" addresses %20I64d\n", nEnd - nStart); + printf(" addresses %15"PRI64d"\n", PerformanceCounter() - nStart); printf("Loading block index...\n"); - QueryPerformanceCounter((LARGE_INTEGER*)&nStart); + nStart = PerformanceCounter(); if (!LoadBlockIndex()) strErrors += "Error loading blkindex.dat \n"; - QueryPerformanceCounter((LARGE_INTEGER*)&nEnd); - printf(" block index %20I64d\n", nEnd - nStart); + printf(" block index %15"PRI64d"\n", PerformanceCounter() - nStart); printf("Loading wallet...\n"); - QueryPerformanceCounter((LARGE_INTEGER*)&nStart); + nStart = PerformanceCounter(); if (!LoadWallet(fFirstRun)) strErrors += "Error loading wallet.dat \n"; - QueryPerformanceCounter((LARGE_INTEGER*)&nEnd); - printf(" wallet %20I64d\n", nEnd - nStart); + printf(" wallet %15"PRI64d"\n", PerformanceCounter() - nStart); printf("Done loading\n"); @@ -3742,7 +3739,7 @@ void ThreadRandSendTest(void* parg) return; } - loop + while (!fShutdown) { Sleep(GetRand(30) * 1000 + 100); @@ -3767,6 +3764,8 @@ void ThreadRandSendTest(void* parg) CScript scriptPubKey; scriptPubKey << OP_DUP << OP_HASH160 << hash160 << OP_EQUALVERIFY << OP_CHECKSIG; + if (fShutdown) + return; if (!SendMoney(scriptPubKey, nValue, wtx)) return; } @@ -3776,8 +3775,6 @@ void ThreadRandSendTest(void* parg) // randsendtest to any connected node void RandSend() { - CWalletTx wtx; - while (vNodes.empty()) Sleep(1000); CAddress addr; @@ -3785,6 +3782,7 @@ void RandSend() addr = vNodes[GetRand(vNodes.size())]->addr; // Message + CWalletTx wtx; wtx.mapValue["to"] = addr.ToString(); wtx.mapValue["from"] = addrLocalHost.ToString(); static int nRep; @@ -3799,6 +3797,8 @@ void RandSend() } // Send to IP address + if (fShutdown) + return; CSendingDialog* pdialog = new CSendingDialog(pframeMain, addr, nValue, wtx); if (!pdialog->Show()) wxMessageBox("ShowModal Failed "); diff --git a/util.cpp b/util.cpp index bdf899d78e..ef950920fd 100644 --- a/util.cpp +++ b/util.cpp @@ -14,8 +14,7 @@ bool fPrintToConsole = false; // Init openssl library multithreading support static wxMutex** ppmutexOpenSSL; - -void win32_locking_callback(int mode, int i, const char* file, int line) +void locking_callback(int mode, int i, const char* file, int line) { if (mode & CRYPTO_LOCK) ppmutexOpenSSL[i]->Lock(); @@ -33,7 +32,7 @@ public: ppmutexOpenSSL = (wxMutex**)OPENSSL_malloc(CRYPTO_num_locks() * sizeof(wxMutex*)); for (int i = 0; i < CRYPTO_num_locks(); i++) ppmutexOpenSSL[i] = new wxMutex(); - CRYPTO_set_locking_callback(win32_locking_callback); + CRYPTO_set_locking_callback(locking_callback); // Seed random number generator with screen scrape and other hardware sources RAND_screen(); @@ -45,7 +44,7 @@ public: { // Shutdown openssl library multithreading support CRYPTO_set_locking_callback(NULL); - for (int i =0 ; i < CRYPTO_num_locks(); i++) + for (int i = 0; i < CRYPTO_num_locks(); i++) delete ppmutexOpenSSL[i]; OPENSSL_free(ppmutexOpenSSL); } @@ -62,10 +61,9 @@ instance_of_cinit; void RandAddSeed() { // Seed with CPU performance counter - LARGE_INTEGER PerformanceCount; - QueryPerformanceCounter(&PerformanceCount); - RAND_add(&PerformanceCount, sizeof(PerformanceCount), 1.5); - memset(&PerformanceCount, 0, sizeof(PerformanceCount)); + int64 nCounter = PerformanceCounter(); + RAND_add(&nCounter, sizeof(nCounter), 1.5); + memset(&nCounter, 0, sizeof(nCounter)); } void RandAddSeedPerfmon() @@ -196,7 +194,7 @@ void ParseString(const string& str, char c, vector& v) string FormatMoney(int64 n, bool fPlus) { n /= CENT; - string str = strprintf("%I64d.%02I64d", (n > 0 ? n : -n)/100, (n > 0 ? n : -n)%100); + string str = strprintf("%"PRI64d".%02"PRI64d, (n > 0 ? n : -n)/100, (n > 0 ? n : -n)%100); for (int i = 6; i < str.size(); i += 4) if (isdigit(str[str.size() - i - 1])) str.insert(str.size() - i, 1, ','); @@ -435,7 +433,7 @@ void AddTimeData(unsigned int ip, int64 nTime) if (vTimeOffsets.empty()) vTimeOffsets.push_back(0); vTimeOffsets.push_back(nOffsetSample); - printf("Added time data, samples %d, offset %+I64d (%+I64d minutes)\n", vTimeOffsets.size(), vTimeOffsets.back(), vTimeOffsets.back()/60); + printf("Added time data, samples %d, offset %+"PRI64d" (%+"PRI64d" minutes)\n", vTimeOffsets.size(), vTimeOffsets.back(), vTimeOffsets.back()/60); if (vTimeOffsets.size() >= 5 && vTimeOffsets.size() % 2 == 1) { sort(vTimeOffsets.begin(), vTimeOffsets.end()); @@ -449,7 +447,7 @@ void AddTimeData(unsigned int ip, int64 nTime) /// to make sure it doesn't get changed again } foreach(int64 n, vTimeOffsets) - printf("%+I64d ", n); - printf("| nTimeOffset = %+I64d (%+I64d minutes)\n", nTimeOffset, nTimeOffset/60); + printf("%+"PRI64d" ", n); + printf("| nTimeOffset = %+"PRI64d" (%+"PRI64d" minutes)\n", nTimeOffset, nTimeOffset/60); } } diff --git a/util.h b/util.h index 436281c90a..1c7215d29d 100644 --- a/util.h +++ b/util.h @@ -13,7 +13,6 @@ typedef unsigned long long uint64; #if defined(_MSC_VER) && _MSC_VER < 1300 #define for if (false) ; else for #endif - #ifndef _MSC_VER #define __forceinline inline #endif @@ -25,25 +24,22 @@ typedef unsigned long long uint64; #define UBEGIN(a) ((unsigned char*)&(a)) #define UEND(a) ((unsigned char*)&((&(a))[1])) #define ARRAYLEN(array) (sizeof(array)/sizeof((array)[0])) - -#ifdef _WINDOWS #define printf OutputDebugStringF -#endif #ifdef snprintf #undef snprintf #endif #define snprintf my_snprintf -#ifndef PRId64 +#ifndef PRI64d #if defined(_MSC_VER) || defined(__BORLANDC__) || defined(__MSVCRT__) -#define PRId64 "I64d" -#define PRIu64 "I64u" -#define PRIx64 "I64x" +#define PRI64d "I64d" +#define PRI64u "I64u" +#define PRI64x "I64x" #else -#define PRId64 "lld" -#define PRIu64 "llu" -#define PRIx64 "llx" +#define PRI64d "lld" +#define PRI64u "llu" +#define PRI64x "llx" #endif #endif @@ -64,8 +60,6 @@ inline T& REF(const T& val) - - extern bool fDebug; extern bool fPrintToDebugger; extern bool fPrintToConsole; @@ -101,9 +95,7 @@ void AddTimeData(unsigned int ip, int64 nTime); - -// Wrapper to automatically initialize critical section -// Could use wxCriticalSection for portability, but it doesn't support TryEnterCriticalSection +// Wrapper to automatically initialize critical sections class CCriticalSection { #ifdef __WXMSW__ @@ -191,6 +183,7 @@ inline int OutputDebugStringF(const char* pszFormat, ...) } } +#ifdef __WXMSW__ if (fPrintToDebugger) { // accumulate a line at a time @@ -230,6 +223,7 @@ inline int OutputDebugStringF(const char* pszFormat, ...) pend -= (p1 - pszBuffer); } } +#endif #endif if (fPrintToConsole) @@ -254,7 +248,7 @@ inline int OutputDebugStringF(const char* pszFormat, ...) inline string i64tostr(int64 n) { - return strprintf("%"PRId64, n); + return strprintf("%"PRI64d, n); } inline string itostr(int n) @@ -328,6 +322,20 @@ inline void PrintHex(vector vch, const char* pszFormat="%s", bool printf(pszFormat, HexStr(vch, fSpaces).c_str()); } +inline int64 PerformanceCounter() +{ + int64 nCounter = 0; + QueryPerformanceCounter((LARGE_INTEGER*)&nCounter); + return nCounter; +} + +#ifndef __WXMSW__ +inline void Sleep(unsigned int nMilliseconds) +{ + wxMilliSleep(nMilliseconds); +} +#endif + @@ -370,6 +378,7 @@ inline void heapchk() + template inline uint256 Hash(const T1 pbegin, const T1 pend) { -- cgit v1.2.3 From e8474beb6f2c5e2654f8ebc671b3dbf5fae78563 Mon Sep 17 00:00:00 2001 From: s_nakamoto Date: Thu, 29 Oct 2009 20:10:46 +0000 Subject: better wallet.dat flush, consolidated QueryPerformanceCounter, PRI64d printf portability git-svn-id: https://bitcoin.svn.sourceforge.net/svnroot/bitcoin/trunk@20 1a98c847-1fd6-4fd8-948a-caf3550aa51b --- build.txt | 3 ++- db.cpp | 76 ++++++++++++++++++++++++++++++++++++++++++------------------- db.h | 12 +++++++++- main.cpp | 6 ++--- main.h | 2 +- makefile.vc | 4 ++-- net.h | 2 +- ui.cpp | 26 ++++++++++----------- util.cpp | 22 ++++++++---------- util.h | 43 ++++++++++++++++++++-------------- 10 files changed, 121 insertions(+), 75 deletions(-) diff --git a/build.txt b/build.txt index f510055767..67b03fe24a 100644 --- a/build.txt +++ b/build.txt @@ -10,7 +10,7 @@ cryptographic software written by Eric Young (eay@cryptsoft.com). Compilers Supported ------------------- -MinGW GCC (currently v3.4.5) +MinGW GCC Microsoft Visual C++ 6.0 SP6 @@ -20,6 +20,7 @@ Libraries you need to obtain separately to build: default path download wxWidgets \wxwidgets http://www.wxwidgets.org/downloads/ + or prebuilt: http://wxpack.sourceforge.net OpenSSL \openssl http://www.openssl.org/source/ Berkeley DB \db http://www.oracle.com/technology/software/products/berkeley-db/index.html Boost \boost http://www.boost.org/users/download/ diff --git a/db.cpp b/db.cpp index 315e93b73a..699a94f2ea 100644 --- a/db.cpp +++ b/db.cpp @@ -4,8 +4,11 @@ #include "headers.h" +void ThreadFlushWalletDB(void* parg); +unsigned int nWalletDBUpdated; + @@ -56,6 +59,8 @@ CDB::CDB(const char* pszFile, const char* pszMode, bool fTxn) : pdb(NULL) { if (!fDbEnvInit) { + if (fShutdown) + return; string strAppDir = GetAppDir(); string strLogDir = strAppDir + "\\database"; _mkdir(strLogDir.c_str()); @@ -121,12 +126,10 @@ void CDB::Close() pdb->close(0); delete pdb; pdb = NULL; + dbenv.txn_checkpoint(0, 0, 0); CRITICAL_BLOCK(cs_db) - { - dbenv.txn_checkpoint(0, 0, 0); --mapFileUseCount[strFile]; - } RandAddSeed(); } @@ -499,25 +502,6 @@ bool CReviewDB::WriteReviews(uint256 hash, const vector& vReviews) // CWalletDB // -CWalletDB::~CWalletDB() -{ - // Flush whenever all handles to wallet.dat are closed - CRITICAL_BLOCK(cs_db) - { - Close(); // close includes a txn_checkpoint - map::iterator mi = mapFileUseCount.find(strFile); - if (mi != mapFileUseCount.end()) - { - int nRefCount = (*mi).second; - if (nRefCount == 0) - { - dbenv.lsn_reset(strFile.c_str(), 0); - mapFileUseCount.erase(mi++); - } - } - } -} - bool CWalletDB::LoadWallet(vector& vchDefaultKeyRet) { vchDefaultKeyRet.clear(); @@ -610,7 +594,7 @@ bool CWalletDB::LoadWallet(vector& vchDefaultKeyRet) printf("fShowGenerated = %d\n", fShowGenerated); printf("fGenerateBitcoins = %d\n", fGenerateBitcoins); - printf("nTransactionFee = %I64d\n", nTransactionFee); + printf("nTransactionFee = %"PRI64d"\n", nTransactionFee); printf("addrIncoming = %s\n", addrIncoming.ToString().c_str()); printf("fMinimizeToTray = %d\n", fMinimizeToTray); printf("fMinimizeOnClose = %d\n", fMinimizeOnClose); @@ -655,5 +639,51 @@ bool LoadWallet(bool& fFirstRunRet) CWalletDB().WriteDefaultKey(keyUser.GetPubKey()); } + _beginthread(ThreadFlushWalletDB, 0, NULL); return true; } + +void ThreadFlushWalletDB(void* parg) +{ + static bool fOneThread; + if (fOneThread) + return; + fOneThread = true; + + unsigned int nLastSeen = nWalletDBUpdated; + unsigned int nLastFlushed = nWalletDBUpdated; + int64 nLastWalletUpdate = GetTime(); + while (!fShutdown) + { + Sleep(500); + + if (nLastSeen != nWalletDBUpdated) + { + nLastSeen = nWalletDBUpdated; + nLastWalletUpdate = GetTime(); + } + + if (nLastFlushed != nWalletDBUpdated && nLastWalletUpdate < GetTime() - 1) + { + TRY_CRITICAL_BLOCK(cs_db) + { + string strFile = "wallet.dat"; + map::iterator mi = mapFileUseCount.find(strFile); + if (mi != mapFileUseCount.end()) + { + int nRefCount = (*mi).second; + if (nRefCount == 0 && !fShutdown) + { + // Flush wallet.dat so it's self contained + nLastFlushed == nWalletDBUpdated; + int64 nStart = PerformanceCounter(); + dbenv.txn_checkpoint(0, 0, 0); + dbenv.lsn_reset(strFile.c_str(), 0); + printf("Flushed wallet.dat %15"PRI64d"\n", PerformanceCounter() - nStart); + mapFileUseCount.erase(mi++); + } + } + } + } + } +} diff --git a/db.h b/db.h index 4961468759..d11b397eba 100644 --- a/db.h +++ b/db.h @@ -17,7 +17,10 @@ extern map mapAddressBook; extern bool fClient; +extern unsigned int nWalletDBUpdated; extern DbEnv dbenv; + + extern void DBFlush(bool fShutdown); @@ -334,11 +337,11 @@ bool LoadAddresses(); + class CWalletDB : public CDB { public: CWalletDB(const char* pszMode="r+", bool fTxn=false) : CDB("wallet.dat", pszMode, fTxn) { } - ~CWalletDB(); private: CWalletDB(const CWalletDB&); void operator=(const CWalletDB&); @@ -351,12 +354,14 @@ public: bool WriteName(const string& strAddress, const string& strName) { + nWalletDBUpdated++; mapAddressBook[strAddress] = strName; return Write(make_pair(string("name"), strAddress), strName); } bool EraseName(const string& strAddress) { + nWalletDBUpdated++; mapAddressBook.erase(strAddress); return Erase(make_pair(string("name"), strAddress)); } @@ -368,11 +373,13 @@ public: bool WriteTx(uint256 hash, const CWalletTx& wtx) { + nWalletDBUpdated++; return Write(make_pair(string("tx"), hash), wtx); } bool EraseTx(uint256 hash) { + nWalletDBUpdated++; return Erase(make_pair(string("tx"), hash)); } @@ -384,6 +391,7 @@ public: bool WriteKey(const vector& vchPubKey, const CPrivKey& vchPrivKey) { + nWalletDBUpdated++; return Write(make_pair(string("key"), vchPubKey), vchPrivKey, false); } @@ -395,6 +403,7 @@ public: bool WriteDefaultKey(const vector& vchPubKey) { + nWalletDBUpdated++; return Write(string("defaultkey"), vchPubKey); } @@ -407,6 +416,7 @@ public: template bool WriteSetting(const string& strKey, const T& value) { + nWalletDBUpdated++; return Write(make_pair(string("setting"), strKey), value); } diff --git a/main.cpp b/main.cpp index 710b789200..4194333d84 100644 --- a/main.cpp +++ b/main.cpp @@ -2518,8 +2518,7 @@ bool BitcoinMiner() int64 GetBalance() { - int64 nStart, nEnd; - QueryPerformanceCounter((LARGE_INTEGER*)&nStart); + int64 nStart = PerformanceCounter(); int64 nTotal = 0; CRITICAL_BLOCK(cs_mapWallet) @@ -2533,8 +2532,7 @@ int64 GetBalance() } } - QueryPerformanceCounter((LARGE_INTEGER*)&nEnd); - ///printf(" GetBalance() time = %16I64d\n", nEnd - nStart); + ///printf(" GetBalance() time = %15"PRI64d"\n", PerformanceCounter() - nStart); return nTotal; } diff --git a/main.h b/main.h index 958f7a5f1c..fcfd33d134 100644 --- a/main.h +++ b/main.h @@ -344,7 +344,7 @@ public: { if (scriptPubKey.size() < 6) return "CTxOut(error)"; - return strprintf("CTxOut(nValue=%I64d.%08I64d, scriptPubKey=%s)", nValue / COIN, nValue % COIN, scriptPubKey.ToString().substr(0,24).c_str()); + return strprintf("CTxOut(nValue=%"PRI64d".%08"PRI64d", scriptPubKey=%s)", nValue / COIN, nValue % COIN, scriptPubKey.ToString().substr(0,24).c_str()); } void print() const diff --git a/makefile.vc b/makefile.vc index c3bd0c4bcd..fb7f3086e3 100644 --- a/makefile.vc +++ b/makefile.vc @@ -13,8 +13,8 @@ DEBUGFLAGS=/Zi /Od /D__WXDEBUG__ -INCLUDEPATHS=/I"/boost" /I"/DB/build_windows" /I"/OpenSSL/include" /I"/wxWidgets/lib/vc_lib/mswd" /I"/wxWidgets/include" -LIBPATHS=/LIBPATH:"/DB/build_windows/$(BUILD)" /LIBPATH:"/OpenSSL/out" /LIBPATH:"/wxWidgets/lib/vc_lib" +INCLUDEPATHS=/I"/boost" /I"/db/build_windows" /I"/openssl/include" /I"/wxwidgets/lib/vc_lib/mswd" /I"/wxwidgets/include" +LIBPATHS=/LIBPATH:"/db/build_windows/$(BUILD)" /LIBPATH:"/openssl/out" /LIBPATH:"/wxwidgets/lib/vc_lib" LIBS= \ libdb47s$(D).lib \ libeay32.lib \ diff --git a/net.h b/net.h index 5995ac3343..4011a3ef75 100644 --- a/net.h +++ b/net.h @@ -589,7 +589,7 @@ public: // We're using mapAskFor as a priority queue, // the key is the earliest time the request can be sent int64& nRequestTime = mapAlreadyAskedFor[inv]; - printf("askfor %s %I64d\n", inv.ToString().c_str(), nRequestTime); + printf("askfor %s %"PRI64d"\n", inv.ToString().c_str(), nRequestTime); // Make sure not to reuse time indexes to keep things in the same order int64 nNow = (GetTime() - 1) * 1000000; diff --git a/ui.cpp b/ui.cpp index 917c64b445..ce287e3911 100644 --- a/ui.cpp +++ b/ui.cpp @@ -3414,28 +3414,25 @@ bool CMyApp::OnInit2() // bool fFirstRun; string strErrors; - int64 nStart, nEnd; + int64 nStart; printf("Loading addresses...\n"); - QueryPerformanceCounter((LARGE_INTEGER*)&nStart); + nStart = PerformanceCounter(); if (!LoadAddresses()) strErrors += "Error loading addr.dat \n"; - QueryPerformanceCounter((LARGE_INTEGER*)&nEnd); - printf(" addresses %20I64d\n", nEnd - nStart); + printf(" addresses %15"PRI64d"\n", PerformanceCounter() - nStart); printf("Loading block index...\n"); - QueryPerformanceCounter((LARGE_INTEGER*)&nStart); + nStart = PerformanceCounter(); if (!LoadBlockIndex()) strErrors += "Error loading blkindex.dat \n"; - QueryPerformanceCounter((LARGE_INTEGER*)&nEnd); - printf(" block index %20I64d\n", nEnd - nStart); + printf(" block index %15"PRI64d"\n", PerformanceCounter() - nStart); printf("Loading wallet...\n"); - QueryPerformanceCounter((LARGE_INTEGER*)&nStart); + nStart = PerformanceCounter(); if (!LoadWallet(fFirstRun)) strErrors += "Error loading wallet.dat \n"; - QueryPerformanceCounter((LARGE_INTEGER*)&nEnd); - printf(" wallet %20I64d\n", nEnd - nStart); + printf(" wallet %15"PRI64d"\n", PerformanceCounter() - nStart); printf("Done loading\n"); @@ -3742,7 +3739,7 @@ void ThreadRandSendTest(void* parg) return; } - loop + while (!fShutdown) { Sleep(GetRand(30) * 1000 + 100); @@ -3767,6 +3764,8 @@ void ThreadRandSendTest(void* parg) CScript scriptPubKey; scriptPubKey << OP_DUP << OP_HASH160 << hash160 << OP_EQUALVERIFY << OP_CHECKSIG; + if (fShutdown) + return; if (!SendMoney(scriptPubKey, nValue, wtx)) return; } @@ -3776,8 +3775,6 @@ void ThreadRandSendTest(void* parg) // randsendtest to any connected node void RandSend() { - CWalletTx wtx; - while (vNodes.empty()) Sleep(1000); CAddress addr; @@ -3785,6 +3782,7 @@ void RandSend() addr = vNodes[GetRand(vNodes.size())]->addr; // Message + CWalletTx wtx; wtx.mapValue["to"] = addr.ToString(); wtx.mapValue["from"] = addrLocalHost.ToString(); static int nRep; @@ -3799,6 +3797,8 @@ void RandSend() } // Send to IP address + if (fShutdown) + return; CSendingDialog* pdialog = new CSendingDialog(pframeMain, addr, nValue, wtx); if (!pdialog->Show()) wxMessageBox("ShowModal Failed "); diff --git a/util.cpp b/util.cpp index bdf899d78e..ef950920fd 100644 --- a/util.cpp +++ b/util.cpp @@ -14,8 +14,7 @@ bool fPrintToConsole = false; // Init openssl library multithreading support static wxMutex** ppmutexOpenSSL; - -void win32_locking_callback(int mode, int i, const char* file, int line) +void locking_callback(int mode, int i, const char* file, int line) { if (mode & CRYPTO_LOCK) ppmutexOpenSSL[i]->Lock(); @@ -33,7 +32,7 @@ public: ppmutexOpenSSL = (wxMutex**)OPENSSL_malloc(CRYPTO_num_locks() * sizeof(wxMutex*)); for (int i = 0; i < CRYPTO_num_locks(); i++) ppmutexOpenSSL[i] = new wxMutex(); - CRYPTO_set_locking_callback(win32_locking_callback); + CRYPTO_set_locking_callback(locking_callback); // Seed random number generator with screen scrape and other hardware sources RAND_screen(); @@ -45,7 +44,7 @@ public: { // Shutdown openssl library multithreading support CRYPTO_set_locking_callback(NULL); - for (int i =0 ; i < CRYPTO_num_locks(); i++) + for (int i = 0; i < CRYPTO_num_locks(); i++) delete ppmutexOpenSSL[i]; OPENSSL_free(ppmutexOpenSSL); } @@ -62,10 +61,9 @@ instance_of_cinit; void RandAddSeed() { // Seed with CPU performance counter - LARGE_INTEGER PerformanceCount; - QueryPerformanceCounter(&PerformanceCount); - RAND_add(&PerformanceCount, sizeof(PerformanceCount), 1.5); - memset(&PerformanceCount, 0, sizeof(PerformanceCount)); + int64 nCounter = PerformanceCounter(); + RAND_add(&nCounter, sizeof(nCounter), 1.5); + memset(&nCounter, 0, sizeof(nCounter)); } void RandAddSeedPerfmon() @@ -196,7 +194,7 @@ void ParseString(const string& str, char c, vector& v) string FormatMoney(int64 n, bool fPlus) { n /= CENT; - string str = strprintf("%I64d.%02I64d", (n > 0 ? n : -n)/100, (n > 0 ? n : -n)%100); + string str = strprintf("%"PRI64d".%02"PRI64d, (n > 0 ? n : -n)/100, (n > 0 ? n : -n)%100); for (int i = 6; i < str.size(); i += 4) if (isdigit(str[str.size() - i - 1])) str.insert(str.size() - i, 1, ','); @@ -435,7 +433,7 @@ void AddTimeData(unsigned int ip, int64 nTime) if (vTimeOffsets.empty()) vTimeOffsets.push_back(0); vTimeOffsets.push_back(nOffsetSample); - printf("Added time data, samples %d, offset %+I64d (%+I64d minutes)\n", vTimeOffsets.size(), vTimeOffsets.back(), vTimeOffsets.back()/60); + printf("Added time data, samples %d, offset %+"PRI64d" (%+"PRI64d" minutes)\n", vTimeOffsets.size(), vTimeOffsets.back(), vTimeOffsets.back()/60); if (vTimeOffsets.size() >= 5 && vTimeOffsets.size() % 2 == 1) { sort(vTimeOffsets.begin(), vTimeOffsets.end()); @@ -449,7 +447,7 @@ void AddTimeData(unsigned int ip, int64 nTime) /// to make sure it doesn't get changed again } foreach(int64 n, vTimeOffsets) - printf("%+I64d ", n); - printf("| nTimeOffset = %+I64d (%+I64d minutes)\n", nTimeOffset, nTimeOffset/60); + printf("%+"PRI64d" ", n); + printf("| nTimeOffset = %+"PRI64d" (%+"PRI64d" minutes)\n", nTimeOffset, nTimeOffset/60); } } diff --git a/util.h b/util.h index 436281c90a..1c7215d29d 100644 --- a/util.h +++ b/util.h @@ -13,7 +13,6 @@ typedef unsigned long long uint64; #if defined(_MSC_VER) && _MSC_VER < 1300 #define for if (false) ; else for #endif - #ifndef _MSC_VER #define __forceinline inline #endif @@ -25,25 +24,22 @@ typedef unsigned long long uint64; #define UBEGIN(a) ((unsigned char*)&(a)) #define UEND(a) ((unsigned char*)&((&(a))[1])) #define ARRAYLEN(array) (sizeof(array)/sizeof((array)[0])) - -#ifdef _WINDOWS #define printf OutputDebugStringF -#endif #ifdef snprintf #undef snprintf #endif #define snprintf my_snprintf -#ifndef PRId64 +#ifndef PRI64d #if defined(_MSC_VER) || defined(__BORLANDC__) || defined(__MSVCRT__) -#define PRId64 "I64d" -#define PRIu64 "I64u" -#define PRIx64 "I64x" +#define PRI64d "I64d" +#define PRI64u "I64u" +#define PRI64x "I64x" #else -#define PRId64 "lld" -#define PRIu64 "llu" -#define PRIx64 "llx" +#define PRI64d "lld" +#define PRI64u "llu" +#define PRI64x "llx" #endif #endif @@ -64,8 +60,6 @@ inline T& REF(const T& val) - - extern bool fDebug; extern bool fPrintToDebugger; extern bool fPrintToConsole; @@ -101,9 +95,7 @@ void AddTimeData(unsigned int ip, int64 nTime); - -// Wrapper to automatically initialize critical section -// Could use wxCriticalSection for portability, but it doesn't support TryEnterCriticalSection +// Wrapper to automatically initialize critical sections class CCriticalSection { #ifdef __WXMSW__ @@ -191,6 +183,7 @@ inline int OutputDebugStringF(const char* pszFormat, ...) } } +#ifdef __WXMSW__ if (fPrintToDebugger) { // accumulate a line at a time @@ -230,6 +223,7 @@ inline int OutputDebugStringF(const char* pszFormat, ...) pend -= (p1 - pszBuffer); } } +#endif #endif if (fPrintToConsole) @@ -254,7 +248,7 @@ inline int OutputDebugStringF(const char* pszFormat, ...) inline string i64tostr(int64 n) { - return strprintf("%"PRId64, n); + return strprintf("%"PRI64d, n); } inline string itostr(int n) @@ -328,6 +322,20 @@ inline void PrintHex(vector vch, const char* pszFormat="%s", bool printf(pszFormat, HexStr(vch, fSpaces).c_str()); } +inline int64 PerformanceCounter() +{ + int64 nCounter = 0; + QueryPerformanceCounter((LARGE_INTEGER*)&nCounter); + return nCounter; +} + +#ifndef __WXMSW__ +inline void Sleep(unsigned int nMilliseconds) +{ + wxMilliSleep(nMilliseconds); +} +#endif + @@ -370,6 +378,7 @@ inline void heapchk() + template inline uint256 Hash(const T1 pbegin, const T1 pend) { -- cgit v1.2.3 From ae3ae3df7616df799a59ee74cb1ef2b5fcec1c76 Mon Sep 17 00:00:00 2001 From: sirius-m Date: Fri, 30 Oct 2009 00:45:35 +0000 Subject: setup script removes startup shortcut and runs with highest exec level --- setup.nsi | 3 +++ 1 file changed, 3 insertions(+) diff --git a/setup.nsi b/setup.nsi index 023914fab9..e30ff13cc4 100644 --- a/setup.nsi +++ b/setup.nsi @@ -3,6 +3,8 @@ Name Bitcoin +RequestExecutionLevel highest + # General Symbol Definitions !define REGKEY "SOFTWARE\$(^Name)" !define VERSION 0.1.6 @@ -110,6 +112,7 @@ Section -un.post UNSEC0001 DeleteRegKey HKCU "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" Delete /REBOOTOK "$SMPROGRAMS\$StartMenuGroup\Uninstall Bitcoin.lnk" Delete /REBOOTOK "$SMPROGRAMS\$StartMenuGroup\Bitcoin.lnk" + Delete /REBOOTOK "$SMSTARTUP\Bitcoin.lnk" Delete /REBOOTOK $INSTDIR\uninstall.exe Delete /REBOOTOK $INSTDIR\db.log DeleteRegValue HKCU "${REGKEY}" StartMenuGroup -- cgit v1.2.3 From a0c17c03eb323ddec28e36cfc30174a58264cbcf Mon Sep 17 00:00:00 2001 From: sirius-m Date: Fri, 30 Oct 2009 00:45:35 +0000 Subject: setup script removes startup shortcut and runs with highest exec level git-svn-id: https://bitcoin.svn.sourceforge.net/svnroot/bitcoin/trunk@21 1a98c847-1fd6-4fd8-948a-caf3550aa51b --- setup.nsi | 3 +++ 1 file changed, 3 insertions(+) diff --git a/setup.nsi b/setup.nsi index 023914fab9..e30ff13cc4 100644 --- a/setup.nsi +++ b/setup.nsi @@ -3,6 +3,8 @@ Name Bitcoin +RequestExecutionLevel highest + # General Symbol Definitions !define REGKEY "SOFTWARE\$(^Name)" !define VERSION 0.1.6 @@ -110,6 +112,7 @@ Section -un.post UNSEC0001 DeleteRegKey HKCU "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$(^Name)" Delete /REBOOTOK "$SMPROGRAMS\$StartMenuGroup\Uninstall Bitcoin.lnk" Delete /REBOOTOK "$SMPROGRAMS\$StartMenuGroup\Bitcoin.lnk" + Delete /REBOOTOK "$SMSTARTUP\Bitcoin.lnk" Delete /REBOOTOK $INSTDIR\uninstall.exe Delete /REBOOTOK $INSTDIR\db.log DeleteRegValue HKCU "${REGKEY}" StartMenuGroup -- cgit v1.2.3 From 8938414f0c1e325a3c2242b703f24411956aee15 Mon Sep 17 00:00:00 2001 From: s_nakamoto Date: Fri, 30 Oct 2009 00:57:05 +0000 Subject: make CheckDiskSpace portable --- main.cpp | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/main.cpp b/main.cpp index 4194333d84..b98477b033 100644 --- a/main.cpp +++ b/main.cpp @@ -1398,21 +1398,15 @@ string GetAppDir() bool CheckDiskSpace(int64 nAdditionalBytes) { - uint64 nFreeBytesAvailable = 0; // bytes available to caller - uint64 nTotalNumberOfBytes = 0; // bytes on disk - uint64 nTotalNumberOfFreeBytes = 0; // free bytes on disk - - if (!GetDiskFreeSpaceEx(GetAppDir().c_str(), - (PULARGE_INTEGER)&nFreeBytesAvailable, - (PULARGE_INTEGER)&nTotalNumberOfBytes, - (PULARGE_INTEGER)&nTotalNumberOfFreeBytes)) + wxLongLong nFreeBytesAvailable = 0; + if (!wxGetDiskSpace(GetDataDir(), NULL, &nFreeBytesAvailable)) { - printf("ERROR: GetDiskFreeSpaceEx() failed\n"); + printf("ERROR: wxGetDiskSpace() failed\n"); return true; } // Check for 15MB because database could create another 10MB log file at any time - if ((int64)nFreeBytesAvailable < 15000000 + nAdditionalBytes) + if (nFreeBytesAvailable < (int64)15000000 + nAdditionalBytes) { fShutdown = true; wxMessageBox("Warning: Your disk space is low ", "Bitcoin", wxICON_EXCLAMATION); -- cgit v1.2.3 From 32d490313b21d5cea64f99ca9db4388591bb3ab9 Mon Sep 17 00:00:00 2001 From: s_nakamoto Date: Fri, 30 Oct 2009 00:57:05 +0000 Subject: make CheckDiskSpace portable git-svn-id: https://bitcoin.svn.sourceforge.net/svnroot/bitcoin/trunk@22 1a98c847-1fd6-4fd8-948a-caf3550aa51b --- main.cpp | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/main.cpp b/main.cpp index 4194333d84..b98477b033 100644 --- a/main.cpp +++ b/main.cpp @@ -1398,21 +1398,15 @@ string GetAppDir() bool CheckDiskSpace(int64 nAdditionalBytes) { - uint64 nFreeBytesAvailable = 0; // bytes available to caller - uint64 nTotalNumberOfBytes = 0; // bytes on disk - uint64 nTotalNumberOfFreeBytes = 0; // free bytes on disk - - if (!GetDiskFreeSpaceEx(GetAppDir().c_str(), - (PULARGE_INTEGER)&nFreeBytesAvailable, - (PULARGE_INTEGER)&nTotalNumberOfBytes, - (PULARGE_INTEGER)&nTotalNumberOfFreeBytes)) + wxLongLong nFreeBytesAvailable = 0; + if (!wxGetDiskSpace(GetDataDir(), NULL, &nFreeBytesAvailable)) { - printf("ERROR: GetDiskFreeSpaceEx() failed\n"); + printf("ERROR: wxGetDiskSpace() failed\n"); return true; } // Check for 15MB because database could create another 10MB log file at any time - if ((int64)nFreeBytesAvailable < 15000000 + nAdditionalBytes) + if (nFreeBytesAvailable < (int64)15000000 + nAdditionalBytes) { fShutdown = true; wxMessageBox("Warning: Your disk space is low ", "Bitcoin", wxICON_EXCLAMATION); -- cgit v1.2.3 From e874738d3de335faacb83d0398cabdff7477bfa0 Mon Sep 17 00:00:00 2001 From: sirius-m Date: Sat, 31 Oct 2009 09:11:43 +0000 Subject: Linux alternatives for the Windows headers and PerformanceCounter. Some typedefs and #defines for the Linux build. Fixed GetDataDir. --- headers.h | 27 ++++++++++++++++++--------- irc.h | 5 +++++ main.cpp | 2 +- net.h | 6 ++++++ util.h | 12 ++++++++++-- 5 files changed, 40 insertions(+), 12 deletions(-) diff --git a/headers.h b/headers.h index 29b16fb780..16238f89b7 100644 --- a/headers.h +++ b/headers.h @@ -25,20 +25,13 @@ #include #include #include -#include -#include -#include -#include -#include -#include +#include #include #include -#include #include #include #include #include -#include #include #include #define BOUNDSCHECK 1 @@ -56,7 +49,23 @@ #include #include #include -#include +#include + +#ifdef __WXMSW__ +#include +#include +#include +#include +#include +#include +#include +#else +#include +#include +#include +#include +#endif + #pragma hdrstop using namespace std; using namespace boost; diff --git a/irc.h b/irc.h index 91c3ffe686..1dc348a8be 100644 --- a/irc.h +++ b/irc.h @@ -1,6 +1,11 @@ // Copyright (c) 2009 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 __WXMSW__ +#define closesocket(s) close(s) +typedef u_int SOCKET; +#endif extern bool RecvLine(SOCKET hSocket, string& strLine); extern void ThreadIRCSeed(void* parg); diff --git a/main.cpp b/main.cpp index b98477b033..156267771c 100644 --- a/main.cpp +++ b/main.cpp @@ -1399,7 +1399,7 @@ string GetAppDir() bool CheckDiskSpace(int64 nAdditionalBytes) { wxLongLong nFreeBytesAvailable = 0; - if (!wxGetDiskSpace(GetDataDir(), NULL, &nFreeBytesAvailable)) + if (!wxGetDiskSpace(wxStandardPaths::Get().GetDataDir(), NULL, &nFreeBytesAvailable)) { printf("ERROR: wxGetDiskSpace() failed\n"); return true; diff --git a/net.h b/net.h index 4011a3ef75..2eece2c061 100644 --- a/net.h +++ b/net.h @@ -1,6 +1,12 @@ // Copyright (c) 2009 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 __WXMSW__ +#define closesocket(s) close(s) +#define INVALID_SOCKET (SOCKET)(~0) +typedef u_int SOCKET; +#endif class CMessageHeader; class CAddress; diff --git a/util.h b/util.h index 1c7215d29d..5d18776002 100644 --- a/util.h +++ b/util.h @@ -321,11 +321,19 @@ inline void PrintHex(vector vch, const char* pszFormat="%s", bool { printf(pszFormat, HexStr(vch, fSpaces).c_str()); } + inline int64 PerformanceCounter() { - int64 nCounter = 0; - QueryPerformanceCounter((LARGE_INTEGER*)&nCounter); + int64 nCounter = 0; +#ifdef __WXMSW__ + QueryPerformanceCounter((LARGE_INTEGER*)&nCounter); +#else + // this could be changed to reading /dev/urandom + timeval t; + gettimeofday(&t, NULL); + nCounter += t.tv_sec * 1000000 + t.tv_usec; +#endif return nCounter; } -- cgit v1.2.3 From fe9f3d626d79f71d819caf43878299fa5e6af83e Mon Sep 17 00:00:00 2001 From: sirius-m Date: Sat, 31 Oct 2009 09:11:43 +0000 Subject: Linux alternatives for the Windows headers and PerformanceCounter. Some typedefs and #defines for the Linux build. Fixed GetDataDir. git-svn-id: https://bitcoin.svn.sourceforge.net/svnroot/bitcoin/trunk@23 1a98c847-1fd6-4fd8-948a-caf3550aa51b --- headers.h | 27 ++++++++++++++++++--------- irc.h | 5 +++++ main.cpp | 2 +- net.h | 6 ++++++ util.h | 12 ++++++++++-- 5 files changed, 40 insertions(+), 12 deletions(-) diff --git a/headers.h b/headers.h index 29b16fb780..16238f89b7 100644 --- a/headers.h +++ b/headers.h @@ -25,20 +25,13 @@ #include #include #include -#include -#include -#include -#include -#include -#include +#include #include #include -#include #include #include #include #include -#include #include #include #define BOUNDSCHECK 1 @@ -56,7 +49,23 @@ #include #include #include -#include +#include + +#ifdef __WXMSW__ +#include +#include +#include +#include +#include +#include +#include +#else +#include +#include +#include +#include +#endif + #pragma hdrstop using namespace std; using namespace boost; diff --git a/irc.h b/irc.h index 91c3ffe686..1dc348a8be 100644 --- a/irc.h +++ b/irc.h @@ -1,6 +1,11 @@ // Copyright (c) 2009 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 __WXMSW__ +#define closesocket(s) close(s) +typedef u_int SOCKET; +#endif extern bool RecvLine(SOCKET hSocket, string& strLine); extern void ThreadIRCSeed(void* parg); diff --git a/main.cpp b/main.cpp index b98477b033..156267771c 100644 --- a/main.cpp +++ b/main.cpp @@ -1399,7 +1399,7 @@ string GetAppDir() bool CheckDiskSpace(int64 nAdditionalBytes) { wxLongLong nFreeBytesAvailable = 0; - if (!wxGetDiskSpace(GetDataDir(), NULL, &nFreeBytesAvailable)) + if (!wxGetDiskSpace(wxStandardPaths::Get().GetDataDir(), NULL, &nFreeBytesAvailable)) { printf("ERROR: wxGetDiskSpace() failed\n"); return true; diff --git a/net.h b/net.h index 4011a3ef75..2eece2c061 100644 --- a/net.h +++ b/net.h @@ -1,6 +1,12 @@ // Copyright (c) 2009 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 __WXMSW__ +#define closesocket(s) close(s) +#define INVALID_SOCKET (SOCKET)(~0) +typedef u_int SOCKET; +#endif class CMessageHeader; class CAddress; diff --git a/util.h b/util.h index 1c7215d29d..5d18776002 100644 --- a/util.h +++ b/util.h @@ -321,11 +321,19 @@ inline void PrintHex(vector vch, const char* pszFormat="%s", bool { printf(pszFormat, HexStr(vch, fSpaces).c_str()); } + inline int64 PerformanceCounter() { - int64 nCounter = 0; - QueryPerformanceCounter((LARGE_INTEGER*)&nCounter); + int64 nCounter = 0; +#ifdef __WXMSW__ + QueryPerformanceCounter((LARGE_INTEGER*)&nCounter); +#else + // this could be changed to reading /dev/urandom + timeval t; + gettimeofday(&t, NULL); + nCounter += t.tv_sec * 1000000 + t.tv_usec; +#endif return nCounter; } -- cgit v1.2.3 From 99142385daea73bb2c8fadf44b6d36df31813fb0 Mon Sep 17 00:00:00 2001 From: sirius-m Date: Sat, 31 Oct 2009 09:52:24 +0000 Subject: added wx/stdpaths.h --- headers.h | 1 + 1 file changed, 1 insertion(+) diff --git a/headers.h b/headers.h index 16238f89b7..f00b7dde05 100644 --- a/headers.h +++ b/headers.h @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include -- cgit v1.2.3 From 5750932cdf72ea9b5e64b8a05b43c42f5acb417d Mon Sep 17 00:00:00 2001 From: sirius-m Date: Sat, 31 Oct 2009 09:52:24 +0000 Subject: added wx/stdpaths.h git-svn-id: https://bitcoin.svn.sourceforge.net/svnroot/bitcoin/trunk@24 1a98c847-1fd6-4fd8-948a-caf3550aa51b --- headers.h | 1 + 1 file changed, 1 insertion(+) diff --git a/headers.h b/headers.h index 16238f89b7..f00b7dde05 100644 --- a/headers.h +++ b/headers.h @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include -- cgit v1.2.3 From e66ec79b18717bf83b7dbbe54f844b4463dabdeb Mon Sep 17 00:00:00 2001 From: s_nakamoto Date: Sun, 1 Nov 2009 01:16:51 +0000 Subject: move debug.log and db.log to data dir, portable GetDataDir, optimize GetBalance, fix repaint bogdown, -addnode and -? switches --- build.txt | 2 +- db.cpp | 19 +-- irc.cpp | 7 +- irc.h | 5 - main.cpp | 50 +------ main.h | 20 ++- net.cpp | 34 ++++- net.h | 78 ++++++----- ui.cpp | 457 +++++++++++++++++++++++++++----------------------------------- ui.h | 5 +- util.cpp | 82 +++++++++-- util.h | 39 ++++-- 12 files changed, 416 insertions(+), 382 deletions(-) diff --git a/build.txt b/build.txt index 67b03fe24a..4368af855a 100644 --- a/build.txt +++ b/build.txt @@ -10,7 +10,7 @@ cryptographic software written by Eric Young (eay@cryptsoft.com). Compilers Supported ------------------- -MinGW GCC +MinGW GCC (v3.4.5) Microsoft Visual C++ 6.0 SP6 diff --git a/db.cpp b/db.cpp index 699a94f2ea..f9e25834d0 100644 --- a/db.cpp +++ b/db.cpp @@ -61,18 +61,19 @@ CDB::CDB(const char* pszFile, const char* pszMode, bool fTxn) : pdb(NULL) { if (fShutdown) return; - string strAppDir = GetAppDir(); - string strLogDir = strAppDir + "\\database"; + string strDataDir = GetDataDir(); + string strLogDir = strDataDir + "\\database"; _mkdir(strLogDir.c_str()); - printf("dbenv.open strAppDir=%s\n", strAppDir.c_str()); + string strErrorFile = strDataDir + "\\db.log"; + printf("dbenv.open strLogDir=%s strErrorFile=%s\n", strLogDir.c_str(), strErrorFile.c_str()); dbenv.set_lg_dir(strLogDir.c_str()); dbenv.set_lg_max(10000000); dbenv.set_lk_max_locks(10000); dbenv.set_lk_max_objects(10000); - dbenv.set_errfile(fopen("db.log", "a")); /// debug + dbenv.set_errfile(fopen(strErrorFile.c_str(), "a")); /// debug ///dbenv.log_set_config(DB_LOG_AUTO_REMOVE, 1); /// causes corruption - ret = dbenv.open(strAppDir.c_str(), + ret = dbenv.open(strDataDir.c_str(), DB_CREATE | DB_INIT_LOCK | DB_INIT_LOG | @@ -139,6 +140,8 @@ void DBFlush(bool fShutdown) // Flush log data to the actual data file // on all files that are not in use printf("DBFlush(%s)\n", fShutdown ? "true" : "false"); + if (!fDbEnvInit) + return; CRITICAL_BLOCK(cs_db) { dbenv.txn_checkpoint(0, 0, 0); @@ -421,7 +424,7 @@ bool CAddrDB::LoadAddresses() while (fgets(psz, sizeof(psz), filein)) { CAddress addr(psz, NODE_NETWORK); - if (addr.ip != 0) + if (addr.IsValid()) { AddAddress(*this, addr); mapIRCAddresses.insert(make_pair(addr.GetKey(), addr)); @@ -676,10 +679,10 @@ void ThreadFlushWalletDB(void* parg) { // Flush wallet.dat so it's self contained nLastFlushed == nWalletDBUpdated; - int64 nStart = PerformanceCounter(); + int64 nStart = GetTimeMillis(); dbenv.txn_checkpoint(0, 0, 0); dbenv.lsn_reset(strFile.c_str(), 0); - printf("Flushed wallet.dat %15"PRI64d"\n", PerformanceCounter() - nStart); + printf("Flushed wallet.dat %"PRI64d"ms\n", GetTimeMillis() - nStart); mapFileUseCount.erase(mi++); } } diff --git a/irc.cpp b/irc.cpp index 707b4fe19f..f839dc5224 100644 --- a/irc.cpp +++ b/irc.cpp @@ -40,7 +40,7 @@ bool DecodeAddress(string str, CAddress& addr) return false; memcpy(&tmp, &vch[0], sizeof(tmp)); - addr = CAddress(tmp.ip, tmp.port); + addr = CAddress(tmp.ip, tmp.port, NODE_NETWORK); return true; } @@ -163,6 +163,7 @@ void ThreadIRCSeed(void* parg) int nErrorWait = 10; int nRetryWait = 10; + // IRC server blocks TOR users if (fUseProxy && addrProxy.port == htons(9050)) return; @@ -237,14 +238,14 @@ void ThreadIRCSeed(void* parg) { // index 7 is limited to 16 characters // could get full length name at index 10, but would be different from join messages - strcpy(pszName, vWords[7].c_str()); + strlcpy(pszName, vWords[7].c_str(), sizeof(pszName)); printf("IRC got who\n"); } if (vWords[1] == "JOIN" && vWords[0].size() > 1) { // :username!username@50000007.F000000B.90000002.IP JOIN :#channelname - strcpy(pszName, vWords[0].c_str() + 1); + strlcpy(pszName, vWords[0].c_str() + 1, sizeof(pszName)); if (strchr(pszName, '!')) *strchr(pszName, '!') = '\0'; printf("IRC got join\n"); diff --git a/irc.h b/irc.h index 1dc348a8be..91c3ffe686 100644 --- a/irc.h +++ b/irc.h @@ -1,11 +1,6 @@ // Copyright (c) 2009 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 __WXMSW__ -#define closesocket(s) close(s) -typedef u_int SOCKET; -#endif extern bool RecvLine(SOCKET hSocket, string& strLine); extern void ThreadIRCSeed(void* parg); diff --git a/main.cpp b/main.cpp index 156267771c..ade3b51c77 100644 --- a/main.cpp +++ b/main.cpp @@ -42,7 +42,6 @@ map > mapPubKeys; CCriticalSection cs_mapKeys; CKey keyUser; -string strSetDataDir; int nDropMessagesTest = 0; // Settings @@ -1361,52 +1360,17 @@ bool ScanMessageStart(Stream& s) } } -string GetAppDir() -{ - string strDir; - if (!strSetDataDir.empty()) - { - strDir = strSetDataDir; - } - else if (getenv("APPDATA")) - { - strDir = strprintf("%s\\Bitcoin", getenv("APPDATA")); - } - else if (getenv("USERPROFILE")) - { - string strAppData = strprintf("%s\\Application Data", getenv("USERPROFILE")); - static bool fMkdirDone; - if (!fMkdirDone) - { - fMkdirDone = true; - _mkdir(strAppData.c_str()); - } - strDir = strprintf("%s\\Bitcoin", strAppData.c_str()); - } - else - { - return "."; - } - static bool fMkdirDone; - if (!fMkdirDone) - { - fMkdirDone = true; - _mkdir(strDir.c_str()); - } - return strDir; -} - bool CheckDiskSpace(int64 nAdditionalBytes) { wxLongLong nFreeBytesAvailable = 0; - if (!wxGetDiskSpace(wxStandardPaths::Get().GetDataDir(), NULL, &nFreeBytesAvailable)) + if (!wxGetDiskSpace(GetDataDir(), NULL, &nFreeBytesAvailable)) { printf("ERROR: wxGetDiskSpace() failed\n"); return true; } // Check for 15MB because database could create another 10MB log file at any time - if (nFreeBytesAvailable < (int64)15000000 + nAdditionalBytes) + if (nFreeBytesAvailable.GetValue() < (int64)15000000 + nAdditionalBytes) { fShutdown = true; wxMessageBox("Warning: Your disk space is low ", "Bitcoin", wxICON_EXCLAMATION); @@ -1420,7 +1384,7 @@ FILE* OpenBlockFile(unsigned int nFile, unsigned int nBlockPos, const char* pszM { if (nFile == -1) return NULL; - FILE* file = fopen(strprintf("%s\\blk%04d.dat", GetAppDir().c_str(), nFile).c_str(), pszMode); + FILE* file = fopen(strprintf("%s\\blk%04d.dat", GetDataDir().c_str(), nFile).c_str(), pszMode); if (!file) return NULL; if (nBlockPos != 0 && !strchr(pszMode, 'a') && !strchr(pszMode, 'w')) @@ -1719,7 +1683,7 @@ bool ProcessMessages(CNode* pfrom) if (strstr(e.what(), "CDataStream::read() : end of data")) { // Allow exceptions from underlength message on vRecv - LogException(&e, "ProcessMessage()"); + printf("ProcessMessage(%s, %d bytes) : Exception '%s' caught, normally caused by a message being shorter than its stated length\n", strCommand.c_str(), nMessageSize, e.what()); } else PrintException(&e, "ProcessMessage()"); @@ -2512,7 +2476,7 @@ bool BitcoinMiner() int64 GetBalance() { - int64 nStart = PerformanceCounter(); + int64 nStart = GetTimeMillis(); int64 nTotal = 0; CRITICAL_BLOCK(cs_mapWallet) @@ -2522,11 +2486,11 @@ int64 GetBalance() CWalletTx* pcoin = &(*it).second; if (!pcoin->IsFinal() || pcoin->fSpent) continue; - nTotal += pcoin->GetCredit(); + nTotal += pcoin->GetCredit(true); } } - ///printf(" GetBalance() time = %15"PRI64d"\n", PerformanceCounter() - nStart); + //printf("GetBalance() %"PRI64d"ms\n", GetTimeMillis() - nStart); return nTotal; } diff --git a/main.h b/main.h index fcfd33d134..a0258cf2ce 100644 --- a/main.h +++ b/main.h @@ -34,7 +34,6 @@ extern int nBestHeight; extern uint256 hashBestChain; extern CBlockIndex* pindexBest; extern unsigned int nTransactionsUpdated; -extern string strSetDataDir; extern int nDropMessagesTest; // Settings @@ -50,7 +49,6 @@ extern int nLimitProcessors; -string GetAppDir(); bool CheckDiskSpace(int64 nAdditionalBytes=0); FILE* OpenBlockFile(unsigned int nFile, unsigned int nBlockPos, const char* pszMode="rb"); FILE* AppendBlockFile(unsigned int& nFileRet); @@ -405,10 +403,10 @@ public: { // Time based nLockTime implemented in 0.1.6, // do not use time based until most 0.1.5 nodes have upgraded. - if (nBlockTime == 0) - nBlockTime = GetAdjustedTime(); if (nLockTime == 0) return true; + if (nBlockTime == 0) + nBlockTime = GetAdjustedTime(); if (nLockTime < (nLockTime < 500000000 ? nBestHeight : nBlockTime)) return true; foreach(const CTxIn& txin, vin) @@ -627,6 +625,8 @@ public: // memory only mutable bool fMerkleVerified; + mutable bool fGetCreditCached; + mutable int64 nGetCreditCached; CMerkleTx() @@ -644,14 +644,22 @@ public: hashBlock = 0; nIndex = -1; fMerkleVerified = false; + fGetCreditCached = false; + nGetCreditCached = 0; } - int64 GetCredit() const + int64 GetCredit(bool fUseCache=false) const { // Must wait until coinbase is safely deep enough in the chain before valuing it if (IsCoinBase() && GetBlocksToMaturity() > 0) return 0; - return CTransaction::GetCredit(); + + // GetBalance can assume transactions in mapWallet won't change + if (fUseCache && fGetCreditCached) + return nGetCreditCached; + nGetCreditCached = CTransaction::GetCredit(); + fGetCreditCached = true; + return nGetCreditCached; } IMPLEMENT_SERIALIZE diff --git a/net.cpp b/net.cpp index 22b84f9dee..8ccf48b819 100644 --- a/net.cpp +++ b/net.cpp @@ -21,8 +21,7 @@ bool OpenNetworkConnection(const CAddress& addrConnect); bool fClient = false; uint64 nLocalServices = (fClient ? 0 : NODE_NETWORK); CAddress addrLocalHost(0, DEFAULT_PORT, nLocalServices); -CNode nodeLocalHost(INVALID_SOCKET, CAddress("127.0.0.1", nLocalServices)); -CNode* pnodeLocalHost = &nodeLocalHost; +CNode* pnodeLocalHost = NULL; uint64 nLocalHostNonce = 0; bool fShutdown = false; array vnThreadsRunning; @@ -129,7 +128,7 @@ bool GetMyExternalIP2(const CAddress& addrConnect, const char* pszGet, const cha strLine = wxString(strLine).Trim(); CAddress addr(strLine.c_str()); printf("GetMyExternalIP() received [%s] %s\n", strLine.c_str(), addr.ToString().c_str()); - if (addr.ip == 0 || !addr.IsRoutable()) + if (addr.ip == 0 || addr.ip == INADDR_NONE || !addr.IsRoutable()) return false; ipRet = addr.ip; return true; @@ -740,10 +739,29 @@ void ThreadOpenConnections2(void* parg) printf("ThreadOpenConnections started\n"); // Connect to one specified address - while (mapArgs.count("/connect")) + while (mapArgs.count("-connect")) { - OpenNetworkConnection(CAddress(mapArgs["/connect"].c_str())); - Sleep(10000); + OpenNetworkConnection(CAddress(mapArgs["-connect"])); + for (int i = 0; i < 10; i++) + { + Sleep(1000); + CheckForShutdown(1); + } + } + + // Connect to manually added nodes first + if (mapArgs.count("-addnode")) + { + foreach(string strAddr, mapMultiArgs["-addnode"]) + { + CAddress addr(strAddr, NODE_NETWORK); + if (addr.IsValid()) + { + OpenNetworkConnection(addr); + Sleep(1000); + CheckForShutdown(1); + } + } } // Initiate network connections @@ -967,6 +985,8 @@ void ThreadMessageHandler2(void* parg) bool StartNode(string& strError) { + if (pnodeLocalHost == NULL) + pnodeLocalHost = new CNode(INVALID_SOCKET, CAddress("127.0.0.1", nLocalServices)); strError = ""; // Sockets startup @@ -1031,7 +1051,7 @@ bool StartNode(string& strError) printf("%s\n", strError.c_str()); return false; } - printf("bound to addrLocalHost = %s\n\n", addrLocalHost.ToString().c_str()); + printf("bound to addrLocalHost = %s\n", addrLocalHost.ToString().c_str()); // Listen for incoming connections if (listen(hListenSocket, SOMAXCONN) == SOCKET_ERROR) diff --git a/net.h b/net.h index 2eece2c061..7716426f04 100644 --- a/net.h +++ b/net.h @@ -1,12 +1,6 @@ // Copyright (c) 2009 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 __WXMSW__ -#define closesocket(s) close(s) -#define INVALID_SOCKET (SOCKET)(~0) -typedef u_int SOCKET; -#endif class CMessageHeader; class CAddress; @@ -148,61 +142,73 @@ public: CAddress() { - nServices = 0; - memcpy(pchReserved, pchIPv4, sizeof(pchReserved)); - ip = 0; - port = DEFAULT_PORT; - nTime = GetAdjustedTime(); - nLastFailed = 0; + Init(); } - CAddress(unsigned int ipIn, unsigned short portIn=DEFAULT_PORT, uint64 nServicesIn=0) + CAddress(unsigned int ipIn, unsigned short portIn=DEFAULT_PORT, uint64 nServicesIn=NODE_NETWORK) { - nServices = nServicesIn; - memcpy(pchReserved, pchIPv4, sizeof(pchReserved)); + Init(); ip = ipIn; port = portIn; - nTime = GetAdjustedTime(); - nLastFailed = 0; + nServices = nServicesIn; } - explicit CAddress(const struct sockaddr_in& sockaddr, uint64 nServicesIn=0) + explicit CAddress(const struct sockaddr_in& sockaddr, uint64 nServicesIn=NODE_NETWORK) { - nServices = nServicesIn; - memcpy(pchReserved, pchIPv4, sizeof(pchReserved)); + Init(); ip = sockaddr.sin_addr.s_addr; port = sockaddr.sin_port; - nTime = GetAdjustedTime(); - nLastFailed = 0; + nServices = nServicesIn; } - explicit CAddress(const char* pszIn, uint64 nServicesIn=0) + explicit CAddress(const char* pszIn, uint64 nServicesIn=NODE_NETWORK) { + Init(); + SetAddress(pszIn); nServices = nServicesIn; + } + + explicit CAddress(string strIn, uint64 nServicesIn=NODE_NETWORK) + { + Init(); + SetAddress(strIn.c_str()); + nServices = nServicesIn; + } + + void Init() + { + nServices = NODE_NETWORK; memcpy(pchReserved, pchIPv4, sizeof(pchReserved)); ip = INADDR_NONE; port = DEFAULT_PORT; nTime = GetAdjustedTime(); nLastFailed = 0; + } + bool SetAddress(const char* pszIn) + { + ip = INADDR_NONE; + port = DEFAULT_PORT; char psz[100]; - if (strlen(pszIn) > ARRAYLEN(psz)-1) - return; - strcpy(psz, pszIn); + strlcpy(psz, pszIn, sizeof(psz)); unsigned int a=0, b=0, c=0, d=0, e=0; if (sscanf(psz, "%u.%u.%u.%u:%u", &a, &b, &c, &d, &e) < 4) - return; + return false; char* pszPort = strchr(psz, ':'); if (pszPort) { *pszPort++ = '\0'; port = htons(atoi(pszPort)); - if (atoi(pszPort) > USHRT_MAX) + if (atoi(pszPort) < 0 || atoi(pszPort) > USHRT_MAX) port = htons(USHRT_MAX); - if (atoi(pszPort) < 0) - port = htons(0); } ip = inet_addr(psz); + return IsValid(); + } + + bool SetAddress(string strIn) + { + return SetAddress(strIn.c_str()); } IMPLEMENT_SERIALIZE @@ -274,7 +280,17 @@ public: bool IsRoutable() const { - return !(GetByte(3) == 10 || (GetByte(3) == 192 && GetByte(2) == 168) || GetByte(3) == 127 || GetByte(3) == 0); + return !(GetByte(3) == 10 || + (GetByte(3) == 192 && GetByte(2) == 168) || + GetByte(3) == 127 || + GetByte(3) == 0 || + ip == 0 || + ip == INADDR_NONE); + } + + bool IsValid() const + { + return (ip != 0 && ip != INADDR_NONE && port != htons(USHRT_MAX)); } unsigned char GetByte(int n) const diff --git a/ui.cpp b/ui.cpp index ce287e3911..9185b8159f 100644 --- a/ui.cpp +++ b/ui.cpp @@ -25,7 +25,6 @@ DEFINE_EVENT_TYPE(wxEVT_TABLEDELETED) CMainFrame* pframeMain = NULL; CMyTaskBarIcon* ptaskbaricon = NULL; map mapAddressBook; -map mapArgs; bool fRandSendTest = false; void RandSend(); extern int g_isPainting; @@ -283,7 +282,6 @@ CMainFrame::CMainFrame(wxWindow* parent) : CMainFrameBase(parent) fRefreshListCtrl = false; fRefreshListCtrlRunning = false; fOnSetFocusAddress = false; - pindexBestLast = NULL; m_choiceFilter->SetSelection(0); m_staticTextBalance->SetLabel(FormatMoney(GetBalance()) + " "); m_listCtrl->SetFocus(); @@ -507,6 +505,7 @@ bool CMainFrame::InsertTransaction(const CWalletTx& wtx, bool fNew, int nIndex) string strStatus = FormatTxStatus(wtx); map mapValue = wtx.mapValue; wtx.nLinesDisplayed = 1; + nListViewUpdated++; // Filter if (wtx.IsCoinBase()) @@ -712,48 +711,6 @@ bool CMainFrame::InsertTransaction(const CWalletTx& wtx, bool fNew, int nIndex) return true; } -void CMainFrame::RefreshStatus() -{ - static int nLastTop; - int nTop = max((int)m_listCtrl->GetTopItem(), 0); - if (nTop == nLastTop && pindexBestLast == pindexBest) - return; - - TRY_CRITICAL_BLOCK(cs_mapWallet) - { - int nStart = nTop; - int nEnd = min(nStart + 100, m_listCtrl->GetItemCount()); - if (pindexBestLast == pindexBest) - { - if (nStart >= nLastTop && nStart < nLastTop + 100) - nStart = nLastTop + 100; - if (nEnd >= nLastTop && nEnd < nLastTop + 100) - nEnd = nLastTop; - } - nLastTop = nTop; - pindexBestLast = pindexBest; - - for (int nIndex = nStart; nIndex < min(nEnd, m_listCtrl->GetItemCount()); nIndex++) - { - uint256 hash((string)GetItemText(m_listCtrl, nIndex, 1)); - map::iterator mi = mapWallet.find(hash); - if (mi == mapWallet.end()) - { - printf("CMainFrame::RefreshStatus() : tx not found in mapWallet\n"); - continue; - } - CWalletTx& wtx = (*mi).second; - if (wtx.IsCoinBase() || wtx.GetTxTime() != wtx.nTimeDisplayed) - { - if (!InsertTransaction(wtx, false, nIndex)) - m_listCtrl->DeleteItem(nIndex--); - } - else - m_listCtrl->SetItem(nIndex, 2, FormatTxStatus(wtx)); - } - } -} - void CMainFrame::RefreshListCtrl() { fRefreshListCtrl = true; @@ -832,21 +789,104 @@ void CMainFrame::OnIdle(wxIdleEvent& event) } } +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(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::iterator mi = mapWallet.find(hash); + if (mi == mapWallet.end()) + { + printf("CMainFrame::RefreshStatusColumn() : tx not found in mapWallet\n"); + continue; + } + CWalletTx& wtx = (*mi).second; + if (wtx.IsCoinBase() || wtx.GetTxTime() != wtx.nTimeDisplayed) + { + if (!InsertTransaction(wtx, false, nIndex)) + m_listCtrl->DeleteItem(nIndex--); + } + else + m_listCtrl->SetItem(nIndex, 2, FormatTxStatus(wtx)); + } + } +} + void CMainFrame::OnPaint(wxPaintEvent& event) { event.Skip(); } -void DelayedRepaint(void* parg) + +unsigned int nNeedRepaint = 0; +unsigned int nLastRepaint = 0; +int64 nLastRepaintTime = 0; +int64 nRepaintInterval = 500; + +void ThreadDelayedRepaint(void* parg) { - static bool fOneThread; - if (fOneThread) - return; - fOneThread = true; - Sleep(1000); - printf("DelayedRepaint()\n"); - MainFrameRepaint(); - fOneThread = false; + while (!fShutdown) + { + if (nLastRepaint != nNeedRepaint && GetTimeMillis() - nLastRepaintTime >= nRepaintInterval) + { + nLastRepaint = nNeedRepaint; + if (pframeMain) + { + printf("DelayedRepaint\n"); + wxPaintEvent event; + pframeMain->Refresh(); + pframeMain->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->Refresh(); + pframeMain->AddPendingEvent(event); + } } void CMainFrame::OnPaintListCtrl(wxPaintEvent& event) @@ -854,43 +894,54 @@ void CMainFrame::OnPaintListCtrl(wxPaintEvent& event) if (ptaskbaricon) ptaskbaricon->UpdateTooltip(); - // Update listctrl contents - if (!vWalletUpdated.empty()) + // + // Slower stuff + // + static int nTransactionCount; + bool fPaintedBalance = false; + if (GetTimeMillis() - nLastRepaintTime >= nRepaintInterval) { - TRY_CRITICAL_BLOCK(cs_mapWallet) + nLastRepaint = nNeedRepaint; + nLastRepaintTime = GetTimeMillis(); + + // Update listctrl contents + if (!vWalletUpdated.empty()) { - bool fInserted = false; - foreach(uint256 hash, vWalletUpdated) + TRY_CRITICAL_BLOCK(cs_mapWallet) { - map::iterator mi = mapWallet.find(hash); - if (mi != mapWallet.end()) - fInserted |= InsertTransaction((*mi).second, false); + bool fInserted = false; + foreach(uint256 hash, vWalletUpdated) + { + map::iterator mi = mapWallet.find(hash); + if (mi != mapWallet.end()) + fInserted |= InsertTransaction((*mi).second, false); + } + vWalletUpdated.clear(); + if (fInserted) + m_listCtrl->ScrollList(0, INT_MAX); } - vWalletUpdated.clear(); - if (fInserted) - m_listCtrl->ScrollList(0, INT_MAX); } - } - - // Update status column of visible items only - RefreshStatus(); - - // Balance total - bool fRefreshed = false; - static int nTransactionCount; - TRY_CRITICAL_BLOCK(cs_mapWallet) - { - fRefreshed = true; - m_staticTextBalance->SetLabel(FormatMoney(GetBalance()) + " "); - // Count hidden and multi-line transactions - nTransactionCount = 0; - for (map::iterator it = mapWallet.begin(); it != mapWallet.end(); ++it) + // Balance total + TRY_CRITICAL_BLOCK(cs_mapWallet) { - CWalletTx& wtx = (*it).second; - nTransactionCount += wtx.nLinesDisplayed; + fPaintedBalance = true; + m_staticTextBalance->SetLabel(FormatMoney(GetBalance()) + " "); + + // Count hidden and multi-line transactions + nTransactionCount = 0; + for (map::iterator it = mapWallet.begin(); it != mapWallet.end(); ++it) + { + CWalletTx& wtx = (*it).second; + nTransactionCount += wtx.nLinesDisplayed; + } } } + if (!vWalletUpdated.empty() || !fPaintedBalance) + nNeedRepaint++; + + // Update status column of visible items only + RefreshStatusColumn(); // Update status bar string strGen = ""; @@ -903,13 +954,10 @@ void CMainFrame::OnPaintListCtrl(wxPaintEvent& event) string strStatus = strprintf(" %d connections %d blocks %d transactions", vNodes.size(), nBestHeight + 1, nTransactionCount); m_statusBar->SetStatusText(strStatus, 2); - // mapWallet was locked, try again later - if (!vWalletUpdated.empty() || !fRefreshed) - _beginthread(DelayedRepaint, 0, NULL); - m_listCtrl->OnPaint(event); } + void CrossThreadCall(wxCommandEvent& event) { if (pframeMain) @@ -994,13 +1042,6 @@ void CMainFrame::OnMenuHelpAbout(wxCommandEvent& event) void CMainFrame::OnButtonSend(wxCommandEvent& event) { - /// debug test - if (fRandSendTest) - { - RandSend(); - return; - } - // Toolbar: Send CSendDialog dialog(this); dialog.ShowModal(); @@ -1684,8 +1725,8 @@ void CSendDialog::OnButtonSend(wxCommandEvent& event) else { // Parse IP address - CAddress addr(strAddress.c_str()); - if (addr.ip == 0) + CAddress addr(strAddress); + if (!addr.IsValid()) { wxMessageBox("Invalid address ", "Send Coins"); return; @@ -1818,14 +1859,6 @@ void CSendingDialog::OnPaint(wxPaintEvent& event) wxMessageBox("Transfer cancelled ", "Sending...", wxOK, this); } event.Skip(); - - /// debug test - if (fRandSendTest && fWorkDone && fSuccess) - { - Close(); - Sleep(1000); - RandSend(); - } } @@ -3305,27 +3338,6 @@ bool CMyApp::OnInit() return false; } -map ParseParameters(int argc, char* argv[]) -{ - map mapArgs; - for (int i = 0; i < argc; i++) - { - char psz[10000]; - strcpy(psz, argv[i]); - char* pszValue = ""; - if (strchr(psz, '=')) - { - pszValue = strchr(psz, '='); - *pszValue++ = '\0'; - } - strlwr(psz); - if (psz[0] == '-') - psz[0] = '/'; - mapArgs[psz] = pszValue; - } - return mapArgs; -} - bool CMyApp::OnInit2() { #ifdef _MSC_VER @@ -3337,10 +3349,27 @@ bool CMyApp::OnInit2() // Disable malfunctioning wxWidgets debug assertion g_isPainting = 10000; #endif - - //// debug print - printf("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"); - printf("Bitcoin version %d, Windows version %08x\n", VERSION, GetVersion()); + wxImage::AddHandler(new wxPNGHandler); + SetAppName("Bitcoin"); + + ParseParameters(argc, argv); + if (mapArgs.count("-?") || mapArgs.count("--help")) + { + string strUsage = + "Usage: bitcoin [options]\t\t\t\t\t\t\n" + "Options:\n" + " -gen\t\t Generate coins\n" + " -gen=0\t\t Don't generate coins\n" + " -min\t\t Start minimized\n" + " -datadir=\t Specify data directory\n" + " -proxy=\t Connect through socks4 proxy,\n" + " \t\t e.g. -proxy=127.0.0.1:9050 to use TOR\n" + " -addnode=\t Add a node to connect to\n" + " -connect=\t Connect only to the specified node\n" + " -?\t\t This help message\n"; + wxMessageBox(strUsage, "Bitcoin", wxOK); + exit(0); + } // // Limit to single instance per user @@ -3382,31 +3411,31 @@ bool CMyApp::OnInit2() // // Parameters // - wxImage::AddHandler(new wxPNGHandler); - mapArgs = ParseParameters(argc, argv); - - if (mapArgs.count("/datadir")) - strSetDataDir = mapArgs["/datadir"]; + if (mapArgs.count("-datadir")) + strlcpy(pszSetDataDir, mapArgs["-datadir"].c_str(), sizeof(pszSetDataDir)); - if (mapArgs.count("/debug")) + if (mapArgs.count("-debug")) fDebug = true; - if (mapArgs.count("/printtodebugger")) + if (mapArgs.count("-printtodebugger")) fPrintToDebugger = true; - if (mapArgs.count("/dropmessages")) + printf("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"); + printf("Bitcoin version %d, Windows version %08x\n", VERSION, GetVersion()); + + if (mapArgs.count("-dropmessages")) { - nDropMessagesTest = atoi(mapArgs["/dropmessages"]); + nDropMessagesTest = atoi(mapArgs["-dropmessages"]); if (nDropMessagesTest == 0) nDropMessagesTest = 20; } - if (mapArgs.count("/loadblockindextest")) + if (mapArgs.count("-loadblockindextest")) { CTxDB txdb("r"); txdb.LoadBlockIndex(); PrintBlockTree(); - ExitProcess(0); + exit(0); } // @@ -3417,22 +3446,22 @@ bool CMyApp::OnInit2() int64 nStart; printf("Loading addresses...\n"); - nStart = PerformanceCounter(); + nStart = GetTimeMillis(); if (!LoadAddresses()) strErrors += "Error loading addr.dat \n"; - printf(" addresses %15"PRI64d"\n", PerformanceCounter() - nStart); + printf(" addresses %15"PRI64d"ms\n", GetTimeMillis() - nStart); printf("Loading block index...\n"); - nStart = PerformanceCounter(); + nStart = GetTimeMillis(); if (!LoadBlockIndex()) strErrors += "Error loading blkindex.dat \n"; - printf(" block index %15"PRI64d"\n", PerformanceCounter() - nStart); + printf(" block index %15"PRI64d"ms\n", GetTimeMillis() - nStart); printf("Loading wallet...\n"); - nStart = PerformanceCounter(); + nStart = GetTimeMillis(); if (!LoadWallet(fFirstRun)) strErrors += "Error loading wallet.dat \n"; - printf(" wallet %15"PRI64d"\n", PerformanceCounter() - nStart); + printf(" wallet %15"PRI64d"ms\n", GetTimeMillis() - nStart); printf("Done loading\n"); @@ -3457,45 +3486,59 @@ bool CMyApp::OnInit2() // // Parameters // - if (mapArgs.count("/printblockindex") || mapArgs.count("/printblocktree")) + if (mapArgs.count("-printblockindex") || mapArgs.count("-printblocktree")) { PrintBlockTree(); OnExit(); return false; } - if (mapArgs.count("/proxy")) + if (mapArgs.count("-gen")) + { + if (mapArgs["-gen"].empty()) + fGenerateBitcoins = true; + else + fGenerateBitcoins = atoi(mapArgs["-gen"].c_str()); + } + + if (mapArgs.count("-proxy")) { fUseProxy = true; - addrProxy = CAddress(mapArgs["/proxy"].c_str()); - if (addrProxy.ip == INADDR_NONE) + addrProxy = CAddress(mapArgs["-proxy"]); + if (!addrProxy.IsValid()) { - wxMessageBox("Invalid /proxy address", "Bitcoin"); + wxMessageBox("Invalid -proxy address", "Bitcoin"); OnExit(); + return false; } CWalletDB walletdb; walletdb.WriteSetting("fUseProxy", fUseProxy); walletdb.WriteSetting("addrProxy", addrProxy); } - if (mapArgs.count("/gen")) + if (mapArgs.count("-addnode")) { - if (mapArgs["/gen"].empty()) - fGenerateBitcoins = true; - else - fGenerateBitcoins = atoi(mapArgs["/gen"].c_str()); + CAddrDB addrdb; + foreach(string strAddr, mapMultiArgs["-addnode"]) + { + CAddress addr(strAddr, NODE_NETWORK); + if (addr.IsValid()) + AddAddress(addrdb, addr); + } } // // Create the main frame window // pframeMain = new CMainFrame(NULL); - if (mapArgs.count("/min")) + if (mapArgs.count("-min")) pframeMain->Iconize(true); pframeMain->Show(true); // have to show first to get taskbar button to hide pframeMain->Show(!fMinimizeToTray || !pframeMain->IsIconized()); ptaskbaricon->Show(fMinimizeToTray); + _beginthread(ThreadDelayedRepaint, 0, NULL); + if (!CheckDiskSpace()) { OnExit(); @@ -3516,7 +3559,7 @@ bool CMyApp::OnInit2() // // Tests // - if (argc >= 2 && stricmp(argv[1], "/send") == 0) + if (argc >= 2 && stricmp(argv[1], "-send") == 0) { int64 nValue = 1; if (argc >= 3) @@ -3525,7 +3568,7 @@ bool CMyApp::OnInit2() string strAddress; if (argc >= 4) strAddress = argv[3]; - CAddress addr(strAddress.c_str()); + CAddress addr(strAddress); CWalletTx wtx; wtx.mapValue["to"] = strAddress; @@ -3538,15 +3581,6 @@ bool CMyApp::OnInit2() return false; } - if (mapArgs.count("/randsendtest")) - { - if (!mapArgs["/randsendtest"].empty()) - _beginthread(ThreadRandSendTest, 0, new string(mapArgs["/randsendtest"])); - else - fRandSendTest = true; - fDebug = true; - } - return true; } @@ -3610,19 +3644,6 @@ void CMyApp::OnFatalException() -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) - { - printf("MainFrameRepaint()\n"); - wxPaintEvent event; - pframeMain->Refresh(); - pframeMain->AddPendingEvent(event); - } -} - typedef WINSHELLAPI BOOL WINAPI (*PSHGETSPECIALFOLDERPATHA)(HWND hwndOwner, LPSTR lpszPath, int nFolder, BOOL fCreate); @@ -3666,7 +3687,7 @@ string StartupShortcutPath() bool GetStartOnSystemStartup() { - return FileExists(StartupShortcutPath().c_str()); + return wxFileExists(StartupShortcutPath()); } void SetStartOnSystemStartup(bool fAutoStart) @@ -3727,79 +3748,3 @@ void SetStartOnSystemStartup(bool fAutoStart) - -// randsendtest to bitcoin address -void ThreadRandSendTest(void* parg) -{ - string strAddress = *(string*)parg; - uint160 hash160; - if (!AddressToHash160(strAddress, hash160)) - { - wxMessageBox(strprintf("ThreadRandSendTest: Bitcoin address '%s' not valid ", strAddress.c_str())); - return; - } - - while (!fShutdown) - { - Sleep(GetRand(30) * 1000 + 100); - - // Message - CWalletTx wtx; - wtx.mapValue["to"] = strAddress; - wtx.mapValue["from"] = addrLocalHost.ToString(); - static int nRep; - wtx.mapValue["message"] = strprintf("randsendtest %d\n", ++nRep); - - // Value - int64 nValue = (GetRand(9) + 1) * 100 * CENT; - if (GetBalance() < nValue) - { - wxMessageBox("Out of money "); - while (GetBalance() < 1000) - Sleep(1000); - } - nValue += (nRep % 100) * CENT; - - // Send to bitcoin address - CScript scriptPubKey; - scriptPubKey << OP_DUP << OP_HASH160 << hash160 << OP_EQUALVERIFY << OP_CHECKSIG; - - if (fShutdown) - return; - if (!SendMoney(scriptPubKey, nValue, wtx)) - return; - } -} - - -// randsendtest to any connected node -void RandSend() -{ - while (vNodes.empty()) - Sleep(1000); - CAddress addr; - CRITICAL_BLOCK(cs_vNodes) - addr = vNodes[GetRand(vNodes.size())]->addr; - - // Message - CWalletTx wtx; - wtx.mapValue["to"] = addr.ToString(); - wtx.mapValue["from"] = addrLocalHost.ToString(); - static int nRep; - wtx.mapValue["message"] = strprintf("randsendtest %d\n", ++nRep); - - // Value - int64 nValue = (GetRand(999) + 1) * CENT; - if (GetBalance() < nValue) - { - wxMessageBox("Out of money "); - return; - } - - // Send to IP address - if (fShutdown) - return; - CSendingDialog* pdialog = new CSendingDialog(pframeMain, addr, nValue, wtx); - if (!pdialog->Show()) - wxMessageBox("ShowModal Failed "); -} diff --git a/ui.h b/ui.h index 9fc7e0ebe7..47839e81e2 100644 --- a/ui.h +++ b/ui.h @@ -83,15 +83,14 @@ public: bool fRefreshListCtrl; bool fRefreshListCtrlRunning; bool fOnSetFocusAddress; - CBlockIndex* pindexBestLast; - set setUnmaturedDisplayed; + unsigned int nListViewUpdated; void OnCrossThreadCall(wxCommandEvent& event); void InsertLine(bool fNew, int nIndex, uint256 hashKey, string strSort, 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 RefreshStatus(); + void RefreshStatusColumn(); }; diff --git a/util.cpp b/util.cpp index ef950920fd..23b59f11f7 100644 --- a/util.cpp +++ b/util.cpp @@ -5,9 +5,13 @@ #include "headers.h" +map mapArgs; +map > mapMultiArgs; bool fDebug = false; bool fPrintToDebugger = false; bool fPrintToConsole = false; +char pszSetDataDir[MAX_PATH] = ""; + @@ -68,6 +72,8 @@ void RandAddSeed() void RandAddSeedPerfmon() { +#ifdef __WXMSW__ + // Don't need this on Linux, OpenSSL automatically uses /dev/urandom // This can take up to 2 seconds, so only do it every 10 minutes static int64 nLastPerfmon; if (GetTime() < nLastPerfmon + 10 * 60) @@ -95,6 +101,7 @@ void RandAddSeedPerfmon() strftime(pszTime, sizeof(pszTime), "%x %H:%M:%S", ptmTime); printf("%s RandAddSeed() %d bytes\n", pszTime, nSize); } +#endif } @@ -304,6 +311,32 @@ vector ParseHex(const std::string& str) } +void ParseParameters(int argc, char* argv[]) +{ + mapArgs.clear(); + mapMultiArgs.clear(); + for (int i = 0; i < argc; i++) + { + char psz[10000]; + strlcpy(psz, argv[i], sizeof(psz)); + char* pszValue = ""; + if (strchr(psz, '=')) + { + pszValue = strchr(psz, '='); + *pszValue++ = '\0'; + } + strlwr(psz); + #ifdef __WXMSW__ + if (psz[0] == '/') + psz[0] = '-'; + #endif + mapArgs[psz] = pszValue; + mapMultiArgs[psz].push_back(pszValue); + } +} + + + @@ -346,15 +379,6 @@ void PrintException(std::exception* pex, const char* pszThread) -bool FileExists(const char* psz) -{ -#ifdef WIN32 - return GetFileAttributes(psz) != -1; -#else - return access(psz, 0) != -1; -#endif -} - int GetFilesize(FILE* file) { int nSavePos = ftell(file); @@ -365,6 +389,46 @@ int GetFilesize(FILE* file) return nFilesize; } +void GetDataDir(char* pszDir) +{ + // pszDir must be at least MAX_PATH length. + if (pszSetDataDir[0] != 0) + { + strlcpy(pszDir, pszSetDataDir, MAX_PATH); + static bool fMkdirDone; + if (!fMkdirDone) + { + fMkdirDone = true; + _mkdir(pszDir); + } + } + else + { + // This can be called during exceptions by printf, so we cache the + // value so we don't have to do memory allocations after that. + // wxStandardPaths::GetUserDataDir + // Return the directory for the user-dependent application data files: + // Unix: ~/.appname + // Windows: C:\Documents and Settings\username\Application Data\appname + // Mac: ~/Library/Application Support/appname + static char pszCachedDir[MAX_PATH]; + if (pszCachedDir[0] == 0) + { + strlcpy(pszCachedDir, wxStandardPaths::Get().GetUserDataDir().c_str(), sizeof(pszCachedDir)); + _mkdir(pszCachedDir); + } + strlcpy(pszDir, pszCachedDir, MAX_PATH); + } + +} + +string GetDataDir() +{ + char pszDir[MAX_PATH]; + GetDataDir(pszDir); + return pszDir; +} + diff --git a/util.h b/util.h index 5d18776002..822a049ce7 100644 --- a/util.h +++ b/util.h @@ -54,16 +54,23 @@ inline T& REF(const T& val) return (T&)val; } +#ifndef __WXMSW__ +#define closesocket(s) close(s) +#define INVALID_SOCKET (SOCKET)(~0) +typedef u_int SOCKET; +#endif +extern map mapArgs; +extern map > mapMultiArgs; extern bool fDebug; extern bool fPrintToDebugger; extern bool fPrintToConsole; -extern map mapArgs; +extern char pszSetDataDir[MAX_PATH]; void RandAddSeed(); void RandAddSeedPerfmon(); @@ -77,8 +84,10 @@ string FormatMoney(int64 n, bool fPlus=false); bool ParseMoney(const char* pszIn, int64& nRet); vector ParseHex(const char* psz); vector ParseHex(const std::string& str); -bool FileExists(const char* psz); +void ParseParameters(int argc, char* argv[]); int GetFilesize(FILE* file); +void GetDataDir(char* pszDirRet); +string GetDataDir(); uint64 GetRand(uint64 nMax); int64 GetTime(); int64 GetAdjustedTime(); @@ -172,9 +181,14 @@ inline int OutputDebugStringF(const char* pszFormat, ...) if (!fPrintToConsole) { // print to debug.log - FILE* fileout = fopen("debug.log", "a"); + char pszFile[MAX_PATH+100]; + GetDataDir(pszFile); + strlcat(pszFile, "\\debug.log", sizeof(pszFile)); + FILE* fileout = fopen(pszFile, "a"); if (fileout) { + //// Debug print useful for profiling + //fprintf(fileout, " %"PRI64d" ", wxGetLocalTimeMillis().GetValue()); va_list arg_ptr; va_start(arg_ptr, pszFormat); ret = vfprintf(fileout, pszFormat, arg_ptr); @@ -321,22 +335,25 @@ inline void PrintHex(vector vch, const char* pszFormat="%s", bool { printf(pszFormat, HexStr(vch, fSpaces).c_str()); } - inline int64 PerformanceCounter() { - int64 nCounter = 0; + int64 nCounter = 0; #ifdef __WXMSW__ - QueryPerformanceCounter((LARGE_INTEGER*)&nCounter); + QueryPerformanceCounter((LARGE_INTEGER*)&nCounter); #else - // this could be changed to reading /dev/urandom - timeval t; - gettimeofday(&t, NULL); - nCounter += t.tv_sec * 1000000 + t.tv_usec; + timeval t; + gettimeofday(&t, NULL); + nCounter = t.tv_sec * 1000000 + t.tv_usec; #endif return nCounter; } +inline int64 GetTimeMillis() +{ + return wxGetLocalTimeMillis().GetValue(); +} + #ifndef __WXMSW__ inline void Sleep(unsigned int nMilliseconds) { @@ -354,8 +371,10 @@ inline void Sleep(unsigned int nMilliseconds) inline void heapchk() { +#ifdef __WXMSW__ if (_heapchk() != _HEAPOK) DebugBreak(); +#endif } // Randomize the stack to help protect against buffer overrun exploits -- cgit v1.2.3 From 4ac57f013e20da2d0f87fff69625cbd4419089f3 Mon Sep 17 00:00:00 2001 From: s_nakamoto Date: Sun, 1 Nov 2009 01:16:51 +0000 Subject: move debug.log and db.log to data dir, portable GetDataDir, optimize GetBalance, fix repaint bogdown, -addnode and -? switches git-svn-id: https://bitcoin.svn.sourceforge.net/svnroot/bitcoin/trunk@25 1a98c847-1fd6-4fd8-948a-caf3550aa51b --- build.txt | 2 +- db.cpp | 19 +-- irc.cpp | 7 +- irc.h | 5 - main.cpp | 50 +------ main.h | 20 ++- net.cpp | 34 ++++- net.h | 78 ++++++----- ui.cpp | 457 +++++++++++++++++++++++++++----------------------------------- ui.h | 5 +- util.cpp | 82 +++++++++-- util.h | 39 ++++-- 12 files changed, 416 insertions(+), 382 deletions(-) diff --git a/build.txt b/build.txt index 67b03fe24a..4368af855a 100644 --- a/build.txt +++ b/build.txt @@ -10,7 +10,7 @@ cryptographic software written by Eric Young (eay@cryptsoft.com). Compilers Supported ------------------- -MinGW GCC +MinGW GCC (v3.4.5) Microsoft Visual C++ 6.0 SP6 diff --git a/db.cpp b/db.cpp index 699a94f2ea..f9e25834d0 100644 --- a/db.cpp +++ b/db.cpp @@ -61,18 +61,19 @@ CDB::CDB(const char* pszFile, const char* pszMode, bool fTxn) : pdb(NULL) { if (fShutdown) return; - string strAppDir = GetAppDir(); - string strLogDir = strAppDir + "\\database"; + string strDataDir = GetDataDir(); + string strLogDir = strDataDir + "\\database"; _mkdir(strLogDir.c_str()); - printf("dbenv.open strAppDir=%s\n", strAppDir.c_str()); + string strErrorFile = strDataDir + "\\db.log"; + printf("dbenv.open strLogDir=%s strErrorFile=%s\n", strLogDir.c_str(), strErrorFile.c_str()); dbenv.set_lg_dir(strLogDir.c_str()); dbenv.set_lg_max(10000000); dbenv.set_lk_max_locks(10000); dbenv.set_lk_max_objects(10000); - dbenv.set_errfile(fopen("db.log", "a")); /// debug + dbenv.set_errfile(fopen(strErrorFile.c_str(), "a")); /// debug ///dbenv.log_set_config(DB_LOG_AUTO_REMOVE, 1); /// causes corruption - ret = dbenv.open(strAppDir.c_str(), + ret = dbenv.open(strDataDir.c_str(), DB_CREATE | DB_INIT_LOCK | DB_INIT_LOG | @@ -139,6 +140,8 @@ void DBFlush(bool fShutdown) // Flush log data to the actual data file // on all files that are not in use printf("DBFlush(%s)\n", fShutdown ? "true" : "false"); + if (!fDbEnvInit) + return; CRITICAL_BLOCK(cs_db) { dbenv.txn_checkpoint(0, 0, 0); @@ -421,7 +424,7 @@ bool CAddrDB::LoadAddresses() while (fgets(psz, sizeof(psz), filein)) { CAddress addr(psz, NODE_NETWORK); - if (addr.ip != 0) + if (addr.IsValid()) { AddAddress(*this, addr); mapIRCAddresses.insert(make_pair(addr.GetKey(), addr)); @@ -676,10 +679,10 @@ void ThreadFlushWalletDB(void* parg) { // Flush wallet.dat so it's self contained nLastFlushed == nWalletDBUpdated; - int64 nStart = PerformanceCounter(); + int64 nStart = GetTimeMillis(); dbenv.txn_checkpoint(0, 0, 0); dbenv.lsn_reset(strFile.c_str(), 0); - printf("Flushed wallet.dat %15"PRI64d"\n", PerformanceCounter() - nStart); + printf("Flushed wallet.dat %"PRI64d"ms\n", GetTimeMillis() - nStart); mapFileUseCount.erase(mi++); } } diff --git a/irc.cpp b/irc.cpp index 707b4fe19f..f839dc5224 100644 --- a/irc.cpp +++ b/irc.cpp @@ -40,7 +40,7 @@ bool DecodeAddress(string str, CAddress& addr) return false; memcpy(&tmp, &vch[0], sizeof(tmp)); - addr = CAddress(tmp.ip, tmp.port); + addr = CAddress(tmp.ip, tmp.port, NODE_NETWORK); return true; } @@ -163,6 +163,7 @@ void ThreadIRCSeed(void* parg) int nErrorWait = 10; int nRetryWait = 10; + // IRC server blocks TOR users if (fUseProxy && addrProxy.port == htons(9050)) return; @@ -237,14 +238,14 @@ void ThreadIRCSeed(void* parg) { // index 7 is limited to 16 characters // could get full length name at index 10, but would be different from join messages - strcpy(pszName, vWords[7].c_str()); + strlcpy(pszName, vWords[7].c_str(), sizeof(pszName)); printf("IRC got who\n"); } if (vWords[1] == "JOIN" && vWords[0].size() > 1) { // :username!username@50000007.F000000B.90000002.IP JOIN :#channelname - strcpy(pszName, vWords[0].c_str() + 1); + strlcpy(pszName, vWords[0].c_str() + 1, sizeof(pszName)); if (strchr(pszName, '!')) *strchr(pszName, '!') = '\0'; printf("IRC got join\n"); diff --git a/irc.h b/irc.h index 1dc348a8be..91c3ffe686 100644 --- a/irc.h +++ b/irc.h @@ -1,11 +1,6 @@ // Copyright (c) 2009 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 __WXMSW__ -#define closesocket(s) close(s) -typedef u_int SOCKET; -#endif extern bool RecvLine(SOCKET hSocket, string& strLine); extern void ThreadIRCSeed(void* parg); diff --git a/main.cpp b/main.cpp index 156267771c..ade3b51c77 100644 --- a/main.cpp +++ b/main.cpp @@ -42,7 +42,6 @@ map > mapPubKeys; CCriticalSection cs_mapKeys; CKey keyUser; -string strSetDataDir; int nDropMessagesTest = 0; // Settings @@ -1361,52 +1360,17 @@ bool ScanMessageStart(Stream& s) } } -string GetAppDir() -{ - string strDir; - if (!strSetDataDir.empty()) - { - strDir = strSetDataDir; - } - else if (getenv("APPDATA")) - { - strDir = strprintf("%s\\Bitcoin", getenv("APPDATA")); - } - else if (getenv("USERPROFILE")) - { - string strAppData = strprintf("%s\\Application Data", getenv("USERPROFILE")); - static bool fMkdirDone; - if (!fMkdirDone) - { - fMkdirDone = true; - _mkdir(strAppData.c_str()); - } - strDir = strprintf("%s\\Bitcoin", strAppData.c_str()); - } - else - { - return "."; - } - static bool fMkdirDone; - if (!fMkdirDone) - { - fMkdirDone = true; - _mkdir(strDir.c_str()); - } - return strDir; -} - bool CheckDiskSpace(int64 nAdditionalBytes) { wxLongLong nFreeBytesAvailable = 0; - if (!wxGetDiskSpace(wxStandardPaths::Get().GetDataDir(), NULL, &nFreeBytesAvailable)) + if (!wxGetDiskSpace(GetDataDir(), NULL, &nFreeBytesAvailable)) { printf("ERROR: wxGetDiskSpace() failed\n"); return true; } // Check for 15MB because database could create another 10MB log file at any time - if (nFreeBytesAvailable < (int64)15000000 + nAdditionalBytes) + if (nFreeBytesAvailable.GetValue() < (int64)15000000 + nAdditionalBytes) { fShutdown = true; wxMessageBox("Warning: Your disk space is low ", "Bitcoin", wxICON_EXCLAMATION); @@ -1420,7 +1384,7 @@ FILE* OpenBlockFile(unsigned int nFile, unsigned int nBlockPos, const char* pszM { if (nFile == -1) return NULL; - FILE* file = fopen(strprintf("%s\\blk%04d.dat", GetAppDir().c_str(), nFile).c_str(), pszMode); + FILE* file = fopen(strprintf("%s\\blk%04d.dat", GetDataDir().c_str(), nFile).c_str(), pszMode); if (!file) return NULL; if (nBlockPos != 0 && !strchr(pszMode, 'a') && !strchr(pszMode, 'w')) @@ -1719,7 +1683,7 @@ bool ProcessMessages(CNode* pfrom) if (strstr(e.what(), "CDataStream::read() : end of data")) { // Allow exceptions from underlength message on vRecv - LogException(&e, "ProcessMessage()"); + printf("ProcessMessage(%s, %d bytes) : Exception '%s' caught, normally caused by a message being shorter than its stated length\n", strCommand.c_str(), nMessageSize, e.what()); } else PrintException(&e, "ProcessMessage()"); @@ -2512,7 +2476,7 @@ bool BitcoinMiner() int64 GetBalance() { - int64 nStart = PerformanceCounter(); + int64 nStart = GetTimeMillis(); int64 nTotal = 0; CRITICAL_BLOCK(cs_mapWallet) @@ -2522,11 +2486,11 @@ int64 GetBalance() CWalletTx* pcoin = &(*it).second; if (!pcoin->IsFinal() || pcoin->fSpent) continue; - nTotal += pcoin->GetCredit(); + nTotal += pcoin->GetCredit(true); } } - ///printf(" GetBalance() time = %15"PRI64d"\n", PerformanceCounter() - nStart); + //printf("GetBalance() %"PRI64d"ms\n", GetTimeMillis() - nStart); return nTotal; } diff --git a/main.h b/main.h index fcfd33d134..a0258cf2ce 100644 --- a/main.h +++ b/main.h @@ -34,7 +34,6 @@ extern int nBestHeight; extern uint256 hashBestChain; extern CBlockIndex* pindexBest; extern unsigned int nTransactionsUpdated; -extern string strSetDataDir; extern int nDropMessagesTest; // Settings @@ -50,7 +49,6 @@ extern int nLimitProcessors; -string GetAppDir(); bool CheckDiskSpace(int64 nAdditionalBytes=0); FILE* OpenBlockFile(unsigned int nFile, unsigned int nBlockPos, const char* pszMode="rb"); FILE* AppendBlockFile(unsigned int& nFileRet); @@ -405,10 +403,10 @@ public: { // Time based nLockTime implemented in 0.1.6, // do not use time based until most 0.1.5 nodes have upgraded. - if (nBlockTime == 0) - nBlockTime = GetAdjustedTime(); if (nLockTime == 0) return true; + if (nBlockTime == 0) + nBlockTime = GetAdjustedTime(); if (nLockTime < (nLockTime < 500000000 ? nBestHeight : nBlockTime)) return true; foreach(const CTxIn& txin, vin) @@ -627,6 +625,8 @@ public: // memory only mutable bool fMerkleVerified; + mutable bool fGetCreditCached; + mutable int64 nGetCreditCached; CMerkleTx() @@ -644,14 +644,22 @@ public: hashBlock = 0; nIndex = -1; fMerkleVerified = false; + fGetCreditCached = false; + nGetCreditCached = 0; } - int64 GetCredit() const + int64 GetCredit(bool fUseCache=false) const { // Must wait until coinbase is safely deep enough in the chain before valuing it if (IsCoinBase() && GetBlocksToMaturity() > 0) return 0; - return CTransaction::GetCredit(); + + // GetBalance can assume transactions in mapWallet won't change + if (fUseCache && fGetCreditCached) + return nGetCreditCached; + nGetCreditCached = CTransaction::GetCredit(); + fGetCreditCached = true; + return nGetCreditCached; } IMPLEMENT_SERIALIZE diff --git a/net.cpp b/net.cpp index 22b84f9dee..8ccf48b819 100644 --- a/net.cpp +++ b/net.cpp @@ -21,8 +21,7 @@ bool OpenNetworkConnection(const CAddress& addrConnect); bool fClient = false; uint64 nLocalServices = (fClient ? 0 : NODE_NETWORK); CAddress addrLocalHost(0, DEFAULT_PORT, nLocalServices); -CNode nodeLocalHost(INVALID_SOCKET, CAddress("127.0.0.1", nLocalServices)); -CNode* pnodeLocalHost = &nodeLocalHost; +CNode* pnodeLocalHost = NULL; uint64 nLocalHostNonce = 0; bool fShutdown = false; array vnThreadsRunning; @@ -129,7 +128,7 @@ bool GetMyExternalIP2(const CAddress& addrConnect, const char* pszGet, const cha strLine = wxString(strLine).Trim(); CAddress addr(strLine.c_str()); printf("GetMyExternalIP() received [%s] %s\n", strLine.c_str(), addr.ToString().c_str()); - if (addr.ip == 0 || !addr.IsRoutable()) + if (addr.ip == 0 || addr.ip == INADDR_NONE || !addr.IsRoutable()) return false; ipRet = addr.ip; return true; @@ -740,10 +739,29 @@ void ThreadOpenConnections2(void* parg) printf("ThreadOpenConnections started\n"); // Connect to one specified address - while (mapArgs.count("/connect")) + while (mapArgs.count("-connect")) { - OpenNetworkConnection(CAddress(mapArgs["/connect"].c_str())); - Sleep(10000); + OpenNetworkConnection(CAddress(mapArgs["-connect"])); + for (int i = 0; i < 10; i++) + { + Sleep(1000); + CheckForShutdown(1); + } + } + + // Connect to manually added nodes first + if (mapArgs.count("-addnode")) + { + foreach(string strAddr, mapMultiArgs["-addnode"]) + { + CAddress addr(strAddr, NODE_NETWORK); + if (addr.IsValid()) + { + OpenNetworkConnection(addr); + Sleep(1000); + CheckForShutdown(1); + } + } } // Initiate network connections @@ -967,6 +985,8 @@ void ThreadMessageHandler2(void* parg) bool StartNode(string& strError) { + if (pnodeLocalHost == NULL) + pnodeLocalHost = new CNode(INVALID_SOCKET, CAddress("127.0.0.1", nLocalServices)); strError = ""; // Sockets startup @@ -1031,7 +1051,7 @@ bool StartNode(string& strError) printf("%s\n", strError.c_str()); return false; } - printf("bound to addrLocalHost = %s\n\n", addrLocalHost.ToString().c_str()); + printf("bound to addrLocalHost = %s\n", addrLocalHost.ToString().c_str()); // Listen for incoming connections if (listen(hListenSocket, SOMAXCONN) == SOCKET_ERROR) diff --git a/net.h b/net.h index 2eece2c061..7716426f04 100644 --- a/net.h +++ b/net.h @@ -1,12 +1,6 @@ // Copyright (c) 2009 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 __WXMSW__ -#define closesocket(s) close(s) -#define INVALID_SOCKET (SOCKET)(~0) -typedef u_int SOCKET; -#endif class CMessageHeader; class CAddress; @@ -148,61 +142,73 @@ public: CAddress() { - nServices = 0; - memcpy(pchReserved, pchIPv4, sizeof(pchReserved)); - ip = 0; - port = DEFAULT_PORT; - nTime = GetAdjustedTime(); - nLastFailed = 0; + Init(); } - CAddress(unsigned int ipIn, unsigned short portIn=DEFAULT_PORT, uint64 nServicesIn=0) + CAddress(unsigned int ipIn, unsigned short portIn=DEFAULT_PORT, uint64 nServicesIn=NODE_NETWORK) { - nServices = nServicesIn; - memcpy(pchReserved, pchIPv4, sizeof(pchReserved)); + Init(); ip = ipIn; port = portIn; - nTime = GetAdjustedTime(); - nLastFailed = 0; + nServices = nServicesIn; } - explicit CAddress(const struct sockaddr_in& sockaddr, uint64 nServicesIn=0) + explicit CAddress(const struct sockaddr_in& sockaddr, uint64 nServicesIn=NODE_NETWORK) { - nServices = nServicesIn; - memcpy(pchReserved, pchIPv4, sizeof(pchReserved)); + Init(); ip = sockaddr.sin_addr.s_addr; port = sockaddr.sin_port; - nTime = GetAdjustedTime(); - nLastFailed = 0; + nServices = nServicesIn; } - explicit CAddress(const char* pszIn, uint64 nServicesIn=0) + explicit CAddress(const char* pszIn, uint64 nServicesIn=NODE_NETWORK) { + Init(); + SetAddress(pszIn); nServices = nServicesIn; + } + + explicit CAddress(string strIn, uint64 nServicesIn=NODE_NETWORK) + { + Init(); + SetAddress(strIn.c_str()); + nServices = nServicesIn; + } + + void Init() + { + nServices = NODE_NETWORK; memcpy(pchReserved, pchIPv4, sizeof(pchReserved)); ip = INADDR_NONE; port = DEFAULT_PORT; nTime = GetAdjustedTime(); nLastFailed = 0; + } + bool SetAddress(const char* pszIn) + { + ip = INADDR_NONE; + port = DEFAULT_PORT; char psz[100]; - if (strlen(pszIn) > ARRAYLEN(psz)-1) - return; - strcpy(psz, pszIn); + strlcpy(psz, pszIn, sizeof(psz)); unsigned int a=0, b=0, c=0, d=0, e=0; if (sscanf(psz, "%u.%u.%u.%u:%u", &a, &b, &c, &d, &e) < 4) - return; + return false; char* pszPort = strchr(psz, ':'); if (pszPort) { *pszPort++ = '\0'; port = htons(atoi(pszPort)); - if (atoi(pszPort) > USHRT_MAX) + if (atoi(pszPort) < 0 || atoi(pszPort) > USHRT_MAX) port = htons(USHRT_MAX); - if (atoi(pszPort) < 0) - port = htons(0); } ip = inet_addr(psz); + return IsValid(); + } + + bool SetAddress(string strIn) + { + return SetAddress(strIn.c_str()); } IMPLEMENT_SERIALIZE @@ -274,7 +280,17 @@ public: bool IsRoutable() const { - return !(GetByte(3) == 10 || (GetByte(3) == 192 && GetByte(2) == 168) || GetByte(3) == 127 || GetByte(3) == 0); + return !(GetByte(3) == 10 || + (GetByte(3) == 192 && GetByte(2) == 168) || + GetByte(3) == 127 || + GetByte(3) == 0 || + ip == 0 || + ip == INADDR_NONE); + } + + bool IsValid() const + { + return (ip != 0 && ip != INADDR_NONE && port != htons(USHRT_MAX)); } unsigned char GetByte(int n) const diff --git a/ui.cpp b/ui.cpp index ce287e3911..9185b8159f 100644 --- a/ui.cpp +++ b/ui.cpp @@ -25,7 +25,6 @@ DEFINE_EVENT_TYPE(wxEVT_TABLEDELETED) CMainFrame* pframeMain = NULL; CMyTaskBarIcon* ptaskbaricon = NULL; map mapAddressBook; -map mapArgs; bool fRandSendTest = false; void RandSend(); extern int g_isPainting; @@ -283,7 +282,6 @@ CMainFrame::CMainFrame(wxWindow* parent) : CMainFrameBase(parent) fRefreshListCtrl = false; fRefreshListCtrlRunning = false; fOnSetFocusAddress = false; - pindexBestLast = NULL; m_choiceFilter->SetSelection(0); m_staticTextBalance->SetLabel(FormatMoney(GetBalance()) + " "); m_listCtrl->SetFocus(); @@ -507,6 +505,7 @@ bool CMainFrame::InsertTransaction(const CWalletTx& wtx, bool fNew, int nIndex) string strStatus = FormatTxStatus(wtx); map mapValue = wtx.mapValue; wtx.nLinesDisplayed = 1; + nListViewUpdated++; // Filter if (wtx.IsCoinBase()) @@ -712,48 +711,6 @@ bool CMainFrame::InsertTransaction(const CWalletTx& wtx, bool fNew, int nIndex) return true; } -void CMainFrame::RefreshStatus() -{ - static int nLastTop; - int nTop = max((int)m_listCtrl->GetTopItem(), 0); - if (nTop == nLastTop && pindexBestLast == pindexBest) - return; - - TRY_CRITICAL_BLOCK(cs_mapWallet) - { - int nStart = nTop; - int nEnd = min(nStart + 100, m_listCtrl->GetItemCount()); - if (pindexBestLast == pindexBest) - { - if (nStart >= nLastTop && nStart < nLastTop + 100) - nStart = nLastTop + 100; - if (nEnd >= nLastTop && nEnd < nLastTop + 100) - nEnd = nLastTop; - } - nLastTop = nTop; - pindexBestLast = pindexBest; - - for (int nIndex = nStart; nIndex < min(nEnd, m_listCtrl->GetItemCount()); nIndex++) - { - uint256 hash((string)GetItemText(m_listCtrl, nIndex, 1)); - map::iterator mi = mapWallet.find(hash); - if (mi == mapWallet.end()) - { - printf("CMainFrame::RefreshStatus() : tx not found in mapWallet\n"); - continue; - } - CWalletTx& wtx = (*mi).second; - if (wtx.IsCoinBase() || wtx.GetTxTime() != wtx.nTimeDisplayed) - { - if (!InsertTransaction(wtx, false, nIndex)) - m_listCtrl->DeleteItem(nIndex--); - } - else - m_listCtrl->SetItem(nIndex, 2, FormatTxStatus(wtx)); - } - } -} - void CMainFrame::RefreshListCtrl() { fRefreshListCtrl = true; @@ -832,21 +789,104 @@ void CMainFrame::OnIdle(wxIdleEvent& event) } } +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(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::iterator mi = mapWallet.find(hash); + if (mi == mapWallet.end()) + { + printf("CMainFrame::RefreshStatusColumn() : tx not found in mapWallet\n"); + continue; + } + CWalletTx& wtx = (*mi).second; + if (wtx.IsCoinBase() || wtx.GetTxTime() != wtx.nTimeDisplayed) + { + if (!InsertTransaction(wtx, false, nIndex)) + m_listCtrl->DeleteItem(nIndex--); + } + else + m_listCtrl->SetItem(nIndex, 2, FormatTxStatus(wtx)); + } + } +} + void CMainFrame::OnPaint(wxPaintEvent& event) { event.Skip(); } -void DelayedRepaint(void* parg) + +unsigned int nNeedRepaint = 0; +unsigned int nLastRepaint = 0; +int64 nLastRepaintTime = 0; +int64 nRepaintInterval = 500; + +void ThreadDelayedRepaint(void* parg) { - static bool fOneThread; - if (fOneThread) - return; - fOneThread = true; - Sleep(1000); - printf("DelayedRepaint()\n"); - MainFrameRepaint(); - fOneThread = false; + while (!fShutdown) + { + if (nLastRepaint != nNeedRepaint && GetTimeMillis() - nLastRepaintTime >= nRepaintInterval) + { + nLastRepaint = nNeedRepaint; + if (pframeMain) + { + printf("DelayedRepaint\n"); + wxPaintEvent event; + pframeMain->Refresh(); + pframeMain->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->Refresh(); + pframeMain->AddPendingEvent(event); + } } void CMainFrame::OnPaintListCtrl(wxPaintEvent& event) @@ -854,43 +894,54 @@ void CMainFrame::OnPaintListCtrl(wxPaintEvent& event) if (ptaskbaricon) ptaskbaricon->UpdateTooltip(); - // Update listctrl contents - if (!vWalletUpdated.empty()) + // + // Slower stuff + // + static int nTransactionCount; + bool fPaintedBalance = false; + if (GetTimeMillis() - nLastRepaintTime >= nRepaintInterval) { - TRY_CRITICAL_BLOCK(cs_mapWallet) + nLastRepaint = nNeedRepaint; + nLastRepaintTime = GetTimeMillis(); + + // Update listctrl contents + if (!vWalletUpdated.empty()) { - bool fInserted = false; - foreach(uint256 hash, vWalletUpdated) + TRY_CRITICAL_BLOCK(cs_mapWallet) { - map::iterator mi = mapWallet.find(hash); - if (mi != mapWallet.end()) - fInserted |= InsertTransaction((*mi).second, false); + bool fInserted = false; + foreach(uint256 hash, vWalletUpdated) + { + map::iterator mi = mapWallet.find(hash); + if (mi != mapWallet.end()) + fInserted |= InsertTransaction((*mi).second, false); + } + vWalletUpdated.clear(); + if (fInserted) + m_listCtrl->ScrollList(0, INT_MAX); } - vWalletUpdated.clear(); - if (fInserted) - m_listCtrl->ScrollList(0, INT_MAX); } - } - - // Update status column of visible items only - RefreshStatus(); - - // Balance total - bool fRefreshed = false; - static int nTransactionCount; - TRY_CRITICAL_BLOCK(cs_mapWallet) - { - fRefreshed = true; - m_staticTextBalance->SetLabel(FormatMoney(GetBalance()) + " "); - // Count hidden and multi-line transactions - nTransactionCount = 0; - for (map::iterator it = mapWallet.begin(); it != mapWallet.end(); ++it) + // Balance total + TRY_CRITICAL_BLOCK(cs_mapWallet) { - CWalletTx& wtx = (*it).second; - nTransactionCount += wtx.nLinesDisplayed; + fPaintedBalance = true; + m_staticTextBalance->SetLabel(FormatMoney(GetBalance()) + " "); + + // Count hidden and multi-line transactions + nTransactionCount = 0; + for (map::iterator it = mapWallet.begin(); it != mapWallet.end(); ++it) + { + CWalletTx& wtx = (*it).second; + nTransactionCount += wtx.nLinesDisplayed; + } } } + if (!vWalletUpdated.empty() || !fPaintedBalance) + nNeedRepaint++; + + // Update status column of visible items only + RefreshStatusColumn(); // Update status bar string strGen = ""; @@ -903,13 +954,10 @@ void CMainFrame::OnPaintListCtrl(wxPaintEvent& event) string strStatus = strprintf(" %d connections %d blocks %d transactions", vNodes.size(), nBestHeight + 1, nTransactionCount); m_statusBar->SetStatusText(strStatus, 2); - // mapWallet was locked, try again later - if (!vWalletUpdated.empty() || !fRefreshed) - _beginthread(DelayedRepaint, 0, NULL); - m_listCtrl->OnPaint(event); } + void CrossThreadCall(wxCommandEvent& event) { if (pframeMain) @@ -994,13 +1042,6 @@ void CMainFrame::OnMenuHelpAbout(wxCommandEvent& event) void CMainFrame::OnButtonSend(wxCommandEvent& event) { - /// debug test - if (fRandSendTest) - { - RandSend(); - return; - } - // Toolbar: Send CSendDialog dialog(this); dialog.ShowModal(); @@ -1684,8 +1725,8 @@ void CSendDialog::OnButtonSend(wxCommandEvent& event) else { // Parse IP address - CAddress addr(strAddress.c_str()); - if (addr.ip == 0) + CAddress addr(strAddress); + if (!addr.IsValid()) { wxMessageBox("Invalid address ", "Send Coins"); return; @@ -1818,14 +1859,6 @@ void CSendingDialog::OnPaint(wxPaintEvent& event) wxMessageBox("Transfer cancelled ", "Sending...", wxOK, this); } event.Skip(); - - /// debug test - if (fRandSendTest && fWorkDone && fSuccess) - { - Close(); - Sleep(1000); - RandSend(); - } } @@ -3305,27 +3338,6 @@ bool CMyApp::OnInit() return false; } -map ParseParameters(int argc, char* argv[]) -{ - map mapArgs; - for (int i = 0; i < argc; i++) - { - char psz[10000]; - strcpy(psz, argv[i]); - char* pszValue = ""; - if (strchr(psz, '=')) - { - pszValue = strchr(psz, '='); - *pszValue++ = '\0'; - } - strlwr(psz); - if (psz[0] == '-') - psz[0] = '/'; - mapArgs[psz] = pszValue; - } - return mapArgs; -} - bool CMyApp::OnInit2() { #ifdef _MSC_VER @@ -3337,10 +3349,27 @@ bool CMyApp::OnInit2() // Disable malfunctioning wxWidgets debug assertion g_isPainting = 10000; #endif - - //// debug print - printf("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"); - printf("Bitcoin version %d, Windows version %08x\n", VERSION, GetVersion()); + wxImage::AddHandler(new wxPNGHandler); + SetAppName("Bitcoin"); + + ParseParameters(argc, argv); + if (mapArgs.count("-?") || mapArgs.count("--help")) + { + string strUsage = + "Usage: bitcoin [options]\t\t\t\t\t\t\n" + "Options:\n" + " -gen\t\t Generate coins\n" + " -gen=0\t\t Don't generate coins\n" + " -min\t\t Start minimized\n" + " -datadir=\t Specify data directory\n" + " -proxy=\t Connect through socks4 proxy,\n" + " \t\t e.g. -proxy=127.0.0.1:9050 to use TOR\n" + " -addnode=\t Add a node to connect to\n" + " -connect=\t Connect only to the specified node\n" + " -?\t\t This help message\n"; + wxMessageBox(strUsage, "Bitcoin", wxOK); + exit(0); + } // // Limit to single instance per user @@ -3382,31 +3411,31 @@ bool CMyApp::OnInit2() // // Parameters // - wxImage::AddHandler(new wxPNGHandler); - mapArgs = ParseParameters(argc, argv); - - if (mapArgs.count("/datadir")) - strSetDataDir = mapArgs["/datadir"]; + if (mapArgs.count("-datadir")) + strlcpy(pszSetDataDir, mapArgs["-datadir"].c_str(), sizeof(pszSetDataDir)); - if (mapArgs.count("/debug")) + if (mapArgs.count("-debug")) fDebug = true; - if (mapArgs.count("/printtodebugger")) + if (mapArgs.count("-printtodebugger")) fPrintToDebugger = true; - if (mapArgs.count("/dropmessages")) + printf("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"); + printf("Bitcoin version %d, Windows version %08x\n", VERSION, GetVersion()); + + if (mapArgs.count("-dropmessages")) { - nDropMessagesTest = atoi(mapArgs["/dropmessages"]); + nDropMessagesTest = atoi(mapArgs["-dropmessages"]); if (nDropMessagesTest == 0) nDropMessagesTest = 20; } - if (mapArgs.count("/loadblockindextest")) + if (mapArgs.count("-loadblockindextest")) { CTxDB txdb("r"); txdb.LoadBlockIndex(); PrintBlockTree(); - ExitProcess(0); + exit(0); } // @@ -3417,22 +3446,22 @@ bool CMyApp::OnInit2() int64 nStart; printf("Loading addresses...\n"); - nStart = PerformanceCounter(); + nStart = GetTimeMillis(); if (!LoadAddresses()) strErrors += "Error loading addr.dat \n"; - printf(" addresses %15"PRI64d"\n", PerformanceCounter() - nStart); + printf(" addresses %15"PRI64d"ms\n", GetTimeMillis() - nStart); printf("Loading block index...\n"); - nStart = PerformanceCounter(); + nStart = GetTimeMillis(); if (!LoadBlockIndex()) strErrors += "Error loading blkindex.dat \n"; - printf(" block index %15"PRI64d"\n", PerformanceCounter() - nStart); + printf(" block index %15"PRI64d"ms\n", GetTimeMillis() - nStart); printf("Loading wallet...\n"); - nStart = PerformanceCounter(); + nStart = GetTimeMillis(); if (!LoadWallet(fFirstRun)) strErrors += "Error loading wallet.dat \n"; - printf(" wallet %15"PRI64d"\n", PerformanceCounter() - nStart); + printf(" wallet %15"PRI64d"ms\n", GetTimeMillis() - nStart); printf("Done loading\n"); @@ -3457,45 +3486,59 @@ bool CMyApp::OnInit2() // // Parameters // - if (mapArgs.count("/printblockindex") || mapArgs.count("/printblocktree")) + if (mapArgs.count("-printblockindex") || mapArgs.count("-printblocktree")) { PrintBlockTree(); OnExit(); return false; } - if (mapArgs.count("/proxy")) + if (mapArgs.count("-gen")) + { + if (mapArgs["-gen"].empty()) + fGenerateBitcoins = true; + else + fGenerateBitcoins = atoi(mapArgs["-gen"].c_str()); + } + + if (mapArgs.count("-proxy")) { fUseProxy = true; - addrProxy = CAddress(mapArgs["/proxy"].c_str()); - if (addrProxy.ip == INADDR_NONE) + addrProxy = CAddress(mapArgs["-proxy"]); + if (!addrProxy.IsValid()) { - wxMessageBox("Invalid /proxy address", "Bitcoin"); + wxMessageBox("Invalid -proxy address", "Bitcoin"); OnExit(); + return false; } CWalletDB walletdb; walletdb.WriteSetting("fUseProxy", fUseProxy); walletdb.WriteSetting("addrProxy", addrProxy); } - if (mapArgs.count("/gen")) + if (mapArgs.count("-addnode")) { - if (mapArgs["/gen"].empty()) - fGenerateBitcoins = true; - else - fGenerateBitcoins = atoi(mapArgs["/gen"].c_str()); + CAddrDB addrdb; + foreach(string strAddr, mapMultiArgs["-addnode"]) + { + CAddress addr(strAddr, NODE_NETWORK); + if (addr.IsValid()) + AddAddress(addrdb, addr); + } } // // Create the main frame window // pframeMain = new CMainFrame(NULL); - if (mapArgs.count("/min")) + if (mapArgs.count("-min")) pframeMain->Iconize(true); pframeMain->Show(true); // have to show first to get taskbar button to hide pframeMain->Show(!fMinimizeToTray || !pframeMain->IsIconized()); ptaskbaricon->Show(fMinimizeToTray); + _beginthread(ThreadDelayedRepaint, 0, NULL); + if (!CheckDiskSpace()) { OnExit(); @@ -3516,7 +3559,7 @@ bool CMyApp::OnInit2() // // Tests // - if (argc >= 2 && stricmp(argv[1], "/send") == 0) + if (argc >= 2 && stricmp(argv[1], "-send") == 0) { int64 nValue = 1; if (argc >= 3) @@ -3525,7 +3568,7 @@ bool CMyApp::OnInit2() string strAddress; if (argc >= 4) strAddress = argv[3]; - CAddress addr(strAddress.c_str()); + CAddress addr(strAddress); CWalletTx wtx; wtx.mapValue["to"] = strAddress; @@ -3538,15 +3581,6 @@ bool CMyApp::OnInit2() return false; } - if (mapArgs.count("/randsendtest")) - { - if (!mapArgs["/randsendtest"].empty()) - _beginthread(ThreadRandSendTest, 0, new string(mapArgs["/randsendtest"])); - else - fRandSendTest = true; - fDebug = true; - } - return true; } @@ -3610,19 +3644,6 @@ void CMyApp::OnFatalException() -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) - { - printf("MainFrameRepaint()\n"); - wxPaintEvent event; - pframeMain->Refresh(); - pframeMain->AddPendingEvent(event); - } -} - typedef WINSHELLAPI BOOL WINAPI (*PSHGETSPECIALFOLDERPATHA)(HWND hwndOwner, LPSTR lpszPath, int nFolder, BOOL fCreate); @@ -3666,7 +3687,7 @@ string StartupShortcutPath() bool GetStartOnSystemStartup() { - return FileExists(StartupShortcutPath().c_str()); + return wxFileExists(StartupShortcutPath()); } void SetStartOnSystemStartup(bool fAutoStart) @@ -3727,79 +3748,3 @@ void SetStartOnSystemStartup(bool fAutoStart) - -// randsendtest to bitcoin address -void ThreadRandSendTest(void* parg) -{ - string strAddress = *(string*)parg; - uint160 hash160; - if (!AddressToHash160(strAddress, hash160)) - { - wxMessageBox(strprintf("ThreadRandSendTest: Bitcoin address '%s' not valid ", strAddress.c_str())); - return; - } - - while (!fShutdown) - { - Sleep(GetRand(30) * 1000 + 100); - - // Message - CWalletTx wtx; - wtx.mapValue["to"] = strAddress; - wtx.mapValue["from"] = addrLocalHost.ToString(); - static int nRep; - wtx.mapValue["message"] = strprintf("randsendtest %d\n", ++nRep); - - // Value - int64 nValue = (GetRand(9) + 1) * 100 * CENT; - if (GetBalance() < nValue) - { - wxMessageBox("Out of money "); - while (GetBalance() < 1000) - Sleep(1000); - } - nValue += (nRep % 100) * CENT; - - // Send to bitcoin address - CScript scriptPubKey; - scriptPubKey << OP_DUP << OP_HASH160 << hash160 << OP_EQUALVERIFY << OP_CHECKSIG; - - if (fShutdown) - return; - if (!SendMoney(scriptPubKey, nValue, wtx)) - return; - } -} - - -// randsendtest to any connected node -void RandSend() -{ - while (vNodes.empty()) - Sleep(1000); - CAddress addr; - CRITICAL_BLOCK(cs_vNodes) - addr = vNodes[GetRand(vNodes.size())]->addr; - - // Message - CWalletTx wtx; - wtx.mapValue["to"] = addr.ToString(); - wtx.mapValue["from"] = addrLocalHost.ToString(); - static int nRep; - wtx.mapValue["message"] = strprintf("randsendtest %d\n", ++nRep); - - // Value - int64 nValue = (GetRand(999) + 1) * CENT; - if (GetBalance() < nValue) - { - wxMessageBox("Out of money "); - return; - } - - // Send to IP address - if (fShutdown) - return; - CSendingDialog* pdialog = new CSendingDialog(pframeMain, addr, nValue, wtx); - if (!pdialog->Show()) - wxMessageBox("ShowModal Failed "); -} diff --git a/ui.h b/ui.h index 9fc7e0ebe7..47839e81e2 100644 --- a/ui.h +++ b/ui.h @@ -83,15 +83,14 @@ public: bool fRefreshListCtrl; bool fRefreshListCtrlRunning; bool fOnSetFocusAddress; - CBlockIndex* pindexBestLast; - set setUnmaturedDisplayed; + unsigned int nListViewUpdated; void OnCrossThreadCall(wxCommandEvent& event); void InsertLine(bool fNew, int nIndex, uint256 hashKey, string strSort, 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 RefreshStatus(); + void RefreshStatusColumn(); }; diff --git a/util.cpp b/util.cpp index ef950920fd..23b59f11f7 100644 --- a/util.cpp +++ b/util.cpp @@ -5,9 +5,13 @@ #include "headers.h" +map mapArgs; +map > mapMultiArgs; bool fDebug = false; bool fPrintToDebugger = false; bool fPrintToConsole = false; +char pszSetDataDir[MAX_PATH] = ""; + @@ -68,6 +72,8 @@ void RandAddSeed() void RandAddSeedPerfmon() { +#ifdef __WXMSW__ + // Don't need this on Linux, OpenSSL automatically uses /dev/urandom // This can take up to 2 seconds, so only do it every 10 minutes static int64 nLastPerfmon; if (GetTime() < nLastPerfmon + 10 * 60) @@ -95,6 +101,7 @@ void RandAddSeedPerfmon() strftime(pszTime, sizeof(pszTime), "%x %H:%M:%S", ptmTime); printf("%s RandAddSeed() %d bytes\n", pszTime, nSize); } +#endif } @@ -304,6 +311,32 @@ vector ParseHex(const std::string& str) } +void ParseParameters(int argc, char* argv[]) +{ + mapArgs.clear(); + mapMultiArgs.clear(); + for (int i = 0; i < argc; i++) + { + char psz[10000]; + strlcpy(psz, argv[i], sizeof(psz)); + char* pszValue = ""; + if (strchr(psz, '=')) + { + pszValue = strchr(psz, '='); + *pszValue++ = '\0'; + } + strlwr(psz); + #ifdef __WXMSW__ + if (psz[0] == '/') + psz[0] = '-'; + #endif + mapArgs[psz] = pszValue; + mapMultiArgs[psz].push_back(pszValue); + } +} + + + @@ -346,15 +379,6 @@ void PrintException(std::exception* pex, const char* pszThread) -bool FileExists(const char* psz) -{ -#ifdef WIN32 - return GetFileAttributes(psz) != -1; -#else - return access(psz, 0) != -1; -#endif -} - int GetFilesize(FILE* file) { int nSavePos = ftell(file); @@ -365,6 +389,46 @@ int GetFilesize(FILE* file) return nFilesize; } +void GetDataDir(char* pszDir) +{ + // pszDir must be at least MAX_PATH length. + if (pszSetDataDir[0] != 0) + { + strlcpy(pszDir, pszSetDataDir, MAX_PATH); + static bool fMkdirDone; + if (!fMkdirDone) + { + fMkdirDone = true; + _mkdir(pszDir); + } + } + else + { + // This can be called during exceptions by printf, so we cache the + // value so we don't have to do memory allocations after that. + // wxStandardPaths::GetUserDataDir + // Return the directory for the user-dependent application data files: + // Unix: ~/.appname + // Windows: C:\Documents and Settings\username\Application Data\appname + // Mac: ~/Library/Application Support/appname + static char pszCachedDir[MAX_PATH]; + if (pszCachedDir[0] == 0) + { + strlcpy(pszCachedDir, wxStandardPaths::Get().GetUserDataDir().c_str(), sizeof(pszCachedDir)); + _mkdir(pszCachedDir); + } + strlcpy(pszDir, pszCachedDir, MAX_PATH); + } + +} + +string GetDataDir() +{ + char pszDir[MAX_PATH]; + GetDataDir(pszDir); + return pszDir; +} + diff --git a/util.h b/util.h index 5d18776002..822a049ce7 100644 --- a/util.h +++ b/util.h @@ -54,16 +54,23 @@ inline T& REF(const T& val) return (T&)val; } +#ifndef __WXMSW__ +#define closesocket(s) close(s) +#define INVALID_SOCKET (SOCKET)(~0) +typedef u_int SOCKET; +#endif +extern map mapArgs; +extern map > mapMultiArgs; extern bool fDebug; extern bool fPrintToDebugger; extern bool fPrintToConsole; -extern map mapArgs; +extern char pszSetDataDir[MAX_PATH]; void RandAddSeed(); void RandAddSeedPerfmon(); @@ -77,8 +84,10 @@ string FormatMoney(int64 n, bool fPlus=false); bool ParseMoney(const char* pszIn, int64& nRet); vector ParseHex(const char* psz); vector ParseHex(const std::string& str); -bool FileExists(const char* psz); +void ParseParameters(int argc, char* argv[]); int GetFilesize(FILE* file); +void GetDataDir(char* pszDirRet); +string GetDataDir(); uint64 GetRand(uint64 nMax); int64 GetTime(); int64 GetAdjustedTime(); @@ -172,9 +181,14 @@ inline int OutputDebugStringF(const char* pszFormat, ...) if (!fPrintToConsole) { // print to debug.log - FILE* fileout = fopen("debug.log", "a"); + char pszFile[MAX_PATH+100]; + GetDataDir(pszFile); + strlcat(pszFile, "\\debug.log", sizeof(pszFile)); + FILE* fileout = fopen(pszFile, "a"); if (fileout) { + //// Debug print useful for profiling + //fprintf(fileout, " %"PRI64d" ", wxGetLocalTimeMillis().GetValue()); va_list arg_ptr; va_start(arg_ptr, pszFormat); ret = vfprintf(fileout, pszFormat, arg_ptr); @@ -321,22 +335,25 @@ inline void PrintHex(vector vch, const char* pszFormat="%s", bool { printf(pszFormat, HexStr(vch, fSpaces).c_str()); } - inline int64 PerformanceCounter() { - int64 nCounter = 0; + int64 nCounter = 0; #ifdef __WXMSW__ - QueryPerformanceCounter((LARGE_INTEGER*)&nCounter); + QueryPerformanceCounter((LARGE_INTEGER*)&nCounter); #else - // this could be changed to reading /dev/urandom - timeval t; - gettimeofday(&t, NULL); - nCounter += t.tv_sec * 1000000 + t.tv_usec; + timeval t; + gettimeofday(&t, NULL); + nCounter = t.tv_sec * 1000000 + t.tv_usec; #endif return nCounter; } +inline int64 GetTimeMillis() +{ + return wxGetLocalTimeMillis().GetValue(); +} + #ifndef __WXMSW__ inline void Sleep(unsigned int nMilliseconds) { @@ -354,8 +371,10 @@ inline void Sleep(unsigned int nMilliseconds) inline void heapchk() { +#ifdef __WXMSW__ if (_heapchk() != _HEAPOK) DebugBreak(); +#endif } // Randomize the stack to help protect against buffer overrun exploits -- cgit v1.2.3 From f7d3cc0e584e7184b9f5cd9736d34f41c5e70182 Mon Sep 17 00:00:00 2001 From: s_nakamoto Date: Wed, 4 Nov 2009 04:58:46 +0000 Subject: renamed build.txt to build-msw.txt --- build-msw.txt | 91 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 91 insertions(+) create mode 100644 build-msw.txt diff --git a/build-msw.txt b/build-msw.txt new file mode 100644 index 0000000000..eb6348bada --- /dev/null +++ b/build-msw.txt @@ -0,0 +1,91 @@ +Bitcoin v0.2.0 BETA + +Copyright (c) 2009 Satoshi Nakamoto +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/). This product includes +cryptographic software written by Eric Young (eay@cryptsoft.com). + + + WINDOWS BUILD NOTES + + +Compilers Supported +------------------- +MinGW GCC +Microsoft Visual C++ 6.0 SP6 + + +Dependencies +------------ +Libraries you need to obtain separately to build: + + default path download +wxWidgets \wxwidgets http://www.wxwidgets.org/downloads/ + or prebuilt: http://wxpack.sourceforge.net +OpenSSL \openssl http://www.openssl.org/source/ +Berkeley DB \db http://www.oracle.com/technology/software/products/berkeley-db/index.html +Boost \boost http://www.boost.org/users/download/ + +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 + +Versions used in this release: +MinGW GCC 3.4.5 +wxWidgets 2.8.9 +OpenSSL 0.9.8k +Berkeley DB 4.7.25.NC +Boost 1.34.1 + + +Notes +----- +The UI layout is edited with wxFormBuilder. Open the project file +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.exe" to strip the debug +symbols, which reduces the executable size by about 90%. + + +OpenSSL +------- +Bitcoin does not use any encryption. If you want to do a no-everything +build of OpenSSL to exclude encryption routines, a few patches are required. +(instructions for OpenSSL v0.9.8k) + +Edit engines\e_gmp.c and engines\e_capi.c and add this #ifndef around +the openssl/rsa.h include: + #ifndef OPENSSL_NO_RSA + #include + #endif + +Edit ms\mingw32.bat and replace the Configure line's parameters with this +no-everything list. You have to put this in the batch file because batch +files can't take more than nine command line parameters. + perl Configure mingw threads no-rc2 no-rc4 no-rc5 no-idea no-des no-bf no-cast no-aes no-camellia no-seed no-rsa no-dh + +Also REM out the following line in ms\mingw32.bat after the mingw32-make +line. The build fails after it's already finished building libeay32, which +is all we care about, but the failure aborts the script before it runs +dllwrap to generate libeay32.dll. + REM if errorlevel 1 goto end + +Build + cd \openssl + ms\mingw32.bat + +If you want to use it with MSVC, generate the .lib file + lib /machine:i386 /def:ms\libeay32.def /out:out\libeay32.lib + + +Berkeley DB +----------- +Using MinGW and MSYS: +cd \db\build_unix +sh ../dist/configure --enable-mingw --enable-cxx +make -- cgit v1.2.3 From b7362c07ae42ac4282361ee95b82424d502f1b82 Mon Sep 17 00:00:00 2001 From: s_nakamoto Date: Wed, 4 Nov 2009 04:58:46 +0000 Subject: renamed build.txt to build-msw.txt git-svn-id: https://bitcoin.svn.sourceforge.net/svnroot/bitcoin/trunk@28 1a98c847-1fd6-4fd8-948a-caf3550aa51b --- build-msw.txt | 91 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 91 insertions(+) create mode 100644 build-msw.txt diff --git a/build-msw.txt b/build-msw.txt new file mode 100644 index 0000000000..eb6348bada --- /dev/null +++ b/build-msw.txt @@ -0,0 +1,91 @@ +Bitcoin v0.2.0 BETA + +Copyright (c) 2009 Satoshi Nakamoto +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/). This product includes +cryptographic software written by Eric Young (eay@cryptsoft.com). + + + WINDOWS BUILD NOTES + + +Compilers Supported +------------------- +MinGW GCC +Microsoft Visual C++ 6.0 SP6 + + +Dependencies +------------ +Libraries you need to obtain separately to build: + + default path download +wxWidgets \wxwidgets http://www.wxwidgets.org/downloads/ + or prebuilt: http://wxpack.sourceforge.net +OpenSSL \openssl http://www.openssl.org/source/ +Berkeley DB \db http://www.oracle.com/technology/software/products/berkeley-db/index.html +Boost \boost http://www.boost.org/users/download/ + +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 + +Versions used in this release: +MinGW GCC 3.4.5 +wxWidgets 2.8.9 +OpenSSL 0.9.8k +Berkeley DB 4.7.25.NC +Boost 1.34.1 + + +Notes +----- +The UI layout is edited with wxFormBuilder. Open the project file +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.exe" to strip the debug +symbols, which reduces the executable size by about 90%. + + +OpenSSL +------- +Bitcoin does not use any encryption. If you want to do a no-everything +build of OpenSSL to exclude encryption routines, a few patches are required. +(instructions for OpenSSL v0.9.8k) + +Edit engines\e_gmp.c and engines\e_capi.c and add this #ifndef around +the openssl/rsa.h include: + #ifndef OPENSSL_NO_RSA + #include + #endif + +Edit ms\mingw32.bat and replace the Configure line's parameters with this +no-everything list. You have to put this in the batch file because batch +files can't take more than nine command line parameters. + perl Configure mingw threads no-rc2 no-rc4 no-rc5 no-idea no-des no-bf no-cast no-aes no-camellia no-seed no-rsa no-dh + +Also REM out the following line in ms\mingw32.bat after the mingw32-make +line. The build fails after it's already finished building libeay32, which +is all we care about, but the failure aborts the script before it runs +dllwrap to generate libeay32.dll. + REM if errorlevel 1 goto end + +Build + cd \openssl + ms\mingw32.bat + +If you want to use it with MSVC, generate the .lib file + lib /machine:i386 /def:ms\libeay32.def /out:out\libeay32.lib + + +Berkeley DB +----------- +Using MinGW and MSYS: +cd \db\build_unix +sh ../dist/configure --enable-mingw --enable-cxx +make -- cgit v1.2.3 From fba40889418cb1861440a3fdccee048c69f0fb89 Mon Sep 17 00:00:00 2001 From: s_nakamoto Date: Thu, 5 Nov 2009 04:41:36 +0000 Subject: unix build merged in, bitmap resources from xpm instead of rc, better addr relay, better selection of addrs by time last seen for faster connect --- build-unix.txt | 73 ++++++++++++ build.txt | 88 -------------- db.cpp | 10 +- headers.h | 38 +++++-- irc.cpp | 16 +-- irc.h | 4 +- main.cpp | 68 +++++++---- main.h | 8 ++ makefile.unix | 86 ++++++++++++++ net.cpp | 177 ++++++++++++++-------------- net.h | 3 +- ui.cpp | 103 +++++++++-------- uibase.cpp | 10 +- uiproject.fbp | 10 +- util.cpp | 8 +- util.h | 40 +++++-- xpm/addressbook16.xpm | 278 ++++++++++++++++++++++++++++++++++++++++++++ xpm/addressbook20.xpm | 282 +++++++++++++++++++++++++++++++++++++++++++++ xpm/bitcoin.xpm | 304 +++++++++++++++++++++++++++++++++++++++++++++++++ xpm/check.xpm | 41 +++++++ xpm/send16.xpm | 278 ++++++++++++++++++++++++++++++++++++++++++++ xpm/send16noshadow.xpm | 278 ++++++++++++++++++++++++++++++++++++++++++++ xpm/send20.xpm | 282 +++++++++++++++++++++++++++++++++++++++++++++ 23 files changed, 2184 insertions(+), 301 deletions(-) create mode 100644 build-unix.txt delete mode 100644 build.txt create mode 100644 makefile.unix create mode 100644 xpm/addressbook16.xpm create mode 100644 xpm/addressbook20.xpm create mode 100644 xpm/bitcoin.xpm create mode 100644 xpm/check.xpm create mode 100644 xpm/send16.xpm create mode 100644 xpm/send16noshadow.xpm create mode 100644 xpm/send20.xpm diff --git a/build-unix.txt b/build-unix.txt new file mode 100644 index 0000000000..6b29e1e5c4 --- /dev/null +++ b/build-unix.txt @@ -0,0 +1,73 @@ +Bitcoin v0.2.0 BETA + +Copyright (c) 2009 Satoshi Nakamoto +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/). This product includes +cryptographic software written by Eric Young (eay@cryptsoft.com). + + +UNIX BUILD NOTES + + +Dependencies +------------ +apt-get install build-essential +apt-get install libgtk2.0-dev +apt-get install libssl-dev + +Libraries you need to obtain separately and build: + default path download +wxWidgets \wxwidgets http://www.wxwidgets.org/downloads/ +Berkeley DB \db http://www.oracle.com/technology/software/products/berkeley-db/index.html +Boost \boost http://www.boost.org/users/download/ + +Their licenses: +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 + +Versions used in this release: +GCC 4.3.3 +OpenSSL 0.9.8k +wxWidgets 2.8.9 +Berkeley DB 4.7.25.NC +Boost 1.40.0 + + +Notes +----- +The UI layout is edited with wxFormBuilder. Open the project file +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/wxWidgets-2.8.9 +mkdir buildgtk +cd buildgtk +../configure --with-gtk --enable-debug --disable-shared --enable-monolithic +make +su +make install +ldconfig + + +Berkeley DB +----------- +cd /usr/local/db-4.7.25.NC/build_unix +../dist/configure --enable-cxx +make + + +Boost +----- +cd /usr/local/boost_1_40_0 +su +./bootstrap.sh +./bjam install diff --git a/build.txt b/build.txt deleted file mode 100644 index 4368af855a..0000000000 --- a/build.txt +++ /dev/null @@ -1,88 +0,0 @@ -BitCoin v0.1.6 BETA - -Copyright (c) 2009 Satoshi Nakamoto -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/). This product includes -cryptographic software written by Eric Young (eay@cryptsoft.com). - - -Compilers Supported -------------------- -MinGW GCC (v3.4.5) -Microsoft Visual C++ 6.0 SP6 - - -Dependencies ------------- -Libraries you need to obtain separately to build: - - default path download -wxWidgets \wxwidgets http://www.wxwidgets.org/downloads/ - or prebuilt: http://wxpack.sourceforge.net -OpenSSL \openssl http://www.openssl.org/source/ -Berkeley DB \db http://www.oracle.com/technology/software/products/berkeley-db/index.html -Boost \boost http://www.boost.org/users/download/ - -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 - - -Notes ------ -The UI layout is edited with wxFormBuilder. Open the project file -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.exe" to strip the debug -symbols, which reduces the executable size by about 90%. - - -OpenSSL -------- -Bitcoin does not use any encryption. If you want to do a no-everything -build of OpenSSL to exclude encryption routines, a few patches are required. -(OpenSSL v0.9.8h) - -Edit engines\e_gmp.c and put this #ifndef around #include - #ifndef OPENSSL_NO_RSA - #include - #endif - -Add this to crypto\err\err_all.c before the ERR_load_crypto_strings line: - void ERR_load_RSA_strings(void) { } - -Edit ms\mingw32.bat and replace the Configure line's parameters with this -no-everything list. You have to put this in the batch file because batch -files can't take more than 9 command line parameters. - perl Configure mingw threads no-rc2 no-rc4 no-rc5 no-idea no-des no-bf no-cast no-aes no-camellia no-seed no-rsa no-dh - -Also REM out the following line in ms\mingw32.bat. The build fails after it's -already finished building libeay32, which is all we care about, but the -failure aborts the script before it runs dllwrap to generate libeay32.dll. - REM if errorlevel 1 goto end - -Build - ms\mingw32.bat - -If you want to use it with MSVC, generate the .lib file - lib /machine:i386 /def:ms\libeay32.def /out:out\libeay32.lib - - -Berkeley DB ------------ -Using MinGW and MSYS: -cd \db\build_unix -sh ../dist/configure --enable-mingw --enable-cxx -make - - -Boost ------ -If you have trouble compiling Boost with Microsoft Visual C++ 6.0, try going -back to Boost version 1.35. It looks like they may be starting to reduce -support for MSVC 6.0. diff --git a/db.cpp b/db.cpp index f9e25834d0..b702b0cbac 100644 --- a/db.cpp +++ b/db.cpp @@ -62,9 +62,9 @@ CDB::CDB(const char* pszFile, const char* pszMode, bool fTxn) : pdb(NULL) if (fShutdown) return; string strDataDir = GetDataDir(); - string strLogDir = strDataDir + "\\database"; + string strLogDir = strDataDir + "/database"; _mkdir(strLogDir.c_str()); - string strErrorFile = strDataDir + "\\db.log"; + string strErrorFile = strDataDir + "/db.log"; printf("dbenv.open strLogDir=%s strErrorFile=%s\n", strLogDir.c_str(), strErrorFile.c_str()); dbenv.set_lg_dir(strLogDir.c_str()); @@ -411,7 +411,6 @@ bool CAddrDB::WriteAddress(const CAddress& addr) bool CAddrDB::LoadAddresses() { - CRITICAL_BLOCK(cs_mapIRCAddresses) CRITICAL_BLOCK(cs_mapAddresses) { // Load user provided addresses @@ -425,10 +424,7 @@ bool CAddrDB::LoadAddresses() { CAddress addr(psz, NODE_NETWORK); if (addr.IsValid()) - { AddAddress(*this, addr); - mapIRCAddresses.insert(make_pair(addr.GetKey(), addr)); - } } } catch (...) { } @@ -678,7 +674,7 @@ void ThreadFlushWalletDB(void* parg) if (nRefCount == 0 && !fShutdown) { // Flush wallet.dat so it's self contained - nLastFlushed == nWalletDBUpdated; + nLastFlushed = nWalletDBUpdated; int64 nStart = GetTimeMillis(); dbenv.txn_checkpoint(0, 0, 0); dbenv.lsn_reset(strFile.c_str(), 0); diff --git a/headers.h b/headers.h index f00b7dde05..c7f3cd8514 100644 --- a/headers.h +++ b/headers.h @@ -17,16 +17,18 @@ #endif #define _WIN32_IE 0x0400 #define WIN32_LEAN_AND_MEAN 1 +#define __STDC_LIMIT_MACROS // to enable UINT64_MAX from stdint.h #include #include #include #include #include +#include #include #include #include #include -#include +#include #include #include #include @@ -50,22 +52,28 @@ #include #include #include -#include - +#include + #ifdef __WXMSW__ #include #include -#include +#include #include -#include -#include -#include -#else +#include +#include +#include +#else #include +#include #include -#include -#include -#endif +#include +#include +#include +#include +#include +#include +#include +#endif #pragma hdrstop using namespace std; @@ -88,3 +96,11 @@ using namespace boost; #include "market.h" #include "uibase.h" #include "ui.h" + +#include "xpm/addressbook16.xpm" +#include "xpm/addressbook20.xpm" +#include "xpm/bitcoin.xpm" +#include "xpm/check.xpm" +#include "xpm/send16.xpm" +#include "xpm/send16noshadow.xpm" +#include "xpm/send20.xpm" diff --git a/irc.cpp b/irc.cpp index f839dc5224..4d4ed0f414 100644 --- a/irc.cpp +++ b/irc.cpp @@ -4,10 +4,7 @@ #include "headers.h" - -map, CAddress> mapIRCAddresses; -CCriticalSection cs_mapIRCAddresses; - +int nGotIRCAddresses = 0; @@ -259,16 +256,7 @@ void ThreadIRCSeed(void* parg) CAddrDB addrdb; if (AddAddress(addrdb, addr)) printf("IRC got new address\n"); - else - { - // make it try connecting again - CRITICAL_BLOCK(cs_mapAddresses) - if (mapAddresses.count(addr.GetKey())) - mapAddresses[addr.GetKey()].nLastFailed = 0; - } - - CRITICAL_BLOCK(cs_mapIRCAddresses) - mapIRCAddresses.insert(make_pair(addr.GetKey(), addr)); + nGotIRCAddresses++; } else { diff --git a/irc.h b/irc.h index 91c3ffe686..c69fd9ee97 100644 --- a/irc.h +++ b/irc.h @@ -4,7 +4,5 @@ extern bool RecvLine(SOCKET hSocket, string& strLine); extern void ThreadIRCSeed(void* parg); -extern bool fRestartIRCSeed; -extern map, CAddress> mapIRCAddresses; -extern CCriticalSection cs_mapIRCAddresses; +extern int nGotIRCAddresses; diff --git a/main.cpp b/main.cpp index ade3b51c77..2119495e64 100644 --- a/main.cpp +++ b/main.cpp @@ -100,13 +100,10 @@ bool AddToWallet(const CWalletTx& wtxIn) if (fInsertedNew) wtx.nTimeReceived = GetAdjustedTime(); - //// debug print - printf("AddToWallet %s %s\n", wtxIn.GetHash().ToString().substr(0,6).c_str(), fInsertedNew ? "new" : "update"); - + bool fUpdated = false; if (!fInsertedNew) { // Merge - bool fUpdated = false; if (wtxIn.hashBlock != 0 && wtxIn.hashBlock != wtx.hashBlock) { wtx.hashBlock = wtxIn.hashBlock; @@ -128,13 +125,15 @@ bool AddToWallet(const CWalletTx& wtxIn) wtx.fSpent = wtxIn.fSpent; fUpdated = true; } - if (!fUpdated) - return true; } + //// debug print + printf("AddToWallet %s %s%s\n", wtxIn.GetHash().ToString().substr(0,6).c_str(), (fInsertedNew ? "new" : ""), (fUpdated ? "update" : "")); + // Write to disk - if (!wtx.WriteToDisk()) - return false; + if (fInsertedNew || fUpdated) + if (!wtx.WriteToDisk()) + return false; // Notify UI vWalletUpdated.push_back(hash); @@ -820,7 +819,7 @@ bool CTransaction::ConnectInputs(CTxDB& txdb, map& mapTestPoo } if (prevout.n >= txPrev.vout.size() || prevout.n >= txindex.vSpent.size()) - return error("ConnectInputs() : %s prevout.n out of range %d %d %d", GetHash().ToString().substr(0,6).c_str(), prevout.n, txPrev.vout.size(), txindex.vSpent.size()); + return error("ConnectInputs() : %s prevout.n out of range %d %d %d prev tx %s\n%s", GetHash().ToString().substr(0,6).c_str(), prevout.n, txPrev.vout.size(), txindex.vSpent.size(), prevout.hash.ToString().substr(0,6).c_str(), txPrev.ToString().c_str()); // If prev is coinbase, check that it's matured if (txPrev.IsCoinBase()) @@ -1217,7 +1216,7 @@ bool CBlock::AcceptBlock() if (nTime <= pindexPrev->GetMedianTimePast()) return error("AcceptBlock() : block's timestamp is too early"); - // Check that all transactions are finalized (starting around 30 Nov 2009) + // Check that all transactions are finalized (starting around Dec 2009) if (nBestHeight > 31000) // 25620 + 5320 foreach(const CTransaction& tx, vtx) if (!tx.IsFinal(nTime)) @@ -1384,7 +1383,7 @@ FILE* OpenBlockFile(unsigned int nFile, unsigned int nBlockPos, const char* pszM { if (nFile == -1) return NULL; - FILE* file = fopen(strprintf("%s\\blk%04d.dat", GetDataDir().c_str(), nFile).c_str(), pszMode); + FILE* file = fopen(strprintf("%s/blk%04d.dat", GetDataDir().c_str(), nFile).c_str(), pszMode); if (!file) return NULL; if (nBlockPos != 0 && !strchr(pszMode, 'a') && !strchr(pszMode, 'w')) @@ -1718,6 +1717,7 @@ bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) + if (strCommand == "version") { // Each connection can only send one version message @@ -1765,6 +1765,10 @@ bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) pfrom->fSuccessfullyConnected = true; + // Update the last seen time + if (pfrom->fNetworkNode) + AddressCurrentlyConnected(pfrom->addr); + printf("version message: version %d\n", pfrom->nVersion); } @@ -1781,23 +1785,16 @@ bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) vector vAddr; vRecv >> vAddr; - // Clear addrknown lists periodically to allow refresh broadcasts - static int64 nLastClearedAddrKnown; - if (nLastClearedAddrKnown < GetAdjustedTime() - 24 * 60 * 60) - { - nLastClearedAddrKnown = GetAdjustedTime(); - CRITICAL_BLOCK(cs_vNodes) - foreach(CNode* pnode, vNodes) - pnode->setAddrKnown.clear(); - } - // Store the new addresses CAddrDB addrdb; - foreach(const CAddress& addr, vAddr) + foreach(CAddress& addr, vAddr) { if (fShutdown) return true; - AddAddress(addrdb, addr); + addr.nTime = GetAdjustedTime(); + if (pfrom->fGetAddr) + addr.nTime -= 5 * 24 * 60 * 60; + AddAddress(addrdb, addr, false); pfrom->AddAddressKnown(addr); if (!pfrom->fGetAddr && addr.IsRoutable()) { @@ -1816,6 +1813,10 @@ bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) vector vInv; vRecv >> vInv; + // Update the last seen time for this node's address + if (pfrom->fNetworkNode) + AddressCurrentlyConnected(pfrom->addr); + CTxDB txdb("r"); foreach(const CInv& inv, vInv) { @@ -2099,6 +2100,25 @@ bool SendMessages(CNode* pto) if (pto->nVersion == 0) return true; + // Address refresh broadcast + static int64 nLastRebroadcast; + if (nLastRebroadcast < GetTime() - 24 * 60 * 60) // every 24 hours + { + nLastRebroadcast = GetTime(); + CRITICAL_BLOCK(cs_vNodes) + { + foreach(CNode* pnode, vNodes) + { + // Periodically clear setAddrKnown to allow refresh broadcasts + pnode->setAddrKnown.clear(); + + // Rebroadcast our address + if (addrLocalHost.IsRoutable() && !fUseProxy) + pnode->PushAddress(addrLocalHost); + } + } + } + // // Message: addr @@ -2187,7 +2207,7 @@ void GenerateBitcoins(bool fGenerate) } if (fGenerateBitcoins) { - int nProcessors = atoi(getenv("NUMBER_OF_PROCESSORS")); + int nProcessors = wxThread::GetCPUCount(); printf("%d processors\n", nProcessors); if (nProcessors < 1) nProcessors = 1; diff --git a/main.h b/main.h index a0258cf2ce..6d8f0ed87c 100644 --- a/main.h +++ b/main.h @@ -968,6 +968,14 @@ public: return error("CBlock::WriteToDisk() : ftell failed"); fileout << *this; + // Flush stdio buffers and commit to disk before returning + fflush(fileout); +#ifdef __WXMSW__ + _commit(_fileno(fileout)); +#else + fsync(fileno(fileout)); +#endif + return true; } diff --git a/makefile.unix b/makefile.unix new file mode 100644 index 0000000000..c62efc008f --- /dev/null +++ b/makefile.unix @@ -0,0 +1,86 @@ +# Copyright (c) 2009 Satoshi Nakamoto +# Distributed under the MIT/X11 software license, see the accompanying +# file license.txt or http://www.opensource.org/licenses/mit-license.php. + + +ifneq "$(BUILD)" "debug" +ifneq "$(BUILD)" "release" +BUILD=debug +endif +endif +ifeq "$(BUILD)" "debug" +D=d +DEBUGFLAGS=-g -D__WXDEBUG__ +endif + + + +INCLUDEPATHS=-I"/usr/include" \ + -I"/usr/local/boost_1_40_0" \ + -I"/usr/local/db-4.7.25.NC/build_unix" \ + -I"/usr/local/include/wx-2.8" \ + -I"/usr/local/lib/wx/include/gtk2-ansi-debug-static-2.8" + +LIBPATHS=-L"/usr/lib" \ + -L"/usr/local/lib" \ + -L"/usr/local/db-4.7.25.NC/build_unix" + +LIBS= \ + -Wl,-Bstatic -l boost_thread -l boost_system -l boost_filesystem -Wl,-Bdynamic \ + -Wl,-Bstatic -l db_cxx -l wx_gtk2$(D)-2.8 -Wl,-Bdynamic \ + -l crypto \ + -l gtk-x11-2.0 -l gthread-2.0 -l SM +WXDEFS=-D__WXGTK__ -DNOPCH +CFLAGS=-O0 -w -Wno-invalid-offsetof -Wformat $(DEBUGFLAGS) $(WXDEFS) $(INCLUDEPATHS) +HEADERS=headers.h util.h main.h serialize.h uint256.h key.h bignum.h script.h db.h base58.h + + + +all: bitcoin + + +headers.h.gch: headers.h $(HEADERS) net.h irc.h market.h uibase.h ui.h + g++ -c $(CFLAGS) -o $@ $< + +obj/util.o: util.cpp $(HEADERS) + g++ -c $(CFLAGS) -o $@ $< + +obj/script.o: script.cpp $(HEADERS) + g++ -c $(CFLAGS) -o $@ $< + +obj/db.o: db.cpp $(HEADERS) market.h + g++ -c $(CFLAGS) -o $@ $< + +obj/net.o: net.cpp $(HEADERS) net.h + g++ -c $(CFLAGS) -o $@ $< + +obj/main.o: main.cpp $(HEADERS) net.h market.h sha.h + g++ -c $(CFLAGS) -o $@ $< + +obj/market.o: market.cpp $(HEADERS) market.h + g++ -c $(CFLAGS) -o $@ $< + +obj/ui.o: ui.cpp $(HEADERS) net.h uibase.h ui.h market.h + g++ -c $(CFLAGS) -o $@ $< + +obj/uibase.o: uibase.cpp uibase.h + g++ -c $(CFLAGS) -o $@ $< + +obj/sha.o: sha.cpp sha.h + g++ -c $(CFLAGS) -O3 -o $@ $< + +obj/irc.o: irc.cpp $(HEADERS) + g++ -c $(CFLAGS) -o $@ $< + + + + +OBJS=obj/util.o obj/script.o obj/db.o obj/net.o obj/main.o obj/market.o \ + obj/ui.o obj/uibase.o obj/sha.o obj/irc.o + +bitcoin: headers.h.gch $(OBJS) + g++ $(CFLAGS) -o $@ $(LIBPATHS) $(OBJS) $(LIBS) + +clean: + -rm obj/* + -rm headers.h.gch diff --git a/net.cpp b/net.cpp index 8ccf48b819..c14061e7d3 100644 --- a/net.cpp +++ b/net.cpp @@ -3,7 +3,6 @@ // file license.txt or http://www.opensource.org/licenses/mit-license.php. #include "headers.h" -#include void ThreadMessageHandler2(void* parg); void ThreadSocketHandler2(void* parg); @@ -201,12 +200,14 @@ bool GetMyExternalIP(unsigned int& ipRet) -bool AddAddress(CAddrDB& addrdb, const CAddress& addr) +bool AddAddress(CAddrDB& addrdb, CAddress addr, bool fCurrentlyOnline) { if (!addr.IsRoutable()) return false; if (addr.ip == addrLocalHost.ip) return false; + if (fCurrentlyOnline) + addr.nTime = GetAdjustedTime(); CRITICAL_BLOCK(cs_mapAddresses) { map, CAddress>::iterator it = mapAddresses.find(addr.GetKey()); @@ -219,24 +220,47 @@ bool AddAddress(CAddrDB& addrdb, const CAddress& addr) } else { + bool fUpdated = false; CAddress& addrFound = (*it).second; if ((addrFound.nServices | addr.nServices) != addrFound.nServices) { // Services have been added addrFound.nServices |= addr.nServices; - addrdb.WriteAddress(addrFound); - return true; + fUpdated = true; + } + int64 nUpdateInterval = (fCurrentlyOnline ? 60 * 60 : 24 * 60 * 60); + if (addrFound.nTime < addr.nTime - nUpdateInterval) + { + // Periodically update most recently seen time + addrFound.nTime = addr.nTime; + fUpdated = true; } - else if (addrFound.nTime < GetAdjustedTime() - 24 * 60 * 60) + if (fUpdated) + addrdb.WriteAddress(addrFound); + } + } + return false; +} + +void AddressCurrentlyConnected(const CAddress& addr) +{ + CRITICAL_BLOCK(cs_mapAddresses) + { + // Only if it's been published already + map, CAddress>::iterator it = mapAddresses.find(addr.GetKey()); + if (it != mapAddresses.end()) + { + CAddress& addrFound = (*it).second; + int64 nUpdateInterval = 60 * 60; + if (addrFound.nTime < GetAdjustedTime() - nUpdateInterval) { // Periodically update most recently seen time addrFound.nTime = GetAdjustedTime(); + CAddrDB addrdb; addrdb.WriteAddress(addrFound); - return false; } } } - return false; } @@ -398,9 +422,14 @@ CNode* ConnectNode(CAddress addrConnect, int64 nTimeout) printf("connected %s\n", addrConnect.ToStringLog().c_str()); // Set to nonblocking - u_long nOne = 1; +#ifdef __WXMSW__ + u_long nOne = 1; if (ioctlsocket(hSocket, FIONBIO, &nOne) == SOCKET_ERROR) printf("ConnectSocket() : ioctlsocket nonblocking setting failed, error %d\n", WSAGetLastError()); +#else + if (fcntl(hSocket, F_SETFL, O_NONBLOCK) == SOCKET_ERROR) + printf("ConnectSocket() : fcntl nonblocking setting failed, error %d\n", errno); +#endif // Add node CNode* pnode = new CNode(hSocket, addrConnect, false); @@ -418,7 +447,7 @@ CNode* ConnectNode(CAddress addrConnect, int64 nTimeout) else { CRITICAL_BLOCK(cs_mapAddresses) - mapAddresses[addrConnect.GetKey()].nLastFailed = GetTime(); + mapAddresses[addrConnect.GetKey()].nLastFailed = GetAdjustedTime(); return NULL; } } @@ -432,7 +461,7 @@ void CNode::DoDisconnect() // If outbound and never got version message, mark address as failed if (!fInbound && !fSuccessfullyConnected) CRITICAL_BLOCK(cs_mapAddresses) - mapAddresses[addr.GetKey()].nLastFailed = GetTime(); + mapAddresses[addr.GetKey()].nLastFailed = GetAdjustedTime(); // All of a nodes broadcasts and subscriptions are automatically torn down // when it goes down, so a node has to stay up to keep its broadcast going. @@ -549,8 +578,8 @@ void ThreadSocketHandler2(void* parg) timeout.tv_sec = 0; timeout.tv_usec = 50000; // frequency to poll pnode->vSend - struct fd_set fdsetRecv; - struct fd_set fdsetSend; + fd_set fdsetRecv; + fd_set fdsetSend; FD_ZERO(&fdsetRecv); FD_ZERO(&fdsetSend); SOCKET hSocketMax = 0; @@ -599,7 +628,11 @@ void ThreadSocketHandler2(void* parg) if (FD_ISSET(hListenSocket, &fdsetRecv)) { struct sockaddr_in sockaddr; +#ifdef __WXMSW__ int len = sizeof(sockaddr); +#else + socklen_t len = sizeof(sockaddr); +#endif SOCKET hSocket = accept(hListenSocket, (struct sockaddr*)&sockaddr, &len); CAddress addr(sockaddr); if (hSocket == INVALID_SOCKET) @@ -765,14 +798,12 @@ void ThreadOpenConnections2(void* parg) } // Initiate network connections - int nTry = 0; - bool fIRCOnly = false; - const int nMaxConnections = 15; loop { // Wait vnThreadsRunning[1]--; Sleep(500); + const int nMaxConnections = 15; while (vNodes.size() >= nMaxConnections || vNodes.size() >= mapAddresses.size()) { CheckForShutdown(1); @@ -781,93 +812,55 @@ void ThreadOpenConnections2(void* parg) vnThreadsRunning[1]++; CheckForShutdown(1); - // - // The IP selection process is designed to limit vulnerability to address flooding. - // Any class C (a.b.c.?) has an equal chance of being chosen, then an IP is - // chosen within the class C. An attacker may be able to allocate many IPs, but - // they would normally be concentrated in blocks of class C's. They can hog the - // attention within their class C, but not the whole IP address space overall. - // A lone node in a class C will get as much attention as someone holding all 255 - // IPs in another class C. + // Choose an address to connect to based on most recently seen // + CAddress addrConnect; + int64 nBestTime = 0; + int64 nDelay = ((60 * 60) << vNodes.size()); + if (vNodes.size() >= 3) + nDelay *= 4; + if (nGotIRCAddresses > 0) + nDelay *= 100; + + // Do this here so we don't have to critsect vNodes inside mapAddresses critsect + set setConnected; + CRITICAL_BLOCK(cs_vNodes) + foreach(CNode* pnode, vNodes) + setConnected.insert(pnode->addr.ip); - // Every other try is with IRC addresses only - fIRCOnly = !fIRCOnly; - if (mapIRCAddresses.empty()) - fIRCOnly = false; - else if (nTry++ < 30 && vNodes.size() < nMaxConnections/2) - fIRCOnly = true; - - // Make a list of unique class C's - unsigned char pchIPCMask[4] = { 0xff, 0xff, 0xff, 0x00 }; - unsigned int nIPCMask = *(unsigned int*)pchIPCMask; - vector vIPC; - CRITICAL_BLOCK(cs_mapIRCAddresses) CRITICAL_BLOCK(cs_mapAddresses) { - vIPC.reserve(mapAddresses.size()); - unsigned int nPrev = 0; foreach(const PAIRTYPE(vector, CAddress)& item, mapAddresses) { const CAddress& addr = item.second; - if (!addr.IsIPv4()) - continue; - if (fIRCOnly && !mapIRCAddresses.count(item.first)) + if (!addr.IsIPv4() || !addr.IsValid() || setConnected.count(addr.ip)) continue; - // Taking advantage of mapAddresses being in sorted order, - // with IPs of the same class C grouped together. - unsigned int ipC = addr.ip & nIPCMask; - if (ipC != nPrev) - vIPC.push_back(nPrev = ipC); - } - } - if (vIPC.empty()) - continue; - - // Choose a random class C - unsigned int ipC = vIPC[GetRand(vIPC.size())]; + // Limit retry frequency + if (GetAdjustedTime() < addr.nLastFailed + nDelay) + continue; - // Organize all addresses in the class C by IP - map > mapIP; - CRITICAL_BLOCK(cs_mapIRCAddresses) - CRITICAL_BLOCK(cs_mapAddresses) - { - int64 nDelay = ((30 * 60) << vNodes.size()); - if (!fIRCOnly) - { - nDelay *= 2; - if (vNodes.size() >= 3) - nDelay *= 4; - if (!mapIRCAddresses.empty()) - nDelay *= 100; - } + // Try again only after all addresses had a first attempt + int64 nTime = addr.nTime; + if (addr.nLastFailed > addr.nTime) + nTime -= 365 * 24 * 60 * 60; - for (map, CAddress>::iterator mi = mapAddresses.lower_bound(CAddress(ipC, 0).GetKey()); - mi != mapAddresses.upper_bound(CAddress(ipC | ~nIPCMask, 0xffff).GetKey()); - ++mi) - { - const CAddress& addr = (*mi).second; - if (fIRCOnly && !mapIRCAddresses.count((*mi).first)) - continue; + // Randomize the order a little, putting the standard port first + nTime += GetRand(1 * 60 * 60); + if (addr.port != DEFAULT_PORT) + nTime -= 1 * 60 * 60; - int64 nRandomizer = (addr.nLastFailed * addr.ip * 7777U) % 20000; - if (GetTime() - addr.nLastFailed > nDelay * nRandomizer / 10000) - mapIP[addr.ip].push_back(addr); + if (nTime > nBestTime) + { + nBestTime = nTime; + addrConnect = addr; + } } } - if (mapIP.empty()) - continue; - - // Choose a random IP in the class C - map >::iterator mi = mapIP.begin(); - advance(mi, GetRand(mapIP.size())); - // Once we've chosen an IP, we'll try every given port before moving on - foreach(const CAddress& addrConnect, (*mi).second) - if (OpenNetworkConnection(addrConnect)) - break; + if (addrConnect.IsValid()) + OpenNetworkConnection(addrConnect); } } @@ -989,6 +982,7 @@ bool StartNode(string& strError) pnodeLocalHost = new CNode(INVALID_SOCKET, CAddress("127.0.0.1", nLocalServices)); strError = ""; +#ifdef __WXMSW__ // Sockets startup WSADATA wsadata; int ret = WSAStartup(MAKEWORD(2,2), &wsadata); @@ -998,6 +992,7 @@ bool StartNode(string& strError) printf("%s\n", strError.c_str()); return false; } +#endif // Get local host ip char pszHostName[255]; @@ -1029,10 +1024,14 @@ bool StartNode(string& strError) } // Set to nonblocking, incoming connections will also inherit this +#ifdef __WXMSW__ u_long nOne = 1; if (ioctlsocket(hListenSocket, FIONBIO, &nOne) == SOCKET_ERROR) +#else + if (fcntl(hListenSocket, F_SETFL, O_NONBLOCK) == SOCKET_ERROR) +#endif { - strError = strprintf("Error: Couldn't set properties on socket for incoming connections (ioctlsocket returned error %d)", WSAGetLastError()); + strError = strprintf("Error: Couldn't set properties on socket for incoming connections (error %d)", WSAGetLastError()); printf("%s\n", strError.c_str()); return false; } @@ -1041,7 +1040,7 @@ bool StartNode(string& strError) // IP address, and port for the socket that is being bound int nRetryLimit = 15; struct sockaddr_in sockaddr = addrLocalHost.GetSockAddr(); - if (bind(hListenSocket, (struct sockaddr*)&sockaddr, sizeof(sockaddr)) == SOCKET_ERROR) + if (::bind(hListenSocket, (struct sockaddr*)&sockaddr, sizeof(sockaddr)) == SOCKET_ERROR) { int nErr = WSAGetLastError(); if (nErr == WSAEADDRINUSE) @@ -1131,7 +1130,9 @@ bool StopNode() Sleep(50); // Sockets shutdown +#ifdef __WXMSW__ WSACleanup(); +#endif return true; } diff --git a/net.h b/net.h index 7716426f04..275a4cb88b 100644 --- a/net.h +++ b/net.h @@ -22,7 +22,8 @@ enum bool ConnectSocket(const CAddress& addrConnect, SOCKET& hSocketRet); bool GetMyExternalIP(unsigned int& ipRet); -bool AddAddress(CAddrDB& addrdb, const CAddress& addr); +bool AddAddress(CAddrDB& addrdb, CAddress addr, bool fCurrentlyOnline=true); +void AddressCurrentlyConnected(const CAddress& addr); CNode* FindNode(unsigned int ip); CNode* ConnectNode(CAddress addrConnect, int64 nTimeout=0); void AbandonRequests(void (*fn)(void*, CDataStream&), void* param1); diff --git a/ui.cpp b/ui.cpp index 9185b8159f..212548199f 100644 --- a/ui.cpp +++ b/ui.cpp @@ -260,7 +260,8 @@ void AddPendingReplyEvent3(void* pevthandler, CDataStream& vRecv) CDataStream GetStreamFromEvent(const wxCommandEvent& event) { wxString strData = event.GetString(); - return CDataStream(strData.begin(), strData.begin() + event.GetInt(), SER_NETWORK); + const char* pszBegin = strData.c_str(); + return CDataStream(pszBegin, pszBegin + event.GetInt(), SER_NETWORK); } @@ -288,20 +289,6 @@ CMainFrame::CMainFrame(wxWindow* parent) : CMainFrameBase(parent) SetIcon(wxICON(bitcoin)); ptaskbaricon = new CMyTaskBarIcon(); - // Init toolbar with transparency masked bitmaps - m_toolBar->ClearTools(); - - //// shouldn't have to do mask separately anymore, bitmap alpha support added in wx 2.8.9, - wxBitmap bmpSend(wxT("send20"), wxBITMAP_TYPE_RESOURCE); - bmpSend.SetMask(new wxMask(wxBitmap(wxT("send20mask"), wxBITMAP_TYPE_RESOURCE))); - m_toolBar->AddTool(wxID_BUTTONSEND, wxT("&Send Coins"), bmpSend, wxNullBitmap, wxITEM_NORMAL, wxEmptyString, wxEmptyString); - - wxBitmap bmpAddressBook(wxT("addressbook20"), wxBITMAP_TYPE_RESOURCE); - bmpAddressBook.SetMask(new wxMask(wxBitmap(wxT("addressbook20mask"), wxBITMAP_TYPE_RESOURCE))); - m_toolBar->AddTool(wxID_BUTTONRECEIVE, wxT("&Address Book"), bmpAddressBook, wxNullBitmap, wxITEM_NORMAL, wxEmptyString, wxEmptyString); - - m_toolBar->Realize(); - // Init column headers int nDateWidth = DateTimeStr(1229413914).size() * 6 + 8; if (!strstr(DateTimeStr(1229413914).c_str(), "2008")) @@ -909,15 +896,17 @@ void CMainFrame::OnPaintListCtrl(wxPaintEvent& event) { TRY_CRITICAL_BLOCK(cs_mapWallet) { - bool fInserted = false; + string strTop; + if (m_listCtrl->GetItemCount()) + strTop = (string)m_listCtrl->GetItemText(0); foreach(uint256 hash, vWalletUpdated) { map::iterator mi = mapWallet.find(hash); if (mi != mapWallet.end()) - fInserted |= InsertTransaction((*mi).second, false); + InsertTransaction((*mi).second, false); } vWalletUpdated.clear(); - if (fInserted) + if (m_listCtrl->GetItemCount() && strTop != (string)m_listCtrl->GetItemText(0)) m_listCtrl->ScrollList(0, INT_MAX); } } @@ -954,7 +943,9 @@ void CMainFrame::OnPaintListCtrl(wxPaintEvent& event) string strStatus = strprintf(" %d connections %d blocks %d transactions", vNodes.size(), nBestHeight + 1, nTransactionCount); m_statusBar->SetStatusText(strStatus, 2); +#ifdef __WXMSW__ m_listCtrl->OnPaint(event); +#endif } @@ -1407,7 +1398,7 @@ COptionsDialog::COptionsDialog(wxWindow* parent) : COptionsDialogBase(parent) m_checkBoxLimitProcessors->SetValue(fLimitProcessors); m_spinCtrlLimitProcessors->Enable(fLimitProcessors); m_spinCtrlLimitProcessors->SetValue(nLimitProcessors); - int nProcessors = atoi(getenv("NUMBER_OF_PROCESSORS")); + int nProcessors = wxThread::GetCPUCount(); if (nProcessors < 1) nProcessors = 999; m_spinCtrlLimitProcessors->SetRange(1, nProcessors); @@ -1549,17 +1540,11 @@ void COptionsDialog::OnButtonApply(wxCommandEvent& event) walletdb.WriteSetting("fMinimizeOnClose", fMinimizeOnClose); } - if (fUseProxy != m_checkBoxUseProxy->GetValue()) - { - fUseProxy = m_checkBoxUseProxy->GetValue(); - walletdb.WriteSetting("fUseProxy", fUseProxy); - } + fUseProxy = m_checkBoxUseProxy->GetValue(); + walletdb.WriteSetting("fUseProxy", fUseProxy); - if (addrProxy != GetProxyAddr()) - { - addrProxy = GetProxyAddr(); - walletdb.WriteSetting("addrProxy", addrProxy); - } + addrProxy = GetProxyAddr(); + walletdb.WriteSetting("addrProxy", addrProxy); } @@ -1608,10 +1593,8 @@ CSendDialog::CSendDialog(wxWindow* parent, const wxString& strAddress) : CSendDi //// todo: should add a display of your balance for convenience // Set Icon - wxBitmap bmpSend(wxT("send16"), wxBITMAP_TYPE_RESOURCE); - bmpSend.SetMask(new wxMask(wxBitmap(wxT("send16masknoshadow"), wxBITMAP_TYPE_RESOURCE))); wxIcon iconSend; - iconSend.CopyFromBitmap(bmpSend); + iconSend.CopyFromBitmap(wxBitmap(send16noshadow_xpm)); SetIcon(iconSend); wxCommandEvent event; @@ -2231,10 +2214,8 @@ CAddressBookDialog::CAddressBookDialog(wxWindow* parent, const wxString& strInit m_listCtrl->SetFocus(); // Set Icon - wxBitmap bmpAddressBook(wxT("addressbook16"), wxBITMAP_TYPE_RESOURCE); - bmpAddressBook.SetMask(new wxMask(wxBitmap(wxT("addressbook16mask"), wxBITMAP_TYPE_RESOURCE))); wxIcon iconAddressBook; - iconAddressBook.CopyFromBitmap(bmpAddressBook); + iconAddressBook.CopyFromBitmap(wxBitmap(addressbook16_xpm)); SetIcon(iconAddressBook); // Fill listctrl with address book data @@ -3345,7 +3326,7 @@ bool CMyApp::OnInit2() _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE); _CrtSetReportFile(_CRT_WARN, CreateFile("NUL", GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0)); #endif -#ifdef __WXDEBUG__ +#if defined(__WXMSW__) && defined(__WXDEBUG__) // Disable malfunctioning wxWidgets debug assertion g_isPainting = 10000; #endif @@ -3362,8 +3343,7 @@ bool CMyApp::OnInit2() " -gen=0\t\t Don't generate coins\n" " -min\t\t Start minimized\n" " -datadir=\t Specify data directory\n" - " -proxy=\t Connect through socks4 proxy,\n" - " \t\t e.g. -proxy=127.0.0.1:9050 to use TOR\n" + " -proxy=\t Connect through socks4 proxy\n" " -addnode=\t Add a node to connect to\n" " -connect=\t Connect only to the specified node\n" " -?\t\t This help message\n"; @@ -3386,6 +3366,8 @@ bool CMyApp::OnInit2() unsigned int nStart = GetTime(); loop { + // TODO: find out how to do this in Linux, or replace with wxWidgets commands +#ifdef __WXMSW__ // Show the previous instance and exit HWND hwndPrev = FindWindow("wxWindowClassNR", "Bitcoin"); if (hwndPrev) @@ -3395,6 +3377,7 @@ bool CMyApp::OnInit2() SetForegroundWindow(hwndPrev); return false; } +#endif if (GetTime() > nStart + 60) return false; @@ -3421,7 +3404,7 @@ bool CMyApp::OnInit2() fPrintToDebugger = true; printf("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"); - printf("Bitcoin version %d, Windows version %08x\n", VERSION, GetVersion()); + printf("Bitcoin version %d, OS version %s\n", VERSION, wxGetOsDescription().mb_str()); if (mapArgs.count("-dropmessages")) { @@ -3493,12 +3476,36 @@ bool CMyApp::OnInit2() return false; } + if (mapArgs.count("-printblock")) + { + string strMatch = mapArgs["-printblock"]; + int nFound = 0; + for (map::iterator mi = mapBlockIndex.begin(); mi != mapBlockIndex.end(); ++mi) + { + uint256 hash = (*mi).first; + if (strncmp(hash.ToString().c_str(), strMatch.c_str(), strMatch.size()) == 0) + { + CBlockIndex* pindex = (*mi).second; + CBlock block; + block.ReadFromDisk(pindex, true); + block.BuildMerkleTree(); + block.print(); + printf("\n"); + nFound++; + } + } + if (nFound == 0) + printf("No blocks matching %s were found\n", strMatch.c_str()); + OnExit(); + return false; + } + if (mapArgs.count("-gen")) { if (mapArgs["-gen"].empty()) fGenerateBitcoins = true; else - fGenerateBitcoins = atoi(mapArgs["-gen"].c_str()); + fGenerateBitcoins = (atoi(mapArgs["-gen"].c_str()) != 0); } if (mapArgs.count("-proxy")) @@ -3511,9 +3518,6 @@ bool CMyApp::OnInit2() OnExit(); return false; } - CWalletDB walletdb; - walletdb.WriteSetting("fUseProxy", fUseProxy); - walletdb.WriteSetting("addrProxy", addrProxy); } if (mapArgs.count("-addnode")) @@ -3522,6 +3526,7 @@ bool CMyApp::OnInit2() foreach(string strAddr, mapMultiArgs["-addnode"]) { CAddress addr(strAddr, NODE_NETWORK); + addr.nTime = 0; // so it won't relay unless successfully connected if (addr.IsValid()) AddAddress(addrdb, addr); } @@ -3559,7 +3564,11 @@ bool CMyApp::OnInit2() // // Tests // +#ifdef __WXMSW__ if (argc >= 2 && stricmp(argv[1], "-send") == 0) +#else + if (argc >= 2 && strcmp(argv[1], "-send") == 0) +#endif { int64 nValue = 1; if (argc >= 3) @@ -3646,7 +3655,8 @@ void CMyApp::OnFatalException() -typedef WINSHELLAPI BOOL WINAPI (*PSHGETSPECIALFOLDERPATHA)(HWND hwndOwner, LPSTR lpszPath, int nFolder, BOOL fCreate); +#ifdef __WXMSW__ +typedef WINSHELLAPI BOOL (WINAPI *PSHGETSPECIALFOLDERPATHA)(HWND hwndOwner, LPSTR lpszPath, int nFolder, BOOL fCreate); string MyGetSpecialFolderPath(int nFolder, bool fCreate) { @@ -3737,7 +3747,10 @@ void SetStartOnSystemStartup(bool fAutoStart) CoUninitialize(); } } - +#else +bool GetStartOnSystemStartup() { return false; } +void SetStartOnSystemStartup(bool fAutoStart) { } +#endif diff --git a/uibase.cpp b/uibase.cpp index b03e578bd8..bb564e9960 100644 --- a/uibase.cpp +++ b/uibase.cpp @@ -7,6 +7,10 @@ #include "uibase.h" +#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 ) @@ -60,8 +64,8 @@ CMainFrameBase::CMainFrameBase( wxWindow* parent, wxWindowID id, const wxString& m_toolBar->SetToolSeparation( 1 ); m_toolBar->SetFont( wxFont( wxNORMAL_FONT->GetPointSize(), 70, 90, 90, false, wxEmptyString ) ); - m_toolBar->AddTool( wxID_BUTTONSEND, wxT("&Send Coins"), wxBitmap( wxT("send20"), wxBITMAP_TYPE_RESOURCE ), wxNullBitmap, wxITEM_NORMAL, wxEmptyString, wxEmptyString ); - m_toolBar->AddTool( wxID_BUTTONRECEIVE, wxT("&Address Book"), wxBitmap( wxT("addressbook20"), wxBITMAP_TYPE_RESOURCE ), wxNullBitmap, wxITEM_NORMAL, wxEmptyString, wxEmptyString ); + m_toolBar->AddTool( wxID_BUTTONSEND, wxT("&Send Coins"), wxBitmap( send20_xpm ), wxNullBitmap, wxITEM_NORMAL, wxEmptyString, wxEmptyString ); + m_toolBar->AddTool( wxID_BUTTONRECEIVE, wxT("&Address Book"), wxBitmap( addressbook20_xpm ), wxNullBitmap, wxITEM_NORMAL, wxEmptyString, wxEmptyString ); m_toolBar->Realize(); m_statusBar = this->CreateStatusBar( 1, wxST_SIZEGRIP, wxID_ANY ); @@ -666,7 +670,7 @@ CSendDialogBase::CSendDialogBase( wxWindow* parent, wxWindowID id, const wxStrin bSizer47->Add( 0, 0, 1, wxEXPAND, 5 ); - m_bitmapCheckMark = new wxStaticBitmap( this, wxID_ANY, wxICON( check ), wxDefaultPosition, wxSize( 16,16 ), 0 ); + 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, wxT("Pay &To:"), wxDefaultPosition, wxSize( -1,-1 ), wxALIGN_RIGHT ); diff --git a/uiproject.fbp b/uiproject.fbp index 313e5aa6cc..7bce7349f5 100644 --- a/uiproject.fbp +++ b/uiproject.fbp @@ -225,7 +225,7 @@ - + 20,20 @@ -273,7 +273,7 @@ - send20; Load From Resource + xpm/send20.xpm; Load From File wxID_BUTTONSEND wxITEM_NORMAL &Send Coins @@ -287,7 +287,7 @@ - addressbook20; Load From Resource + xpm/addressbook20.xpm; Load From File wxID_BUTTONRECEIVE wxITEM_NORMAL &Address Book @@ -1685,7 +1685,7 @@ - + @@ -3699,7 +3699,7 @@ 0 - check; Load From Icon Resource [-1; -1] + xpm/check.xpm; Load From File 1 diff --git a/util.cpp b/util.cpp index 23b59f11f7..d2e624d676 100644 --- a/util.cpp +++ b/util.cpp @@ -38,8 +38,10 @@ public: ppmutexOpenSSL[i] = new wxMutex(); CRYPTO_set_locking_callback(locking_callback); +#ifdef __WXMSW__ // Seed random number generator with screen scrape and other hardware sources RAND_screen(); +#endif // Seed random number generator with performance counter RandAddSeed(); @@ -325,8 +327,8 @@ void ParseParameters(int argc, char* argv[]) pszValue = strchr(psz, '='); *pszValue++ = '\0'; } - strlwr(psz); #ifdef __WXMSW__ + _strlwr(psz); if (psz[0] == '/') psz[0] = '-'; #endif @@ -343,9 +345,13 @@ void ParseParameters(int argc, char* argv[]) void FormatException(char* pszMessage, std::exception* pex, const char* pszThread) { +#ifdef __WXMSW__ char pszModule[MAX_PATH]; pszModule[0] = '\0'; GetModuleFileName(NULL, pszModule, sizeof(pszModule)); +#else + const char* pszModule = wxStandardPaths::Get().GetExecutablePath().mb_str(); +#endif if (pex) snprintf(pszMessage, 1000, "EXCEPTION: %s \n%s \n%s in %s \n", typeid(*pex).name(), pex->what(), pszModule, pszThread); diff --git a/util.h b/util.h index 822a049ce7..3bc7c798a5 100644 --- a/util.h +++ b/util.h @@ -55,9 +55,34 @@ inline T& REF(const T& val) } #ifndef __WXMSW__ -#define closesocket(s) close(s) -#define INVALID_SOCKET (SOCKET)(~0) +#define _UI64_MAX UINT64_MAX +#define _I64_MAX INT64_MAX +#define WSAGetLastError() errno +#define WSAEWOULDBLOCK EWOULDBLOCK +#define WSAEMSGSIZE EMSGSIZE +#define WSAEINTR EINTR +#define WSAEINPROGRESS EINPROGRESS +#define WSAEADDRINUSE EADDRINUSE +#define closesocket(s) close(s) +#define INVALID_SOCKET (SOCKET)(~0) +#define SOCKET_ERROR -1 typedef u_int SOCKET; +#define _vsnprintf(a,b,c,d) vsnprintf(a,b,c,d) +#define strlwr(psz) to_lower(psz) +#define _strlwr(psz) to_lower(psz) +#define _mkdir(psz) filesystem::create_directory(psz) +#define MAX_PATH 1024 +#define Sleep(n) wxMilliSleep(n) +#define Beep(n1,n2) (0) +inline int _beginthread(void(*pfn)(void*), unsigned nStack, void* parg) { thread(bind(pfn, parg)); return 0; } +inline void _endthread() { pthread_exit(NULL); } +inline int GetCurrentThread() { return 0; } +// threads are processes on linux, so setpriority affects just the one thread +inline void SetThreadPriority(int nThread, int nPriority) { setpriority(PRIO_PROCESS, getpid(), nPriority); } +#define THREAD_PRIORITY_LOWEST PRIO_MIN +#define THREAD_PRIORITY_BELOW_NORMAL 2 +#define THREAD_PRIORITY_NORMAL 0 +#define THREAD_PRIORITY_ABOVE_NORMAL 0 #endif @@ -120,7 +145,7 @@ public: protected: wxMutex mutex; public: - explicit CCriticalSection() { } + explicit CCriticalSection() : mutex(wxMUTEX_RECURSIVE) { } ~CCriticalSection() { } void Enter() { mutex.Lock(); } void Leave() { mutex.Unlock(); } @@ -183,7 +208,7 @@ inline int OutputDebugStringF(const char* pszFormat, ...) // print to debug.log char pszFile[MAX_PATH+100]; GetDataDir(pszFile); - strlcat(pszFile, "\\debug.log", sizeof(pszFile)); + strlcat(pszFile, "/debug.log", sizeof(pszFile)); FILE* fileout = fopen(pszFile, "a"); if (fileout) { @@ -354,13 +379,6 @@ inline int64 GetTimeMillis() return wxGetLocalTimeMillis().GetValue(); } -#ifndef __WXMSW__ -inline void Sleep(unsigned int nMilliseconds) -{ - wxMilliSleep(nMilliseconds); -} -#endif - diff --git a/xpm/addressbook16.xpm b/xpm/addressbook16.xpm new file mode 100644 index 0000000000..471f700c70 --- /dev/null +++ b/xpm/addressbook16.xpm @@ -0,0 +1,278 @@ +/* XPM */ +static 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", +" 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/xpm/addressbook20.xpm b/xpm/addressbook20.xpm new file mode 100644 index 0000000000..48df12d801 --- /dev/null +++ b/xpm/addressbook20.xpm @@ -0,0 +1,282 @@ +/* XPM */ +static 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", +" > > > > > > > > > > > > > > > > > > > ", +"> > > > > > > > > > > > > > > > > > > > ", +"> > 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/xpm/bitcoin.xpm b/xpm/bitcoin.xpm new file mode 100644 index 0000000000..166d5aa6e4 --- /dev/null +++ b/xpm/bitcoin.xpm @@ -0,0 +1,304 @@ +/* XPM */ +static char * bitcoin_xpm[] = { +/* columns rows colors chars-per-pixel */ +"48 48 250 2", +" c #725203", +". c #795603", +"X c #7D5903", +"o c #76560B", +"O c #77590E", +"+ c #795A0D", +"@ c #7B5D14", +"# c #7C5F18", +"$ c #7D6019", +"% c #825D05", +"& c #856007", +"* c #86620B", +"= c #8B660B", +"- c #8E690E", +"; c #906A0F", +": c #8F6B17", +"> c #83641C", +", c #8D6C1E", +"< c #926C11", +"1 c #967014", +"2 c #997215", +"3 c #9C761B", +"4 c #9E791D", +"5 c #A37C1E", +"6 c #816520", +"7 c #876A25", +"8 c #8E6E22", +"9 c #866A29", +"0 c #896E2C", +"q c #8E7020", +"w c #937324", +"e c #997722", +"r c #9E7B25", +"t c #94762B", +"y c #967828", +"u c #9A7B2D", +"i c #8B7131", +"p c #9E7E31", +"a c #947839", +"s c #A37D22", +"d c #A68125", +"f c #AA8325", +"g c #AE8827", +"h c #A6832D", +"j c #AA852B", +"k c #AD892B", +"l c #B08727", +"z c #B28827", +"x c #B08729", +"c c #B38B2C", +"v c #B88E2F", +"b c #B8902D", +"n c #A38334", +"m c #A98632", +"M c #AB8A34", +"N c #A4873C", +"B c #A78A3D", +"V c #AC8B3C", +"C c #B38D32", +"Z c #BA8F30", +"A c #B28E3C", +"S c #B69332", +"D c #BC9433", +"F c #BF9832", +"G c #B4923C", +"H c #BA963D", +"J c #B7993E", +"K c #BE9A3B", +"L c #C1932F", +"P c #C39732", +"I c #C49935", +"U c #C59C3A", +"Y c #C99E3D", +"T c #C2A13F", +"R c #CDA23F", +"E c #9D8342", +"W c #AB8C43", +"Q c #B28E40", +"! c #AE9144", +"~ c #AE914A", +"^ c #B49445", +"/ c #BC9B44", +"( c #B3964D", +") c #B5994C", +"_ c #BD9B4A", +"` c #A98F50", +"' c #B19553", +"] c #B59A54", +"[ c #BD9F51", +"{ c #B59B5C", +"} c #B89D5C", +"| c #BEA155", +" . c #BDA35D", +".. c #B59C61", +"X. c #B99F66", +"o. c #BCA363", +"O. c #BDA56C", +"+. c #BCA571", +"@. c #BDA873", +"#. c #BFAA78", +"$. c #C49D43", +"%. c #C99F45", +"&. c #C29E4B", +"*. c #C5A144", +"=. c #CCA244", +"-. c #C5A44B", +";. c #CAA54B", +":. c #C8A84C", +">. c #D0A644", +",. c #D3AA44", +"<. c #D3AC4C", +"1. c #D8AD4D", +"2. c #DAB046", +"3. c #DCB24E", +"4. c #C3A454", +"5. c #CBA751", +"6. c #CCAA53", +"7. c #C1A65B", +"8. c #C8A75A", +"9. c #CBAC5B", +"0. c #D0A650", +"q. c #D2AC53", +"w. c #DAAD54", +"e. c #D3AD5C", +"r. c #CFB259", +"t. c #D4B156", +"y. c #DDB454", +"u. c #D4B25C", +"i. c #DAB65A", +"p. c #D7B95F", +"a. c #DEBA5E", +"s. c #E2B555", +"d. c #E5BA53", +"f. c #E1B55A", +"g. c #E5BC5C", +"h. c #EABF5D", +"j. c #C1A761", +"k. c #C4AA63", +"l. c #CBAE63", +"z. c #CBB166", +"x. c #CBB26C", +"c. c #D4B263", +"v. c #DAB462", +"b. c #D6B864", +"n. c #DCB965", +"m. c #D3B669", +"M. c #DCB768", +"N. c #D4BA6E", +"B. c #DCBB6C", +"V. c #CDB672", +"C. c #D2B972", +"Z. c #DBBE72", +"A. c #E4BC62", +"S. c #E9BE62", +"D. c #E2BD6C", +"F. c #E0BF72", +"G. c #E6C05E", +"H. c #EFC05D", +"J. c #F0C15B", +"K. c #DFC167", +"L. c #D7C069", +"P. c #DDC36D", +"I. c #DBC376", +"U. c #D4C17B", +"Y. c #DAC17B", +"T. c #D8C878", +"R. c #E4C362", +"E. c #EBC364", +"W. c #E3C865", +"Q. c #EDC866", +"!. c #E4C36A", +"~. c #E9C66B", +"^. c #ECCA6B", +"/. c #F1C564", +"(. c #F8C765", +"). c #F5CB66", +"_. c #F8CC67", +"`. c #F6CC6A", +"'. c #F9CD6B", +"]. c #EED26A", +"[. c #F2D06F", +"{. c #FBD26D", +"}. c #E4C374", +"|. c #EBC474", +" X c #E1C972", +".X c #EDCD72", +"XX c #E4C57A", +"oX c #E9C67C", +"OX c #E5C87C", +"+X c #EACA7D", +"@X c #F2CC74", +"#X c #FBCF71", +"$X c #EED174", +"%X c #ECD37B", +"&X c #F4D274", +"*X c #FDD473", +"=X c #FFD975", +"-X c #F4D57C", +";X c #FCD57A", +":X c #F3DA7C", +">X c #FEDB7C", +",X c #FFE37D", +"X=XQ.s.=.v 5 1 < E HXHXHXHXHXHXHXHXHXHXHXHXHXHX", +"HXHXHXHXHXHXHXHXHXHXHX' g f F d.).).{.{.=X=X=X{.{.{.`.`.`.).g.U f 2 * a HXHXHXHXHXHXHXHXHXHXHXHX", +"HXHXHXHXHXHXHXHXHXHXV f b G.J.{.{.{.*X=X,X=X*X{.`.).`.).).{.`.{./.U 5 ; + HXHXHXHXHXHXHXHXHXHXHX", +"HXHXHXHXHXHXHXHX} h g 1.)._._.{.,X*X=X,X{.{.)._.).).`.`.`.{.*X*X*X`.y.g 2 & $ HXHXHXHXHXHXHXHXHX", +"HXHXHXHXHXHXHX{ j c G.).{.{.{.=X,X{.{.J.d.2.R 2.,.3.g.`.&X;X;X;X&X[.{.`.I 3 & + HXHXHXHXHXHXHXHX", +"HXHXHXHXHXHX{ d D /.{.{.*X=X=X*X).3.R I I I P F F U $.;.n.-XrXrX;X&X;X>XdX:.4 X o HXHXHXHXHXHXHX", +"HXHXHXHXHX..j v /.*X=X=X=X=X`.1.R R R R I I I P K U *.e.D.|.}.+XrXqXhXhXdXfX:.4 X o HXHXHXHXHXHX", +"HXHXHXHXHXh v `.{.>X,X*X{.g.>.Y R I I I I I I U U ;.t.D.|.oXB.z.F.kXvXcXjXjXjX/ 1 . + HXHXHXHXHX", +"HXHXHXHXV g Q.=X=X>X>X'.>.Y Y U R I I I P P I U U <.n.~.}.F.XXXX}.%XbXbXcXcXcXsXc = # HXHXHXHX", +"HXHXHX} j t.>X>X>X*X'.>.U U I U P U U I P P I U T 6.M.D.oX5XwXeXeXqX0XvXbXbXcXjXW.5 % HXHXHXHX", +"HXHXHXM G hXhXqX>X*X<.U U U I I I I I I D D U T T -.9.B.3XpXpXzXgXqX:X:XbXbXcXjXfXT < o HXHXHX", +"HXHX} k XlXkXkXrXA.$.D Z Z Z v v v b b v D U U *.-.9.B.OX2XOXI.P.L.K.W.$XbXcXjX,X].d % 9 HXHX", +"HXHXV J xXxXxXxXrX5.&.A M m m m h h n s 5 g S K *.:.8.4.| k.x.C.N.z.7.) :.$XjXfX,X,XT ; o HXHX", +"HXHXM L.vXxXxXxXF._ MXCXCXCXCXCXCXCXCXmXY.h g K *./ ^ Y.mXCXCXCXCXCXCXVXZ.4.hXfX,X,XW.4 X HXHX", +"HX] k gXxXxXxXgXe.V MXCXCXCXCXVXCXCXCXCXCXyXh D G [ mXCXCXCXCXCXCXCXCXCX4XG ~.fX,X,X,Xg & $ HX", +"HXV J vXxXxXxX6Xe.V MXCXCXCXCXk.N VXCXCXCXVX| h ^ MXCXCXCXCXuX( n V l.mX4XA y.fX,X,X=XT ; HX", +"HXk r.xXxXxXxX|.v.V MXCXCXCXCXo.> 4XCXCXCXCXx.w tXCXCXCXCXnXn V / / M V m.&.t.=X,X,X=Xy.2 o HX", +"HXk P.xXvXxXxX|.M.Q nXCXCXCXCXj.w X>X=XH.5 X $ ", +"o.k %XvXbXBXkX|.D.Q nXCXCXCXCXj., 7XCXCXCXCX~ k.CXCXCXCXCXV &.n.R.g.G.g.S.S.S.(.qX*X=X`.5 X $ ", +" .k 0XvXvXvXrX@XD.^ VXCXCXCXCXx.~ VXCXCXCXX=X*X*Xd X $ ", +"{ k sXcXvXBXeX@XD.( nXCXCXCXCXCXCXCXCXVXo., u T.CXCXCXVXmXn t.E.g.g.h.S.g.S.f.A.>X;X*X*Xf & o ", +"{ k sXjXlXcX0X~.n.^ MXCXCXCXCXCXCXCXCXCXCXU.t U.CXCXCXCXmXM p.~.W.g.s.s.s.s.f.A.>X*X*X*Xj % ", +"o.k :XjXlXlX-XD.v.A MXCXCXCXCXj.t mXCXCXCXCX .x.CXCXCXCXVXV p.$X^.E.g.s.w.w.w.A.9X;X*X*Xf X ", +"o.g ].dXjXhX-Xn.e.V MXCXCXCXCXj.8 X*X#X5 X O ", +"HXj K.dXdXhX9Xv.9.M MXCXCXCXCXk.a Z.CXCXCXCX7Xu CXCXCXCXCXV./ !.$X~.f.5.%.0.q.S.>X*X*XE.5 X # ", +"HXj t.dX,XdXdXi.6.N MXCXCXCXCXo.q XqXqXqX!.6.m MXCXCXCXCXV.' VXCXCXZXCXk.! ] VXCXCXCXCXVXC.[ 7.Z.VX2Xx %.#X#X'.'.%.- o 6 ", +"HX( g &X>X>XdX-X5.M MXCXCXCXCXCXCXCXCXCXCX7X) m.9. .MXCXCXCXCXCXCXCXCXCX2Xs 1.'.`.'.'.x % HX", +"HXO.j y.>X>X>X>X6.! zXMXMXMXMXMXMXMXMXuXx.( N.8X6Xz.) C.uXCXCXCXCXCXVX7X4.c h.'.(.(.s.5 X HX", +"HXHXj H &X=X:X>X~./ V h y u n n n N W ( 7.Z.8XpXpX+Xm.| V V ^ ) ( m e 3 s R (.(.'.'.Y ; . > HX", +"HXHX} f G.&X&X&X:Xt._ / ) _ 4.8.l.m.B.Z.2XwXpXeXwX6X+XP.c.8.-./ C x x z P J.(.'.(./.5 % HXHX", +"HXHXHXh D &X&X&X&X@X:.4.5.9.c.m.F.OX+XwXwXwXwX6X3XOX}.D.D.v.w.%.Y I P P d.(.(.'.'.=.< . + HXHX", +"HXHXHX] d y.[.&X&X&X~.:.4.9.e.M.B.}.oX3X5X3X3X+X}.F.M.e.0.0.0.%.%.Y Y s.#X#X#X#XS.s % HXHXHX", +"HXHXHXHXm g `.@X&X&X&X~.5.6.e.b.B.}.XX+X3XOX}.I.F.F.D.e.e.e.e.e.q.0.A.;X;X#X-X@XZ = o + HXHXHX", +"HXHXHXHX..j D @X&X&X&X&X@Xp.u.M.D.}.XXOXOXZ.Z.XX1XOXoXoXF.F.F.M.D.6XrXqX9X9X9X%.1 . HXHXHXHX", +"HXHXHXHXHX' f $.&X&X&X>XqXqX XB.D.!.XXXXZ.XXOX5XwXwXwXwXiXwXwXnXVXZXBXxXzXxXb.r X $ HXHXHXHX", +"HXHXHXHXHXHX~ j ;.qXqXqXqXrXkXrX+XD.Z.Z.XX1X2X5X5X5XwXwXiXnXCXGXGXFXFXSXAXT.s % @ HXHXHXHXHX", +"HXHXHXHXHXHXHX~ j -.0XrXzXxXzXzXzXzXwX3XXXXXOX1X2X5XpXmXAXFXGXGXGXFXFXSXL.r % O HXHXHXHXHXHX", +"HXHXHXHXHXHXHXHX! j / gXSXSXZXxXzXzXkXxXzXBXBXBXZXCXAXAXAXAXSXSXSXSXNX| 3 & O HXHXHXHXHXHXHX", +"HXHXHXHXHXHXHXHXHX} n V U.DXSXBXzXkXkXkXxXxXxXBXxXBXBXCXZXZXZXAXAXU.M < . @ HXHXHXHXHXHXHXHX", +"HXHXHXHXHXHXHXHXHXHXHXV d G Z.pXzXkXzXjXkXkXxXzXxXxXxXBXBXZXNXT.G 3 * . 9 HXHXHXHXHXHXHXHXHX", +"HXHXHXHXHXHXHXHXHXHXHXHX@.u s k -.K.6XhXjXhXkXlXzXzXzXeXOX9.k 3 = X O HXHXHXHXHXHXHXHXHXHXHX", +"HXHXHXHXHXHXHXHXHXHXHXHXHXHX..w < s j k K -.;.:.-./ C j 4 < & . O HXHXHXHXHXHXHXHXHXHXHXHXHX", +"HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXE * = - - < < - = & X . 0 HXHXHXHXHXHXHXHXHXHXHXHXHXHXHX", +"HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXi 7 7 @ o o O > 0 i HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHX" +}; diff --git a/xpm/check.xpm b/xpm/check.xpm new file mode 100644 index 0000000000..8f0b9d28ec --- /dev/null +++ b/xpm/check.xpm @@ -0,0 +1,41 @@ +/* XPM */ +static 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/xpm/send16.xpm b/xpm/send16.xpm new file mode 100644 index 0000000000..1eeceb4ec7 --- /dev/null +++ b/xpm/send16.xpm @@ -0,0 +1,278 @@ +/* XPM */ +static 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", +" 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", +" 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", +" Date: Thu, 5 Nov 2009 04:41:36 +0000 Subject: unix build merged in, bitmap resources from xpm instead of rc, better addr relay, better selection of addrs by time last seen for faster connect git-svn-id: https://bitcoin.svn.sourceforge.net/svnroot/bitcoin/trunk@32 1a98c847-1fd6-4fd8-948a-caf3550aa51b --- build-unix.txt | 73 ++++++++++++ build.txt | 88 -------------- db.cpp | 10 +- headers.h | 38 +++++-- irc.cpp | 16 +-- irc.h | 4 +- main.cpp | 68 +++++++---- main.h | 8 ++ makefile.unix | 86 ++++++++++++++ net.cpp | 177 ++++++++++++++-------------- net.h | 3 +- ui.cpp | 103 +++++++++-------- uibase.cpp | 10 +- uiproject.fbp | 10 +- util.cpp | 8 +- util.h | 40 +++++-- xpm/addressbook16.xpm | 278 ++++++++++++++++++++++++++++++++++++++++++++ xpm/addressbook20.xpm | 282 +++++++++++++++++++++++++++++++++++++++++++++ xpm/bitcoin.xpm | 304 +++++++++++++++++++++++++++++++++++++++++++++++++ xpm/check.xpm | 41 +++++++ xpm/send16.xpm | 278 ++++++++++++++++++++++++++++++++++++++++++++ xpm/send16noshadow.xpm | 278 ++++++++++++++++++++++++++++++++++++++++++++ xpm/send20.xpm | 282 +++++++++++++++++++++++++++++++++++++++++++++ 23 files changed, 2184 insertions(+), 301 deletions(-) create mode 100644 build-unix.txt delete mode 100644 build.txt create mode 100644 makefile.unix create mode 100644 xpm/addressbook16.xpm create mode 100644 xpm/addressbook20.xpm create mode 100644 xpm/bitcoin.xpm create mode 100644 xpm/check.xpm create mode 100644 xpm/send16.xpm create mode 100644 xpm/send16noshadow.xpm create mode 100644 xpm/send20.xpm diff --git a/build-unix.txt b/build-unix.txt new file mode 100644 index 0000000000..6b29e1e5c4 --- /dev/null +++ b/build-unix.txt @@ -0,0 +1,73 @@ +Bitcoin v0.2.0 BETA + +Copyright (c) 2009 Satoshi Nakamoto +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/). This product includes +cryptographic software written by Eric Young (eay@cryptsoft.com). + + +UNIX BUILD NOTES + + +Dependencies +------------ +apt-get install build-essential +apt-get install libgtk2.0-dev +apt-get install libssl-dev + +Libraries you need to obtain separately and build: + default path download +wxWidgets \wxwidgets http://www.wxwidgets.org/downloads/ +Berkeley DB \db http://www.oracle.com/technology/software/products/berkeley-db/index.html +Boost \boost http://www.boost.org/users/download/ + +Their licenses: +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 + +Versions used in this release: +GCC 4.3.3 +OpenSSL 0.9.8k +wxWidgets 2.8.9 +Berkeley DB 4.7.25.NC +Boost 1.40.0 + + +Notes +----- +The UI layout is edited with wxFormBuilder. Open the project file +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/wxWidgets-2.8.9 +mkdir buildgtk +cd buildgtk +../configure --with-gtk --enable-debug --disable-shared --enable-monolithic +make +su +make install +ldconfig + + +Berkeley DB +----------- +cd /usr/local/db-4.7.25.NC/build_unix +../dist/configure --enable-cxx +make + + +Boost +----- +cd /usr/local/boost_1_40_0 +su +./bootstrap.sh +./bjam install diff --git a/build.txt b/build.txt deleted file mode 100644 index 4368af855a..0000000000 --- a/build.txt +++ /dev/null @@ -1,88 +0,0 @@ -BitCoin v0.1.6 BETA - -Copyright (c) 2009 Satoshi Nakamoto -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/). This product includes -cryptographic software written by Eric Young (eay@cryptsoft.com). - - -Compilers Supported -------------------- -MinGW GCC (v3.4.5) -Microsoft Visual C++ 6.0 SP6 - - -Dependencies ------------- -Libraries you need to obtain separately to build: - - default path download -wxWidgets \wxwidgets http://www.wxwidgets.org/downloads/ - or prebuilt: http://wxpack.sourceforge.net -OpenSSL \openssl http://www.openssl.org/source/ -Berkeley DB \db http://www.oracle.com/technology/software/products/berkeley-db/index.html -Boost \boost http://www.boost.org/users/download/ - -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 - - -Notes ------ -The UI layout is edited with wxFormBuilder. Open the project file -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.exe" to strip the debug -symbols, which reduces the executable size by about 90%. - - -OpenSSL -------- -Bitcoin does not use any encryption. If you want to do a no-everything -build of OpenSSL to exclude encryption routines, a few patches are required. -(OpenSSL v0.9.8h) - -Edit engines\e_gmp.c and put this #ifndef around #include - #ifndef OPENSSL_NO_RSA - #include - #endif - -Add this to crypto\err\err_all.c before the ERR_load_crypto_strings line: - void ERR_load_RSA_strings(void) { } - -Edit ms\mingw32.bat and replace the Configure line's parameters with this -no-everything list. You have to put this in the batch file because batch -files can't take more than 9 command line parameters. - perl Configure mingw threads no-rc2 no-rc4 no-rc5 no-idea no-des no-bf no-cast no-aes no-camellia no-seed no-rsa no-dh - -Also REM out the following line in ms\mingw32.bat. The build fails after it's -already finished building libeay32, which is all we care about, but the -failure aborts the script before it runs dllwrap to generate libeay32.dll. - REM if errorlevel 1 goto end - -Build - ms\mingw32.bat - -If you want to use it with MSVC, generate the .lib file - lib /machine:i386 /def:ms\libeay32.def /out:out\libeay32.lib - - -Berkeley DB ------------ -Using MinGW and MSYS: -cd \db\build_unix -sh ../dist/configure --enable-mingw --enable-cxx -make - - -Boost ------ -If you have trouble compiling Boost with Microsoft Visual C++ 6.0, try going -back to Boost version 1.35. It looks like they may be starting to reduce -support for MSVC 6.0. diff --git a/db.cpp b/db.cpp index f9e25834d0..b702b0cbac 100644 --- a/db.cpp +++ b/db.cpp @@ -62,9 +62,9 @@ CDB::CDB(const char* pszFile, const char* pszMode, bool fTxn) : pdb(NULL) if (fShutdown) return; string strDataDir = GetDataDir(); - string strLogDir = strDataDir + "\\database"; + string strLogDir = strDataDir + "/database"; _mkdir(strLogDir.c_str()); - string strErrorFile = strDataDir + "\\db.log"; + string strErrorFile = strDataDir + "/db.log"; printf("dbenv.open strLogDir=%s strErrorFile=%s\n", strLogDir.c_str(), strErrorFile.c_str()); dbenv.set_lg_dir(strLogDir.c_str()); @@ -411,7 +411,6 @@ bool CAddrDB::WriteAddress(const CAddress& addr) bool CAddrDB::LoadAddresses() { - CRITICAL_BLOCK(cs_mapIRCAddresses) CRITICAL_BLOCK(cs_mapAddresses) { // Load user provided addresses @@ -425,10 +424,7 @@ bool CAddrDB::LoadAddresses() { CAddress addr(psz, NODE_NETWORK); if (addr.IsValid()) - { AddAddress(*this, addr); - mapIRCAddresses.insert(make_pair(addr.GetKey(), addr)); - } } } catch (...) { } @@ -678,7 +674,7 @@ void ThreadFlushWalletDB(void* parg) if (nRefCount == 0 && !fShutdown) { // Flush wallet.dat so it's self contained - nLastFlushed == nWalletDBUpdated; + nLastFlushed = nWalletDBUpdated; int64 nStart = GetTimeMillis(); dbenv.txn_checkpoint(0, 0, 0); dbenv.lsn_reset(strFile.c_str(), 0); diff --git a/headers.h b/headers.h index f00b7dde05..c7f3cd8514 100644 --- a/headers.h +++ b/headers.h @@ -17,16 +17,18 @@ #endif #define _WIN32_IE 0x0400 #define WIN32_LEAN_AND_MEAN 1 +#define __STDC_LIMIT_MACROS // to enable UINT64_MAX from stdint.h #include #include #include #include #include +#include #include #include #include #include -#include +#include #include #include #include @@ -50,22 +52,28 @@ #include #include #include -#include - +#include + #ifdef __WXMSW__ #include #include -#include +#include #include -#include -#include -#include -#else +#include +#include +#include +#else #include +#include #include -#include -#include -#endif +#include +#include +#include +#include +#include +#include +#include +#endif #pragma hdrstop using namespace std; @@ -88,3 +96,11 @@ using namespace boost; #include "market.h" #include "uibase.h" #include "ui.h" + +#include "xpm/addressbook16.xpm" +#include "xpm/addressbook20.xpm" +#include "xpm/bitcoin.xpm" +#include "xpm/check.xpm" +#include "xpm/send16.xpm" +#include "xpm/send16noshadow.xpm" +#include "xpm/send20.xpm" diff --git a/irc.cpp b/irc.cpp index f839dc5224..4d4ed0f414 100644 --- a/irc.cpp +++ b/irc.cpp @@ -4,10 +4,7 @@ #include "headers.h" - -map, CAddress> mapIRCAddresses; -CCriticalSection cs_mapIRCAddresses; - +int nGotIRCAddresses = 0; @@ -259,16 +256,7 @@ void ThreadIRCSeed(void* parg) CAddrDB addrdb; if (AddAddress(addrdb, addr)) printf("IRC got new address\n"); - else - { - // make it try connecting again - CRITICAL_BLOCK(cs_mapAddresses) - if (mapAddresses.count(addr.GetKey())) - mapAddresses[addr.GetKey()].nLastFailed = 0; - } - - CRITICAL_BLOCK(cs_mapIRCAddresses) - mapIRCAddresses.insert(make_pair(addr.GetKey(), addr)); + nGotIRCAddresses++; } else { diff --git a/irc.h b/irc.h index 91c3ffe686..c69fd9ee97 100644 --- a/irc.h +++ b/irc.h @@ -4,7 +4,5 @@ extern bool RecvLine(SOCKET hSocket, string& strLine); extern void ThreadIRCSeed(void* parg); -extern bool fRestartIRCSeed; -extern map, CAddress> mapIRCAddresses; -extern CCriticalSection cs_mapIRCAddresses; +extern int nGotIRCAddresses; diff --git a/main.cpp b/main.cpp index ade3b51c77..2119495e64 100644 --- a/main.cpp +++ b/main.cpp @@ -100,13 +100,10 @@ bool AddToWallet(const CWalletTx& wtxIn) if (fInsertedNew) wtx.nTimeReceived = GetAdjustedTime(); - //// debug print - printf("AddToWallet %s %s\n", wtxIn.GetHash().ToString().substr(0,6).c_str(), fInsertedNew ? "new" : "update"); - + bool fUpdated = false; if (!fInsertedNew) { // Merge - bool fUpdated = false; if (wtxIn.hashBlock != 0 && wtxIn.hashBlock != wtx.hashBlock) { wtx.hashBlock = wtxIn.hashBlock; @@ -128,13 +125,15 @@ bool AddToWallet(const CWalletTx& wtxIn) wtx.fSpent = wtxIn.fSpent; fUpdated = true; } - if (!fUpdated) - return true; } + //// debug print + printf("AddToWallet %s %s%s\n", wtxIn.GetHash().ToString().substr(0,6).c_str(), (fInsertedNew ? "new" : ""), (fUpdated ? "update" : "")); + // Write to disk - if (!wtx.WriteToDisk()) - return false; + if (fInsertedNew || fUpdated) + if (!wtx.WriteToDisk()) + return false; // Notify UI vWalletUpdated.push_back(hash); @@ -820,7 +819,7 @@ bool CTransaction::ConnectInputs(CTxDB& txdb, map& mapTestPoo } if (prevout.n >= txPrev.vout.size() || prevout.n >= txindex.vSpent.size()) - return error("ConnectInputs() : %s prevout.n out of range %d %d %d", GetHash().ToString().substr(0,6).c_str(), prevout.n, txPrev.vout.size(), txindex.vSpent.size()); + return error("ConnectInputs() : %s prevout.n out of range %d %d %d prev tx %s\n%s", GetHash().ToString().substr(0,6).c_str(), prevout.n, txPrev.vout.size(), txindex.vSpent.size(), prevout.hash.ToString().substr(0,6).c_str(), txPrev.ToString().c_str()); // If prev is coinbase, check that it's matured if (txPrev.IsCoinBase()) @@ -1217,7 +1216,7 @@ bool CBlock::AcceptBlock() if (nTime <= pindexPrev->GetMedianTimePast()) return error("AcceptBlock() : block's timestamp is too early"); - // Check that all transactions are finalized (starting around 30 Nov 2009) + // Check that all transactions are finalized (starting around Dec 2009) if (nBestHeight > 31000) // 25620 + 5320 foreach(const CTransaction& tx, vtx) if (!tx.IsFinal(nTime)) @@ -1384,7 +1383,7 @@ FILE* OpenBlockFile(unsigned int nFile, unsigned int nBlockPos, const char* pszM { if (nFile == -1) return NULL; - FILE* file = fopen(strprintf("%s\\blk%04d.dat", GetDataDir().c_str(), nFile).c_str(), pszMode); + FILE* file = fopen(strprintf("%s/blk%04d.dat", GetDataDir().c_str(), nFile).c_str(), pszMode); if (!file) return NULL; if (nBlockPos != 0 && !strchr(pszMode, 'a') && !strchr(pszMode, 'w')) @@ -1718,6 +1717,7 @@ bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) + if (strCommand == "version") { // Each connection can only send one version message @@ -1765,6 +1765,10 @@ bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) pfrom->fSuccessfullyConnected = true; + // Update the last seen time + if (pfrom->fNetworkNode) + AddressCurrentlyConnected(pfrom->addr); + printf("version message: version %d\n", pfrom->nVersion); } @@ -1781,23 +1785,16 @@ bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) vector vAddr; vRecv >> vAddr; - // Clear addrknown lists periodically to allow refresh broadcasts - static int64 nLastClearedAddrKnown; - if (nLastClearedAddrKnown < GetAdjustedTime() - 24 * 60 * 60) - { - nLastClearedAddrKnown = GetAdjustedTime(); - CRITICAL_BLOCK(cs_vNodes) - foreach(CNode* pnode, vNodes) - pnode->setAddrKnown.clear(); - } - // Store the new addresses CAddrDB addrdb; - foreach(const CAddress& addr, vAddr) + foreach(CAddress& addr, vAddr) { if (fShutdown) return true; - AddAddress(addrdb, addr); + addr.nTime = GetAdjustedTime(); + if (pfrom->fGetAddr) + addr.nTime -= 5 * 24 * 60 * 60; + AddAddress(addrdb, addr, false); pfrom->AddAddressKnown(addr); if (!pfrom->fGetAddr && addr.IsRoutable()) { @@ -1816,6 +1813,10 @@ bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) vector vInv; vRecv >> vInv; + // Update the last seen time for this node's address + if (pfrom->fNetworkNode) + AddressCurrentlyConnected(pfrom->addr); + CTxDB txdb("r"); foreach(const CInv& inv, vInv) { @@ -2099,6 +2100,25 @@ bool SendMessages(CNode* pto) if (pto->nVersion == 0) return true; + // Address refresh broadcast + static int64 nLastRebroadcast; + if (nLastRebroadcast < GetTime() - 24 * 60 * 60) // every 24 hours + { + nLastRebroadcast = GetTime(); + CRITICAL_BLOCK(cs_vNodes) + { + foreach(CNode* pnode, vNodes) + { + // Periodically clear setAddrKnown to allow refresh broadcasts + pnode->setAddrKnown.clear(); + + // Rebroadcast our address + if (addrLocalHost.IsRoutable() && !fUseProxy) + pnode->PushAddress(addrLocalHost); + } + } + } + // // Message: addr @@ -2187,7 +2207,7 @@ void GenerateBitcoins(bool fGenerate) } if (fGenerateBitcoins) { - int nProcessors = atoi(getenv("NUMBER_OF_PROCESSORS")); + int nProcessors = wxThread::GetCPUCount(); printf("%d processors\n", nProcessors); if (nProcessors < 1) nProcessors = 1; diff --git a/main.h b/main.h index a0258cf2ce..6d8f0ed87c 100644 --- a/main.h +++ b/main.h @@ -968,6 +968,14 @@ public: return error("CBlock::WriteToDisk() : ftell failed"); fileout << *this; + // Flush stdio buffers and commit to disk before returning + fflush(fileout); +#ifdef __WXMSW__ + _commit(_fileno(fileout)); +#else + fsync(fileno(fileout)); +#endif + return true; } diff --git a/makefile.unix b/makefile.unix new file mode 100644 index 0000000000..c62efc008f --- /dev/null +++ b/makefile.unix @@ -0,0 +1,86 @@ +# Copyright (c) 2009 Satoshi Nakamoto +# Distributed under the MIT/X11 software license, see the accompanying +# file license.txt or http://www.opensource.org/licenses/mit-license.php. + + +ifneq "$(BUILD)" "debug" +ifneq "$(BUILD)" "release" +BUILD=debug +endif +endif +ifeq "$(BUILD)" "debug" +D=d +DEBUGFLAGS=-g -D__WXDEBUG__ +endif + + + +INCLUDEPATHS=-I"/usr/include" \ + -I"/usr/local/boost_1_40_0" \ + -I"/usr/local/db-4.7.25.NC/build_unix" \ + -I"/usr/local/include/wx-2.8" \ + -I"/usr/local/lib/wx/include/gtk2-ansi-debug-static-2.8" + +LIBPATHS=-L"/usr/lib" \ + -L"/usr/local/lib" \ + -L"/usr/local/db-4.7.25.NC/build_unix" + +LIBS= \ + -Wl,-Bstatic -l boost_thread -l boost_system -l boost_filesystem -Wl,-Bdynamic \ + -Wl,-Bstatic -l db_cxx -l wx_gtk2$(D)-2.8 -Wl,-Bdynamic \ + -l crypto \ + -l gtk-x11-2.0 -l gthread-2.0 -l SM +WXDEFS=-D__WXGTK__ -DNOPCH +CFLAGS=-O0 -w -Wno-invalid-offsetof -Wformat $(DEBUGFLAGS) $(WXDEFS) $(INCLUDEPATHS) +HEADERS=headers.h util.h main.h serialize.h uint256.h key.h bignum.h script.h db.h base58.h + + + +all: bitcoin + + +headers.h.gch: headers.h $(HEADERS) net.h irc.h market.h uibase.h ui.h + g++ -c $(CFLAGS) -o $@ $< + +obj/util.o: util.cpp $(HEADERS) + g++ -c $(CFLAGS) -o $@ $< + +obj/script.o: script.cpp $(HEADERS) + g++ -c $(CFLAGS) -o $@ $< + +obj/db.o: db.cpp $(HEADERS) market.h + g++ -c $(CFLAGS) -o $@ $< + +obj/net.o: net.cpp $(HEADERS) net.h + g++ -c $(CFLAGS) -o $@ $< + +obj/main.o: main.cpp $(HEADERS) net.h market.h sha.h + g++ -c $(CFLAGS) -o $@ $< + +obj/market.o: market.cpp $(HEADERS) market.h + g++ -c $(CFLAGS) -o $@ $< + +obj/ui.o: ui.cpp $(HEADERS) net.h uibase.h ui.h market.h + g++ -c $(CFLAGS) -o $@ $< + +obj/uibase.o: uibase.cpp uibase.h + g++ -c $(CFLAGS) -o $@ $< + +obj/sha.o: sha.cpp sha.h + g++ -c $(CFLAGS) -O3 -o $@ $< + +obj/irc.o: irc.cpp $(HEADERS) + g++ -c $(CFLAGS) -o $@ $< + + + + +OBJS=obj/util.o obj/script.o obj/db.o obj/net.o obj/main.o obj/market.o \ + obj/ui.o obj/uibase.o obj/sha.o obj/irc.o + +bitcoin: headers.h.gch $(OBJS) + g++ $(CFLAGS) -o $@ $(LIBPATHS) $(OBJS) $(LIBS) + +clean: + -rm obj/* + -rm headers.h.gch diff --git a/net.cpp b/net.cpp index 8ccf48b819..c14061e7d3 100644 --- a/net.cpp +++ b/net.cpp @@ -3,7 +3,6 @@ // file license.txt or http://www.opensource.org/licenses/mit-license.php. #include "headers.h" -#include void ThreadMessageHandler2(void* parg); void ThreadSocketHandler2(void* parg); @@ -201,12 +200,14 @@ bool GetMyExternalIP(unsigned int& ipRet) -bool AddAddress(CAddrDB& addrdb, const CAddress& addr) +bool AddAddress(CAddrDB& addrdb, CAddress addr, bool fCurrentlyOnline) { if (!addr.IsRoutable()) return false; if (addr.ip == addrLocalHost.ip) return false; + if (fCurrentlyOnline) + addr.nTime = GetAdjustedTime(); CRITICAL_BLOCK(cs_mapAddresses) { map, CAddress>::iterator it = mapAddresses.find(addr.GetKey()); @@ -219,24 +220,47 @@ bool AddAddress(CAddrDB& addrdb, const CAddress& addr) } else { + bool fUpdated = false; CAddress& addrFound = (*it).second; if ((addrFound.nServices | addr.nServices) != addrFound.nServices) { // Services have been added addrFound.nServices |= addr.nServices; - addrdb.WriteAddress(addrFound); - return true; + fUpdated = true; + } + int64 nUpdateInterval = (fCurrentlyOnline ? 60 * 60 : 24 * 60 * 60); + if (addrFound.nTime < addr.nTime - nUpdateInterval) + { + // Periodically update most recently seen time + addrFound.nTime = addr.nTime; + fUpdated = true; } - else if (addrFound.nTime < GetAdjustedTime() - 24 * 60 * 60) + if (fUpdated) + addrdb.WriteAddress(addrFound); + } + } + return false; +} + +void AddressCurrentlyConnected(const CAddress& addr) +{ + CRITICAL_BLOCK(cs_mapAddresses) + { + // Only if it's been published already + map, CAddress>::iterator it = mapAddresses.find(addr.GetKey()); + if (it != mapAddresses.end()) + { + CAddress& addrFound = (*it).second; + int64 nUpdateInterval = 60 * 60; + if (addrFound.nTime < GetAdjustedTime() - nUpdateInterval) { // Periodically update most recently seen time addrFound.nTime = GetAdjustedTime(); + CAddrDB addrdb; addrdb.WriteAddress(addrFound); - return false; } } } - return false; } @@ -398,9 +422,14 @@ CNode* ConnectNode(CAddress addrConnect, int64 nTimeout) printf("connected %s\n", addrConnect.ToStringLog().c_str()); // Set to nonblocking - u_long nOne = 1; +#ifdef __WXMSW__ + u_long nOne = 1; if (ioctlsocket(hSocket, FIONBIO, &nOne) == SOCKET_ERROR) printf("ConnectSocket() : ioctlsocket nonblocking setting failed, error %d\n", WSAGetLastError()); +#else + if (fcntl(hSocket, F_SETFL, O_NONBLOCK) == SOCKET_ERROR) + printf("ConnectSocket() : fcntl nonblocking setting failed, error %d\n", errno); +#endif // Add node CNode* pnode = new CNode(hSocket, addrConnect, false); @@ -418,7 +447,7 @@ CNode* ConnectNode(CAddress addrConnect, int64 nTimeout) else { CRITICAL_BLOCK(cs_mapAddresses) - mapAddresses[addrConnect.GetKey()].nLastFailed = GetTime(); + mapAddresses[addrConnect.GetKey()].nLastFailed = GetAdjustedTime(); return NULL; } } @@ -432,7 +461,7 @@ void CNode::DoDisconnect() // If outbound and never got version message, mark address as failed if (!fInbound && !fSuccessfullyConnected) CRITICAL_BLOCK(cs_mapAddresses) - mapAddresses[addr.GetKey()].nLastFailed = GetTime(); + mapAddresses[addr.GetKey()].nLastFailed = GetAdjustedTime(); // All of a nodes broadcasts and subscriptions are automatically torn down // when it goes down, so a node has to stay up to keep its broadcast going. @@ -549,8 +578,8 @@ void ThreadSocketHandler2(void* parg) timeout.tv_sec = 0; timeout.tv_usec = 50000; // frequency to poll pnode->vSend - struct fd_set fdsetRecv; - struct fd_set fdsetSend; + fd_set fdsetRecv; + fd_set fdsetSend; FD_ZERO(&fdsetRecv); FD_ZERO(&fdsetSend); SOCKET hSocketMax = 0; @@ -599,7 +628,11 @@ void ThreadSocketHandler2(void* parg) if (FD_ISSET(hListenSocket, &fdsetRecv)) { struct sockaddr_in sockaddr; +#ifdef __WXMSW__ int len = sizeof(sockaddr); +#else + socklen_t len = sizeof(sockaddr); +#endif SOCKET hSocket = accept(hListenSocket, (struct sockaddr*)&sockaddr, &len); CAddress addr(sockaddr); if (hSocket == INVALID_SOCKET) @@ -765,14 +798,12 @@ void ThreadOpenConnections2(void* parg) } // Initiate network connections - int nTry = 0; - bool fIRCOnly = false; - const int nMaxConnections = 15; loop { // Wait vnThreadsRunning[1]--; Sleep(500); + const int nMaxConnections = 15; while (vNodes.size() >= nMaxConnections || vNodes.size() >= mapAddresses.size()) { CheckForShutdown(1); @@ -781,93 +812,55 @@ void ThreadOpenConnections2(void* parg) vnThreadsRunning[1]++; CheckForShutdown(1); - // - // The IP selection process is designed to limit vulnerability to address flooding. - // Any class C (a.b.c.?) has an equal chance of being chosen, then an IP is - // chosen within the class C. An attacker may be able to allocate many IPs, but - // they would normally be concentrated in blocks of class C's. They can hog the - // attention within their class C, but not the whole IP address space overall. - // A lone node in a class C will get as much attention as someone holding all 255 - // IPs in another class C. + // Choose an address to connect to based on most recently seen // + CAddress addrConnect; + int64 nBestTime = 0; + int64 nDelay = ((60 * 60) << vNodes.size()); + if (vNodes.size() >= 3) + nDelay *= 4; + if (nGotIRCAddresses > 0) + nDelay *= 100; + + // Do this here so we don't have to critsect vNodes inside mapAddresses critsect + set setConnected; + CRITICAL_BLOCK(cs_vNodes) + foreach(CNode* pnode, vNodes) + setConnected.insert(pnode->addr.ip); - // Every other try is with IRC addresses only - fIRCOnly = !fIRCOnly; - if (mapIRCAddresses.empty()) - fIRCOnly = false; - else if (nTry++ < 30 && vNodes.size() < nMaxConnections/2) - fIRCOnly = true; - - // Make a list of unique class C's - unsigned char pchIPCMask[4] = { 0xff, 0xff, 0xff, 0x00 }; - unsigned int nIPCMask = *(unsigned int*)pchIPCMask; - vector vIPC; - CRITICAL_BLOCK(cs_mapIRCAddresses) CRITICAL_BLOCK(cs_mapAddresses) { - vIPC.reserve(mapAddresses.size()); - unsigned int nPrev = 0; foreach(const PAIRTYPE(vector, CAddress)& item, mapAddresses) { const CAddress& addr = item.second; - if (!addr.IsIPv4()) - continue; - if (fIRCOnly && !mapIRCAddresses.count(item.first)) + if (!addr.IsIPv4() || !addr.IsValid() || setConnected.count(addr.ip)) continue; - // Taking advantage of mapAddresses being in sorted order, - // with IPs of the same class C grouped together. - unsigned int ipC = addr.ip & nIPCMask; - if (ipC != nPrev) - vIPC.push_back(nPrev = ipC); - } - } - if (vIPC.empty()) - continue; - - // Choose a random class C - unsigned int ipC = vIPC[GetRand(vIPC.size())]; + // Limit retry frequency + if (GetAdjustedTime() < addr.nLastFailed + nDelay) + continue; - // Organize all addresses in the class C by IP - map > mapIP; - CRITICAL_BLOCK(cs_mapIRCAddresses) - CRITICAL_BLOCK(cs_mapAddresses) - { - int64 nDelay = ((30 * 60) << vNodes.size()); - if (!fIRCOnly) - { - nDelay *= 2; - if (vNodes.size() >= 3) - nDelay *= 4; - if (!mapIRCAddresses.empty()) - nDelay *= 100; - } + // Try again only after all addresses had a first attempt + int64 nTime = addr.nTime; + if (addr.nLastFailed > addr.nTime) + nTime -= 365 * 24 * 60 * 60; - for (map, CAddress>::iterator mi = mapAddresses.lower_bound(CAddress(ipC, 0).GetKey()); - mi != mapAddresses.upper_bound(CAddress(ipC | ~nIPCMask, 0xffff).GetKey()); - ++mi) - { - const CAddress& addr = (*mi).second; - if (fIRCOnly && !mapIRCAddresses.count((*mi).first)) - continue; + // Randomize the order a little, putting the standard port first + nTime += GetRand(1 * 60 * 60); + if (addr.port != DEFAULT_PORT) + nTime -= 1 * 60 * 60; - int64 nRandomizer = (addr.nLastFailed * addr.ip * 7777U) % 20000; - if (GetTime() - addr.nLastFailed > nDelay * nRandomizer / 10000) - mapIP[addr.ip].push_back(addr); + if (nTime > nBestTime) + { + nBestTime = nTime; + addrConnect = addr; + } } } - if (mapIP.empty()) - continue; - - // Choose a random IP in the class C - map >::iterator mi = mapIP.begin(); - advance(mi, GetRand(mapIP.size())); - // Once we've chosen an IP, we'll try every given port before moving on - foreach(const CAddress& addrConnect, (*mi).second) - if (OpenNetworkConnection(addrConnect)) - break; + if (addrConnect.IsValid()) + OpenNetworkConnection(addrConnect); } } @@ -989,6 +982,7 @@ bool StartNode(string& strError) pnodeLocalHost = new CNode(INVALID_SOCKET, CAddress("127.0.0.1", nLocalServices)); strError = ""; +#ifdef __WXMSW__ // Sockets startup WSADATA wsadata; int ret = WSAStartup(MAKEWORD(2,2), &wsadata); @@ -998,6 +992,7 @@ bool StartNode(string& strError) printf("%s\n", strError.c_str()); return false; } +#endif // Get local host ip char pszHostName[255]; @@ -1029,10 +1024,14 @@ bool StartNode(string& strError) } // Set to nonblocking, incoming connections will also inherit this +#ifdef __WXMSW__ u_long nOne = 1; if (ioctlsocket(hListenSocket, FIONBIO, &nOne) == SOCKET_ERROR) +#else + if (fcntl(hListenSocket, F_SETFL, O_NONBLOCK) == SOCKET_ERROR) +#endif { - strError = strprintf("Error: Couldn't set properties on socket for incoming connections (ioctlsocket returned error %d)", WSAGetLastError()); + strError = strprintf("Error: Couldn't set properties on socket for incoming connections (error %d)", WSAGetLastError()); printf("%s\n", strError.c_str()); return false; } @@ -1041,7 +1040,7 @@ bool StartNode(string& strError) // IP address, and port for the socket that is being bound int nRetryLimit = 15; struct sockaddr_in sockaddr = addrLocalHost.GetSockAddr(); - if (bind(hListenSocket, (struct sockaddr*)&sockaddr, sizeof(sockaddr)) == SOCKET_ERROR) + if (::bind(hListenSocket, (struct sockaddr*)&sockaddr, sizeof(sockaddr)) == SOCKET_ERROR) { int nErr = WSAGetLastError(); if (nErr == WSAEADDRINUSE) @@ -1131,7 +1130,9 @@ bool StopNode() Sleep(50); // Sockets shutdown +#ifdef __WXMSW__ WSACleanup(); +#endif return true; } diff --git a/net.h b/net.h index 7716426f04..275a4cb88b 100644 --- a/net.h +++ b/net.h @@ -22,7 +22,8 @@ enum bool ConnectSocket(const CAddress& addrConnect, SOCKET& hSocketRet); bool GetMyExternalIP(unsigned int& ipRet); -bool AddAddress(CAddrDB& addrdb, const CAddress& addr); +bool AddAddress(CAddrDB& addrdb, CAddress addr, bool fCurrentlyOnline=true); +void AddressCurrentlyConnected(const CAddress& addr); CNode* FindNode(unsigned int ip); CNode* ConnectNode(CAddress addrConnect, int64 nTimeout=0); void AbandonRequests(void (*fn)(void*, CDataStream&), void* param1); diff --git a/ui.cpp b/ui.cpp index 9185b8159f..212548199f 100644 --- a/ui.cpp +++ b/ui.cpp @@ -260,7 +260,8 @@ void AddPendingReplyEvent3(void* pevthandler, CDataStream& vRecv) CDataStream GetStreamFromEvent(const wxCommandEvent& event) { wxString strData = event.GetString(); - return CDataStream(strData.begin(), strData.begin() + event.GetInt(), SER_NETWORK); + const char* pszBegin = strData.c_str(); + return CDataStream(pszBegin, pszBegin + event.GetInt(), SER_NETWORK); } @@ -288,20 +289,6 @@ CMainFrame::CMainFrame(wxWindow* parent) : CMainFrameBase(parent) SetIcon(wxICON(bitcoin)); ptaskbaricon = new CMyTaskBarIcon(); - // Init toolbar with transparency masked bitmaps - m_toolBar->ClearTools(); - - //// shouldn't have to do mask separately anymore, bitmap alpha support added in wx 2.8.9, - wxBitmap bmpSend(wxT("send20"), wxBITMAP_TYPE_RESOURCE); - bmpSend.SetMask(new wxMask(wxBitmap(wxT("send20mask"), wxBITMAP_TYPE_RESOURCE))); - m_toolBar->AddTool(wxID_BUTTONSEND, wxT("&Send Coins"), bmpSend, wxNullBitmap, wxITEM_NORMAL, wxEmptyString, wxEmptyString); - - wxBitmap bmpAddressBook(wxT("addressbook20"), wxBITMAP_TYPE_RESOURCE); - bmpAddressBook.SetMask(new wxMask(wxBitmap(wxT("addressbook20mask"), wxBITMAP_TYPE_RESOURCE))); - m_toolBar->AddTool(wxID_BUTTONRECEIVE, wxT("&Address Book"), bmpAddressBook, wxNullBitmap, wxITEM_NORMAL, wxEmptyString, wxEmptyString); - - m_toolBar->Realize(); - // Init column headers int nDateWidth = DateTimeStr(1229413914).size() * 6 + 8; if (!strstr(DateTimeStr(1229413914).c_str(), "2008")) @@ -909,15 +896,17 @@ void CMainFrame::OnPaintListCtrl(wxPaintEvent& event) { TRY_CRITICAL_BLOCK(cs_mapWallet) { - bool fInserted = false; + string strTop; + if (m_listCtrl->GetItemCount()) + strTop = (string)m_listCtrl->GetItemText(0); foreach(uint256 hash, vWalletUpdated) { map::iterator mi = mapWallet.find(hash); if (mi != mapWallet.end()) - fInserted |= InsertTransaction((*mi).second, false); + InsertTransaction((*mi).second, false); } vWalletUpdated.clear(); - if (fInserted) + if (m_listCtrl->GetItemCount() && strTop != (string)m_listCtrl->GetItemText(0)) m_listCtrl->ScrollList(0, INT_MAX); } } @@ -954,7 +943,9 @@ void CMainFrame::OnPaintListCtrl(wxPaintEvent& event) string strStatus = strprintf(" %d connections %d blocks %d transactions", vNodes.size(), nBestHeight + 1, nTransactionCount); m_statusBar->SetStatusText(strStatus, 2); +#ifdef __WXMSW__ m_listCtrl->OnPaint(event); +#endif } @@ -1407,7 +1398,7 @@ COptionsDialog::COptionsDialog(wxWindow* parent) : COptionsDialogBase(parent) m_checkBoxLimitProcessors->SetValue(fLimitProcessors); m_spinCtrlLimitProcessors->Enable(fLimitProcessors); m_spinCtrlLimitProcessors->SetValue(nLimitProcessors); - int nProcessors = atoi(getenv("NUMBER_OF_PROCESSORS")); + int nProcessors = wxThread::GetCPUCount(); if (nProcessors < 1) nProcessors = 999; m_spinCtrlLimitProcessors->SetRange(1, nProcessors); @@ -1549,17 +1540,11 @@ void COptionsDialog::OnButtonApply(wxCommandEvent& event) walletdb.WriteSetting("fMinimizeOnClose", fMinimizeOnClose); } - if (fUseProxy != m_checkBoxUseProxy->GetValue()) - { - fUseProxy = m_checkBoxUseProxy->GetValue(); - walletdb.WriteSetting("fUseProxy", fUseProxy); - } + fUseProxy = m_checkBoxUseProxy->GetValue(); + walletdb.WriteSetting("fUseProxy", fUseProxy); - if (addrProxy != GetProxyAddr()) - { - addrProxy = GetProxyAddr(); - walletdb.WriteSetting("addrProxy", addrProxy); - } + addrProxy = GetProxyAddr(); + walletdb.WriteSetting("addrProxy", addrProxy); } @@ -1608,10 +1593,8 @@ CSendDialog::CSendDialog(wxWindow* parent, const wxString& strAddress) : CSendDi //// todo: should add a display of your balance for convenience // Set Icon - wxBitmap bmpSend(wxT("send16"), wxBITMAP_TYPE_RESOURCE); - bmpSend.SetMask(new wxMask(wxBitmap(wxT("send16masknoshadow"), wxBITMAP_TYPE_RESOURCE))); wxIcon iconSend; - iconSend.CopyFromBitmap(bmpSend); + iconSend.CopyFromBitmap(wxBitmap(send16noshadow_xpm)); SetIcon(iconSend); wxCommandEvent event; @@ -2231,10 +2214,8 @@ CAddressBookDialog::CAddressBookDialog(wxWindow* parent, const wxString& strInit m_listCtrl->SetFocus(); // Set Icon - wxBitmap bmpAddressBook(wxT("addressbook16"), wxBITMAP_TYPE_RESOURCE); - bmpAddressBook.SetMask(new wxMask(wxBitmap(wxT("addressbook16mask"), wxBITMAP_TYPE_RESOURCE))); wxIcon iconAddressBook; - iconAddressBook.CopyFromBitmap(bmpAddressBook); + iconAddressBook.CopyFromBitmap(wxBitmap(addressbook16_xpm)); SetIcon(iconAddressBook); // Fill listctrl with address book data @@ -3345,7 +3326,7 @@ bool CMyApp::OnInit2() _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE); _CrtSetReportFile(_CRT_WARN, CreateFile("NUL", GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0)); #endif -#ifdef __WXDEBUG__ +#if defined(__WXMSW__) && defined(__WXDEBUG__) // Disable malfunctioning wxWidgets debug assertion g_isPainting = 10000; #endif @@ -3362,8 +3343,7 @@ bool CMyApp::OnInit2() " -gen=0\t\t Don't generate coins\n" " -min\t\t Start minimized\n" " -datadir=\t Specify data directory\n" - " -proxy=\t Connect through socks4 proxy,\n" - " \t\t e.g. -proxy=127.0.0.1:9050 to use TOR\n" + " -proxy=\t Connect through socks4 proxy\n" " -addnode=\t Add a node to connect to\n" " -connect=\t Connect only to the specified node\n" " -?\t\t This help message\n"; @@ -3386,6 +3366,8 @@ bool CMyApp::OnInit2() unsigned int nStart = GetTime(); loop { + // TODO: find out how to do this in Linux, or replace with wxWidgets commands +#ifdef __WXMSW__ // Show the previous instance and exit HWND hwndPrev = FindWindow("wxWindowClassNR", "Bitcoin"); if (hwndPrev) @@ -3395,6 +3377,7 @@ bool CMyApp::OnInit2() SetForegroundWindow(hwndPrev); return false; } +#endif if (GetTime() > nStart + 60) return false; @@ -3421,7 +3404,7 @@ bool CMyApp::OnInit2() fPrintToDebugger = true; printf("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"); - printf("Bitcoin version %d, Windows version %08x\n", VERSION, GetVersion()); + printf("Bitcoin version %d, OS version %s\n", VERSION, wxGetOsDescription().mb_str()); if (mapArgs.count("-dropmessages")) { @@ -3493,12 +3476,36 @@ bool CMyApp::OnInit2() return false; } + if (mapArgs.count("-printblock")) + { + string strMatch = mapArgs["-printblock"]; + int nFound = 0; + for (map::iterator mi = mapBlockIndex.begin(); mi != mapBlockIndex.end(); ++mi) + { + uint256 hash = (*mi).first; + if (strncmp(hash.ToString().c_str(), strMatch.c_str(), strMatch.size()) == 0) + { + CBlockIndex* pindex = (*mi).second; + CBlock block; + block.ReadFromDisk(pindex, true); + block.BuildMerkleTree(); + block.print(); + printf("\n"); + nFound++; + } + } + if (nFound == 0) + printf("No blocks matching %s were found\n", strMatch.c_str()); + OnExit(); + return false; + } + if (mapArgs.count("-gen")) { if (mapArgs["-gen"].empty()) fGenerateBitcoins = true; else - fGenerateBitcoins = atoi(mapArgs["-gen"].c_str()); + fGenerateBitcoins = (atoi(mapArgs["-gen"].c_str()) != 0); } if (mapArgs.count("-proxy")) @@ -3511,9 +3518,6 @@ bool CMyApp::OnInit2() OnExit(); return false; } - CWalletDB walletdb; - walletdb.WriteSetting("fUseProxy", fUseProxy); - walletdb.WriteSetting("addrProxy", addrProxy); } if (mapArgs.count("-addnode")) @@ -3522,6 +3526,7 @@ bool CMyApp::OnInit2() foreach(string strAddr, mapMultiArgs["-addnode"]) { CAddress addr(strAddr, NODE_NETWORK); + addr.nTime = 0; // so it won't relay unless successfully connected if (addr.IsValid()) AddAddress(addrdb, addr); } @@ -3559,7 +3564,11 @@ bool CMyApp::OnInit2() // // Tests // +#ifdef __WXMSW__ if (argc >= 2 && stricmp(argv[1], "-send") == 0) +#else + if (argc >= 2 && strcmp(argv[1], "-send") == 0) +#endif { int64 nValue = 1; if (argc >= 3) @@ -3646,7 +3655,8 @@ void CMyApp::OnFatalException() -typedef WINSHELLAPI BOOL WINAPI (*PSHGETSPECIALFOLDERPATHA)(HWND hwndOwner, LPSTR lpszPath, int nFolder, BOOL fCreate); +#ifdef __WXMSW__ +typedef WINSHELLAPI BOOL (WINAPI *PSHGETSPECIALFOLDERPATHA)(HWND hwndOwner, LPSTR lpszPath, int nFolder, BOOL fCreate); string MyGetSpecialFolderPath(int nFolder, bool fCreate) { @@ -3737,7 +3747,10 @@ void SetStartOnSystemStartup(bool fAutoStart) CoUninitialize(); } } - +#else +bool GetStartOnSystemStartup() { return false; } +void SetStartOnSystemStartup(bool fAutoStart) { } +#endif diff --git a/uibase.cpp b/uibase.cpp index b03e578bd8..bb564e9960 100644 --- a/uibase.cpp +++ b/uibase.cpp @@ -7,6 +7,10 @@ #include "uibase.h" +#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 ) @@ -60,8 +64,8 @@ CMainFrameBase::CMainFrameBase( wxWindow* parent, wxWindowID id, const wxString& m_toolBar->SetToolSeparation( 1 ); m_toolBar->SetFont( wxFont( wxNORMAL_FONT->GetPointSize(), 70, 90, 90, false, wxEmptyString ) ); - m_toolBar->AddTool( wxID_BUTTONSEND, wxT("&Send Coins"), wxBitmap( wxT("send20"), wxBITMAP_TYPE_RESOURCE ), wxNullBitmap, wxITEM_NORMAL, wxEmptyString, wxEmptyString ); - m_toolBar->AddTool( wxID_BUTTONRECEIVE, wxT("&Address Book"), wxBitmap( wxT("addressbook20"), wxBITMAP_TYPE_RESOURCE ), wxNullBitmap, wxITEM_NORMAL, wxEmptyString, wxEmptyString ); + m_toolBar->AddTool( wxID_BUTTONSEND, wxT("&Send Coins"), wxBitmap( send20_xpm ), wxNullBitmap, wxITEM_NORMAL, wxEmptyString, wxEmptyString ); + m_toolBar->AddTool( wxID_BUTTONRECEIVE, wxT("&Address Book"), wxBitmap( addressbook20_xpm ), wxNullBitmap, wxITEM_NORMAL, wxEmptyString, wxEmptyString ); m_toolBar->Realize(); m_statusBar = this->CreateStatusBar( 1, wxST_SIZEGRIP, wxID_ANY ); @@ -666,7 +670,7 @@ CSendDialogBase::CSendDialogBase( wxWindow* parent, wxWindowID id, const wxStrin bSizer47->Add( 0, 0, 1, wxEXPAND, 5 ); - m_bitmapCheckMark = new wxStaticBitmap( this, wxID_ANY, wxICON( check ), wxDefaultPosition, wxSize( 16,16 ), 0 ); + 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, wxT("Pay &To:"), wxDefaultPosition, wxSize( -1,-1 ), wxALIGN_RIGHT ); diff --git a/uiproject.fbp b/uiproject.fbp index 313e5aa6cc..7bce7349f5 100644 --- a/uiproject.fbp +++ b/uiproject.fbp @@ -225,7 +225,7 @@ - + 20,20 @@ -273,7 +273,7 @@ - send20; Load From Resource + xpm/send20.xpm; Load From File wxID_BUTTONSEND wxITEM_NORMAL &Send Coins @@ -287,7 +287,7 @@ - addressbook20; Load From Resource + xpm/addressbook20.xpm; Load From File wxID_BUTTONRECEIVE wxITEM_NORMAL &Address Book @@ -1685,7 +1685,7 @@ - + @@ -3699,7 +3699,7 @@ 0 - check; Load From Icon Resource [-1; -1] + xpm/check.xpm; Load From File 1 diff --git a/util.cpp b/util.cpp index 23b59f11f7..d2e624d676 100644 --- a/util.cpp +++ b/util.cpp @@ -38,8 +38,10 @@ public: ppmutexOpenSSL[i] = new wxMutex(); CRYPTO_set_locking_callback(locking_callback); +#ifdef __WXMSW__ // Seed random number generator with screen scrape and other hardware sources RAND_screen(); +#endif // Seed random number generator with performance counter RandAddSeed(); @@ -325,8 +327,8 @@ void ParseParameters(int argc, char* argv[]) pszValue = strchr(psz, '='); *pszValue++ = '\0'; } - strlwr(psz); #ifdef __WXMSW__ + _strlwr(psz); if (psz[0] == '/') psz[0] = '-'; #endif @@ -343,9 +345,13 @@ void ParseParameters(int argc, char* argv[]) void FormatException(char* pszMessage, std::exception* pex, const char* pszThread) { +#ifdef __WXMSW__ char pszModule[MAX_PATH]; pszModule[0] = '\0'; GetModuleFileName(NULL, pszModule, sizeof(pszModule)); +#else + const char* pszModule = wxStandardPaths::Get().GetExecutablePath().mb_str(); +#endif if (pex) snprintf(pszMessage, 1000, "EXCEPTION: %s \n%s \n%s in %s \n", typeid(*pex).name(), pex->what(), pszModule, pszThread); diff --git a/util.h b/util.h index 822a049ce7..3bc7c798a5 100644 --- a/util.h +++ b/util.h @@ -55,9 +55,34 @@ inline T& REF(const T& val) } #ifndef __WXMSW__ -#define closesocket(s) close(s) -#define INVALID_SOCKET (SOCKET)(~0) +#define _UI64_MAX UINT64_MAX +#define _I64_MAX INT64_MAX +#define WSAGetLastError() errno +#define WSAEWOULDBLOCK EWOULDBLOCK +#define WSAEMSGSIZE EMSGSIZE +#define WSAEINTR EINTR +#define WSAEINPROGRESS EINPROGRESS +#define WSAEADDRINUSE EADDRINUSE +#define closesocket(s) close(s) +#define INVALID_SOCKET (SOCKET)(~0) +#define SOCKET_ERROR -1 typedef u_int SOCKET; +#define _vsnprintf(a,b,c,d) vsnprintf(a,b,c,d) +#define strlwr(psz) to_lower(psz) +#define _strlwr(psz) to_lower(psz) +#define _mkdir(psz) filesystem::create_directory(psz) +#define MAX_PATH 1024 +#define Sleep(n) wxMilliSleep(n) +#define Beep(n1,n2) (0) +inline int _beginthread(void(*pfn)(void*), unsigned nStack, void* parg) { thread(bind(pfn, parg)); return 0; } +inline void _endthread() { pthread_exit(NULL); } +inline int GetCurrentThread() { return 0; } +// threads are processes on linux, so setpriority affects just the one thread +inline void SetThreadPriority(int nThread, int nPriority) { setpriority(PRIO_PROCESS, getpid(), nPriority); } +#define THREAD_PRIORITY_LOWEST PRIO_MIN +#define THREAD_PRIORITY_BELOW_NORMAL 2 +#define THREAD_PRIORITY_NORMAL 0 +#define THREAD_PRIORITY_ABOVE_NORMAL 0 #endif @@ -120,7 +145,7 @@ public: protected: wxMutex mutex; public: - explicit CCriticalSection() { } + explicit CCriticalSection() : mutex(wxMUTEX_RECURSIVE) { } ~CCriticalSection() { } void Enter() { mutex.Lock(); } void Leave() { mutex.Unlock(); } @@ -183,7 +208,7 @@ inline int OutputDebugStringF(const char* pszFormat, ...) // print to debug.log char pszFile[MAX_PATH+100]; GetDataDir(pszFile); - strlcat(pszFile, "\\debug.log", sizeof(pszFile)); + strlcat(pszFile, "/debug.log", sizeof(pszFile)); FILE* fileout = fopen(pszFile, "a"); if (fileout) { @@ -354,13 +379,6 @@ inline int64 GetTimeMillis() return wxGetLocalTimeMillis().GetValue(); } -#ifndef __WXMSW__ -inline void Sleep(unsigned int nMilliseconds) -{ - wxMilliSleep(nMilliseconds); -} -#endif - diff --git a/xpm/addressbook16.xpm b/xpm/addressbook16.xpm new file mode 100644 index 0000000000..471f700c70 --- /dev/null +++ b/xpm/addressbook16.xpm @@ -0,0 +1,278 @@ +/* XPM */ +static 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", +" 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/xpm/addressbook20.xpm b/xpm/addressbook20.xpm new file mode 100644 index 0000000000..48df12d801 --- /dev/null +++ b/xpm/addressbook20.xpm @@ -0,0 +1,282 @@ +/* XPM */ +static 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", +" > > > > > > > > > > > > > > > > > > > ", +"> > > > > > > > > > > > > > > > > > > > ", +"> > 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/xpm/bitcoin.xpm b/xpm/bitcoin.xpm new file mode 100644 index 0000000000..166d5aa6e4 --- /dev/null +++ b/xpm/bitcoin.xpm @@ -0,0 +1,304 @@ +/* XPM */ +static char * bitcoin_xpm[] = { +/* columns rows colors chars-per-pixel */ +"48 48 250 2", +" c #725203", +". c #795603", +"X c #7D5903", +"o c #76560B", +"O c #77590E", +"+ c #795A0D", +"@ c #7B5D14", +"# c #7C5F18", +"$ c #7D6019", +"% c #825D05", +"& c #856007", +"* c #86620B", +"= c #8B660B", +"- c #8E690E", +"; c #906A0F", +": c #8F6B17", +"> c #83641C", +", c #8D6C1E", +"< c #926C11", +"1 c #967014", +"2 c #997215", +"3 c #9C761B", +"4 c #9E791D", +"5 c #A37C1E", +"6 c #816520", +"7 c #876A25", +"8 c #8E6E22", +"9 c #866A29", +"0 c #896E2C", +"q c #8E7020", +"w c #937324", +"e c #997722", +"r c #9E7B25", +"t c #94762B", +"y c #967828", +"u c #9A7B2D", +"i c #8B7131", +"p c #9E7E31", +"a c #947839", +"s c #A37D22", +"d c #A68125", +"f c #AA8325", +"g c #AE8827", +"h c #A6832D", +"j c #AA852B", +"k c #AD892B", +"l c #B08727", +"z c #B28827", +"x c #B08729", +"c c #B38B2C", +"v c #B88E2F", +"b c #B8902D", +"n c #A38334", +"m c #A98632", +"M c #AB8A34", +"N c #A4873C", +"B c #A78A3D", +"V c #AC8B3C", +"C c #B38D32", +"Z c #BA8F30", +"A c #B28E3C", +"S c #B69332", +"D c #BC9433", +"F c #BF9832", +"G c #B4923C", +"H c #BA963D", +"J c #B7993E", +"K c #BE9A3B", +"L c #C1932F", +"P c #C39732", +"I c #C49935", +"U c #C59C3A", +"Y c #C99E3D", +"T c #C2A13F", +"R c #CDA23F", +"E c #9D8342", +"W c #AB8C43", +"Q c #B28E40", +"! c #AE9144", +"~ c #AE914A", +"^ c #B49445", +"/ c #BC9B44", +"( c #B3964D", +") c #B5994C", +"_ c #BD9B4A", +"` c #A98F50", +"' c #B19553", +"] c #B59A54", +"[ c #BD9F51", +"{ c #B59B5C", +"} c #B89D5C", +"| c #BEA155", +" . c #BDA35D", +".. c #B59C61", +"X. c #B99F66", +"o. c #BCA363", +"O. c #BDA56C", +"+. c #BCA571", +"@. c #BDA873", +"#. c #BFAA78", +"$. c #C49D43", +"%. c #C99F45", +"&. c #C29E4B", +"*. c #C5A144", +"=. c #CCA244", +"-. c #C5A44B", +";. c #CAA54B", +":. c #C8A84C", +">. c #D0A644", +",. c #D3AA44", +"<. c #D3AC4C", +"1. c #D8AD4D", +"2. c #DAB046", +"3. c #DCB24E", +"4. c #C3A454", +"5. c #CBA751", +"6. c #CCAA53", +"7. c #C1A65B", +"8. c #C8A75A", +"9. c #CBAC5B", +"0. c #D0A650", +"q. c #D2AC53", +"w. c #DAAD54", +"e. c #D3AD5C", +"r. c #CFB259", +"t. c #D4B156", +"y. c #DDB454", +"u. c #D4B25C", +"i. c #DAB65A", +"p. c #D7B95F", +"a. c #DEBA5E", +"s. c #E2B555", +"d. c #E5BA53", +"f. c #E1B55A", +"g. c #E5BC5C", +"h. c #EABF5D", +"j. c #C1A761", +"k. c #C4AA63", +"l. c #CBAE63", +"z. c #CBB166", +"x. c #CBB26C", +"c. c #D4B263", +"v. c #DAB462", +"b. c #D6B864", +"n. c #DCB965", +"m. c #D3B669", +"M. c #DCB768", +"N. c #D4BA6E", +"B. c #DCBB6C", +"V. c #CDB672", +"C. c #D2B972", +"Z. c #DBBE72", +"A. c #E4BC62", +"S. c #E9BE62", +"D. c #E2BD6C", +"F. c #E0BF72", +"G. c #E6C05E", +"H. c #EFC05D", +"J. c #F0C15B", +"K. c #DFC167", +"L. c #D7C069", +"P. c #DDC36D", +"I. c #DBC376", +"U. c #D4C17B", +"Y. c #DAC17B", +"T. c #D8C878", +"R. c #E4C362", +"E. c #EBC364", +"W. c #E3C865", +"Q. c #EDC866", +"!. c #E4C36A", +"~. c #E9C66B", +"^. c #ECCA6B", +"/. c #F1C564", +"(. c #F8C765", +"). c #F5CB66", +"_. c #F8CC67", +"`. c #F6CC6A", +"'. c #F9CD6B", +"]. c #EED26A", +"[. c #F2D06F", +"{. c #FBD26D", +"}. c #E4C374", +"|. c #EBC474", +" X c #E1C972", +".X c #EDCD72", +"XX c #E4C57A", +"oX c #E9C67C", +"OX c #E5C87C", +"+X c #EACA7D", +"@X c #F2CC74", +"#X c #FBCF71", +"$X c #EED174", +"%X c #ECD37B", +"&X c #F4D274", +"*X c #FDD473", +"=X c #FFD975", +"-X c #F4D57C", +";X c #FCD57A", +":X c #F3DA7C", +">X c #FEDB7C", +",X c #FFE37D", +"X=XQ.s.=.v 5 1 < E HXHXHXHXHXHXHXHXHXHXHXHXHXHX", +"HXHXHXHXHXHXHXHXHXHXHX' g f F d.).).{.{.=X=X=X{.{.{.`.`.`.).g.U f 2 * a HXHXHXHXHXHXHXHXHXHXHXHX", +"HXHXHXHXHXHXHXHXHXHXV f b G.J.{.{.{.*X=X,X=X*X{.`.).`.).).{.`.{./.U 5 ; + HXHXHXHXHXHXHXHXHXHXHX", +"HXHXHXHXHXHXHXHX} h g 1.)._._.{.,X*X=X,X{.{.)._.).).`.`.`.{.*X*X*X`.y.g 2 & $ HXHXHXHXHXHXHXHXHX", +"HXHXHXHXHXHXHX{ j c G.).{.{.{.=X,X{.{.J.d.2.R 2.,.3.g.`.&X;X;X;X&X[.{.`.I 3 & + HXHXHXHXHXHXHXHX", +"HXHXHXHXHXHX{ d D /.{.{.*X=X=X*X).3.R I I I P F F U $.;.n.-XrXrX;X&X;X>XdX:.4 X o HXHXHXHXHXHXHX", +"HXHXHXHXHX..j v /.*X=X=X=X=X`.1.R R R R I I I P K U *.e.D.|.}.+XrXqXhXhXdXfX:.4 X o HXHXHXHXHXHX", +"HXHXHXHXHXh v `.{.>X,X*X{.g.>.Y R I I I I I I U U ;.t.D.|.oXB.z.F.kXvXcXjXjXjX/ 1 . + HXHXHXHXHX", +"HXHXHXHXV g Q.=X=X>X>X'.>.Y Y U R I I I P P I U U <.n.~.}.F.XXXX}.%XbXbXcXcXcXsXc = # HXHXHXHX", +"HXHXHX} j t.>X>X>X*X'.>.U U I U P U U I P P I U T 6.M.D.oX5XwXeXeXqX0XvXbXbXcXjXW.5 % HXHXHXHX", +"HXHXHXM G hXhXqX>X*X<.U U U I I I I I I D D U T T -.9.B.3XpXpXzXgXqX:X:XbXbXcXjXfXT < o HXHXHX", +"HXHX} k XlXkXkXrXA.$.D Z Z Z v v v b b v D U U *.-.9.B.OX2XOXI.P.L.K.W.$XbXcXjX,X].d % 9 HXHX", +"HXHXV J xXxXxXxXrX5.&.A M m m m h h n s 5 g S K *.:.8.4.| k.x.C.N.z.7.) :.$XjXfX,X,XT ; o HXHX", +"HXHXM L.vXxXxXxXF._ MXCXCXCXCXCXCXCXCXmXY.h g K *./ ^ Y.mXCXCXCXCXCXCXVXZ.4.hXfX,X,XW.4 X HXHX", +"HX] k gXxXxXxXgXe.V MXCXCXCXCXVXCXCXCXCXCXyXh D G [ mXCXCXCXCXCXCXCXCXCX4XG ~.fX,X,X,Xg & $ HX", +"HXV J vXxXxXxX6Xe.V MXCXCXCXCXk.N VXCXCXCXVX| h ^ MXCXCXCXCXuX( n V l.mX4XA y.fX,X,X=XT ; HX", +"HXk r.xXxXxXxX|.v.V MXCXCXCXCXo.> 4XCXCXCXCXx.w tXCXCXCXCXnXn V / / M V m.&.t.=X,X,X=Xy.2 o HX", +"HXk P.xXvXxXxX|.M.Q nXCXCXCXCXj.w X>X=XH.5 X $ ", +"o.k %XvXbXBXkX|.D.Q nXCXCXCXCXj., 7XCXCXCXCX~ k.CXCXCXCXCXV &.n.R.g.G.g.S.S.S.(.qX*X=X`.5 X $ ", +" .k 0XvXvXvXrX@XD.^ VXCXCXCXCXx.~ VXCXCXCXX=X*X*Xd X $ ", +"{ k sXcXvXBXeX@XD.( nXCXCXCXCXCXCXCXCXVXo., u T.CXCXCXVXmXn t.E.g.g.h.S.g.S.f.A.>X;X*X*Xf & o ", +"{ k sXjXlXcX0X~.n.^ MXCXCXCXCXCXCXCXCXCXCXU.t U.CXCXCXCXmXM p.~.W.g.s.s.s.s.f.A.>X*X*X*Xj % ", +"o.k :XjXlXlX-XD.v.A MXCXCXCXCXj.t mXCXCXCXCX .x.CXCXCXCXVXV p.$X^.E.g.s.w.w.w.A.9X;X*X*Xf X ", +"o.g ].dXjXhX-Xn.e.V MXCXCXCXCXj.8 X*X#X5 X O ", +"HXj K.dXdXhX9Xv.9.M MXCXCXCXCXk.a Z.CXCXCXCX7Xu CXCXCXCXCXV./ !.$X~.f.5.%.0.q.S.>X*X*XE.5 X # ", +"HXj t.dX,XdXdXi.6.N MXCXCXCXCXo.q XqXqXqX!.6.m MXCXCXCXCXV.' VXCXCXZXCXk.! ] VXCXCXCXCXVXC.[ 7.Z.VX2Xx %.#X#X'.'.%.- o 6 ", +"HX( g &X>X>XdX-X5.M MXCXCXCXCXCXCXCXCXCXCX7X) m.9. .MXCXCXCXCXCXCXCXCXCX2Xs 1.'.`.'.'.x % HX", +"HXO.j y.>X>X>X>X6.! zXMXMXMXMXMXMXMXMXuXx.( N.8X6Xz.) C.uXCXCXCXCXCXVX7X4.c h.'.(.(.s.5 X HX", +"HXHXj H &X=X:X>X~./ V h y u n n n N W ( 7.Z.8XpXpX+Xm.| V V ^ ) ( m e 3 s R (.(.'.'.Y ; . > HX", +"HXHX} f G.&X&X&X:Xt._ / ) _ 4.8.l.m.B.Z.2XwXpXeXwX6X+XP.c.8.-./ C x x z P J.(.'.(./.5 % HXHX", +"HXHXHXh D &X&X&X&X@X:.4.5.9.c.m.F.OX+XwXwXwXwX6X3XOX}.D.D.v.w.%.Y I P P d.(.(.'.'.=.< . + HXHX", +"HXHXHX] d y.[.&X&X&X~.:.4.9.e.M.B.}.oX3X5X3X3X+X}.F.M.e.0.0.0.%.%.Y Y s.#X#X#X#XS.s % HXHXHX", +"HXHXHXHXm g `.@X&X&X&X~.5.6.e.b.B.}.XX+X3XOX}.I.F.F.D.e.e.e.e.e.q.0.A.;X;X#X-X@XZ = o + HXHXHX", +"HXHXHXHX..j D @X&X&X&X&X@Xp.u.M.D.}.XXOXOXZ.Z.XX1XOXoXoXF.F.F.M.D.6XrXqX9X9X9X%.1 . HXHXHXHX", +"HXHXHXHXHX' f $.&X&X&X>XqXqX XB.D.!.XXXXZ.XXOX5XwXwXwXwXiXwXwXnXVXZXBXxXzXxXb.r X $ HXHXHXHX", +"HXHXHXHXHXHX~ j ;.qXqXqXqXrXkXrX+XD.Z.Z.XX1X2X5X5X5XwXwXiXnXCXGXGXFXFXSXAXT.s % @ HXHXHXHXHX", +"HXHXHXHXHXHXHX~ j -.0XrXzXxXzXzXzXzXwX3XXXXXOX1X2X5XpXmXAXFXGXGXGXFXFXSXL.r % O HXHXHXHXHXHX", +"HXHXHXHXHXHXHXHX! j / gXSXSXZXxXzXzXkXxXzXBXBXBXZXCXAXAXAXAXSXSXSXSXNX| 3 & O HXHXHXHXHXHXHX", +"HXHXHXHXHXHXHXHXHX} n V U.DXSXBXzXkXkXkXxXxXxXBXxXBXBXCXZXZXZXAXAXU.M < . @ HXHXHXHXHXHXHXHX", +"HXHXHXHXHXHXHXHXHXHXHXV d G Z.pXzXkXzXjXkXkXxXzXxXxXxXBXBXZXNXT.G 3 * . 9 HXHXHXHXHXHXHXHXHX", +"HXHXHXHXHXHXHXHXHXHXHXHX@.u s k -.K.6XhXjXhXkXlXzXzXzXeXOX9.k 3 = X O HXHXHXHXHXHXHXHXHXHXHX", +"HXHXHXHXHXHXHXHXHXHXHXHXHXHX..w < s j k K -.;.:.-./ C j 4 < & . O HXHXHXHXHXHXHXHXHXHXHXHXHX", +"HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXE * = - - < < - = & X . 0 HXHXHXHXHXHXHXHXHXHXHXHXHXHXHX", +"HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXi 7 7 @ o o O > 0 i HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHX" +}; diff --git a/xpm/check.xpm b/xpm/check.xpm new file mode 100644 index 0000000000..8f0b9d28ec --- /dev/null +++ b/xpm/check.xpm @@ -0,0 +1,41 @@ +/* XPM */ +static 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/xpm/send16.xpm b/xpm/send16.xpm new file mode 100644 index 0000000000..1eeceb4ec7 --- /dev/null +++ b/xpm/send16.xpm @@ -0,0 +1,278 @@ +/* XPM */ +static 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", +" 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", +" 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", +" Date: Fri, 6 Nov 2009 05:50:05 +0000 Subject: got rid of CheckForShutdown, replaced some thread-unsafe wxWidgets calls, Linux fixes, socket send MSG_NOSIGNAL, bind INADDR_ANY, works reliably on Linux now except if wxMessageBox is used in a thread other than the GUI thread --- db.cpp | 2 +- irc.cpp | 9 ++- main.cpp | 67 ++++++++++++-------- main.h | 2 +- net.cpp | 193 +++++++++++++++++++++++++++++++--------------------------- net.h | 2 +- ui.cpp | 63 +++++++++++++++---- ui.h | 3 +- uibase.cpp | 60 ++---------------- uiproject.fbp | 68 ++++++++++----------- util.cpp | 12 ++-- util.h | 14 ++++- 12 files changed, 260 insertions(+), 235 deletions(-) diff --git a/db.cpp b/db.cpp index b702b0cbac..1235592631 100644 --- a/db.cpp +++ b/db.cpp @@ -550,7 +550,7 @@ bool CWalletDB::LoadWallet(vector& vchDefaultKeyRet) //printf("LoadWallet %s\n", wtx.GetHash().ToString().c_str()); //printf(" %12I64d %s %s %s\n", // wtx.vout[0].nValue, - // DateTimeStr(wtx.nTime).c_str(), + // DateTimeStrFormat("%x %H:%M:%S", wtx.nTime).c_str(), // wtx.hashBlock.ToString().substr(0,14).c_str(), // wtx.mapValue["message"].c_str()); } diff --git a/irc.cpp b/irc.cpp index 4d4ed0f414..3b232caead 100644 --- a/irc.cpp +++ b/irc.cpp @@ -167,9 +167,12 @@ void ThreadIRCSeed(void* parg) while (!fShutdown) { CAddress addrConnect("216.155.130.130:6667"); - struct hostent* phostent = gethostbyname("chat.freenode.net"); - if (phostent && phostent->h_addr_list && phostent->h_addr_list[0]) - addrConnect = CAddress(*(u_long*)phostent->h_addr_list[0], htons(6667)); + if (!(fUseProxy && addrProxy.port == htons(9050))) + { + struct hostent* phostent = gethostbyname("chat.freenode.net"); + if (phostent && phostent->h_addr_list && phostent->h_addr_list[0]) + addrConnect = CAddress(*(u_long*)phostent->h_addr_list[0], htons(6667)); + } SOCKET hSocket; if (!ConnectSocket(addrConnect, hSocket)) diff --git a/main.cpp b/main.cpp index 2119495e64..cc22bad679 100644 --- a/main.cpp +++ b/main.cpp @@ -1361,15 +1361,24 @@ bool ScanMessageStart(Stream& s) bool CheckDiskSpace(int64 nAdditionalBytes) { - wxLongLong nFreeBytesAvailable = 0; - if (!wxGetDiskSpace(GetDataDir(), NULL, &nFreeBytesAvailable)) - { - printf("ERROR: wxGetDiskSpace() failed\n"); +#ifdef __WXMSW__ + uint64 nFreeBytesAvailable = 0; // bytes available to caller + uint64 nTotalNumberOfBytes = 0; // bytes on disk + uint64 nTotalNumberOfFreeBytes = 0; // free bytes on disk + if (!GetDiskFreeSpaceEx(GetDataDir().c_str(), + (PULARGE_INTEGER)&nFreeBytesAvailable, + (PULARGE_INTEGER)&nTotalNumberOfBytes, + (PULARGE_INTEGER)&nTotalNumberOfFreeBytes)) + { + printf("ERROR: GetDiskFreeSpaceEx() failed\n"); return true; } +#else + uint64 nFreeBytesAvailable = filesystem::space(GetDataDir()).available; +#endif // Check for 15MB because database could create another 10MB log file at any time - if (nFreeBytesAvailable.GetValue() < (int64)15000000 + nAdditionalBytes) + if (nFreeBytesAvailable < (int64)15000000 + nAdditionalBytes) { fShutdown = true; wxMessageBox("Warning: Your disk space is low ", "Bitcoin", wxICON_EXCLAMATION); @@ -1546,7 +1555,7 @@ void PrintBlockTree() pindex->nFile, pindex->nBlockPos, block.GetHash().ToString().substr(0,14).c_str(), - DateTimeStr(block.nTime).c_str(), + DateTimeStrFormat("%x %H:%M:%S", block.nTime).c_str(), block.vtx.size()); CRITICAL_BLOCK(cs_mapWallet) @@ -1673,20 +1682,24 @@ bool ProcessMessages(CNode* pfrom) bool fRet = false; try { - CheckForShutdown(2); CRITICAL_BLOCK(cs_main) fRet = ProcessMessage(pfrom, strCommand, vMsg); - CheckForShutdown(2); + if (fShutdown) + return true; } - catch (std::ios_base::failure& e) { + catch (std::ios_base::failure& e) + { if (strstr(e.what(), "CDataStream::read() : end of data")) { // Allow exceptions from underlength message on vRecv printf("ProcessMessage(%s, %d bytes) : Exception '%s' caught, normally caused by a message being shorter than its stated length\n", strCommand.c_str(), nMessageSize, e.what()); } else + { PrintException(&e, "ProcessMessage()"); - } catch (std::exception& e) { + } + } + catch (std::exception& e) { PrintException(&e, "ProcessMessage()"); } catch (...) { PrintException(NULL, "ProcessMessage()"); @@ -2093,7 +2106,6 @@ bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) bool SendMessages(CNode* pto) { - CheckForShutdown(2); CRITICAL_BLOCK(cs_main) { // Don't send anything until we get their version message @@ -2223,12 +2235,10 @@ void GenerateBitcoins(bool fGenerate) void ThreadBitcoinMiner(void* parg) { - vnThreadsRunning[3]++; - CheckForShutdown(3); try { - bool fRet = BitcoinMiner(); - printf("BitcoinMiner returned %s\n", fRet ? "true" : "false"); + vnThreadsRunning[3]++; + BitcoinMiner(); vnThreadsRunning[3]--; } catch (std::exception& e) { @@ -2238,6 +2248,8 @@ void ThreadBitcoinMiner(void* parg) vnThreadsRunning[3]--; PrintException(NULL, "ThreadBitcoinMiner()"); } + + printf("ThreadBitcoinMiner exiting, %d threads remaining\n", vnThreadsRunning[3]); } int FormatHashBlocks(void* pbuffer, unsigned int len) @@ -2285,7 +2297,7 @@ void BlockSHA256(const void* pin, unsigned int nBlocks, void* pout) } -bool BitcoinMiner() +void BitcoinMiner() { printf("BitcoinMiner started\n"); @@ -2296,11 +2308,13 @@ bool BitcoinMiner() { SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_LOWEST); Sleep(50); - CheckForShutdown(3); + if (fShutdown) + return; while (vNodes.empty()) { Sleep(1000); - CheckForShutdown(3); + if (fShutdown) + return; } unsigned int nTransactionsUpdatedLast = nTransactionsUpdated; @@ -2324,7 +2338,7 @@ bool BitcoinMiner() // auto_ptr pblock(new CBlock()); if (!pblock.get()) - return false; + return; // Add our coinbase tx as first transaction pblock->vtx.push_back(txNew); @@ -2433,7 +2447,7 @@ bool BitcoinMiner() { // Save key if (!AddKey(key)) - return false; + return; key.MakeNewKey(); // Process this block the same as if we had received it from another node @@ -2450,7 +2464,12 @@ bool BitcoinMiner() // Update nTime every few seconds if ((++tmp.block.nNonce & 0xffff) == 0) { - CheckForShutdown(3); + if (fShutdown) + return; + if (!fGenerateBitcoins) + return; + if (fLimitProcessors && vnThreadsRunning[3] > nLimitProcessors) + return; if (tmp.block.nNonce == 0) break; if (pindexPrev != pindexBest) @@ -2459,16 +2478,10 @@ bool BitcoinMiner() break; if (vNodes.empty()) break; - if (!fGenerateBitcoins) - return true; - if (fLimitProcessors && vnThreadsRunning[3] > nLimitProcessors) - return true; tmp.block.nTime = pblock->nTime = max(pindexPrev->GetMedianTimePast()+1, GetAdjustedTime()); } } } - - return true; } diff --git a/main.h b/main.h index 6d8f0ed87c..16b8c6a3d6 100644 --- a/main.h +++ b/main.h @@ -68,7 +68,7 @@ bool CommitTransactionSpent(const CWalletTx& wtxNew, const CKey& key); bool SendMoney(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew); void GenerateBitcoins(bool fGenerate); void ThreadBitcoinMiner(void* parg); -bool BitcoinMiner(); +void BitcoinMiner(); diff --git a/net.cpp b/net.cpp index c14061e7d3..44a75a177f 100644 --- a/net.cpp +++ b/net.cpp @@ -48,6 +48,10 @@ bool ConnectSocket(const CAddress& addrConnect, SOCKET& hSocketRet) SOCKET hSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (hSocket == INVALID_SOCKET) return false; +#if defined(__BSD__) || defined(__WXOSX__) + int set = 1; + setsockopt(hSocket, SOL_SOCKET, SO_NOSIGPIPE, (void*)&set, sizeof(int)); +#endif bool fRoutable = !(addrConnect.GetByte(3) == 10 || (addrConnect.GetByte(3) == 192 && addrConnect.GetByte(2) == 168)); bool fProxy = (fUseProxy && fRoutable); @@ -68,7 +72,7 @@ bool ConnectSocket(const CAddress& addrConnect, SOCKET& hSocketRet) char* pszSocks4 = pszSocks4IP; int nSize = sizeof(pszSocks4IP); - int ret = send(hSocket, pszSocks4, nSize, 0); + int ret = send(hSocket, pszSocks4, nSize, MSG_NOSIGNAL); if (ret != nSize) { closesocket(hSocket); @@ -100,7 +104,7 @@ bool GetMyExternalIP2(const CAddress& addrConnect, const char* pszGet, const cha if (!ConnectSocket(addrConnect, hSocket)) return error("GetMyExternalIP() : connection to %s failed", addrConnect.ToString().c_str()); - send(hSocket, pszGet, strlen(pszGet), 0); + send(hSocket, pszGet, strlen(pszGet), MSG_NOSIGNAL); string strLine; while (RecvLine(hSocket, strLine)) @@ -124,7 +128,8 @@ bool GetMyExternalIP2(const CAddress& addrConnect, const char* pszGet, const cha if (strLine.find("<")) strLine = strLine.substr(0, strLine.find("<")); strLine = strLine.substr(strspn(strLine.c_str(), " \t\n\r")); - strLine = wxString(strLine).Trim(); + while (strLine.size() > 0 && isspace(strLine[strLine.size()-1])) + strLine.resize(strLine.size()-1); CAddress addr(strLine.c_str()); printf("GetMyExternalIP() received [%s] %s\n", strLine.c_str(), addr.ToString().c_str()); if (addr.ip == 0 || addr.ip == INADDR_NONE || !addr.IsRoutable()) @@ -492,24 +497,26 @@ void ThreadSocketHandler(void* parg) { IMPLEMENT_RANDOMIZE_STACK(ThreadSocketHandler(parg)); - loop + try { vnThreadsRunning[0]++; - CheckForShutdown(0); - try - { - ThreadSocketHandler2(parg); - vnThreadsRunning[0]--; - } - catch (std::exception& e) { - vnThreadsRunning[0]--; - PrintException(&e, "ThreadSocketHandler()"); - } catch (...) { - vnThreadsRunning[0]--; - PrintException(NULL, "ThreadSocketHandler()"); - } - Sleep(5000); + ThreadSocketHandler2(parg); + vnThreadsRunning[0]--; } + catch (std::exception& e) { + vnThreadsRunning[0]--; + PrintException(&e, "ThreadSocketHandler()"); + } catch (...) { + vnThreadsRunning[0]--; + PrintException(NULL, "ThreadSocketHandler()"); + } + + foreach(CNode* pnode, vNodes) + closesocket(pnode->hSocket); + if (closesocket(hListenSocket) == SOCKET_ERROR) + printf("closesocket(hListenSocket) failed with error %d\n", WSAGetLastError()); + + printf("ThreadSocketHandler exiting\n"); } void ThreadSocketHandler2(void* parg) @@ -600,7 +607,8 @@ void ThreadSocketHandler2(void* parg) vnThreadsRunning[0]--; int nSelect = select(hSocketMax + 1, &fdsetRecv, &fdsetSend, NULL, &timeout); vnThreadsRunning[0]++; - CheckForShutdown(0); + if (fShutdown) + return; if (nSelect == SOCKET_ERROR) { int nErr = WSAGetLastError(); @@ -659,7 +667,8 @@ void ThreadSocketHandler2(void* parg) vNodesCopy = vNodes; foreach(CNode* pnode, vNodesCopy) { - CheckForShutdown(0); + if (fShutdown) + return; SOCKET hSocket = pnode->hSocket; // @@ -708,7 +717,7 @@ void ThreadSocketHandler2(void* parg) CDataStream& vSend = pnode->vSend; if (!vSend.empty()) { - int nBytes = send(hSocket, &vSend[0], vSend.size(), 0); + int nBytes = send(hSocket, &vSend[0], vSend.size(), MSG_NOSIGNAL); if (nBytes > 0) { vSend.erase(vSend.begin(), vSend.begin() + nBytes); @@ -747,24 +756,21 @@ void ThreadOpenConnections(void* parg) { IMPLEMENT_RANDOMIZE_STACK(ThreadOpenConnections(parg)); - loop + try { vnThreadsRunning[1]++; - CheckForShutdown(1); - try - { - ThreadOpenConnections2(parg); - vnThreadsRunning[1]--; - } - catch (std::exception& e) { - vnThreadsRunning[1]--; - PrintException(&e, "ThreadOpenConnections()"); - } catch (...) { - vnThreadsRunning[1]--; - PrintException(NULL, "ThreadOpenConnections()"); - } - Sleep(5000); + ThreadOpenConnections2(parg); + vnThreadsRunning[1]--; + } + catch (std::exception& e) { + vnThreadsRunning[1]--; + PrintException(&e, "ThreadOpenConnections()"); + } catch (...) { + vnThreadsRunning[1]--; + PrintException(NULL, "ThreadOpenConnections()"); } + + printf("ThreadOpenConnections exiting\n"); } void ThreadOpenConnections2(void* parg) @@ -778,7 +784,8 @@ void ThreadOpenConnections2(void* parg) for (int i = 0; i < 10; i++) { Sleep(1000); - CheckForShutdown(1); + if (fShutdown) + return; } } @@ -792,7 +799,8 @@ void ThreadOpenConnections2(void* parg) { OpenNetworkConnection(addr); Sleep(1000); - CheckForShutdown(1); + if (fShutdown) + return; } } } @@ -806,11 +814,13 @@ void ThreadOpenConnections2(void* parg) const int nMaxConnections = 15; while (vNodes.size() >= nMaxConnections || vNodes.size() >= mapAddresses.size()) { - CheckForShutdown(1); + if (fShutdown) + return; Sleep(2000); } vnThreadsRunning[1]++; - CheckForShutdown(1); + if (fShutdown) + return; // // Choose an address to connect to based on most recently seen @@ -869,14 +879,16 @@ bool OpenNetworkConnection(const CAddress& addrConnect) // // Initiate outbound network connection // - CheckForShutdown(1); + if (fShutdown) + return false; if (addrConnect.ip == addrLocalHost.ip || !addrConnect.IsIPv4() || FindNode(addrConnect.ip)) return false; vnThreadsRunning[1]--; CNode* pnode = ConnectNode(addrConnect); vnThreadsRunning[1]++; - CheckForShutdown(1); + if (fShutdown) + return false; if (!pnode) return false; pnode->fNetworkNode = true; @@ -914,24 +926,21 @@ void ThreadMessageHandler(void* parg) { IMPLEMENT_RANDOMIZE_STACK(ThreadMessageHandler(parg)); - loop + try { vnThreadsRunning[2]++; - CheckForShutdown(2); - try - { - ThreadMessageHandler2(parg); - vnThreadsRunning[2]--; - } - catch (std::exception& e) { - vnThreadsRunning[2]--; - PrintException(&e, "ThreadMessageHandler()"); - } catch (...) { - vnThreadsRunning[2]--; - PrintException(NULL, "ThreadMessageHandler()"); - } - Sleep(5000); + ThreadMessageHandler2(parg); + vnThreadsRunning[2]--; + } + catch (std::exception& e) { + vnThreadsRunning[2]--; + PrintException(&e, "ThreadMessageHandler()"); + } catch (...) { + vnThreadsRunning[2]--; + PrintException(NULL, "ThreadMessageHandler()"); } + + printf("ThreadMessageHandler exiting\n"); } void ThreadMessageHandler2(void* parg) @@ -951,10 +960,14 @@ void ThreadMessageHandler2(void* parg) // Receive messages TRY_CRITICAL_BLOCK(pnode->cs_vRecv) ProcessMessages(pnode); + if (fShutdown) + return; // Send messages TRY_CRITICAL_BLOCK(pnode->cs_vSend) SendMessages(pnode); + if (fShutdown) + return; pnode->Release(); } @@ -963,7 +976,8 @@ void ThreadMessageHandler2(void* parg) vnThreadsRunning[2]--; Sleep(100); vnThreadsRunning[2]++; - CheckForShutdown(2); + if (fShutdown) + return; } } @@ -996,7 +1010,7 @@ bool StartNode(string& strError) // Get local host ip char pszHostName[255]; - if (gethostname(pszHostName, 255) == SOCKET_ERROR) + if (gethostname(pszHostName, sizeof(pszHostName)) == SOCKET_ERROR) { strError = strprintf("Error: Unable to get IP address of this computer (gethostname returned error %d)", WSAGetLastError()); printf("%s\n", strError.c_str()); @@ -1009,9 +1023,16 @@ bool StartNode(string& strError) printf("%s\n", strError.c_str()); return false; } - addrLocalHost = CAddress(*(long*)(phostent->h_addr_list[0]), - DEFAULT_PORT, - nLocalServices); + + // Take the first IP that isn't loopback 127.x.x.x + for (int i = 0; phostent->h_addr_list[i] != NULL; i++) + printf("host ip %d: %s\n", i, CAddress(*(unsigned int*)phostent->h_addr_list[i]).ToStringIP().c_str()); + for (int i = 0; phostent->h_addr_list[i] != NULL; i++) + { + addrLocalHost = CAddress(*(unsigned int*)phostent->h_addr_list[i], DEFAULT_PORT, nLocalServices); + if (addrLocalHost.IsValid() && addrLocalHost.GetByte(3) != 127) + break; + } printf("addrLocalHost = %s\n", addrLocalHost.ToString().c_str()); // Create socket for listening for incoming connections @@ -1022,6 +1043,10 @@ bool StartNode(string& strError) printf("%s\n", strError.c_str()); return false; } +#if defined(__BSD__) || defined(__WXOSX__) + int set = 1; + setsockopt(hSocket, SOL_SOCKET, SO_NOSIGPIPE, (void*)&set, sizeof(int)); +#endif // Set to nonblocking, incoming connections will also inherit this #ifdef __WXMSW__ @@ -1038,19 +1063,22 @@ bool StartNode(string& strError) // The sockaddr_in structure specifies the address family, // IP address, and port for the socket that is being bound - int nRetryLimit = 15; - struct sockaddr_in sockaddr = addrLocalHost.GetSockAddr(); + struct sockaddr_in sockaddr; + memset(&sockaddr, 0, sizeof(sockaddr)); + sockaddr.sin_family = AF_INET; + sockaddr.sin_addr.s_addr = INADDR_ANY; // bind to all IPs on this computer + sockaddr.sin_port = DEFAULT_PORT; if (::bind(hListenSocket, (struct sockaddr*)&sockaddr, sizeof(sockaddr)) == SOCKET_ERROR) { int nErr = WSAGetLastError(); if (nErr == WSAEADDRINUSE) - strError = strprintf("Error: Unable to bind to port %s on this computer. The program is probably already running.", addrLocalHost.ToString().c_str()); + strError = strprintf("Error: Unable to bind to port %d on this computer. The program is probably already running.", ntohs(sockaddr.sin_port)); else - strError = strprintf("Error: Unable to bind to port %s on this computer (bind returned error %d)", addrLocalHost.ToString().c_str(), nErr); + strError = strprintf("Error: Unable to bind to port %d on this computer (bind returned error %d)", ntohs(sockaddr.sin_port), nErr); printf("%s\n", strError.c_str()); return false; } - printf("bound to addrLocalHost = %s\n", addrLocalHost.ToString().c_str()); + printf("bound to port %d\n", ntohs(sockaddr.sin_port)); // Listen for incoming connections if (listen(hListenSocket, SOMAXCONN) == SOCKET_ERROR) @@ -1065,6 +1093,7 @@ bool StartNode(string& strError) { // Proxies can't take incoming connections addrLocalHost.ip = CAddress("0.0.0.0").ip; + printf("addrLocalHost = %s\n", addrLocalHost.ToString().c_str()); } else { @@ -1115,17 +1144,17 @@ bool StopNode() fShutdown = true; nTransactionsUpdated++; int64 nStart = GetTime(); - while (vnThreadsRunning[0] || vnThreadsRunning[2] || vnThreadsRunning[3]) + while (vnThreadsRunning[0] > 0 || vnThreadsRunning[2] > 0 || vnThreadsRunning[3] > 0) { if (GetTime() - nStart > 15) break; Sleep(20); } - if (vnThreadsRunning[0]) printf("ThreadSocketHandler still running\n"); - if (vnThreadsRunning[1]) printf("ThreadOpenConnections still running\n"); - if (vnThreadsRunning[2]) printf("ThreadMessageHandler still running\n"); - if (vnThreadsRunning[3]) printf("ThreadBitcoinMiner still running\n"); - while (vnThreadsRunning[2]) + if (vnThreadsRunning[0] > 0) printf("ThreadSocketHandler still running\n"); + if (vnThreadsRunning[1] > 0) printf("ThreadOpenConnections still running\n"); + if (vnThreadsRunning[2] > 0) printf("ThreadMessageHandler still running\n"); + if (vnThreadsRunning[3] > 0) printf("ThreadBitcoinMiner still running\n"); + while (vnThreadsRunning[2] > 0) Sleep(20); Sleep(50); @@ -1135,21 +1164,3 @@ bool StopNode() #endif return true; } - -void CheckForShutdown(int n) -{ - if (fShutdown) - { - if (n != -1) - if (--vnThreadsRunning[n] < 0) - vnThreadsRunning[n] = 0; - if (n == 0) - { - foreach(CNode* pnode, vNodes) - closesocket(pnode->hSocket); - closesocket(hListenSocket); - } - printf("Thread %d exiting\n", n); - _endthread(); - } -} diff --git a/net.h b/net.h index 275a4cb88b..024e7336e4 100644 --- a/net.h +++ b/net.h @@ -30,7 +30,6 @@ void AbandonRequests(void (*fn)(void*, CDataStream&), void* param1); bool AnySubscribed(unsigned int nChannel); bool StartNode(string& strError=REF(string())); bool StopNode(); -void CheckForShutdown(int n); @@ -268,6 +267,7 @@ public: 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; diff --git a/ui.cpp b/ui.cpp index 212548199f..92e1d59ce6 100644 --- a/ui.cpp +++ b/ui.cpp @@ -65,11 +65,13 @@ bool Is24HourTime() 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"); @@ -283,6 +285,7 @@ CMainFrame::CMainFrame(wxWindow* parent) : CMainFrameBase(parent) fRefreshListCtrl = false; fRefreshListCtrlRunning = false; fOnSetFocusAddress = false; + fRefresh = false; m_choiceFilter->SetSelection(0); m_staticTextBalance->SetLabel(FormatMoney(GetBalance()) + " "); m_listCtrl->SetFocus(); @@ -350,7 +353,7 @@ void Shutdown(void* parg) StopNode(); DBFlush(true); - printf("Bitcoin exiting\n"); + printf("Bitcoin exiting\n\n"); exit(0); } } @@ -391,6 +394,30 @@ void CMainFrame::OnListColBeginDrag(wxListEvent& event) event.Veto(); } +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 wxString& str2, const wxString& str3, const wxString& str4, const wxString& str5, const wxString& str6) { string str0 = strSort; @@ -407,7 +434,7 @@ void CMainFrame::InsertLine(bool fNew, int nIndex, uint256 hashKey, string strSo // fNew is for blind insert, only use if you're sure it's new if (fNew || nIndex == -1) { - nIndex = m_listCtrl->InsertItem(0, str0); + nIndex = m_listCtrl->InsertItem(GetSortIndex(strSort), str0); } else { @@ -415,7 +442,7 @@ void CMainFrame::InsertLine(bool fNew, int nIndex, uint256 hashKey, string strSo if (GetItemText(m_listCtrl, nIndex, 0) != str0) { m_listCtrl->DeleteItem(nIndex); - nIndex = m_listCtrl->InsertItem(0, str0); + nIndex = m_listCtrl->InsertItem(GetSortIndex(strSort), str0); } } @@ -826,6 +853,11 @@ void CMainFrame::RefreshStatusColumn() void CMainFrame::OnPaint(wxPaintEvent& event) { + if (fRefresh) + { + fRefresh = false; + Refresh(); + } event.Skip(); } @@ -846,7 +878,7 @@ void ThreadDelayedRepaint(void* parg) { printf("DelayedRepaint\n"); wxPaintEvent event; - pframeMain->Refresh(); + pframeMain->fRefresh = true; pframeMain->AddPendingEvent(event); } } @@ -871,7 +903,7 @@ void MainFrameRepaint() printf("MainFrameRepaint\n"); wxPaintEvent event; - pframeMain->Refresh(); + pframeMain->fRefresh = true; pframeMain->AddPendingEvent(event); } } @@ -907,7 +939,7 @@ void CMainFrame::OnPaintListCtrl(wxPaintEvent& event) } vWalletUpdated.clear(); if (m_listCtrl->GetItemCount() && strTop != (string)m_listCtrl->GetItemText(0)) - m_listCtrl->ScrollList(0, INT_MAX); + m_listCtrl->ScrollList(0, INT_MIN/2); } } @@ -943,9 +975,10 @@ void CMainFrame::OnPaintListCtrl(wxPaintEvent& event) string strStatus = strprintf(" %d connections %d blocks %d transactions", vNodes.size(), nBestHeight + 1, nTransactionCount); m_statusBar->SetStatusText(strStatus, 2); -#ifdef __WXMSW__ - m_listCtrl->OnPaint(event); -#endif + // Pass through to listctrl to actually do the paint, we're just hooking the message + m_listCtrl->Disconnect(wxEVT_PAINT, (wxObjectEventFunction)NULL, NULL, this); + m_listCtrl->GetEventHandler()->ProcessEvent(event); + m_listCtrl->Connect(wxEVT_PAINT, wxPaintEventHandler(CMainFrame::OnPaintListCtrl), NULL, this); } @@ -3331,7 +3364,11 @@ bool CMyApp::OnInit2() g_isPainting = 10000; #endif wxImage::AddHandler(new wxPNGHandler); +#ifdef __WXMSW__ SetAppName("Bitcoin"); +#else + SetAppName("bitcoin"); +#endif ParseParameters(argc, argv); if (mapArgs.count("-?") || mapArgs.count("--help")) @@ -3355,7 +3392,10 @@ bool CMyApp::OnInit2() // Limit to single instance per user // Required to protect the database files if we're going to keep deleting log.* // - wxString strMutexName = wxString("Bitcoin.") + getenv("HOMEPATH"); +#ifdef __WXMSW__ + // todo: wxSingleInstanceChecker wasn't working on Linux, never deleted its lock file + // maybe should go by whether successfully bind port 8333 instead + wxString strMutexName = wxString("bitcoin_running.") + getenv("HOMEPATH"); for (int i = 0; i < strMutexName.size(); i++) if (!isalnum(strMutexName[i])) strMutexName[i] = '.'; @@ -3367,7 +3407,6 @@ bool CMyApp::OnInit2() loop { // TODO: find out how to do this in Linux, or replace with wxWidgets commands -#ifdef __WXMSW__ // Show the previous instance and exit HWND hwndPrev = FindWindow("wxWindowClassNR", "Bitcoin"); if (hwndPrev) @@ -3377,7 +3416,6 @@ bool CMyApp::OnInit2() SetForegroundWindow(hwndPrev); return false; } -#endif if (GetTime() > nStart + 60) return false; @@ -3390,6 +3428,7 @@ bool CMyApp::OnInit2() break; } } +#endif // // Parameters diff --git a/ui.h b/ui.h index 47839e81e2..1d0491f109 100644 --- a/ui.h +++ b/ui.h @@ -32,7 +32,6 @@ extern int fMinimizeOnClose; extern void HandleCtrlA(wxKeyEvent& event); -extern string DateTimeStr(int64 nTime); extern string FormatTxStatus(const CWalletTx& wtx); extern void CrossThreadCall(int nID, void* pdata); extern void MainFrameRepaint(); @@ -84,8 +83,10 @@ public: bool fRefreshListCtrlRunning; bool fOnSetFocusAddress; unsigned int nListViewUpdated; + bool fRefresh; void OnCrossThreadCall(wxCommandEvent& event); + int GetSortIndex(const string& strSort); void InsertLine(bool fNew, int nIndex, uint256 hashKey, string strSort, 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); diff --git a/uibase.cpp b/uibase.cpp index bb564e9960..9a61999523 100644 --- a/uibase.cpp +++ b/uibase.cpp @@ -84,7 +84,7 @@ CMainFrameBase::CMainFrameBase( wxWindow* parent, wxWindowID id, const wxString& m_staticText32->Wrap( -1 ); bSizer85->Add( m_staticText32, 0, wxALIGN_CENTER_VERTICAL|wxLEFT, 5 ); - m_textCtrlAddress = new wxTextCtrl( this, wxID_TEXTCTRLADDRESS, wxEmptyString, wxDefaultPosition, wxSize( 250,-1 ), wxTE_READONLY ); + m_textCtrlAddress = new wxTextCtrl( this, wxID_TEXTCTRLADDRESS, wxEmptyString, wxDefaultPosition, wxSize( 340,-1 ), wxTE_READONLY ); m_textCtrlAddress->SetBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_MENU ) ); bSizer85->Add( m_textCtrlAddress, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 ); @@ -143,7 +143,7 @@ CMainFrameBase::CMainFrameBase( wxWindow* parent, wxWindowID id, const wxString& wxBoxSizer* bSizer157; bSizer157 = new wxBoxSizer( wxVERTICAL ); - m_listCtrl = new wxListCtrl( m_panel7, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_NO_SORT_HEADER|wxLC_REPORT|wxLC_SORT_DESCENDING|wxALWAYS_SHOW_SB ); + m_listCtrl = new wxListCtrl( m_panel7, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_NO_SORT_HEADER|wxLC_REPORT|wxLC_SORT_DESCENDING|wxVSCROLL ); bSizer157->Add( m_listCtrl, 1, wxEXPAND|wxALL, 5 ); m_panel7->SetSizer( bSizer157 ); @@ -343,7 +343,7 @@ CTxDetailsDialogBase::CTxDetailsDialogBase( wxWindow* parent, wxWindowID id, con wxBoxSizer* bSizer65; bSizer65 = new wxBoxSizer( wxVERTICAL ); - m_buttonOK = new wxButton( this, wxID_OK, wxT("OK"), wxDefaultPosition, wxSize( 85,25 ), 0 ); + m_buttonOK = new wxButton( this, wxID_OK, wxT("OK"), wxDefaultPosition, wxSize( -1,-1 ), 0 ); bSizer65->Add( m_buttonOK, 0, wxALL, 5 ); bSizer64->Add( bSizer65, 0, wxALIGN_RIGHT, 5 ); @@ -520,17 +520,13 @@ COptionsDialogBase::COptionsDialogBase( wxWindow* parent, wxWindowID id, const w wxBoxSizer* bSizer58; bSizer58 = new wxBoxSizer( wxHORIZONTAL ); - m_buttonOK = new wxButton( this, wxID_OK, wxT("OK"), wxDefaultPosition, wxSize( 85,25 ), 0 ); + m_buttonOK = new wxButton( this, wxID_OK, wxT("OK"), wxDefaultPosition, wxSize( -1,-1 ), 0 ); bSizer58->Add( m_buttonOK, 0, wxALL, 5 ); m_buttonCancel = new wxButton( this, wxID_CANCEL, wxT("Cancel"), wxDefaultPosition, wxSize( -1,-1 ), 0 ); - m_buttonCancel->SetMinSize( wxSize( 85,25 ) ); - bSizer58->Add( m_buttonCancel, 0, wxALL, 5 ); m_buttonApply = new wxButton( this, wxID_APPLY, wxT("&Apply"), wxDefaultPosition, wxSize( -1,-1 ), 0 ); - m_buttonApply->SetMinSize( wxSize( 85,25 ) ); - bSizer58->Add( m_buttonApply, 0, wxALL, 5 ); bSizer55->Add( bSizer58, 0, wxALIGN_RIGHT, 5 ); @@ -622,7 +618,7 @@ CAboutDialogBase::CAboutDialogBase( wxWindow* parent, wxWindowID id, const wxStr bSizer61->Add( 0, 0, 1, wxEXPAND, 5 ); - m_buttonOK = new wxButton( this, wxID_OK, wxT("OK"), wxDefaultPosition, wxSize( 85,25 ), 0 ); + m_buttonOK = new wxButton( this, wxID_OK, wxT("OK"), wxDefaultPosition, wxSize( -1,-1 ), 0 ); bSizer61->Add( m_buttonOK, 0, wxALL, 5 ); bSizer60->Add( bSizer61, 0, wxALIGN_RIGHT|wxEXPAND, 5 ); @@ -767,13 +763,10 @@ CSendDialogBase::CSendDialogBase( wxWindow* parent, wxWindowID id, const wxStrin m_buttonSend = new wxButton( this, wxID_BUTTONSEND, wxT("&Send"), wxDefaultPosition, wxSize( -1,-1 ), 0 ); m_buttonSend->SetFont( wxFont( wxNORMAL_FONT->GetPointSize(), 70, 90, 90, false, wxEmptyString ) ); - m_buttonSend->SetMinSize( wxSize( 85,25 ) ); bSizer23->Add( m_buttonSend, 0, wxALL, 5 ); m_buttonCancel = new wxButton( this, wxID_CANCEL, wxT("Cancel"), wxDefaultPosition, wxSize( -1,-1 ), 0 ); - m_buttonCancel->SetMinSize( wxSize( 85,25 ) ); - bSizer23->Add( m_buttonCancel, 0, wxALL, 5 ); bSizer21->Add( bSizer23, 0, wxEXPAND, 5 ); @@ -833,13 +826,10 @@ CSendingDialogBase::CSendingDialogBase( wxWindow* parent, wxWindowID id, const w m_buttonOK = new wxButton( this, wxID_ANY, wxT("OK"), wxDefaultPosition, wxDefaultSize, 0 ); m_buttonOK->Enable( false ); - m_buttonOK->SetMinSize( wxSize( 85,25 ) ); bSizer69->Add( m_buttonOK, 0, wxALL, 5 ); m_buttonCancel = new wxButton( this, wxID_CANCEL, wxT("Cancel"), wxDefaultPosition, wxSize( -1,-1 ), 0 ); - m_buttonCancel->SetMinSize( wxSize( 85,25 ) ); - bSizer69->Add( m_buttonCancel, 0, wxALL, 5 ); bSizer68->Add( bSizer69, 0, wxEXPAND, 5 ); @@ -887,28 +877,19 @@ CYourAddressDialogBase::CYourAddressDialogBase( wxWindow* parent, wxWindowID id, bSizer69->Add( 0, 0, 1, wxEXPAND, 5 ); m_buttonRename = new wxButton( this, wxID_BUTTONRENAME, wxT("&Edit..."), wxDefaultPosition, wxDefaultSize, 0 ); - m_buttonRename->SetMinSize( wxSize( 85,25 ) ); - bSizer69->Add( m_buttonRename, 0, wxALL, 5 ); m_buttonNew = new wxButton( this, wxID_BUTTONNEW, wxT("&New Address..."), wxDefaultPosition, wxSize( -1,-1 ), 0 ); - m_buttonNew->SetMinSize( wxSize( 110,25 ) ); - bSizer69->Add( m_buttonNew, 0, wxALL, 5 ); m_buttonCopy = new wxButton( this, wxID_BUTTONCOPY, wxT("&Copy to Clipboard"), wxDefaultPosition, wxSize( -1,-1 ), 0 ); - m_buttonCopy->SetMinSize( wxSize( 120,25 ) ); - bSizer69->Add( m_buttonCopy, 0, wxALL, 5 ); m_buttonOK = new wxButton( this, wxID_OK, wxT("OK"), wxDefaultPosition, wxDefaultSize, 0 ); - m_buttonOK->SetMinSize( wxSize( 85,25 ) ); - bSizer69->Add( m_buttonOK, 0, wxALL, 5 ); m_buttonCancel = new wxButton( this, wxID_CANCEL, wxT("Cancel"), wxDefaultPosition, wxSize( -1,-1 ), 0 ); m_buttonCancel->Hide(); - m_buttonCancel->SetMinSize( wxSize( 85,25 ) ); bSizer69->Add( m_buttonCancel, 0, wxALL, 5 ); @@ -969,28 +950,18 @@ CAddressBookDialogBase::CAddressBookDialogBase( wxWindow* parent, wxWindowID id, bSizer69->Add( 0, 0, 1, wxEXPAND, 5 ); m_buttonEdit = new wxButton( this, wxID_BUTTONEDIT, wxT("&Edit..."), wxDefaultPosition, wxDefaultSize, 0 ); - m_buttonEdit->SetMinSize( wxSize( 85,25 ) ); - bSizer69->Add( m_buttonEdit, 0, wxALL, 5 ); m_buttonNew = new wxButton( this, wxID_BUTTONNEW, wxT("&New Address..."), wxDefaultPosition, wxDefaultSize, 0 ); - m_buttonNew->SetMinSize( wxSize( 110,25 ) ); - bSizer69->Add( m_buttonNew, 0, wxALL, 5 ); m_buttonDelete = new wxButton( this, wxID_BUTTONDELETE, wxT("&Delete"), wxDefaultPosition, wxDefaultSize, 0 ); - m_buttonDelete->SetMinSize( wxSize( 85,25 ) ); - bSizer69->Add( m_buttonDelete, 0, wxALL, 5 ); m_buttonOK = new wxButton( this, wxID_OK, wxT("OK"), wxDefaultPosition, wxSize( -1,-1 ), 0 ); - m_buttonOK->SetMinSize( wxSize( 85,25 ) ); - bSizer69->Add( m_buttonOK, 0, wxALL, 5 ); m_buttonCancel = new wxButton( this, wxID_CANCEL, wxT("Cancel"), wxDefaultPosition, wxSize( -1,-1 ), 0 ); - m_buttonCancel->SetMinSize( wxSize( 85,25 ) ); - bSizer69->Add( m_buttonCancel, 0, wxALL, 5 ); bSizer68->Add( bSizer69, 0, wxEXPAND, 5 ); @@ -1389,18 +1360,12 @@ CEditProductDialogBase::CEditProductDialogBase( wxWindow* parent, wxWindowID id, bSizer26 = new wxBoxSizer( wxHORIZONTAL ); m_buttonOK = new wxButton( this, wxID_BUTTONSEND, wxT("&Send"), wxDefaultPosition, wxDefaultSize, 0 ); - m_buttonOK->SetMinSize( wxSize( 85,25 ) ); - bSizer26->Add( m_buttonOK, 0, wxALL, 5 ); m_buttonPreview = new wxButton( this, wxID_BUTTONPREVIEW, wxT("&Preview"), wxDefaultPosition, wxDefaultSize, 0 ); - m_buttonPreview->SetMinSize( wxSize( 85,25 ) ); - bSizer26->Add( m_buttonPreview, 0, wxALL, 5 ); m_buttonCancel = new wxButton( this, wxID_CANCEL, wxT("Cancel"), wxDefaultPosition, wxDefaultSize, 0 ); - m_buttonCancel->SetMinSize( wxSize( 85,25 ) ); - bSizer26->Add( m_buttonCancel, 0, wxALL, 5 ); bSizer20->Add( bSizer26, 0, wxALIGN_RIGHT, 5 ); @@ -1605,18 +1570,13 @@ CViewProductDialogBase::CViewProductDialogBase( wxWindow* parent, wxWindowID id, m_buttonBack = new wxButton( this, wxID_BUTTONBACK, wxT("< &Back "), wxDefaultPosition, wxDefaultSize, 0 ); m_buttonBack->Enable( false ); - m_buttonBack->SetMinSize( wxSize( 85,25 ) ); bSizer26->Add( m_buttonBack, 0, wxALL, 5 ); m_buttonNext = new wxButton( this, wxID_BUTTONNEXT, wxT(" &Next >"), wxDefaultPosition, wxDefaultSize, 0 ); - m_buttonNext->SetMinSize( wxSize( 85,25 ) ); - bSizer26->Add( m_buttonNext, 0, wxALL, 5 ); m_buttonCancel = new wxButton( this, wxID_CANCEL, wxT("Cancel"), wxDefaultPosition, wxDefaultSize, 0 ); - m_buttonCancel->SetMinSize( wxSize( 85,25 ) ); - bSizer26->Add( m_buttonCancel, 0, wxALL, 5 ); bSizer20->Add( bSizer26, 0, wxALIGN_RIGHT, 5 ); @@ -1662,8 +1622,6 @@ CViewOrderDialogBase::CViewOrderDialogBase( wxWindow* parent, wxWindowID id, con bSizer26 = new wxBoxSizer( wxHORIZONTAL ); m_buttonOK = new wxButton( this, wxID_OK, wxT("OK"), wxDefaultPosition, wxDefaultSize, 0 ); - m_buttonOK->SetMinSize( wxSize( 85,25 ) ); - bSizer26->Add( m_buttonOK, 0, wxALL, 5 ); bSizer20->Add( bSizer26, 0, wxALIGN_RIGHT, 5 ); @@ -1720,13 +1678,9 @@ CEditReviewDialogBase::CEditReviewDialogBase( wxWindow* parent, wxWindowID id, c bSizer113 = new wxBoxSizer( wxHORIZONTAL ); m_buttonSubmit = new wxButton( this, wxID_SUBMIT, wxT("&Submit"), wxDefaultPosition, wxDefaultSize, 0 ); - m_buttonSubmit->SetMinSize( wxSize( 85,25 ) ); - bSizer113->Add( m_buttonSubmit, 0, wxALL, 5 ); m_buttonCancel = new wxButton( this, wxID_CANCEL, wxT("Cancel"), wxDefaultPosition, wxDefaultSize, 0 ); - m_buttonCancel->SetMinSize( wxSize( 85,25 ) ); - bSizer113->Add( m_buttonCancel, 0, wxALL, 5 ); bSizer112->Add( bSizer113, 0, wxALIGN_RIGHT, 5 ); @@ -1951,13 +1905,9 @@ CGetTextFromUserDialogBase::CGetTextFromUserDialogBase( wxWindow* parent, wxWind bSizer80->Add( 0, 0, 1, wxEXPAND, 5 ); m_buttonOK = new wxButton( this, wxID_OK, wxT("OK"), wxDefaultPosition, wxSize( -1,-1 ), 0 ); - m_buttonOK->SetMinSize( wxSize( 85,25 ) ); - bSizer80->Add( m_buttonOK, 0, wxALL, 5 ); m_buttonCancel = new wxButton( this, wxID_CANCEL, wxT("Cancel"), wxDefaultPosition, wxDefaultSize, 0 ); - m_buttonCancel->SetMinSize( wxSize( 85,25 ) ); - bSizer80->Add( m_buttonCancel, 0, wxALL, 5 ); bSizer79->Add( bSizer80, 0, wxEXPAND, 5 ); diff --git a/uiproject.fbp b/uiproject.fbp index 7bce7349f5..17656b56a5 100644 --- a/uiproject.fbp +++ b/uiproject.fbp @@ -70,7 +70,7 @@ - + 240,240,240 1 @@ -225,7 +225,7 @@ - + 20,20 @@ -439,7 +439,7 @@ m_textCtrlAddress protected - 250,-1 + 340,-1 wxTE_READONLY @@ -944,7 +944,7 @@ - wxALWAYS_SHOW_SB + wxVSCROLL @@ -1648,7 +1648,7 @@ m_buttonOK protected - 85,25 + -1,-1 @@ -3031,7 +3031,7 @@ m_buttonOK protected - 85,25 + -1,-1 @@ -3079,7 +3079,7 @@ wxID_CANCEL Cancel - 85,25 + -1,-1 m_buttonCancel protected @@ -3131,7 +3131,7 @@ wxID_APPLY &Apply - 85,25 + -1,-1 m_buttonApply protected @@ -3493,7 +3493,7 @@ m_buttonOK protected - 85,25 + -1,-1 @@ -4485,7 +4485,7 @@ wxID_BUTTONSEND &Send - 85,25 + -1,-1 m_buttonSend protected @@ -4537,7 +4537,7 @@ wxID_CANCEL Cancel - 85,25 + -1,-1 m_buttonCancel protected @@ -4775,7 +4775,7 @@ wxID_ANY OK - 85,25 + -1,-1 m_buttonOK protected @@ -4827,7 +4827,7 @@ wxID_CANCEL Cancel - 85,25 + -1,-1 m_buttonCancel protected @@ -5089,7 +5089,7 @@ wxID_BUTTONRENAME &Edit... - 85,25 + -1,-1 m_buttonRename protected @@ -5141,7 +5141,7 @@ wxID_BUTTONNEW &New Address... - 110,25 + -1,-1 m_buttonNew protected @@ -5193,7 +5193,7 @@ wxID_BUTTONCOPY &Copy to Clipboard - 120,25 + -1,-1 m_buttonCopy protected @@ -5245,7 +5245,7 @@ wxID_OK OK - 85,25 + -1,-1 m_buttonOK protected @@ -5297,7 +5297,7 @@ wxID_CANCEL Cancel - 85,25 + -1,-1 m_buttonCancel protected @@ -5559,7 +5559,7 @@ wxID_BUTTONEDIT &Edit... - 85,25 + -1,-1 m_buttonEdit protected @@ -5611,7 +5611,7 @@ wxID_BUTTONNEW &New Address... - 110,25 + -1,-1 m_buttonNew protected @@ -5663,7 +5663,7 @@ wxID_BUTTONDELETE &Delete - 85,25 + -1,-1 m_buttonDelete protected @@ -5715,7 +5715,7 @@ wxID_OK OK - 85,25 + -1,-1 m_buttonOK protected @@ -5767,7 +5767,7 @@ wxID_CANCEL Cancel - 85,25 + -1,-1 m_buttonCancel public @@ -10225,7 +10225,7 @@ wxID_BUTTONSEND &Send - 85,25 + -1,-1 m_buttonOK protected @@ -10277,7 +10277,7 @@ wxID_BUTTONPREVIEW &Preview - 85,25 + -1,-1 m_buttonPreview protected @@ -10329,7 +10329,7 @@ wxID_CANCEL Cancel - 85,25 + -1,-1 m_buttonCancel protected @@ -10798,7 +10798,7 @@ wxID_BUTTONBACK < &Back - 85,25 + -1,-1 m_buttonBack protected @@ -10850,7 +10850,7 @@ wxID_BUTTONNEXT &Next > - 85,25 + -1,-1 m_buttonNext protected @@ -10902,7 +10902,7 @@ wxID_CANCEL Cancel - 85,25 + -1,-1 m_buttonCancel protected @@ -11087,7 +11087,7 @@ wxID_OK OK - 85,25 + -1,-1 m_buttonOK protected @@ -11488,7 +11488,7 @@ wxID_SUBMIT &Submit - 85,25 + -1,-1 m_buttonSubmit protected @@ -11540,7 +11540,7 @@ wxID_CANCEL Cancel - 85,25 + -1,-1 m_buttonCancel protected @@ -12907,7 +12907,7 @@ wxID_OK OK - 85,25 + -1,-1 m_buttonOK protected @@ -12959,7 +12959,7 @@ wxID_CANCEL Cancel - 85,25 + -1,-1 m_buttonCancel protected diff --git a/util.cpp b/util.cpp index d2e624d676..5efb579bf7 100644 --- a/util.cpp +++ b/util.cpp @@ -96,12 +96,7 @@ void RandAddSeedPerfmon() hash = 0; memset(pdata, 0, nSize); - time_t nTime; - time(&nTime); - struct tm* ptmTime = gmtime(&nTime); - char pszTime[200]; - strftime(pszTime, sizeof(pszTime), "%x %H:%M:%S", ptmTime); - printf("%s RandAddSeed() %d bytes\n", pszTime, nSize); + printf("%s RandAddSeed() %d bytes\n", DateTimeStrFormat("%x %H:%M:%S", GetTime()).c_str(), nSize); } #endif } @@ -350,7 +345,9 @@ void FormatException(char* pszMessage, std::exception* pex, const char* pszThrea pszModule[0] = '\0'; GetModuleFileName(NULL, pszModule, sizeof(pszModule)); #else - const char* pszModule = wxStandardPaths::Get().GetExecutablePath().mb_str(); + // might not be thread safe, uses wxString + //const char* pszModule = wxStandardPaths::Get().GetExecutablePath().mb_str(); + const char* pszModule = "bitcoin"; #endif if (pex) snprintf(pszMessage, 1000, @@ -425,7 +422,6 @@ void GetDataDir(char* pszDir) } strlcpy(pszDir, pszCachedDir, MAX_PATH); } - } string GetDataDir() diff --git a/util.h b/util.h index 3bc7c798a5..8fcfcd0dc9 100644 --- a/util.h +++ b/util.h @@ -84,6 +84,10 @@ inline void SetThreadPriority(int nThread, int nPriority) { setpriority(PRIO_PRO #define THREAD_PRIORITY_NORMAL 0 #define THREAD_PRIORITY_ABOVE_NORMAL 0 #endif +#ifndef MSG_NOSIGNAL +#define MSG_NOSIGNAL 0 +#endif + @@ -379,6 +383,14 @@ inline int64 GetTimeMillis() return wxGetLocalTimeMillis().GetValue(); } +inline string DateTimeStrFormat(const char* pszFormat, int64 nTime) +{ + time_t n = nTime; + struct tm* ptmTime = gmtime(&n); + char pszTime[200]; + strftime(pszTime, sizeof(pszTime), pszFormat, ptmTime); + return pszTime; +} @@ -400,7 +412,7 @@ inline void heapchk() { \ static char nLoops; \ if (nLoops <= 0) \ - nLoops = GetRand(50) + 1; \ + nLoops = GetRand(20) + 1; \ if (nLoops-- > 1) \ { \ ThreadFn; \ -- cgit v1.2.3 From 300d4608f2504e3e4a02a13b6c6000b52c436975 Mon Sep 17 00:00:00 2001 From: s_nakamoto Date: Fri, 6 Nov 2009 05:50:05 +0000 Subject: got rid of CheckForShutdown, replaced some thread-unsafe wxWidgets calls, Linux fixes, socket send MSG_NOSIGNAL, bind INADDR_ANY, works reliably on Linux now except if wxMessageBox is used in a thread other than the GUI thread git-svn-id: https://bitcoin.svn.sourceforge.net/svnroot/bitcoin/trunk@33 1a98c847-1fd6-4fd8-948a-caf3550aa51b --- db.cpp | 2 +- irc.cpp | 9 ++- main.cpp | 67 ++++++++++++-------- main.h | 2 +- net.cpp | 193 +++++++++++++++++++++++++++++++--------------------------- net.h | 2 +- ui.cpp | 63 +++++++++++++++---- ui.h | 3 +- uibase.cpp | 60 ++---------------- uiproject.fbp | 68 ++++++++++----------- util.cpp | 12 ++-- util.h | 14 ++++- 12 files changed, 260 insertions(+), 235 deletions(-) diff --git a/db.cpp b/db.cpp index b702b0cbac..1235592631 100644 --- a/db.cpp +++ b/db.cpp @@ -550,7 +550,7 @@ bool CWalletDB::LoadWallet(vector& vchDefaultKeyRet) //printf("LoadWallet %s\n", wtx.GetHash().ToString().c_str()); //printf(" %12I64d %s %s %s\n", // wtx.vout[0].nValue, - // DateTimeStr(wtx.nTime).c_str(), + // DateTimeStrFormat("%x %H:%M:%S", wtx.nTime).c_str(), // wtx.hashBlock.ToString().substr(0,14).c_str(), // wtx.mapValue["message"].c_str()); } diff --git a/irc.cpp b/irc.cpp index 4d4ed0f414..3b232caead 100644 --- a/irc.cpp +++ b/irc.cpp @@ -167,9 +167,12 @@ void ThreadIRCSeed(void* parg) while (!fShutdown) { CAddress addrConnect("216.155.130.130:6667"); - struct hostent* phostent = gethostbyname("chat.freenode.net"); - if (phostent && phostent->h_addr_list && phostent->h_addr_list[0]) - addrConnect = CAddress(*(u_long*)phostent->h_addr_list[0], htons(6667)); + if (!(fUseProxy && addrProxy.port == htons(9050))) + { + struct hostent* phostent = gethostbyname("chat.freenode.net"); + if (phostent && phostent->h_addr_list && phostent->h_addr_list[0]) + addrConnect = CAddress(*(u_long*)phostent->h_addr_list[0], htons(6667)); + } SOCKET hSocket; if (!ConnectSocket(addrConnect, hSocket)) diff --git a/main.cpp b/main.cpp index 2119495e64..cc22bad679 100644 --- a/main.cpp +++ b/main.cpp @@ -1361,15 +1361,24 @@ bool ScanMessageStart(Stream& s) bool CheckDiskSpace(int64 nAdditionalBytes) { - wxLongLong nFreeBytesAvailable = 0; - if (!wxGetDiskSpace(GetDataDir(), NULL, &nFreeBytesAvailable)) - { - printf("ERROR: wxGetDiskSpace() failed\n"); +#ifdef __WXMSW__ + uint64 nFreeBytesAvailable = 0; // bytes available to caller + uint64 nTotalNumberOfBytes = 0; // bytes on disk + uint64 nTotalNumberOfFreeBytes = 0; // free bytes on disk + if (!GetDiskFreeSpaceEx(GetDataDir().c_str(), + (PULARGE_INTEGER)&nFreeBytesAvailable, + (PULARGE_INTEGER)&nTotalNumberOfBytes, + (PULARGE_INTEGER)&nTotalNumberOfFreeBytes)) + { + printf("ERROR: GetDiskFreeSpaceEx() failed\n"); return true; } +#else + uint64 nFreeBytesAvailable = filesystem::space(GetDataDir()).available; +#endif // Check for 15MB because database could create another 10MB log file at any time - if (nFreeBytesAvailable.GetValue() < (int64)15000000 + nAdditionalBytes) + if (nFreeBytesAvailable < (int64)15000000 + nAdditionalBytes) { fShutdown = true; wxMessageBox("Warning: Your disk space is low ", "Bitcoin", wxICON_EXCLAMATION); @@ -1546,7 +1555,7 @@ void PrintBlockTree() pindex->nFile, pindex->nBlockPos, block.GetHash().ToString().substr(0,14).c_str(), - DateTimeStr(block.nTime).c_str(), + DateTimeStrFormat("%x %H:%M:%S", block.nTime).c_str(), block.vtx.size()); CRITICAL_BLOCK(cs_mapWallet) @@ -1673,20 +1682,24 @@ bool ProcessMessages(CNode* pfrom) bool fRet = false; try { - CheckForShutdown(2); CRITICAL_BLOCK(cs_main) fRet = ProcessMessage(pfrom, strCommand, vMsg); - CheckForShutdown(2); + if (fShutdown) + return true; } - catch (std::ios_base::failure& e) { + catch (std::ios_base::failure& e) + { if (strstr(e.what(), "CDataStream::read() : end of data")) { // Allow exceptions from underlength message on vRecv printf("ProcessMessage(%s, %d bytes) : Exception '%s' caught, normally caused by a message being shorter than its stated length\n", strCommand.c_str(), nMessageSize, e.what()); } else + { PrintException(&e, "ProcessMessage()"); - } catch (std::exception& e) { + } + } + catch (std::exception& e) { PrintException(&e, "ProcessMessage()"); } catch (...) { PrintException(NULL, "ProcessMessage()"); @@ -2093,7 +2106,6 @@ bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) bool SendMessages(CNode* pto) { - CheckForShutdown(2); CRITICAL_BLOCK(cs_main) { // Don't send anything until we get their version message @@ -2223,12 +2235,10 @@ void GenerateBitcoins(bool fGenerate) void ThreadBitcoinMiner(void* parg) { - vnThreadsRunning[3]++; - CheckForShutdown(3); try { - bool fRet = BitcoinMiner(); - printf("BitcoinMiner returned %s\n", fRet ? "true" : "false"); + vnThreadsRunning[3]++; + BitcoinMiner(); vnThreadsRunning[3]--; } catch (std::exception& e) { @@ -2238,6 +2248,8 @@ void ThreadBitcoinMiner(void* parg) vnThreadsRunning[3]--; PrintException(NULL, "ThreadBitcoinMiner()"); } + + printf("ThreadBitcoinMiner exiting, %d threads remaining\n", vnThreadsRunning[3]); } int FormatHashBlocks(void* pbuffer, unsigned int len) @@ -2285,7 +2297,7 @@ void BlockSHA256(const void* pin, unsigned int nBlocks, void* pout) } -bool BitcoinMiner() +void BitcoinMiner() { printf("BitcoinMiner started\n"); @@ -2296,11 +2308,13 @@ bool BitcoinMiner() { SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_LOWEST); Sleep(50); - CheckForShutdown(3); + if (fShutdown) + return; while (vNodes.empty()) { Sleep(1000); - CheckForShutdown(3); + if (fShutdown) + return; } unsigned int nTransactionsUpdatedLast = nTransactionsUpdated; @@ -2324,7 +2338,7 @@ bool BitcoinMiner() // auto_ptr pblock(new CBlock()); if (!pblock.get()) - return false; + return; // Add our coinbase tx as first transaction pblock->vtx.push_back(txNew); @@ -2433,7 +2447,7 @@ bool BitcoinMiner() { // Save key if (!AddKey(key)) - return false; + return; key.MakeNewKey(); // Process this block the same as if we had received it from another node @@ -2450,7 +2464,12 @@ bool BitcoinMiner() // Update nTime every few seconds if ((++tmp.block.nNonce & 0xffff) == 0) { - CheckForShutdown(3); + if (fShutdown) + return; + if (!fGenerateBitcoins) + return; + if (fLimitProcessors && vnThreadsRunning[3] > nLimitProcessors) + return; if (tmp.block.nNonce == 0) break; if (pindexPrev != pindexBest) @@ -2459,16 +2478,10 @@ bool BitcoinMiner() break; if (vNodes.empty()) break; - if (!fGenerateBitcoins) - return true; - if (fLimitProcessors && vnThreadsRunning[3] > nLimitProcessors) - return true; tmp.block.nTime = pblock->nTime = max(pindexPrev->GetMedianTimePast()+1, GetAdjustedTime()); } } } - - return true; } diff --git a/main.h b/main.h index 6d8f0ed87c..16b8c6a3d6 100644 --- a/main.h +++ b/main.h @@ -68,7 +68,7 @@ bool CommitTransactionSpent(const CWalletTx& wtxNew, const CKey& key); bool SendMoney(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew); void GenerateBitcoins(bool fGenerate); void ThreadBitcoinMiner(void* parg); -bool BitcoinMiner(); +void BitcoinMiner(); diff --git a/net.cpp b/net.cpp index c14061e7d3..44a75a177f 100644 --- a/net.cpp +++ b/net.cpp @@ -48,6 +48,10 @@ bool ConnectSocket(const CAddress& addrConnect, SOCKET& hSocketRet) SOCKET hSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (hSocket == INVALID_SOCKET) return false; +#if defined(__BSD__) || defined(__WXOSX__) + int set = 1; + setsockopt(hSocket, SOL_SOCKET, SO_NOSIGPIPE, (void*)&set, sizeof(int)); +#endif bool fRoutable = !(addrConnect.GetByte(3) == 10 || (addrConnect.GetByte(3) == 192 && addrConnect.GetByte(2) == 168)); bool fProxy = (fUseProxy && fRoutable); @@ -68,7 +72,7 @@ bool ConnectSocket(const CAddress& addrConnect, SOCKET& hSocketRet) char* pszSocks4 = pszSocks4IP; int nSize = sizeof(pszSocks4IP); - int ret = send(hSocket, pszSocks4, nSize, 0); + int ret = send(hSocket, pszSocks4, nSize, MSG_NOSIGNAL); if (ret != nSize) { closesocket(hSocket); @@ -100,7 +104,7 @@ bool GetMyExternalIP2(const CAddress& addrConnect, const char* pszGet, const cha if (!ConnectSocket(addrConnect, hSocket)) return error("GetMyExternalIP() : connection to %s failed", addrConnect.ToString().c_str()); - send(hSocket, pszGet, strlen(pszGet), 0); + send(hSocket, pszGet, strlen(pszGet), MSG_NOSIGNAL); string strLine; while (RecvLine(hSocket, strLine)) @@ -124,7 +128,8 @@ bool GetMyExternalIP2(const CAddress& addrConnect, const char* pszGet, const cha if (strLine.find("<")) strLine = strLine.substr(0, strLine.find("<")); strLine = strLine.substr(strspn(strLine.c_str(), " \t\n\r")); - strLine = wxString(strLine).Trim(); + while (strLine.size() > 0 && isspace(strLine[strLine.size()-1])) + strLine.resize(strLine.size()-1); CAddress addr(strLine.c_str()); printf("GetMyExternalIP() received [%s] %s\n", strLine.c_str(), addr.ToString().c_str()); if (addr.ip == 0 || addr.ip == INADDR_NONE || !addr.IsRoutable()) @@ -492,24 +497,26 @@ void ThreadSocketHandler(void* parg) { IMPLEMENT_RANDOMIZE_STACK(ThreadSocketHandler(parg)); - loop + try { vnThreadsRunning[0]++; - CheckForShutdown(0); - try - { - ThreadSocketHandler2(parg); - vnThreadsRunning[0]--; - } - catch (std::exception& e) { - vnThreadsRunning[0]--; - PrintException(&e, "ThreadSocketHandler()"); - } catch (...) { - vnThreadsRunning[0]--; - PrintException(NULL, "ThreadSocketHandler()"); - } - Sleep(5000); + ThreadSocketHandler2(parg); + vnThreadsRunning[0]--; } + catch (std::exception& e) { + vnThreadsRunning[0]--; + PrintException(&e, "ThreadSocketHandler()"); + } catch (...) { + vnThreadsRunning[0]--; + PrintException(NULL, "ThreadSocketHandler()"); + } + + foreach(CNode* pnode, vNodes) + closesocket(pnode->hSocket); + if (closesocket(hListenSocket) == SOCKET_ERROR) + printf("closesocket(hListenSocket) failed with error %d\n", WSAGetLastError()); + + printf("ThreadSocketHandler exiting\n"); } void ThreadSocketHandler2(void* parg) @@ -600,7 +607,8 @@ void ThreadSocketHandler2(void* parg) vnThreadsRunning[0]--; int nSelect = select(hSocketMax + 1, &fdsetRecv, &fdsetSend, NULL, &timeout); vnThreadsRunning[0]++; - CheckForShutdown(0); + if (fShutdown) + return; if (nSelect == SOCKET_ERROR) { int nErr = WSAGetLastError(); @@ -659,7 +667,8 @@ void ThreadSocketHandler2(void* parg) vNodesCopy = vNodes; foreach(CNode* pnode, vNodesCopy) { - CheckForShutdown(0); + if (fShutdown) + return; SOCKET hSocket = pnode->hSocket; // @@ -708,7 +717,7 @@ void ThreadSocketHandler2(void* parg) CDataStream& vSend = pnode->vSend; if (!vSend.empty()) { - int nBytes = send(hSocket, &vSend[0], vSend.size(), 0); + int nBytes = send(hSocket, &vSend[0], vSend.size(), MSG_NOSIGNAL); if (nBytes > 0) { vSend.erase(vSend.begin(), vSend.begin() + nBytes); @@ -747,24 +756,21 @@ void ThreadOpenConnections(void* parg) { IMPLEMENT_RANDOMIZE_STACK(ThreadOpenConnections(parg)); - loop + try { vnThreadsRunning[1]++; - CheckForShutdown(1); - try - { - ThreadOpenConnections2(parg); - vnThreadsRunning[1]--; - } - catch (std::exception& e) { - vnThreadsRunning[1]--; - PrintException(&e, "ThreadOpenConnections()"); - } catch (...) { - vnThreadsRunning[1]--; - PrintException(NULL, "ThreadOpenConnections()"); - } - Sleep(5000); + ThreadOpenConnections2(parg); + vnThreadsRunning[1]--; + } + catch (std::exception& e) { + vnThreadsRunning[1]--; + PrintException(&e, "ThreadOpenConnections()"); + } catch (...) { + vnThreadsRunning[1]--; + PrintException(NULL, "ThreadOpenConnections()"); } + + printf("ThreadOpenConnections exiting\n"); } void ThreadOpenConnections2(void* parg) @@ -778,7 +784,8 @@ void ThreadOpenConnections2(void* parg) for (int i = 0; i < 10; i++) { Sleep(1000); - CheckForShutdown(1); + if (fShutdown) + return; } } @@ -792,7 +799,8 @@ void ThreadOpenConnections2(void* parg) { OpenNetworkConnection(addr); Sleep(1000); - CheckForShutdown(1); + if (fShutdown) + return; } } } @@ -806,11 +814,13 @@ void ThreadOpenConnections2(void* parg) const int nMaxConnections = 15; while (vNodes.size() >= nMaxConnections || vNodes.size() >= mapAddresses.size()) { - CheckForShutdown(1); + if (fShutdown) + return; Sleep(2000); } vnThreadsRunning[1]++; - CheckForShutdown(1); + if (fShutdown) + return; // // Choose an address to connect to based on most recently seen @@ -869,14 +879,16 @@ bool OpenNetworkConnection(const CAddress& addrConnect) // // Initiate outbound network connection // - CheckForShutdown(1); + if (fShutdown) + return false; if (addrConnect.ip == addrLocalHost.ip || !addrConnect.IsIPv4() || FindNode(addrConnect.ip)) return false; vnThreadsRunning[1]--; CNode* pnode = ConnectNode(addrConnect); vnThreadsRunning[1]++; - CheckForShutdown(1); + if (fShutdown) + return false; if (!pnode) return false; pnode->fNetworkNode = true; @@ -914,24 +926,21 @@ void ThreadMessageHandler(void* parg) { IMPLEMENT_RANDOMIZE_STACK(ThreadMessageHandler(parg)); - loop + try { vnThreadsRunning[2]++; - CheckForShutdown(2); - try - { - ThreadMessageHandler2(parg); - vnThreadsRunning[2]--; - } - catch (std::exception& e) { - vnThreadsRunning[2]--; - PrintException(&e, "ThreadMessageHandler()"); - } catch (...) { - vnThreadsRunning[2]--; - PrintException(NULL, "ThreadMessageHandler()"); - } - Sleep(5000); + ThreadMessageHandler2(parg); + vnThreadsRunning[2]--; + } + catch (std::exception& e) { + vnThreadsRunning[2]--; + PrintException(&e, "ThreadMessageHandler()"); + } catch (...) { + vnThreadsRunning[2]--; + PrintException(NULL, "ThreadMessageHandler()"); } + + printf("ThreadMessageHandler exiting\n"); } void ThreadMessageHandler2(void* parg) @@ -951,10 +960,14 @@ void ThreadMessageHandler2(void* parg) // Receive messages TRY_CRITICAL_BLOCK(pnode->cs_vRecv) ProcessMessages(pnode); + if (fShutdown) + return; // Send messages TRY_CRITICAL_BLOCK(pnode->cs_vSend) SendMessages(pnode); + if (fShutdown) + return; pnode->Release(); } @@ -963,7 +976,8 @@ void ThreadMessageHandler2(void* parg) vnThreadsRunning[2]--; Sleep(100); vnThreadsRunning[2]++; - CheckForShutdown(2); + if (fShutdown) + return; } } @@ -996,7 +1010,7 @@ bool StartNode(string& strError) // Get local host ip char pszHostName[255]; - if (gethostname(pszHostName, 255) == SOCKET_ERROR) + if (gethostname(pszHostName, sizeof(pszHostName)) == SOCKET_ERROR) { strError = strprintf("Error: Unable to get IP address of this computer (gethostname returned error %d)", WSAGetLastError()); printf("%s\n", strError.c_str()); @@ -1009,9 +1023,16 @@ bool StartNode(string& strError) printf("%s\n", strError.c_str()); return false; } - addrLocalHost = CAddress(*(long*)(phostent->h_addr_list[0]), - DEFAULT_PORT, - nLocalServices); + + // Take the first IP that isn't loopback 127.x.x.x + for (int i = 0; phostent->h_addr_list[i] != NULL; i++) + printf("host ip %d: %s\n", i, CAddress(*(unsigned int*)phostent->h_addr_list[i]).ToStringIP().c_str()); + for (int i = 0; phostent->h_addr_list[i] != NULL; i++) + { + addrLocalHost = CAddress(*(unsigned int*)phostent->h_addr_list[i], DEFAULT_PORT, nLocalServices); + if (addrLocalHost.IsValid() && addrLocalHost.GetByte(3) != 127) + break; + } printf("addrLocalHost = %s\n", addrLocalHost.ToString().c_str()); // Create socket for listening for incoming connections @@ -1022,6 +1043,10 @@ bool StartNode(string& strError) printf("%s\n", strError.c_str()); return false; } +#if defined(__BSD__) || defined(__WXOSX__) + int set = 1; + setsockopt(hSocket, SOL_SOCKET, SO_NOSIGPIPE, (void*)&set, sizeof(int)); +#endif // Set to nonblocking, incoming connections will also inherit this #ifdef __WXMSW__ @@ -1038,19 +1063,22 @@ bool StartNode(string& strError) // The sockaddr_in structure specifies the address family, // IP address, and port for the socket that is being bound - int nRetryLimit = 15; - struct sockaddr_in sockaddr = addrLocalHost.GetSockAddr(); + struct sockaddr_in sockaddr; + memset(&sockaddr, 0, sizeof(sockaddr)); + sockaddr.sin_family = AF_INET; + sockaddr.sin_addr.s_addr = INADDR_ANY; // bind to all IPs on this computer + sockaddr.sin_port = DEFAULT_PORT; if (::bind(hListenSocket, (struct sockaddr*)&sockaddr, sizeof(sockaddr)) == SOCKET_ERROR) { int nErr = WSAGetLastError(); if (nErr == WSAEADDRINUSE) - strError = strprintf("Error: Unable to bind to port %s on this computer. The program is probably already running.", addrLocalHost.ToString().c_str()); + strError = strprintf("Error: Unable to bind to port %d on this computer. The program is probably already running.", ntohs(sockaddr.sin_port)); else - strError = strprintf("Error: Unable to bind to port %s on this computer (bind returned error %d)", addrLocalHost.ToString().c_str(), nErr); + strError = strprintf("Error: Unable to bind to port %d on this computer (bind returned error %d)", ntohs(sockaddr.sin_port), nErr); printf("%s\n", strError.c_str()); return false; } - printf("bound to addrLocalHost = %s\n", addrLocalHost.ToString().c_str()); + printf("bound to port %d\n", ntohs(sockaddr.sin_port)); // Listen for incoming connections if (listen(hListenSocket, SOMAXCONN) == SOCKET_ERROR) @@ -1065,6 +1093,7 @@ bool StartNode(string& strError) { // Proxies can't take incoming connections addrLocalHost.ip = CAddress("0.0.0.0").ip; + printf("addrLocalHost = %s\n", addrLocalHost.ToString().c_str()); } else { @@ -1115,17 +1144,17 @@ bool StopNode() fShutdown = true; nTransactionsUpdated++; int64 nStart = GetTime(); - while (vnThreadsRunning[0] || vnThreadsRunning[2] || vnThreadsRunning[3]) + while (vnThreadsRunning[0] > 0 || vnThreadsRunning[2] > 0 || vnThreadsRunning[3] > 0) { if (GetTime() - nStart > 15) break; Sleep(20); } - if (vnThreadsRunning[0]) printf("ThreadSocketHandler still running\n"); - if (vnThreadsRunning[1]) printf("ThreadOpenConnections still running\n"); - if (vnThreadsRunning[2]) printf("ThreadMessageHandler still running\n"); - if (vnThreadsRunning[3]) printf("ThreadBitcoinMiner still running\n"); - while (vnThreadsRunning[2]) + if (vnThreadsRunning[0] > 0) printf("ThreadSocketHandler still running\n"); + if (vnThreadsRunning[1] > 0) printf("ThreadOpenConnections still running\n"); + if (vnThreadsRunning[2] > 0) printf("ThreadMessageHandler still running\n"); + if (vnThreadsRunning[3] > 0) printf("ThreadBitcoinMiner still running\n"); + while (vnThreadsRunning[2] > 0) Sleep(20); Sleep(50); @@ -1135,21 +1164,3 @@ bool StopNode() #endif return true; } - -void CheckForShutdown(int n) -{ - if (fShutdown) - { - if (n != -1) - if (--vnThreadsRunning[n] < 0) - vnThreadsRunning[n] = 0; - if (n == 0) - { - foreach(CNode* pnode, vNodes) - closesocket(pnode->hSocket); - closesocket(hListenSocket); - } - printf("Thread %d exiting\n", n); - _endthread(); - } -} diff --git a/net.h b/net.h index 275a4cb88b..024e7336e4 100644 --- a/net.h +++ b/net.h @@ -30,7 +30,6 @@ void AbandonRequests(void (*fn)(void*, CDataStream&), void* param1); bool AnySubscribed(unsigned int nChannel); bool StartNode(string& strError=REF(string())); bool StopNode(); -void CheckForShutdown(int n); @@ -268,6 +267,7 @@ public: 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; diff --git a/ui.cpp b/ui.cpp index 212548199f..92e1d59ce6 100644 --- a/ui.cpp +++ b/ui.cpp @@ -65,11 +65,13 @@ bool Is24HourTime() 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"); @@ -283,6 +285,7 @@ CMainFrame::CMainFrame(wxWindow* parent) : CMainFrameBase(parent) fRefreshListCtrl = false; fRefreshListCtrlRunning = false; fOnSetFocusAddress = false; + fRefresh = false; m_choiceFilter->SetSelection(0); m_staticTextBalance->SetLabel(FormatMoney(GetBalance()) + " "); m_listCtrl->SetFocus(); @@ -350,7 +353,7 @@ void Shutdown(void* parg) StopNode(); DBFlush(true); - printf("Bitcoin exiting\n"); + printf("Bitcoin exiting\n\n"); exit(0); } } @@ -391,6 +394,30 @@ void CMainFrame::OnListColBeginDrag(wxListEvent& event) event.Veto(); } +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 wxString& str2, const wxString& str3, const wxString& str4, const wxString& str5, const wxString& str6) { string str0 = strSort; @@ -407,7 +434,7 @@ void CMainFrame::InsertLine(bool fNew, int nIndex, uint256 hashKey, string strSo // fNew is for blind insert, only use if you're sure it's new if (fNew || nIndex == -1) { - nIndex = m_listCtrl->InsertItem(0, str0); + nIndex = m_listCtrl->InsertItem(GetSortIndex(strSort), str0); } else { @@ -415,7 +442,7 @@ void CMainFrame::InsertLine(bool fNew, int nIndex, uint256 hashKey, string strSo if (GetItemText(m_listCtrl, nIndex, 0) != str0) { m_listCtrl->DeleteItem(nIndex); - nIndex = m_listCtrl->InsertItem(0, str0); + nIndex = m_listCtrl->InsertItem(GetSortIndex(strSort), str0); } } @@ -826,6 +853,11 @@ void CMainFrame::RefreshStatusColumn() void CMainFrame::OnPaint(wxPaintEvent& event) { + if (fRefresh) + { + fRefresh = false; + Refresh(); + } event.Skip(); } @@ -846,7 +878,7 @@ void ThreadDelayedRepaint(void* parg) { printf("DelayedRepaint\n"); wxPaintEvent event; - pframeMain->Refresh(); + pframeMain->fRefresh = true; pframeMain->AddPendingEvent(event); } } @@ -871,7 +903,7 @@ void MainFrameRepaint() printf("MainFrameRepaint\n"); wxPaintEvent event; - pframeMain->Refresh(); + pframeMain->fRefresh = true; pframeMain->AddPendingEvent(event); } } @@ -907,7 +939,7 @@ void CMainFrame::OnPaintListCtrl(wxPaintEvent& event) } vWalletUpdated.clear(); if (m_listCtrl->GetItemCount() && strTop != (string)m_listCtrl->GetItemText(0)) - m_listCtrl->ScrollList(0, INT_MAX); + m_listCtrl->ScrollList(0, INT_MIN/2); } } @@ -943,9 +975,10 @@ void CMainFrame::OnPaintListCtrl(wxPaintEvent& event) string strStatus = strprintf(" %d connections %d blocks %d transactions", vNodes.size(), nBestHeight + 1, nTransactionCount); m_statusBar->SetStatusText(strStatus, 2); -#ifdef __WXMSW__ - m_listCtrl->OnPaint(event); -#endif + // Pass through to listctrl to actually do the paint, we're just hooking the message + m_listCtrl->Disconnect(wxEVT_PAINT, (wxObjectEventFunction)NULL, NULL, this); + m_listCtrl->GetEventHandler()->ProcessEvent(event); + m_listCtrl->Connect(wxEVT_PAINT, wxPaintEventHandler(CMainFrame::OnPaintListCtrl), NULL, this); } @@ -3331,7 +3364,11 @@ bool CMyApp::OnInit2() g_isPainting = 10000; #endif wxImage::AddHandler(new wxPNGHandler); +#ifdef __WXMSW__ SetAppName("Bitcoin"); +#else + SetAppName("bitcoin"); +#endif ParseParameters(argc, argv); if (mapArgs.count("-?") || mapArgs.count("--help")) @@ -3355,7 +3392,10 @@ bool CMyApp::OnInit2() // Limit to single instance per user // Required to protect the database files if we're going to keep deleting log.* // - wxString strMutexName = wxString("Bitcoin.") + getenv("HOMEPATH"); +#ifdef __WXMSW__ + // todo: wxSingleInstanceChecker wasn't working on Linux, never deleted its lock file + // maybe should go by whether successfully bind port 8333 instead + wxString strMutexName = wxString("bitcoin_running.") + getenv("HOMEPATH"); for (int i = 0; i < strMutexName.size(); i++) if (!isalnum(strMutexName[i])) strMutexName[i] = '.'; @@ -3367,7 +3407,6 @@ bool CMyApp::OnInit2() loop { // TODO: find out how to do this in Linux, or replace with wxWidgets commands -#ifdef __WXMSW__ // Show the previous instance and exit HWND hwndPrev = FindWindow("wxWindowClassNR", "Bitcoin"); if (hwndPrev) @@ -3377,7 +3416,6 @@ bool CMyApp::OnInit2() SetForegroundWindow(hwndPrev); return false; } -#endif if (GetTime() > nStart + 60) return false; @@ -3390,6 +3428,7 @@ bool CMyApp::OnInit2() break; } } +#endif // // Parameters diff --git a/ui.h b/ui.h index 47839e81e2..1d0491f109 100644 --- a/ui.h +++ b/ui.h @@ -32,7 +32,6 @@ extern int fMinimizeOnClose; extern void HandleCtrlA(wxKeyEvent& event); -extern string DateTimeStr(int64 nTime); extern string FormatTxStatus(const CWalletTx& wtx); extern void CrossThreadCall(int nID, void* pdata); extern void MainFrameRepaint(); @@ -84,8 +83,10 @@ public: bool fRefreshListCtrlRunning; bool fOnSetFocusAddress; unsigned int nListViewUpdated; + bool fRefresh; void OnCrossThreadCall(wxCommandEvent& event); + int GetSortIndex(const string& strSort); void InsertLine(bool fNew, int nIndex, uint256 hashKey, string strSort, 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); diff --git a/uibase.cpp b/uibase.cpp index bb564e9960..9a61999523 100644 --- a/uibase.cpp +++ b/uibase.cpp @@ -84,7 +84,7 @@ CMainFrameBase::CMainFrameBase( wxWindow* parent, wxWindowID id, const wxString& m_staticText32->Wrap( -1 ); bSizer85->Add( m_staticText32, 0, wxALIGN_CENTER_VERTICAL|wxLEFT, 5 ); - m_textCtrlAddress = new wxTextCtrl( this, wxID_TEXTCTRLADDRESS, wxEmptyString, wxDefaultPosition, wxSize( 250,-1 ), wxTE_READONLY ); + m_textCtrlAddress = new wxTextCtrl( this, wxID_TEXTCTRLADDRESS, wxEmptyString, wxDefaultPosition, wxSize( 340,-1 ), wxTE_READONLY ); m_textCtrlAddress->SetBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_MENU ) ); bSizer85->Add( m_textCtrlAddress, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 ); @@ -143,7 +143,7 @@ CMainFrameBase::CMainFrameBase( wxWindow* parent, wxWindowID id, const wxString& wxBoxSizer* bSizer157; bSizer157 = new wxBoxSizer( wxVERTICAL ); - m_listCtrl = new wxListCtrl( m_panel7, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_NO_SORT_HEADER|wxLC_REPORT|wxLC_SORT_DESCENDING|wxALWAYS_SHOW_SB ); + m_listCtrl = new wxListCtrl( m_panel7, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_NO_SORT_HEADER|wxLC_REPORT|wxLC_SORT_DESCENDING|wxVSCROLL ); bSizer157->Add( m_listCtrl, 1, wxEXPAND|wxALL, 5 ); m_panel7->SetSizer( bSizer157 ); @@ -343,7 +343,7 @@ CTxDetailsDialogBase::CTxDetailsDialogBase( wxWindow* parent, wxWindowID id, con wxBoxSizer* bSizer65; bSizer65 = new wxBoxSizer( wxVERTICAL ); - m_buttonOK = new wxButton( this, wxID_OK, wxT("OK"), wxDefaultPosition, wxSize( 85,25 ), 0 ); + m_buttonOK = new wxButton( this, wxID_OK, wxT("OK"), wxDefaultPosition, wxSize( -1,-1 ), 0 ); bSizer65->Add( m_buttonOK, 0, wxALL, 5 ); bSizer64->Add( bSizer65, 0, wxALIGN_RIGHT, 5 ); @@ -520,17 +520,13 @@ COptionsDialogBase::COptionsDialogBase( wxWindow* parent, wxWindowID id, const w wxBoxSizer* bSizer58; bSizer58 = new wxBoxSizer( wxHORIZONTAL ); - m_buttonOK = new wxButton( this, wxID_OK, wxT("OK"), wxDefaultPosition, wxSize( 85,25 ), 0 ); + m_buttonOK = new wxButton( this, wxID_OK, wxT("OK"), wxDefaultPosition, wxSize( -1,-1 ), 0 ); bSizer58->Add( m_buttonOK, 0, wxALL, 5 ); m_buttonCancel = new wxButton( this, wxID_CANCEL, wxT("Cancel"), wxDefaultPosition, wxSize( -1,-1 ), 0 ); - m_buttonCancel->SetMinSize( wxSize( 85,25 ) ); - bSizer58->Add( m_buttonCancel, 0, wxALL, 5 ); m_buttonApply = new wxButton( this, wxID_APPLY, wxT("&Apply"), wxDefaultPosition, wxSize( -1,-1 ), 0 ); - m_buttonApply->SetMinSize( wxSize( 85,25 ) ); - bSizer58->Add( m_buttonApply, 0, wxALL, 5 ); bSizer55->Add( bSizer58, 0, wxALIGN_RIGHT, 5 ); @@ -622,7 +618,7 @@ CAboutDialogBase::CAboutDialogBase( wxWindow* parent, wxWindowID id, const wxStr bSizer61->Add( 0, 0, 1, wxEXPAND, 5 ); - m_buttonOK = new wxButton( this, wxID_OK, wxT("OK"), wxDefaultPosition, wxSize( 85,25 ), 0 ); + m_buttonOK = new wxButton( this, wxID_OK, wxT("OK"), wxDefaultPosition, wxSize( -1,-1 ), 0 ); bSizer61->Add( m_buttonOK, 0, wxALL, 5 ); bSizer60->Add( bSizer61, 0, wxALIGN_RIGHT|wxEXPAND, 5 ); @@ -767,13 +763,10 @@ CSendDialogBase::CSendDialogBase( wxWindow* parent, wxWindowID id, const wxStrin m_buttonSend = new wxButton( this, wxID_BUTTONSEND, wxT("&Send"), wxDefaultPosition, wxSize( -1,-1 ), 0 ); m_buttonSend->SetFont( wxFont( wxNORMAL_FONT->GetPointSize(), 70, 90, 90, false, wxEmptyString ) ); - m_buttonSend->SetMinSize( wxSize( 85,25 ) ); bSizer23->Add( m_buttonSend, 0, wxALL, 5 ); m_buttonCancel = new wxButton( this, wxID_CANCEL, wxT("Cancel"), wxDefaultPosition, wxSize( -1,-1 ), 0 ); - m_buttonCancel->SetMinSize( wxSize( 85,25 ) ); - bSizer23->Add( m_buttonCancel, 0, wxALL, 5 ); bSizer21->Add( bSizer23, 0, wxEXPAND, 5 ); @@ -833,13 +826,10 @@ CSendingDialogBase::CSendingDialogBase( wxWindow* parent, wxWindowID id, const w m_buttonOK = new wxButton( this, wxID_ANY, wxT("OK"), wxDefaultPosition, wxDefaultSize, 0 ); m_buttonOK->Enable( false ); - m_buttonOK->SetMinSize( wxSize( 85,25 ) ); bSizer69->Add( m_buttonOK, 0, wxALL, 5 ); m_buttonCancel = new wxButton( this, wxID_CANCEL, wxT("Cancel"), wxDefaultPosition, wxSize( -1,-1 ), 0 ); - m_buttonCancel->SetMinSize( wxSize( 85,25 ) ); - bSizer69->Add( m_buttonCancel, 0, wxALL, 5 ); bSizer68->Add( bSizer69, 0, wxEXPAND, 5 ); @@ -887,28 +877,19 @@ CYourAddressDialogBase::CYourAddressDialogBase( wxWindow* parent, wxWindowID id, bSizer69->Add( 0, 0, 1, wxEXPAND, 5 ); m_buttonRename = new wxButton( this, wxID_BUTTONRENAME, wxT("&Edit..."), wxDefaultPosition, wxDefaultSize, 0 ); - m_buttonRename->SetMinSize( wxSize( 85,25 ) ); - bSizer69->Add( m_buttonRename, 0, wxALL, 5 ); m_buttonNew = new wxButton( this, wxID_BUTTONNEW, wxT("&New Address..."), wxDefaultPosition, wxSize( -1,-1 ), 0 ); - m_buttonNew->SetMinSize( wxSize( 110,25 ) ); - bSizer69->Add( m_buttonNew, 0, wxALL, 5 ); m_buttonCopy = new wxButton( this, wxID_BUTTONCOPY, wxT("&Copy to Clipboard"), wxDefaultPosition, wxSize( -1,-1 ), 0 ); - m_buttonCopy->SetMinSize( wxSize( 120,25 ) ); - bSizer69->Add( m_buttonCopy, 0, wxALL, 5 ); m_buttonOK = new wxButton( this, wxID_OK, wxT("OK"), wxDefaultPosition, wxDefaultSize, 0 ); - m_buttonOK->SetMinSize( wxSize( 85,25 ) ); - bSizer69->Add( m_buttonOK, 0, wxALL, 5 ); m_buttonCancel = new wxButton( this, wxID_CANCEL, wxT("Cancel"), wxDefaultPosition, wxSize( -1,-1 ), 0 ); m_buttonCancel->Hide(); - m_buttonCancel->SetMinSize( wxSize( 85,25 ) ); bSizer69->Add( m_buttonCancel, 0, wxALL, 5 ); @@ -969,28 +950,18 @@ CAddressBookDialogBase::CAddressBookDialogBase( wxWindow* parent, wxWindowID id, bSizer69->Add( 0, 0, 1, wxEXPAND, 5 ); m_buttonEdit = new wxButton( this, wxID_BUTTONEDIT, wxT("&Edit..."), wxDefaultPosition, wxDefaultSize, 0 ); - m_buttonEdit->SetMinSize( wxSize( 85,25 ) ); - bSizer69->Add( m_buttonEdit, 0, wxALL, 5 ); m_buttonNew = new wxButton( this, wxID_BUTTONNEW, wxT("&New Address..."), wxDefaultPosition, wxDefaultSize, 0 ); - m_buttonNew->SetMinSize( wxSize( 110,25 ) ); - bSizer69->Add( m_buttonNew, 0, wxALL, 5 ); m_buttonDelete = new wxButton( this, wxID_BUTTONDELETE, wxT("&Delete"), wxDefaultPosition, wxDefaultSize, 0 ); - m_buttonDelete->SetMinSize( wxSize( 85,25 ) ); - bSizer69->Add( m_buttonDelete, 0, wxALL, 5 ); m_buttonOK = new wxButton( this, wxID_OK, wxT("OK"), wxDefaultPosition, wxSize( -1,-1 ), 0 ); - m_buttonOK->SetMinSize( wxSize( 85,25 ) ); - bSizer69->Add( m_buttonOK, 0, wxALL, 5 ); m_buttonCancel = new wxButton( this, wxID_CANCEL, wxT("Cancel"), wxDefaultPosition, wxSize( -1,-1 ), 0 ); - m_buttonCancel->SetMinSize( wxSize( 85,25 ) ); - bSizer69->Add( m_buttonCancel, 0, wxALL, 5 ); bSizer68->Add( bSizer69, 0, wxEXPAND, 5 ); @@ -1389,18 +1360,12 @@ CEditProductDialogBase::CEditProductDialogBase( wxWindow* parent, wxWindowID id, bSizer26 = new wxBoxSizer( wxHORIZONTAL ); m_buttonOK = new wxButton( this, wxID_BUTTONSEND, wxT("&Send"), wxDefaultPosition, wxDefaultSize, 0 ); - m_buttonOK->SetMinSize( wxSize( 85,25 ) ); - bSizer26->Add( m_buttonOK, 0, wxALL, 5 ); m_buttonPreview = new wxButton( this, wxID_BUTTONPREVIEW, wxT("&Preview"), wxDefaultPosition, wxDefaultSize, 0 ); - m_buttonPreview->SetMinSize( wxSize( 85,25 ) ); - bSizer26->Add( m_buttonPreview, 0, wxALL, 5 ); m_buttonCancel = new wxButton( this, wxID_CANCEL, wxT("Cancel"), wxDefaultPosition, wxDefaultSize, 0 ); - m_buttonCancel->SetMinSize( wxSize( 85,25 ) ); - bSizer26->Add( m_buttonCancel, 0, wxALL, 5 ); bSizer20->Add( bSizer26, 0, wxALIGN_RIGHT, 5 ); @@ -1605,18 +1570,13 @@ CViewProductDialogBase::CViewProductDialogBase( wxWindow* parent, wxWindowID id, m_buttonBack = new wxButton( this, wxID_BUTTONBACK, wxT("< &Back "), wxDefaultPosition, wxDefaultSize, 0 ); m_buttonBack->Enable( false ); - m_buttonBack->SetMinSize( wxSize( 85,25 ) ); bSizer26->Add( m_buttonBack, 0, wxALL, 5 ); m_buttonNext = new wxButton( this, wxID_BUTTONNEXT, wxT(" &Next >"), wxDefaultPosition, wxDefaultSize, 0 ); - m_buttonNext->SetMinSize( wxSize( 85,25 ) ); - bSizer26->Add( m_buttonNext, 0, wxALL, 5 ); m_buttonCancel = new wxButton( this, wxID_CANCEL, wxT("Cancel"), wxDefaultPosition, wxDefaultSize, 0 ); - m_buttonCancel->SetMinSize( wxSize( 85,25 ) ); - bSizer26->Add( m_buttonCancel, 0, wxALL, 5 ); bSizer20->Add( bSizer26, 0, wxALIGN_RIGHT, 5 ); @@ -1662,8 +1622,6 @@ CViewOrderDialogBase::CViewOrderDialogBase( wxWindow* parent, wxWindowID id, con bSizer26 = new wxBoxSizer( wxHORIZONTAL ); m_buttonOK = new wxButton( this, wxID_OK, wxT("OK"), wxDefaultPosition, wxDefaultSize, 0 ); - m_buttonOK->SetMinSize( wxSize( 85,25 ) ); - bSizer26->Add( m_buttonOK, 0, wxALL, 5 ); bSizer20->Add( bSizer26, 0, wxALIGN_RIGHT, 5 ); @@ -1720,13 +1678,9 @@ CEditReviewDialogBase::CEditReviewDialogBase( wxWindow* parent, wxWindowID id, c bSizer113 = new wxBoxSizer( wxHORIZONTAL ); m_buttonSubmit = new wxButton( this, wxID_SUBMIT, wxT("&Submit"), wxDefaultPosition, wxDefaultSize, 0 ); - m_buttonSubmit->SetMinSize( wxSize( 85,25 ) ); - bSizer113->Add( m_buttonSubmit, 0, wxALL, 5 ); m_buttonCancel = new wxButton( this, wxID_CANCEL, wxT("Cancel"), wxDefaultPosition, wxDefaultSize, 0 ); - m_buttonCancel->SetMinSize( wxSize( 85,25 ) ); - bSizer113->Add( m_buttonCancel, 0, wxALL, 5 ); bSizer112->Add( bSizer113, 0, wxALIGN_RIGHT, 5 ); @@ -1951,13 +1905,9 @@ CGetTextFromUserDialogBase::CGetTextFromUserDialogBase( wxWindow* parent, wxWind bSizer80->Add( 0, 0, 1, wxEXPAND, 5 ); m_buttonOK = new wxButton( this, wxID_OK, wxT("OK"), wxDefaultPosition, wxSize( -1,-1 ), 0 ); - m_buttonOK->SetMinSize( wxSize( 85,25 ) ); - bSizer80->Add( m_buttonOK, 0, wxALL, 5 ); m_buttonCancel = new wxButton( this, wxID_CANCEL, wxT("Cancel"), wxDefaultPosition, wxDefaultSize, 0 ); - m_buttonCancel->SetMinSize( wxSize( 85,25 ) ); - bSizer80->Add( m_buttonCancel, 0, wxALL, 5 ); bSizer79->Add( bSizer80, 0, wxEXPAND, 5 ); diff --git a/uiproject.fbp b/uiproject.fbp index 7bce7349f5..17656b56a5 100644 --- a/uiproject.fbp +++ b/uiproject.fbp @@ -70,7 +70,7 @@ - + 240,240,240 1 @@ -225,7 +225,7 @@ - + 20,20 @@ -439,7 +439,7 @@ m_textCtrlAddress protected - 250,-1 + 340,-1 wxTE_READONLY @@ -944,7 +944,7 @@ - wxALWAYS_SHOW_SB + wxVSCROLL @@ -1648,7 +1648,7 @@ m_buttonOK protected - 85,25 + -1,-1 @@ -3031,7 +3031,7 @@ m_buttonOK protected - 85,25 + -1,-1 @@ -3079,7 +3079,7 @@ wxID_CANCEL Cancel - 85,25 + -1,-1 m_buttonCancel protected @@ -3131,7 +3131,7 @@ wxID_APPLY &Apply - 85,25 + -1,-1 m_buttonApply protected @@ -3493,7 +3493,7 @@ m_buttonOK protected - 85,25 + -1,-1 @@ -4485,7 +4485,7 @@ wxID_BUTTONSEND &Send - 85,25 + -1,-1 m_buttonSend protected @@ -4537,7 +4537,7 @@ wxID_CANCEL Cancel - 85,25 + -1,-1 m_buttonCancel protected @@ -4775,7 +4775,7 @@ wxID_ANY OK - 85,25 + -1,-1 m_buttonOK protected @@ -4827,7 +4827,7 @@ wxID_CANCEL Cancel - 85,25 + -1,-1 m_buttonCancel protected @@ -5089,7 +5089,7 @@ wxID_BUTTONRENAME &Edit... - 85,25 + -1,-1 m_buttonRename protected @@ -5141,7 +5141,7 @@ wxID_BUTTONNEW &New Address... - 110,25 + -1,-1 m_buttonNew protected @@ -5193,7 +5193,7 @@ wxID_BUTTONCOPY &Copy to Clipboard - 120,25 + -1,-1 m_buttonCopy protected @@ -5245,7 +5245,7 @@ wxID_OK OK - 85,25 + -1,-1 m_buttonOK protected @@ -5297,7 +5297,7 @@ wxID_CANCEL Cancel - 85,25 + -1,-1 m_buttonCancel protected @@ -5559,7 +5559,7 @@ wxID_BUTTONEDIT &Edit... - 85,25 + -1,-1 m_buttonEdit protected @@ -5611,7 +5611,7 @@ wxID_BUTTONNEW &New Address... - 110,25 + -1,-1 m_buttonNew protected @@ -5663,7 +5663,7 @@ wxID_BUTTONDELETE &Delete - 85,25 + -1,-1 m_buttonDelete protected @@ -5715,7 +5715,7 @@ wxID_OK OK - 85,25 + -1,-1 m_buttonOK protected @@ -5767,7 +5767,7 @@ wxID_CANCEL Cancel - 85,25 + -1,-1 m_buttonCancel public @@ -10225,7 +10225,7 @@ wxID_BUTTONSEND &Send - 85,25 + -1,-1 m_buttonOK protected @@ -10277,7 +10277,7 @@ wxID_BUTTONPREVIEW &Preview - 85,25 + -1,-1 m_buttonPreview protected @@ -10329,7 +10329,7 @@ wxID_CANCEL Cancel - 85,25 + -1,-1 m_buttonCancel protected @@ -10798,7 +10798,7 @@ wxID_BUTTONBACK < &Back - 85,25 + -1,-1 m_buttonBack protected @@ -10850,7 +10850,7 @@ wxID_BUTTONNEXT &Next > - 85,25 + -1,-1 m_buttonNext protected @@ -10902,7 +10902,7 @@ wxID_CANCEL Cancel - 85,25 + -1,-1 m_buttonCancel protected @@ -11087,7 +11087,7 @@ wxID_OK OK - 85,25 + -1,-1 m_buttonOK protected @@ -11488,7 +11488,7 @@ wxID_SUBMIT &Submit - 85,25 + -1,-1 m_buttonSubmit protected @@ -11540,7 +11540,7 @@ wxID_CANCEL Cancel - 85,25 + -1,-1 m_buttonCancel protected @@ -12907,7 +12907,7 @@ wxID_OK OK - 85,25 + -1,-1 m_buttonOK protected @@ -12959,7 +12959,7 @@ wxID_CANCEL Cancel - 85,25 + -1,-1 m_buttonCancel protected diff --git a/util.cpp b/util.cpp index d2e624d676..5efb579bf7 100644 --- a/util.cpp +++ b/util.cpp @@ -96,12 +96,7 @@ void RandAddSeedPerfmon() hash = 0; memset(pdata, 0, nSize); - time_t nTime; - time(&nTime); - struct tm* ptmTime = gmtime(&nTime); - char pszTime[200]; - strftime(pszTime, sizeof(pszTime), "%x %H:%M:%S", ptmTime); - printf("%s RandAddSeed() %d bytes\n", pszTime, nSize); + printf("%s RandAddSeed() %d bytes\n", DateTimeStrFormat("%x %H:%M:%S", GetTime()).c_str(), nSize); } #endif } @@ -350,7 +345,9 @@ void FormatException(char* pszMessage, std::exception* pex, const char* pszThrea pszModule[0] = '\0'; GetModuleFileName(NULL, pszModule, sizeof(pszModule)); #else - const char* pszModule = wxStandardPaths::Get().GetExecutablePath().mb_str(); + // might not be thread safe, uses wxString + //const char* pszModule = wxStandardPaths::Get().GetExecutablePath().mb_str(); + const char* pszModule = "bitcoin"; #endif if (pex) snprintf(pszMessage, 1000, @@ -425,7 +422,6 @@ void GetDataDir(char* pszDir) } strlcpy(pszDir, pszCachedDir, MAX_PATH); } - } string GetDataDir() diff --git a/util.h b/util.h index 3bc7c798a5..8fcfcd0dc9 100644 --- a/util.h +++ b/util.h @@ -84,6 +84,10 @@ inline void SetThreadPriority(int nThread, int nPriority) { setpriority(PRIO_PRO #define THREAD_PRIORITY_NORMAL 0 #define THREAD_PRIORITY_ABOVE_NORMAL 0 #endif +#ifndef MSG_NOSIGNAL +#define MSG_NOSIGNAL 0 +#endif + @@ -379,6 +383,14 @@ inline int64 GetTimeMillis() return wxGetLocalTimeMillis().GetValue(); } +inline string DateTimeStrFormat(const char* pszFormat, int64 nTime) +{ + time_t n = nTime; + struct tm* ptmTime = gmtime(&n); + char pszTime[200]; + strftime(pszTime, sizeof(pszTime), pszFormat, ptmTime); + return pszTime; +} @@ -400,7 +412,7 @@ inline void heapchk() { \ static char nLoops; \ if (nLoops <= 0) \ - nLoops = GetRand(50) + 1; \ + nLoops = GetRand(20) + 1; \ if (nLoops-- > 1) \ { \ ThreadFn; \ -- cgit v1.2.3 From 85c33b960211722e2183e90b2fa0460f5fe52467 Mon Sep 17 00:00:00 2001 From: s_nakamoto Date: Fri, 6 Nov 2009 18:53:26 +0000 Subject: UIThreadCall, ThreadSafeMessageBox --- headers.h | 2 + main.cpp | 2 +- ui.cpp | 68 ++-- ui.h | 22 +- uibase.cpp | 160 ---------- uibase.h | 82 +---- uiproject.fbp | 992 ---------------------------------------------------------- 7 files changed, 44 insertions(+), 1284 deletions(-) diff --git a/headers.h b/headers.h index c7f3cd8514..6cd2da07db 100644 --- a/headers.h +++ b/headers.h @@ -53,6 +53,8 @@ #include #include #include +#include +#include #ifdef __WXMSW__ #include diff --git a/main.cpp b/main.cpp index cc22bad679..e4f1deb841 100644 --- a/main.cpp +++ b/main.cpp @@ -1381,7 +1381,7 @@ bool CheckDiskSpace(int64 nAdditionalBytes) if (nFreeBytesAvailable < (int64)15000000 + nAdditionalBytes) { fShutdown = true; - wxMessageBox("Warning: Your disk space is low ", "Bitcoin", wxICON_EXCLAMATION); + ThreadSafeMessageBox("Warning: Your disk space is low ", "Bitcoin", wxOK | wxICON_EXCLAMATION); _beginthread(Shutdown, 0, NULL); return false; } diff --git a/ui.cpp b/ui.cpp index 92e1d59ce6..d330231341 100644 --- a/ui.cpp +++ b/ui.cpp @@ -14,13 +14,10 @@ void SetStartOnSystemStartup(bool fAutoStart); -DEFINE_EVENT_TYPE(wxEVT_CROSSTHREADCALL) +DEFINE_EVENT_TYPE(wxEVT_UITHREADCALL) DEFINE_EVENT_TYPE(wxEVT_REPLY1) DEFINE_EVENT_TYPE(wxEVT_REPLY2) DEFINE_EVENT_TYPE(wxEVT_REPLY3) -DEFINE_EVENT_TYPE(wxEVT_TABLEADDED) -DEFINE_EVENT_TYPE(wxEVT_TABLEUPDATED) -DEFINE_EVENT_TYPE(wxEVT_TABLEDELETED) CMainFrame* pframeMain = NULL; CMyTaskBarIcon* ptaskbaricon = NULL; @@ -184,6 +181,24 @@ void AddToMyProducts(CProduct product) ""); } +void StringMessageBox(const string& message, const string& caption, int style, wxWindow* parent, int x, int y) +{ + wxMessageBox(message, caption, style, parent, x, y); +} + +int ThreadSafeMessageBox(const string& message, const string& caption, int style, wxWindow* parent, int x, int y) +{ +#ifdef __WXMSW__ + wxMessageBox(message, caption, style, parent, x, y); +#else + UIThreadCall(bind(StringMessageBox, message, caption, style, parent, x, y)); +#endif +} + + + + + @@ -193,6 +208,7 @@ void AddToMyProducts(CProduct product) // // Custom events // +// If this code gets used again, it should be replaced with something like UIThreadCall set setCallbackAvailable; CCriticalSection cs_setCallbackAvailable; @@ -279,7 +295,7 @@ CDataStream GetStreamFromEvent(const wxCommandEvent& event) CMainFrame::CMainFrame(wxWindow* parent) : CMainFrameBase(parent) { - Connect(wxEVT_CROSSTHREADCALL, wxCommandEventHandler(CMainFrame::OnCrossThreadCall), NULL, this); + Connect(wxEVT_UITHREADCALL, wxCommandEventHandler(CMainFrame::OnUIThreadCall), NULL, this); // Init fRefreshListCtrl = false; @@ -982,36 +998,27 @@ void CMainFrame::OnPaintListCtrl(wxPaintEvent& event) } -void CrossThreadCall(wxCommandEvent& event) +void UIThreadCall(boost::function 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::function(fn)); pframeMain->GetEventHandler()->AddPendingEvent(event); + } } -void CrossThreadCall(int nID, void* pdata) -{ - wxCommandEvent event; - event.SetInt(nID); - event.SetClientData(pdata); - if (pframeMain) - pframeMain->GetEventHandler()->AddPendingEvent(event); -} - -void CMainFrame::OnCrossThreadCall(wxCommandEvent& event) +void CMainFrame::OnUIThreadCall(wxCommandEvent& event) { - void* pdata = event.GetClientData(); - switch (event.GetInt()) - { - case UICALL_ADDORDER: - { - break; - } - - case UICALL_UPDATEORDER: - { - break; - } - } + boost::function* pfn = (boost::function*)event.GetClientData(); + (*pfn)(); + delete pfn; } void CMainFrame::OnMenuFileExit(wxCommandEvent& event) @@ -3305,9 +3312,6 @@ wxMenu* CMyTaskBarIcon::CreatePopupMenu() - - - ////////////////////////////////////////////////////////////////////////////// // // CMyApp diff --git a/ui.h b/ui.h index 1d0491f109..1db40997f4 100644 --- a/ui.h +++ b/ui.h @@ -5,19 +5,10 @@ -DECLARE_EVENT_TYPE(wxEVT_CROSSTHREADCALL, -1) +DECLARE_EVENT_TYPE(wxEVT_UITHREADCALL, -1) DECLARE_EVENT_TYPE(wxEVT_REPLY1, -1) DECLARE_EVENT_TYPE(wxEVT_REPLY2, -1) DECLARE_EVENT_TYPE(wxEVT_REPLY3, -1) -DECLARE_EVENT_TYPE(wxEVT_TABLEADDED, -1) -DECLARE_EVENT_TYPE(wxEVT_TABLEUPDATED, -1) -DECLARE_EVENT_TYPE(wxEVT_TABLEDELETED, -1) - -enum -{ - UICALL_ADDORDER = 1, - UICALL_UPDATEORDER, -}; @@ -33,9 +24,10 @@ extern int fMinimizeOnClose; extern void HandleCtrlA(wxKeyEvent& event); extern string FormatTxStatus(const CWalletTx& wtx); -extern void CrossThreadCall(int nID, void* pdata); +extern void UIThreadCall(boost::function); extern void MainFrameRepaint(); extern void Shutdown(void* parg); +extern int ThreadSafeMessageBox(const string& message, const string& caption="Message", int style=wxOK, wxWindow* parent=NULL, int x=-1, int y=-1); @@ -85,7 +77,7 @@ public: unsigned int nListViewUpdated; bool fRefresh; - void OnCrossThreadCall(wxCommandEvent& event); + void OnUIThreadCall(wxCommandEvent& event); int GetSortIndex(const string& strSort); void InsertLine(bool fNew, int nIndex, uint256 hashKey, string strSort, const wxString& str1, const wxString& str2, const wxString& str3, const wxString& str4, const wxString& str5); bool DeleteLine(uint256 hashKey); @@ -473,9 +465,3 @@ public: DECLARE_EVENT_TABLE() }; - - - - - - diff --git a/uibase.cpp b/uibase.cpp index 9a61999523..6a280cda64 100644 --- a/uibase.cpp +++ b/uibase.cpp @@ -1702,166 +1702,6 @@ CEditReviewDialogBase::~CEditReviewDialogBase() m_buttonCancel->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditReviewDialogBase::OnButtonCancel ), NULL, this ); } -CPokerLobbyDialogBase::CPokerLobbyDialogBase( 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 ) ); - - wxBoxSizer* bSizer156; - bSizer156 = new wxBoxSizer( wxHORIZONTAL ); - - m_treeCtrl = new wxTreeCtrl( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTR_HAS_BUTTONS|wxTR_HIDE_ROOT|wxTR_LINES_AT_ROOT ); - m_treeCtrl->SetMinSize( wxSize( 130,-1 ) ); - - bSizer156->Add( m_treeCtrl, 0, wxEXPAND|wxTOP|wxBOTTOM|wxLEFT, 5 ); - - wxBoxSizer* bSizer172; - bSizer172 = new wxBoxSizer( wxVERTICAL ); - - m_listCtrl = new wxListCtrl( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_NO_SORT_HEADER|wxLC_REPORT ); - bSizer172->Add( m_listCtrl, 1, wxEXPAND|wxALL, 5 ); - - m_buttonNewTable = new wxButton( this, wxID_OPENNEWTABLE, wxT("&Open New Table"), wxDefaultPosition, wxDefaultSize, 0 ); - bSizer172->Add( m_buttonNewTable, 0, wxALL, 5 ); - - bSizer156->Add( bSizer172, 1, wxEXPAND, 5 ); - - this->SetSizer( bSizer156 ); - this->Layout(); - - // Connect Events - m_treeCtrl->Connect( wxEVT_COMMAND_TREE_SEL_CHANGED, wxTreeEventHandler( CPokerLobbyDialogBase::OnTreeSelChanged ), NULL, this ); - m_listCtrl->Connect( wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler( CPokerLobbyDialogBase::OnListItemActivated ), NULL, this ); - m_listCtrl->Connect( wxEVT_COMMAND_LIST_ITEM_SELECTED, wxListEventHandler( CPokerLobbyDialogBase::OnListItemSelected ), NULL, this ); - m_buttonNewTable->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CPokerLobbyDialogBase::OnButtonNewTable ), NULL, this ); -} - -CPokerLobbyDialogBase::~CPokerLobbyDialogBase() -{ - // Disconnect Events - m_treeCtrl->Disconnect( wxEVT_COMMAND_TREE_SEL_CHANGED, wxTreeEventHandler( CPokerLobbyDialogBase::OnTreeSelChanged ), NULL, this ); - m_listCtrl->Disconnect( wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler( CPokerLobbyDialogBase::OnListItemActivated ), NULL, this ); - m_listCtrl->Disconnect( wxEVT_COMMAND_LIST_ITEM_SELECTED, wxListEventHandler( CPokerLobbyDialogBase::OnListItemSelected ), NULL, this ); - m_buttonNewTable->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CPokerLobbyDialogBase::OnButtonNewTable ), NULL, this ); -} - -CPokerDialogBase::CPokerDialogBase( 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 ); - - wxBoxSizer* bSizer174; - bSizer174 = new wxBoxSizer( wxVERTICAL ); - - m_checkSitOut = new wxCheckBox( this, wxID_ANY, wxT("Deal Me Out"), wxDefaultPosition, wxDefaultSize, 0 ); - - bSizer174->Add( m_checkSitOut, 0, wxALL, 5 ); - - m_buttonDealHand = new wxButton( this, wxID_DEALHAND, wxT("&Deal Hand"), wxDefaultPosition, wxSize( 150,25 ), 0 ); - bSizer174->Add( m_buttonDealHand, 0, wxALL, 5 ); - - m_buttonFold = new wxButton( this, wxID_FOLD, wxT("&Fold"), wxDefaultPosition, wxSize( 80,25 ), 0 ); - bSizer174->Add( m_buttonFold, 0, wxALL, 5 ); - - m_buttonCall = new wxButton( this, wxID_CALL, wxT("&Call"), wxDefaultPosition, wxSize( 80,25 ), 0 ); - bSizer174->Add( m_buttonCall, 0, wxALL, 5 ); - - m_buttonRaise = new wxButton( this, wxID_RAISE, wxT("&Raise"), wxDefaultPosition, wxSize( 80,25 ), 0 ); - bSizer174->Add( m_buttonRaise, 0, wxALL, 5 ); - - m_buttonLeaveTable = new wxButton( this, wxID_LEAVETABLE, wxT("&Leave Table"), wxDefaultPosition, wxSize( 90,25 ), 0 ); - bSizer174->Add( m_buttonLeaveTable, 0, wxALL, 5 ); - - m_textDitchPlayer = new wxTextCtrl( this, wxID_DITCHPLAYER, wxEmptyString, wxDefaultPosition, wxSize( 45,-1 ), wxTE_PROCESS_ENTER ); - bSizer174->Add( m_textDitchPlayer, 0, wxALL, 5 ); - - m_checkPreFold = new wxCheckBox( this, wxID_ANY, wxT("FOLD"), wxDefaultPosition, wxSize( 100,-1 ), 0 ); - - bSizer174->Add( m_checkPreFold, 0, wxALL, 5 ); - - m_checkPreCall = new wxCheckBox( this, wxID_ANY, wxT("CALL"), wxDefaultPosition, wxSize( 100,-1 ), 0 ); - - bSizer174->Add( m_checkPreCall, 0, wxALL, 5 ); - - m_checkPreCallAny = new wxCheckBox( this, wxID_ANY, wxT("CALL ANY"), wxDefaultPosition, wxSize( 100,-1 ), 0 ); - - bSizer174->Add( m_checkPreCallAny, 0, wxALL, 5 ); - - m_checkPreRaise = new wxCheckBox( this, wxID_ANY, wxT("RAISE"), wxDefaultPosition, wxSize( 100,-1 ), 0 ); - - bSizer174->Add( m_checkPreRaise, 0, wxALL, 5 ); - - m_checkPreRaiseAny = new wxCheckBox( this, wxID_ANY, wxT("RAISE ANY"), wxDefaultPosition, wxSize( 100,-1 ), 0 ); - - bSizer174->Add( m_checkPreRaiseAny, 0, wxALL, 5 ); - - this->SetSizer( bSizer174 ); - this->Layout(); - m_statusBar = this->CreateStatusBar( 1, wxST_SIZEGRIP, wxID_ANY ); - - // Connect Events - this->Connect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( CPokerDialogBase::OnClose ) ); - this->Connect( wxEVT_LEFT_DOWN, wxMouseEventHandler( CPokerDialogBase::OnMouseEvents ) ); - this->Connect( wxEVT_LEFT_UP, wxMouseEventHandler( CPokerDialogBase::OnMouseEvents ) ); - this->Connect( wxEVT_MIDDLE_DOWN, wxMouseEventHandler( CPokerDialogBase::OnMouseEvents ) ); - this->Connect( wxEVT_MIDDLE_UP, wxMouseEventHandler( CPokerDialogBase::OnMouseEvents ) ); - this->Connect( wxEVT_RIGHT_DOWN, wxMouseEventHandler( CPokerDialogBase::OnMouseEvents ) ); - this->Connect( wxEVT_RIGHT_UP, wxMouseEventHandler( CPokerDialogBase::OnMouseEvents ) ); - this->Connect( wxEVT_MOTION, wxMouseEventHandler( CPokerDialogBase::OnMouseEvents ) ); - this->Connect( wxEVT_LEFT_DCLICK, wxMouseEventHandler( CPokerDialogBase::OnMouseEvents ) ); - this->Connect( wxEVT_MIDDLE_DCLICK, wxMouseEventHandler( CPokerDialogBase::OnMouseEvents ) ); - this->Connect( wxEVT_RIGHT_DCLICK, wxMouseEventHandler( CPokerDialogBase::OnMouseEvents ) ); - this->Connect( wxEVT_LEAVE_WINDOW, wxMouseEventHandler( CPokerDialogBase::OnMouseEvents ) ); - this->Connect( wxEVT_ENTER_WINDOW, wxMouseEventHandler( CPokerDialogBase::OnMouseEvents ) ); - this->Connect( wxEVT_MOUSEWHEEL, wxMouseEventHandler( CPokerDialogBase::OnMouseEvents ) ); - this->Connect( wxEVT_PAINT, wxPaintEventHandler( CPokerDialogBase::OnPaint ) ); - this->Connect( wxEVT_SIZE, wxSizeEventHandler( CPokerDialogBase::OnSize ) ); - m_checkSitOut->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( CPokerDialogBase::OnCheckSitOut ), NULL, this ); - m_buttonDealHand->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CPokerDialogBase::OnButtonDealHand ), NULL, this ); - m_buttonFold->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CPokerDialogBase::OnButtonFold ), NULL, this ); - m_buttonCall->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CPokerDialogBase::OnButtonCall ), NULL, this ); - m_buttonRaise->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CPokerDialogBase::OnButtonRaise ), NULL, this ); - m_buttonLeaveTable->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CPokerDialogBase::OnButtonLeaveTable ), NULL, this ); - m_textDitchPlayer->Connect( wxEVT_COMMAND_TEXT_ENTER, wxCommandEventHandler( CPokerDialogBase::OnDitchPlayer ), NULL, this ); - m_checkPreFold->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( CPokerDialogBase::OnCheckPreFold ), NULL, this ); - m_checkPreCall->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( CPokerDialogBase::OnCheckPreCall ), NULL, this ); - m_checkPreCallAny->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( CPokerDialogBase::OnCheckPreCallAny ), NULL, this ); - m_checkPreRaise->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( CPokerDialogBase::OnCheckPreRaise ), NULL, this ); - m_checkPreRaiseAny->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( CPokerDialogBase::OnCheckPreRaiseAny ), NULL, this ); -} - -CPokerDialogBase::~CPokerDialogBase() -{ - // Disconnect Events - this->Disconnect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( CPokerDialogBase::OnClose ) ); - this->Disconnect( wxEVT_LEFT_DOWN, wxMouseEventHandler( CPokerDialogBase::OnMouseEvents ) ); - this->Disconnect( wxEVT_LEFT_UP, wxMouseEventHandler( CPokerDialogBase::OnMouseEvents ) ); - this->Disconnect( wxEVT_MIDDLE_DOWN, wxMouseEventHandler( CPokerDialogBase::OnMouseEvents ) ); - this->Disconnect( wxEVT_MIDDLE_UP, wxMouseEventHandler( CPokerDialogBase::OnMouseEvents ) ); - this->Disconnect( wxEVT_RIGHT_DOWN, wxMouseEventHandler( CPokerDialogBase::OnMouseEvents ) ); - this->Disconnect( wxEVT_RIGHT_UP, wxMouseEventHandler( CPokerDialogBase::OnMouseEvents ) ); - this->Disconnect( wxEVT_MOTION, wxMouseEventHandler( CPokerDialogBase::OnMouseEvents ) ); - this->Disconnect( wxEVT_LEFT_DCLICK, wxMouseEventHandler( CPokerDialogBase::OnMouseEvents ) ); - this->Disconnect( wxEVT_MIDDLE_DCLICK, wxMouseEventHandler( CPokerDialogBase::OnMouseEvents ) ); - this->Disconnect( wxEVT_RIGHT_DCLICK, wxMouseEventHandler( CPokerDialogBase::OnMouseEvents ) ); - this->Disconnect( wxEVT_LEAVE_WINDOW, wxMouseEventHandler( CPokerDialogBase::OnMouseEvents ) ); - this->Disconnect( wxEVT_ENTER_WINDOW, wxMouseEventHandler( CPokerDialogBase::OnMouseEvents ) ); - this->Disconnect( wxEVT_MOUSEWHEEL, wxMouseEventHandler( CPokerDialogBase::OnMouseEvents ) ); - this->Disconnect( wxEVT_PAINT, wxPaintEventHandler( CPokerDialogBase::OnPaint ) ); - this->Disconnect( wxEVT_SIZE, wxSizeEventHandler( CPokerDialogBase::OnSize ) ); - m_checkSitOut->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( CPokerDialogBase::OnCheckSitOut ), NULL, this ); - m_buttonDealHand->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CPokerDialogBase::OnButtonDealHand ), NULL, this ); - m_buttonFold->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CPokerDialogBase::OnButtonFold ), NULL, this ); - m_buttonCall->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CPokerDialogBase::OnButtonCall ), NULL, this ); - m_buttonRaise->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CPokerDialogBase::OnButtonRaise ), NULL, this ); - m_buttonLeaveTable->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CPokerDialogBase::OnButtonLeaveTable ), NULL, this ); - m_textDitchPlayer->Disconnect( wxEVT_COMMAND_TEXT_ENTER, wxCommandEventHandler( CPokerDialogBase::OnDitchPlayer ), NULL, this ); - m_checkPreFold->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( CPokerDialogBase::OnCheckPreFold ), NULL, this ); - m_checkPreCall->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( CPokerDialogBase::OnCheckPreCall ), NULL, this ); - m_checkPreCallAny->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( CPokerDialogBase::OnCheckPreCallAny ), NULL, this ); - m_checkPreRaise->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( CPokerDialogBase::OnCheckPreRaise ), NULL, this ); - m_checkPreRaiseAny->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( CPokerDialogBase::OnCheckPreRaiseAny ), 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 ); diff --git a/uibase.h b/uibase.h index d52158f127..6332b931c8 100644 --- a/uibase.h +++ b/uibase.h @@ -37,7 +37,6 @@ #include #include #include -#include /////////////////////////////////////////////////////////////////////////// @@ -88,14 +87,7 @@ #define wxID_BUTTONBACK 1044 #define wxID_BUTTONNEXT 1045 #define wxID_SUBMIT 1046 -#define wxID_OPENNEWTABLE 1047 -#define wxID_DEALHAND 1048 -#define wxID_FOLD 1049 -#define wxID_CALL 1050 -#define wxID_RAISE 1051 -#define wxID_LEAVETABLE 1052 -#define wxID_DITCHPLAYER 1053 -#define wxID_TEXTCTRL 1054 +#define wxID_TEXTCTRL 1047 /////////////////////////////////////////////////////////////////////////////// /// Class CMainFrameBase @@ -652,78 +644,6 @@ class CEditReviewDialogBase : public wxFrame }; -/////////////////////////////////////////////////////////////////////////////// -/// Class CPokerLobbyDialogBase -/////////////////////////////////////////////////////////////////////////////// -class CPokerLobbyDialogBase : public wxFrame -{ - private: - - protected: - wxTreeCtrl* m_treeCtrl; - wxListCtrl* m_listCtrl; - wxButton* m_buttonNewTable; - - // Virtual event handlers, overide them in your derived class - virtual void OnTreeSelChanged( wxTreeEvent& event ){ event.Skip(); } - virtual void OnListItemActivated( wxListEvent& event ){ event.Skip(); } - virtual void OnListItemSelected( wxListEvent& event ){ event.Skip(); } - virtual void OnButtonNewTable( wxCommandEvent& event ){ event.Skip(); } - - - public: - CPokerLobbyDialogBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxT("Poker Lobby"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 586,457 ), long style = wxDEFAULT_FRAME_STYLE|wxTAB_TRAVERSAL ); - ~CPokerLobbyDialogBase(); - -}; - -/////////////////////////////////////////////////////////////////////////////// -/// Class CPokerDialogBase -/////////////////////////////////////////////////////////////////////////////// -class CPokerDialogBase : public wxFrame -{ - private: - - protected: - wxButton* m_buttonDealHand; - wxButton* m_buttonFold; - wxButton* m_buttonCall; - wxButton* m_buttonRaise; - wxButton* m_buttonLeaveTable; - wxTextCtrl* m_textDitchPlayer; - - // Virtual event handlers, overide them in your derived class - virtual void OnClose( wxCloseEvent& event ){ event.Skip(); } - virtual void OnMouseEvents( wxMouseEvent& event ){ event.Skip(); } - virtual void OnPaint( wxPaintEvent& event ){ event.Skip(); } - virtual void OnSize( wxSizeEvent& event ){ event.Skip(); } - virtual void OnCheckSitOut( wxCommandEvent& event ){ event.Skip(); } - virtual void OnButtonDealHand( wxCommandEvent& event ){ event.Skip(); } - virtual void OnButtonFold( wxCommandEvent& event ){ event.Skip(); } - virtual void OnButtonCall( wxCommandEvent& event ){ event.Skip(); } - virtual void OnButtonRaise( wxCommandEvent& event ){ event.Skip(); } - virtual void OnButtonLeaveTable( wxCommandEvent& event ){ event.Skip(); } - virtual void OnDitchPlayer( wxCommandEvent& event ){ event.Skip(); } - virtual void OnCheckPreFold( wxCommandEvent& event ){ event.Skip(); } - virtual void OnCheckPreCall( wxCommandEvent& event ){ event.Skip(); } - virtual void OnCheckPreCallAny( wxCommandEvent& event ){ event.Skip(); } - virtual void OnCheckPreRaise( wxCommandEvent& event ){ event.Skip(); } - virtual void OnCheckPreRaiseAny( wxCommandEvent& event ){ event.Skip(); } - - - public: - wxCheckBox* m_checkSitOut; - wxCheckBox* m_checkPreFold; - wxCheckBox* m_checkPreCall; - wxCheckBox* m_checkPreCallAny; - wxCheckBox* m_checkPreRaise; - wxCheckBox* m_checkPreRaiseAny; - wxStatusBar* m_statusBar; - CPokerDialogBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxT("Poker"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 806,550 ), long style = wxDEFAULT_FRAME_STYLE|wxFRAME_NO_TASKBAR|wxFULL_REPAINT_ON_RESIZE|wxTAB_TRAVERSAL ); - ~CPokerDialogBase(); - -}; - /////////////////////////////////////////////////////////////////////////////// /// Class CGetTextFromUserDialogBase /////////////////////////////////////////////////////////////////////////////// diff --git a/uiproject.fbp b/uiproject.fbp index 17656b56a5..7c5bb24f9d 100644 --- a/uiproject.fbp +++ b/uiproject.fbp @@ -11581,998 +11581,6 @@ - - wxSYS_COLOUR_BTNFACE - - - 1 - - - - 0 - wxID_ANY - - - CPokerLobbyDialogBase - - 586,457 - wxDEFAULT_FRAME_STYLE - - Poker Lobby - - - - wxTAB_TRAVERSAL - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - bSizer156 - wxHORIZONTAL - none - - 5 - wxEXPAND|wxTOP|wxBOTTOM|wxLEFT - 0 - - - - 1 - - - 0 - wxID_ANY - - 130,-1 - m_treeCtrl - protected - - - wxTR_HAS_BUTTONS|wxTR_HIDE_ROOT|wxTR_LINES_AT_ROOT - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - OnTreeSelChanged - - - - - - - - 5 - wxEXPAND - 1 - - - bSizer172 - wxVERTICAL - none - - 5 - wxEXPAND|wxALL - 1 - - - - 1 - - - 0 - wxID_ANY - - - m_listCtrl - protected - - - wxLC_NO_SORT_HEADER|wxLC_REPORT - - - - - - - - - - - - - - - - - - - - - - - - - - - - - OnListItemActivated - - - - - OnListItemSelected - - - - - - - - - - - - - - - - - - 5 - wxALL - 0 - - - - 0 - 1 - - - 0 - wxID_OPENNEWTABLE - &Open New Table - - - m_buttonNewTable - protected - - - - - - - - - OnButtonNewTable - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1 - - - - 0 - wxID_ANY - - - CPokerDialogBase - - 806,550 - wxDEFAULT_FRAME_STYLE|wxFRAME_NO_TASKBAR - - Poker - - - - wxFULL_REPAINT_ON_RESIZE|wxTAB_TRAVERSAL - 1 - - - - OnClose - - - - - - - - - - - - - - - - - OnMouseEvents - - OnPaint - - - - - OnSize - - - - bSizer174 - wxVERTICAL - none - - 5 - wxALL - 0 - - - 0 - - 1 - - - 0 - wxID_ANY - Deal Me Out - - - m_checkSitOut - public - - - - - - - - - - OnCheckSitOut - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALL - 0 - - - - 0 - 1 - - - 0 - wxID_DEALHAND - &Deal Hand - - - m_buttonDealHand - protected - - 150,25 - - - - - - - OnButtonDealHand - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALL - 0 - - - - 0 - 1 - - - 0 - wxID_FOLD - &Fold - - - m_buttonFold - protected - - 80,25 - - - - - - - OnButtonFold - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALL - 0 - - - - 0 - 1 - - - 0 - wxID_CALL - &Call - - - m_buttonCall - protected - - 80,25 - - - - - - - OnButtonCall - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALL - 0 - - - - 0 - 1 - - - 0 - wxID_RAISE - &Raise - - - m_buttonRaise - protected - - 80,25 - - - - - - - OnButtonRaise - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALL - 0 - - - - 0 - 1 - - - 0 - wxID_LEAVETABLE - &Leave Table - - - m_buttonLeaveTable - protected - - 90,25 - - - - - - - OnButtonLeaveTable - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALL - 0 - - - - 1 - - - 0 - wxID_DITCHPLAYER - - 0 - - m_textDitchPlayer - protected - - 45,-1 - wxTE_PROCESS_ENTER - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - OnDitchPlayer - - - - - - - 5 - wxALL - 0 - - - 0 - - 1 - - - 0 - wxID_ANY - FOLD - - - m_checkPreFold - public - - 100,-1 - - - - - - - - OnCheckPreFold - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALL - 0 - - - 0 - - 1 - - - 0 - wxID_ANY - CALL - - - m_checkPreCall - public - - 100,-1 - - - - - - - - OnCheckPreCall - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALL - 0 - - - 0 - - 1 - - - 0 - wxID_ANY - CALL ANY - - - m_checkPreCallAny - public - - 100,-1 - - - - - - - - OnCheckPreCallAny - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALL - 0 - - - 0 - - 1 - - - 0 - wxID_ANY - RAISE - - - m_checkPreRaise - public - - 100,-1 - - - - - - - - OnCheckPreRaise - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALL - 0 - - - 0 - - 1 - - - 0 - wxID_ANY - RAISE ANY - - - m_checkPreRaiseAny - public - - 100,-1 - - - - - - - - OnCheckPreRaiseAny - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1 - - 1 - - 0 - wxID_ANY - - - m_statusBar - public - - - wxST_SIZEGRIP - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- cgit v1.2.3 From 8acda009d921a65dab87bd0a40f63981a1586561 Mon Sep 17 00:00:00 2001 From: s_nakamoto Date: Fri, 6 Nov 2009 18:53:26 +0000 Subject: UIThreadCall, ThreadSafeMessageBox git-svn-id: https://bitcoin.svn.sourceforge.net/svnroot/bitcoin/trunk@34 1a98c847-1fd6-4fd8-948a-caf3550aa51b --- headers.h | 2 + main.cpp | 2 +- ui.cpp | 68 ++-- ui.h | 22 +- uibase.cpp | 160 ---------- uibase.h | 82 +---- uiproject.fbp | 992 ---------------------------------------------------------- 7 files changed, 44 insertions(+), 1284 deletions(-) diff --git a/headers.h b/headers.h index c7f3cd8514..6cd2da07db 100644 --- a/headers.h +++ b/headers.h @@ -53,6 +53,8 @@ #include #include #include +#include +#include #ifdef __WXMSW__ #include diff --git a/main.cpp b/main.cpp index cc22bad679..e4f1deb841 100644 --- a/main.cpp +++ b/main.cpp @@ -1381,7 +1381,7 @@ bool CheckDiskSpace(int64 nAdditionalBytes) if (nFreeBytesAvailable < (int64)15000000 + nAdditionalBytes) { fShutdown = true; - wxMessageBox("Warning: Your disk space is low ", "Bitcoin", wxICON_EXCLAMATION); + ThreadSafeMessageBox("Warning: Your disk space is low ", "Bitcoin", wxOK | wxICON_EXCLAMATION); _beginthread(Shutdown, 0, NULL); return false; } diff --git a/ui.cpp b/ui.cpp index 92e1d59ce6..d330231341 100644 --- a/ui.cpp +++ b/ui.cpp @@ -14,13 +14,10 @@ void SetStartOnSystemStartup(bool fAutoStart); -DEFINE_EVENT_TYPE(wxEVT_CROSSTHREADCALL) +DEFINE_EVENT_TYPE(wxEVT_UITHREADCALL) DEFINE_EVENT_TYPE(wxEVT_REPLY1) DEFINE_EVENT_TYPE(wxEVT_REPLY2) DEFINE_EVENT_TYPE(wxEVT_REPLY3) -DEFINE_EVENT_TYPE(wxEVT_TABLEADDED) -DEFINE_EVENT_TYPE(wxEVT_TABLEUPDATED) -DEFINE_EVENT_TYPE(wxEVT_TABLEDELETED) CMainFrame* pframeMain = NULL; CMyTaskBarIcon* ptaskbaricon = NULL; @@ -184,6 +181,24 @@ void AddToMyProducts(CProduct product) ""); } +void StringMessageBox(const string& message, const string& caption, int style, wxWindow* parent, int x, int y) +{ + wxMessageBox(message, caption, style, parent, x, y); +} + +int ThreadSafeMessageBox(const string& message, const string& caption, int style, wxWindow* parent, int x, int y) +{ +#ifdef __WXMSW__ + wxMessageBox(message, caption, style, parent, x, y); +#else + UIThreadCall(bind(StringMessageBox, message, caption, style, parent, x, y)); +#endif +} + + + + + @@ -193,6 +208,7 @@ void AddToMyProducts(CProduct product) // // Custom events // +// If this code gets used again, it should be replaced with something like UIThreadCall set setCallbackAvailable; CCriticalSection cs_setCallbackAvailable; @@ -279,7 +295,7 @@ CDataStream GetStreamFromEvent(const wxCommandEvent& event) CMainFrame::CMainFrame(wxWindow* parent) : CMainFrameBase(parent) { - Connect(wxEVT_CROSSTHREADCALL, wxCommandEventHandler(CMainFrame::OnCrossThreadCall), NULL, this); + Connect(wxEVT_UITHREADCALL, wxCommandEventHandler(CMainFrame::OnUIThreadCall), NULL, this); // Init fRefreshListCtrl = false; @@ -982,36 +998,27 @@ void CMainFrame::OnPaintListCtrl(wxPaintEvent& event) } -void CrossThreadCall(wxCommandEvent& event) +void UIThreadCall(boost::function 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::function(fn)); pframeMain->GetEventHandler()->AddPendingEvent(event); + } } -void CrossThreadCall(int nID, void* pdata) -{ - wxCommandEvent event; - event.SetInt(nID); - event.SetClientData(pdata); - if (pframeMain) - pframeMain->GetEventHandler()->AddPendingEvent(event); -} - -void CMainFrame::OnCrossThreadCall(wxCommandEvent& event) +void CMainFrame::OnUIThreadCall(wxCommandEvent& event) { - void* pdata = event.GetClientData(); - switch (event.GetInt()) - { - case UICALL_ADDORDER: - { - break; - } - - case UICALL_UPDATEORDER: - { - break; - } - } + boost::function* pfn = (boost::function*)event.GetClientData(); + (*pfn)(); + delete pfn; } void CMainFrame::OnMenuFileExit(wxCommandEvent& event) @@ -3305,9 +3312,6 @@ wxMenu* CMyTaskBarIcon::CreatePopupMenu() - - - ////////////////////////////////////////////////////////////////////////////// // // CMyApp diff --git a/ui.h b/ui.h index 1d0491f109..1db40997f4 100644 --- a/ui.h +++ b/ui.h @@ -5,19 +5,10 @@ -DECLARE_EVENT_TYPE(wxEVT_CROSSTHREADCALL, -1) +DECLARE_EVENT_TYPE(wxEVT_UITHREADCALL, -1) DECLARE_EVENT_TYPE(wxEVT_REPLY1, -1) DECLARE_EVENT_TYPE(wxEVT_REPLY2, -1) DECLARE_EVENT_TYPE(wxEVT_REPLY3, -1) -DECLARE_EVENT_TYPE(wxEVT_TABLEADDED, -1) -DECLARE_EVENT_TYPE(wxEVT_TABLEUPDATED, -1) -DECLARE_EVENT_TYPE(wxEVT_TABLEDELETED, -1) - -enum -{ - UICALL_ADDORDER = 1, - UICALL_UPDATEORDER, -}; @@ -33,9 +24,10 @@ extern int fMinimizeOnClose; extern void HandleCtrlA(wxKeyEvent& event); extern string FormatTxStatus(const CWalletTx& wtx); -extern void CrossThreadCall(int nID, void* pdata); +extern void UIThreadCall(boost::function); extern void MainFrameRepaint(); extern void Shutdown(void* parg); +extern int ThreadSafeMessageBox(const string& message, const string& caption="Message", int style=wxOK, wxWindow* parent=NULL, int x=-1, int y=-1); @@ -85,7 +77,7 @@ public: unsigned int nListViewUpdated; bool fRefresh; - void OnCrossThreadCall(wxCommandEvent& event); + void OnUIThreadCall(wxCommandEvent& event); int GetSortIndex(const string& strSort); void InsertLine(bool fNew, int nIndex, uint256 hashKey, string strSort, const wxString& str1, const wxString& str2, const wxString& str3, const wxString& str4, const wxString& str5); bool DeleteLine(uint256 hashKey); @@ -473,9 +465,3 @@ public: DECLARE_EVENT_TABLE() }; - - - - - - diff --git a/uibase.cpp b/uibase.cpp index 9a61999523..6a280cda64 100644 --- a/uibase.cpp +++ b/uibase.cpp @@ -1702,166 +1702,6 @@ CEditReviewDialogBase::~CEditReviewDialogBase() m_buttonCancel->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditReviewDialogBase::OnButtonCancel ), NULL, this ); } -CPokerLobbyDialogBase::CPokerLobbyDialogBase( 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 ) ); - - wxBoxSizer* bSizer156; - bSizer156 = new wxBoxSizer( wxHORIZONTAL ); - - m_treeCtrl = new wxTreeCtrl( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTR_HAS_BUTTONS|wxTR_HIDE_ROOT|wxTR_LINES_AT_ROOT ); - m_treeCtrl->SetMinSize( wxSize( 130,-1 ) ); - - bSizer156->Add( m_treeCtrl, 0, wxEXPAND|wxTOP|wxBOTTOM|wxLEFT, 5 ); - - wxBoxSizer* bSizer172; - bSizer172 = new wxBoxSizer( wxVERTICAL ); - - m_listCtrl = new wxListCtrl( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_NO_SORT_HEADER|wxLC_REPORT ); - bSizer172->Add( m_listCtrl, 1, wxEXPAND|wxALL, 5 ); - - m_buttonNewTable = new wxButton( this, wxID_OPENNEWTABLE, wxT("&Open New Table"), wxDefaultPosition, wxDefaultSize, 0 ); - bSizer172->Add( m_buttonNewTable, 0, wxALL, 5 ); - - bSizer156->Add( bSizer172, 1, wxEXPAND, 5 ); - - this->SetSizer( bSizer156 ); - this->Layout(); - - // Connect Events - m_treeCtrl->Connect( wxEVT_COMMAND_TREE_SEL_CHANGED, wxTreeEventHandler( CPokerLobbyDialogBase::OnTreeSelChanged ), NULL, this ); - m_listCtrl->Connect( wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler( CPokerLobbyDialogBase::OnListItemActivated ), NULL, this ); - m_listCtrl->Connect( wxEVT_COMMAND_LIST_ITEM_SELECTED, wxListEventHandler( CPokerLobbyDialogBase::OnListItemSelected ), NULL, this ); - m_buttonNewTable->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CPokerLobbyDialogBase::OnButtonNewTable ), NULL, this ); -} - -CPokerLobbyDialogBase::~CPokerLobbyDialogBase() -{ - // Disconnect Events - m_treeCtrl->Disconnect( wxEVT_COMMAND_TREE_SEL_CHANGED, wxTreeEventHandler( CPokerLobbyDialogBase::OnTreeSelChanged ), NULL, this ); - m_listCtrl->Disconnect( wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler( CPokerLobbyDialogBase::OnListItemActivated ), NULL, this ); - m_listCtrl->Disconnect( wxEVT_COMMAND_LIST_ITEM_SELECTED, wxListEventHandler( CPokerLobbyDialogBase::OnListItemSelected ), NULL, this ); - m_buttonNewTable->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CPokerLobbyDialogBase::OnButtonNewTable ), NULL, this ); -} - -CPokerDialogBase::CPokerDialogBase( 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 ); - - wxBoxSizer* bSizer174; - bSizer174 = new wxBoxSizer( wxVERTICAL ); - - m_checkSitOut = new wxCheckBox( this, wxID_ANY, wxT("Deal Me Out"), wxDefaultPosition, wxDefaultSize, 0 ); - - bSizer174->Add( m_checkSitOut, 0, wxALL, 5 ); - - m_buttonDealHand = new wxButton( this, wxID_DEALHAND, wxT("&Deal Hand"), wxDefaultPosition, wxSize( 150,25 ), 0 ); - bSizer174->Add( m_buttonDealHand, 0, wxALL, 5 ); - - m_buttonFold = new wxButton( this, wxID_FOLD, wxT("&Fold"), wxDefaultPosition, wxSize( 80,25 ), 0 ); - bSizer174->Add( m_buttonFold, 0, wxALL, 5 ); - - m_buttonCall = new wxButton( this, wxID_CALL, wxT("&Call"), wxDefaultPosition, wxSize( 80,25 ), 0 ); - bSizer174->Add( m_buttonCall, 0, wxALL, 5 ); - - m_buttonRaise = new wxButton( this, wxID_RAISE, wxT("&Raise"), wxDefaultPosition, wxSize( 80,25 ), 0 ); - bSizer174->Add( m_buttonRaise, 0, wxALL, 5 ); - - m_buttonLeaveTable = new wxButton( this, wxID_LEAVETABLE, wxT("&Leave Table"), wxDefaultPosition, wxSize( 90,25 ), 0 ); - bSizer174->Add( m_buttonLeaveTable, 0, wxALL, 5 ); - - m_textDitchPlayer = new wxTextCtrl( this, wxID_DITCHPLAYER, wxEmptyString, wxDefaultPosition, wxSize( 45,-1 ), wxTE_PROCESS_ENTER ); - bSizer174->Add( m_textDitchPlayer, 0, wxALL, 5 ); - - m_checkPreFold = new wxCheckBox( this, wxID_ANY, wxT("FOLD"), wxDefaultPosition, wxSize( 100,-1 ), 0 ); - - bSizer174->Add( m_checkPreFold, 0, wxALL, 5 ); - - m_checkPreCall = new wxCheckBox( this, wxID_ANY, wxT("CALL"), wxDefaultPosition, wxSize( 100,-1 ), 0 ); - - bSizer174->Add( m_checkPreCall, 0, wxALL, 5 ); - - m_checkPreCallAny = new wxCheckBox( this, wxID_ANY, wxT("CALL ANY"), wxDefaultPosition, wxSize( 100,-1 ), 0 ); - - bSizer174->Add( m_checkPreCallAny, 0, wxALL, 5 ); - - m_checkPreRaise = new wxCheckBox( this, wxID_ANY, wxT("RAISE"), wxDefaultPosition, wxSize( 100,-1 ), 0 ); - - bSizer174->Add( m_checkPreRaise, 0, wxALL, 5 ); - - m_checkPreRaiseAny = new wxCheckBox( this, wxID_ANY, wxT("RAISE ANY"), wxDefaultPosition, wxSize( 100,-1 ), 0 ); - - bSizer174->Add( m_checkPreRaiseAny, 0, wxALL, 5 ); - - this->SetSizer( bSizer174 ); - this->Layout(); - m_statusBar = this->CreateStatusBar( 1, wxST_SIZEGRIP, wxID_ANY ); - - // Connect Events - this->Connect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( CPokerDialogBase::OnClose ) ); - this->Connect( wxEVT_LEFT_DOWN, wxMouseEventHandler( CPokerDialogBase::OnMouseEvents ) ); - this->Connect( wxEVT_LEFT_UP, wxMouseEventHandler( CPokerDialogBase::OnMouseEvents ) ); - this->Connect( wxEVT_MIDDLE_DOWN, wxMouseEventHandler( CPokerDialogBase::OnMouseEvents ) ); - this->Connect( wxEVT_MIDDLE_UP, wxMouseEventHandler( CPokerDialogBase::OnMouseEvents ) ); - this->Connect( wxEVT_RIGHT_DOWN, wxMouseEventHandler( CPokerDialogBase::OnMouseEvents ) ); - this->Connect( wxEVT_RIGHT_UP, wxMouseEventHandler( CPokerDialogBase::OnMouseEvents ) ); - this->Connect( wxEVT_MOTION, wxMouseEventHandler( CPokerDialogBase::OnMouseEvents ) ); - this->Connect( wxEVT_LEFT_DCLICK, wxMouseEventHandler( CPokerDialogBase::OnMouseEvents ) ); - this->Connect( wxEVT_MIDDLE_DCLICK, wxMouseEventHandler( CPokerDialogBase::OnMouseEvents ) ); - this->Connect( wxEVT_RIGHT_DCLICK, wxMouseEventHandler( CPokerDialogBase::OnMouseEvents ) ); - this->Connect( wxEVT_LEAVE_WINDOW, wxMouseEventHandler( CPokerDialogBase::OnMouseEvents ) ); - this->Connect( wxEVT_ENTER_WINDOW, wxMouseEventHandler( CPokerDialogBase::OnMouseEvents ) ); - this->Connect( wxEVT_MOUSEWHEEL, wxMouseEventHandler( CPokerDialogBase::OnMouseEvents ) ); - this->Connect( wxEVT_PAINT, wxPaintEventHandler( CPokerDialogBase::OnPaint ) ); - this->Connect( wxEVT_SIZE, wxSizeEventHandler( CPokerDialogBase::OnSize ) ); - m_checkSitOut->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( CPokerDialogBase::OnCheckSitOut ), NULL, this ); - m_buttonDealHand->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CPokerDialogBase::OnButtonDealHand ), NULL, this ); - m_buttonFold->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CPokerDialogBase::OnButtonFold ), NULL, this ); - m_buttonCall->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CPokerDialogBase::OnButtonCall ), NULL, this ); - m_buttonRaise->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CPokerDialogBase::OnButtonRaise ), NULL, this ); - m_buttonLeaveTable->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CPokerDialogBase::OnButtonLeaveTable ), NULL, this ); - m_textDitchPlayer->Connect( wxEVT_COMMAND_TEXT_ENTER, wxCommandEventHandler( CPokerDialogBase::OnDitchPlayer ), NULL, this ); - m_checkPreFold->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( CPokerDialogBase::OnCheckPreFold ), NULL, this ); - m_checkPreCall->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( CPokerDialogBase::OnCheckPreCall ), NULL, this ); - m_checkPreCallAny->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( CPokerDialogBase::OnCheckPreCallAny ), NULL, this ); - m_checkPreRaise->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( CPokerDialogBase::OnCheckPreRaise ), NULL, this ); - m_checkPreRaiseAny->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( CPokerDialogBase::OnCheckPreRaiseAny ), NULL, this ); -} - -CPokerDialogBase::~CPokerDialogBase() -{ - // Disconnect Events - this->Disconnect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( CPokerDialogBase::OnClose ) ); - this->Disconnect( wxEVT_LEFT_DOWN, wxMouseEventHandler( CPokerDialogBase::OnMouseEvents ) ); - this->Disconnect( wxEVT_LEFT_UP, wxMouseEventHandler( CPokerDialogBase::OnMouseEvents ) ); - this->Disconnect( wxEVT_MIDDLE_DOWN, wxMouseEventHandler( CPokerDialogBase::OnMouseEvents ) ); - this->Disconnect( wxEVT_MIDDLE_UP, wxMouseEventHandler( CPokerDialogBase::OnMouseEvents ) ); - this->Disconnect( wxEVT_RIGHT_DOWN, wxMouseEventHandler( CPokerDialogBase::OnMouseEvents ) ); - this->Disconnect( wxEVT_RIGHT_UP, wxMouseEventHandler( CPokerDialogBase::OnMouseEvents ) ); - this->Disconnect( wxEVT_MOTION, wxMouseEventHandler( CPokerDialogBase::OnMouseEvents ) ); - this->Disconnect( wxEVT_LEFT_DCLICK, wxMouseEventHandler( CPokerDialogBase::OnMouseEvents ) ); - this->Disconnect( wxEVT_MIDDLE_DCLICK, wxMouseEventHandler( CPokerDialogBase::OnMouseEvents ) ); - this->Disconnect( wxEVT_RIGHT_DCLICK, wxMouseEventHandler( CPokerDialogBase::OnMouseEvents ) ); - this->Disconnect( wxEVT_LEAVE_WINDOW, wxMouseEventHandler( CPokerDialogBase::OnMouseEvents ) ); - this->Disconnect( wxEVT_ENTER_WINDOW, wxMouseEventHandler( CPokerDialogBase::OnMouseEvents ) ); - this->Disconnect( wxEVT_MOUSEWHEEL, wxMouseEventHandler( CPokerDialogBase::OnMouseEvents ) ); - this->Disconnect( wxEVT_PAINT, wxPaintEventHandler( CPokerDialogBase::OnPaint ) ); - this->Disconnect( wxEVT_SIZE, wxSizeEventHandler( CPokerDialogBase::OnSize ) ); - m_checkSitOut->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( CPokerDialogBase::OnCheckSitOut ), NULL, this ); - m_buttonDealHand->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CPokerDialogBase::OnButtonDealHand ), NULL, this ); - m_buttonFold->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CPokerDialogBase::OnButtonFold ), NULL, this ); - m_buttonCall->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CPokerDialogBase::OnButtonCall ), NULL, this ); - m_buttonRaise->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CPokerDialogBase::OnButtonRaise ), NULL, this ); - m_buttonLeaveTable->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CPokerDialogBase::OnButtonLeaveTable ), NULL, this ); - m_textDitchPlayer->Disconnect( wxEVT_COMMAND_TEXT_ENTER, wxCommandEventHandler( CPokerDialogBase::OnDitchPlayer ), NULL, this ); - m_checkPreFold->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( CPokerDialogBase::OnCheckPreFold ), NULL, this ); - m_checkPreCall->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( CPokerDialogBase::OnCheckPreCall ), NULL, this ); - m_checkPreCallAny->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( CPokerDialogBase::OnCheckPreCallAny ), NULL, this ); - m_checkPreRaise->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( CPokerDialogBase::OnCheckPreRaise ), NULL, this ); - m_checkPreRaiseAny->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( CPokerDialogBase::OnCheckPreRaiseAny ), 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 ); diff --git a/uibase.h b/uibase.h index d52158f127..6332b931c8 100644 --- a/uibase.h +++ b/uibase.h @@ -37,7 +37,6 @@ #include #include #include -#include /////////////////////////////////////////////////////////////////////////// @@ -88,14 +87,7 @@ #define wxID_BUTTONBACK 1044 #define wxID_BUTTONNEXT 1045 #define wxID_SUBMIT 1046 -#define wxID_OPENNEWTABLE 1047 -#define wxID_DEALHAND 1048 -#define wxID_FOLD 1049 -#define wxID_CALL 1050 -#define wxID_RAISE 1051 -#define wxID_LEAVETABLE 1052 -#define wxID_DITCHPLAYER 1053 -#define wxID_TEXTCTRL 1054 +#define wxID_TEXTCTRL 1047 /////////////////////////////////////////////////////////////////////////////// /// Class CMainFrameBase @@ -652,78 +644,6 @@ class CEditReviewDialogBase : public wxFrame }; -/////////////////////////////////////////////////////////////////////////////// -/// Class CPokerLobbyDialogBase -/////////////////////////////////////////////////////////////////////////////// -class CPokerLobbyDialogBase : public wxFrame -{ - private: - - protected: - wxTreeCtrl* m_treeCtrl; - wxListCtrl* m_listCtrl; - wxButton* m_buttonNewTable; - - // Virtual event handlers, overide them in your derived class - virtual void OnTreeSelChanged( wxTreeEvent& event ){ event.Skip(); } - virtual void OnListItemActivated( wxListEvent& event ){ event.Skip(); } - virtual void OnListItemSelected( wxListEvent& event ){ event.Skip(); } - virtual void OnButtonNewTable( wxCommandEvent& event ){ event.Skip(); } - - - public: - CPokerLobbyDialogBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxT("Poker Lobby"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 586,457 ), long style = wxDEFAULT_FRAME_STYLE|wxTAB_TRAVERSAL ); - ~CPokerLobbyDialogBase(); - -}; - -/////////////////////////////////////////////////////////////////////////////// -/// Class CPokerDialogBase -/////////////////////////////////////////////////////////////////////////////// -class CPokerDialogBase : public wxFrame -{ - private: - - protected: - wxButton* m_buttonDealHand; - wxButton* m_buttonFold; - wxButton* m_buttonCall; - wxButton* m_buttonRaise; - wxButton* m_buttonLeaveTable; - wxTextCtrl* m_textDitchPlayer; - - // Virtual event handlers, overide them in your derived class - virtual void OnClose( wxCloseEvent& event ){ event.Skip(); } - virtual void OnMouseEvents( wxMouseEvent& event ){ event.Skip(); } - virtual void OnPaint( wxPaintEvent& event ){ event.Skip(); } - virtual void OnSize( wxSizeEvent& event ){ event.Skip(); } - virtual void OnCheckSitOut( wxCommandEvent& event ){ event.Skip(); } - virtual void OnButtonDealHand( wxCommandEvent& event ){ event.Skip(); } - virtual void OnButtonFold( wxCommandEvent& event ){ event.Skip(); } - virtual void OnButtonCall( wxCommandEvent& event ){ event.Skip(); } - virtual void OnButtonRaise( wxCommandEvent& event ){ event.Skip(); } - virtual void OnButtonLeaveTable( wxCommandEvent& event ){ event.Skip(); } - virtual void OnDitchPlayer( wxCommandEvent& event ){ event.Skip(); } - virtual void OnCheckPreFold( wxCommandEvent& event ){ event.Skip(); } - virtual void OnCheckPreCall( wxCommandEvent& event ){ event.Skip(); } - virtual void OnCheckPreCallAny( wxCommandEvent& event ){ event.Skip(); } - virtual void OnCheckPreRaise( wxCommandEvent& event ){ event.Skip(); } - virtual void OnCheckPreRaiseAny( wxCommandEvent& event ){ event.Skip(); } - - - public: - wxCheckBox* m_checkSitOut; - wxCheckBox* m_checkPreFold; - wxCheckBox* m_checkPreCall; - wxCheckBox* m_checkPreCallAny; - wxCheckBox* m_checkPreRaise; - wxCheckBox* m_checkPreRaiseAny; - wxStatusBar* m_statusBar; - CPokerDialogBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxT("Poker"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 806,550 ), long style = wxDEFAULT_FRAME_STYLE|wxFRAME_NO_TASKBAR|wxFULL_REPAINT_ON_RESIZE|wxTAB_TRAVERSAL ); - ~CPokerDialogBase(); - -}; - /////////////////////////////////////////////////////////////////////////////// /// Class CGetTextFromUserDialogBase /////////////////////////////////////////////////////////////////////////////// diff --git a/uiproject.fbp b/uiproject.fbp index 17656b56a5..7c5bb24f9d 100644 --- a/uiproject.fbp +++ b/uiproject.fbp @@ -11581,998 +11581,6 @@ - - wxSYS_COLOUR_BTNFACE - - - 1 - - - - 0 - wxID_ANY - - - CPokerLobbyDialogBase - - 586,457 - wxDEFAULT_FRAME_STYLE - - Poker Lobby - - - - wxTAB_TRAVERSAL - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - bSizer156 - wxHORIZONTAL - none - - 5 - wxEXPAND|wxTOP|wxBOTTOM|wxLEFT - 0 - - - - 1 - - - 0 - wxID_ANY - - 130,-1 - m_treeCtrl - protected - - - wxTR_HAS_BUTTONS|wxTR_HIDE_ROOT|wxTR_LINES_AT_ROOT - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - OnTreeSelChanged - - - - - - - - 5 - wxEXPAND - 1 - - - bSizer172 - wxVERTICAL - none - - 5 - wxEXPAND|wxALL - 1 - - - - 1 - - - 0 - wxID_ANY - - - m_listCtrl - protected - - - wxLC_NO_SORT_HEADER|wxLC_REPORT - - - - - - - - - - - - - - - - - - - - - - - - - - - - - OnListItemActivated - - - - - OnListItemSelected - - - - - - - - - - - - - - - - - - 5 - wxALL - 0 - - - - 0 - 1 - - - 0 - wxID_OPENNEWTABLE - &Open New Table - - - m_buttonNewTable - protected - - - - - - - - - OnButtonNewTable - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1 - - - - 0 - wxID_ANY - - - CPokerDialogBase - - 806,550 - wxDEFAULT_FRAME_STYLE|wxFRAME_NO_TASKBAR - - Poker - - - - wxFULL_REPAINT_ON_RESIZE|wxTAB_TRAVERSAL - 1 - - - - OnClose - - - - - - - - - - - - - - - - - OnMouseEvents - - OnPaint - - - - - OnSize - - - - bSizer174 - wxVERTICAL - none - - 5 - wxALL - 0 - - - 0 - - 1 - - - 0 - wxID_ANY - Deal Me Out - - - m_checkSitOut - public - - - - - - - - - - OnCheckSitOut - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALL - 0 - - - - 0 - 1 - - - 0 - wxID_DEALHAND - &Deal Hand - - - m_buttonDealHand - protected - - 150,25 - - - - - - - OnButtonDealHand - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALL - 0 - - - - 0 - 1 - - - 0 - wxID_FOLD - &Fold - - - m_buttonFold - protected - - 80,25 - - - - - - - OnButtonFold - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALL - 0 - - - - 0 - 1 - - - 0 - wxID_CALL - &Call - - - m_buttonCall - protected - - 80,25 - - - - - - - OnButtonCall - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALL - 0 - - - - 0 - 1 - - - 0 - wxID_RAISE - &Raise - - - m_buttonRaise - protected - - 80,25 - - - - - - - OnButtonRaise - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALL - 0 - - - - 0 - 1 - - - 0 - wxID_LEAVETABLE - &Leave Table - - - m_buttonLeaveTable - protected - - 90,25 - - - - - - - OnButtonLeaveTable - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALL - 0 - - - - 1 - - - 0 - wxID_DITCHPLAYER - - 0 - - m_textDitchPlayer - protected - - 45,-1 - wxTE_PROCESS_ENTER - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - OnDitchPlayer - - - - - - - 5 - wxALL - 0 - - - 0 - - 1 - - - 0 - wxID_ANY - FOLD - - - m_checkPreFold - public - - 100,-1 - - - - - - - - OnCheckPreFold - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALL - 0 - - - 0 - - 1 - - - 0 - wxID_ANY - CALL - - - m_checkPreCall - public - - 100,-1 - - - - - - - - OnCheckPreCall - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALL - 0 - - - 0 - - 1 - - - 0 - wxID_ANY - CALL ANY - - - m_checkPreCallAny - public - - 100,-1 - - - - - - - - OnCheckPreCallAny - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALL - 0 - - - 0 - - 1 - - - 0 - wxID_ANY - RAISE - - - m_checkPreRaise - public - - 100,-1 - - - - - - - - OnCheckPreRaise - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALL - 0 - - - 0 - - 1 - - - 0 - wxID_ANY - RAISE ANY - - - m_checkPreRaiseAny - public - - 100,-1 - - - - - - - - OnCheckPreRaiseAny - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1 - - 1 - - 0 - wxID_ANY - - - m_statusBar - public - - - wxST_SIZEGRIP - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- cgit v1.2.3 From 1a01afab238cbf48331559f4be4b20f9027c53b4 Mon Sep 17 00:00:00 2001 From: s_nakamoto Date: Sat, 7 Nov 2009 05:05:03 +0000 Subject: UI tweaks, use BindListenPort to detect instance already running, setsockopt(SO_REUSEADDR) so can bind during TIME_WAIT after exit and restart --- db.cpp | 2 +- main.cpp | 8 +- main.h | 1 - net.cpp | 98 ++++++++++---------- net.h | 6 +- ui.cpp | 122 +++++++++++++++---------- ui.h | 2 +- uibase.cpp | 91 ++++++++++--------- uibase.h | 2 +- uiproject.fbp | 287 ++++++++++++++++++++++++++++++---------------------------- util.cpp | 11 +++ 11 files changed, 346 insertions(+), 284 deletions(-) diff --git a/db.cpp b/db.cpp index 1235592631..61d6025332 100644 --- a/db.cpp +++ b/db.cpp @@ -139,7 +139,7 @@ void DBFlush(bool fShutdown) { // Flush log data to the actual data file // on all files that are not in use - printf("DBFlush(%s)\n", fShutdown ? "true" : "false"); + printf("DBFlush(%s)%s\n", fShutdown ? "true" : "false", fDbEnvInit ? "" : " db not started"); if (!fDbEnvInit) return; CRITICAL_BLOCK(cs_db) diff --git a/main.cpp b/main.cpp index e4f1deb841..fe213c099a 100644 --- a/main.cpp +++ b/main.cpp @@ -42,8 +42,6 @@ map > mapPubKeys; CCriticalSection cs_mapKeys; CKey keyUser; -int nDropMessagesTest = 0; - // Settings int fGenerateBitcoins = false; int64 nTransactionFee = 0; @@ -1721,9 +1719,9 @@ bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) static map > mapReuseKey; RandAddSeedPerfmon(); printf("received: %s (%d bytes)\n", strCommand.c_str(), vRecv.size()); - if (nDropMessagesTest > 0 && GetRand(nDropMessagesTest) == 0) + if (mapArgs.count("-dropmessagestest") && GetRand(atoi(mapArgs["-dropmessagestest"])) == 0) { - printf("dropmessages DROPPING RECV MESSAGE\n"); + printf("dropmessagestest DROPPING RECV MESSAGE\n"); return true; } @@ -2315,6 +2313,8 @@ void BitcoinMiner() Sleep(1000); if (fShutdown) return; + if (!fGenerateBitcoins) + return; } unsigned int nTransactionsUpdatedLast = nTransactionsUpdated; diff --git a/main.h b/main.h index 16b8c6a3d6..853fdfa5b6 100644 --- a/main.h +++ b/main.h @@ -34,7 +34,6 @@ extern int nBestHeight; extern uint256 hashBestChain; extern CBlockIndex* pindexBest; extern unsigned int nTransactionsUpdated; -extern int nDropMessagesTest; // Settings extern int fGenerateBitcoins; diff --git a/net.cpp b/net.cpp index 44a75a177f..b4df35cb58 100644 --- a/net.cpp +++ b/net.cpp @@ -511,11 +511,6 @@ void ThreadSocketHandler(void* parg) PrintException(NULL, "ThreadSocketHandler()"); } - foreach(CNode* pnode, vNodes) - closesocket(pnode->hSocket); - if (closesocket(hListenSocket) == SOCKET_ERROR) - printf("closesocket(hListenSocket) failed with error %d\n", WSAGetLastError()); - printf("ThreadSocketHandler exiting\n"); } @@ -989,15 +984,13 @@ void ThreadMessageHandler2(void* parg) - -bool StartNode(string& strError) +bool BindListenPort(string& strError) { - if (pnodeLocalHost == NULL) - pnodeLocalHost = new CNode(INVALID_SOCKET, CAddress("127.0.0.1", nLocalServices)); strError = ""; + int nOne = 1; #ifdef __WXMSW__ - // Sockets startup + // Initialize Windows Sockets WSADATA wsadata; int ret = WSAStartup(MAKEWORD(2,2), &wsadata); if (ret != NO_ERROR) @@ -1008,33 +1001,6 @@ bool StartNode(string& strError) } #endif - // Get local host ip - char pszHostName[255]; - if (gethostname(pszHostName, sizeof(pszHostName)) == SOCKET_ERROR) - { - strError = strprintf("Error: Unable to get IP address of this computer (gethostname returned error %d)", WSAGetLastError()); - printf("%s\n", strError.c_str()); - return false; - } - struct hostent* phostent = gethostbyname(pszHostName); - if (!phostent) - { - strError = strprintf("Error: Unable to get IP address of this computer (gethostbyname returned error %d)", WSAGetLastError()); - printf("%s\n", strError.c_str()); - return false; - } - - // Take the first IP that isn't loopback 127.x.x.x - for (int i = 0; phostent->h_addr_list[i] != NULL; i++) - printf("host ip %d: %s\n", i, CAddress(*(unsigned int*)phostent->h_addr_list[i]).ToStringIP().c_str()); - for (int i = 0; phostent->h_addr_list[i] != NULL; i++) - { - addrLocalHost = CAddress(*(unsigned int*)phostent->h_addr_list[i], DEFAULT_PORT, nLocalServices); - if (addrLocalHost.IsValid() && addrLocalHost.GetByte(3) != 127) - break; - } - printf("addrLocalHost = %s\n", addrLocalHost.ToString().c_str()); - // Create socket for listening for incoming connections hListenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (hListenSocket == INVALID_SOCKET) @@ -1043,15 +1009,21 @@ bool StartNode(string& strError) printf("%s\n", strError.c_str()); return false; } + #if defined(__BSD__) || defined(__WXOSX__) - int set = 1; - setsockopt(hSocket, SOL_SOCKET, SO_NOSIGPIPE, (void*)&set, sizeof(int)); + // Different way of disabling SIGPIPE on BSD + setsockopt(hListenSocket, SOL_SOCKET, SO_NOSIGPIPE, (void*)&nOne, sizeof(int)); +#endif + +#ifndef __WXMSW__ + // Allow binding if the port is still in TIME_WAIT state after + // the program was closed and restarted. Not an issue on windows. + setsockopt(hListenSocket, SOL_SOCKET, SO_REUSEADDR, (void*)&nOne, sizeof(int)); #endif - // Set to nonblocking, incoming connections will also inherit this #ifdef __WXMSW__ - u_long nOne = 1; - if (ioctlsocket(hListenSocket, FIONBIO, &nOne) == SOCKET_ERROR) + // Set to nonblocking, incoming connections will also inherit this + if (ioctlsocket(hListenSocket, FIONBIO, (u_long*)&nOne) == SOCKET_ERROR) #else if (fcntl(hListenSocket, F_SETFL, O_NONBLOCK) == SOCKET_ERROR) #endif @@ -1072,7 +1044,7 @@ bool StartNode(string& strError) { int nErr = WSAGetLastError(); if (nErr == WSAEADDRINUSE) - strError = strprintf("Error: Unable to bind to port %d on this computer. The program is probably already running.", ntohs(sockaddr.sin_port)); + strError = strprintf("Unable to bind to port %d on this computer. Bitcoin may be running already.", ntohs(sockaddr.sin_port)); else strError = strprintf("Error: Unable to bind to port %d on this computer (bind returned error %d)", ntohs(sockaddr.sin_port), nErr); printf("%s\n", strError.c_str()); @@ -1088,6 +1060,42 @@ bool StartNode(string& strError) return false; } + return true; +} + +bool StartNode(string& strError) +{ + strError = ""; + if (pnodeLocalHost == NULL) + pnodeLocalHost = new CNode(INVALID_SOCKET, CAddress("127.0.0.1", nLocalServices)); + + // Get local host ip + char pszHostName[255]; + if (gethostname(pszHostName, sizeof(pszHostName)) == SOCKET_ERROR) + { + strError = strprintf("Error: Unable to get IP address of this computer (gethostname returned error %d)", WSAGetLastError()); + printf("%s\n", strError.c_str()); + return false; + } + struct hostent* phostent = gethostbyname(pszHostName); + if (!phostent) + { + strError = strprintf("Error: Unable to get IP address of this computer (gethostbyname returned error %d)", WSAGetLastError()); + printf("%s\n", strError.c_str()); + return false; + } + + // Take the first IP that isn't loopback 127.x.x.x + for (int i = 0; phostent->h_addr_list[i] != NULL; i++) + printf("host ip %d: %s\n", i, CAddress(*(unsigned int*)phostent->h_addr_list[i]).ToStringIP().c_str()); + for (int i = 0; phostent->h_addr_list[i] != NULL; i++) + { + addrLocalHost = CAddress(*(unsigned int*)phostent->h_addr_list[i], DEFAULT_PORT, nLocalServices); + if (addrLocalHost.IsValid() && addrLocalHost.GetByte(3) != 127) + break; + } + printf("addrLocalHost = %s\n", addrLocalHost.ToString().c_str()); + // Get our external IP address for incoming connections if (fUseProxy) { @@ -1158,9 +1166,5 @@ bool StopNode() Sleep(20); Sleep(50); - // Sockets shutdown -#ifdef __WXMSW__ - WSACleanup(); -#endif return true; } diff --git a/net.h b/net.h index 024e7336e4..7b83d462fe 100644 --- a/net.h +++ b/net.h @@ -28,6 +28,7 @@ CNode* FindNode(unsigned int ip); CNode* ConnectNode(CAddress addrConnect, int64 nTimeout=0); void AbandonRequests(void (*fn)(void*, CDataStream&), void* param1); bool AnySubscribed(unsigned int nChannel); +bool BindListenPort(string& strError=REF(string())); bool StartNode(string& strError=REF(string())); bool StopNode(); @@ -456,6 +457,8 @@ extern CNode* pnodeLocalHost; extern uint64 nLocalHostNonce; extern bool fShutdown; extern array vnThreadsRunning; +extern SOCKET hListenSocket; + extern vector vNodes; extern CCriticalSection cs_vNodes; extern map, CAddress> mapAddresses; @@ -647,8 +650,7 @@ public: void EndMessage() { - extern int nDropMessagesTest; - if (nDropMessagesTest > 0 && GetRand(nDropMessagesTest) == 0) + if (mapArgs.count("-dropmessagestest") && GetRand(atoi(mapArgs["-dropmessagestest"])) == 0) { printf("dropmessages DROPPING SEND MESSAGE\n"); AbortMessage(); diff --git a/ui.cpp b/ui.cpp index d330231341..bfb0ad2939 100644 --- a/ui.cpp +++ b/ui.cpp @@ -181,17 +181,30 @@ void AddToMyProducts(CProduct product) ""); } -void StringMessageBox(const string& message, const string& caption, int style, wxWindow* parent, int x, int y) +void CalledMessageBox(const string& message, const string& caption, int style, wxWindow* parent, int x, int y, int* pnRet, bool* pfDone) { - wxMessageBox(message, caption, style, parent, x, y); + *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__ - wxMessageBox(message, caption, style, parent, x, y); + return wxMessageBox(message, caption, style, parent, x, y); #else - UIThreadCall(bind(StringMessageBox, message, caption, style, parent, x, y)); + if (wxThread::IsMain()) + { + 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 } @@ -303,6 +316,18 @@ CMainFrame::CMainFrame(wxWindow* parent) : CMainFrameBase(parent) fOnSetFocusAddress = false; fRefresh = false; m_choiceFilter->SetSelection(0); +#ifndef __WXMSW__ + wxFont fontTmp = m_staticTextBalance->GetFont(); + fontTmp.SetPointSize(10); + fontTmp.SetFamily(wxFONTFAMILY_TELETYPE); + m_staticTextBalance->SetFont(fontTmp); + m_staticTextBalance->SetSize(140, 17); + // ampersand underlines aren't working on gtk + m_toolBar->ClearTools(); + 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(); +#endif m_staticTextBalance->SetLabel(FormatMoney(GetBalance()) + " "); m_listCtrl->SetFocus(); SetIcon(wxICON(bitcoin)); @@ -998,7 +1023,7 @@ void CMainFrame::OnPaintListCtrl(wxPaintEvent& event) } -void UIThreadCall(boost::function fn) +void UIThreadCall(boost::function0 fn) { // Call this with a function object created with bind. // bind needs all parameters to match the function's expected types @@ -1009,14 +1034,14 @@ void UIThreadCall(boost::function fn) if (pframeMain) { wxCommandEvent event(wxEVT_UITHREADCALL); - event.SetClientData((void*)new boost::function(fn)); + event.SetClientData((void*)new boost::function0(fn)); pframeMain->GetEventHandler()->AddPendingEvent(event); } } void CMainFrame::OnUIThreadCall(wxCommandEvent& event) { - boost::function* pfn = (boost::function*)event.GetClientData(); + boost::function0* pfn = (boost::function0*)event.GetClientData(); (*pfn)(); delete pfn; } @@ -1630,7 +1655,14 @@ CSendDialog::CSendDialog(wxWindow* parent, const wxString& strAddress) : CSendDi 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(); + fontTmp.SetPointSize(fontTmp.GetPointSize()-1); + m_staticTextInstructions->SetFont(fontTmp); + SetSize(725, wxDefaultCoord); +#endif // Set Icon wxIcon iconSend; @@ -1801,7 +1833,7 @@ CSendingDialog::CSendingDialog(wxWindow* parent, const CAddress& addrIn, int64 n fUIDone = false; fWorkDone = false; - SetTitle(strprintf("Sending %s to %s...", FormatMoney(nPrice).c_str(), wtx.mapValue["to"].c_str())); + SetTitle(strprintf("Sending %s to %s", FormatMoney(nPrice).c_str(), wtx.mapValue["to"].c_str())); m_textCtrlStatus->SetValue(""); _beginthread(SendingDialogStartTransfer, 0, this); @@ -3344,16 +3376,19 @@ IMPLEMENT_APP(CMyApp) bool CMyApp::OnInit() { + bool fRet = false; try { - return OnInit2(); + fRet = OnInit2(); } catch (std::exception& e) { PrintException(&e, "OnInit()"); } catch (...) { PrintException(NULL, "OnInit()"); } - return false; + if (!fRet) + Shutdown(NULL); + return fRet; } bool CMyApp::OnInit2() @@ -3374,6 +3409,9 @@ bool CMyApp::OnInit2() SetAppName("bitcoin"); #endif + // + // Parameters + // ParseParameters(argc, argv); if (mapArgs.count("-?") || mapArgs.count("--help")) { @@ -3389,7 +3427,27 @@ bool CMyApp::OnInit2() " -connect=\t Connect only to the specified node\n" " -?\t\t This help message\n"; wxMessageBox(strUsage, "Bitcoin", wxOK); - exit(0); + return false; + } + + if (mapArgs.count("-datadir")) + strlcpy(pszSetDataDir, mapArgs["-datadir"].c_str(), sizeof(pszSetDataDir)); + + if (mapArgs.count("-debug")) + fDebug = true; + + if (mapArgs.count("-printtodebugger")) + fPrintToDebugger = true; + + printf("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"); + printf("Bitcoin version %d, OS version %s\n", VERSION, wxGetOsDescription().mb_str()); + + if (mapArgs.count("-loadblockindextest")) + { + CTxDB txdb("r"); + txdb.LoadBlockIndex(); + PrintBlockTree(); + return false; } // @@ -3434,41 +3492,20 @@ bool CMyApp::OnInit2() } #endif - // - // Parameters - // - if (mapArgs.count("-datadir")) - strlcpy(pszSetDataDir, mapArgs["-datadir"].c_str(), sizeof(pszSetDataDir)); - - if (mapArgs.count("-debug")) - fDebug = true; - - if (mapArgs.count("-printtodebugger")) - fPrintToDebugger = true; - - printf("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"); - printf("Bitcoin version %d, OS version %s\n", VERSION, wxGetOsDescription().mb_str()); - - if (mapArgs.count("-dropmessages")) - { - nDropMessagesTest = atoi(mapArgs["-dropmessages"]); - if (nDropMessagesTest == 0) - nDropMessagesTest = 20; - } - - if (mapArgs.count("-loadblockindextest")) + // Bind to the port early so we can tell if another instance is already running. + // This is a backup to wxSingleInstanceChecker, which doesn't work on Linux. + string strErrors; + if (!BindListenPort(strErrors)) { - CTxDB txdb("r"); - txdb.LoadBlockIndex(); - PrintBlockTree(); - exit(0); + wxMessageBox(strErrors, "Bitcoin"); + return false; } // // Load data files // bool fFirstRun; - string strErrors; + strErrors = ""; int64 nStart; printf("Loading addresses...\n"); @@ -3502,7 +3539,6 @@ bool CMyApp::OnInit2() if (!strErrors.empty()) { wxMessageBox(strErrors, "Bitcoin"); - OnExit(); return false; } @@ -3515,7 +3551,6 @@ bool CMyApp::OnInit2() if (mapArgs.count("-printblockindex") || mapArgs.count("-printblocktree")) { PrintBlockTree(); - OnExit(); return false; } @@ -3539,7 +3574,6 @@ bool CMyApp::OnInit2() } if (nFound == 0) printf("No blocks matching %s were found\n", strMatch.c_str()); - OnExit(); return false; } @@ -3558,7 +3592,6 @@ bool CMyApp::OnInit2() if (!addrProxy.IsValid()) { wxMessageBox("Invalid -proxy address", "Bitcoin"); - OnExit(); return false; } } @@ -3588,10 +3621,7 @@ bool CMyApp::OnInit2() _beginthread(ThreadDelayedRepaint, 0, NULL); if (!CheckDiskSpace()) - { - OnExit(); return false; - } RandAddSeedPerfmon(); diff --git a/ui.h b/ui.h index 1db40997f4..a919c3668d 100644 --- a/ui.h +++ b/ui.h @@ -24,7 +24,7 @@ extern int fMinimizeOnClose; extern void HandleCtrlA(wxKeyEvent& event); extern string FormatTxStatus(const CWalletTx& wtx); -extern void UIThreadCall(boost::function); +extern void UIThreadCall(boost::function0); extern void MainFrameRepaint(); extern void Shutdown(void* parg); extern int ThreadSafeMessageBox(const string& message, const string& caption="Message", int style=wxOK, wxWindow* parent=NULL, int x=-1, int y=-1); diff --git a/uibase.cpp b/uibase.cpp index 6a280cda64..7bc8081f09 100644 --- a/uibase.cpp +++ b/uibase.cpp @@ -89,7 +89,7 @@ CMainFrameBase::CMainFrameBase( wxWindow* parent, wxWindowID id, const wxString& bSizer85->Add( m_textCtrlAddress, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 ); - m_buttonCopy = new wxButton( this, wxID_BUTTONCOPY, wxT("&Copy to Clipboard"), wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT ); + m_buttonCopy = new wxButton( this, wxID_BUTTONCOPY, wxT(" &Copy to Clipboard "), wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT ); bSizer85->Add( m_buttonCopy, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 5 ); m_button91 = new wxButton( this, wxID_BUTTONCHANGE, wxT("C&hange..."), wxDefaultPosition, wxDefaultSize, 0 ); @@ -116,7 +116,7 @@ CMainFrameBase::CMainFrameBase( wxWindow* parent, wxWindowID id, const wxString& m_staticTextBalance = new wxStaticText( m_panel14, 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( wxSystemSettings::GetColour( wxSYS_COLOUR_WINDOW ) ); + m_staticTextBalance->SetBackgroundColour( wxColour( 255, 255, 255 ) ); bSizer66->Add( m_staticTextBalance, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 ); @@ -341,10 +341,10 @@ CTxDetailsDialogBase::CTxDetailsDialogBase( wxWindow* parent, wxWindowID id, con bSizer64->Add( bSizer66, 1, wxEXPAND, 5 ); wxBoxSizer* bSizer65; - bSizer65 = new wxBoxSizer( wxVERTICAL ); + bSizer65 = new wxBoxSizer( wxHORIZONTAL ); m_buttonOK = new wxButton( this, wxID_OK, wxT("OK"), wxDefaultPosition, wxSize( -1,-1 ), 0 ); - bSizer65->Add( m_buttonOK, 0, wxALL, 5 ); + bSizer65->Add( m_buttonOK, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); bSizer64->Add( bSizer65, 0, wxALIGN_RIGHT, 5 ); @@ -521,13 +521,13 @@ COptionsDialogBase::COptionsDialogBase( wxWindow* parent, wxWindowID id, const w bSizer58 = new wxBoxSizer( wxHORIZONTAL ); m_buttonOK = new wxButton( this, wxID_OK, wxT("OK"), wxDefaultPosition, wxSize( -1,-1 ), 0 ); - bSizer58->Add( m_buttonOK, 0, wxALL, 5 ); + bSizer58->Add( m_buttonOK, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); m_buttonCancel = new wxButton( this, wxID_CANCEL, wxT("Cancel"), wxDefaultPosition, wxSize( -1,-1 ), 0 ); - bSizer58->Add( m_buttonCancel, 0, wxALL, 5 ); + bSizer58->Add( m_buttonCancel, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); m_buttonApply = new wxButton( this, wxID_APPLY, wxT("&Apply"), wxDefaultPosition, wxSize( -1,-1 ), 0 ); - bSizer58->Add( m_buttonApply, 0, wxALL, 5 ); + bSizer58->Add( m_buttonApply, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); bSizer55->Add( bSizer58, 0, wxALIGN_RIGHT, 5 ); @@ -619,7 +619,7 @@ CAboutDialogBase::CAboutDialogBase( wxWindow* parent, wxWindowID id, const wxStr bSizer61->Add( 0, 0, 1, wxEXPAND, 5 ); m_buttonOK = new wxButton( this, wxID_OK, wxT("OK"), wxDefaultPosition, wxSize( -1,-1 ), 0 ); - bSizer61->Add( m_buttonOK, 0, wxALL, 5 ); + bSizer61->Add( m_buttonOK, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); bSizer60->Add( bSizer61, 0, wxALIGN_RIGHT|wxEXPAND, 5 ); @@ -655,9 +655,9 @@ CSendDialogBase::CSendDialogBase( wxWindow* parent, wxWindowID id, const wxStrin fgSizer1->Add( 0, 0, 0, wxEXPAND, 5 ); - m_staticText14 = new wxStaticText( this, wxID_ANY, wxT("Enter the recipient's IP address (e.g. 123.45.6.7) for online transfer with comments and confirmation, \nor Bitcoin address (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJED9L) if recipient is not online."), wxDefaultPosition, wxDefaultSize, 0 ); - m_staticText14->Wrap( -1 ); - fgSizer1->Add( m_staticText14, 0, wxTOP|wxRIGHT|wxLEFT, 5 ); + m_staticTextInstructions = new wxStaticText( this, wxID_ANY, wxT("Enter the recipient's IP address (e.g. 123.45.6.7) for online transfer with comments and confirmation, \nor Bitcoin address (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJED9L) if recipient is not online."), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticTextInstructions->Wrap( -1 ); + fgSizer1->Add( m_staticTextInstructions, 0, wxTOP|wxRIGHT|wxLEFT, 5 ); wxBoxSizer* bSizer47; bSizer47 = new wxBoxSizer( wxHORIZONTAL ); @@ -681,11 +681,16 @@ CSendDialogBase::CSendDialogBase( wxWindow* parent, wxWindowID id, const wxStrin 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, wxT("&Paste"), wxDefaultPosition, wxSize( -1,-1 ), wxBU_EXACTFIT ); - bSizer19->Add( m_buttonPaste, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 5 ); + bSizer66->Add( m_buttonPaste, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxEXPAND, 5 ); m_buttonAddress = new wxButton( this, wxID_BUTTONADDRESSBOOK, wxT(" Address &Book..."), wxDefaultPosition, wxDefaultSize, 0 ); - bSizer19->Add( m_buttonAddress, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 5 ); + 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 ); @@ -764,10 +769,10 @@ CSendDialogBase::CSendDialogBase( wxWindow* parent, wxWindowID id, const wxStrin m_buttonSend = new wxButton( this, wxID_BUTTONSEND, wxT("&Send"), wxDefaultPosition, wxSize( -1,-1 ), 0 ); m_buttonSend->SetFont( wxFont( wxNORMAL_FONT->GetPointSize(), 70, 90, 90, false, wxEmptyString ) ); - bSizer23->Add( m_buttonSend, 0, wxALL, 5 ); + bSizer23->Add( m_buttonSend, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); m_buttonCancel = new wxButton( this, wxID_CANCEL, wxT("Cancel"), wxDefaultPosition, wxSize( -1,-1 ), 0 ); - bSizer23->Add( m_buttonCancel, 0, wxALL, 5 ); + bSizer23->Add( m_buttonCancel, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); bSizer21->Add( bSizer23, 0, wxEXPAND, 5 ); @@ -827,10 +832,10 @@ CSendingDialogBase::CSendingDialogBase( wxWindow* parent, wxWindowID id, const w m_buttonOK = new wxButton( this, wxID_ANY, wxT("OK"), wxDefaultPosition, wxDefaultSize, 0 ); m_buttonOK->Enable( false ); - bSizer69->Add( m_buttonOK, 0, wxALL, 5 ); + bSizer69->Add( m_buttonOK, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); m_buttonCancel = new wxButton( this, wxID_CANCEL, wxT("Cancel"), wxDefaultPosition, wxSize( -1,-1 ), 0 ); - bSizer69->Add( m_buttonCancel, 0, wxALL, 5 ); + bSizer69->Add( m_buttonCancel, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); bSizer68->Add( bSizer69, 0, wxEXPAND, 5 ); @@ -877,21 +882,21 @@ CYourAddressDialogBase::CYourAddressDialogBase( wxWindow* parent, wxWindowID id, bSizer69->Add( 0, 0, 1, wxEXPAND, 5 ); m_buttonRename = new wxButton( this, wxID_BUTTONRENAME, wxT("&Edit..."), wxDefaultPosition, wxDefaultSize, 0 ); - bSizer69->Add( m_buttonRename, 0, wxALL, 5 ); + bSizer69->Add( m_buttonRename, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); - m_buttonNew = new wxButton( this, wxID_BUTTONNEW, wxT("&New Address..."), wxDefaultPosition, wxSize( -1,-1 ), 0 ); - bSizer69->Add( m_buttonNew, 0, wxALL, 5 ); + m_buttonNew = new wxButton( this, wxID_BUTTONNEW, wxT(" &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, wxT("&Copy to Clipboard"), wxDefaultPosition, wxSize( -1,-1 ), 0 ); - bSizer69->Add( m_buttonCopy, 0, wxALL, 5 ); + m_buttonCopy = new wxButton( this, wxID_BUTTONCOPY, wxT(" &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, wxT("OK"), wxDefaultPosition, wxDefaultSize, 0 ); - bSizer69->Add( m_buttonOK, 0, wxALL, 5 ); + bSizer69->Add( m_buttonOK, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); m_buttonCancel = new wxButton( this, wxID_CANCEL, wxT("Cancel"), wxDefaultPosition, wxSize( -1,-1 ), 0 ); m_buttonCancel->Hide(); - bSizer69->Add( m_buttonCancel, 0, wxALL, 5 ); + bSizer69->Add( m_buttonCancel, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); bSizer68->Add( bSizer69, 0, wxEXPAND, 5 ); @@ -950,19 +955,19 @@ CAddressBookDialogBase::CAddressBookDialogBase( wxWindow* parent, wxWindowID id, bSizer69->Add( 0, 0, 1, wxEXPAND, 5 ); m_buttonEdit = new wxButton( this, wxID_BUTTONEDIT, wxT("&Edit..."), wxDefaultPosition, wxDefaultSize, 0 ); - bSizer69->Add( m_buttonEdit, 0, wxALL, 5 ); + bSizer69->Add( m_buttonEdit, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); - m_buttonNew = new wxButton( this, wxID_BUTTONNEW, wxT("&New Address..."), wxDefaultPosition, wxDefaultSize, 0 ); - bSizer69->Add( m_buttonNew, 0, wxALL, 5 ); + m_buttonNew = new wxButton( this, wxID_BUTTONNEW, wxT(" &New Address... "), wxDefaultPosition, wxDefaultSize, 0 ); + bSizer69->Add( m_buttonNew, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); m_buttonDelete = new wxButton( this, wxID_BUTTONDELETE, wxT("&Delete"), wxDefaultPosition, wxDefaultSize, 0 ); - bSizer69->Add( m_buttonDelete, 0, wxALL, 5 ); + bSizer69->Add( m_buttonDelete, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); m_buttonOK = new wxButton( this, wxID_OK, wxT("OK"), wxDefaultPosition, wxSize( -1,-1 ), 0 ); - bSizer69->Add( m_buttonOK, 0, wxALL, 5 ); + bSizer69->Add( m_buttonOK, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); m_buttonCancel = new wxButton( this, wxID_CANCEL, wxT("Cancel"), wxDefaultPosition, wxSize( -1,-1 ), 0 ); - bSizer69->Add( m_buttonCancel, 0, wxALL, 5 ); + bSizer69->Add( m_buttonCancel, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); bSizer68->Add( bSizer69, 0, wxEXPAND, 5 ); @@ -1360,13 +1365,13 @@ CEditProductDialogBase::CEditProductDialogBase( wxWindow* parent, wxWindowID id, bSizer26 = new wxBoxSizer( wxHORIZONTAL ); m_buttonOK = new wxButton( this, wxID_BUTTONSEND, wxT("&Send"), wxDefaultPosition, wxDefaultSize, 0 ); - bSizer26->Add( m_buttonOK, 0, wxALL, 5 ); + bSizer26->Add( m_buttonOK, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); m_buttonPreview = new wxButton( this, wxID_BUTTONPREVIEW, wxT("&Preview"), wxDefaultPosition, wxDefaultSize, 0 ); - bSizer26->Add( m_buttonPreview, 0, wxALL, 5 ); + bSizer26->Add( m_buttonPreview, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); m_buttonCancel = new wxButton( this, wxID_CANCEL, wxT("Cancel"), wxDefaultPosition, wxDefaultSize, 0 ); - bSizer26->Add( m_buttonCancel, 0, wxALL, 5 ); + bSizer26->Add( m_buttonCancel, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); bSizer20->Add( bSizer26, 0, wxALIGN_RIGHT, 5 ); @@ -1551,10 +1556,10 @@ CViewProductDialogBase::CViewProductDialogBase( wxWindow* parent, wxWindowID id, bSizer25 = new wxBoxSizer( wxHORIZONTAL ); m_buttonSubmitForm = new wxButton( m_scrolledWindow, wxID_BUTTONSAMPLE, wxT("&Submit"), wxDefaultPosition, wxDefaultSize, 0 ); - bSizer25->Add( m_buttonSubmitForm, 0, wxALL, 5 ); + bSizer25->Add( m_buttonSubmitForm, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); m_buttonCancelForm = new wxButton( m_scrolledWindow, wxID_CANCEL2, wxT("Cancel"), wxDefaultPosition, wxDefaultSize, 0 ); - bSizer25->Add( m_buttonCancelForm, 0, wxALL, 5 ); + bSizer25->Add( m_buttonCancelForm, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); bSizer21->Add( bSizer25, 0, wxALIGN_CENTER_HORIZONTAL, 5 ); @@ -1571,13 +1576,13 @@ CViewProductDialogBase::CViewProductDialogBase( wxWindow* parent, wxWindowID id, m_buttonBack = new wxButton( this, wxID_BUTTONBACK, wxT("< &Back "), wxDefaultPosition, wxDefaultSize, 0 ); m_buttonBack->Enable( false ); - bSizer26->Add( m_buttonBack, 0, wxALL, 5 ); + bSizer26->Add( m_buttonBack, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); m_buttonNext = new wxButton( this, wxID_BUTTONNEXT, wxT(" &Next >"), wxDefaultPosition, wxDefaultSize, 0 ); - bSizer26->Add( m_buttonNext, 0, wxALL, 5 ); + bSizer26->Add( m_buttonNext, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); m_buttonCancel = new wxButton( this, wxID_CANCEL, wxT("Cancel"), wxDefaultPosition, wxDefaultSize, 0 ); - bSizer26->Add( m_buttonCancel, 0, wxALL, 5 ); + bSizer26->Add( m_buttonCancel, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); bSizer20->Add( bSizer26, 0, wxALIGN_RIGHT, 5 ); @@ -1622,7 +1627,7 @@ CViewOrderDialogBase::CViewOrderDialogBase( wxWindow* parent, wxWindowID id, con bSizer26 = new wxBoxSizer( wxHORIZONTAL ); m_buttonOK = new wxButton( this, wxID_OK, wxT("OK"), wxDefaultPosition, wxDefaultSize, 0 ); - bSizer26->Add( m_buttonOK, 0, wxALL, 5 ); + bSizer26->Add( m_buttonOK, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); bSizer20->Add( bSizer26, 0, wxALIGN_RIGHT, 5 ); @@ -1678,10 +1683,10 @@ CEditReviewDialogBase::CEditReviewDialogBase( wxWindow* parent, wxWindowID id, c bSizer113 = new wxBoxSizer( wxHORIZONTAL ); m_buttonSubmit = new wxButton( this, wxID_SUBMIT, wxT("&Submit"), wxDefaultPosition, wxDefaultSize, 0 ); - bSizer113->Add( m_buttonSubmit, 0, wxALL, 5 ); + bSizer113->Add( m_buttonSubmit, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); m_buttonCancel = new wxButton( this, wxID_CANCEL, wxT("Cancel"), wxDefaultPosition, wxDefaultSize, 0 ); - bSizer113->Add( m_buttonCancel, 0, wxALL, 5 ); + bSizer113->Add( m_buttonCancel, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); bSizer112->Add( bSizer113, 0, wxALIGN_RIGHT, 5 ); @@ -1745,10 +1750,10 @@ CGetTextFromUserDialogBase::CGetTextFromUserDialogBase( wxWindow* parent, wxWind bSizer80->Add( 0, 0, 1, wxEXPAND, 5 ); m_buttonOK = new wxButton( this, wxID_OK, wxT("OK"), wxDefaultPosition, wxSize( -1,-1 ), 0 ); - bSizer80->Add( m_buttonOK, 0, wxALL, 5 ); + bSizer80->Add( m_buttonOK, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); m_buttonCancel = new wxButton( this, wxID_CANCEL, wxT("Cancel"), wxDefaultPosition, wxDefaultSize, 0 ); - bSizer80->Add( m_buttonCancel, 0, wxALL, 5 ); + bSizer80->Add( m_buttonCancel, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); bSizer79->Add( bSizer80, 0, wxEXPAND, 5 ); diff --git a/uibase.h b/uibase.h index 6332b931c8..2cb99e9a59 100644 --- a/uibase.h +++ b/uibase.h @@ -277,7 +277,7 @@ class CSendDialogBase : public wxDialog protected: - wxStaticText* m_staticText14; + wxStaticText* m_staticTextInstructions; wxStaticBitmap* m_bitmapCheckMark; wxStaticText* m_staticText36; diff --git a/uiproject.fbp b/uiproject.fbp index 7c5bb24f9d..3aa1c86bcf 100644 --- a/uiproject.fbp +++ b/uiproject.fbp @@ -225,7 +225,7 @@ - + 20,20 @@ -489,7 +489,7 @@ 0 wxID_BUTTONCOPY - &Copy to Clipboard + &Copy to Clipboard m_buttonCopy @@ -708,7 +708,7 @@ wxALIGN_CENTER_VERTICAL|wxALL 0 - wxSYS_COLOUR_WINDOW + 255,255,255 1 @@ -1627,11 +1627,11 @@ bSizer65 - wxVERTICAL + wxHORIZONTAL none 5 - wxALL + wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND 0 @@ -3014,7 +3014,7 @@ none 5 - wxALL + wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND 0 @@ -3066,7 +3066,7 @@ 5 - wxALL + wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND 0 @@ -3118,7 +3118,7 @@ 5 - wxALL + wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND 0 @@ -3476,7 +3476,7 @@ 5 - wxALL + wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND 0 @@ -3638,7 +3638,7 @@ Enter the recipient's IP address (e.g. 123.45.6.7) for online transfer with comments and confirmation, or Bitcoin address (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJED9L) if recipient is not online. - m_staticText14 + m_staticTextInstructions protected @@ -3861,106 +3861,117 @@ 5 - wxALIGN_CENTER_VERTICAL|wxRIGHT + wxALIGN_CENTER_VERTICAL 0 - - - - 0 - 1 - - - 0 - wxID_BUTTONPASTE - &Paste - - - m_buttonPaste - protected - - -1,-1 - wxBU_EXACTFIT - - - - - - OnButtonPaste - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALIGN_CENTER_VERTICAL|wxRIGHT - 0 - - - - 0 - 1 - - - 0 - wxID_BUTTONADDRESSBOOK - Address &Book... - + - m_buttonAddress - protected - - - - - - - - - OnButtonAddressBook - - - - - - - - - - - - - - - - - - - - - - - + bSizer66 + wxHORIZONTAL + none + + 5 + wxALIGN_CENTER_VERTICAL|wxRIGHT|wxEXPAND + 0 + + + + 0 + 1 + + + 0 + wxID_BUTTONPASTE + &Paste + + + m_buttonPaste + protected + + -1,-1 + wxBU_EXACTFIT + + + + + + OnButtonPaste + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALIGN_CENTER_VERTICAL|wxRIGHT|wxEXPAND + 0 + + + + 0 + 1 + + + 0 + wxID_BUTTONADDRESSBOOK + Address &Book... + + + m_buttonAddress + protected + + + + + + + + + OnButtonAddressBook + + + + + + + + + + + + + + + + + + + + + + + + + @@ -4472,7 +4483,7 @@ 5 - wxALL + wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND 0 @@ -4524,7 +4535,7 @@ 5 - wxALL + wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND 0 @@ -4762,7 +4773,7 @@ 5 - wxALL + wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND 0 @@ -4814,7 +4825,7 @@ 5 - wxALL + wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND 0 @@ -5076,7 +5087,7 @@ 5 - wxALL + wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND 0 @@ -5128,7 +5139,7 @@ 5 - wxALL + wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND 0 @@ -5139,7 +5150,7 @@ 0 wxID_BUTTONNEW - &New Address... + &New Address... -1,-1 m_buttonNew @@ -5180,7 +5191,7 @@ 5 - wxALL + wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND 0 @@ -5191,7 +5202,7 @@ 0 wxID_BUTTONCOPY - &Copy to Clipboard + &Copy to Clipboard -1,-1 m_buttonCopy @@ -5232,7 +5243,7 @@ 5 - wxALL + wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND 0 @@ -5284,7 +5295,7 @@ 5 - wxALL + wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND 0 @@ -5546,7 +5557,7 @@ 5 - wxALL + wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND 0 @@ -5598,7 +5609,7 @@ 5 - wxALL + wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND 0 @@ -5609,7 +5620,7 @@ 0 wxID_BUTTONNEW - &New Address... + &New Address... -1,-1 m_buttonNew @@ -5650,7 +5661,7 @@ 5 - wxALL + wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND 0 @@ -5702,7 +5713,7 @@ 5 - wxALL + wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND 0 @@ -5754,7 +5765,7 @@ 5 - wxALL + wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND 0 @@ -10212,7 +10223,7 @@ none 5 - wxALL + wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND 0 @@ -10264,7 +10275,7 @@ 5 - wxALL + wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND 0 @@ -10316,7 +10327,7 @@ 5 - wxALL + wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND 0 @@ -10665,7 +10676,7 @@ none 5 - wxALL + wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND 0 @@ -10717,7 +10728,7 @@ 5 - wxALL + wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND 0 @@ -10785,7 +10796,7 @@ none 5 - wxALL + wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND 0 @@ -10837,7 +10848,7 @@ 5 - wxALL + wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND 0 @@ -10889,7 +10900,7 @@ 5 - wxALL + wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND 0 @@ -11074,7 +11085,7 @@ none 5 - wxALL + wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND 0 @@ -11475,7 +11486,7 @@ none 5 - wxALL + wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND 0 @@ -11527,7 +11538,7 @@ 5 - wxALL + wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND 0 @@ -11902,7 +11913,7 @@ 5 - wxALL + wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND 0 @@ -11954,7 +11965,7 @@ 5 - wxALL + wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND 0 diff --git a/util.cpp b/util.cpp index 5efb579bf7..4a5b983d22 100644 --- a/util.cpp +++ b/util.cpp @@ -53,6 +53,17 @@ public: for (int i = 0; i < CRYPTO_num_locks(); i++) delete ppmutexOpenSSL[i]; OPENSSL_free(ppmutexOpenSSL); + + // Close sockets + foreach(CNode* pnode, vNodes) + closesocket(pnode->hSocket); + if (closesocket(hListenSocket) == SOCKET_ERROR) + printf("closesocket(hListenSocket) failed with error %d\n", WSAGetLastError()); + +#ifdef __WXMSW__ + // Shutdown Windows Sockets + WSACleanup(); +#endif } } instance_of_cinit; -- cgit v1.2.3 From 8b4cefd3245c349cad14baaf2ba42380dcc88112 Mon Sep 17 00:00:00 2001 From: s_nakamoto Date: Sat, 7 Nov 2009 05:05:03 +0000 Subject: UI tweaks, use BindListenPort to detect instance already running, setsockopt(SO_REUSEADDR) so can bind during TIME_WAIT after exit and restart git-svn-id: https://bitcoin.svn.sourceforge.net/svnroot/bitcoin/trunk@35 1a98c847-1fd6-4fd8-948a-caf3550aa51b --- db.cpp | 2 +- main.cpp | 8 +- main.h | 1 - net.cpp | 98 ++++++++++---------- net.h | 6 +- ui.cpp | 122 +++++++++++++++---------- ui.h | 2 +- uibase.cpp | 91 ++++++++++--------- uibase.h | 2 +- uiproject.fbp | 287 ++++++++++++++++++++++++++++++---------------------------- util.cpp | 11 +++ 11 files changed, 346 insertions(+), 284 deletions(-) diff --git a/db.cpp b/db.cpp index 1235592631..61d6025332 100644 --- a/db.cpp +++ b/db.cpp @@ -139,7 +139,7 @@ void DBFlush(bool fShutdown) { // Flush log data to the actual data file // on all files that are not in use - printf("DBFlush(%s)\n", fShutdown ? "true" : "false"); + printf("DBFlush(%s)%s\n", fShutdown ? "true" : "false", fDbEnvInit ? "" : " db not started"); if (!fDbEnvInit) return; CRITICAL_BLOCK(cs_db) diff --git a/main.cpp b/main.cpp index e4f1deb841..fe213c099a 100644 --- a/main.cpp +++ b/main.cpp @@ -42,8 +42,6 @@ map > mapPubKeys; CCriticalSection cs_mapKeys; CKey keyUser; -int nDropMessagesTest = 0; - // Settings int fGenerateBitcoins = false; int64 nTransactionFee = 0; @@ -1721,9 +1719,9 @@ bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) static map > mapReuseKey; RandAddSeedPerfmon(); printf("received: %s (%d bytes)\n", strCommand.c_str(), vRecv.size()); - if (nDropMessagesTest > 0 && GetRand(nDropMessagesTest) == 0) + if (mapArgs.count("-dropmessagestest") && GetRand(atoi(mapArgs["-dropmessagestest"])) == 0) { - printf("dropmessages DROPPING RECV MESSAGE\n"); + printf("dropmessagestest DROPPING RECV MESSAGE\n"); return true; } @@ -2315,6 +2313,8 @@ void BitcoinMiner() Sleep(1000); if (fShutdown) return; + if (!fGenerateBitcoins) + return; } unsigned int nTransactionsUpdatedLast = nTransactionsUpdated; diff --git a/main.h b/main.h index 16b8c6a3d6..853fdfa5b6 100644 --- a/main.h +++ b/main.h @@ -34,7 +34,6 @@ extern int nBestHeight; extern uint256 hashBestChain; extern CBlockIndex* pindexBest; extern unsigned int nTransactionsUpdated; -extern int nDropMessagesTest; // Settings extern int fGenerateBitcoins; diff --git a/net.cpp b/net.cpp index 44a75a177f..b4df35cb58 100644 --- a/net.cpp +++ b/net.cpp @@ -511,11 +511,6 @@ void ThreadSocketHandler(void* parg) PrintException(NULL, "ThreadSocketHandler()"); } - foreach(CNode* pnode, vNodes) - closesocket(pnode->hSocket); - if (closesocket(hListenSocket) == SOCKET_ERROR) - printf("closesocket(hListenSocket) failed with error %d\n", WSAGetLastError()); - printf("ThreadSocketHandler exiting\n"); } @@ -989,15 +984,13 @@ void ThreadMessageHandler2(void* parg) - -bool StartNode(string& strError) +bool BindListenPort(string& strError) { - if (pnodeLocalHost == NULL) - pnodeLocalHost = new CNode(INVALID_SOCKET, CAddress("127.0.0.1", nLocalServices)); strError = ""; + int nOne = 1; #ifdef __WXMSW__ - // Sockets startup + // Initialize Windows Sockets WSADATA wsadata; int ret = WSAStartup(MAKEWORD(2,2), &wsadata); if (ret != NO_ERROR) @@ -1008,33 +1001,6 @@ bool StartNode(string& strError) } #endif - // Get local host ip - char pszHostName[255]; - if (gethostname(pszHostName, sizeof(pszHostName)) == SOCKET_ERROR) - { - strError = strprintf("Error: Unable to get IP address of this computer (gethostname returned error %d)", WSAGetLastError()); - printf("%s\n", strError.c_str()); - return false; - } - struct hostent* phostent = gethostbyname(pszHostName); - if (!phostent) - { - strError = strprintf("Error: Unable to get IP address of this computer (gethostbyname returned error %d)", WSAGetLastError()); - printf("%s\n", strError.c_str()); - return false; - } - - // Take the first IP that isn't loopback 127.x.x.x - for (int i = 0; phostent->h_addr_list[i] != NULL; i++) - printf("host ip %d: %s\n", i, CAddress(*(unsigned int*)phostent->h_addr_list[i]).ToStringIP().c_str()); - for (int i = 0; phostent->h_addr_list[i] != NULL; i++) - { - addrLocalHost = CAddress(*(unsigned int*)phostent->h_addr_list[i], DEFAULT_PORT, nLocalServices); - if (addrLocalHost.IsValid() && addrLocalHost.GetByte(3) != 127) - break; - } - printf("addrLocalHost = %s\n", addrLocalHost.ToString().c_str()); - // Create socket for listening for incoming connections hListenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (hListenSocket == INVALID_SOCKET) @@ -1043,15 +1009,21 @@ bool StartNode(string& strError) printf("%s\n", strError.c_str()); return false; } + #if defined(__BSD__) || defined(__WXOSX__) - int set = 1; - setsockopt(hSocket, SOL_SOCKET, SO_NOSIGPIPE, (void*)&set, sizeof(int)); + // Different way of disabling SIGPIPE on BSD + setsockopt(hListenSocket, SOL_SOCKET, SO_NOSIGPIPE, (void*)&nOne, sizeof(int)); +#endif + +#ifndef __WXMSW__ + // Allow binding if the port is still in TIME_WAIT state after + // the program was closed and restarted. Not an issue on windows. + setsockopt(hListenSocket, SOL_SOCKET, SO_REUSEADDR, (void*)&nOne, sizeof(int)); #endif - // Set to nonblocking, incoming connections will also inherit this #ifdef __WXMSW__ - u_long nOne = 1; - if (ioctlsocket(hListenSocket, FIONBIO, &nOne) == SOCKET_ERROR) + // Set to nonblocking, incoming connections will also inherit this + if (ioctlsocket(hListenSocket, FIONBIO, (u_long*)&nOne) == SOCKET_ERROR) #else if (fcntl(hListenSocket, F_SETFL, O_NONBLOCK) == SOCKET_ERROR) #endif @@ -1072,7 +1044,7 @@ bool StartNode(string& strError) { int nErr = WSAGetLastError(); if (nErr == WSAEADDRINUSE) - strError = strprintf("Error: Unable to bind to port %d on this computer. The program is probably already running.", ntohs(sockaddr.sin_port)); + strError = strprintf("Unable to bind to port %d on this computer. Bitcoin may be running already.", ntohs(sockaddr.sin_port)); else strError = strprintf("Error: Unable to bind to port %d on this computer (bind returned error %d)", ntohs(sockaddr.sin_port), nErr); printf("%s\n", strError.c_str()); @@ -1088,6 +1060,42 @@ bool StartNode(string& strError) return false; } + return true; +} + +bool StartNode(string& strError) +{ + strError = ""; + if (pnodeLocalHost == NULL) + pnodeLocalHost = new CNode(INVALID_SOCKET, CAddress("127.0.0.1", nLocalServices)); + + // Get local host ip + char pszHostName[255]; + if (gethostname(pszHostName, sizeof(pszHostName)) == SOCKET_ERROR) + { + strError = strprintf("Error: Unable to get IP address of this computer (gethostname returned error %d)", WSAGetLastError()); + printf("%s\n", strError.c_str()); + return false; + } + struct hostent* phostent = gethostbyname(pszHostName); + if (!phostent) + { + strError = strprintf("Error: Unable to get IP address of this computer (gethostbyname returned error %d)", WSAGetLastError()); + printf("%s\n", strError.c_str()); + return false; + } + + // Take the first IP that isn't loopback 127.x.x.x + for (int i = 0; phostent->h_addr_list[i] != NULL; i++) + printf("host ip %d: %s\n", i, CAddress(*(unsigned int*)phostent->h_addr_list[i]).ToStringIP().c_str()); + for (int i = 0; phostent->h_addr_list[i] != NULL; i++) + { + addrLocalHost = CAddress(*(unsigned int*)phostent->h_addr_list[i], DEFAULT_PORT, nLocalServices); + if (addrLocalHost.IsValid() && addrLocalHost.GetByte(3) != 127) + break; + } + printf("addrLocalHost = %s\n", addrLocalHost.ToString().c_str()); + // Get our external IP address for incoming connections if (fUseProxy) { @@ -1158,9 +1166,5 @@ bool StopNode() Sleep(20); Sleep(50); - // Sockets shutdown -#ifdef __WXMSW__ - WSACleanup(); -#endif return true; } diff --git a/net.h b/net.h index 024e7336e4..7b83d462fe 100644 --- a/net.h +++ b/net.h @@ -28,6 +28,7 @@ CNode* FindNode(unsigned int ip); CNode* ConnectNode(CAddress addrConnect, int64 nTimeout=0); void AbandonRequests(void (*fn)(void*, CDataStream&), void* param1); bool AnySubscribed(unsigned int nChannel); +bool BindListenPort(string& strError=REF(string())); bool StartNode(string& strError=REF(string())); bool StopNode(); @@ -456,6 +457,8 @@ extern CNode* pnodeLocalHost; extern uint64 nLocalHostNonce; extern bool fShutdown; extern array vnThreadsRunning; +extern SOCKET hListenSocket; + extern vector vNodes; extern CCriticalSection cs_vNodes; extern map, CAddress> mapAddresses; @@ -647,8 +650,7 @@ public: void EndMessage() { - extern int nDropMessagesTest; - if (nDropMessagesTest > 0 && GetRand(nDropMessagesTest) == 0) + if (mapArgs.count("-dropmessagestest") && GetRand(atoi(mapArgs["-dropmessagestest"])) == 0) { printf("dropmessages DROPPING SEND MESSAGE\n"); AbortMessage(); diff --git a/ui.cpp b/ui.cpp index d330231341..bfb0ad2939 100644 --- a/ui.cpp +++ b/ui.cpp @@ -181,17 +181,30 @@ void AddToMyProducts(CProduct product) ""); } -void StringMessageBox(const string& message, const string& caption, int style, wxWindow* parent, int x, int y) +void CalledMessageBox(const string& message, const string& caption, int style, wxWindow* parent, int x, int y, int* pnRet, bool* pfDone) { - wxMessageBox(message, caption, style, parent, x, y); + *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__ - wxMessageBox(message, caption, style, parent, x, y); + return wxMessageBox(message, caption, style, parent, x, y); #else - UIThreadCall(bind(StringMessageBox, message, caption, style, parent, x, y)); + if (wxThread::IsMain()) + { + 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 } @@ -303,6 +316,18 @@ CMainFrame::CMainFrame(wxWindow* parent) : CMainFrameBase(parent) fOnSetFocusAddress = false; fRefresh = false; m_choiceFilter->SetSelection(0); +#ifndef __WXMSW__ + wxFont fontTmp = m_staticTextBalance->GetFont(); + fontTmp.SetPointSize(10); + fontTmp.SetFamily(wxFONTFAMILY_TELETYPE); + m_staticTextBalance->SetFont(fontTmp); + m_staticTextBalance->SetSize(140, 17); + // ampersand underlines aren't working on gtk + m_toolBar->ClearTools(); + 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(); +#endif m_staticTextBalance->SetLabel(FormatMoney(GetBalance()) + " "); m_listCtrl->SetFocus(); SetIcon(wxICON(bitcoin)); @@ -998,7 +1023,7 @@ void CMainFrame::OnPaintListCtrl(wxPaintEvent& event) } -void UIThreadCall(boost::function fn) +void UIThreadCall(boost::function0 fn) { // Call this with a function object created with bind. // bind needs all parameters to match the function's expected types @@ -1009,14 +1034,14 @@ void UIThreadCall(boost::function fn) if (pframeMain) { wxCommandEvent event(wxEVT_UITHREADCALL); - event.SetClientData((void*)new boost::function(fn)); + event.SetClientData((void*)new boost::function0(fn)); pframeMain->GetEventHandler()->AddPendingEvent(event); } } void CMainFrame::OnUIThreadCall(wxCommandEvent& event) { - boost::function* pfn = (boost::function*)event.GetClientData(); + boost::function0* pfn = (boost::function0*)event.GetClientData(); (*pfn)(); delete pfn; } @@ -1630,7 +1655,14 @@ CSendDialog::CSendDialog(wxWindow* parent, const wxString& strAddress) : CSendDi 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(); + fontTmp.SetPointSize(fontTmp.GetPointSize()-1); + m_staticTextInstructions->SetFont(fontTmp); + SetSize(725, wxDefaultCoord); +#endif // Set Icon wxIcon iconSend; @@ -1801,7 +1833,7 @@ CSendingDialog::CSendingDialog(wxWindow* parent, const CAddress& addrIn, int64 n fUIDone = false; fWorkDone = false; - SetTitle(strprintf("Sending %s to %s...", FormatMoney(nPrice).c_str(), wtx.mapValue["to"].c_str())); + SetTitle(strprintf("Sending %s to %s", FormatMoney(nPrice).c_str(), wtx.mapValue["to"].c_str())); m_textCtrlStatus->SetValue(""); _beginthread(SendingDialogStartTransfer, 0, this); @@ -3344,16 +3376,19 @@ IMPLEMENT_APP(CMyApp) bool CMyApp::OnInit() { + bool fRet = false; try { - return OnInit2(); + fRet = OnInit2(); } catch (std::exception& e) { PrintException(&e, "OnInit()"); } catch (...) { PrintException(NULL, "OnInit()"); } - return false; + if (!fRet) + Shutdown(NULL); + return fRet; } bool CMyApp::OnInit2() @@ -3374,6 +3409,9 @@ bool CMyApp::OnInit2() SetAppName("bitcoin"); #endif + // + // Parameters + // ParseParameters(argc, argv); if (mapArgs.count("-?") || mapArgs.count("--help")) { @@ -3389,7 +3427,27 @@ bool CMyApp::OnInit2() " -connect=\t Connect only to the specified node\n" " -?\t\t This help message\n"; wxMessageBox(strUsage, "Bitcoin", wxOK); - exit(0); + return false; + } + + if (mapArgs.count("-datadir")) + strlcpy(pszSetDataDir, mapArgs["-datadir"].c_str(), sizeof(pszSetDataDir)); + + if (mapArgs.count("-debug")) + fDebug = true; + + if (mapArgs.count("-printtodebugger")) + fPrintToDebugger = true; + + printf("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"); + printf("Bitcoin version %d, OS version %s\n", VERSION, wxGetOsDescription().mb_str()); + + if (mapArgs.count("-loadblockindextest")) + { + CTxDB txdb("r"); + txdb.LoadBlockIndex(); + PrintBlockTree(); + return false; } // @@ -3434,41 +3492,20 @@ bool CMyApp::OnInit2() } #endif - // - // Parameters - // - if (mapArgs.count("-datadir")) - strlcpy(pszSetDataDir, mapArgs["-datadir"].c_str(), sizeof(pszSetDataDir)); - - if (mapArgs.count("-debug")) - fDebug = true; - - if (mapArgs.count("-printtodebugger")) - fPrintToDebugger = true; - - printf("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"); - printf("Bitcoin version %d, OS version %s\n", VERSION, wxGetOsDescription().mb_str()); - - if (mapArgs.count("-dropmessages")) - { - nDropMessagesTest = atoi(mapArgs["-dropmessages"]); - if (nDropMessagesTest == 0) - nDropMessagesTest = 20; - } - - if (mapArgs.count("-loadblockindextest")) + // Bind to the port early so we can tell if another instance is already running. + // This is a backup to wxSingleInstanceChecker, which doesn't work on Linux. + string strErrors; + if (!BindListenPort(strErrors)) { - CTxDB txdb("r"); - txdb.LoadBlockIndex(); - PrintBlockTree(); - exit(0); + wxMessageBox(strErrors, "Bitcoin"); + return false; } // // Load data files // bool fFirstRun; - string strErrors; + strErrors = ""; int64 nStart; printf("Loading addresses...\n"); @@ -3502,7 +3539,6 @@ bool CMyApp::OnInit2() if (!strErrors.empty()) { wxMessageBox(strErrors, "Bitcoin"); - OnExit(); return false; } @@ -3515,7 +3551,6 @@ bool CMyApp::OnInit2() if (mapArgs.count("-printblockindex") || mapArgs.count("-printblocktree")) { PrintBlockTree(); - OnExit(); return false; } @@ -3539,7 +3574,6 @@ bool CMyApp::OnInit2() } if (nFound == 0) printf("No blocks matching %s were found\n", strMatch.c_str()); - OnExit(); return false; } @@ -3558,7 +3592,6 @@ bool CMyApp::OnInit2() if (!addrProxy.IsValid()) { wxMessageBox("Invalid -proxy address", "Bitcoin"); - OnExit(); return false; } } @@ -3588,10 +3621,7 @@ bool CMyApp::OnInit2() _beginthread(ThreadDelayedRepaint, 0, NULL); if (!CheckDiskSpace()) - { - OnExit(); return false; - } RandAddSeedPerfmon(); diff --git a/ui.h b/ui.h index 1db40997f4..a919c3668d 100644 --- a/ui.h +++ b/ui.h @@ -24,7 +24,7 @@ extern int fMinimizeOnClose; extern void HandleCtrlA(wxKeyEvent& event); extern string FormatTxStatus(const CWalletTx& wtx); -extern void UIThreadCall(boost::function); +extern void UIThreadCall(boost::function0); extern void MainFrameRepaint(); extern void Shutdown(void* parg); extern int ThreadSafeMessageBox(const string& message, const string& caption="Message", int style=wxOK, wxWindow* parent=NULL, int x=-1, int y=-1); diff --git a/uibase.cpp b/uibase.cpp index 6a280cda64..7bc8081f09 100644 --- a/uibase.cpp +++ b/uibase.cpp @@ -89,7 +89,7 @@ CMainFrameBase::CMainFrameBase( wxWindow* parent, wxWindowID id, const wxString& bSizer85->Add( m_textCtrlAddress, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 ); - m_buttonCopy = new wxButton( this, wxID_BUTTONCOPY, wxT("&Copy to Clipboard"), wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT ); + m_buttonCopy = new wxButton( this, wxID_BUTTONCOPY, wxT(" &Copy to Clipboard "), wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT ); bSizer85->Add( m_buttonCopy, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 5 ); m_button91 = new wxButton( this, wxID_BUTTONCHANGE, wxT("C&hange..."), wxDefaultPosition, wxDefaultSize, 0 ); @@ -116,7 +116,7 @@ CMainFrameBase::CMainFrameBase( wxWindow* parent, wxWindowID id, const wxString& m_staticTextBalance = new wxStaticText( m_panel14, 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( wxSystemSettings::GetColour( wxSYS_COLOUR_WINDOW ) ); + m_staticTextBalance->SetBackgroundColour( wxColour( 255, 255, 255 ) ); bSizer66->Add( m_staticTextBalance, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 ); @@ -341,10 +341,10 @@ CTxDetailsDialogBase::CTxDetailsDialogBase( wxWindow* parent, wxWindowID id, con bSizer64->Add( bSizer66, 1, wxEXPAND, 5 ); wxBoxSizer* bSizer65; - bSizer65 = new wxBoxSizer( wxVERTICAL ); + bSizer65 = new wxBoxSizer( wxHORIZONTAL ); m_buttonOK = new wxButton( this, wxID_OK, wxT("OK"), wxDefaultPosition, wxSize( -1,-1 ), 0 ); - bSizer65->Add( m_buttonOK, 0, wxALL, 5 ); + bSizer65->Add( m_buttonOK, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); bSizer64->Add( bSizer65, 0, wxALIGN_RIGHT, 5 ); @@ -521,13 +521,13 @@ COptionsDialogBase::COptionsDialogBase( wxWindow* parent, wxWindowID id, const w bSizer58 = new wxBoxSizer( wxHORIZONTAL ); m_buttonOK = new wxButton( this, wxID_OK, wxT("OK"), wxDefaultPosition, wxSize( -1,-1 ), 0 ); - bSizer58->Add( m_buttonOK, 0, wxALL, 5 ); + bSizer58->Add( m_buttonOK, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); m_buttonCancel = new wxButton( this, wxID_CANCEL, wxT("Cancel"), wxDefaultPosition, wxSize( -1,-1 ), 0 ); - bSizer58->Add( m_buttonCancel, 0, wxALL, 5 ); + bSizer58->Add( m_buttonCancel, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); m_buttonApply = new wxButton( this, wxID_APPLY, wxT("&Apply"), wxDefaultPosition, wxSize( -1,-1 ), 0 ); - bSizer58->Add( m_buttonApply, 0, wxALL, 5 ); + bSizer58->Add( m_buttonApply, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); bSizer55->Add( bSizer58, 0, wxALIGN_RIGHT, 5 ); @@ -619,7 +619,7 @@ CAboutDialogBase::CAboutDialogBase( wxWindow* parent, wxWindowID id, const wxStr bSizer61->Add( 0, 0, 1, wxEXPAND, 5 ); m_buttonOK = new wxButton( this, wxID_OK, wxT("OK"), wxDefaultPosition, wxSize( -1,-1 ), 0 ); - bSizer61->Add( m_buttonOK, 0, wxALL, 5 ); + bSizer61->Add( m_buttonOK, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); bSizer60->Add( bSizer61, 0, wxALIGN_RIGHT|wxEXPAND, 5 ); @@ -655,9 +655,9 @@ CSendDialogBase::CSendDialogBase( wxWindow* parent, wxWindowID id, const wxStrin fgSizer1->Add( 0, 0, 0, wxEXPAND, 5 ); - m_staticText14 = new wxStaticText( this, wxID_ANY, wxT("Enter the recipient's IP address (e.g. 123.45.6.7) for online transfer with comments and confirmation, \nor Bitcoin address (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJED9L) if recipient is not online."), wxDefaultPosition, wxDefaultSize, 0 ); - m_staticText14->Wrap( -1 ); - fgSizer1->Add( m_staticText14, 0, wxTOP|wxRIGHT|wxLEFT, 5 ); + m_staticTextInstructions = new wxStaticText( this, wxID_ANY, wxT("Enter the recipient's IP address (e.g. 123.45.6.7) for online transfer with comments and confirmation, \nor Bitcoin address (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJED9L) if recipient is not online."), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticTextInstructions->Wrap( -1 ); + fgSizer1->Add( m_staticTextInstructions, 0, wxTOP|wxRIGHT|wxLEFT, 5 ); wxBoxSizer* bSizer47; bSizer47 = new wxBoxSizer( wxHORIZONTAL ); @@ -681,11 +681,16 @@ CSendDialogBase::CSendDialogBase( wxWindow* parent, wxWindowID id, const wxStrin 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, wxT("&Paste"), wxDefaultPosition, wxSize( -1,-1 ), wxBU_EXACTFIT ); - bSizer19->Add( m_buttonPaste, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 5 ); + bSizer66->Add( m_buttonPaste, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxEXPAND, 5 ); m_buttonAddress = new wxButton( this, wxID_BUTTONADDRESSBOOK, wxT(" Address &Book..."), wxDefaultPosition, wxDefaultSize, 0 ); - bSizer19->Add( m_buttonAddress, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 5 ); + 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 ); @@ -764,10 +769,10 @@ CSendDialogBase::CSendDialogBase( wxWindow* parent, wxWindowID id, const wxStrin m_buttonSend = new wxButton( this, wxID_BUTTONSEND, wxT("&Send"), wxDefaultPosition, wxSize( -1,-1 ), 0 ); m_buttonSend->SetFont( wxFont( wxNORMAL_FONT->GetPointSize(), 70, 90, 90, false, wxEmptyString ) ); - bSizer23->Add( m_buttonSend, 0, wxALL, 5 ); + bSizer23->Add( m_buttonSend, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); m_buttonCancel = new wxButton( this, wxID_CANCEL, wxT("Cancel"), wxDefaultPosition, wxSize( -1,-1 ), 0 ); - bSizer23->Add( m_buttonCancel, 0, wxALL, 5 ); + bSizer23->Add( m_buttonCancel, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); bSizer21->Add( bSizer23, 0, wxEXPAND, 5 ); @@ -827,10 +832,10 @@ CSendingDialogBase::CSendingDialogBase( wxWindow* parent, wxWindowID id, const w m_buttonOK = new wxButton( this, wxID_ANY, wxT("OK"), wxDefaultPosition, wxDefaultSize, 0 ); m_buttonOK->Enable( false ); - bSizer69->Add( m_buttonOK, 0, wxALL, 5 ); + bSizer69->Add( m_buttonOK, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); m_buttonCancel = new wxButton( this, wxID_CANCEL, wxT("Cancel"), wxDefaultPosition, wxSize( -1,-1 ), 0 ); - bSizer69->Add( m_buttonCancel, 0, wxALL, 5 ); + bSizer69->Add( m_buttonCancel, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); bSizer68->Add( bSizer69, 0, wxEXPAND, 5 ); @@ -877,21 +882,21 @@ CYourAddressDialogBase::CYourAddressDialogBase( wxWindow* parent, wxWindowID id, bSizer69->Add( 0, 0, 1, wxEXPAND, 5 ); m_buttonRename = new wxButton( this, wxID_BUTTONRENAME, wxT("&Edit..."), wxDefaultPosition, wxDefaultSize, 0 ); - bSizer69->Add( m_buttonRename, 0, wxALL, 5 ); + bSizer69->Add( m_buttonRename, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); - m_buttonNew = new wxButton( this, wxID_BUTTONNEW, wxT("&New Address..."), wxDefaultPosition, wxSize( -1,-1 ), 0 ); - bSizer69->Add( m_buttonNew, 0, wxALL, 5 ); + m_buttonNew = new wxButton( this, wxID_BUTTONNEW, wxT(" &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, wxT("&Copy to Clipboard"), wxDefaultPosition, wxSize( -1,-1 ), 0 ); - bSizer69->Add( m_buttonCopy, 0, wxALL, 5 ); + m_buttonCopy = new wxButton( this, wxID_BUTTONCOPY, wxT(" &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, wxT("OK"), wxDefaultPosition, wxDefaultSize, 0 ); - bSizer69->Add( m_buttonOK, 0, wxALL, 5 ); + bSizer69->Add( m_buttonOK, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); m_buttonCancel = new wxButton( this, wxID_CANCEL, wxT("Cancel"), wxDefaultPosition, wxSize( -1,-1 ), 0 ); m_buttonCancel->Hide(); - bSizer69->Add( m_buttonCancel, 0, wxALL, 5 ); + bSizer69->Add( m_buttonCancel, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); bSizer68->Add( bSizer69, 0, wxEXPAND, 5 ); @@ -950,19 +955,19 @@ CAddressBookDialogBase::CAddressBookDialogBase( wxWindow* parent, wxWindowID id, bSizer69->Add( 0, 0, 1, wxEXPAND, 5 ); m_buttonEdit = new wxButton( this, wxID_BUTTONEDIT, wxT("&Edit..."), wxDefaultPosition, wxDefaultSize, 0 ); - bSizer69->Add( m_buttonEdit, 0, wxALL, 5 ); + bSizer69->Add( m_buttonEdit, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); - m_buttonNew = new wxButton( this, wxID_BUTTONNEW, wxT("&New Address..."), wxDefaultPosition, wxDefaultSize, 0 ); - bSizer69->Add( m_buttonNew, 0, wxALL, 5 ); + m_buttonNew = new wxButton( this, wxID_BUTTONNEW, wxT(" &New Address... "), wxDefaultPosition, wxDefaultSize, 0 ); + bSizer69->Add( m_buttonNew, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); m_buttonDelete = new wxButton( this, wxID_BUTTONDELETE, wxT("&Delete"), wxDefaultPosition, wxDefaultSize, 0 ); - bSizer69->Add( m_buttonDelete, 0, wxALL, 5 ); + bSizer69->Add( m_buttonDelete, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); m_buttonOK = new wxButton( this, wxID_OK, wxT("OK"), wxDefaultPosition, wxSize( -1,-1 ), 0 ); - bSizer69->Add( m_buttonOK, 0, wxALL, 5 ); + bSizer69->Add( m_buttonOK, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); m_buttonCancel = new wxButton( this, wxID_CANCEL, wxT("Cancel"), wxDefaultPosition, wxSize( -1,-1 ), 0 ); - bSizer69->Add( m_buttonCancel, 0, wxALL, 5 ); + bSizer69->Add( m_buttonCancel, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); bSizer68->Add( bSizer69, 0, wxEXPAND, 5 ); @@ -1360,13 +1365,13 @@ CEditProductDialogBase::CEditProductDialogBase( wxWindow* parent, wxWindowID id, bSizer26 = new wxBoxSizer( wxHORIZONTAL ); m_buttonOK = new wxButton( this, wxID_BUTTONSEND, wxT("&Send"), wxDefaultPosition, wxDefaultSize, 0 ); - bSizer26->Add( m_buttonOK, 0, wxALL, 5 ); + bSizer26->Add( m_buttonOK, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); m_buttonPreview = new wxButton( this, wxID_BUTTONPREVIEW, wxT("&Preview"), wxDefaultPosition, wxDefaultSize, 0 ); - bSizer26->Add( m_buttonPreview, 0, wxALL, 5 ); + bSizer26->Add( m_buttonPreview, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); m_buttonCancel = new wxButton( this, wxID_CANCEL, wxT("Cancel"), wxDefaultPosition, wxDefaultSize, 0 ); - bSizer26->Add( m_buttonCancel, 0, wxALL, 5 ); + bSizer26->Add( m_buttonCancel, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); bSizer20->Add( bSizer26, 0, wxALIGN_RIGHT, 5 ); @@ -1551,10 +1556,10 @@ CViewProductDialogBase::CViewProductDialogBase( wxWindow* parent, wxWindowID id, bSizer25 = new wxBoxSizer( wxHORIZONTAL ); m_buttonSubmitForm = new wxButton( m_scrolledWindow, wxID_BUTTONSAMPLE, wxT("&Submit"), wxDefaultPosition, wxDefaultSize, 0 ); - bSizer25->Add( m_buttonSubmitForm, 0, wxALL, 5 ); + bSizer25->Add( m_buttonSubmitForm, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); m_buttonCancelForm = new wxButton( m_scrolledWindow, wxID_CANCEL2, wxT("Cancel"), wxDefaultPosition, wxDefaultSize, 0 ); - bSizer25->Add( m_buttonCancelForm, 0, wxALL, 5 ); + bSizer25->Add( m_buttonCancelForm, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); bSizer21->Add( bSizer25, 0, wxALIGN_CENTER_HORIZONTAL, 5 ); @@ -1571,13 +1576,13 @@ CViewProductDialogBase::CViewProductDialogBase( wxWindow* parent, wxWindowID id, m_buttonBack = new wxButton( this, wxID_BUTTONBACK, wxT("< &Back "), wxDefaultPosition, wxDefaultSize, 0 ); m_buttonBack->Enable( false ); - bSizer26->Add( m_buttonBack, 0, wxALL, 5 ); + bSizer26->Add( m_buttonBack, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); m_buttonNext = new wxButton( this, wxID_BUTTONNEXT, wxT(" &Next >"), wxDefaultPosition, wxDefaultSize, 0 ); - bSizer26->Add( m_buttonNext, 0, wxALL, 5 ); + bSizer26->Add( m_buttonNext, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); m_buttonCancel = new wxButton( this, wxID_CANCEL, wxT("Cancel"), wxDefaultPosition, wxDefaultSize, 0 ); - bSizer26->Add( m_buttonCancel, 0, wxALL, 5 ); + bSizer26->Add( m_buttonCancel, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); bSizer20->Add( bSizer26, 0, wxALIGN_RIGHT, 5 ); @@ -1622,7 +1627,7 @@ CViewOrderDialogBase::CViewOrderDialogBase( wxWindow* parent, wxWindowID id, con bSizer26 = new wxBoxSizer( wxHORIZONTAL ); m_buttonOK = new wxButton( this, wxID_OK, wxT("OK"), wxDefaultPosition, wxDefaultSize, 0 ); - bSizer26->Add( m_buttonOK, 0, wxALL, 5 ); + bSizer26->Add( m_buttonOK, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); bSizer20->Add( bSizer26, 0, wxALIGN_RIGHT, 5 ); @@ -1678,10 +1683,10 @@ CEditReviewDialogBase::CEditReviewDialogBase( wxWindow* parent, wxWindowID id, c bSizer113 = new wxBoxSizer( wxHORIZONTAL ); m_buttonSubmit = new wxButton( this, wxID_SUBMIT, wxT("&Submit"), wxDefaultPosition, wxDefaultSize, 0 ); - bSizer113->Add( m_buttonSubmit, 0, wxALL, 5 ); + bSizer113->Add( m_buttonSubmit, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); m_buttonCancel = new wxButton( this, wxID_CANCEL, wxT("Cancel"), wxDefaultPosition, wxDefaultSize, 0 ); - bSizer113->Add( m_buttonCancel, 0, wxALL, 5 ); + bSizer113->Add( m_buttonCancel, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); bSizer112->Add( bSizer113, 0, wxALIGN_RIGHT, 5 ); @@ -1745,10 +1750,10 @@ CGetTextFromUserDialogBase::CGetTextFromUserDialogBase( wxWindow* parent, wxWind bSizer80->Add( 0, 0, 1, wxEXPAND, 5 ); m_buttonOK = new wxButton( this, wxID_OK, wxT("OK"), wxDefaultPosition, wxSize( -1,-1 ), 0 ); - bSizer80->Add( m_buttonOK, 0, wxALL, 5 ); + bSizer80->Add( m_buttonOK, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); m_buttonCancel = new wxButton( this, wxID_CANCEL, wxT("Cancel"), wxDefaultPosition, wxDefaultSize, 0 ); - bSizer80->Add( m_buttonCancel, 0, wxALL, 5 ); + bSizer80->Add( m_buttonCancel, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); bSizer79->Add( bSizer80, 0, wxEXPAND, 5 ); diff --git a/uibase.h b/uibase.h index 6332b931c8..2cb99e9a59 100644 --- a/uibase.h +++ b/uibase.h @@ -277,7 +277,7 @@ class CSendDialogBase : public wxDialog protected: - wxStaticText* m_staticText14; + wxStaticText* m_staticTextInstructions; wxStaticBitmap* m_bitmapCheckMark; wxStaticText* m_staticText36; diff --git a/uiproject.fbp b/uiproject.fbp index 7c5bb24f9d..3aa1c86bcf 100644 --- a/uiproject.fbp +++ b/uiproject.fbp @@ -225,7 +225,7 @@ - + 20,20 @@ -489,7 +489,7 @@ 0 wxID_BUTTONCOPY - &Copy to Clipboard + &Copy to Clipboard m_buttonCopy @@ -708,7 +708,7 @@ wxALIGN_CENTER_VERTICAL|wxALL 0 - wxSYS_COLOUR_WINDOW + 255,255,255 1 @@ -1627,11 +1627,11 @@ bSizer65 - wxVERTICAL + wxHORIZONTAL none 5 - wxALL + wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND 0 @@ -3014,7 +3014,7 @@ none 5 - wxALL + wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND 0 @@ -3066,7 +3066,7 @@ 5 - wxALL + wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND 0 @@ -3118,7 +3118,7 @@ 5 - wxALL + wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND 0 @@ -3476,7 +3476,7 @@ 5 - wxALL + wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND 0 @@ -3638,7 +3638,7 @@ Enter the recipient's IP address (e.g. 123.45.6.7) for online transfer with comments and confirmation, or Bitcoin address (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJED9L) if recipient is not online. - m_staticText14 + m_staticTextInstructions protected @@ -3861,106 +3861,117 @@ 5 - wxALIGN_CENTER_VERTICAL|wxRIGHT + wxALIGN_CENTER_VERTICAL 0 - - - - 0 - 1 - - - 0 - wxID_BUTTONPASTE - &Paste - - - m_buttonPaste - protected - - -1,-1 - wxBU_EXACTFIT - - - - - - OnButtonPaste - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALIGN_CENTER_VERTICAL|wxRIGHT - 0 - - - - 0 - 1 - - - 0 - wxID_BUTTONADDRESSBOOK - Address &Book... - + - m_buttonAddress - protected - - - - - - - - - OnButtonAddressBook - - - - - - - - - - - - - - - - - - - - - - - + bSizer66 + wxHORIZONTAL + none + + 5 + wxALIGN_CENTER_VERTICAL|wxRIGHT|wxEXPAND + 0 + + + + 0 + 1 + + + 0 + wxID_BUTTONPASTE + &Paste + + + m_buttonPaste + protected + + -1,-1 + wxBU_EXACTFIT + + + + + + OnButtonPaste + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALIGN_CENTER_VERTICAL|wxRIGHT|wxEXPAND + 0 + + + + 0 + 1 + + + 0 + wxID_BUTTONADDRESSBOOK + Address &Book... + + + m_buttonAddress + protected + + + + + + + + + OnButtonAddressBook + + + + + + + + + + + + + + + + + + + + + + + + + @@ -4472,7 +4483,7 @@ 5 - wxALL + wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND 0 @@ -4524,7 +4535,7 @@ 5 - wxALL + wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND 0 @@ -4762,7 +4773,7 @@ 5 - wxALL + wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND 0 @@ -4814,7 +4825,7 @@ 5 - wxALL + wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND 0 @@ -5076,7 +5087,7 @@ 5 - wxALL + wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND 0 @@ -5128,7 +5139,7 @@ 5 - wxALL + wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND 0 @@ -5139,7 +5150,7 @@ 0 wxID_BUTTONNEW - &New Address... + &New Address... -1,-1 m_buttonNew @@ -5180,7 +5191,7 @@ 5 - wxALL + wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND 0 @@ -5191,7 +5202,7 @@ 0 wxID_BUTTONCOPY - &Copy to Clipboard + &Copy to Clipboard -1,-1 m_buttonCopy @@ -5232,7 +5243,7 @@ 5 - wxALL + wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND 0 @@ -5284,7 +5295,7 @@ 5 - wxALL + wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND 0 @@ -5546,7 +5557,7 @@ 5 - wxALL + wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND 0 @@ -5598,7 +5609,7 @@ 5 - wxALL + wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND 0 @@ -5609,7 +5620,7 @@ 0 wxID_BUTTONNEW - &New Address... + &New Address... -1,-1 m_buttonNew @@ -5650,7 +5661,7 @@ 5 - wxALL + wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND 0 @@ -5702,7 +5713,7 @@ 5 - wxALL + wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND 0 @@ -5754,7 +5765,7 @@ 5 - wxALL + wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND 0 @@ -10212,7 +10223,7 @@ none 5 - wxALL + wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND 0 @@ -10264,7 +10275,7 @@ 5 - wxALL + wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND 0 @@ -10316,7 +10327,7 @@ 5 - wxALL + wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND 0 @@ -10665,7 +10676,7 @@ none 5 - wxALL + wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND 0 @@ -10717,7 +10728,7 @@ 5 - wxALL + wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND 0 @@ -10785,7 +10796,7 @@ none 5 - wxALL + wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND 0 @@ -10837,7 +10848,7 @@ 5 - wxALL + wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND 0 @@ -10889,7 +10900,7 @@ 5 - wxALL + wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND 0 @@ -11074,7 +11085,7 @@ none 5 - wxALL + wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND 0 @@ -11475,7 +11486,7 @@ none 5 - wxALL + wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND 0 @@ -11527,7 +11538,7 @@ 5 - wxALL + wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND 0 @@ -11902,7 +11913,7 @@ 5 - wxALL + wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND 0 @@ -11954,7 +11965,7 @@ 5 - wxALL + wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND 0 diff --git a/util.cpp b/util.cpp index 5efb579bf7..4a5b983d22 100644 --- a/util.cpp +++ b/util.cpp @@ -53,6 +53,17 @@ public: for (int i = 0; i < CRYPTO_num_locks(); i++) delete ppmutexOpenSSL[i]; OPENSSL_free(ppmutexOpenSSL); + + // Close sockets + foreach(CNode* pnode, vNodes) + closesocket(pnode->hSocket); + if (closesocket(hListenSocket) == SOCKET_ERROR) + printf("closesocket(hListenSocket) failed with error %d\n", WSAGetLastError()); + +#ifdef __WXMSW__ + // Shutdown Windows Sockets + WSACleanup(); +#endif } } instance_of_cinit; -- cgit v1.2.3 From 158ea66c6c6653a033f884f13dc082046a58f74a Mon Sep 17 00:00:00 2001 From: s_nakamoto Date: Sat, 7 Nov 2009 18:51:41 +0000 Subject: ui tweaks, multiple xpm icon sizes --- headers.h | 5 +- net.cpp | 4 +- ui.cpp | 18 ++-- xpm/bitcoin.xpm | 304 ------------------------------------------------------ xpm/bitcoin16.xpm | 203 ++++++++++++++++++++++++++++++++++++ xpm/bitcoin20.xpm | 226 ++++++++++++++++++++++++++++++++++++++++ xpm/bitcoin32.xpm | 223 +++++++++++++++++++++++++++++++++++++++ xpm/bitcoin48.xpm | 278 +++++++++++++++++++++++++++++++++++++++++++++++++ 8 files changed, 948 insertions(+), 313 deletions(-) delete mode 100644 xpm/bitcoin.xpm create mode 100644 xpm/bitcoin16.xpm create mode 100644 xpm/bitcoin20.xpm create mode 100644 xpm/bitcoin32.xpm create mode 100644 xpm/bitcoin48.xpm diff --git a/headers.h b/headers.h index 6cd2da07db..34eafb2602 100644 --- a/headers.h +++ b/headers.h @@ -101,7 +101,10 @@ using namespace boost; #include "xpm/addressbook16.xpm" #include "xpm/addressbook20.xpm" -#include "xpm/bitcoin.xpm" +#include "xpm/bitcoin16.xpm" +#include "xpm/bitcoin20.xpm" +#include "xpm/bitcoin32.xpm" +#include "xpm/bitcoin48.xpm" #include "xpm/check.xpm" #include "xpm/send16.xpm" #include "xpm/send16noshadow.xpm" diff --git a/net.cpp b/net.cpp index b4df35cb58..d70a62a297 100644 --- a/net.cpp +++ b/net.cpp @@ -1044,13 +1044,13 @@ bool BindListenPort(string& strError) { int nErr = WSAGetLastError(); if (nErr == WSAEADDRINUSE) - strError = strprintf("Unable to bind to port %d on this computer. Bitcoin may be running already.", ntohs(sockaddr.sin_port)); + strError = strprintf("Unable to bind to port %d on this computer. Bitcoin is probably already running.", ntohs(sockaddr.sin_port)); else strError = strprintf("Error: Unable to bind to port %d on this computer (bind returned error %d)", ntohs(sockaddr.sin_port), nErr); printf("%s\n", strError.c_str()); return false; } - printf("bound to port %d\n", ntohs(sockaddr.sin_port)); + printf("Bound to port %d\n", ntohs(sockaddr.sin_port)); // Listen for incoming connections if (listen(hListenSocket, SOMAXCONN) == SOCKET_ERROR) diff --git a/ui.cpp b/ui.cpp index bfb0ad2939..a1873d5c2d 100644 --- a/ui.cpp +++ b/ui.cpp @@ -316,13 +316,15 @@ CMainFrame::CMainFrame(wxWindow* parent) : CMainFrameBase(parent) fOnSetFocusAddress = false; fRefresh = false; m_choiceFilter->SetSelection(0); -#ifndef __WXMSW__ - wxFont fontTmp = m_staticTextBalance->GetFont(); - fontTmp.SetPointSize(10); +#ifdef __WXMSW__ + SetIcon(wxICON(bitcoin)); +#else + SetIcon(bitcoin16_xpm); + wxFont fontTmp = m_staticText41->GetFont(); fontTmp.SetFamily(wxFONTFAMILY_TELETYPE); m_staticTextBalance->SetFont(fontTmp); m_staticTextBalance->SetSize(140, 17); - // ampersand underlines aren't working on gtk + // & underlines don't work on the toolbar buttons on gtk m_toolBar->ClearTools(); 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); @@ -330,7 +332,6 @@ CMainFrame::CMainFrame(wxWindow* parent) : CMainFrameBase(parent) #endif m_staticTextBalance->SetLabel(FormatMoney(GetBalance()) + " "); m_listCtrl->SetFocus(); - SetIcon(wxICON(bitcoin)); ptaskbaricon = new CMyTaskBarIcon(); // Init column headers @@ -1659,7 +1660,8 @@ CSendDialog::CSendDialog(wxWindow* parent, const wxString& strAddress) : CSendDi //// todo: should add a display of your balance for convenience #ifndef __WXMSW__ wxFont fontTmp = m_staticTextInstructions->GetFont(); - fontTmp.SetPointSize(fontTmp.GetPointSize()-1); + if (fontTmp.GetPointSize() > 9); + fontTmp.SetPointSize(9); m_staticTextInstructions->SetFont(fontTmp); SetSize(725, wxDefaultCoord); #endif @@ -3270,7 +3272,11 @@ void CMyTaskBarIcon::Show(bool fShow) if (strncmp(pszPrevTip, strTooltip.c_str(), sizeof(pszPrevTip)-1) != 0) { strlcpy(pszPrevTip, strTooltip.c_str(), sizeof(pszPrevTip)); +#ifdef __WXMSW__ SetIcon(wxICON(bitcoin), strTooltip); +#else + SetIcon(bitcoin20_xpm, strTooltip); +#endif } } else diff --git a/xpm/bitcoin.xpm b/xpm/bitcoin.xpm deleted file mode 100644 index 166d5aa6e4..0000000000 --- a/xpm/bitcoin.xpm +++ /dev/null @@ -1,304 +0,0 @@ -/* XPM */ -static char * bitcoin_xpm[] = { -/* columns rows colors chars-per-pixel */ -"48 48 250 2", -" c #725203", -". c #795603", -"X c #7D5903", -"o c #76560B", -"O c #77590E", -"+ c #795A0D", -"@ c #7B5D14", -"# c #7C5F18", -"$ c #7D6019", -"% c #825D05", -"& c #856007", -"* c #86620B", -"= c #8B660B", -"- c #8E690E", -"; c #906A0F", -": c #8F6B17", -"> c #83641C", -", c #8D6C1E", -"< c #926C11", -"1 c #967014", -"2 c #997215", -"3 c #9C761B", -"4 c #9E791D", -"5 c #A37C1E", -"6 c #816520", -"7 c #876A25", -"8 c #8E6E22", -"9 c #866A29", -"0 c #896E2C", -"q c #8E7020", -"w c #937324", -"e c #997722", -"r c #9E7B25", -"t c #94762B", -"y c #967828", -"u c #9A7B2D", -"i c #8B7131", -"p c #9E7E31", -"a c #947839", -"s c #A37D22", -"d c #A68125", -"f c #AA8325", -"g c #AE8827", -"h c #A6832D", -"j c #AA852B", -"k c #AD892B", -"l c #B08727", -"z c #B28827", -"x c #B08729", -"c c #B38B2C", -"v c #B88E2F", -"b c #B8902D", -"n c #A38334", -"m c #A98632", -"M c #AB8A34", -"N c #A4873C", -"B c #A78A3D", -"V c #AC8B3C", -"C c #B38D32", -"Z c #BA8F30", -"A c #B28E3C", -"S c #B69332", -"D c #BC9433", -"F c #BF9832", -"G c #B4923C", -"H c #BA963D", -"J c #B7993E", -"K c #BE9A3B", -"L c #C1932F", -"P c #C39732", -"I c #C49935", -"U c #C59C3A", -"Y c #C99E3D", -"T c #C2A13F", -"R c #CDA23F", -"E c #9D8342", -"W c #AB8C43", -"Q c #B28E40", -"! c #AE9144", -"~ c #AE914A", -"^ c #B49445", -"/ c #BC9B44", -"( c #B3964D", -") c #B5994C", -"_ c #BD9B4A", -"` c #A98F50", -"' c #B19553", -"] c #B59A54", -"[ c #BD9F51", -"{ c #B59B5C", -"} c #B89D5C", -"| c #BEA155", -" . c #BDA35D", -".. c #B59C61", -"X. c #B99F66", -"o. c #BCA363", -"O. c #BDA56C", -"+. c #BCA571", -"@. c #BDA873", -"#. c #BFAA78", -"$. c #C49D43", -"%. c #C99F45", -"&. c #C29E4B", -"*. c #C5A144", -"=. c #CCA244", -"-. c #C5A44B", -";. c #CAA54B", -":. c #C8A84C", -">. c #D0A644", -",. c #D3AA44", -"<. c #D3AC4C", -"1. c #D8AD4D", -"2. c #DAB046", -"3. c #DCB24E", -"4. c #C3A454", -"5. c #CBA751", -"6. c #CCAA53", -"7. c #C1A65B", -"8. c #C8A75A", -"9. c #CBAC5B", -"0. c #D0A650", -"q. c #D2AC53", -"w. c #DAAD54", -"e. c #D3AD5C", -"r. c #CFB259", -"t. c #D4B156", -"y. c #DDB454", -"u. c #D4B25C", -"i. c #DAB65A", -"p. c #D7B95F", -"a. c #DEBA5E", -"s. c #E2B555", -"d. c #E5BA53", -"f. c #E1B55A", -"g. c #E5BC5C", -"h. c #EABF5D", -"j. c #C1A761", -"k. c #C4AA63", -"l. c #CBAE63", -"z. c #CBB166", -"x. c #CBB26C", -"c. c #D4B263", -"v. c #DAB462", -"b. c #D6B864", -"n. c #DCB965", -"m. c #D3B669", -"M. c #DCB768", -"N. c #D4BA6E", -"B. c #DCBB6C", -"V. c #CDB672", -"C. c #D2B972", -"Z. c #DBBE72", -"A. c #E4BC62", -"S. c #E9BE62", -"D. c #E2BD6C", -"F. c #E0BF72", -"G. c #E6C05E", -"H. c #EFC05D", -"J. c #F0C15B", -"K. c #DFC167", -"L. c #D7C069", -"P. c #DDC36D", -"I. c #DBC376", -"U. c #D4C17B", -"Y. c #DAC17B", -"T. c #D8C878", -"R. c #E4C362", -"E. c #EBC364", -"W. c #E3C865", -"Q. c #EDC866", -"!. c #E4C36A", -"~. c #E9C66B", -"^. c #ECCA6B", -"/. c #F1C564", -"(. c #F8C765", -"). c #F5CB66", -"_. c #F8CC67", -"`. c #F6CC6A", -"'. c #F9CD6B", -"]. c #EED26A", -"[. c #F2D06F", -"{. c #FBD26D", -"}. c #E4C374", -"|. c #EBC474", -" X c #E1C972", -".X c #EDCD72", -"XX c #E4C57A", -"oX c #E9C67C", -"OX c #E5C87C", -"+X c #EACA7D", -"@X c #F2CC74", -"#X c #FBCF71", -"$X c #EED174", -"%X c #ECD37B", -"&X c #F4D274", -"*X c #FDD473", -"=X c #FFD975", -"-X c #F4D57C", -";X c #FCD57A", -":X c #F3DA7C", -">X c #FEDB7C", -",X c #FFE37D", -"X=XQ.s.=.v 5 1 < E HXHXHXHXHXHXHXHXHXHXHXHXHXHX", -"HXHXHXHXHXHXHXHXHXHXHX' g f F d.).).{.{.=X=X=X{.{.{.`.`.`.).g.U f 2 * a HXHXHXHXHXHXHXHXHXHXHXHX", -"HXHXHXHXHXHXHXHXHXHXV f b G.J.{.{.{.*X=X,X=X*X{.`.).`.).).{.`.{./.U 5 ; + HXHXHXHXHXHXHXHXHXHXHX", -"HXHXHXHXHXHXHXHX} h g 1.)._._.{.,X*X=X,X{.{.)._.).).`.`.`.{.*X*X*X`.y.g 2 & $ HXHXHXHXHXHXHXHXHX", -"HXHXHXHXHXHXHX{ j c G.).{.{.{.=X,X{.{.J.d.2.R 2.,.3.g.`.&X;X;X;X&X[.{.`.I 3 & + HXHXHXHXHXHXHXHX", -"HXHXHXHXHXHX{ d D /.{.{.*X=X=X*X).3.R I I I P F F U $.;.n.-XrXrX;X&X;X>XdX:.4 X o HXHXHXHXHXHXHX", -"HXHXHXHXHX..j v /.*X=X=X=X=X`.1.R R R R I I I P K U *.e.D.|.}.+XrXqXhXhXdXfX:.4 X o HXHXHXHXHXHX", -"HXHXHXHXHXh v `.{.>X,X*X{.g.>.Y R I I I I I I U U ;.t.D.|.oXB.z.F.kXvXcXjXjXjX/ 1 . + HXHXHXHXHX", -"HXHXHXHXV g Q.=X=X>X>X'.>.Y Y U R I I I P P I U U <.n.~.}.F.XXXX}.%XbXbXcXcXcXsXc = # HXHXHXHX", -"HXHXHX} j t.>X>X>X*X'.>.U U I U P U U I P P I U T 6.M.D.oX5XwXeXeXqX0XvXbXbXcXjXW.5 % HXHXHXHX", -"HXHXHXM G hXhXqX>X*X<.U U U I I I I I I D D U T T -.9.B.3XpXpXzXgXqX:X:XbXbXcXjXfXT < o HXHXHX", -"HXHX} k XlXkXkXrXA.$.D Z Z Z v v v b b v D U U *.-.9.B.OX2XOXI.P.L.K.W.$XbXcXjX,X].d % 9 HXHX", -"HXHXV J xXxXxXxXrX5.&.A M m m m h h n s 5 g S K *.:.8.4.| k.x.C.N.z.7.) :.$XjXfX,X,XT ; o HXHX", -"HXHXM L.vXxXxXxXF._ MXCXCXCXCXCXCXCXCXmXY.h g K *./ ^ Y.mXCXCXCXCXCXCXVXZ.4.hXfX,X,XW.4 X HXHX", -"HX] k gXxXxXxXgXe.V MXCXCXCXCXVXCXCXCXCXCXyXh D G [ mXCXCXCXCXCXCXCXCXCX4XG ~.fX,X,X,Xg & $ HX", -"HXV J vXxXxXxX6Xe.V MXCXCXCXCXk.N VXCXCXCXVX| h ^ MXCXCXCXCXuX( n V l.mX4XA y.fX,X,X=XT ; HX", -"HXk r.xXxXxXxX|.v.V MXCXCXCXCXo.> 4XCXCXCXCXx.w tXCXCXCXCXnXn V / / M V m.&.t.=X,X,X=Xy.2 o HX", -"HXk P.xXvXxXxX|.M.Q nXCXCXCXCXj.w X>X=XH.5 X $ ", -"o.k %XvXbXBXkX|.D.Q nXCXCXCXCXj., 7XCXCXCXCX~ k.CXCXCXCXCXV &.n.R.g.G.g.S.S.S.(.qX*X=X`.5 X $ ", -" .k 0XvXvXvXrX@XD.^ VXCXCXCXCXx.~ VXCXCXCXX=X*X*Xd X $ ", -"{ k sXcXvXBXeX@XD.( nXCXCXCXCXCXCXCXCXVXo., u T.CXCXCXVXmXn t.E.g.g.h.S.g.S.f.A.>X;X*X*Xf & o ", -"{ k sXjXlXcX0X~.n.^ MXCXCXCXCXCXCXCXCXCXCXU.t U.CXCXCXCXmXM p.~.W.g.s.s.s.s.f.A.>X*X*X*Xj % ", -"o.k :XjXlXlX-XD.v.A MXCXCXCXCXj.t mXCXCXCXCX .x.CXCXCXCXVXV p.$X^.E.g.s.w.w.w.A.9X;X*X*Xf X ", -"o.g ].dXjXhX-Xn.e.V MXCXCXCXCXj.8 X*X#X5 X O ", -"HXj K.dXdXhX9Xv.9.M MXCXCXCXCXk.a Z.CXCXCXCX7Xu CXCXCXCXCXV./ !.$X~.f.5.%.0.q.S.>X*X*XE.5 X # ", -"HXj t.dX,XdXdXi.6.N MXCXCXCXCXo.q XqXqXqX!.6.m MXCXCXCXCXV.' VXCXCXZXCXk.! ] VXCXCXCXCXVXC.[ 7.Z.VX2Xx %.#X#X'.'.%.- o 6 ", -"HX( g &X>X>XdX-X5.M MXCXCXCXCXCXCXCXCXCXCX7X) m.9. .MXCXCXCXCXCXCXCXCXCX2Xs 1.'.`.'.'.x % HX", -"HXO.j y.>X>X>X>X6.! zXMXMXMXMXMXMXMXMXuXx.( N.8X6Xz.) C.uXCXCXCXCXCXVX7X4.c h.'.(.(.s.5 X HX", -"HXHXj H &X=X:X>X~./ V h y u n n n N W ( 7.Z.8XpXpX+Xm.| V V ^ ) ( m e 3 s R (.(.'.'.Y ; . > HX", -"HXHX} f G.&X&X&X:Xt._ / ) _ 4.8.l.m.B.Z.2XwXpXeXwX6X+XP.c.8.-./ C x x z P J.(.'.(./.5 % HXHX", -"HXHXHXh D &X&X&X&X@X:.4.5.9.c.m.F.OX+XwXwXwXwX6X3XOX}.D.D.v.w.%.Y I P P d.(.(.'.'.=.< . + HXHX", -"HXHXHX] d y.[.&X&X&X~.:.4.9.e.M.B.}.oX3X5X3X3X+X}.F.M.e.0.0.0.%.%.Y Y s.#X#X#X#XS.s % HXHXHX", -"HXHXHXHXm g `.@X&X&X&X~.5.6.e.b.B.}.XX+X3XOX}.I.F.F.D.e.e.e.e.e.q.0.A.;X;X#X-X@XZ = o + HXHXHX", -"HXHXHXHX..j D @X&X&X&X&X@Xp.u.M.D.}.XXOXOXZ.Z.XX1XOXoXoXF.F.F.M.D.6XrXqX9X9X9X%.1 . HXHXHXHX", -"HXHXHXHXHX' f $.&X&X&X>XqXqX XB.D.!.XXXXZ.XXOX5XwXwXwXwXiXwXwXnXVXZXBXxXzXxXb.r X $ HXHXHXHX", -"HXHXHXHXHXHX~ j ;.qXqXqXqXrXkXrX+XD.Z.Z.XX1X2X5X5X5XwXwXiXnXCXGXGXFXFXSXAXT.s % @ HXHXHXHXHX", -"HXHXHXHXHXHXHX~ j -.0XrXzXxXzXzXzXzXwX3XXXXXOX1X2X5XpXmXAXFXGXGXGXFXFXSXL.r % O HXHXHXHXHXHX", -"HXHXHXHXHXHXHXHX! j / gXSXSXZXxXzXzXkXxXzXBXBXBXZXCXAXAXAXAXSXSXSXSXNX| 3 & O HXHXHXHXHXHXHX", -"HXHXHXHXHXHXHXHXHX} n V U.DXSXBXzXkXkXkXxXxXxXBXxXBXBXCXZXZXZXAXAXU.M < . @ HXHXHXHXHXHXHXHX", -"HXHXHXHXHXHXHXHXHXHXHXV d G Z.pXzXkXzXjXkXkXxXzXxXxXxXBXBXZXNXT.G 3 * . 9 HXHXHXHXHXHXHXHXHX", -"HXHXHXHXHXHXHXHXHXHXHXHX@.u s k -.K.6XhXjXhXkXlXzXzXzXeXOX9.k 3 = X O HXHXHXHXHXHXHXHXHXHXHX", -"HXHXHXHXHXHXHXHXHXHXHXHXHXHX..w < s j k K -.;.:.-./ C j 4 < & . O HXHXHXHXHXHXHXHXHXHXHXHXHX", -"HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXE * = - - < < - = & X . 0 HXHXHXHXHXHXHXHXHXHXHXHXHXHXHX", -"HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXi 7 7 @ o o O > 0 i HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHX" -}; diff --git a/xpm/bitcoin16.xpm b/xpm/bitcoin16.xpm new file mode 100644 index 0000000000..8bec142c8b --- /dev/null +++ b/xpm/bitcoin16.xpm @@ -0,0 +1,203 @@ +/* XPM */ +static char * bitcoin16_xpm[] = { +/* columns rows colors chars-per-pixel */ +"16 16 181 2", +" c #775605", +". c #745507", +"X c #785806", +"o c #7D5A06", +"O c #745508", +"+ c #755508", +"@ c #755608", +"# c #775708", +"$ c #77580B", +"% c #7A5A0B", +"& c #7D5E14", +"* c #86630D", +"= c #8D6B16", +"- c #886818", +"; c #927019", +": c #91701E", +"> c #9A751E", +", c #957627", +"< c #9A7925", +"1 c #987827", +"2 c #98782B", +"3 c #9D7C2F", +"4 c #9E7E31", +"5 c #A57D22", +"6 c #A88227", +"7 c #B78D2E", +"8 c #B78F2E", +"9 c #A78430", +"0 c #A48733", +"q c #A68536", +"w c #A98937", +"e c #B98F31", +"r c #B49233", +"t c #B39337", +"y c #C09837", +"u c #C39936", +"i c #C49936", +"p c #C69C39", +"a c #C89C3A", +"s c #CCA23A", +"d c #AF9240", +"f c #B99644", +"g c #BE9C46", +"h c #BF9D4A", +"j c #BA9F58", +"k c #BEA04B", +"l c #BBA253", +"z c #BAA057", +"x c #C29E44", +"c c #C2A144", +"v c #CAA246", +"b c #CCA344", +"n c #CEA645", +"m c #C2A04A", +"M c #C7A349", +"N c #C5A34A", +"B c #C7A64D", +"V c #CFA649", +"C c #CEAA4C", +"Z c #D1A84B", +"A c #D4AC49", +"S c #D5AC49", +"D c #D7AD48", +"F c #D5AF4D", +"G c #C0A451", +"H c #CAA550", +"J c #CBAA58", +"K c #CAAD5D", +"L c #D9AD53", +"P c #DFB757", +"I c #D5B058", +"U c #D7B75D", +"Y c #DCB75A", +"T c #DFBB5E", +"R c #E1B957", +"E c #E3B759", +"W c #E6BC5B", +"Q c #E7BE5D", +"! c #E5BC5E", +"~ c #CAAE62", +"^ c #C8AF6A", +"/ c #CDB565", +"( c #CDB46D", +") c #D7B360", +"_ c #D5B862", +"` c #D1B66C", +"' c #D8BB68", +"] c #DBBA6E", +"[ c #DFBE6D", +"{ c #D0B872", +"} c #D2B974", +"| c #DABF74", +" . c #D8BF77", +".. c #D6BD79", +"X. c #D5BE7B", +"o. c #D7BF7A", +"O. c #E8BC61", +"+. c #DDC075", +"@. c #DCC279", +"#. c #DCC47E", +"$. c #EDC661", +"%. c #EEC562", +"&. c #E0C16B", +"*. c #E0C36B", +"=. c #E3C26A", +"-. c #E7C26A", +";. c #E3C569", +":. c #E3C26C", +">. c #E4C16C", +",. c #EEC969", +"<. c #F4C664", +"1. c #F0CA68", +"2. c #F7CA68", +"3. c #F6CD69", +"4. c #F7CD69", +"5. c #F7CF68", +"6. c #E6C374", +"7. c #E1C47A", +"8. c #E1C77B", +"9. c #E5C578", +"0. c #E4C579", +"q. c #E4C67A", +"w. c #E5C67C", +"e. c #E8C57B", +"r. c #E8CB7B", +"t. c #EDCC78", +"y. c #EBCB7C", +"u. c #F0CF73", +"i. c #F6CF74", +"p. c #F4D173", +"a. c #F7D072", +"s. c #F5D376", +"d. c #FAD071", +"f. c #FBD470", +"g. c #FAD572", +"h. c #FDD671", +"j. c #FDD773", +"k. c #F3DB76", +"l. c #F8D578", +"z. c #FBDB79", +"x. c #FFE57E", +"c. c #DEC681", +"v. c #DFC782", +"b. c #E0C682", +"n. c #E1C984", +"m. c #E2C985", +"M. c #E3CB87", +"N. c #E9C980", +"B. c #EBCC82", +"V. c #E3CC88", +"C. c #E4CF8D", +"Z. c #EFD187", +"A. c #EFD488", +"S. c #EFD58D", +"D. c #F6D581", +"F. c #F1D687", +"G. c #F9D680", +"H. c #F7DA8B", +"J. c #F2DE93", +"K. c #FADF93", +"L. c #F3DB98", +"P. c #F0DB9B", +"I. c #FEE081", +"U. c #FEE18C", +"Y. c #FCE38F", +"T. c #F7E98E", +"R. c #FFE88C", +"E. c #F6E491", +"W. c #FBEA91", +"Q. c #FFE897", +"!. c #FFEE9A", +"~. c #FEE99D", +"^. c #FEEC9F", +"/. c #FEF092", +"(. c #FFF29A", +"). c #FBE7A9", +"_. c #F4EDA8", +"`. c #FAEBAA", +"'. c #FEEBAD", +"]. c #FEFABD", +"[. c None", +/* pixels */ +"[.[.[.[.[.3 f M m q [.[.[.[.[.[.", +"[.[.[.4 A 5.j.f.3.3.! 6 [.[.[.[.", +"[.[.9 %.h.%.D s n -.z.l.c % [.[.", +"[.1 1.g.S p i i C 6.7.W./.t [.[.", +"[._ U.Z e 7 7 y B | #.*.T.k.* [.", +", E.F.c.).).C.g K `.`.C.' x.r + ", +"d !.y.M.).j '.( ).L.h M I z.F + ", +"G (.t.M.'.'.C.j ).b.T Q O.d.R X ", +"k T.O.M.`.^ `.X.).V.;.! L i.E ", +"w I.6.c.'.).C.{ c.).).C.H d.v + ", +"[.,.u.~ } X.@.@.| .#.` V 2.5 ", +"[.x p.U J ] B.Z.9.) v a <.E o [.", +"[.[.Y s.-.[ 0.0.N.e.w.H.D.> + [.", +"[.[.2 &.).Y.A.S.L.`.]._.0 . [.[.", +"[.[.[.[.l r.Y.Q.~.J./ = $ [.[.[.", +"[.[.[.[.[.[.: 1 ; - & [.[.[.[.[." +}; diff --git a/xpm/bitcoin20.xpm b/xpm/bitcoin20.xpm new file mode 100644 index 0000000000..2dd61a59dc --- /dev/null +++ b/xpm/bitcoin20.xpm @@ -0,0 +1,226 @@ +/* XPM */ +static char * bitcoin20_xpm[] = { +/* columns rows colors chars-per-pixel */ +"20 20 200 2", +" c #7B5500", +". c #7B5900", +"X c #735508", +"o c #7B5908", +"O c #7B5D08", +"+ c #7B5910", +"@ c #7B6118", +"# c #845D08", +"$ c #846108", +"% c #8C6510", +"& c #8C6910", +"* c #8C6918", +"= c #946D10", +"- c #947118", +"; c #9C7518", +": c #A57918", +"> c #846929", +", c #846D29", +"< c #947121", +"1 c #8C7539", +"2 c #947939", +"3 c #8C7542", +"4 c #AD8221", +"5 c #B58E29", +"6 c #B58E31", +"7 c #B59231", +"8 c #BD9231", +"9 c #BD9631", +"0 c #C69A31", +"q c #C69A39", +"w c #C69E39", +"e c #CE9E39", +"r c #CEA239", +"t c #948652", +"y c #A58A4A", +"u c #BD9642", +"i c #BD9A42", +"p c #B5964A", +"a c #B59A4A", +"s c #BD9E4A", +"d c #A58E5A", +"f c #BD9A52", +"g c #BD9E52", +"h c #BDA252", +"j c #BDA25A", +"k c #BD9E63", +"l c #A59673", +"z c #AD9A73", +"x c #AD9E7B", +"c c #BDA263", +"v c #BDA26B", +"b c #BDA273", +"n c #BDA673", +"m c #B5A27B", +"M c #BDAA7B", +"N c #C69E42", +"B c #CE9E42", +"V c #C6A242", +"C c #CEA242", +"Z c #CEA642", +"A c #C6A24A", +"S c #C6A64A", +"D c #CEA64A", +"F c #CEAA4A", +"G c #D6A642", +"H c #DEAE4A", +"J c #DEB24A", +"K c #C6A252", +"L c #C6A652", +"P c #CEAA52", +"I c #CEAE52", +"U c #C6A65A", +"Y c #C6AA5A", +"T c #CEAA5A", +"R c #CEAE5A", +"E c #D6AE52", +"W c #DEAE52", +"Q c #D6AE5A", +"! c #D6B252", +"~ c #DEB252", +"^ c #DEB652", +"/ c #D6B65A", +"( c #DEB65A", +") c #DEBA5A", +"_ c #EFBE52", +"` c #E7BA5A", +"' c #E7BE5A", +"] c #EFBE5A", +"[ c #C6A663", +"{ c #C6AE63", +"} c #CEAE63", +"| c #D6AE63", +" . c #CEB26B", +".. c #CEB66B", +"X. c #DEB663", +"o. c #D6BE63", +"O. c #DEBA63", +"+. c #DEBE63", +"@. c #D6B66B", +"#. c #DEB66B", +"$. c #D6BA6B", +"%. c #D6BE6B", +"&. c #DEBA6B", +"*. c #DEBE6B", +"=. c #D6BA73", +"-. c #DEBE73", +";. c #EFBE63", +":. c #E7BE73", +">. c #DEC37B", +",. c #E7C363", +"<. c #EFC763", +"1. c #EFCF63", +"2. c #E7C36B", +"3. c #E7C76B", +"4. c #EFC36B", +"5. c #EFC76B", +"6. c #E7CB6B", +"7. c #EFCB6B", +"8. c #F7CB63", +"9. c #F7CB6B", +"0. c #F7CF6B", +"q. c #FFCB6B", +"w. c #F7D36B", +"e. c #FFD36B", +"r. c #E7C373", +"t. c #E7CB73", +"y. c #EFCF73", +"u. c #E7C37B", +"i. c #E7C77B", +"p. c #E7CB7B", +"a. c #EFCB7B", +"s. c #F7CF73", +"d. c #EFD373", +"f. c #EFD37B", +"g. c #F7D373", +"h. c #FFD373", +"j. c #FFD773", +"k. c #FFDB73", +"l. c #F7DB7B", +"z. c #FFDF7B", +"x. c #ADA284", +"c. c #BDAA84", +"v. c #BDAE84", +"b. c #B5A68C", +"n. c #B5AE9C", +"m. c #BDB6A5", +"M. c #C6BA9C", +"N. c #C6BAA5", +"B. c #C6BEA5", +"V. c #DEC784", +"C. c #E7CB84", +"Z. c #E7CF84", +"A. c #EFCF84", +"S. c #E7CF8C", +"D. c #EFCF8C", +"F. c #EFD384", +"G. c #E7D38C", +"H. c #EFD38C", +"J. c #EFD78C", +"K. c #F7D784", +"L. c #FFD784", +"P. c #F7DB84", +"I. c #F7DF84", +"U. c #FFDB84", +"Y. c #FFDF84", +"T. c #F7DB8C", +"R. c #EFD394", +"E. c #EFD794", +"W. c #EFDB94", +"Q. c #EFDB9C", +"!. c #F7DB9C", +"~. c #F7DF9C", +"^. c #FFE384", +"/. c #FFE784", +"(. c #FFE38C", +"). c #FFEB8C", +"_. c #EFE79C", +"`. c #FFE794", +"'. c #FFEB94", +"]. c #FFEF94", +"[. c #FFEB9C", +"{. c #FFEF9C", +"}. c #FFF394", +"|. c #FFF794", +" X c #C6C3B5", +".X c #CEC7BD", +"XX c #F7E3A5", +"oX c #FFE7A5", +"OX c #F7EBA5", +"+X c #FFEBA5", +"@X c #FFEFA5", +"#X c #FFE7AD", +"$X c #FFEBAD", +"%X c #FFEFAD", +"&X c #FFF3AD", +"*X c #FFF7B5", +"=X c #FFFBB5", +"-X c #FFFFBD", +";X c #CEC7C6", +":X c None", +/* pixels */ +":X:X:X:X:X:XM.v f i g k c..X:X:X:X:X:X:X", +":X:X:X:XM.u H 8.j.j.e.0.^ 7 d X:X:X:X:X", +":X:X:Xn Z 0.k.j.8._ ] 9.h.h.~ ; b.:X:X:X", +":X:Xn J j.j.' C 0 0 w E a.K.^.d.- x.:X:X", +":XN.F k.w.G w q 0 0 D 2.i.a.].|.6.$ m.:X", +":Xg (.U.C 9 8 8 8 q S *.H.f.y.].).9 , :X", +"B.o.{.p.-.>.>.>.R 7 N =.G.E.Z.&./.1.# n.", +"M I.[.| R.$X..~.#Xs V.$XG.h @.T l.z.; t ", +"c {.'.X.E.$Xj G.$XU #X$Xg ) ! ( 0.k.5 > ", +"j }.`.O.E.$XE.oXC.p $X$XA ,.' ;.5.j.9 o ", +"j ).I.Q E.$X .Q.#X .$X$XP 7.` W 4.j.8 X ", +"c z.Y.P R.$X[ S.$X{ XX$X$.) P D 5.h.4 @ ", +"v.<.Y.I R.$XW.oXXX} @.XX#XE.XXK 8.8.& 3 ", +".XC j.3.s a h Y .J.A.T Y h 6 e 8.H . x ", +":Xk <.g./ P #.i.F.A.r.X.E B r 9.q.: + :X", +":X.Xi s.g.+.O.r.i.u.i.u.:.r.L.L.N l :X", +":X:XN.V U.(.T.a.i.C.D.!.%X-X=X%.# 1 :X:X", +":X:X:XN.g _.+X`.[.+X@X&X*XOXh O 1 :X:X:X", +":X:X:X:X;Xb i +.f.P.K.t.L = o z :X:X:X:X", +":X:X:X:X:X:X.Xm y < % * 2 x :X:X:X:X:X:X" +}; diff --git a/xpm/bitcoin32.xpm b/xpm/bitcoin32.xpm new file mode 100644 index 0000000000..25da102f6a --- /dev/null +++ b/xpm/bitcoin32.xpm @@ -0,0 +1,223 @@ +/* XPM */ +static char * bitcoin32_xpm[] = { +/* columns rows colors chars-per-pixel */ +"32 32 185 2", +" c #715103", +". c #725203", +"X c #725204", +"o c #735304", +"O c #745404", +"+ c #765504", +"@ c #775504", +"# c #785604", +"$ c #795704", +"% c #795705", +"& c #77580A", +"* c #77580B", +"= c #77580C", +"- c #785808", +"; c #785809", +": c #78590D", +"> c #795A0D", +", c #7F5E0D", +"< c #7C5C0E", +"1 c #815F0E", +"2 c #89650F", +"3 c #8C670F", +"4 c #8D680F", +"5 c #836110", +"6 c #866410", +"7 c #8F6A11", +"8 c #926C12", +"9 c #946F14", +"0 c #967015", +"q c #987217", +"w c #997318", +"e c #9A751C", +"r c #9B761E", +"t c #9C7720", +"y c #9D7924", +"u c #9D7B28", +"i c #9E7C2C", +"p c #A07F31", +"a c #AA852D", +"s c #A9852E", +"d c #AC872D", +"f c #AE892E", +"g c #AF8A2E", +"h c #B08B2F", +"j c #A18133", +"k c #A78533", +"l c #A28235", +"z c #A48435", +"x c #A68535", +"c c #A58536", +"v c #A68536", +"b c #A88530", +"n c #B18C30", +"m c #B18D33", +"M c #B08D37", +"N c #B08F3B", +"B c #B08F3D", +"V c #BC9537", +"C c #BE9736", +"Z c #BF9737", +"A c #B6933B", +"S c #B0903F", +"D c #B2913E", +"F c #B4923D", +"G c #B99438", +"H c #C09736", +"J c #C19835", +"K c #C29836", +"L c #C39937", +"P c #C39A37", +"I c #C49B38", +"U c #C59C3A", +"Y c #C69D3B", +"T c #C79E3C", +"R c #C89F3D", +"E c #CAA03F", +"W c #C6A247", +"Q c #CAA140", +"! c #C9A242", +"~ c #C8A245", +"^ c #C2A14B", +"/ c #C3A24D", +"( c #C3A24F", +") c #C2A351", +"_ c #C1A352", +"` c #C0A355", +"' c #C1A457", +"] c #C1A458", +"[ c #C1A55A", +"{ c #C2A65C", +"} c #C3A75D", +"| c #C3A85E", +" . c #C6AA5D", +".. c #C7AA5D", +"X. c #C5A95E", +"o. c #CFAE5A", +"O. c #C8AB5E", +"+. c #D4AF56", +"@. c #D1AE58", +"#. c #D6B056", +"$. c #D8B155", +"%. c #D9B256", +"&. c #DAB357", +"*. c #DBB457", +"=. c #DDB558", +"-. c #DFB759", +";. c #E2BB5B", +":. c #E3BC5D", +">. c #E4BD5E", +",. c #C9AC61", +"<. c #C9AD62", +"1. c #CAAE62", +"2. c #CCAF62", +"3. c #DDBC69", +"4. c #DFBD68", +"5. c #DCBB6E", +"6. c #DCBC6C", +"7. c #DBBC70", +"8. c #DABD72", +"9. c #DBBE74", +"0. c #E4BD61", +"q. c #E4BE60", +"w. c #E3BE65", +"e. c #E2BF66", +"r. c #DDC177", +"t. c #DFC279", +"y. c #EFCB6F", +"u. c #F1CA6B", +"i. c #F4CB6A", +"p. c #F5CC6A", +"a. c #F7CD6B", +"s. c #F0CA6D", +"d. c #F7CF6E", +"f. c #EFCD72", +"g. c #EFCE77", +"h. c #E0C47B", +"j. c #E3C77E", +"k. c #E4C87F", +"l. c #F7D070", +"z. c #F8D171", +"x. c #F8D272", +"c. c #FAD473", +"v. c #FBD676", +"b. c #FCD574", +"n. c #FCD674", +"m. c #FCD777", +"M. c #F0D17E", +"N. c #FCD778", +"B. c #FCDA7A", +"V. c #FDDC7C", +"C. c #FDDE7E", +"Z. c #E6CA80", +"A. c #E8CC83", +"S. c #EACD84", +"D. c #ECD086", +"F. c #EFD286", +"G. c #EED287", +"H. c #F0D283", +"J. c #FDDF80", +"K. c #F6DF91", +"L. c #F5DE92", +"P. c #F4DE95", +"I. c #F4DF98", +"U. c #FDE081", +"Y. c #FCE184", +"T. c #FBE188", +"R. c #FAE18B", +"E. c #F8E08D", +"W. c #F5E19B", +"Q. c #F5E29C", +"!. c #F7E49D", +"~. c #F9E69B", +"^. c #FBE89B", +"/. c #FDEB9B", +"(. c #FDEC9B", +"). c #FEEE9B", +"_. c #FEEF9C", +"`. c #FEEEA3", +"'. c #FDEBA9", +"]. c #FDEBAC", +"[. c #FDEBAD", +"{. c #FDECAD", +"}. c #FDF0B0", +"|. c #FDF2B1", +" X c None", +/* pixels */ +" 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 X X X X X X X Xc F z z F z j X X X X X X X X X X X X X", +" X X X X X X X X Xz b V ~ %.;.u.e.-.! f e i X X X X X X X X X X", +" X X X X X X Xz d ! >.a.l.B.v.c.a.a.a.a.>.R w 6 X X X X X X X X", +" X X X X X Xb L q.a.n.c.n.n.c.a.i.i.a.a.z.z.>.m 3 5 X X X X X X", +" X X X X Xs +.a.c.n.B.c.>.#.E E ! +.>.n.J.v.z.z.~ 8 & X X X X X", +" X X X Xs %.c.n.B.l.*.E Y L L L L W +.r.Z.H.Y.Y.R.+.7 ; X X X X", +" X X Xk %.n.J.n.>.! Y Y I L L L T *.w.h.7.5.K.).).).W 6 = X X X", +" X Xj T V.B.n.;.L L L I L L L Y ~ *.s.Z.G.D.B._._._.Y.h % > X X", +" X Xm H.R.Y.0.L H H L L C V C Y ! ..8.G.E.H.M.g._._.Y.q.8 o X X", +" Xj o.)./.K.@.^ A F M N M s n C W ) { <.9.9.2.X.#./.Y.C.m % > X", +" XM D.)._.t.,.[.[.[.[.{.[.W.A G C O.I.[.[.[.[.{.5.y.Y.B.*.2 o X", +" XA /.).~.%.{ [.[.[.| D.[.[.I.b ,.[.[.[.j.) ' D.5.@.Y.V.a.w . X", +"i O.).).E.3.X.[.[.[.S X.[.[.'.i Q.[.{.D.z X.~ A ) %.B.V.n.s + = ", +"z 6._._.R.w.<.[.[.[.S <.[.[.I.F [.[.[.X.) 0.>.;.>.>.l.B.n.C % > ", +"z e._._.H.e.,.[.[.[.j.W.[.D.S { [.[.].' -.>.>.>.e.0.s.N.n.Y % & ", +"v s.)._.M.3.O.[.].].W.'.[.].{ { [.[.[.' 3.e.;.;.%.-.s.N.n.R # . ", +"z ;.T.E.g.-.{ [.].].S <.[.{.].` [.[.[.<.e.f.e.*.$.$.s.V.n.L $ O ", +"j o.Y.Y.g.+.] {.].]._ | [.[.[.F ].[.[.A.) y.e.@.W @.s.N.n.h $ = ", +" XZ J.Y.N.@.' [.[.].F 7.[.[.].z h.[.[.].7.^ ^ 5.2.U z.z.a.r X = ", +" Xs n.V.Y.+.` [.[.].].].{.{.9.2...A.{.[.[.[.].[.2.! a.u.;.3 = ", +" XF *.m.B.s.^ X.,.{ ,.<.1.] 2.G.D.O.` 2.9.7.2.^ d ;.u.a.K $ X X", +" X Xm z.c.v.o.^ ^ ^ { <.7.Z.K.K.H.Z.6.o.^ A f h E a.i.0.w X = X", +" X Xz #.l.z.f.X.O.<.5.t.Z.D.D.A.j.7.*.@.^ ! Y ! i.a.a.Y , X X X", +" X X Xd u.l.z.y.o.o.3.r.j.Z.h.r.9.5.%.%.#.+.#.c.B.z.-.8 . & X X", +" X X Xj m f.c.v.l.s.3.4.h.t.r.k.D.G.H.D.A.D./.!.E.M.y + X X X X", +" X X X Xj Z v.J.T.R.E.Z.7.t.Z.A.S.H.D.Q.|.|.|.|.!.b % . X X X X", +" X X X X Xj A D.|.`.~.~.!.E.I.I.Q.{.|.|.|.|.|.D.u % X < X X X X", +" X X X X X Xj z 9.{.`.~.~.^././.`.`.`.}.|.Q.] 9 $ X X X X X X X", +" X X X X X X X Xj s X.k.Y.R.~.~./.~.K.h.) e , . = X X X X X X X", +" X X X X X X X X X X9 w t n A C A s r 3 $ X > X X X X X X X X X", +" X X X X X X X X X X X X X5 2 1 $ ; 5 5 5 X X X X X X X X X X X" +}; diff --git a/xpm/bitcoin48.xpm b/xpm/bitcoin48.xpm new file mode 100644 index 0000000000..788e855ddd --- /dev/null +++ b/xpm/bitcoin48.xpm @@ -0,0 +1,278 @@ +/* XPM */ +static char * bitcoin48_xpm[] = { +/* columns rows colors chars-per-pixel */ +"48 48 224 2", +" c #715103", +". c #735203", +"X c #735204", +"o c #745405", +"O c #755506", +"+ c #775606", +"@ c #785707", +"# c #7A5806", +"$ c #7C5905", +"% c #7D5A05", +"& c #7E5B05", +"* c #7F5C07", +"= c #7E5C0A", +"- c #7B5C11", +"; c #7C5D13", +": c #7D5E15", +"> c #805C05", +", c #805C06", +"< c #8B6813", +"1 c #8D6912", +"2 c #8F6A12", +"3 c #896816", +"4 c #806219", +"5 c #82631A", +"6 c #876719", +"7 c #84651B", +"8 c #906C13", +"9 c #916D15", +"0 c #936F18", +"q c #94701B", +"w c #95721B", +"e c #98731A", +"r c #99741B", +"t c #99751E", +"y c #9A761F", +"u c #9B7822", +"i c #9F7A21", +"p c #9D7922", +"a c #A27C20", +"s c #A47E21", +"d c #A67F22", +"f c #9E8038", +"g c #9E803B", +"h c #9E813C", +"j c #9F833D", +"k c #A68023", +"l c #A78124", +"z c #A98326", +"x c #AA8427", +"c c #A7832B", +"v c #A7832C", +"b c #A6832D", +"n c #A98429", +"m c #A8842B", +"M c #AD892F", +"N c #AE8A2F", +"B c #AF8A2F", +"V c #B28B2E", +"C c #B48C2E", +"Z c #B68E2F", +"A c #B78E2F", +"S c #A38232", +"D c #A08136", +"F c #AC8931", +"G c #AB8934", +"H c #AA8836", +"J c #AA8937", +"K c #A1843F", +"L c #A2853F", +"P c #AB8A39", +"I c #AB8B3A", +"U c #AD8C3C", +"Y c #AE8E3E", +"T c #B89030", +"R c #BA9131", +"E c #BC9332", +"W c #BE9533", +"Q c #C09733", +"! c #C29834", +"~ c #C39934", +"^ c #C39935", +"/ c #C39A37", +"( c #C39A38", +") c #C49A38", +"_ c #C49B38", +"` c #C59C3A", +"' c #C69E3C", +"] c #C69E3E", +"[ c #C79F3F", +"{ c #A48640", +"} c #A58741", +"| c #A68842", +" . c #A78A43", +".. c #AA8D45", +"X. c #AD9046", +"o. c #B19040", +"O. c #B59443", +"+. c #B29447", +"@. c #B79745", +"#. c #B79847", +"$. c #B89846", +"%. c #B69748", +"&. c #C8A040", +"*. c #CAA241", +"=. c #CBA343", +"-. c #C9A346", +";. c #CBA445", +":. c #C7A44D", +">. c #C5A44F", +",. c #C9A448", +"<. c #C9A44A", +"1. c #C5A551", +"2. c #C4A554", +"3. c #CBAA57", +"4. c #CDAA57", +"5. c #C3A559", +"6. c #C4A65A", +"7. c #C7A85A", +"8. c #D0AB55", +"9. c #D2AD56", +"0. c #D4AE57", +"q. c #D4AF58", +"w. c #D5B05A", +"e. c #D5B15C", +"r. c #D5B25E", +"t. c #DFB65A", +"y. c #DEB75B", +"u. c #E1B759", +"i. c #E2B95B", +"p. c #E4BA5C", +"a. c #E4BC5F", +"s. c #D4B567", +"d. c #D8B764", +"f. c #D5B769", +"g. c #D4B76A", +"h. c #D4B86B", +"j. c #E5BD61", +"k. c #E6BE62", +"l. c #E6BF63", +"z. c #E0BF6F", +"x. c #E7C063", +"c. c #EAC263", +"v. c #EDC563", +"b. c #EBC364", +"n. c #EEC565", +"m. c #EEC767", +"M. c #E1C06F", +"N. c #EBC76D", +"B. c #EEC869", +"V. c #F7CD6A", +"C. c #F6CD6B", +"Z. c #F4CE6F", +"A. c #F8CD6A", +"S. c #F9CF6E", +"D. c #FAD16F", +"F. c #E1C071", +"G. c #E4C370", +"H. c #E1C174", +"J. c #E0C276", +"K. c #E1C377", +"L. c #E8C670", +"P. c #E2C479", +"I. c #E0C47A", +"U. c #E2C57C", +"Y. c #E3C77E", +"T. c #F3D073", +"R. c #FBD270", +"E. c #FCD572", +"W. c #FCD674", +"Q. c #FDD774", +"!. c #FED876", +"~. c #FED977", +"^. c #F2D278", +"/. c #F1D37B", +"(. c #FDDA78", +"). c #FDDB7A", +"_. c #FDDB7C", +"`. c #FDDD7D", +"'. c #FDDF7F", +"]. c #E4C880", +"[. c #E6CA83", +"{. c #E7CD86", +"}. c #E9CF89", +"|. c #EBD089", +" X c #EFD289", +".X c #F2D382", +"XX c #F0D387", +"oX c #FDDF80", +"OX c #FCDF84", +"+X c #FBDF89", +"@X c #F9DE8B", +"#X c #FBE08B", +"$X c #FBE28C", +"%X c #FCE48F", +"&X c #FDE592", +"*X c #FEE692", +"=X c #FEE693", +"-X c #FEE895", +";X c #FEEA96", +":X c #FEEC97", +">X c #FEEE98", +",X c #FEEE99", +"X>X:X:X%X' 0 O # sXsXsXsXsX", +"sXsXsXsXG n m.(.!.(.(.S.;.] [ _ ` _ ^ ^ ! Q ^ _ ` 9.k.M.U.K.U.H.U./.>X>X>X>X>X#XV < . - sXsXsXsX", +"sXsXsXh n w._._.(.W.S.;._ _ _ / _ _ _ _ Q Q / ` [ 9.d.G.H.|.XX@X#X#X).:X>X>X>X>Xm.a > sXsXsXsX", +"sXsXsXG @.#X+XOX_.R.8._ _ _ _ ! ^ _ ) ! W W _ ] [ <.r.h.{.@X6X&X#X#X).).>X>X>X;X#X' 8 + + sXsXsX", +"sXsXL M H.;X=X&X#Xk.] E R T Z T A A A A R E _ ` &.<.4.F.Y.[.U.H.z.h.z.L.^.>X>X;X'.m.k > : sXsX", +"sXsXP @.,X,X1X;X+X3.%.o.G H F m m b b a s z E _ [ 1.2.2.2.7.h.h.h.h.2.$.1.^.;X#X'.).` 2 . + sXsX", +"sXsXF f.X>X/.L.d.o.6X0X0XwXwX0X0XwXwX0X9XI.u I.0XwXqXqX3XG r.B.c.i.u.u.u.u.y.p.`.!.E.E.x * X ", +" .n ^.&X;X;X.Xx.d.Y 6X0XwX0X0X5.u 3X0XwXwX9X5.h.wX0XqXqX6XP d.T.N.c.i.u.y.0.0.k.(.!.W.E.k * X ", +"L x C.'.*X&X^.j.r.P 7XqX0XwX0X6.0 I.wX0XwX0XI.@.0XqXqXqX0X+.q.T.T.N.a.y.9.8.9.l._.!.!.D.s $ - ", +"sXx k.#X#X$X.Xy.8.G 3XqXwX0XwX7.u I.0XwX0XwX}.u qXqXqXqX0Xh.$.G.T.N.p.9.-.-.8.N._.!.E.b.i # X : ", +"sXc 9.'.'.#X'.y.4.H 7XqX0XwX0X6.q ].9XwX0XwXU.u {.0XwX0XwX8X%.#.w.4.$.#.f.W -.Z.W.R.R.y.r O = ", +"sXN _ '.'.'.#Xx.3.P 7XqXwX0XwXh.+.8XwX0X0X0X7.X.#.8X0XwX0XwX6Xh.2.5.U.6X{.F *.R.R.R.S.*.1 ; ", +"sXX.x E.`.).`.T.1.G 8XwX0XwXwX0XwX0X0XwX0X}.%.h.7.5.3X0X0XwX0XwXwX0X0X0X[.z 9.A.V.V.V.n * X sX", +"sXg x y.~.).).#X4.o.3X3X3X3X3X3X3X7X3X Xh.%.h. X|.3.#.h.3X0X0X0X0X0X8X}.2.V c.A.C.V.i.e # X X sX", +"sXsXn W E.E.).`.L.$.P g u p f D d . .+.6.U. X@X@X}.f.1.U Y %.%.+.H y e l &.A.A.V.V.' 8 X ; sX", +"sXsX..x k.T.T.T.W.9.#.#.#.#.1.7.4.s.h.z.}.}.@X@X X X].z.d.3.:.@.V V V C E c.A.A.A.c.s > sXsX", +"sXsXsXb W T.T.T./.T.:.1.3.4.r.h.z.].[. X X X X X[.Y.H.z.z.d.0.;.` / Q Q u.A.A.A.D.*.9 O X # sXsX", +"sXsXsX| l y.T.T.T./.N.<.1.4.r.f.z.z.].[.{.{.[.].H.z.s.r.8.8.-.-.*.] ] u.D.E.D.D.k.a > sXsXsX", +"sXsXsXsXn F B.T.T.T.^.N.1.4.w.s.z.z.U.[.{.].J.J.H.F.h.r.w.r.w.0.8.8.k.W.W.R.D.T.Z 1 O @ sXsXsX", +"sXsXsXsXf x W T.T.T.^./.T.r.r.d.z.L.U.].U.z.z.P.Y.[.[.U.P.F.G.h.h..X@XOXOX.X.X<.9 # sXsXsXsX", +"sXsXsXsXsXL x [ W.W.W.)._.OXN.d.z.z.I.U.I.z.U. X.X X XXXXX X XXXwXyX,X1X1X=Xs.p > X ; sXsXsXsX", +"sXsXsXsXsXsX| x :._.oX_.OX$X=X+X/.G.h.z.I.].}.}.|.|. X X X3XtXpXpXpXpXpXaXP.a > X - sXsXsXsXsX", +"sXsXsXsXsXsXsX{ c <.+X@X=X;X;X&X=X&XXX[.U.P.U.].[.}.XX3XyXpXpXpXpXpXpXpXh.a > O sXsXsXsXsXsX", +"sXsXsXsXsXsXsXsXL c @.+XpXpXuX1X=X=X;X1X1X1X1XrXwXwXyXyXyXuXpXaXpXuX3X2.u > . @ sXsXsXsXsXsXsX", +"sXsXsXsXsXsXsXsXsXj n Y I.aXaX0X=X=X&X;X=X1X1X1X Date: Sat, 7 Nov 2009 18:51:41 +0000 Subject: ui tweaks, multiple xpm icon sizes git-svn-id: https://bitcoin.svn.sourceforge.net/svnroot/bitcoin/trunk@36 1a98c847-1fd6-4fd8-948a-caf3550aa51b --- headers.h | 5 +- net.cpp | 4 +- ui.cpp | 18 ++-- xpm/bitcoin.xpm | 304 ------------------------------------------------------ xpm/bitcoin16.xpm | 203 ++++++++++++++++++++++++++++++++++++ xpm/bitcoin20.xpm | 226 ++++++++++++++++++++++++++++++++++++++++ xpm/bitcoin32.xpm | 223 +++++++++++++++++++++++++++++++++++++++ xpm/bitcoin48.xpm | 278 +++++++++++++++++++++++++++++++++++++++++++++++++ 8 files changed, 948 insertions(+), 313 deletions(-) delete mode 100644 xpm/bitcoin.xpm create mode 100644 xpm/bitcoin16.xpm create mode 100644 xpm/bitcoin20.xpm create mode 100644 xpm/bitcoin32.xpm create mode 100644 xpm/bitcoin48.xpm diff --git a/headers.h b/headers.h index 6cd2da07db..34eafb2602 100644 --- a/headers.h +++ b/headers.h @@ -101,7 +101,10 @@ using namespace boost; #include "xpm/addressbook16.xpm" #include "xpm/addressbook20.xpm" -#include "xpm/bitcoin.xpm" +#include "xpm/bitcoin16.xpm" +#include "xpm/bitcoin20.xpm" +#include "xpm/bitcoin32.xpm" +#include "xpm/bitcoin48.xpm" #include "xpm/check.xpm" #include "xpm/send16.xpm" #include "xpm/send16noshadow.xpm" diff --git a/net.cpp b/net.cpp index b4df35cb58..d70a62a297 100644 --- a/net.cpp +++ b/net.cpp @@ -1044,13 +1044,13 @@ bool BindListenPort(string& strError) { int nErr = WSAGetLastError(); if (nErr == WSAEADDRINUSE) - strError = strprintf("Unable to bind to port %d on this computer. Bitcoin may be running already.", ntohs(sockaddr.sin_port)); + strError = strprintf("Unable to bind to port %d on this computer. Bitcoin is probably already running.", ntohs(sockaddr.sin_port)); else strError = strprintf("Error: Unable to bind to port %d on this computer (bind returned error %d)", ntohs(sockaddr.sin_port), nErr); printf("%s\n", strError.c_str()); return false; } - printf("bound to port %d\n", ntohs(sockaddr.sin_port)); + printf("Bound to port %d\n", ntohs(sockaddr.sin_port)); // Listen for incoming connections if (listen(hListenSocket, SOMAXCONN) == SOCKET_ERROR) diff --git a/ui.cpp b/ui.cpp index bfb0ad2939..a1873d5c2d 100644 --- a/ui.cpp +++ b/ui.cpp @@ -316,13 +316,15 @@ CMainFrame::CMainFrame(wxWindow* parent) : CMainFrameBase(parent) fOnSetFocusAddress = false; fRefresh = false; m_choiceFilter->SetSelection(0); -#ifndef __WXMSW__ - wxFont fontTmp = m_staticTextBalance->GetFont(); - fontTmp.SetPointSize(10); +#ifdef __WXMSW__ + SetIcon(wxICON(bitcoin)); +#else + SetIcon(bitcoin16_xpm); + wxFont fontTmp = m_staticText41->GetFont(); fontTmp.SetFamily(wxFONTFAMILY_TELETYPE); m_staticTextBalance->SetFont(fontTmp); m_staticTextBalance->SetSize(140, 17); - // ampersand underlines aren't working on gtk + // & underlines don't work on the toolbar buttons on gtk m_toolBar->ClearTools(); 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); @@ -330,7 +332,6 @@ CMainFrame::CMainFrame(wxWindow* parent) : CMainFrameBase(parent) #endif m_staticTextBalance->SetLabel(FormatMoney(GetBalance()) + " "); m_listCtrl->SetFocus(); - SetIcon(wxICON(bitcoin)); ptaskbaricon = new CMyTaskBarIcon(); // Init column headers @@ -1659,7 +1660,8 @@ CSendDialog::CSendDialog(wxWindow* parent, const wxString& strAddress) : CSendDi //// todo: should add a display of your balance for convenience #ifndef __WXMSW__ wxFont fontTmp = m_staticTextInstructions->GetFont(); - fontTmp.SetPointSize(fontTmp.GetPointSize()-1); + if (fontTmp.GetPointSize() > 9); + fontTmp.SetPointSize(9); m_staticTextInstructions->SetFont(fontTmp); SetSize(725, wxDefaultCoord); #endif @@ -3270,7 +3272,11 @@ void CMyTaskBarIcon::Show(bool fShow) if (strncmp(pszPrevTip, strTooltip.c_str(), sizeof(pszPrevTip)-1) != 0) { strlcpy(pszPrevTip, strTooltip.c_str(), sizeof(pszPrevTip)); +#ifdef __WXMSW__ SetIcon(wxICON(bitcoin), strTooltip); +#else + SetIcon(bitcoin20_xpm, strTooltip); +#endif } } else diff --git a/xpm/bitcoin.xpm b/xpm/bitcoin.xpm deleted file mode 100644 index 166d5aa6e4..0000000000 --- a/xpm/bitcoin.xpm +++ /dev/null @@ -1,304 +0,0 @@ -/* XPM */ -static char * bitcoin_xpm[] = { -/* columns rows colors chars-per-pixel */ -"48 48 250 2", -" c #725203", -". c #795603", -"X c #7D5903", -"o c #76560B", -"O c #77590E", -"+ c #795A0D", -"@ c #7B5D14", -"# c #7C5F18", -"$ c #7D6019", -"% c #825D05", -"& c #856007", -"* c #86620B", -"= c #8B660B", -"- c #8E690E", -"; c #906A0F", -": c #8F6B17", -"> c #83641C", -", c #8D6C1E", -"< c #926C11", -"1 c #967014", -"2 c #997215", -"3 c #9C761B", -"4 c #9E791D", -"5 c #A37C1E", -"6 c #816520", -"7 c #876A25", -"8 c #8E6E22", -"9 c #866A29", -"0 c #896E2C", -"q c #8E7020", -"w c #937324", -"e c #997722", -"r c #9E7B25", -"t c #94762B", -"y c #967828", -"u c #9A7B2D", -"i c #8B7131", -"p c #9E7E31", -"a c #947839", -"s c #A37D22", -"d c #A68125", -"f c #AA8325", -"g c #AE8827", -"h c #A6832D", -"j c #AA852B", -"k c #AD892B", -"l c #B08727", -"z c #B28827", -"x c #B08729", -"c c #B38B2C", -"v c #B88E2F", -"b c #B8902D", -"n c #A38334", -"m c #A98632", -"M c #AB8A34", -"N c #A4873C", -"B c #A78A3D", -"V c #AC8B3C", -"C c #B38D32", -"Z c #BA8F30", -"A c #B28E3C", -"S c #B69332", -"D c #BC9433", -"F c #BF9832", -"G c #B4923C", -"H c #BA963D", -"J c #B7993E", -"K c #BE9A3B", -"L c #C1932F", -"P c #C39732", -"I c #C49935", -"U c #C59C3A", -"Y c #C99E3D", -"T c #C2A13F", -"R c #CDA23F", -"E c #9D8342", -"W c #AB8C43", -"Q c #B28E40", -"! c #AE9144", -"~ c #AE914A", -"^ c #B49445", -"/ c #BC9B44", -"( c #B3964D", -") c #B5994C", -"_ c #BD9B4A", -"` c #A98F50", -"' c #B19553", -"] c #B59A54", -"[ c #BD9F51", -"{ c #B59B5C", -"} c #B89D5C", -"| c #BEA155", -" . c #BDA35D", -".. c #B59C61", -"X. c #B99F66", -"o. c #BCA363", -"O. c #BDA56C", -"+. c #BCA571", -"@. c #BDA873", -"#. c #BFAA78", -"$. c #C49D43", -"%. c #C99F45", -"&. c #C29E4B", -"*. c #C5A144", -"=. c #CCA244", -"-. c #C5A44B", -";. c #CAA54B", -":. c #C8A84C", -">. c #D0A644", -",. c #D3AA44", -"<. c #D3AC4C", -"1. c #D8AD4D", -"2. c #DAB046", -"3. c #DCB24E", -"4. c #C3A454", -"5. c #CBA751", -"6. c #CCAA53", -"7. c #C1A65B", -"8. c #C8A75A", -"9. c #CBAC5B", -"0. c #D0A650", -"q. c #D2AC53", -"w. c #DAAD54", -"e. c #D3AD5C", -"r. c #CFB259", -"t. c #D4B156", -"y. c #DDB454", -"u. c #D4B25C", -"i. c #DAB65A", -"p. c #D7B95F", -"a. c #DEBA5E", -"s. c #E2B555", -"d. c #E5BA53", -"f. c #E1B55A", -"g. c #E5BC5C", -"h. c #EABF5D", -"j. c #C1A761", -"k. c #C4AA63", -"l. c #CBAE63", -"z. c #CBB166", -"x. c #CBB26C", -"c. c #D4B263", -"v. c #DAB462", -"b. c #D6B864", -"n. c #DCB965", -"m. c #D3B669", -"M. c #DCB768", -"N. c #D4BA6E", -"B. c #DCBB6C", -"V. c #CDB672", -"C. c #D2B972", -"Z. c #DBBE72", -"A. c #E4BC62", -"S. c #E9BE62", -"D. c #E2BD6C", -"F. c #E0BF72", -"G. c #E6C05E", -"H. c #EFC05D", -"J. c #F0C15B", -"K. c #DFC167", -"L. c #D7C069", -"P. c #DDC36D", -"I. c #DBC376", -"U. c #D4C17B", -"Y. c #DAC17B", -"T. c #D8C878", -"R. c #E4C362", -"E. c #EBC364", -"W. c #E3C865", -"Q. c #EDC866", -"!. c #E4C36A", -"~. c #E9C66B", -"^. c #ECCA6B", -"/. c #F1C564", -"(. c #F8C765", -"). c #F5CB66", -"_. c #F8CC67", -"`. c #F6CC6A", -"'. c #F9CD6B", -"]. c #EED26A", -"[. c #F2D06F", -"{. c #FBD26D", -"}. c #E4C374", -"|. c #EBC474", -" X c #E1C972", -".X c #EDCD72", -"XX c #E4C57A", -"oX c #E9C67C", -"OX c #E5C87C", -"+X c #EACA7D", -"@X c #F2CC74", -"#X c #FBCF71", -"$X c #EED174", -"%X c #ECD37B", -"&X c #F4D274", -"*X c #FDD473", -"=X c #FFD975", -"-X c #F4D57C", -";X c #FCD57A", -":X c #F3DA7C", -">X c #FEDB7C", -",X c #FFE37D", -"X=XQ.s.=.v 5 1 < E HXHXHXHXHXHXHXHXHXHXHXHXHXHX", -"HXHXHXHXHXHXHXHXHXHXHX' g f F d.).).{.{.=X=X=X{.{.{.`.`.`.).g.U f 2 * a HXHXHXHXHXHXHXHXHXHXHXHX", -"HXHXHXHXHXHXHXHXHXHXV f b G.J.{.{.{.*X=X,X=X*X{.`.).`.).).{.`.{./.U 5 ; + HXHXHXHXHXHXHXHXHXHXHX", -"HXHXHXHXHXHXHXHX} h g 1.)._._.{.,X*X=X,X{.{.)._.).).`.`.`.{.*X*X*X`.y.g 2 & $ HXHXHXHXHXHXHXHXHX", -"HXHXHXHXHXHXHX{ j c G.).{.{.{.=X,X{.{.J.d.2.R 2.,.3.g.`.&X;X;X;X&X[.{.`.I 3 & + HXHXHXHXHXHXHXHX", -"HXHXHXHXHXHX{ d D /.{.{.*X=X=X*X).3.R I I I P F F U $.;.n.-XrXrX;X&X;X>XdX:.4 X o HXHXHXHXHXHXHX", -"HXHXHXHXHX..j v /.*X=X=X=X=X`.1.R R R R I I I P K U *.e.D.|.}.+XrXqXhXhXdXfX:.4 X o HXHXHXHXHXHX", -"HXHXHXHXHXh v `.{.>X,X*X{.g.>.Y R I I I I I I U U ;.t.D.|.oXB.z.F.kXvXcXjXjXjX/ 1 . + HXHXHXHXHX", -"HXHXHXHXV g Q.=X=X>X>X'.>.Y Y U R I I I P P I U U <.n.~.}.F.XXXX}.%XbXbXcXcXcXsXc = # HXHXHXHX", -"HXHXHX} j t.>X>X>X*X'.>.U U I U P U U I P P I U T 6.M.D.oX5XwXeXeXqX0XvXbXbXcXjXW.5 % HXHXHXHX", -"HXHXHXM G hXhXqX>X*X<.U U U I I I I I I D D U T T -.9.B.3XpXpXzXgXqX:X:XbXbXcXjXfXT < o HXHXHX", -"HXHX} k XlXkXkXrXA.$.D Z Z Z v v v b b v D U U *.-.9.B.OX2XOXI.P.L.K.W.$XbXcXjX,X].d % 9 HXHX", -"HXHXV J xXxXxXxXrX5.&.A M m m m h h n s 5 g S K *.:.8.4.| k.x.C.N.z.7.) :.$XjXfX,X,XT ; o HXHX", -"HXHXM L.vXxXxXxXF._ MXCXCXCXCXCXCXCXCXmXY.h g K *./ ^ Y.mXCXCXCXCXCXCXVXZ.4.hXfX,X,XW.4 X HXHX", -"HX] k gXxXxXxXgXe.V MXCXCXCXCXVXCXCXCXCXCXyXh D G [ mXCXCXCXCXCXCXCXCXCX4XG ~.fX,X,X,Xg & $ HX", -"HXV J vXxXxXxX6Xe.V MXCXCXCXCXk.N VXCXCXCXVX| h ^ MXCXCXCXCXuX( n V l.mX4XA y.fX,X,X=XT ; HX", -"HXk r.xXxXxXxX|.v.V MXCXCXCXCXo.> 4XCXCXCXCXx.w tXCXCXCXCXnXn V / / M V m.&.t.=X,X,X=Xy.2 o HX", -"HXk P.xXvXxXxX|.M.Q nXCXCXCXCXj.w X>X=XH.5 X $ ", -"o.k %XvXbXBXkX|.D.Q nXCXCXCXCXj., 7XCXCXCXCX~ k.CXCXCXCXCXV &.n.R.g.G.g.S.S.S.(.qX*X=X`.5 X $ ", -" .k 0XvXvXvXrX@XD.^ VXCXCXCXCXx.~ VXCXCXCXX=X*X*Xd X $ ", -"{ k sXcXvXBXeX@XD.( nXCXCXCXCXCXCXCXCXVXo., u T.CXCXCXVXmXn t.E.g.g.h.S.g.S.f.A.>X;X*X*Xf & o ", -"{ k sXjXlXcX0X~.n.^ MXCXCXCXCXCXCXCXCXCXCXU.t U.CXCXCXCXmXM p.~.W.g.s.s.s.s.f.A.>X*X*X*Xj % ", -"o.k :XjXlXlX-XD.v.A MXCXCXCXCXj.t mXCXCXCXCX .x.CXCXCXCXVXV p.$X^.E.g.s.w.w.w.A.9X;X*X*Xf X ", -"o.g ].dXjXhX-Xn.e.V MXCXCXCXCXj.8 X*X#X5 X O ", -"HXj K.dXdXhX9Xv.9.M MXCXCXCXCXk.a Z.CXCXCXCX7Xu CXCXCXCXCXV./ !.$X~.f.5.%.0.q.S.>X*X*XE.5 X # ", -"HXj t.dX,XdXdXi.6.N MXCXCXCXCXo.q XqXqXqX!.6.m MXCXCXCXCXV.' VXCXCXZXCXk.! ] VXCXCXCXCXVXC.[ 7.Z.VX2Xx %.#X#X'.'.%.- o 6 ", -"HX( g &X>X>XdX-X5.M MXCXCXCXCXCXCXCXCXCXCX7X) m.9. .MXCXCXCXCXCXCXCXCXCX2Xs 1.'.`.'.'.x % HX", -"HXO.j y.>X>X>X>X6.! zXMXMXMXMXMXMXMXMXuXx.( N.8X6Xz.) C.uXCXCXCXCXCXVX7X4.c h.'.(.(.s.5 X HX", -"HXHXj H &X=X:X>X~./ V h y u n n n N W ( 7.Z.8XpXpX+Xm.| V V ^ ) ( m e 3 s R (.(.'.'.Y ; . > HX", -"HXHX} f G.&X&X&X:Xt._ / ) _ 4.8.l.m.B.Z.2XwXpXeXwX6X+XP.c.8.-./ C x x z P J.(.'.(./.5 % HXHX", -"HXHXHXh D &X&X&X&X@X:.4.5.9.c.m.F.OX+XwXwXwXwX6X3XOX}.D.D.v.w.%.Y I P P d.(.(.'.'.=.< . + HXHX", -"HXHXHX] d y.[.&X&X&X~.:.4.9.e.M.B.}.oX3X5X3X3X+X}.F.M.e.0.0.0.%.%.Y Y s.#X#X#X#XS.s % HXHXHX", -"HXHXHXHXm g `.@X&X&X&X~.5.6.e.b.B.}.XX+X3XOX}.I.F.F.D.e.e.e.e.e.q.0.A.;X;X#X-X@XZ = o + HXHXHX", -"HXHXHXHX..j D @X&X&X&X&X@Xp.u.M.D.}.XXOXOXZ.Z.XX1XOXoXoXF.F.F.M.D.6XrXqX9X9X9X%.1 . HXHXHXHX", -"HXHXHXHXHX' f $.&X&X&X>XqXqX XB.D.!.XXXXZ.XXOX5XwXwXwXwXiXwXwXnXVXZXBXxXzXxXb.r X $ HXHXHXHX", -"HXHXHXHXHXHX~ j ;.qXqXqXqXrXkXrX+XD.Z.Z.XX1X2X5X5X5XwXwXiXnXCXGXGXFXFXSXAXT.s % @ HXHXHXHXHX", -"HXHXHXHXHXHXHX~ j -.0XrXzXxXzXzXzXzXwX3XXXXXOX1X2X5XpXmXAXFXGXGXGXFXFXSXL.r % O HXHXHXHXHXHX", -"HXHXHXHXHXHXHXHX! j / gXSXSXZXxXzXzXkXxXzXBXBXBXZXCXAXAXAXAXSXSXSXSXNX| 3 & O HXHXHXHXHXHXHX", -"HXHXHXHXHXHXHXHXHX} n V U.DXSXBXzXkXkXkXxXxXxXBXxXBXBXCXZXZXZXAXAXU.M < . @ HXHXHXHXHXHXHXHX", -"HXHXHXHXHXHXHXHXHXHXHXV d G Z.pXzXkXzXjXkXkXxXzXxXxXxXBXBXZXNXT.G 3 * . 9 HXHXHXHXHXHXHXHXHX", -"HXHXHXHXHXHXHXHXHXHXHXHX@.u s k -.K.6XhXjXhXkXlXzXzXzXeXOX9.k 3 = X O HXHXHXHXHXHXHXHXHXHXHX", -"HXHXHXHXHXHXHXHXHXHXHXHXHXHX..w < s j k K -.;.:.-./ C j 4 < & . O HXHXHXHXHXHXHXHXHXHXHXHXHX", -"HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXE * = - - < < - = & X . 0 HXHXHXHXHXHXHXHXHXHXHXHXHXHXHX", -"HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXi 7 7 @ o o O > 0 i HXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHXHX" -}; diff --git a/xpm/bitcoin16.xpm b/xpm/bitcoin16.xpm new file mode 100644 index 0000000000..8bec142c8b --- /dev/null +++ b/xpm/bitcoin16.xpm @@ -0,0 +1,203 @@ +/* XPM */ +static char * bitcoin16_xpm[] = { +/* columns rows colors chars-per-pixel */ +"16 16 181 2", +" c #775605", +". c #745507", +"X c #785806", +"o c #7D5A06", +"O c #745508", +"+ c #755508", +"@ c #755608", +"# c #775708", +"$ c #77580B", +"% c #7A5A0B", +"& c #7D5E14", +"* c #86630D", +"= c #8D6B16", +"- c #886818", +"; c #927019", +": c #91701E", +"> c #9A751E", +", c #957627", +"< c #9A7925", +"1 c #987827", +"2 c #98782B", +"3 c #9D7C2F", +"4 c #9E7E31", +"5 c #A57D22", +"6 c #A88227", +"7 c #B78D2E", +"8 c #B78F2E", +"9 c #A78430", +"0 c #A48733", +"q c #A68536", +"w c #A98937", +"e c #B98F31", +"r c #B49233", +"t c #B39337", +"y c #C09837", +"u c #C39936", +"i c #C49936", +"p c #C69C39", +"a c #C89C3A", +"s c #CCA23A", +"d c #AF9240", +"f c #B99644", +"g c #BE9C46", +"h c #BF9D4A", +"j c #BA9F58", +"k c #BEA04B", +"l c #BBA253", +"z c #BAA057", +"x c #C29E44", +"c c #C2A144", +"v c #CAA246", +"b c #CCA344", +"n c #CEA645", +"m c #C2A04A", +"M c #C7A349", +"N c #C5A34A", +"B c #C7A64D", +"V c #CFA649", +"C c #CEAA4C", +"Z c #D1A84B", +"A c #D4AC49", +"S c #D5AC49", +"D c #D7AD48", +"F c #D5AF4D", +"G c #C0A451", +"H c #CAA550", +"J c #CBAA58", +"K c #CAAD5D", +"L c #D9AD53", +"P c #DFB757", +"I c #D5B058", +"U c #D7B75D", +"Y c #DCB75A", +"T c #DFBB5E", +"R c #E1B957", +"E c #E3B759", +"W c #E6BC5B", +"Q c #E7BE5D", +"! c #E5BC5E", +"~ c #CAAE62", +"^ c #C8AF6A", +"/ c #CDB565", +"( c #CDB46D", +") c #D7B360", +"_ c #D5B862", +"` c #D1B66C", +"' c #D8BB68", +"] c #DBBA6E", +"[ c #DFBE6D", +"{ c #D0B872", +"} c #D2B974", +"| c #DABF74", +" . c #D8BF77", +".. c #D6BD79", +"X. c #D5BE7B", +"o. c #D7BF7A", +"O. c #E8BC61", +"+. c #DDC075", +"@. c #DCC279", +"#. c #DCC47E", +"$. c #EDC661", +"%. c #EEC562", +"&. c #E0C16B", +"*. c #E0C36B", +"=. c #E3C26A", +"-. c #E7C26A", +";. c #E3C569", +":. c #E3C26C", +">. c #E4C16C", +",. c #EEC969", +"<. c #F4C664", +"1. c #F0CA68", +"2. c #F7CA68", +"3. c #F6CD69", +"4. c #F7CD69", +"5. c #F7CF68", +"6. c #E6C374", +"7. c #E1C47A", +"8. c #E1C77B", +"9. c #E5C578", +"0. c #E4C579", +"q. c #E4C67A", +"w. c #E5C67C", +"e. c #E8C57B", +"r. c #E8CB7B", +"t. c #EDCC78", +"y. c #EBCB7C", +"u. c #F0CF73", +"i. c #F6CF74", +"p. c #F4D173", +"a. c #F7D072", +"s. c #F5D376", +"d. c #FAD071", +"f. c #FBD470", +"g. c #FAD572", +"h. c #FDD671", +"j. c #FDD773", +"k. c #F3DB76", +"l. c #F8D578", +"z. c #FBDB79", +"x. c #FFE57E", +"c. c #DEC681", +"v. c #DFC782", +"b. c #E0C682", +"n. c #E1C984", +"m. c #E2C985", +"M. c #E3CB87", +"N. c #E9C980", +"B. c #EBCC82", +"V. c #E3CC88", +"C. c #E4CF8D", +"Z. c #EFD187", +"A. c #EFD488", +"S. c #EFD58D", +"D. c #F6D581", +"F. c #F1D687", +"G. c #F9D680", +"H. c #F7DA8B", +"J. c #F2DE93", +"K. c #FADF93", +"L. c #F3DB98", +"P. c #F0DB9B", +"I. c #FEE081", +"U. c #FEE18C", +"Y. c #FCE38F", +"T. c #F7E98E", +"R. c #FFE88C", +"E. c #F6E491", +"W. c #FBEA91", +"Q. c #FFE897", +"!. c #FFEE9A", +"~. c #FEE99D", +"^. c #FEEC9F", +"/. c #FEF092", +"(. c #FFF29A", +"). c #FBE7A9", +"_. c #F4EDA8", +"`. c #FAEBAA", +"'. c #FEEBAD", +"]. c #FEFABD", +"[. c None", +/* pixels */ +"[.[.[.[.[.3 f M m q [.[.[.[.[.[.", +"[.[.[.4 A 5.j.f.3.3.! 6 [.[.[.[.", +"[.[.9 %.h.%.D s n -.z.l.c % [.[.", +"[.1 1.g.S p i i C 6.7.W./.t [.[.", +"[._ U.Z e 7 7 y B | #.*.T.k.* [.", +", E.F.c.).).C.g K `.`.C.' x.r + ", +"d !.y.M.).j '.( ).L.h M I z.F + ", +"G (.t.M.'.'.C.j ).b.T Q O.d.R X ", +"k T.O.M.`.^ `.X.).V.;.! L i.E ", +"w I.6.c.'.).C.{ c.).).C.H d.v + ", +"[.,.u.~ } X.@.@.| .#.` V 2.5 ", +"[.x p.U J ] B.Z.9.) v a <.E o [.", +"[.[.Y s.-.[ 0.0.N.e.w.H.D.> + [.", +"[.[.2 &.).Y.A.S.L.`.]._.0 . [.[.", +"[.[.[.[.l r.Y.Q.~.J./ = $ [.[.[.", +"[.[.[.[.[.[.: 1 ; - & [.[.[.[.[." +}; diff --git a/xpm/bitcoin20.xpm b/xpm/bitcoin20.xpm new file mode 100644 index 0000000000..2dd61a59dc --- /dev/null +++ b/xpm/bitcoin20.xpm @@ -0,0 +1,226 @@ +/* XPM */ +static char * bitcoin20_xpm[] = { +/* columns rows colors chars-per-pixel */ +"20 20 200 2", +" c #7B5500", +". c #7B5900", +"X c #735508", +"o c #7B5908", +"O c #7B5D08", +"+ c #7B5910", +"@ c #7B6118", +"# c #845D08", +"$ c #846108", +"% c #8C6510", +"& c #8C6910", +"* c #8C6918", +"= c #946D10", +"- c #947118", +"; c #9C7518", +": c #A57918", +"> c #846929", +", c #846D29", +"< c #947121", +"1 c #8C7539", +"2 c #947939", +"3 c #8C7542", +"4 c #AD8221", +"5 c #B58E29", +"6 c #B58E31", +"7 c #B59231", +"8 c #BD9231", +"9 c #BD9631", +"0 c #C69A31", +"q c #C69A39", +"w c #C69E39", +"e c #CE9E39", +"r c #CEA239", +"t c #948652", +"y c #A58A4A", +"u c #BD9642", +"i c #BD9A42", +"p c #B5964A", +"a c #B59A4A", +"s c #BD9E4A", +"d c #A58E5A", +"f c #BD9A52", +"g c #BD9E52", +"h c #BDA252", +"j c #BDA25A", +"k c #BD9E63", +"l c #A59673", +"z c #AD9A73", +"x c #AD9E7B", +"c c #BDA263", +"v c #BDA26B", +"b c #BDA273", +"n c #BDA673", +"m c #B5A27B", +"M c #BDAA7B", +"N c #C69E42", +"B c #CE9E42", +"V c #C6A242", +"C c #CEA242", +"Z c #CEA642", +"A c #C6A24A", +"S c #C6A64A", +"D c #CEA64A", +"F c #CEAA4A", +"G c #D6A642", +"H c #DEAE4A", +"J c #DEB24A", +"K c #C6A252", +"L c #C6A652", +"P c #CEAA52", +"I c #CEAE52", +"U c #C6A65A", +"Y c #C6AA5A", +"T c #CEAA5A", +"R c #CEAE5A", +"E c #D6AE52", +"W c #DEAE52", +"Q c #D6AE5A", +"! c #D6B252", +"~ c #DEB252", +"^ c #DEB652", +"/ c #D6B65A", +"( c #DEB65A", +") c #DEBA5A", +"_ c #EFBE52", +"` c #E7BA5A", +"' c #E7BE5A", +"] c #EFBE5A", +"[ c #C6A663", +"{ c #C6AE63", +"} c #CEAE63", +"| c #D6AE63", +" . c #CEB26B", +".. c #CEB66B", +"X. c #DEB663", +"o. c #D6BE63", +"O. c #DEBA63", +"+. c #DEBE63", +"@. c #D6B66B", +"#. c #DEB66B", +"$. c #D6BA6B", +"%. c #D6BE6B", +"&. c #DEBA6B", +"*. c #DEBE6B", +"=. c #D6BA73", +"-. c #DEBE73", +";. c #EFBE63", +":. c #E7BE73", +">. c #DEC37B", +",. c #E7C363", +"<. c #EFC763", +"1. c #EFCF63", +"2. c #E7C36B", +"3. c #E7C76B", +"4. c #EFC36B", +"5. c #EFC76B", +"6. c #E7CB6B", +"7. c #EFCB6B", +"8. c #F7CB63", +"9. c #F7CB6B", +"0. c #F7CF6B", +"q. c #FFCB6B", +"w. c #F7D36B", +"e. c #FFD36B", +"r. c #E7C373", +"t. c #E7CB73", +"y. c #EFCF73", +"u. c #E7C37B", +"i. c #E7C77B", +"p. c #E7CB7B", +"a. c #EFCB7B", +"s. c #F7CF73", +"d. c #EFD373", +"f. c #EFD37B", +"g. c #F7D373", +"h. c #FFD373", +"j. c #FFD773", +"k. c #FFDB73", +"l. c #F7DB7B", +"z. c #FFDF7B", +"x. c #ADA284", +"c. c #BDAA84", +"v. c #BDAE84", +"b. c #B5A68C", +"n. c #B5AE9C", +"m. c #BDB6A5", +"M. c #C6BA9C", +"N. c #C6BAA5", +"B. c #C6BEA5", +"V. c #DEC784", +"C. c #E7CB84", +"Z. c #E7CF84", +"A. c #EFCF84", +"S. c #E7CF8C", +"D. c #EFCF8C", +"F. c #EFD384", +"G. c #E7D38C", +"H. c #EFD38C", +"J. c #EFD78C", +"K. c #F7D784", +"L. c #FFD784", +"P. c #F7DB84", +"I. c #F7DF84", +"U. c #FFDB84", +"Y. c #FFDF84", +"T. c #F7DB8C", +"R. c #EFD394", +"E. c #EFD794", +"W. c #EFDB94", +"Q. c #EFDB9C", +"!. c #F7DB9C", +"~. c #F7DF9C", +"^. c #FFE384", +"/. c #FFE784", +"(. c #FFE38C", +"). c #FFEB8C", +"_. c #EFE79C", +"`. c #FFE794", +"'. c #FFEB94", +"]. c #FFEF94", +"[. c #FFEB9C", +"{. c #FFEF9C", +"}. c #FFF394", +"|. c #FFF794", +" X c #C6C3B5", +".X c #CEC7BD", +"XX c #F7E3A5", +"oX c #FFE7A5", +"OX c #F7EBA5", +"+X c #FFEBA5", +"@X c #FFEFA5", +"#X c #FFE7AD", +"$X c #FFEBAD", +"%X c #FFEFAD", +"&X c #FFF3AD", +"*X c #FFF7B5", +"=X c #FFFBB5", +"-X c #FFFFBD", +";X c #CEC7C6", +":X c None", +/* pixels */ +":X:X:X:X:X:XM.v f i g k c..X:X:X:X:X:X:X", +":X:X:X:XM.u H 8.j.j.e.0.^ 7 d X:X:X:X:X", +":X:X:Xn Z 0.k.j.8._ ] 9.h.h.~ ; b.:X:X:X", +":X:Xn J j.j.' C 0 0 w E a.K.^.d.- x.:X:X", +":XN.F k.w.G w q 0 0 D 2.i.a.].|.6.$ m.:X", +":Xg (.U.C 9 8 8 8 q S *.H.f.y.].).9 , :X", +"B.o.{.p.-.>.>.>.R 7 N =.G.E.Z.&./.1.# n.", +"M I.[.| R.$X..~.#Xs V.$XG.h @.T l.z.; t ", +"c {.'.X.E.$Xj G.$XU #X$Xg ) ! ( 0.k.5 > ", +"j }.`.O.E.$XE.oXC.p $X$XA ,.' ;.5.j.9 o ", +"j ).I.Q E.$X .Q.#X .$X$XP 7.` W 4.j.8 X ", +"c z.Y.P R.$X[ S.$X{ XX$X$.) P D 5.h.4 @ ", +"v.<.Y.I R.$XW.oXXX} @.XX#XE.XXK 8.8.& 3 ", +".XC j.3.s a h Y .J.A.T Y h 6 e 8.H . x ", +":Xk <.g./ P #.i.F.A.r.X.E B r 9.q.: + :X", +":X.Xi s.g.+.O.r.i.u.i.u.:.r.L.L.N l :X", +":X:XN.V U.(.T.a.i.C.D.!.%X-X=X%.# 1 :X:X", +":X:X:XN.g _.+X`.[.+X@X&X*XOXh O 1 :X:X:X", +":X:X:X:X;Xb i +.f.P.K.t.L = o z :X:X:X:X", +":X:X:X:X:X:X.Xm y < % * 2 x :X:X:X:X:X:X" +}; diff --git a/xpm/bitcoin32.xpm b/xpm/bitcoin32.xpm new file mode 100644 index 0000000000..25da102f6a --- /dev/null +++ b/xpm/bitcoin32.xpm @@ -0,0 +1,223 @@ +/* XPM */ +static char * bitcoin32_xpm[] = { +/* columns rows colors chars-per-pixel */ +"32 32 185 2", +" c #715103", +". c #725203", +"X c #725204", +"o c #735304", +"O c #745404", +"+ c #765504", +"@ c #775504", +"# c #785604", +"$ c #795704", +"% c #795705", +"& c #77580A", +"* c #77580B", +"= c #77580C", +"- c #785808", +"; c #785809", +": c #78590D", +"> c #795A0D", +", c #7F5E0D", +"< c #7C5C0E", +"1 c #815F0E", +"2 c #89650F", +"3 c #8C670F", +"4 c #8D680F", +"5 c #836110", +"6 c #866410", +"7 c #8F6A11", +"8 c #926C12", +"9 c #946F14", +"0 c #967015", +"q c #987217", +"w c #997318", +"e c #9A751C", +"r c #9B761E", +"t c #9C7720", +"y c #9D7924", +"u c #9D7B28", +"i c #9E7C2C", +"p c #A07F31", +"a c #AA852D", +"s c #A9852E", +"d c #AC872D", +"f c #AE892E", +"g c #AF8A2E", +"h c #B08B2F", +"j c #A18133", +"k c #A78533", +"l c #A28235", +"z c #A48435", +"x c #A68535", +"c c #A58536", +"v c #A68536", +"b c #A88530", +"n c #B18C30", +"m c #B18D33", +"M c #B08D37", +"N c #B08F3B", +"B c #B08F3D", +"V c #BC9537", +"C c #BE9736", +"Z c #BF9737", +"A c #B6933B", +"S c #B0903F", +"D c #B2913E", +"F c #B4923D", +"G c #B99438", +"H c #C09736", +"J c #C19835", +"K c #C29836", +"L c #C39937", +"P c #C39A37", +"I c #C49B38", +"U c #C59C3A", +"Y c #C69D3B", +"T c #C79E3C", +"R c #C89F3D", +"E c #CAA03F", +"W c #C6A247", +"Q c #CAA140", +"! c #C9A242", +"~ c #C8A245", +"^ c #C2A14B", +"/ c #C3A24D", +"( c #C3A24F", +") c #C2A351", +"_ c #C1A352", +"` c #C0A355", +"' c #C1A457", +"] c #C1A458", +"[ c #C1A55A", +"{ c #C2A65C", +"} c #C3A75D", +"| c #C3A85E", +" . c #C6AA5D", +".. c #C7AA5D", +"X. c #C5A95E", +"o. c #CFAE5A", +"O. c #C8AB5E", +"+. c #D4AF56", +"@. c #D1AE58", +"#. c #D6B056", +"$. c #D8B155", +"%. c #D9B256", +"&. c #DAB357", +"*. c #DBB457", +"=. c #DDB558", +"-. c #DFB759", +";. c #E2BB5B", +":. c #E3BC5D", +">. c #E4BD5E", +",. c #C9AC61", +"<. c #C9AD62", +"1. c #CAAE62", +"2. c #CCAF62", +"3. c #DDBC69", +"4. c #DFBD68", +"5. c #DCBB6E", +"6. c #DCBC6C", +"7. c #DBBC70", +"8. c #DABD72", +"9. c #DBBE74", +"0. c #E4BD61", +"q. c #E4BE60", +"w. c #E3BE65", +"e. c #E2BF66", +"r. c #DDC177", +"t. c #DFC279", +"y. c #EFCB6F", +"u. c #F1CA6B", +"i. c #F4CB6A", +"p. c #F5CC6A", +"a. c #F7CD6B", +"s. c #F0CA6D", +"d. c #F7CF6E", +"f. c #EFCD72", +"g. c #EFCE77", +"h. c #E0C47B", +"j. c #E3C77E", +"k. c #E4C87F", +"l. c #F7D070", +"z. c #F8D171", +"x. c #F8D272", +"c. c #FAD473", +"v. c #FBD676", +"b. c #FCD574", +"n. c #FCD674", +"m. c #FCD777", +"M. c #F0D17E", +"N. c #FCD778", +"B. c #FCDA7A", +"V. c #FDDC7C", +"C. c #FDDE7E", +"Z. c #E6CA80", +"A. c #E8CC83", +"S. c #EACD84", +"D. c #ECD086", +"F. c #EFD286", +"G. c #EED287", +"H. c #F0D283", +"J. c #FDDF80", +"K. c #F6DF91", +"L. c #F5DE92", +"P. c #F4DE95", +"I. c #F4DF98", +"U. c #FDE081", +"Y. c #FCE184", +"T. c #FBE188", +"R. c #FAE18B", +"E. c #F8E08D", +"W. c #F5E19B", +"Q. c #F5E29C", +"!. c #F7E49D", +"~. c #F9E69B", +"^. c #FBE89B", +"/. c #FDEB9B", +"(. c #FDEC9B", +"). c #FEEE9B", +"_. c #FEEF9C", +"`. c #FEEEA3", +"'. c #FDEBA9", +"]. c #FDEBAC", +"[. c #FDEBAD", +"{. c #FDECAD", +"}. c #FDF0B0", +"|. c #FDF2B1", +" X c None", +/* pixels */ +" 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 X X X X X X X Xc F z z F z j X X X X X X X X X X X X X", +" X X X X X X X X Xz b V ~ %.;.u.e.-.! f e i X X X X X X X X X X", +" X X X X X X Xz d ! >.a.l.B.v.c.a.a.a.a.>.R w 6 X X X X X X X X", +" X X X X X Xb L q.a.n.c.n.n.c.a.i.i.a.a.z.z.>.m 3 5 X X X X X X", +" X X X X Xs +.a.c.n.B.c.>.#.E E ! +.>.n.J.v.z.z.~ 8 & X X X X X", +" X X X Xs %.c.n.B.l.*.E Y L L L L W +.r.Z.H.Y.Y.R.+.7 ; X X X X", +" X X Xk %.n.J.n.>.! Y Y I L L L T *.w.h.7.5.K.).).).W 6 = X X X", +" X Xj T V.B.n.;.L L L I L L L Y ~ *.s.Z.G.D.B._._._.Y.h % > X X", +" X Xm H.R.Y.0.L H H L L C V C Y ! ..8.G.E.H.M.g._._.Y.q.8 o X X", +" Xj o.)./.K.@.^ A F M N M s n C W ) { <.9.9.2.X.#./.Y.C.m % > X", +" XM D.)._.t.,.[.[.[.[.{.[.W.A G C O.I.[.[.[.[.{.5.y.Y.B.*.2 o X", +" XA /.).~.%.{ [.[.[.| D.[.[.I.b ,.[.[.[.j.) ' D.5.@.Y.V.a.w . X", +"i O.).).E.3.X.[.[.[.S X.[.[.'.i Q.[.{.D.z X.~ A ) %.B.V.n.s + = ", +"z 6._._.R.w.<.[.[.[.S <.[.[.I.F [.[.[.X.) 0.>.;.>.>.l.B.n.C % > ", +"z e._._.H.e.,.[.[.[.j.W.[.D.S { [.[.].' -.>.>.>.e.0.s.N.n.Y % & ", +"v s.)._.M.3.O.[.].].W.'.[.].{ { [.[.[.' 3.e.;.;.%.-.s.N.n.R # . ", +"z ;.T.E.g.-.{ [.].].S <.[.{.].` [.[.[.<.e.f.e.*.$.$.s.V.n.L $ O ", +"j o.Y.Y.g.+.] {.].]._ | [.[.[.F ].[.[.A.) y.e.@.W @.s.N.n.h $ = ", +" XZ J.Y.N.@.' [.[.].F 7.[.[.].z h.[.[.].7.^ ^ 5.2.U z.z.a.r X = ", +" Xs n.V.Y.+.` [.[.].].].{.{.9.2...A.{.[.[.[.].[.2.! a.u.;.3 = ", +" XF *.m.B.s.^ X.,.{ ,.<.1.] 2.G.D.O.` 2.9.7.2.^ d ;.u.a.K $ X X", +" X Xm z.c.v.o.^ ^ ^ { <.7.Z.K.K.H.Z.6.o.^ A f h E a.i.0.w X = X", +" X Xz #.l.z.f.X.O.<.5.t.Z.D.D.A.j.7.*.@.^ ! Y ! i.a.a.Y , X X X", +" X X Xd u.l.z.y.o.o.3.r.j.Z.h.r.9.5.%.%.#.+.#.c.B.z.-.8 . & X X", +" X X Xj m f.c.v.l.s.3.4.h.t.r.k.D.G.H.D.A.D./.!.E.M.y + X X X X", +" X X X Xj Z v.J.T.R.E.Z.7.t.Z.A.S.H.D.Q.|.|.|.|.!.b % . X X X X", +" X X X X Xj A D.|.`.~.~.!.E.I.I.Q.{.|.|.|.|.|.D.u % X < X X X X", +" X X X X X Xj z 9.{.`.~.~.^././.`.`.`.}.|.Q.] 9 $ X X X X X X X", +" X X X X X X X Xj s X.k.Y.R.~.~./.~.K.h.) e , . = X X X X X X X", +" X X X X X X X X X X9 w t n A C A s r 3 $ X > X X X X X X X X X", +" X X X X X X X X X X X X X5 2 1 $ ; 5 5 5 X X X X X X X X X X X" +}; diff --git a/xpm/bitcoin48.xpm b/xpm/bitcoin48.xpm new file mode 100644 index 0000000000..788e855ddd --- /dev/null +++ b/xpm/bitcoin48.xpm @@ -0,0 +1,278 @@ +/* XPM */ +static char * bitcoin48_xpm[] = { +/* columns rows colors chars-per-pixel */ +"48 48 224 2", +" c #715103", +". c #735203", +"X c #735204", +"o c #745405", +"O c #755506", +"+ c #775606", +"@ c #785707", +"# c #7A5806", +"$ c #7C5905", +"% c #7D5A05", +"& c #7E5B05", +"* c #7F5C07", +"= c #7E5C0A", +"- c #7B5C11", +"; c #7C5D13", +": c #7D5E15", +"> c #805C05", +", c #805C06", +"< c #8B6813", +"1 c #8D6912", +"2 c #8F6A12", +"3 c #896816", +"4 c #806219", +"5 c #82631A", +"6 c #876719", +"7 c #84651B", +"8 c #906C13", +"9 c #916D15", +"0 c #936F18", +"q c #94701B", +"w c #95721B", +"e c #98731A", +"r c #99741B", +"t c #99751E", +"y c #9A761F", +"u c #9B7822", +"i c #9F7A21", +"p c #9D7922", +"a c #A27C20", +"s c #A47E21", +"d c #A67F22", +"f c #9E8038", +"g c #9E803B", +"h c #9E813C", +"j c #9F833D", +"k c #A68023", +"l c #A78124", +"z c #A98326", +"x c #AA8427", +"c c #A7832B", +"v c #A7832C", +"b c #A6832D", +"n c #A98429", +"m c #A8842B", +"M c #AD892F", +"N c #AE8A2F", +"B c #AF8A2F", +"V c #B28B2E", +"C c #B48C2E", +"Z c #B68E2F", +"A c #B78E2F", +"S c #A38232", +"D c #A08136", +"F c #AC8931", +"G c #AB8934", +"H c #AA8836", +"J c #AA8937", +"K c #A1843F", +"L c #A2853F", +"P c #AB8A39", +"I c #AB8B3A", +"U c #AD8C3C", +"Y c #AE8E3E", +"T c #B89030", +"R c #BA9131", +"E c #BC9332", +"W c #BE9533", +"Q c #C09733", +"! c #C29834", +"~ c #C39934", +"^ c #C39935", +"/ c #C39A37", +"( c #C39A38", +") c #C49A38", +"_ c #C49B38", +"` c #C59C3A", +"' c #C69E3C", +"] c #C69E3E", +"[ c #C79F3F", +"{ c #A48640", +"} c #A58741", +"| c #A68842", +" . c #A78A43", +".. c #AA8D45", +"X. c #AD9046", +"o. c #B19040", +"O. c #B59443", +"+. c #B29447", +"@. c #B79745", +"#. c #B79847", +"$. c #B89846", +"%. c #B69748", +"&. c #C8A040", +"*. c #CAA241", +"=. c #CBA343", +"-. c #C9A346", +";. c #CBA445", +":. c #C7A44D", +">. c #C5A44F", +",. c #C9A448", +"<. c #C9A44A", +"1. c #C5A551", +"2. c #C4A554", +"3. c #CBAA57", +"4. c #CDAA57", +"5. c #C3A559", +"6. c #C4A65A", +"7. c #C7A85A", +"8. c #D0AB55", +"9. c #D2AD56", +"0. c #D4AE57", +"q. c #D4AF58", +"w. c #D5B05A", +"e. c #D5B15C", +"r. c #D5B25E", +"t. c #DFB65A", +"y. c #DEB75B", +"u. c #E1B759", +"i. c #E2B95B", +"p. c #E4BA5C", +"a. c #E4BC5F", +"s. c #D4B567", +"d. c #D8B764", +"f. c #D5B769", +"g. c #D4B76A", +"h. c #D4B86B", +"j. c #E5BD61", +"k. c #E6BE62", +"l. c #E6BF63", +"z. c #E0BF6F", +"x. c #E7C063", +"c. c #EAC263", +"v. c #EDC563", +"b. c #EBC364", +"n. c #EEC565", +"m. c #EEC767", +"M. c #E1C06F", +"N. c #EBC76D", +"B. c #EEC869", +"V. c #F7CD6A", +"C. c #F6CD6B", +"Z. c #F4CE6F", +"A. c #F8CD6A", +"S. c #F9CF6E", +"D. c #FAD16F", +"F. c #E1C071", +"G. c #E4C370", +"H. c #E1C174", +"J. c #E0C276", +"K. c #E1C377", +"L. c #E8C670", +"P. c #E2C479", +"I. c #E0C47A", +"U. c #E2C57C", +"Y. c #E3C77E", +"T. c #F3D073", +"R. c #FBD270", +"E. c #FCD572", +"W. c #FCD674", +"Q. c #FDD774", +"!. c #FED876", +"~. c #FED977", +"^. c #F2D278", +"/. c #F1D37B", +"(. c #FDDA78", +"). c #FDDB7A", +"_. c #FDDB7C", +"`. c #FDDD7D", +"'. c #FDDF7F", +"]. c #E4C880", +"[. c #E6CA83", +"{. c #E7CD86", +"}. c #E9CF89", +"|. c #EBD089", +" X c #EFD289", +".X c #F2D382", +"XX c #F0D387", +"oX c #FDDF80", +"OX c #FCDF84", +"+X c #FBDF89", +"@X c #F9DE8B", +"#X c #FBE08B", +"$X c #FBE28C", +"%X c #FCE48F", +"&X c #FDE592", +"*X c #FEE692", +"=X c #FEE693", +"-X c #FEE895", +";X c #FEEA96", +":X c #FEEC97", +">X c #FEEE98", +",X c #FEEE99", +"X>X:X:X%X' 0 O # sXsXsXsXsX", +"sXsXsXsXG n m.(.!.(.(.S.;.] [ _ ` _ ^ ^ ! Q ^ _ ` 9.k.M.U.K.U.H.U./.>X>X>X>X>X#XV < . - sXsXsXsX", +"sXsXsXh n w._._.(.W.S.;._ _ _ / _ _ _ _ Q Q / ` [ 9.d.G.H.|.XX@X#X#X).:X>X>X>X>Xm.a > sXsXsXsX", +"sXsXsXG @.#X+XOX_.R.8._ _ _ _ ! ^ _ ) ! W W _ ] [ <.r.h.{.@X6X&X#X#X).).>X>X>X;X#X' 8 + + sXsXsX", +"sXsXL M H.;X=X&X#Xk.] E R T Z T A A A A R E _ ` &.<.4.F.Y.[.U.H.z.h.z.L.^.>X>X;X'.m.k > : sXsX", +"sXsXP @.,X,X1X;X+X3.%.o.G H F m m b b a s z E _ [ 1.2.2.2.7.h.h.h.h.2.$.1.^.;X#X'.).` 2 . + sXsX", +"sXsXF f.X>X/.L.d.o.6X0X0XwXwX0X0XwXwX0X9XI.u I.0XwXqXqX3XG r.B.c.i.u.u.u.u.y.p.`.!.E.E.x * X ", +" .n ^.&X;X;X.Xx.d.Y 6X0XwX0X0X5.u 3X0XwXwX9X5.h.wX0XqXqX6XP d.T.N.c.i.u.y.0.0.k.(.!.W.E.k * X ", +"L x C.'.*X&X^.j.r.P 7XqX0XwX0X6.0 I.wX0XwX0XI.@.0XqXqXqX0X+.q.T.T.N.a.y.9.8.9.l._.!.!.D.s $ - ", +"sXx k.#X#X$X.Xy.8.G 3XqXwX0XwX7.u I.0XwX0XwX}.u qXqXqXqX0Xh.$.G.T.N.p.9.-.-.8.N._.!.E.b.i # X : ", +"sXc 9.'.'.#X'.y.4.H 7XqX0XwX0X6.q ].9XwX0XwXU.u {.0XwX0XwX8X%.#.w.4.$.#.f.W -.Z.W.R.R.y.r O = ", +"sXN _ '.'.'.#Xx.3.P 7XqXwX0XwXh.+.8XwX0X0X0X7.X.#.8X0XwX0XwX6Xh.2.5.U.6X{.F *.R.R.R.S.*.1 ; ", +"sXX.x E.`.).`.T.1.G 8XwX0XwXwX0XwX0X0XwX0X}.%.h.7.5.3X0X0XwX0XwXwX0X0X0X[.z 9.A.V.V.V.n * X sX", +"sXg x y.~.).).#X4.o.3X3X3X3X3X3X3X7X3X Xh.%.h. X|.3.#.h.3X0X0X0X0X0X8X}.2.V c.A.C.V.i.e # X X sX", +"sXsXn W E.E.).`.L.$.P g u p f D d . .+.6.U. X@X@X}.f.1.U Y %.%.+.H y e l &.A.A.V.V.' 8 X ; sX", +"sXsX..x k.T.T.T.W.9.#.#.#.#.1.7.4.s.h.z.}.}.@X@X X X].z.d.3.:.@.V V V C E c.A.A.A.c.s > sXsX", +"sXsXsXb W T.T.T./.T.:.1.3.4.r.h.z.].[. X X X X X[.Y.H.z.z.d.0.;.` / Q Q u.A.A.A.D.*.9 O X # sXsX", +"sXsXsX| l y.T.T.T./.N.<.1.4.r.f.z.z.].[.{.{.[.].H.z.s.r.8.8.-.-.*.] ] u.D.E.D.D.k.a > sXsXsX", +"sXsXsXsXn F B.T.T.T.^.N.1.4.w.s.z.z.U.[.{.].J.J.H.F.h.r.w.r.w.0.8.8.k.W.W.R.D.T.Z 1 O @ sXsXsX", +"sXsXsXsXf x W T.T.T.^./.T.r.r.d.z.L.U.].U.z.z.P.Y.[.[.U.P.F.G.h.h..X@XOXOX.X.X<.9 # sXsXsXsX", +"sXsXsXsXsXL x [ W.W.W.)._.OXN.d.z.z.I.U.I.z.U. X.X X XXXXX X XXXwXyX,X1X1X=Xs.p > X ; sXsXsXsX", +"sXsXsXsXsXsX| x :._.oX_.OX$X=X+X/.G.h.z.I.].}.}.|.|. X X X3XtXpXpXpXpXpXaXP.a > X - sXsXsXsXsX", +"sXsXsXsXsXsXsX{ c <.+X@X=X;X;X&X=X&XXX[.U.P.U.].[.}.XX3XyXpXpXpXpXpXpXpXh.a > O sXsXsXsXsXsX", +"sXsXsXsXsXsXsXsXL c @.+XpXpXuX1X=X=X;X1X1X1X1XrXwXwXyXyXyXuXpXaXpXuX3X2.u > . @ sXsXsXsXsXsXsX", +"sXsXsXsXsXsXsXsXsXj n Y I.aXaX0X=X=X&X;X=X1X1X1X Date: Sun, 8 Nov 2009 04:24:52 +0000 Subject: Get local host IP on Linux, Shutdown() a little cleaner -- linux-0.1.6-test1 waypoint --- headers.h | 2 ++ main.cpp | 4 ++-- makefile.unix | 23 +++++++++++++---------- net.cpp | 58 +++++++++++++++++++++++++++++++++++++++++++++++++--------- ui.cpp | 13 ++++++++++++- 5 files changed, 78 insertions(+), 22 deletions(-) diff --git a/headers.h b/headers.h index 34eafb2602..76881bb935 100644 --- a/headers.h +++ b/headers.h @@ -72,6 +72,8 @@ #include #include #include +#include +#include #include #include #include diff --git a/main.cpp b/main.cpp index fe213c099a..b957027f07 100644 --- a/main.cpp +++ b/main.cpp @@ -1215,7 +1215,7 @@ bool CBlock::AcceptBlock() return error("AcceptBlock() : block's timestamp is too early"); // Check that all transactions are finalized (starting around Dec 2009) - if (nBestHeight > 31000) // 25620 + 5320 + if (nBestHeight > 31000) foreach(const CTransaction& tx, vtx) if (!tx.IsFinal(nTime)) return error("AcceptBlock() : contains a non-final transaction"); @@ -1802,7 +1802,7 @@ bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) { if (fShutdown) return true; - addr.nTime = GetAdjustedTime(); + addr.nTime = GetAdjustedTime() - 2 * 60 * 60; if (pfrom->fGetAddr) addr.nTime -= 5 * 24 * 60 * 60; AddAddress(addrdb, addr, false); diff --git a/makefile.unix b/makefile.unix index c62efc008f..24aa8bfe4f 100644 --- a/makefile.unix +++ b/makefile.unix @@ -15,21 +15,24 @@ endif -INCLUDEPATHS=-I"/usr/include" \ - -I"/usr/local/boost_1_40_0" \ - -I"/usr/local/db-4.7.25.NC/build_unix" \ - -I"/usr/local/include/wx-2.8" \ - -I"/usr/local/lib/wx/include/gtk2-ansi-debug-static-2.8" - -LIBPATHS=-L"/usr/lib" \ - -L"/usr/local/lib" \ - -L"/usr/local/db-4.7.25.NC/build_unix" +INCLUDEPATHS= \ + -I"/usr/include" \ + -I"/usr/local/boost_1_40_0" \ + -I"/usr/local/db-4.7.25.NC/build_unix" \ + -I"/usr/local/include/wx-2.8" \ + -I"/usr/local/lib/wx/include/gtk2-ansi-debug-static-2.8" + +LIBPATHS= \ + -L"/usr/lib" \ + -L"/usr/local/lib" \ + -L"/usr/local/db-4.7.25.NC/build_unix" LIBS= \ -Wl,-Bstatic -l boost_thread -l boost_system -l boost_filesystem -Wl,-Bdynamic \ -Wl,-Bstatic -l db_cxx -l wx_gtk2$(D)-2.8 -Wl,-Bdynamic \ -l crypto \ -l gtk-x11-2.0 -l gthread-2.0 -l SM + WXDEFS=-D__WXGTK__ -DNOPCH CFLAGS=-O0 -w -Wno-invalid-offsetof -Wformat $(DEBUGFLAGS) $(WXDEFS) $(INCLUDEPATHS) HEADERS=headers.h util.h main.h serialize.h uint256.h key.h bignum.h script.h db.h base58.h @@ -76,7 +79,7 @@ obj/irc.o: irc.cpp $(HEADERS) OBJS=obj/util.o obj/script.o obj/db.o obj/net.o obj/main.o obj/market.o \ - obj/ui.o obj/uibase.o obj/sha.o obj/irc.o + obj/ui.o obj/uibase.o obj/sha.o obj/irc.o bitcoin: headers.h.gch $(OBJS) g++ $(CFLAGS) -o $@ $(LIBPATHS) $(OBJS) $(LIBS) diff --git a/net.cpp b/net.cpp index d70a62a297..0569604bab 100644 --- a/net.cpp +++ b/net.cpp @@ -842,20 +842,20 @@ void ThreadOpenConnections2(void* parg) if (!addr.IsIPv4() || !addr.IsValid() || setConnected.count(addr.ip)) continue; + // Randomize the order in a deterministic way, putting the standard port first + int64 nRandomizer = (uint64)(addr.nLastFailed * 9567851 + addr.ip * 7789) % (1 * 60 * 60); + if (addr.port != DEFAULT_PORT) + nRandomizer += 1 * 60 * 60; + // Limit retry frequency - if (GetAdjustedTime() < addr.nLastFailed + nDelay) + if (GetAdjustedTime() < addr.nLastFailed + nDelay + nRandomizer) continue; // Try again only after all addresses had a first attempt - int64 nTime = addr.nTime; + int64 nTime = addr.nTime - nRandomizer; if (addr.nLastFailed > addr.nTime) nTime -= 365 * 24 * 60 * 60; - // Randomize the order a little, putting the standard port first - nTime += GetRand(1 * 60 * 60); - if (addr.port != DEFAULT_PORT) - nTime -= 1 * 60 * 60; - if (nTime > nBestTime) { nBestTime = nTime; @@ -1069,6 +1069,7 @@ bool StartNode(string& strError) if (pnodeLocalHost == NULL) pnodeLocalHost = new CNode(INVALID_SOCKET, CAddress("127.0.0.1", nLocalServices)); +#ifdef __WXMSW__ // Get local host ip char pszHostName[255]; if (gethostname(pszHostName, sizeof(pszHostName)) == SOCKET_ERROR) @@ -1090,10 +1091,49 @@ bool StartNode(string& strError) printf("host ip %d: %s\n", i, CAddress(*(unsigned int*)phostent->h_addr_list[i]).ToStringIP().c_str()); for (int i = 0; phostent->h_addr_list[i] != NULL; i++) { - addrLocalHost = CAddress(*(unsigned int*)phostent->h_addr_list[i], DEFAULT_PORT, nLocalServices); - if (addrLocalHost.IsValid() && addrLocalHost.GetByte(3) != 127) + CAddress addr(*(unsigned int*)phostent->h_addr_list[i], DEFAULT_PORT, nLocalServices); + if (addr.IsValid() && addr.GetByte(3) != 127) + { + addrLocalHost = addr; break; + } + } +#else + // Get local host ip + struct ifaddrs* myaddrs; + if (getifaddrs(&myaddrs) == 0) + { + for (struct ifaddrs* ifa = myaddrs; ifa != NULL; ifa = ifa->ifa_next) + { + if (ifa->ifa_addr == NULL) continue; + if ((ifa->ifa_flags & IFF_UP) == 0) continue; + if (strcmp(ifa->ifa_name, "lo") == 0) continue; + if (strcmp(ifa->ifa_name, "lo0") == 0) continue; + char pszIP[100]; + if (ifa->ifa_addr->sa_family == AF_INET) + { + struct sockaddr_in* s4 = (struct sockaddr_in*)(ifa->ifa_addr); + if (inet_ntop(ifa->ifa_addr->sa_family, (void*)&(s4->sin_addr), pszIP, sizeof(pszIP)) != NULL) + printf("ipv4 %s: %s\n", ifa->ifa_name, pszIP); + + // Take the first IP that isn't loopback 127.x.x.x + CAddress addr(*(unsigned int*)&s4->sin_addr, DEFAULT_PORT, nLocalServices); + if (addr.IsValid() && addr.GetByte(3) != 127) + { + addrLocalHost = addr; + break; + } + } + else if (ifa->ifa_addr->sa_family == AF_INET6) + { + struct sockaddr_in6* s6 = (struct sockaddr_in6*)(ifa->ifa_addr); + if (inet_ntop(ifa->ifa_addr->sa_family, (void*)&(s6->sin6_addr), pszIP, sizeof(pszIP)) != NULL) + printf("ipv6 %s: %s\n", ifa->ifa_name, pszIP); + } + } + freeifaddrs(myaddrs); } +#endif printf("addrLocalHost = %s\n", addrLocalHost.ToString().c_str()); // Get our external IP address for incoming connections diff --git a/ui.cpp b/ui.cpp index a1873d5c2d..e12970b81b 100644 --- a/ui.cpp +++ b/ui.cpp @@ -387,17 +387,28 @@ CMainFrame::~CMainFrame() void Shutdown(void* parg) { static CCriticalSection cs_Shutdown; + static bool fTaken; + bool fFirstThread; CRITICAL_BLOCK(cs_Shutdown) + { + fFirstThread = !fTaken; + fTaken = true; + } + if (fFirstThread) { fShutdown = true; nTransactionsUpdated++; DBFlush(false); StopNode(); DBFlush(true); - printf("Bitcoin exiting\n\n"); exit(0); } + else + { + loop + Sleep(100000); + } } void CMainFrame::OnClose(wxCloseEvent& event) -- cgit v1.2.3 From 956468c29adcbff83ab7c2e52d91f8e87b704853 Mon Sep 17 00:00:00 2001 From: s_nakamoto Date: Sun, 8 Nov 2009 04:24:52 +0000 Subject: Get local host IP on Linux, Shutdown() a little cleaner -- linux-0.1.6-test1 waypoint git-svn-id: https://bitcoin.svn.sourceforge.net/svnroot/bitcoin/trunk@37 1a98c847-1fd6-4fd8-948a-caf3550aa51b --- headers.h | 2 ++ main.cpp | 4 ++-- makefile.unix | 23 +++++++++++++---------- net.cpp | 58 +++++++++++++++++++++++++++++++++++++++++++++++++--------- ui.cpp | 13 ++++++++++++- 5 files changed, 78 insertions(+), 22 deletions(-) diff --git a/headers.h b/headers.h index 34eafb2602..76881bb935 100644 --- a/headers.h +++ b/headers.h @@ -72,6 +72,8 @@ #include #include #include +#include +#include #include #include #include diff --git a/main.cpp b/main.cpp index fe213c099a..b957027f07 100644 --- a/main.cpp +++ b/main.cpp @@ -1215,7 +1215,7 @@ bool CBlock::AcceptBlock() return error("AcceptBlock() : block's timestamp is too early"); // Check that all transactions are finalized (starting around Dec 2009) - if (nBestHeight > 31000) // 25620 + 5320 + if (nBestHeight > 31000) foreach(const CTransaction& tx, vtx) if (!tx.IsFinal(nTime)) return error("AcceptBlock() : contains a non-final transaction"); @@ -1802,7 +1802,7 @@ bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) { if (fShutdown) return true; - addr.nTime = GetAdjustedTime(); + addr.nTime = GetAdjustedTime() - 2 * 60 * 60; if (pfrom->fGetAddr) addr.nTime -= 5 * 24 * 60 * 60; AddAddress(addrdb, addr, false); diff --git a/makefile.unix b/makefile.unix index c62efc008f..24aa8bfe4f 100644 --- a/makefile.unix +++ b/makefile.unix @@ -15,21 +15,24 @@ endif -INCLUDEPATHS=-I"/usr/include" \ - -I"/usr/local/boost_1_40_0" \ - -I"/usr/local/db-4.7.25.NC/build_unix" \ - -I"/usr/local/include/wx-2.8" \ - -I"/usr/local/lib/wx/include/gtk2-ansi-debug-static-2.8" - -LIBPATHS=-L"/usr/lib" \ - -L"/usr/local/lib" \ - -L"/usr/local/db-4.7.25.NC/build_unix" +INCLUDEPATHS= \ + -I"/usr/include" \ + -I"/usr/local/boost_1_40_0" \ + -I"/usr/local/db-4.7.25.NC/build_unix" \ + -I"/usr/local/include/wx-2.8" \ + -I"/usr/local/lib/wx/include/gtk2-ansi-debug-static-2.8" + +LIBPATHS= \ + -L"/usr/lib" \ + -L"/usr/local/lib" \ + -L"/usr/local/db-4.7.25.NC/build_unix" LIBS= \ -Wl,-Bstatic -l boost_thread -l boost_system -l boost_filesystem -Wl,-Bdynamic \ -Wl,-Bstatic -l db_cxx -l wx_gtk2$(D)-2.8 -Wl,-Bdynamic \ -l crypto \ -l gtk-x11-2.0 -l gthread-2.0 -l SM + WXDEFS=-D__WXGTK__ -DNOPCH CFLAGS=-O0 -w -Wno-invalid-offsetof -Wformat $(DEBUGFLAGS) $(WXDEFS) $(INCLUDEPATHS) HEADERS=headers.h util.h main.h serialize.h uint256.h key.h bignum.h script.h db.h base58.h @@ -76,7 +79,7 @@ obj/irc.o: irc.cpp $(HEADERS) OBJS=obj/util.o obj/script.o obj/db.o obj/net.o obj/main.o obj/market.o \ - obj/ui.o obj/uibase.o obj/sha.o obj/irc.o + obj/ui.o obj/uibase.o obj/sha.o obj/irc.o bitcoin: headers.h.gch $(OBJS) g++ $(CFLAGS) -o $@ $(LIBPATHS) $(OBJS) $(LIBS) diff --git a/net.cpp b/net.cpp index d70a62a297..0569604bab 100644 --- a/net.cpp +++ b/net.cpp @@ -842,20 +842,20 @@ void ThreadOpenConnections2(void* parg) if (!addr.IsIPv4() || !addr.IsValid() || setConnected.count(addr.ip)) continue; + // Randomize the order in a deterministic way, putting the standard port first + int64 nRandomizer = (uint64)(addr.nLastFailed * 9567851 + addr.ip * 7789) % (1 * 60 * 60); + if (addr.port != DEFAULT_PORT) + nRandomizer += 1 * 60 * 60; + // Limit retry frequency - if (GetAdjustedTime() < addr.nLastFailed + nDelay) + if (GetAdjustedTime() < addr.nLastFailed + nDelay + nRandomizer) continue; // Try again only after all addresses had a first attempt - int64 nTime = addr.nTime; + int64 nTime = addr.nTime - nRandomizer; if (addr.nLastFailed > addr.nTime) nTime -= 365 * 24 * 60 * 60; - // Randomize the order a little, putting the standard port first - nTime += GetRand(1 * 60 * 60); - if (addr.port != DEFAULT_PORT) - nTime -= 1 * 60 * 60; - if (nTime > nBestTime) { nBestTime = nTime; @@ -1069,6 +1069,7 @@ bool StartNode(string& strError) if (pnodeLocalHost == NULL) pnodeLocalHost = new CNode(INVALID_SOCKET, CAddress("127.0.0.1", nLocalServices)); +#ifdef __WXMSW__ // Get local host ip char pszHostName[255]; if (gethostname(pszHostName, sizeof(pszHostName)) == SOCKET_ERROR) @@ -1090,10 +1091,49 @@ bool StartNode(string& strError) printf("host ip %d: %s\n", i, CAddress(*(unsigned int*)phostent->h_addr_list[i]).ToStringIP().c_str()); for (int i = 0; phostent->h_addr_list[i] != NULL; i++) { - addrLocalHost = CAddress(*(unsigned int*)phostent->h_addr_list[i], DEFAULT_PORT, nLocalServices); - if (addrLocalHost.IsValid() && addrLocalHost.GetByte(3) != 127) + CAddress addr(*(unsigned int*)phostent->h_addr_list[i], DEFAULT_PORT, nLocalServices); + if (addr.IsValid() && addr.GetByte(3) != 127) + { + addrLocalHost = addr; break; + } + } +#else + // Get local host ip + struct ifaddrs* myaddrs; + if (getifaddrs(&myaddrs) == 0) + { + for (struct ifaddrs* ifa = myaddrs; ifa != NULL; ifa = ifa->ifa_next) + { + if (ifa->ifa_addr == NULL) continue; + if ((ifa->ifa_flags & IFF_UP) == 0) continue; + if (strcmp(ifa->ifa_name, "lo") == 0) continue; + if (strcmp(ifa->ifa_name, "lo0") == 0) continue; + char pszIP[100]; + if (ifa->ifa_addr->sa_family == AF_INET) + { + struct sockaddr_in* s4 = (struct sockaddr_in*)(ifa->ifa_addr); + if (inet_ntop(ifa->ifa_addr->sa_family, (void*)&(s4->sin_addr), pszIP, sizeof(pszIP)) != NULL) + printf("ipv4 %s: %s\n", ifa->ifa_name, pszIP); + + // Take the first IP that isn't loopback 127.x.x.x + CAddress addr(*(unsigned int*)&s4->sin_addr, DEFAULT_PORT, nLocalServices); + if (addr.IsValid() && addr.GetByte(3) != 127) + { + addrLocalHost = addr; + break; + } + } + else if (ifa->ifa_addr->sa_family == AF_INET6) + { + struct sockaddr_in6* s6 = (struct sockaddr_in6*)(ifa->ifa_addr); + if (inet_ntop(ifa->ifa_addr->sa_family, (void*)&(s6->sin6_addr), pszIP, sizeof(pszIP)) != NULL) + printf("ipv6 %s: %s\n", ifa->ifa_name, pszIP); + } + } + freeifaddrs(myaddrs); } +#endif printf("addrLocalHost = %s\n", addrLocalHost.ToString().c_str()); // Get our external IP address for incoming connections diff --git a/ui.cpp b/ui.cpp index a1873d5c2d..e12970b81b 100644 --- a/ui.cpp +++ b/ui.cpp @@ -387,17 +387,28 @@ CMainFrame::~CMainFrame() void Shutdown(void* parg) { static CCriticalSection cs_Shutdown; + static bool fTaken; + bool fFirstThread; CRITICAL_BLOCK(cs_Shutdown) + { + fFirstThread = !fTaken; + fTaken = true; + } + if (fFirstThread) { fShutdown = true; nTransactionsUpdated++; DBFlush(false); StopNode(); DBFlush(true); - printf("Bitcoin exiting\n\n"); exit(0); } + else + { + loop + Sleep(100000); + } } void CMainFrame::OnClose(wxCloseEvent& event) -- cgit v1.2.3 From 31e6ea7f5d5b3d73f4084261465142c9fe0fb894 Mon Sep 17 00:00:00 2001 From: s_nakamoto Date: Fri, 13 Nov 2009 01:23:08 +0000 Subject: monitor ThreadSocketHandler and terminate and restart if hung, convert _beginthread to CreateThread wrapper, disconnect inactive connections, ping, break up long messages to speed up initial download, better priorities for initiating connections, track how many nodes have requested our blocks and transactions, status #/offline and warning message on unsent blocks, minimize on close as separate option -- linux-test5 --- build-msw.txt | 2 +- build-unix.txt | 1 + db.cpp | 9 +- headers.h | 1 - irc.cpp | 5 +- main.cpp | 144 ++++++++++++++++++++---- main.h | 25 +++-- net.cpp | 342 +++++++++++++++++++++++++++++++++++++-------------------- net.h | 25 +++-- ui.cpp | 137 +++++++++++++++-------- ui.h | 2 +- uibase.cpp | 16 +-- uibase.h | 92 ++++++++-------- uiproject.fbp | 121 +++++++++----------- util.cpp | 48 ++++---- util.h | 105 +++++++++++++++--- 16 files changed, 684 insertions(+), 391 deletions(-) diff --git a/build-msw.txt b/build-msw.txt index eb6348bada..a159a71aeb 100644 --- a/build-msw.txt +++ b/build-msw.txt @@ -8,7 +8,7 @@ the OpenSSL Toolkit (http://www.openssl.org/). This product includes cryptographic software written by Eric Young (eay@cryptsoft.com). - WINDOWS BUILD NOTES +WINDOWS BUILD NOTES Compilers Supported diff --git a/build-unix.txt b/build-unix.txt index 6b29e1e5c4..ceb61ad545 100644 --- a/build-unix.txt +++ b/build-unix.txt @@ -13,6 +13,7 @@ UNIX BUILD NOTES Dependencies ------------ +Install the dev files for the shared libraries: apt-get install build-essential apt-get install libgtk2.0-dev apt-get install libssl-dev diff --git a/db.cpp b/db.cpp index 61d6025332..a9c42880ab 100644 --- a/db.cpp +++ b/db.cpp @@ -505,6 +505,13 @@ bool CWalletDB::LoadWallet(vector& vchDefaultKeyRet) { vchDefaultKeyRet.clear(); + // Modify defaults +#ifndef __WXMSW__ + // Reports that tray icon can disappear on gnome, leaving no way to access the program + fMinimizeToTray = false; + fMinimizeOnClose = false; +#endif + //// todo: shouldn't we catch exceptions and try to recover and continue? CRITICAL_BLOCK(cs_mapKeys) CRITICAL_BLOCK(cs_mapWallet) @@ -638,7 +645,7 @@ bool LoadWallet(bool& fFirstRunRet) CWalletDB().WriteDefaultKey(keyUser.GetPubKey()); } - _beginthread(ThreadFlushWalletDB, 0, NULL); + CreateThread(ThreadFlushWalletDB, NULL); return true; } diff --git a/headers.h b/headers.h index 76881bb935..22bb830f72 100644 --- a/headers.h +++ b/headers.h @@ -75,7 +75,6 @@ #include #include #include -#include #include #endif diff --git a/irc.cpp b/irc.cpp index 3b232caead..8432c6d145 100644 --- a/irc.cpp +++ b/irc.cpp @@ -54,7 +54,7 @@ static bool Send(SOCKET hSocket, const char* pszSend) const char* pszEnd = psz + strlen(psz); while (psz < pszEnd) { - int ret = send(hSocket, psz, pszEnd - psz, 0); + int ret = send(hSocket, psz, pszEnd - psz, MSG_NOSIGNAL); if (ret < 0) return false; psz += ret; @@ -156,7 +156,7 @@ bool Wait(int nSeconds) void ThreadIRCSeed(void* parg) { - SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_NORMAL); + SetThreadPriority(THREAD_PRIORITY_NORMAL); int nErrorWait = 10; int nRetryWait = 10; @@ -256,6 +256,7 @@ void ThreadIRCSeed(void* parg) CAddress addr; if (DecodeAddress(pszName, addr)) { + addr.nTime = GetAdjustedTime() - 51 * 60; CAddrDB addrdb; if (AddAddress(addrdb, addr)) printf("IRC got new address\n"); diff --git a/main.cpp b/main.cpp index b957027f07..13a9f9b72a 100644 --- a/main.cpp +++ b/main.cpp @@ -42,6 +42,9 @@ map > mapPubKeys; CCriticalSection cs_mapKeys; CKey keyUser; +map mapRequestCount; +CCriticalSection cs_mapRequestCount; + // Settings int fGenerateBitcoins = false; int64 nTransactionFee = 0; @@ -274,7 +277,44 @@ int64 CWalletTx::GetTxTime() const return nTimeReceived; } +int CWalletTx::GetRequestCount() const +{ + // Returns -1 if it wasn't being tracked + int nRequests = -1; + CRITICAL_BLOCK(cs_mapRequestCount) + { + if (IsCoinBase()) + { + // Generated block + if (hashBlock != 0) + { + map::iterator mi = mapRequestCount.find(hashBlock); + if (mi != mapRequestCount.end()) + nRequests = (*mi).second; + } + } + else + { + // Did anyone request this transaction? + map::iterator mi = mapRequestCount.find(GetHash()); + if (mi != mapRequestCount.end()) + { + nRequests = (*mi).second; + // How about the block it's in? + if (nRequests == 0 && hashBlock != 0) + { + map::iterator mi = mapRequestCount.find(hashBlock); + if (mi != mapRequestCount.end()) + nRequests = (*mi).second; + else + nRequests = 1; // If it's in someone else's block it must have got out + } + } + } + } + return nRequests; +} @@ -295,7 +335,7 @@ int CMerkleTx::SetMerkleBranch(const CBlock* pblock) CTxIndex txindex; if (!CTxDB("r").ReadTxIndex(GetHash(), txindex)) return 0; - if (!blockTmp.ReadFromDisk(txindex.pos.nFile, txindex.pos.nBlockPos, true)) + if (!blockTmp.ReadFromDisk(txindex.pos.nFile, txindex.pos.nBlockPos)) return 0; pblock = &blockTmp; } @@ -1003,7 +1043,7 @@ bool Reorganize(CTxDB& txdb, CBlockIndex* pindexNew) foreach(CBlockIndex* pindex, vDisconnect) { CBlock block; - if (!block.ReadFromDisk(pindex->nFile, pindex->nBlockPos, true)) + if (!block.ReadFromDisk(pindex->nFile, pindex->nBlockPos)) return error("Reorganize() : ReadFromDisk for disconnect failed"); if (!block.DisconnectBlock(txdb, pindex)) return error("Reorganize() : DisconnectBlock failed"); @@ -1020,7 +1060,7 @@ bool Reorganize(CTxDB& txdb, CBlockIndex* pindexNew) { CBlockIndex* pindex = vConnect[i]; CBlock block; - if (!block.ReadFromDisk(pindex->nFile, pindex->nBlockPos, true)) + if (!block.ReadFromDisk(pindex->nFile, pindex->nBlockPos)) return error("Reorganize() : ReadFromDisk for connect failed"); if (!block.ConnectBlock(txdb, pindex)) { @@ -1380,7 +1420,7 @@ bool CheckDiskSpace(int64 nAdditionalBytes) { fShutdown = true; ThreadSafeMessageBox("Warning: Your disk space is low ", "Bitcoin", wxOK | wxICON_EXCLAMATION); - _beginthread(Shutdown, 0, NULL); + CreateThread(Shutdown, NULL); return false; } return true; @@ -1547,7 +1587,7 @@ void PrintBlockTree() // print item CBlock block; - block.ReadFromDisk(pindex, true); + block.ReadFromDisk(pindex); printf("%d (%u,%u) %s %s tx %d", pindex->nHeight, pindex->nFile, @@ -1623,7 +1663,8 @@ bool ProcessMessages(CNode* pfrom) CDataStream& vRecv = pfrom->vRecv; if (vRecv.empty()) return true; - //printf("ProcessMessages(%d bytes)\n", vRecv.size()); + //if (fDebug) + // printf("ProcessMessages(%d bytes)\n", vRecv.size()); // // Message format @@ -1666,7 +1707,8 @@ bool ProcessMessages(CNode* pfrom) { // Rewind and wait for rest of message ///// need a mechanism to give up waiting for overlong message size error - //printf("message-break\n"); + //if (fDebug) + // printf("message-break\n"); vRecv.insert(vRecv.begin(), BEGIN(hdr), END(hdr)); Sleep(100); break; @@ -1718,6 +1760,8 @@ bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) { static map > mapReuseKey; RandAddSeedPerfmon(); + if (fDebug) + printf("%s ", DateTimeStrFormat("%x %H:%M:%S", GetTime()).c_str()); printf("received: %s (%d bytes)\n", strCommand.c_str(), vRecv.size()); if (mapArgs.count("-dropmessagestest") && GetRand(atoi(mapArgs["-dropmessagestest"])) == 0) { @@ -1739,18 +1783,19 @@ bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) CAddress addrMe; CAddress addrFrom; uint64 nNonce = 1; + string strSubVer; vRecv >> pfrom->nVersion >> pfrom->nServices >> nTime >> addrMe; if (pfrom->nVersion >= 106 && !vRecv.empty()) vRecv >> addrFrom >> nNonce; + if (pfrom->nVersion >= 106 && !vRecv.empty()) + vRecv >> strSubVer; if (pfrom->nVersion == 0) return false; // Disconnect if we connected to ourself - if (nNonce == nLocalHostNonce) + if (nNonce == nLocalHostNonce && nNonce > 1) { pfrom->fDisconnect = true; - pfrom->vRecv.clear(); - pfrom->vSend.clear(); return true; } @@ -1776,10 +1821,6 @@ bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) pfrom->fSuccessfullyConnected = true; - // Update the last seen time - if (pfrom->fNetworkNode) - AddressCurrentlyConnected(pfrom->addr); - printf("version message: version %d\n", pfrom->nVersion); } @@ -1824,10 +1865,6 @@ bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) vector vInv; vRecv >> vInv; - // Update the last seen time for this node's address - if (pfrom->fNetworkNode) - AddressCurrentlyConnected(pfrom->addr); - CTxDB txdb("r"); foreach(const CInv& inv, vInv) { @@ -1842,6 +1879,14 @@ bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) pfrom->AskFor(inv); else if (inv.type == MSG_BLOCK && mapOrphanBlocks.count(inv.hash)) pfrom->PushMessage("getblocks", CBlockLocator(pindexBest), GetOrphanRoot(mapOrphanBlocks[inv.hash])); + + // Track requests for our stuff + CRITICAL_BLOCK(cs_mapRequestCount) + { + map::iterator mi = mapRequestCount.find(inv.hash); + if (mi != mapRequestCount.end()) + (*mi).second++; + } } } @@ -1879,6 +1924,14 @@ bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) pfrom->PushMessage(inv.GetCommand(), (*mi).second); } } + + // Track requests for our stuff + CRITICAL_BLOCK(cs_mapRequestCount) + { + map::iterator mi = mapRequestCount.find(inv.hash); + if (mi != mapRequestCount.end()) + (*mi).second++; + } } } @@ -2086,11 +2139,23 @@ bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) } + else if (strCommand == "ping") + { + } + + else { // Ignore unknown commands for extensibility } + + // Update the last seen time for this node's address + if (pfrom->fNetworkNode) + if (strCommand == "version" || strCommand == "addr" || strCommand == "inv" || strCommand == "getdata" || strCommand == "ping") + AddressCurrentlyConnected(pfrom->addr); + + return true; } @@ -2129,6 +2194,10 @@ bool SendMessages(CNode* pto) } } + // Keep-alive ping + if (pto->nLastSend && GetTime() - pto->nLastSend > 12 * 60 && pto->vSend.empty()) + pto->PushMessage("ping"); + // // Message: addr @@ -2139,7 +2208,14 @@ bool SendMessages(CNode* pto) { // returns true if wasn't already contained in the set if (pto->setAddrKnown.insert(addr).second) + { vAddrToSend.push_back(addr); + if (vAddrToSend.size() >= 1000) + { + pto->PushMessage("addr", vAddrToSend); + vAddrToSend.clear(); + } + } } pto->vAddrToSend.clear(); if (!vAddrToSend.empty()) @@ -2157,7 +2233,14 @@ bool SendMessages(CNode* pto) { // returns true if wasn't already contained in the set if (pto->setInventoryKnown.insert(inv).second) + { vInventoryToSend.push_back(inv); + if (vInventoryToSend.size() >= 1000) + { + pto->PushMessage("inv", vInventoryToSend); + vInventoryToSend.clear(); + } + } } pto->vInventoryToSend.clear(); pto->setInventoryKnown2.clear(); @@ -2179,6 +2262,11 @@ bool SendMessages(CNode* pto) { printf("sending getdata: %s\n", inv.ToString().c_str()); vAskFor.push_back(inv); + if (vAskFor.size() >= 1000) + { + pto->PushMessage("getdata", vAskFor); + vAskFor.clear(); + } } pto->mapAskFor.erase(pto->mapAskFor.begin()); } @@ -2226,8 +2314,8 @@ void GenerateBitcoins(bool fGenerate) int nAddThreads = nProcessors - vnThreadsRunning[3]; printf("Starting %d BitcoinMiner threads\n", nAddThreads); for (int i = 0; i < nAddThreads; i++) - if (_beginthread(ThreadBitcoinMiner, 0, NULL) == -1) - printf("Error: _beginthread(ThreadBitcoinMiner) failed\n"); + if (!CreateThread(ThreadBitcoinMiner, NULL)) + printf("Error: CreateThread(ThreadBitcoinMiner) failed\n"); } } @@ -2304,7 +2392,7 @@ void BitcoinMiner() CBigNum bnExtraNonce = 0; while (fGenerateBitcoins) { - SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_LOWEST); + SetThreadPriority(THREAD_PRIORITY_LOWEST); Sleep(50); if (fShutdown) return; @@ -2440,7 +2528,7 @@ void BitcoinMiner() printf("proof-of-work found \n hash: %s \ntarget: %s\n", hash.GetHex().c_str(), hashTarget.GetHex().c_str()); pblock->print(); - SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_NORMAL); + SetThreadPriority(THREAD_PRIORITY_NORMAL); CRITICAL_BLOCK(cs_main) { if (pindexPrev == pindexBest) @@ -2450,12 +2538,16 @@ void BitcoinMiner() return; key.MakeNewKey(); + // Track how many getdata requests this block gets + CRITICAL_BLOCK(cs_mapRequestCount) + mapRequestCount[pblock->GetHash()] = 0; + // Process this block the same as if we had received it from another node if (!ProcessBlock(NULL, pblock.release())) printf("ERROR in BitcoinMiner, ProcessBlock, block not accepted\n"); } } - SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_LOWEST); + SetThreadPriority(THREAD_PRIORITY_LOWEST); Sleep(500); break; @@ -2534,7 +2626,7 @@ bool SelectCoins(int64 nTargetValue, set& setCoinsRet) setCoinsRet.clear(); // List of values less than target - int64 nLowestLarger = _I64_MAX; + int64 nLowestLarger = INT64_MAX; CWalletTx* pcoinLowestLarger = NULL; vector > vValue; int64 nTotalLower = 0; @@ -2777,6 +2869,10 @@ bool SendMoney(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew) return error("SendMoney() : Error finalizing transaction"); } + // Track how many getdata requests our transaction gets + CRITICAL_BLOCK(cs_mapRequestCount) + mapRequestCount[wtxNew.GetHash()] = 0; + printf("SendMoney: %s\n", wtxNew.GetHash().ToString().substr(0,6).c_str()); // Broadcast diff --git a/main.h b/main.h index 853fdfa5b6..8bb1e19e8a 100644 --- a/main.h +++ b/main.h @@ -34,6 +34,8 @@ extern int nBestHeight; extern uint256 hashBestChain; extern CBlockIndex* pindexBest; extern unsigned int nTransactionsUpdated; +extern map mapRequestCount; +extern CCriticalSection cs_mapRequestCount; // Settings extern int fGenerateBitcoins; @@ -647,6 +649,15 @@ public: nGetCreditCached = 0; } + IMPLEMENT_SERIALIZE + ( + nSerSize += SerReadWrite(s, *(CTransaction*)this, nType, nVersion, ser_action); + nVersion = this->nVersion; + READWRITE(hashBlock); + READWRITE(vMerkleBranch); + READWRITE(nIndex); + ) + int64 GetCredit(bool fUseCache=false) const { // Must wait until coinbase is safely deep enough in the chain before valuing it @@ -661,15 +672,6 @@ public: return nGetCreditCached; } - IMPLEMENT_SERIALIZE - ( - nSerSize += SerReadWrite(s, *(CTransaction*)this, nType, nVersion, ser_action); - nVersion = this->nVersion; - READWRITE(hashBlock); - READWRITE(vMerkleBranch); - READWRITE(nIndex); - ) - int SetMerkleBranch(const CBlock* pblock=NULL); int GetDepthInMainChain() const; @@ -749,6 +751,7 @@ public: int64 GetTxTime() const; + int GetRequestCount() const; void AddSupportingTransactions(CTxDB& txdb); @@ -978,7 +981,7 @@ public: return true; } - bool ReadFromDisk(unsigned int nFile, unsigned int nBlockPos, bool fReadTransactions) + bool ReadFromDisk(unsigned int nFile, unsigned int nBlockPos, bool fReadTransactions=true) { SetNull(); @@ -1027,7 +1030,7 @@ public: int64 GetBlockValue(int64 nFees) const; bool DisconnectBlock(CTxDB& txdb, CBlockIndex* pindex); bool ConnectBlock(CTxDB& txdb, CBlockIndex* pindex); - bool ReadFromDisk(const CBlockIndex* blockindex, bool fReadTransactions); + bool ReadFromDisk(const CBlockIndex* blockindex, bool fReadTransactions=true); bool AddToBlockIndex(unsigned int nFile, unsigned int nBlockPos); bool CheckBlock() const; bool AcceptBlock(); diff --git a/net.cpp b/net.cpp index 0569604bab..71295d5dee 100644 --- a/net.cpp +++ b/net.cpp @@ -13,7 +13,6 @@ bool OpenNetworkConnection(const CAddress& addrConnect); - // // Global state variables // @@ -25,6 +24,7 @@ uint64 nLocalHostNonce = 0; bool fShutdown = false; array vnThreadsRunning; SOCKET hListenSocket = INVALID_SOCKET; +int64 nThreadSocketHandlerHeartbeat = INT64_MAX; vector vNodes; CCriticalSection cs_vNodes; @@ -65,7 +65,7 @@ bool ConnectSocket(const CAddress& addrConnect, SOCKET& hSocketRet) if (fProxy) { - printf("Proxy connecting %s\n", addrConnect.ToStringLog().c_str()); + printf("proxy connecting %s\n", addrConnect.ToStringLog().c_str()); char pszSocks4IP[] = "\4\1\0\0\0\0\0\0user"; memcpy(pszSocks4IP + 2, &addrConnect.port, 2); memcpy(pszSocks4IP + 4, &addrConnect.ip, 4); @@ -87,9 +87,11 @@ bool ConnectSocket(const CAddress& addrConnect, SOCKET& hSocketRet) if (pchRet[1] != 0x5a) { closesocket(hSocket); - return error("Proxy returned error %d", pchRet[1]); + if (pchRet[1] != 0x5b) + printf("ERROR: Proxy returned error %d\n", pchRet[1]); + return false; } - printf("Proxy connection established %s\n", addrConnect.ToStringLog().c_str()); + printf("proxy connected %s\n", addrConnect.ToStringLog().c_str()); } hSocketRet = hSocket; @@ -219,6 +221,7 @@ bool AddAddress(CAddrDB& addrdb, CAddress addr, bool fCurrentlyOnline) if (it == mapAddresses.end()) { // New address + printf("AddAddress(%s)\n", addr.ToStringLog().c_str()); mapAddresses.insert(make_pair(addr.GetKey(), addr)); addrdb.WriteAddress(addr); return true; @@ -256,7 +259,7 @@ void AddressCurrentlyConnected(const CAddress& addr) if (it != mapAddresses.end()) { CAddress& addrFound = (*it).second; - int64 nUpdateInterval = 60 * 60; + int64 nUpdateInterval = 20 * 60; if (addrFound.nTime < GetAdjustedTime() - nUpdateInterval) { // Periodically update most recently seen time @@ -417,7 +420,13 @@ CNode* ConnectNode(CAddress addrConnect, int64 nTimeout) } /// debug print - printf("trying connection %s\n", addrConnect.ToStringLog().c_str()); + printf("trying connection %s lastseen=%.1fhrs lasttry=%.1fhrs\n", + addrConnect.ToStringLog().c_str(), + (double)(addrConnect.nTime - GetAdjustedTime())/3600.0, + (double)(addrConnect.nLastTry - GetAdjustedTime())/3600.0); + + CRITICAL_BLOCK(cs_mapAddresses) + mapAddresses[addrConnect.GetKey()].nLastTry = GetAdjustedTime(); // Connect SOCKET hSocket; @@ -428,7 +437,7 @@ CNode* ConnectNode(CAddress addrConnect, int64 nTimeout) // Set to nonblocking #ifdef __WXMSW__ - u_long nOne = 1; + u_long nOne = 1; if (ioctlsocket(hSocket, FIONBIO, &nOne) == SOCKET_ERROR) printf("ConnectSocket() : ioctlsocket nonblocking setting failed, error %d\n", WSAGetLastError()); #else @@ -445,29 +454,23 @@ CNode* ConnectNode(CAddress addrConnect, int64 nTimeout) CRITICAL_BLOCK(cs_vNodes) vNodes.push_back(pnode); - CRITICAL_BLOCK(cs_mapAddresses) - mapAddresses[addrConnect.GetKey()].nLastFailed = 0; + pnode->nTimeConnected = GetTime(); return pnode; } else { - CRITICAL_BLOCK(cs_mapAddresses) - mapAddresses[addrConnect.GetKey()].nLastFailed = GetAdjustedTime(); return NULL; } } void CNode::DoDisconnect() { + if (fDebug) + printf("%s ", DateTimeStrFormat("%x %H:%M:%S", GetTime()).c_str()); printf("disconnecting node %s\n", addr.ToStringLog().c_str()); closesocket(hSocket); - // If outbound and never got version message, mark address as failed - if (!fInbound && !fSuccessfullyConnected) - CRITICAL_BLOCK(cs_mapAddresses) - mapAddresses[addr.GetKey()].nLastFailed = GetAdjustedTime(); - // All of a nodes broadcasts and subscriptions are automatically torn down // when it goes down, so a node has to stay up to keep its broadcast going. @@ -508,7 +511,7 @@ void ThreadSocketHandler(void* parg) PrintException(&e, "ThreadSocketHandler()"); } catch (...) { vnThreadsRunning[0]--; - PrintException(NULL, "ThreadSocketHandler()"); + throw; // support pthread_cancel() } printf("ThreadSocketHandler exiting\n"); @@ -531,15 +534,18 @@ void ThreadSocketHandler2(void* parg) vector vNodesCopy = vNodes; foreach(CNode* pnode, vNodesCopy) { - if (pnode->ReadyToDisconnect() && pnode->vRecv.empty() && pnode->vSend.empty()) + if (pnode->fDisconnect || + (pnode->GetRefCount() <= 0 && pnode->vRecv.empty() && pnode->vSend.empty())) { // remove from vNodes vNodes.erase(remove(vNodes.begin(), vNodes.end(), pnode), vNodes.end()); + + // close socket pnode->DoDisconnect(); // hold in disconnected pool until all refs are released pnode->nReleaseTime = max(pnode->nReleaseTime, GetTime() + 5 * 60); - if (pnode->fNetworkNode) + if (pnode->fNetworkNode || pnode->fInbound) pnode->Release(); vNodesDisconnected.push_back(pnode); } @@ -582,8 +588,10 @@ void ThreadSocketHandler2(void* parg) fd_set fdsetRecv; fd_set fdsetSend; + fd_set fdsetError; FD_ZERO(&fdsetRecv); FD_ZERO(&fdsetSend); + FD_ZERO(&fdsetError); SOCKET hSocketMax = 0; FD_SET(hListenSocket, &fdsetRecv); hSocketMax = max(hSocketMax, hListenSocket); @@ -592,6 +600,7 @@ void ThreadSocketHandler2(void* parg) foreach(CNode* pnode, vNodes) { FD_SET(pnode->hSocket, &fdsetRecv); + FD_SET(pnode->hSocket, &fdsetError); hSocketMax = max(hSocketMax, pnode->hSocket); TRY_CRITICAL_BLOCK(pnode->cs_vSend) if (!pnode->vSend.empty()) @@ -600,30 +609,21 @@ void ThreadSocketHandler2(void* parg) } vnThreadsRunning[0]--; - int nSelect = select(hSocketMax + 1, &fdsetRecv, &fdsetSend, NULL, &timeout); + int nSelect = select(hSocketMax + 1, &fdsetRecv, &fdsetSend, &fdsetError, &timeout); vnThreadsRunning[0]++; if (fShutdown) return; if (nSelect == SOCKET_ERROR) { int nErr = WSAGetLastError(); - printf("select failed: %d\n", nErr); + printf("socket select error %d\n", nErr); for (int i = 0; i <= hSocketMax; i++) - { FD_SET(i, &fdsetRecv); - FD_SET(i, &fdsetSend); - } + FD_ZERO(&fdsetSend); + FD_ZERO(&fdsetError); Sleep(timeout.tv_usec/1000); } - //// debug print - //foreach(CNode* pnode, vNodes) - //{ - // printf("vRecv = %-5d ", pnode->vRecv.size()); - // printf("vSend = %-5d ", pnode->vSend.size()); - //} - //printf("\n"); - // // Accept new connections @@ -641,7 +641,7 @@ void ThreadSocketHandler2(void* parg) if (hSocket == INVALID_SOCKET) { if (WSAGetLastError() != WSAEWOULDBLOCK) - printf("ERROR ThreadSocketHandler accept failed: %d\n", WSAGetLastError()); + printf("socket error accept failed: %d\n", WSAGetLastError()); } else { @@ -669,7 +669,7 @@ void ThreadSocketHandler2(void* parg) // // Receive // - if (FD_ISSET(hSocket, &fdsetRecv)) + if (FD_ISSET(hSocket, &fdsetRecv) || FD_ISSET(hSocket, &fdsetError)) { TRY_CRITICAL_BLOCK(pnode->cs_vRecv) { @@ -677,25 +677,29 @@ void ThreadSocketHandler2(void* parg) unsigned int nPos = vRecv.size(); // typical socket buffer is 8K-64K - const unsigned int nBufSize = 0x10000; - vRecv.resize(nPos + nBufSize); - int nBytes = recv(hSocket, &vRecv[nPos], nBufSize, 0); - vRecv.resize(nPos + max(nBytes, 0)); - if (nBytes == 0) + char pchBuf[0x10000]; + int nBytes = recv(hSocket, pchBuf, sizeof(pchBuf), MSG_DONTWAIT); + if (nBytes > 0) + { + vRecv.resize(nPos + nBytes); + memcpy(&vRecv[nPos], pchBuf, nBytes); + pnode->nLastRecv = GetTime(); + } + else if (nBytes == 0) { // socket closed gracefully if (!pnode->fDisconnect) - printf("recv: socket closed\n"); + printf("socket closed\n"); pnode->fDisconnect = true; } else if (nBytes < 0) { - // socket error + // error int nErr = WSAGetLastError(); if (nErr != WSAEWOULDBLOCK && nErr != WSAEMSGSIZE && nErr != WSAEINTR && nErr != WSAEINPROGRESS) { if (!pnode->fDisconnect) - printf("recv failed: %d\n", nErr); + printf("socket recv error %d\n", nErr); pnode->fDisconnect = true; } } @@ -712,28 +716,63 @@ void ThreadSocketHandler2(void* parg) CDataStream& vSend = pnode->vSend; if (!vSend.empty()) { - int nBytes = send(hSocket, &vSend[0], vSend.size(), MSG_NOSIGNAL); + int nBytes = send(hSocket, &vSend[0], vSend.size(), MSG_NOSIGNAL | MSG_DONTWAIT); if (nBytes > 0) { vSend.erase(vSend.begin(), vSend.begin() + nBytes); + pnode->nLastSend = GetTime(); } - else if (nBytes == 0) - { - if (pnode->ReadyToDisconnect()) - pnode->vSend.clear(); - } - else + else if (nBytes < 0) { - printf("send error %d\n", nBytes); - if (pnode->ReadyToDisconnect()) - pnode->vSend.clear(); + // error + int nErr = WSAGetLastError(); + if (nErr != WSAEWOULDBLOCK && nErr != WSAEMSGSIZE && nErr != WSAEINTR && nErr != WSAEINPROGRESS) + { + printf("socket send error %d\n", nErr); + pnode->fDisconnect = true; + } } } } } + + // + // Inactivity checking + // + if (pnode->vSend.empty()) + pnode->nLastSendEmpty = GetTime(); + if (GetTime() - pnode->nTimeConnected > 60) + { + if (pnode->nLastRecv == 0 || pnode->nLastSend == 0) + { + printf("socket no message in first 60 seconds, %d %d\n", pnode->nLastRecv != 0, pnode->nLastSend != 0); + pnode->fDisconnect = true; + } + else if (GetTime() - pnode->nLastSend > 10 * 60 && GetTime() - pnode->nLastSendEmpty > 10 * 60) + { + printf("socket not sending\n"); + pnode->fDisconnect = true; + } + else if (GetTime() - pnode->nLastRecv > (pnode->nVersion >= 107 ? 15*60 : 90*60)) + { + printf("socket inactivity timeout\n"); + pnode->fDisconnect = true; + } + } + } + + + //// debug heartbeat + static int64 nHeartbeat1; + if (GetTime() - nHeartbeat1 >= 5 * 60) + { + printf("%s sendrecv\n", DateTimeStrFormat("%x %H:%M:%S", GetTime()).c_str()); + nHeartbeat1 = GetTime(); + fDebug = true; } + nThreadSocketHandlerHeartbeat = GetTime(); Sleep(10); } } @@ -772,15 +811,20 @@ void ThreadOpenConnections2(void* parg) { printf("ThreadOpenConnections started\n"); - // Connect to one specified address + // Connect to specific addresses while (mapArgs.count("-connect")) { - OpenNetworkConnection(CAddress(mapArgs["-connect"])); - for (int i = 0; i < 10; i++) + foreach(string strAddr, mapMultiArgs["-connect"]) { - Sleep(1000); - if (fShutdown) - return; + CAddress addr(strAddr, NODE_NETWORK); + if (addr.IsValid()) + OpenNetworkConnection(addr); + for (int i = 0; i < 10; i++) + { + Sleep(1000); + if (fShutdown) + return; + } } } @@ -821,12 +865,7 @@ void ThreadOpenConnections2(void* parg) // Choose an address to connect to based on most recently seen // CAddress addrConnect; - int64 nBestTime = 0; - int64 nDelay = ((60 * 60) << vNodes.size()); - if (vNodes.size() >= 3) - nDelay *= 4; - if (nGotIRCAddresses > 0) - nDelay *= 100; + int64 nBest = INT64_MIN; // Do this here so we don't have to critsect vNodes inside mapAddresses critsect set setConnected; @@ -841,24 +880,51 @@ void ThreadOpenConnections2(void* parg) const CAddress& addr = item.second; if (!addr.IsIPv4() || !addr.IsValid() || setConnected.count(addr.ip)) continue; + int64 nSinceLastSeen = GetAdjustedTime() - addr.nTime; + int64 nSinceLastTry = GetAdjustedTime() - addr.nLastTry; // Randomize the order in a deterministic way, putting the standard port first - int64 nRandomizer = (uint64)(addr.nLastFailed * 9567851 + addr.ip * 7789) % (1 * 60 * 60); + int64 nRandomizer = (uint64)(addr.nLastTry * 9567851 + addr.ip * 7789) % (30 * 60); if (addr.port != DEFAULT_PORT) - nRandomizer += 1 * 60 * 60; + nRandomizer += 30 * 60; + + // Last seen Base retry frequency + // <1 hour 10 min + // 1 hour 1 hour + // 4 hours 2 hours + // 24 hours 5 hours + // 48 hours 7 hours + // 7 days 13 hours + // 30 days 27 hours + // 90 days 46 hours + // 365 days 93 hours + int64 nDelay = 3600.0 * sqrt(fabs(nSinceLastSeen) / 3600.0) + nRandomizer; + + // Fast reconnect for one hour after last seen + if (nSinceLastSeen < 60 * 60) + nDelay = 10 * 60; // Limit retry frequency - if (GetAdjustedTime() < addr.nLastFailed + nDelay + nRandomizer) + if (nSinceLastTry < nDelay) continue; - // Try again only after all addresses had a first attempt - int64 nTime = addr.nTime - nRandomizer; - if (addr.nLastFailed > addr.nTime) - nTime -= 365 * 24 * 60 * 60; + // If we have IRC, we'll be notified when they first come online, + // and again every 24 hours by the refresh broadcast. + if (nGotIRCAddresses > 0 && vNodes.size() >= 2 && nSinceLastSeen > 24 * 60 * 60) + continue; - if (nTime > nBestTime) + // Only try the old stuff if we don't have enough connections + if (vNodes.size() >= 2 && nSinceLastSeen > 7 * 24 * 60 * 60) + continue; + if (vNodes.size() >= 4 && nSinceLastSeen > 24 * 60 * 60) + continue; + + // If multiple addresses are ready, prioritize by time since + // last seen and time since last tried. + int64 nScore = min(nSinceLastTry, (int64)24 * 60 * 60) - nSinceLastSeen - nRandomizer; + if (nScore > nBest) { - nBestTime = nTime; + nBest = nScore; addrConnect = addr; } } @@ -941,7 +1007,7 @@ void ThreadMessageHandler(void* parg) void ThreadMessageHandler2(void* parg) { printf("ThreadMessageHandler started\n"); - SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_BELOW_NORMAL); + SetThreadPriority(THREAD_PRIORITY_BELOW_NORMAL); loop { // Poll the connected nodes for messages @@ -1063,39 +1129,31 @@ bool BindListenPort(string& strError) return true; } -bool StartNode(string& strError) +void StartNode(void* parg) { - strError = ""; if (pnodeLocalHost == NULL) pnodeLocalHost = new CNode(INVALID_SOCKET, CAddress("127.0.0.1", nLocalServices)); #ifdef __WXMSW__ // Get local host ip - char pszHostName[255]; - if (gethostname(pszHostName, sizeof(pszHostName)) == SOCKET_ERROR) + char pszHostName[1000] = ""; + if (gethostname(pszHostName, sizeof(pszHostName)) != SOCKET_ERROR) { - strError = strprintf("Error: Unable to get IP address of this computer (gethostname returned error %d)", WSAGetLastError()); - printf("%s\n", strError.c_str()); - return false; - } - struct hostent* phostent = gethostbyname(pszHostName); - if (!phostent) - { - strError = strprintf("Error: Unable to get IP address of this computer (gethostbyname returned error %d)", WSAGetLastError()); - printf("%s\n", strError.c_str()); - return false; - } - - // Take the first IP that isn't loopback 127.x.x.x - for (int i = 0; phostent->h_addr_list[i] != NULL; i++) - printf("host ip %d: %s\n", i, CAddress(*(unsigned int*)phostent->h_addr_list[i]).ToStringIP().c_str()); - for (int i = 0; phostent->h_addr_list[i] != NULL; i++) - { - CAddress addr(*(unsigned int*)phostent->h_addr_list[i], DEFAULT_PORT, nLocalServices); - if (addr.IsValid() && addr.GetByte(3) != 127) + struct hostent* phostent = gethostbyname(pszHostName); + if (phostent) { - addrLocalHost = addr; - break; + // Take the first IP that isn't loopback 127.x.x.x + for (int i = 0; phostent->h_addr_list[i] != NULL; i++) + printf("host ip %d: %s\n", i, CAddress(*(unsigned int*)phostent->h_addr_list[i]).ToStringIP().c_str()); + for (int i = 0; phostent->h_addr_list[i] != NULL; i++) + { + CAddress addr(*(unsigned int*)phostent->h_addr_list[i], DEFAULT_PORT, nLocalServices); + if (addr.IsValid() && addr.GetByte(3) != 127) + { + addrLocalHost = addr; + break; + } + } } } #else @@ -1145,45 +1203,85 @@ bool StartNode(string& strError) } else { - if (addrIncoming.ip) + if (addrIncoming.IsValid()) addrLocalHost.ip = addrIncoming.ip; if (GetMyExternalIP(addrLocalHost.ip)) { addrIncoming = addrLocalHost; CWalletDB().WriteSetting("addrIncoming", addrIncoming); + printf("addrLocalHost = %s\n", addrLocalHost.ToString().c_str()); } } - // Get addresses from IRC and advertise ours - if (_beginthread(ThreadIRCSeed, 0, NULL) == -1) - printf("Error: _beginthread(ThreadIRCSeed) failed\n"); - // // Start threads // - if (_beginthread(ThreadSocketHandler, 0, NULL) == -1) - { - strError = "Error: _beginthread(ThreadSocketHandler) failed"; - printf("%s\n", strError.c_str()); - return false; - } - if (_beginthread(ThreadOpenConnections, 0, NULL) == -1) - { - strError = "Error: _beginthread(ThreadOpenConnections) failed"; - printf("%s\n", strError.c_str()); - return false; - } + // Get addresses from IRC and advertise ours + if (!CreateThread(ThreadIRCSeed, NULL)) + printf("Error: CreateThread(ThreadIRCSeed) failed\n"); + + // Send and receive from sockets, accept connections + pthread_t hThreadSocketHandler = CreateThread(ThreadSocketHandler, NULL, true); + + // Initiate outbound connections + if (!CreateThread(ThreadOpenConnections, NULL)) + printf("Error: CreateThread(ThreadOpenConnections) failed\n"); + + // Process messages + if (!CreateThread(ThreadMessageHandler, NULL)) + printf("Error: CreateThread(ThreadMessageHandler) failed\n"); - if (_beginthread(ThreadMessageHandler, 0, NULL) == -1) + // Generate coins in the background + GenerateBitcoins(fGenerateBitcoins); + + // + // Thread monitoring + // + loop { - strError = "Error: _beginthread(ThreadMessageHandler) failed"; - printf("%s\n", strError.c_str()); - return false; + Sleep(15000); + if (GetTime() - nThreadSocketHandlerHeartbeat > 4 * 60) + { + // First see if closing sockets will free it + printf("*** ThreadSocketHandler is stopped ***\n"); + CRITICAL_BLOCK(cs_vNodes) + { + foreach(CNode* pnode, vNodes) + { + bool fGot = false; + TRY_CRITICAL_BLOCK(pnode->cs_vRecv) + TRY_CRITICAL_BLOCK(pnode->cs_vSend) + fGot = true; + if (!fGot) + { + printf("*** closing socket\n"); + closesocket(pnode->hSocket); + pnode->fDisconnect = true; + } + } + } + Sleep(10000); + if (GetTime() - nThreadSocketHandlerHeartbeat < 60) + continue; + + // Hopefully it never comes to this. + // We know it'll always be hung in the recv or send call. + // cs_vRecv or cs_vSend may be left permanently unreleased, + // but we always only use TRY_CRITICAL_SECTION on them. + printf("*** Restarting ThreadSocketHandler ***\n"); + TerminateThread(hThreadSocketHandler, 0); + #ifdef __WXMSW__ + CloseHandle(hThreadSocketHandler); + #endif + vnThreadsRunning[0] = 0; + + // Restart + hThreadSocketHandler = CreateThread(ThreadSocketHandler, NULL, true); + nThreadSocketHandlerHeartbeat = GetTime(); + } } - - return true; } bool StopNode() diff --git a/net.h b/net.h index 7b83d462fe..6300d3efcf 100644 --- a/net.h +++ b/net.h @@ -29,7 +29,7 @@ CNode* ConnectNode(CAddress addrConnect, int64 nTimeout=0); void AbandonRequests(void (*fn)(void*, CDataStream&), void* param1); bool AnySubscribed(unsigned int nChannel); bool BindListenPort(string& strError=REF(string())); -bool StartNode(string& strError=REF(string())); +void StartNode(void* parg); bool StopNode(); @@ -39,7 +39,6 @@ bool StopNode(); - // // Message header // (4) message start @@ -139,7 +138,7 @@ public: unsigned int nTime; // memory only - unsigned int nLastFailed; + unsigned int nLastTry; CAddress() { @@ -183,7 +182,7 @@ public: ip = INADDR_NONE; port = DEFAULT_PORT; nTime = GetAdjustedTime(); - nLastFailed = 0; + nLastTry = 0; } bool SetAddress(const char* pszIn) @@ -458,6 +457,7 @@ extern uint64 nLocalHostNonce; extern bool fShutdown; extern array vnThreadsRunning; extern SOCKET hListenSocket; +extern int64 nThreadSocketHandlerHeartbeat; extern vector vNodes; extern CCriticalSection cs_vNodes; @@ -486,6 +486,10 @@ public: CDataStream vRecv; CCriticalSection cs_vSend; CCriticalSection cs_vRecv; + int64 nLastSend; + int64 nLastRecv; + int64 nLastSendEmpty; + int64 nTimeConnected; unsigned int nPushPos; CAddress addr; int nVersion; @@ -523,6 +527,10 @@ public: hSocket = hSocketIn; vSend.SetType(SER_NETWORK); vRecv.SetType(SER_NETWORK); + nLastSend = 0; + nLastRecv = 0; + nLastSendEmpty = GetTime(); + nTimeConnected = GetTime(); nPushPos = -1; addr = addrIn; nVersion = 0; @@ -542,7 +550,7 @@ public: CAddress addrYou = (fUseProxy ? CAddress("0.0.0.0") : addr); CAddress addrMe = (fUseProxy ? CAddress("0.0.0.0") : addrLocalHost); RAND_bytes((unsigned char*)&nLocalHostNonce, sizeof(nLocalHostNonce)); - PushMessage("version", VERSION, nLocalServices, nTime, addrYou, addrMe, nLocalHostNonce); + PushMessage("version", VERSION, nLocalServices, nTime, addrYou, addrMe, nLocalHostNonce, "linux-test5"); } ~CNode() @@ -557,11 +565,6 @@ private: public: - bool ReadyToDisconnect() - { - return fDisconnect || GetRefCount() <= 0; - } - int GetRefCount() { return max(nRefCount, 0) + (GetTime() < nReleaseTime ? 1 : 0); @@ -635,6 +638,8 @@ public: AbortMessage(); nPushPos = vSend.size(); vSend << CMessageHeader(pszCommand, 0); + if (fDebug) + printf("%s ", DateTimeStrFormat("%x %H:%M:%S", GetTime()).c_str()); printf("sending: %s ", pszCommand); } diff --git a/ui.cpp b/ui.cpp index e12970b81b..9d7556cb57 100644 --- a/ui.cpp +++ b/ui.cpp @@ -25,6 +25,7 @@ map mapAddressBook; bool fRandSendTest = false; void RandSend(); extern int g_isPainting; +bool fClosedToTray = false; // Settings int fShowGenerated = true; @@ -413,16 +414,17 @@ void Shutdown(void* parg) void CMainFrame::OnClose(wxCloseEvent& event) { - if (fMinimizeToTray && fMinimizeOnClose && event.CanVeto() && !IsIconized()) + if (fMinimizeOnClose && event.CanVeto() && !IsIconized()) { // Divert close to minimize event.Veto(); + fClosedToTray = true; Iconize(true); } else { Destroy(); - _beginthread(Shutdown, 0, NULL); + CreateThread(Shutdown, NULL); } } @@ -430,7 +432,16 @@ void CMainFrame::OnIconize(wxIconizeEvent& event) { // Hide the task bar button when minimized. // Event is sent when the frame is minimized or restored. - Show(!fMinimizeToTray || !event.Iconized()); + if (!event.Iconized()) + fClosedToTray = false; +#ifndef __WXMSW__ + // Tray is not reliable on Linux gnome + fClosedToTray = false; +#endif + if (fMinimizeToTray && event.Iconized()) + fClosedToTray = true; + Show(!fClosedToTray); + ptaskbaricon->Show(fMinimizeToTray || fClosedToTray); } void CMainFrame::OnMouseEvents(wxMouseEvent& event) @@ -527,7 +538,6 @@ bool CMainFrame::DeleteLine(uint256 hashKey) string FormatTxStatus(const CWalletTx& wtx) { // Status - int nDepth = wtx.GetDepthInMainChain(); if (!wtx.IsFinal()) { if (wtx.nLockTime < 500000000) @@ -535,10 +545,16 @@ string FormatTxStatus(const CWalletTx& wtx) else return strprintf("Open until %s", DateTimeStr(wtx.nLockTime).c_str()); } - else if (nDepth < 6) - return strprintf("%d/unconfirmed", nDepth); else - return strprintf("%d blocks", nDepth); + { + 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 blocks", nDepth); + } } string SingleLine(const string& strIn) @@ -629,9 +645,17 @@ bool CMainFrame::InsertTransaction(const CWalletTx& wtx, bool fNew, int nIndex) foreach(const CTxOut& txout, wtx.vout) nUnmatured += txout.GetCredit(); if (wtx.IsInMainChain()) - strDescription += strprintf(" (%s matures in %d more blocks)", FormatMoney(nUnmatured).c_str(), wtx.GetBlocksToMaturity()); + { + 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 += " (not accepted)"; + { + strDescription = "Generated (not accepted)"; + } } } else if (!mapValue["from"].empty() || !mapValue["message"].empty()) @@ -701,8 +725,11 @@ bool CMainFrame::InsertTransaction(const CWalletTx& wtx, bool fNew, int nIndex) strStatus, nTime ? DateTimeStr(nTime) : "", "Payment to yourself", - FormatMoney(nNet - nValue, true), - FormatMoney(nValue, true)); + "", + ""); + /// issue: can't tell which is the payment and which is the change anymore + // FormatMoney(nNet - nValue, true), + // FormatMoney(nValue, true)); } else if (fAllFromMe) { @@ -1028,6 +1055,9 @@ void CMainFrame::OnPaintListCtrl(wxPaintEvent& event) string strStatus = strprintf(" %d connections %d blocks %d transactions", vNodes.size(), nBestHeight + 1, nTransactionCount); m_statusBar->SetStatusText(strStatus, 2); + if (fDebug && GetTime() - nThreadSocketHandlerHeartbeat > 60) + m_statusBar->SetStatusText(" ERROR: ThreadSocketHandler has stopped", 0); + // Pass through to listctrl to actually do the paint, we're just hooking the message m_listCtrl->Disconnect(wxEVT_PAINT, (wxObjectEventFunction)NULL, NULL, this); m_listCtrl->GetEventHandler()->ProcessEvent(event); @@ -1237,7 +1267,19 @@ CTxDetailsDialog::CTxDetailsDialog(wxWindow* parent, CWalletTx wtx) : CTxDetails - strHTML += "Status: " + FormatTxStatus(wtx) + "
"; + strHTML += "Status: " + 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 += "
"; + strHTML += "Date: " + (nTime ? DateTimeStr(nTime) : "") + "
"; @@ -1366,9 +1408,10 @@ CTxDetailsDialog::CTxDetailsDialog(wxWindow* parent, CWalletTx wtx) : CTxDetails if (fAllToMe) { // Payment to self - int64 nValue = wtx.vout[0].nValue; - strHTML += "Debit: " + FormatMoney(-nValue) + "
"; - strHTML += "Credit: " + FormatMoney(nValue) + "
"; + /// issue: can't tell which is the payment and which is the change anymore + //int64 nValue = wtx.vout[0].nValue; + //strHTML += "Debit: " + FormatMoney(-nValue) + "
"; + //strHTML += "Credit: " + FormatMoney(nValue) + "
"; } int64 nTxFee = nDebit - wtx.GetValueOut(); @@ -1469,6 +1512,9 @@ COptionsDialog::COptionsDialog(wxWindow* parent) : COptionsDialogBase(parent) //m_listBox->Append("Test 2"); m_listBox->SetSelection(0); SelectPage(0); +#ifndef __WXMSW__ + m_checkBoxMinimizeOnClose->SetLabel("&Minimize on close"); +#endif // Init values m_textCtrlTransactionFee->SetValue(FormatMoney(nTransactionFee)); @@ -1481,9 +1527,7 @@ COptionsDialog::COptionsDialog(wxWindow* parent) : COptionsDialogBase(parent) m_spinCtrlLimitProcessors->SetRange(1, nProcessors); m_checkBoxStartOnSystemStartup->SetValue(fTmpStartOnSystemStartup = GetStartOnSystemStartup()); m_checkBoxMinimizeToTray->SetValue(fMinimizeToTray); - m_checkBoxMinimizeOnClose->Enable(fMinimizeToTray); - m_checkBoxMinimizeOnClose->SetValue(fMinimizeToTray && fMinimizeOnClose); - fTmpMinimizeOnClose = fMinimizeOnClose; + m_checkBoxMinimizeOnClose->SetValue(fMinimizeOnClose); m_checkBoxUseProxy->SetValue(fUseProxy); m_textCtrlProxyIP->Enable(fUseProxy); m_textCtrlProxyPort->Enable(fUseProxy); @@ -1521,22 +1565,6 @@ void COptionsDialog::OnCheckBoxLimitProcessors(wxCommandEvent& event) m_spinCtrlLimitProcessors->Enable(event.IsChecked()); } -void COptionsDialog::OnCheckBoxMinimizeToTray(wxCommandEvent& event) -{ - m_checkBoxMinimizeOnClose->Enable(event.IsChecked()); - - // Save the value in fTmpMinimizeOnClose so we can - // show the checkbox unchecked when its parent is unchecked - if (event.IsChecked()) - m_checkBoxMinimizeOnClose->SetValue(fTmpMinimizeOnClose); - else - { - fTmpMinimizeOnClose = m_checkBoxMinimizeOnClose->GetValue(); - m_checkBoxMinimizeOnClose->SetValue(false); - } - -} - void COptionsDialog::OnCheckBoxUseProxy(wxCommandEvent& event) { m_textCtrlProxyIP->Enable(event.IsChecked()); @@ -1608,12 +1636,12 @@ void COptionsDialog::OnButtonApply(wxCommandEvent& event) { fMinimizeToTray = m_checkBoxMinimizeToTray->GetValue(); walletdb.WriteSetting("fMinimizeToTray", fMinimizeToTray); - ptaskbaricon->Show(fMinimizeToTray); + ptaskbaricon->Show(fMinimizeToTray || fClosedToTray); } - if (fMinimizeOnClose != (fMinimizeToTray ? m_checkBoxMinimizeOnClose->GetValue() : fTmpMinimizeOnClose)) + if (fMinimizeOnClose != m_checkBoxMinimizeOnClose->GetValue()) { - fMinimizeOnClose = (fMinimizeToTray ? m_checkBoxMinimizeOnClose->GetValue() : fTmpMinimizeOnClose); + fMinimizeOnClose = m_checkBoxMinimizeOnClose->GetValue(); walletdb.WriteSetting("fMinimizeOnClose", fMinimizeOnClose); } @@ -1643,6 +1671,9 @@ CAboutDialog::CAboutDialog(wxWindow* parent) : CAboutDialogBase(parent) if (str.Find('Â') != wxNOT_FOUND) str.Remove(str.Find('Â'), 1); m_staticTextMain->SetLabel(str); +#ifndef __WXMSW__ + SetSize(510, 380); +#endif } void CAboutDialog::OnButtonOK(wxCommandEvent& event) @@ -1849,7 +1880,7 @@ CSendingDialog::CSendingDialog(wxWindow* parent, const CAddress& addrIn, int64 n SetTitle(strprintf("Sending %s to %s", FormatMoney(nPrice).c_str(), wtx.mapValue["to"].c_str())); m_textCtrlStatus->SetValue(""); - _beginthread(SendingDialogStartTransfer, 0, this); + CreateThread(SendingDialogStartTransfer, this); } CSendingDialog::~CSendingDialog() @@ -2856,7 +2887,7 @@ CViewProductDialog::CViewProductDialog(wxWindow* parent, const CProduct& product this->Layout(); // Request details from seller - _beginthread(ThreadRequestProductDetails, 0, new pair(product, GetEventHandler())); + CreateThread(ThreadRequestProductDetails, new pair(product, GetEventHandler())); } CViewProductDialog::~CViewProductDialog() @@ -3256,6 +3287,7 @@ void CEditReviewDialog::GetReview(CReview& review) enum { ID_TASKBAR_RESTORE = 10001, + ID_TASKBAR_OPTIONS, ID_TASKBAR_GENERATE, ID_TASKBAR_EXIT, }; @@ -3263,6 +3295,7 @@ enum BEGIN_EVENT_TABLE(CMyTaskBarIcon, wxTaskBarIcon) EVT_TASKBAR_LEFT_DCLICK(CMyTaskBarIcon::OnLeftButtonDClick) EVT_MENU(ID_TASKBAR_RESTORE, CMyTaskBarIcon::OnMenuRestore) + EVT_MENU(ID_TASKBAR_OPTIONS, CMyTaskBarIcon::OnMenuOptions) EVT_MENU(ID_TASKBAR_GENERATE, CMyTaskBarIcon::OnMenuGenerate) EVT_UPDATE_UI(ID_TASKBAR_GENERATE, CMyTaskBarIcon::OnUpdateUIGenerate) EVT_MENU(ID_TASKBAR_EXIT, CMyTaskBarIcon::OnMenuExit) @@ -3312,9 +3345,18 @@ void CMyTaskBarIcon::OnMenuRestore(wxCommandEvent& event) Restore(); } +void CMyTaskBarIcon::OnMenuOptions(wxCommandEvent& event) +{ + // Since it's modal, get the main window to do it + wxCommandEvent event2(wxEVT_COMMAND_MENU_SELECTED, wxID_MENUOPTIONSOPTIONS); + pframeMain->AddPendingEvent(event2); +} + void CMyTaskBarIcon::Restore() { pframeMain->Show(); + wxIconizeEvent event(0, false); + pframeMain->AddPendingEvent(event); pframeMain->Iconize(false); pframeMain->Raise(); } @@ -3344,6 +3386,7 @@ wxMenu* CMyTaskBarIcon::CreatePopupMenu() { wxMenu* pmenu = new wxMenu; pmenu->Append(ID_TASKBAR_RESTORE, "&Open Bitcoin"); + pmenu->Append(ID_TASKBAR_OPTIONS, "O&ptions..."); pmenu->AppendCheckItem(ID_TASKBAR_GENERATE, "&Generate Coins")->Check(fGenerateBitcoins); #ifndef __WXMAC_OSX__ // Mac has built-in quit menu pmenu->AppendSeparator(); @@ -3582,7 +3625,7 @@ bool CMyApp::OnInit2() { CBlockIndex* pindex = (*mi).second; CBlock block; - block.ReadFromDisk(pindex, true); + block.ReadFromDisk(pindex); block.BuildMerkleTree(); block.print(); printf("\n"); @@ -3632,20 +3675,20 @@ bool CMyApp::OnInit2() if (mapArgs.count("-min")) pframeMain->Iconize(true); pframeMain->Show(true); // have to show first to get taskbar button to hide - pframeMain->Show(!fMinimizeToTray || !pframeMain->IsIconized()); - ptaskbaricon->Show(fMinimizeToTray); + if (fMinimizeToTray && pframeMain->IsIconized()) + fClosedToTray = true; + pframeMain->Show(!fClosedToTray); + ptaskbaricon->Show(fMinimizeToTray || fClosedToTray); - _beginthread(ThreadDelayedRepaint, 0, NULL); + CreateThread(ThreadDelayedRepaint, NULL); if (!CheckDiskSpace()) return false; RandAddSeedPerfmon(); - if (!StartNode(strErrors)) - wxMessageBox(strErrors, "Bitcoin"); - - GenerateBitcoins(fGenerateBitcoins); + if (!CreateThread(StartNode, NULL)) + wxMessageBox("Error: CreateThread(StartNode) failed", "Bitcoin"); if (fFirstRun) SetStartOnSystemStartup(true); diff --git a/ui.h b/ui.h index a919c3668d..c4bf8b66f1 100644 --- a/ui.h +++ b/ui.h @@ -112,7 +112,6 @@ protected: void OnListBox(wxCommandEvent& event); void OnKillFocusTransactionFee(wxFocusEvent& event); void OnCheckBoxLimitProcessors(wxCommandEvent& event); - void OnCheckBoxMinimizeToTray(wxCommandEvent& event); void OnCheckBoxUseProxy(wxCommandEvent& event); void OnKillFocusProxy(wxFocusEvent& event); @@ -447,6 +446,7 @@ protected: // Event handlers void OnLeftButtonDClick(wxTaskBarIconEvent& event); void OnMenuRestore(wxCommandEvent& event); + void OnMenuOptions(wxCommandEvent& event); void OnUpdateUIGenerate(wxUpdateUIEvent& event); void OnMenuGenerate(wxCommandEvent& event); void OnMenuExit(wxCommandEvent& event); diff --git a/uibase.cpp b/uibase.cpp index 7bc8081f09..f05f1095fb 100644 --- a/uibase.cpp +++ b/uibase.cpp @@ -45,7 +45,7 @@ CMainFrameBase::CMainFrameBase( wxWindow* parent, wxWindowID id, const wxString& m_menuOptions->Append( m_menuOptionsChangeYourAddress ); wxMenuItem* m_menuOptionsOptions; - m_menuOptionsOptions = new wxMenuItem( m_menuOptions, wxID_ANY, wxString( wxT("&Options...") ) , wxEmptyString, wxITEM_NORMAL ); + m_menuOptionsOptions = new wxMenuItem( m_menuOptions, wxID_MENUOPTIONSOPTIONS, wxString( wxT("&Options...") ) , wxEmptyString, wxITEM_NORMAL ); m_menuOptions->Append( m_menuOptionsOptions ); m_menubar->Append( m_menuOptions, wxT("&Options") ); @@ -428,21 +428,13 @@ COptionsDialogBase::COptionsDialogBase( wxWindow* parent, wxWindowID id, const w bSizer69->Add( m_checkBoxStartOnSystemStartup, 0, wxALL, 5 ); - m_checkBoxMinimizeToTray = new wxCheckBox( m_panelMain, wxID_ANY, wxT("&Minimize to the system tray instead of the taskbar"), wxDefaultPosition, wxDefaultSize, 0 ); + m_checkBoxMinimizeToTray = new wxCheckBox( m_panelMain, wxID_ANY, wxT("&Minimize to the tray instead of the taskbar"), wxDefaultPosition, wxDefaultSize, 0 ); bSizer69->Add( m_checkBoxMinimizeToTray, 0, wxALL, 5 ); - wxBoxSizer* bSizer101; - bSizer101 = new wxBoxSizer( wxHORIZONTAL ); + m_checkBoxMinimizeOnClose = new wxCheckBox( m_panelMain, wxID_ANY, wxT("M&inimize to the tray on close"), wxDefaultPosition, wxDefaultSize, 0 ); - - bSizer101->Add( 16, 0, 0, 0, 5 ); - - m_checkBoxMinimizeOnClose = new wxCheckBox( m_panelMain, wxID_ANY, wxT("Mi&nimize to system tray on close"), wxDefaultPosition, wxDefaultSize, 0 ); - - bSizer101->Add( m_checkBoxMinimizeOnClose, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); - - bSizer69->Add( bSizer101, 1, wxEXPAND, 5 ); + bSizer69->Add( m_checkBoxMinimizeOnClose, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); wxBoxSizer* bSizer102; bSizer102 = new wxBoxSizer( wxHORIZONTAL ); diff --git a/uibase.h b/uibase.h index 2cb99e9a59..e0c152185c 100644 --- a/uibase.h +++ b/uibase.h @@ -43,51 +43,52 @@ #define wxID_MAINFRAME 1000 #define wxID_VIEWSHOWGENERATED 1001 #define wxID_OPTIONSGENERATEBITCOINS 1002 -#define wxID_BUTTONSEND 1003 -#define wxID_BUTTONRECEIVE 1004 -#define wxID_TEXTCTRLADDRESS 1005 -#define wxID_BUTTONCOPY 1006 -#define wxID_BUTTONCHANGE 1007 -#define wxID_TRANSACTIONFEE 1008 -#define wxID_PROXYIP 1009 -#define wxID_PROXYPORT 1010 -#define wxID_TEXTCTRLPAYTO 1011 -#define wxID_BUTTONPASTE 1012 -#define wxID_BUTTONADDRESSBOOK 1013 -#define wxID_TEXTCTRLAMOUNT 1014 -#define wxID_CHOICETRANSFERTYPE 1015 -#define wxID_LISTCTRL 1016 -#define wxID_BUTTONRENAME 1017 -#define wxID_BUTTONNEW 1018 -#define wxID_BUTTONEDIT 1019 -#define wxID_BUTTONDELETE 1020 -#define wxID_DEL0 1021 -#define wxID_DEL1 1022 -#define wxID_DEL2 1023 -#define wxID_DEL3 1024 -#define wxID_DEL4 1025 -#define wxID_DEL5 1026 -#define wxID_DEL6 1027 -#define wxID_DEL7 1028 -#define wxID_DEL8 1029 -#define wxID_DEL9 1030 -#define wxID_DEL10 1031 -#define wxID_DEL11 1032 -#define wxID_DEL12 1033 -#define wxID_DEL13 1034 -#define wxID_DEL14 1035 -#define wxID_DEL15 1036 -#define wxID_DEL16 1037 -#define wxID_DEL17 1038 -#define wxID_DEL18 1039 -#define wxID_DEL19 1040 -#define wxID_BUTTONPREVIEW 1041 -#define wxID_BUTTONSAMPLE 1042 -#define wxID_CANCEL2 1043 -#define wxID_BUTTONBACK 1044 -#define wxID_BUTTONNEXT 1045 -#define wxID_SUBMIT 1046 -#define wxID_TEXTCTRL 1047 +#define wxID_MENUOPTIONSOPTIONS 1003 +#define wxID_BUTTONSEND 1004 +#define wxID_BUTTONRECEIVE 1005 +#define wxID_TEXTCTRLADDRESS 1006 +#define wxID_BUTTONCOPY 1007 +#define wxID_BUTTONCHANGE 1008 +#define wxID_TRANSACTIONFEE 1009 +#define wxID_PROXYIP 1010 +#define wxID_PROXYPORT 1011 +#define wxID_TEXTCTRLPAYTO 1012 +#define wxID_BUTTONPASTE 1013 +#define wxID_BUTTONADDRESSBOOK 1014 +#define wxID_TEXTCTRLAMOUNT 1015 +#define wxID_CHOICETRANSFERTYPE 1016 +#define wxID_LISTCTRL 1017 +#define wxID_BUTTONRENAME 1018 +#define wxID_BUTTONNEW 1019 +#define wxID_BUTTONEDIT 1020 +#define wxID_BUTTONDELETE 1021 +#define wxID_DEL0 1022 +#define wxID_DEL1 1023 +#define wxID_DEL2 1024 +#define wxID_DEL3 1025 +#define wxID_DEL4 1026 +#define wxID_DEL5 1027 +#define wxID_DEL6 1028 +#define wxID_DEL7 1029 +#define wxID_DEL8 1030 +#define wxID_DEL9 1031 +#define wxID_DEL10 1032 +#define wxID_DEL11 1033 +#define wxID_DEL12 1034 +#define wxID_DEL13 1035 +#define wxID_DEL14 1036 +#define wxID_DEL15 1037 +#define wxID_DEL16 1038 +#define wxID_DEL17 1039 +#define wxID_DEL18 1040 +#define wxID_DEL19 1041 +#define wxID_BUTTONPREVIEW 1042 +#define wxID_BUTTONSAMPLE 1043 +#define wxID_CANCEL2 1044 +#define wxID_BUTTONBACK 1045 +#define wxID_BUTTONNEXT 1046 +#define wxID_SUBMIT 1047 +#define wxID_TEXTCTRL 1048 /////////////////////////////////////////////////////////////////////////////// /// Class CMainFrameBase @@ -203,7 +204,6 @@ class COptionsDialogBase : public wxDialog wxStaticText* m_staticText35; wxCheckBox* m_checkBoxStartOnSystemStartup; wxCheckBox* m_checkBoxMinimizeToTray; - wxCheckBox* m_checkBoxMinimizeOnClose; wxCheckBox* m_checkBoxUseProxy; diff --git a/uiproject.fbp b/uiproject.fbp index 3aa1c86bcf..58a99bddd8 100644 --- a/uiproject.fbp +++ b/uiproject.fbp @@ -70,7 +70,7 @@ - + 240,240,240 1 @@ -193,7 +193,7 @@ 0 1 - wxID_ANY + wxID_MENUOPTIONSOPTIONS wxITEM_NORMAL &Options... m_menuOptionsOptions @@ -2319,7 +2319,7 @@ 0 wxID_ANY - &Minimize to the system tray instead of the taskbar + &Minimize to the tray instead of the taskbar m_checkBoxMinimizeToTray @@ -2360,75 +2360,54 @@ 5 - wxEXPAND - 1 - + wxALL|wxALIGN_CENTER_VERTICAL + 0 + + + 0 + + 1 + + + 0 + wxID_ANY + M&inimize to the tray on close + - bSizer101 - wxHORIZONTAL - none - - 5 - - 0 - - 0 - protected - 16 - - - - 5 - wxALL|wxALIGN_CENTER_VERTICAL - 0 - - - 0 - - 1 - - - 0 - wxID_ANY - Mi&nimize to system tray on close - - - m_checkBoxMinimizeOnClose - protected - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + m_checkBoxMinimizeOnClose + protected + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/util.cpp b/util.cpp index 4a5b983d22..7a947730ce 100644 --- a/util.cpp +++ b/util.cpp @@ -85,14 +85,14 @@ void RandAddSeed() void RandAddSeedPerfmon() { -#ifdef __WXMSW__ - // Don't need this on Linux, OpenSSL automatically uses /dev/urandom // This can take up to 2 seconds, so only do it every 10 minutes static int64 nLastPerfmon; if (GetTime() < nLastPerfmon + 10 * 60) return; nLastPerfmon = GetTime(); +#ifdef __WXMSW__ + // Don't need this on Linux, OpenSSL automatically uses /dev/urandom // Seed with the entire set of perfmon data unsigned char pdata[250000]; memset(pdata, 0, sizeof(pdata)); @@ -109,9 +109,30 @@ void RandAddSeedPerfmon() printf("%s RandAddSeed() %d bytes\n", DateTimeStrFormat("%x %H:%M:%S", GetTime()).c_str(), nSize); } +#else + printf("%s RandAddSeed()\n", DateTimeStrFormat("%x %H:%M:%S", GetTime()).c_str()); #endif } +uint64 GetRand(uint64 nMax) +{ + if (nMax == 0) + return 0; + + // The range of the random source must be a multiple of the modulus + // to give every possible output value an equal possibility + uint64 nRange = (UINT64_MAX / nMax) * nMax; + uint64 nRand = 0; + do + RAND_bytes((unsigned char*)&nRand, sizeof(nRand)); + while (nRand >= nRange); + return (nRand % nMax); +} + + + + + @@ -449,28 +470,6 @@ string GetDataDir() -uint64 GetRand(uint64 nMax) -{ - if (nMax == 0) - return 0; - - // The range of the random source must be a multiple of the modulus - // to give every possible output value an equal possibility - uint64 nRange = (_UI64_MAX / nMax) * nMax; - uint64 nRand = 0; - do - RAND_bytes((unsigned char*)&nRand, sizeof(nRand)); - while (nRand >= nRange); - return (nRand % nMax); -} - - - - - - - - // @@ -483,7 +482,6 @@ uint64 GetRand(uint64 nMax) // note: NTP isn't implemented yet, so until then we just use the median // of other nodes clocks to correct ours. // - int64 GetTime() { return time(NULL); diff --git a/util.h b/util.h index 8fcfcd0dc9..ddac449441 100644 --- a/util.h +++ b/util.h @@ -54,9 +54,13 @@ inline T& REF(const T& val) return (T&)val; } -#ifndef __WXMSW__ -#define _UI64_MAX UINT64_MAX -#define _I64_MAX INT64_MAX +#ifdef __WXMSW__ +#define MSG_NOSIGNAL 0 +#define MSG_DONTWAIT 0 +#define UINT64_MAX _UI64_MAX +#define INT64_MAX _I64_MAX +#define INT64_MIN _I64_MIN +#else #define WSAGetLastError() errno #define WSAEWOULDBLOCK EWOULDBLOCK #define WSAEMSGSIZE EMSGSIZE @@ -74,18 +78,6 @@ typedef u_int SOCKET; #define MAX_PATH 1024 #define Sleep(n) wxMilliSleep(n) #define Beep(n1,n2) (0) -inline int _beginthread(void(*pfn)(void*), unsigned nStack, void* parg) { thread(bind(pfn, parg)); return 0; } -inline void _endthread() { pthread_exit(NULL); } -inline int GetCurrentThread() { return 0; } -// threads are processes on linux, so setpriority affects just the one thread -inline void SetThreadPriority(int nThread, int nPriority) { setpriority(PRIO_PROCESS, getpid(), nPriority); } -#define THREAD_PRIORITY_LOWEST PRIO_MIN -#define THREAD_PRIORITY_BELOW_NORMAL 2 -#define THREAD_PRIORITY_NORMAL 0 -#define THREAD_PRIORITY_ABOVE_NORMAL 0 -#endif -#ifndef MSG_NOSIGNAL -#define MSG_NOSIGNAL 0 #endif @@ -133,6 +125,7 @@ void AddTimeData(unsigned int ip, int64 nTime); + // Wrapper to automatically initialize critical sections class CCriticalSection { @@ -201,8 +194,6 @@ public: - - inline int OutputDebugStringF(const char* pszFormat, ...) { int ret = 0; @@ -498,3 +489,83 @@ inline uint160 Hash160(const vector& vch) RIPEMD160((unsigned char*)&hash1, sizeof(hash1), (unsigned char*)&hash2); return hash2; } + + + + + + + + + + + +// Note: It turns out we might have been able to use boost::thread +// by using TerminateThread(boost::thread.native_handle(), 0); +#ifdef __WXMSW__ +typedef HANDLE pthread_t; + +inline pthread_t CreateThread(void(*pfn)(void*), void* parg, bool fWantHandle=false) +{ + DWORD nUnused = 0; + HANDLE hthread = + CreateThread( + NULL, // default security + 0, // inherit stack size from parent + (LPTHREAD_START_ROUTINE)pfn, // function pointer + parg, // argument + 0, // creation option, start immediately + &nUnused); // thread identifier + if (hthread == NULL) + { + printf("Error: CreateThread() returned %d\n", GetLastError()); + return (pthread_t)0; + } + if (!fWantHandle) + { + CloseHandle(hthread); + return (pthread_t)-1; + } + return hthread; +} + +inline void SetThreadPriority(int nPriority) +{ + SetThreadPriority(GetCurrentThread(), nPriority); +} +#else +inline pthread_t CreateThread(void(*pfn)(void*), void* parg, bool fWantHandle=false) +{ + pthread_t hthread = 0; + int ret = pthread_create(&hthread, NULL, (void*(*)(void*))pfn, parg); + if (ret != 0) + { + printf("Error: pthread_create() returned %d\n", ret); + return (pthread_t)0; + } + if (!fWantHandle) + return (pthread_t)-1; + return hthread; +} + +#define THREAD_PRIORITY_LOWEST PRIO_MIN +#define THREAD_PRIORITY_BELOW_NORMAL 2 +#define THREAD_PRIORITY_NORMAL 0 +#define THREAD_PRIORITY_ABOVE_NORMAL 0 + +inline void SetThreadPriority(int nPriority) +{ + // threads are processes on linux, so PRIO_PROCESS affects just the one thread + setpriority(PRIO_PROCESS, getpid(), nPriority); +} + +inline bool TerminateThread(pthread_t hthread, unsigned int nExitCode) +{ + return (pthread_cancel(hthread) == 0); +} + +inline void ExitThread(unsigned int nExitCode) +{ + pthread_exit((void*)nExitCode); +} +#endif -- cgit v1.2.3 From 70e79525c97c33a5fca8674d47d86cc2b7ae197a Mon Sep 17 00:00:00 2001 From: s_nakamoto Date: Fri, 13 Nov 2009 01:23:08 +0000 Subject: monitor ThreadSocketHandler and terminate and restart if hung, convert _beginthread to CreateThread wrapper, disconnect inactive connections, ping, break up long messages to speed up initial download, better priorities for initiating connections, track how many nodes have requested our blocks and transactions, status #/offline and warning message on unsent blocks, minimize on close as separate option -- linux-test5 git-svn-id: https://bitcoin.svn.sourceforge.net/svnroot/bitcoin/trunk@38 1a98c847-1fd6-4fd8-948a-caf3550aa51b --- build-msw.txt | 2 +- build-unix.txt | 1 + db.cpp | 9 +- headers.h | 1 - irc.cpp | 5 +- main.cpp | 144 ++++++++++++++++++++---- main.h | 25 +++-- net.cpp | 342 +++++++++++++++++++++++++++++++++++++-------------------- net.h | 25 +++-- ui.cpp | 137 +++++++++++++++-------- ui.h | 2 +- uibase.cpp | 16 +-- uibase.h | 92 ++++++++-------- uiproject.fbp | 121 +++++++++----------- util.cpp | 48 ++++---- util.h | 105 +++++++++++++++--- 16 files changed, 684 insertions(+), 391 deletions(-) diff --git a/build-msw.txt b/build-msw.txt index eb6348bada..a159a71aeb 100644 --- a/build-msw.txt +++ b/build-msw.txt @@ -8,7 +8,7 @@ the OpenSSL Toolkit (http://www.openssl.org/). This product includes cryptographic software written by Eric Young (eay@cryptsoft.com). - WINDOWS BUILD NOTES +WINDOWS BUILD NOTES Compilers Supported diff --git a/build-unix.txt b/build-unix.txt index 6b29e1e5c4..ceb61ad545 100644 --- a/build-unix.txt +++ b/build-unix.txt @@ -13,6 +13,7 @@ UNIX BUILD NOTES Dependencies ------------ +Install the dev files for the shared libraries: apt-get install build-essential apt-get install libgtk2.0-dev apt-get install libssl-dev diff --git a/db.cpp b/db.cpp index 61d6025332..a9c42880ab 100644 --- a/db.cpp +++ b/db.cpp @@ -505,6 +505,13 @@ bool CWalletDB::LoadWallet(vector& vchDefaultKeyRet) { vchDefaultKeyRet.clear(); + // Modify defaults +#ifndef __WXMSW__ + // Reports that tray icon can disappear on gnome, leaving no way to access the program + fMinimizeToTray = false; + fMinimizeOnClose = false; +#endif + //// todo: shouldn't we catch exceptions and try to recover and continue? CRITICAL_BLOCK(cs_mapKeys) CRITICAL_BLOCK(cs_mapWallet) @@ -638,7 +645,7 @@ bool LoadWallet(bool& fFirstRunRet) CWalletDB().WriteDefaultKey(keyUser.GetPubKey()); } - _beginthread(ThreadFlushWalletDB, 0, NULL); + CreateThread(ThreadFlushWalletDB, NULL); return true; } diff --git a/headers.h b/headers.h index 76881bb935..22bb830f72 100644 --- a/headers.h +++ b/headers.h @@ -75,7 +75,6 @@ #include #include #include -#include #include #endif diff --git a/irc.cpp b/irc.cpp index 3b232caead..8432c6d145 100644 --- a/irc.cpp +++ b/irc.cpp @@ -54,7 +54,7 @@ static bool Send(SOCKET hSocket, const char* pszSend) const char* pszEnd = psz + strlen(psz); while (psz < pszEnd) { - int ret = send(hSocket, psz, pszEnd - psz, 0); + int ret = send(hSocket, psz, pszEnd - psz, MSG_NOSIGNAL); if (ret < 0) return false; psz += ret; @@ -156,7 +156,7 @@ bool Wait(int nSeconds) void ThreadIRCSeed(void* parg) { - SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_NORMAL); + SetThreadPriority(THREAD_PRIORITY_NORMAL); int nErrorWait = 10; int nRetryWait = 10; @@ -256,6 +256,7 @@ void ThreadIRCSeed(void* parg) CAddress addr; if (DecodeAddress(pszName, addr)) { + addr.nTime = GetAdjustedTime() - 51 * 60; CAddrDB addrdb; if (AddAddress(addrdb, addr)) printf("IRC got new address\n"); diff --git a/main.cpp b/main.cpp index b957027f07..13a9f9b72a 100644 --- a/main.cpp +++ b/main.cpp @@ -42,6 +42,9 @@ map > mapPubKeys; CCriticalSection cs_mapKeys; CKey keyUser; +map mapRequestCount; +CCriticalSection cs_mapRequestCount; + // Settings int fGenerateBitcoins = false; int64 nTransactionFee = 0; @@ -274,7 +277,44 @@ int64 CWalletTx::GetTxTime() const return nTimeReceived; } +int CWalletTx::GetRequestCount() const +{ + // Returns -1 if it wasn't being tracked + int nRequests = -1; + CRITICAL_BLOCK(cs_mapRequestCount) + { + if (IsCoinBase()) + { + // Generated block + if (hashBlock != 0) + { + map::iterator mi = mapRequestCount.find(hashBlock); + if (mi != mapRequestCount.end()) + nRequests = (*mi).second; + } + } + else + { + // Did anyone request this transaction? + map::iterator mi = mapRequestCount.find(GetHash()); + if (mi != mapRequestCount.end()) + { + nRequests = (*mi).second; + // How about the block it's in? + if (nRequests == 0 && hashBlock != 0) + { + map::iterator mi = mapRequestCount.find(hashBlock); + if (mi != mapRequestCount.end()) + nRequests = (*mi).second; + else + nRequests = 1; // If it's in someone else's block it must have got out + } + } + } + } + return nRequests; +} @@ -295,7 +335,7 @@ int CMerkleTx::SetMerkleBranch(const CBlock* pblock) CTxIndex txindex; if (!CTxDB("r").ReadTxIndex(GetHash(), txindex)) return 0; - if (!blockTmp.ReadFromDisk(txindex.pos.nFile, txindex.pos.nBlockPos, true)) + if (!blockTmp.ReadFromDisk(txindex.pos.nFile, txindex.pos.nBlockPos)) return 0; pblock = &blockTmp; } @@ -1003,7 +1043,7 @@ bool Reorganize(CTxDB& txdb, CBlockIndex* pindexNew) foreach(CBlockIndex* pindex, vDisconnect) { CBlock block; - if (!block.ReadFromDisk(pindex->nFile, pindex->nBlockPos, true)) + if (!block.ReadFromDisk(pindex->nFile, pindex->nBlockPos)) return error("Reorganize() : ReadFromDisk for disconnect failed"); if (!block.DisconnectBlock(txdb, pindex)) return error("Reorganize() : DisconnectBlock failed"); @@ -1020,7 +1060,7 @@ bool Reorganize(CTxDB& txdb, CBlockIndex* pindexNew) { CBlockIndex* pindex = vConnect[i]; CBlock block; - if (!block.ReadFromDisk(pindex->nFile, pindex->nBlockPos, true)) + if (!block.ReadFromDisk(pindex->nFile, pindex->nBlockPos)) return error("Reorganize() : ReadFromDisk for connect failed"); if (!block.ConnectBlock(txdb, pindex)) { @@ -1380,7 +1420,7 @@ bool CheckDiskSpace(int64 nAdditionalBytes) { fShutdown = true; ThreadSafeMessageBox("Warning: Your disk space is low ", "Bitcoin", wxOK | wxICON_EXCLAMATION); - _beginthread(Shutdown, 0, NULL); + CreateThread(Shutdown, NULL); return false; } return true; @@ -1547,7 +1587,7 @@ void PrintBlockTree() // print item CBlock block; - block.ReadFromDisk(pindex, true); + block.ReadFromDisk(pindex); printf("%d (%u,%u) %s %s tx %d", pindex->nHeight, pindex->nFile, @@ -1623,7 +1663,8 @@ bool ProcessMessages(CNode* pfrom) CDataStream& vRecv = pfrom->vRecv; if (vRecv.empty()) return true; - //printf("ProcessMessages(%d bytes)\n", vRecv.size()); + //if (fDebug) + // printf("ProcessMessages(%d bytes)\n", vRecv.size()); // // Message format @@ -1666,7 +1707,8 @@ bool ProcessMessages(CNode* pfrom) { // Rewind and wait for rest of message ///// need a mechanism to give up waiting for overlong message size error - //printf("message-break\n"); + //if (fDebug) + // printf("message-break\n"); vRecv.insert(vRecv.begin(), BEGIN(hdr), END(hdr)); Sleep(100); break; @@ -1718,6 +1760,8 @@ bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) { static map > mapReuseKey; RandAddSeedPerfmon(); + if (fDebug) + printf("%s ", DateTimeStrFormat("%x %H:%M:%S", GetTime()).c_str()); printf("received: %s (%d bytes)\n", strCommand.c_str(), vRecv.size()); if (mapArgs.count("-dropmessagestest") && GetRand(atoi(mapArgs["-dropmessagestest"])) == 0) { @@ -1739,18 +1783,19 @@ bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) CAddress addrMe; CAddress addrFrom; uint64 nNonce = 1; + string strSubVer; vRecv >> pfrom->nVersion >> pfrom->nServices >> nTime >> addrMe; if (pfrom->nVersion >= 106 && !vRecv.empty()) vRecv >> addrFrom >> nNonce; + if (pfrom->nVersion >= 106 && !vRecv.empty()) + vRecv >> strSubVer; if (pfrom->nVersion == 0) return false; // Disconnect if we connected to ourself - if (nNonce == nLocalHostNonce) + if (nNonce == nLocalHostNonce && nNonce > 1) { pfrom->fDisconnect = true; - pfrom->vRecv.clear(); - pfrom->vSend.clear(); return true; } @@ -1776,10 +1821,6 @@ bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) pfrom->fSuccessfullyConnected = true; - // Update the last seen time - if (pfrom->fNetworkNode) - AddressCurrentlyConnected(pfrom->addr); - printf("version message: version %d\n", pfrom->nVersion); } @@ -1824,10 +1865,6 @@ bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) vector vInv; vRecv >> vInv; - // Update the last seen time for this node's address - if (pfrom->fNetworkNode) - AddressCurrentlyConnected(pfrom->addr); - CTxDB txdb("r"); foreach(const CInv& inv, vInv) { @@ -1842,6 +1879,14 @@ bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) pfrom->AskFor(inv); else if (inv.type == MSG_BLOCK && mapOrphanBlocks.count(inv.hash)) pfrom->PushMessage("getblocks", CBlockLocator(pindexBest), GetOrphanRoot(mapOrphanBlocks[inv.hash])); + + // Track requests for our stuff + CRITICAL_BLOCK(cs_mapRequestCount) + { + map::iterator mi = mapRequestCount.find(inv.hash); + if (mi != mapRequestCount.end()) + (*mi).second++; + } } } @@ -1879,6 +1924,14 @@ bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) pfrom->PushMessage(inv.GetCommand(), (*mi).second); } } + + // Track requests for our stuff + CRITICAL_BLOCK(cs_mapRequestCount) + { + map::iterator mi = mapRequestCount.find(inv.hash); + if (mi != mapRequestCount.end()) + (*mi).second++; + } } } @@ -2086,11 +2139,23 @@ bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) } + else if (strCommand == "ping") + { + } + + else { // Ignore unknown commands for extensibility } + + // Update the last seen time for this node's address + if (pfrom->fNetworkNode) + if (strCommand == "version" || strCommand == "addr" || strCommand == "inv" || strCommand == "getdata" || strCommand == "ping") + AddressCurrentlyConnected(pfrom->addr); + + return true; } @@ -2129,6 +2194,10 @@ bool SendMessages(CNode* pto) } } + // Keep-alive ping + if (pto->nLastSend && GetTime() - pto->nLastSend > 12 * 60 && pto->vSend.empty()) + pto->PushMessage("ping"); + // // Message: addr @@ -2139,7 +2208,14 @@ bool SendMessages(CNode* pto) { // returns true if wasn't already contained in the set if (pto->setAddrKnown.insert(addr).second) + { vAddrToSend.push_back(addr); + if (vAddrToSend.size() >= 1000) + { + pto->PushMessage("addr", vAddrToSend); + vAddrToSend.clear(); + } + } } pto->vAddrToSend.clear(); if (!vAddrToSend.empty()) @@ -2157,7 +2233,14 @@ bool SendMessages(CNode* pto) { // returns true if wasn't already contained in the set if (pto->setInventoryKnown.insert(inv).second) + { vInventoryToSend.push_back(inv); + if (vInventoryToSend.size() >= 1000) + { + pto->PushMessage("inv", vInventoryToSend); + vInventoryToSend.clear(); + } + } } pto->vInventoryToSend.clear(); pto->setInventoryKnown2.clear(); @@ -2179,6 +2262,11 @@ bool SendMessages(CNode* pto) { printf("sending getdata: %s\n", inv.ToString().c_str()); vAskFor.push_back(inv); + if (vAskFor.size() >= 1000) + { + pto->PushMessage("getdata", vAskFor); + vAskFor.clear(); + } } pto->mapAskFor.erase(pto->mapAskFor.begin()); } @@ -2226,8 +2314,8 @@ void GenerateBitcoins(bool fGenerate) int nAddThreads = nProcessors - vnThreadsRunning[3]; printf("Starting %d BitcoinMiner threads\n", nAddThreads); for (int i = 0; i < nAddThreads; i++) - if (_beginthread(ThreadBitcoinMiner, 0, NULL) == -1) - printf("Error: _beginthread(ThreadBitcoinMiner) failed\n"); + if (!CreateThread(ThreadBitcoinMiner, NULL)) + printf("Error: CreateThread(ThreadBitcoinMiner) failed\n"); } } @@ -2304,7 +2392,7 @@ void BitcoinMiner() CBigNum bnExtraNonce = 0; while (fGenerateBitcoins) { - SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_LOWEST); + SetThreadPriority(THREAD_PRIORITY_LOWEST); Sleep(50); if (fShutdown) return; @@ -2440,7 +2528,7 @@ void BitcoinMiner() printf("proof-of-work found \n hash: %s \ntarget: %s\n", hash.GetHex().c_str(), hashTarget.GetHex().c_str()); pblock->print(); - SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_NORMAL); + SetThreadPriority(THREAD_PRIORITY_NORMAL); CRITICAL_BLOCK(cs_main) { if (pindexPrev == pindexBest) @@ -2450,12 +2538,16 @@ void BitcoinMiner() return; key.MakeNewKey(); + // Track how many getdata requests this block gets + CRITICAL_BLOCK(cs_mapRequestCount) + mapRequestCount[pblock->GetHash()] = 0; + // Process this block the same as if we had received it from another node if (!ProcessBlock(NULL, pblock.release())) printf("ERROR in BitcoinMiner, ProcessBlock, block not accepted\n"); } } - SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_LOWEST); + SetThreadPriority(THREAD_PRIORITY_LOWEST); Sleep(500); break; @@ -2534,7 +2626,7 @@ bool SelectCoins(int64 nTargetValue, set& setCoinsRet) setCoinsRet.clear(); // List of values less than target - int64 nLowestLarger = _I64_MAX; + int64 nLowestLarger = INT64_MAX; CWalletTx* pcoinLowestLarger = NULL; vector > vValue; int64 nTotalLower = 0; @@ -2777,6 +2869,10 @@ bool SendMoney(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew) return error("SendMoney() : Error finalizing transaction"); } + // Track how many getdata requests our transaction gets + CRITICAL_BLOCK(cs_mapRequestCount) + mapRequestCount[wtxNew.GetHash()] = 0; + printf("SendMoney: %s\n", wtxNew.GetHash().ToString().substr(0,6).c_str()); // Broadcast diff --git a/main.h b/main.h index 853fdfa5b6..8bb1e19e8a 100644 --- a/main.h +++ b/main.h @@ -34,6 +34,8 @@ extern int nBestHeight; extern uint256 hashBestChain; extern CBlockIndex* pindexBest; extern unsigned int nTransactionsUpdated; +extern map mapRequestCount; +extern CCriticalSection cs_mapRequestCount; // Settings extern int fGenerateBitcoins; @@ -647,6 +649,15 @@ public: nGetCreditCached = 0; } + IMPLEMENT_SERIALIZE + ( + nSerSize += SerReadWrite(s, *(CTransaction*)this, nType, nVersion, ser_action); + nVersion = this->nVersion; + READWRITE(hashBlock); + READWRITE(vMerkleBranch); + READWRITE(nIndex); + ) + int64 GetCredit(bool fUseCache=false) const { // Must wait until coinbase is safely deep enough in the chain before valuing it @@ -661,15 +672,6 @@ public: return nGetCreditCached; } - IMPLEMENT_SERIALIZE - ( - nSerSize += SerReadWrite(s, *(CTransaction*)this, nType, nVersion, ser_action); - nVersion = this->nVersion; - READWRITE(hashBlock); - READWRITE(vMerkleBranch); - READWRITE(nIndex); - ) - int SetMerkleBranch(const CBlock* pblock=NULL); int GetDepthInMainChain() const; @@ -749,6 +751,7 @@ public: int64 GetTxTime() const; + int GetRequestCount() const; void AddSupportingTransactions(CTxDB& txdb); @@ -978,7 +981,7 @@ public: return true; } - bool ReadFromDisk(unsigned int nFile, unsigned int nBlockPos, bool fReadTransactions) + bool ReadFromDisk(unsigned int nFile, unsigned int nBlockPos, bool fReadTransactions=true) { SetNull(); @@ -1027,7 +1030,7 @@ public: int64 GetBlockValue(int64 nFees) const; bool DisconnectBlock(CTxDB& txdb, CBlockIndex* pindex); bool ConnectBlock(CTxDB& txdb, CBlockIndex* pindex); - bool ReadFromDisk(const CBlockIndex* blockindex, bool fReadTransactions); + bool ReadFromDisk(const CBlockIndex* blockindex, bool fReadTransactions=true); bool AddToBlockIndex(unsigned int nFile, unsigned int nBlockPos); bool CheckBlock() const; bool AcceptBlock(); diff --git a/net.cpp b/net.cpp index 0569604bab..71295d5dee 100644 --- a/net.cpp +++ b/net.cpp @@ -13,7 +13,6 @@ bool OpenNetworkConnection(const CAddress& addrConnect); - // // Global state variables // @@ -25,6 +24,7 @@ uint64 nLocalHostNonce = 0; bool fShutdown = false; array vnThreadsRunning; SOCKET hListenSocket = INVALID_SOCKET; +int64 nThreadSocketHandlerHeartbeat = INT64_MAX; vector vNodes; CCriticalSection cs_vNodes; @@ -65,7 +65,7 @@ bool ConnectSocket(const CAddress& addrConnect, SOCKET& hSocketRet) if (fProxy) { - printf("Proxy connecting %s\n", addrConnect.ToStringLog().c_str()); + printf("proxy connecting %s\n", addrConnect.ToStringLog().c_str()); char pszSocks4IP[] = "\4\1\0\0\0\0\0\0user"; memcpy(pszSocks4IP + 2, &addrConnect.port, 2); memcpy(pszSocks4IP + 4, &addrConnect.ip, 4); @@ -87,9 +87,11 @@ bool ConnectSocket(const CAddress& addrConnect, SOCKET& hSocketRet) if (pchRet[1] != 0x5a) { closesocket(hSocket); - return error("Proxy returned error %d", pchRet[1]); + if (pchRet[1] != 0x5b) + printf("ERROR: Proxy returned error %d\n", pchRet[1]); + return false; } - printf("Proxy connection established %s\n", addrConnect.ToStringLog().c_str()); + printf("proxy connected %s\n", addrConnect.ToStringLog().c_str()); } hSocketRet = hSocket; @@ -219,6 +221,7 @@ bool AddAddress(CAddrDB& addrdb, CAddress addr, bool fCurrentlyOnline) if (it == mapAddresses.end()) { // New address + printf("AddAddress(%s)\n", addr.ToStringLog().c_str()); mapAddresses.insert(make_pair(addr.GetKey(), addr)); addrdb.WriteAddress(addr); return true; @@ -256,7 +259,7 @@ void AddressCurrentlyConnected(const CAddress& addr) if (it != mapAddresses.end()) { CAddress& addrFound = (*it).second; - int64 nUpdateInterval = 60 * 60; + int64 nUpdateInterval = 20 * 60; if (addrFound.nTime < GetAdjustedTime() - nUpdateInterval) { // Periodically update most recently seen time @@ -417,7 +420,13 @@ CNode* ConnectNode(CAddress addrConnect, int64 nTimeout) } /// debug print - printf("trying connection %s\n", addrConnect.ToStringLog().c_str()); + printf("trying connection %s lastseen=%.1fhrs lasttry=%.1fhrs\n", + addrConnect.ToStringLog().c_str(), + (double)(addrConnect.nTime - GetAdjustedTime())/3600.0, + (double)(addrConnect.nLastTry - GetAdjustedTime())/3600.0); + + CRITICAL_BLOCK(cs_mapAddresses) + mapAddresses[addrConnect.GetKey()].nLastTry = GetAdjustedTime(); // Connect SOCKET hSocket; @@ -428,7 +437,7 @@ CNode* ConnectNode(CAddress addrConnect, int64 nTimeout) // Set to nonblocking #ifdef __WXMSW__ - u_long nOne = 1; + u_long nOne = 1; if (ioctlsocket(hSocket, FIONBIO, &nOne) == SOCKET_ERROR) printf("ConnectSocket() : ioctlsocket nonblocking setting failed, error %d\n", WSAGetLastError()); #else @@ -445,29 +454,23 @@ CNode* ConnectNode(CAddress addrConnect, int64 nTimeout) CRITICAL_BLOCK(cs_vNodes) vNodes.push_back(pnode); - CRITICAL_BLOCK(cs_mapAddresses) - mapAddresses[addrConnect.GetKey()].nLastFailed = 0; + pnode->nTimeConnected = GetTime(); return pnode; } else { - CRITICAL_BLOCK(cs_mapAddresses) - mapAddresses[addrConnect.GetKey()].nLastFailed = GetAdjustedTime(); return NULL; } } void CNode::DoDisconnect() { + if (fDebug) + printf("%s ", DateTimeStrFormat("%x %H:%M:%S", GetTime()).c_str()); printf("disconnecting node %s\n", addr.ToStringLog().c_str()); closesocket(hSocket); - // If outbound and never got version message, mark address as failed - if (!fInbound && !fSuccessfullyConnected) - CRITICAL_BLOCK(cs_mapAddresses) - mapAddresses[addr.GetKey()].nLastFailed = GetAdjustedTime(); - // All of a nodes broadcasts and subscriptions are automatically torn down // when it goes down, so a node has to stay up to keep its broadcast going. @@ -508,7 +511,7 @@ void ThreadSocketHandler(void* parg) PrintException(&e, "ThreadSocketHandler()"); } catch (...) { vnThreadsRunning[0]--; - PrintException(NULL, "ThreadSocketHandler()"); + throw; // support pthread_cancel() } printf("ThreadSocketHandler exiting\n"); @@ -531,15 +534,18 @@ void ThreadSocketHandler2(void* parg) vector vNodesCopy = vNodes; foreach(CNode* pnode, vNodesCopy) { - if (pnode->ReadyToDisconnect() && pnode->vRecv.empty() && pnode->vSend.empty()) + if (pnode->fDisconnect || + (pnode->GetRefCount() <= 0 && pnode->vRecv.empty() && pnode->vSend.empty())) { // remove from vNodes vNodes.erase(remove(vNodes.begin(), vNodes.end(), pnode), vNodes.end()); + + // close socket pnode->DoDisconnect(); // hold in disconnected pool until all refs are released pnode->nReleaseTime = max(pnode->nReleaseTime, GetTime() + 5 * 60); - if (pnode->fNetworkNode) + if (pnode->fNetworkNode || pnode->fInbound) pnode->Release(); vNodesDisconnected.push_back(pnode); } @@ -582,8 +588,10 @@ void ThreadSocketHandler2(void* parg) fd_set fdsetRecv; fd_set fdsetSend; + fd_set fdsetError; FD_ZERO(&fdsetRecv); FD_ZERO(&fdsetSend); + FD_ZERO(&fdsetError); SOCKET hSocketMax = 0; FD_SET(hListenSocket, &fdsetRecv); hSocketMax = max(hSocketMax, hListenSocket); @@ -592,6 +600,7 @@ void ThreadSocketHandler2(void* parg) foreach(CNode* pnode, vNodes) { FD_SET(pnode->hSocket, &fdsetRecv); + FD_SET(pnode->hSocket, &fdsetError); hSocketMax = max(hSocketMax, pnode->hSocket); TRY_CRITICAL_BLOCK(pnode->cs_vSend) if (!pnode->vSend.empty()) @@ -600,30 +609,21 @@ void ThreadSocketHandler2(void* parg) } vnThreadsRunning[0]--; - int nSelect = select(hSocketMax + 1, &fdsetRecv, &fdsetSend, NULL, &timeout); + int nSelect = select(hSocketMax + 1, &fdsetRecv, &fdsetSend, &fdsetError, &timeout); vnThreadsRunning[0]++; if (fShutdown) return; if (nSelect == SOCKET_ERROR) { int nErr = WSAGetLastError(); - printf("select failed: %d\n", nErr); + printf("socket select error %d\n", nErr); for (int i = 0; i <= hSocketMax; i++) - { FD_SET(i, &fdsetRecv); - FD_SET(i, &fdsetSend); - } + FD_ZERO(&fdsetSend); + FD_ZERO(&fdsetError); Sleep(timeout.tv_usec/1000); } - //// debug print - //foreach(CNode* pnode, vNodes) - //{ - // printf("vRecv = %-5d ", pnode->vRecv.size()); - // printf("vSend = %-5d ", pnode->vSend.size()); - //} - //printf("\n"); - // // Accept new connections @@ -641,7 +641,7 @@ void ThreadSocketHandler2(void* parg) if (hSocket == INVALID_SOCKET) { if (WSAGetLastError() != WSAEWOULDBLOCK) - printf("ERROR ThreadSocketHandler accept failed: %d\n", WSAGetLastError()); + printf("socket error accept failed: %d\n", WSAGetLastError()); } else { @@ -669,7 +669,7 @@ void ThreadSocketHandler2(void* parg) // // Receive // - if (FD_ISSET(hSocket, &fdsetRecv)) + if (FD_ISSET(hSocket, &fdsetRecv) || FD_ISSET(hSocket, &fdsetError)) { TRY_CRITICAL_BLOCK(pnode->cs_vRecv) { @@ -677,25 +677,29 @@ void ThreadSocketHandler2(void* parg) unsigned int nPos = vRecv.size(); // typical socket buffer is 8K-64K - const unsigned int nBufSize = 0x10000; - vRecv.resize(nPos + nBufSize); - int nBytes = recv(hSocket, &vRecv[nPos], nBufSize, 0); - vRecv.resize(nPos + max(nBytes, 0)); - if (nBytes == 0) + char pchBuf[0x10000]; + int nBytes = recv(hSocket, pchBuf, sizeof(pchBuf), MSG_DONTWAIT); + if (nBytes > 0) + { + vRecv.resize(nPos + nBytes); + memcpy(&vRecv[nPos], pchBuf, nBytes); + pnode->nLastRecv = GetTime(); + } + else if (nBytes == 0) { // socket closed gracefully if (!pnode->fDisconnect) - printf("recv: socket closed\n"); + printf("socket closed\n"); pnode->fDisconnect = true; } else if (nBytes < 0) { - // socket error + // error int nErr = WSAGetLastError(); if (nErr != WSAEWOULDBLOCK && nErr != WSAEMSGSIZE && nErr != WSAEINTR && nErr != WSAEINPROGRESS) { if (!pnode->fDisconnect) - printf("recv failed: %d\n", nErr); + printf("socket recv error %d\n", nErr); pnode->fDisconnect = true; } } @@ -712,28 +716,63 @@ void ThreadSocketHandler2(void* parg) CDataStream& vSend = pnode->vSend; if (!vSend.empty()) { - int nBytes = send(hSocket, &vSend[0], vSend.size(), MSG_NOSIGNAL); + int nBytes = send(hSocket, &vSend[0], vSend.size(), MSG_NOSIGNAL | MSG_DONTWAIT); if (nBytes > 0) { vSend.erase(vSend.begin(), vSend.begin() + nBytes); + pnode->nLastSend = GetTime(); } - else if (nBytes == 0) - { - if (pnode->ReadyToDisconnect()) - pnode->vSend.clear(); - } - else + else if (nBytes < 0) { - printf("send error %d\n", nBytes); - if (pnode->ReadyToDisconnect()) - pnode->vSend.clear(); + // error + int nErr = WSAGetLastError(); + if (nErr != WSAEWOULDBLOCK && nErr != WSAEMSGSIZE && nErr != WSAEINTR && nErr != WSAEINPROGRESS) + { + printf("socket send error %d\n", nErr); + pnode->fDisconnect = true; + } } } } } + + // + // Inactivity checking + // + if (pnode->vSend.empty()) + pnode->nLastSendEmpty = GetTime(); + if (GetTime() - pnode->nTimeConnected > 60) + { + if (pnode->nLastRecv == 0 || pnode->nLastSend == 0) + { + printf("socket no message in first 60 seconds, %d %d\n", pnode->nLastRecv != 0, pnode->nLastSend != 0); + pnode->fDisconnect = true; + } + else if (GetTime() - pnode->nLastSend > 10 * 60 && GetTime() - pnode->nLastSendEmpty > 10 * 60) + { + printf("socket not sending\n"); + pnode->fDisconnect = true; + } + else if (GetTime() - pnode->nLastRecv > (pnode->nVersion >= 107 ? 15*60 : 90*60)) + { + printf("socket inactivity timeout\n"); + pnode->fDisconnect = true; + } + } + } + + + //// debug heartbeat + static int64 nHeartbeat1; + if (GetTime() - nHeartbeat1 >= 5 * 60) + { + printf("%s sendrecv\n", DateTimeStrFormat("%x %H:%M:%S", GetTime()).c_str()); + nHeartbeat1 = GetTime(); + fDebug = true; } + nThreadSocketHandlerHeartbeat = GetTime(); Sleep(10); } } @@ -772,15 +811,20 @@ void ThreadOpenConnections2(void* parg) { printf("ThreadOpenConnections started\n"); - // Connect to one specified address + // Connect to specific addresses while (mapArgs.count("-connect")) { - OpenNetworkConnection(CAddress(mapArgs["-connect"])); - for (int i = 0; i < 10; i++) + foreach(string strAddr, mapMultiArgs["-connect"]) { - Sleep(1000); - if (fShutdown) - return; + CAddress addr(strAddr, NODE_NETWORK); + if (addr.IsValid()) + OpenNetworkConnection(addr); + for (int i = 0; i < 10; i++) + { + Sleep(1000); + if (fShutdown) + return; + } } } @@ -821,12 +865,7 @@ void ThreadOpenConnections2(void* parg) // Choose an address to connect to based on most recently seen // CAddress addrConnect; - int64 nBestTime = 0; - int64 nDelay = ((60 * 60) << vNodes.size()); - if (vNodes.size() >= 3) - nDelay *= 4; - if (nGotIRCAddresses > 0) - nDelay *= 100; + int64 nBest = INT64_MIN; // Do this here so we don't have to critsect vNodes inside mapAddresses critsect set setConnected; @@ -841,24 +880,51 @@ void ThreadOpenConnections2(void* parg) const CAddress& addr = item.second; if (!addr.IsIPv4() || !addr.IsValid() || setConnected.count(addr.ip)) continue; + int64 nSinceLastSeen = GetAdjustedTime() - addr.nTime; + int64 nSinceLastTry = GetAdjustedTime() - addr.nLastTry; // Randomize the order in a deterministic way, putting the standard port first - int64 nRandomizer = (uint64)(addr.nLastFailed * 9567851 + addr.ip * 7789) % (1 * 60 * 60); + int64 nRandomizer = (uint64)(addr.nLastTry * 9567851 + addr.ip * 7789) % (30 * 60); if (addr.port != DEFAULT_PORT) - nRandomizer += 1 * 60 * 60; + nRandomizer += 30 * 60; + + // Last seen Base retry frequency + // <1 hour 10 min + // 1 hour 1 hour + // 4 hours 2 hours + // 24 hours 5 hours + // 48 hours 7 hours + // 7 days 13 hours + // 30 days 27 hours + // 90 days 46 hours + // 365 days 93 hours + int64 nDelay = 3600.0 * sqrt(fabs(nSinceLastSeen) / 3600.0) + nRandomizer; + + // Fast reconnect for one hour after last seen + if (nSinceLastSeen < 60 * 60) + nDelay = 10 * 60; // Limit retry frequency - if (GetAdjustedTime() < addr.nLastFailed + nDelay + nRandomizer) + if (nSinceLastTry < nDelay) continue; - // Try again only after all addresses had a first attempt - int64 nTime = addr.nTime - nRandomizer; - if (addr.nLastFailed > addr.nTime) - nTime -= 365 * 24 * 60 * 60; + // If we have IRC, we'll be notified when they first come online, + // and again every 24 hours by the refresh broadcast. + if (nGotIRCAddresses > 0 && vNodes.size() >= 2 && nSinceLastSeen > 24 * 60 * 60) + continue; - if (nTime > nBestTime) + // Only try the old stuff if we don't have enough connections + if (vNodes.size() >= 2 && nSinceLastSeen > 7 * 24 * 60 * 60) + continue; + if (vNodes.size() >= 4 && nSinceLastSeen > 24 * 60 * 60) + continue; + + // If multiple addresses are ready, prioritize by time since + // last seen and time since last tried. + int64 nScore = min(nSinceLastTry, (int64)24 * 60 * 60) - nSinceLastSeen - nRandomizer; + if (nScore > nBest) { - nBestTime = nTime; + nBest = nScore; addrConnect = addr; } } @@ -941,7 +1007,7 @@ void ThreadMessageHandler(void* parg) void ThreadMessageHandler2(void* parg) { printf("ThreadMessageHandler started\n"); - SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_BELOW_NORMAL); + SetThreadPriority(THREAD_PRIORITY_BELOW_NORMAL); loop { // Poll the connected nodes for messages @@ -1063,39 +1129,31 @@ bool BindListenPort(string& strError) return true; } -bool StartNode(string& strError) +void StartNode(void* parg) { - strError = ""; if (pnodeLocalHost == NULL) pnodeLocalHost = new CNode(INVALID_SOCKET, CAddress("127.0.0.1", nLocalServices)); #ifdef __WXMSW__ // Get local host ip - char pszHostName[255]; - if (gethostname(pszHostName, sizeof(pszHostName)) == SOCKET_ERROR) + char pszHostName[1000] = ""; + if (gethostname(pszHostName, sizeof(pszHostName)) != SOCKET_ERROR) { - strError = strprintf("Error: Unable to get IP address of this computer (gethostname returned error %d)", WSAGetLastError()); - printf("%s\n", strError.c_str()); - return false; - } - struct hostent* phostent = gethostbyname(pszHostName); - if (!phostent) - { - strError = strprintf("Error: Unable to get IP address of this computer (gethostbyname returned error %d)", WSAGetLastError()); - printf("%s\n", strError.c_str()); - return false; - } - - // Take the first IP that isn't loopback 127.x.x.x - for (int i = 0; phostent->h_addr_list[i] != NULL; i++) - printf("host ip %d: %s\n", i, CAddress(*(unsigned int*)phostent->h_addr_list[i]).ToStringIP().c_str()); - for (int i = 0; phostent->h_addr_list[i] != NULL; i++) - { - CAddress addr(*(unsigned int*)phostent->h_addr_list[i], DEFAULT_PORT, nLocalServices); - if (addr.IsValid() && addr.GetByte(3) != 127) + struct hostent* phostent = gethostbyname(pszHostName); + if (phostent) { - addrLocalHost = addr; - break; + // Take the first IP that isn't loopback 127.x.x.x + for (int i = 0; phostent->h_addr_list[i] != NULL; i++) + printf("host ip %d: %s\n", i, CAddress(*(unsigned int*)phostent->h_addr_list[i]).ToStringIP().c_str()); + for (int i = 0; phostent->h_addr_list[i] != NULL; i++) + { + CAddress addr(*(unsigned int*)phostent->h_addr_list[i], DEFAULT_PORT, nLocalServices); + if (addr.IsValid() && addr.GetByte(3) != 127) + { + addrLocalHost = addr; + break; + } + } } } #else @@ -1145,45 +1203,85 @@ bool StartNode(string& strError) } else { - if (addrIncoming.ip) + if (addrIncoming.IsValid()) addrLocalHost.ip = addrIncoming.ip; if (GetMyExternalIP(addrLocalHost.ip)) { addrIncoming = addrLocalHost; CWalletDB().WriteSetting("addrIncoming", addrIncoming); + printf("addrLocalHost = %s\n", addrLocalHost.ToString().c_str()); } } - // Get addresses from IRC and advertise ours - if (_beginthread(ThreadIRCSeed, 0, NULL) == -1) - printf("Error: _beginthread(ThreadIRCSeed) failed\n"); - // // Start threads // - if (_beginthread(ThreadSocketHandler, 0, NULL) == -1) - { - strError = "Error: _beginthread(ThreadSocketHandler) failed"; - printf("%s\n", strError.c_str()); - return false; - } - if (_beginthread(ThreadOpenConnections, 0, NULL) == -1) - { - strError = "Error: _beginthread(ThreadOpenConnections) failed"; - printf("%s\n", strError.c_str()); - return false; - } + // Get addresses from IRC and advertise ours + if (!CreateThread(ThreadIRCSeed, NULL)) + printf("Error: CreateThread(ThreadIRCSeed) failed\n"); + + // Send and receive from sockets, accept connections + pthread_t hThreadSocketHandler = CreateThread(ThreadSocketHandler, NULL, true); + + // Initiate outbound connections + if (!CreateThread(ThreadOpenConnections, NULL)) + printf("Error: CreateThread(ThreadOpenConnections) failed\n"); + + // Process messages + if (!CreateThread(ThreadMessageHandler, NULL)) + printf("Error: CreateThread(ThreadMessageHandler) failed\n"); - if (_beginthread(ThreadMessageHandler, 0, NULL) == -1) + // Generate coins in the background + GenerateBitcoins(fGenerateBitcoins); + + // + // Thread monitoring + // + loop { - strError = "Error: _beginthread(ThreadMessageHandler) failed"; - printf("%s\n", strError.c_str()); - return false; + Sleep(15000); + if (GetTime() - nThreadSocketHandlerHeartbeat > 4 * 60) + { + // First see if closing sockets will free it + printf("*** ThreadSocketHandler is stopped ***\n"); + CRITICAL_BLOCK(cs_vNodes) + { + foreach(CNode* pnode, vNodes) + { + bool fGot = false; + TRY_CRITICAL_BLOCK(pnode->cs_vRecv) + TRY_CRITICAL_BLOCK(pnode->cs_vSend) + fGot = true; + if (!fGot) + { + printf("*** closing socket\n"); + closesocket(pnode->hSocket); + pnode->fDisconnect = true; + } + } + } + Sleep(10000); + if (GetTime() - nThreadSocketHandlerHeartbeat < 60) + continue; + + // Hopefully it never comes to this. + // We know it'll always be hung in the recv or send call. + // cs_vRecv or cs_vSend may be left permanently unreleased, + // but we always only use TRY_CRITICAL_SECTION on them. + printf("*** Restarting ThreadSocketHandler ***\n"); + TerminateThread(hThreadSocketHandler, 0); + #ifdef __WXMSW__ + CloseHandle(hThreadSocketHandler); + #endif + vnThreadsRunning[0] = 0; + + // Restart + hThreadSocketHandler = CreateThread(ThreadSocketHandler, NULL, true); + nThreadSocketHandlerHeartbeat = GetTime(); + } } - - return true; } bool StopNode() diff --git a/net.h b/net.h index 7b83d462fe..6300d3efcf 100644 --- a/net.h +++ b/net.h @@ -29,7 +29,7 @@ CNode* ConnectNode(CAddress addrConnect, int64 nTimeout=0); void AbandonRequests(void (*fn)(void*, CDataStream&), void* param1); bool AnySubscribed(unsigned int nChannel); bool BindListenPort(string& strError=REF(string())); -bool StartNode(string& strError=REF(string())); +void StartNode(void* parg); bool StopNode(); @@ -39,7 +39,6 @@ bool StopNode(); - // // Message header // (4) message start @@ -139,7 +138,7 @@ public: unsigned int nTime; // memory only - unsigned int nLastFailed; + unsigned int nLastTry; CAddress() { @@ -183,7 +182,7 @@ public: ip = INADDR_NONE; port = DEFAULT_PORT; nTime = GetAdjustedTime(); - nLastFailed = 0; + nLastTry = 0; } bool SetAddress(const char* pszIn) @@ -458,6 +457,7 @@ extern uint64 nLocalHostNonce; extern bool fShutdown; extern array vnThreadsRunning; extern SOCKET hListenSocket; +extern int64 nThreadSocketHandlerHeartbeat; extern vector vNodes; extern CCriticalSection cs_vNodes; @@ -486,6 +486,10 @@ public: CDataStream vRecv; CCriticalSection cs_vSend; CCriticalSection cs_vRecv; + int64 nLastSend; + int64 nLastRecv; + int64 nLastSendEmpty; + int64 nTimeConnected; unsigned int nPushPos; CAddress addr; int nVersion; @@ -523,6 +527,10 @@ public: hSocket = hSocketIn; vSend.SetType(SER_NETWORK); vRecv.SetType(SER_NETWORK); + nLastSend = 0; + nLastRecv = 0; + nLastSendEmpty = GetTime(); + nTimeConnected = GetTime(); nPushPos = -1; addr = addrIn; nVersion = 0; @@ -542,7 +550,7 @@ public: CAddress addrYou = (fUseProxy ? CAddress("0.0.0.0") : addr); CAddress addrMe = (fUseProxy ? CAddress("0.0.0.0") : addrLocalHost); RAND_bytes((unsigned char*)&nLocalHostNonce, sizeof(nLocalHostNonce)); - PushMessage("version", VERSION, nLocalServices, nTime, addrYou, addrMe, nLocalHostNonce); + PushMessage("version", VERSION, nLocalServices, nTime, addrYou, addrMe, nLocalHostNonce, "linux-test5"); } ~CNode() @@ -557,11 +565,6 @@ private: public: - bool ReadyToDisconnect() - { - return fDisconnect || GetRefCount() <= 0; - } - int GetRefCount() { return max(nRefCount, 0) + (GetTime() < nReleaseTime ? 1 : 0); @@ -635,6 +638,8 @@ public: AbortMessage(); nPushPos = vSend.size(); vSend << CMessageHeader(pszCommand, 0); + if (fDebug) + printf("%s ", DateTimeStrFormat("%x %H:%M:%S", GetTime()).c_str()); printf("sending: %s ", pszCommand); } diff --git a/ui.cpp b/ui.cpp index e12970b81b..9d7556cb57 100644 --- a/ui.cpp +++ b/ui.cpp @@ -25,6 +25,7 @@ map mapAddressBook; bool fRandSendTest = false; void RandSend(); extern int g_isPainting; +bool fClosedToTray = false; // Settings int fShowGenerated = true; @@ -413,16 +414,17 @@ void Shutdown(void* parg) void CMainFrame::OnClose(wxCloseEvent& event) { - if (fMinimizeToTray && fMinimizeOnClose && event.CanVeto() && !IsIconized()) + if (fMinimizeOnClose && event.CanVeto() && !IsIconized()) { // Divert close to minimize event.Veto(); + fClosedToTray = true; Iconize(true); } else { Destroy(); - _beginthread(Shutdown, 0, NULL); + CreateThread(Shutdown, NULL); } } @@ -430,7 +432,16 @@ void CMainFrame::OnIconize(wxIconizeEvent& event) { // Hide the task bar button when minimized. // Event is sent when the frame is minimized or restored. - Show(!fMinimizeToTray || !event.Iconized()); + if (!event.Iconized()) + fClosedToTray = false; +#ifndef __WXMSW__ + // Tray is not reliable on Linux gnome + fClosedToTray = false; +#endif + if (fMinimizeToTray && event.Iconized()) + fClosedToTray = true; + Show(!fClosedToTray); + ptaskbaricon->Show(fMinimizeToTray || fClosedToTray); } void CMainFrame::OnMouseEvents(wxMouseEvent& event) @@ -527,7 +538,6 @@ bool CMainFrame::DeleteLine(uint256 hashKey) string FormatTxStatus(const CWalletTx& wtx) { // Status - int nDepth = wtx.GetDepthInMainChain(); if (!wtx.IsFinal()) { if (wtx.nLockTime < 500000000) @@ -535,10 +545,16 @@ string FormatTxStatus(const CWalletTx& wtx) else return strprintf("Open until %s", DateTimeStr(wtx.nLockTime).c_str()); } - else if (nDepth < 6) - return strprintf("%d/unconfirmed", nDepth); else - return strprintf("%d blocks", nDepth); + { + 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 blocks", nDepth); + } } string SingleLine(const string& strIn) @@ -629,9 +645,17 @@ bool CMainFrame::InsertTransaction(const CWalletTx& wtx, bool fNew, int nIndex) foreach(const CTxOut& txout, wtx.vout) nUnmatured += txout.GetCredit(); if (wtx.IsInMainChain()) - strDescription += strprintf(" (%s matures in %d more blocks)", FormatMoney(nUnmatured).c_str(), wtx.GetBlocksToMaturity()); + { + 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 += " (not accepted)"; + { + strDescription = "Generated (not accepted)"; + } } } else if (!mapValue["from"].empty() || !mapValue["message"].empty()) @@ -701,8 +725,11 @@ bool CMainFrame::InsertTransaction(const CWalletTx& wtx, bool fNew, int nIndex) strStatus, nTime ? DateTimeStr(nTime) : "", "Payment to yourself", - FormatMoney(nNet - nValue, true), - FormatMoney(nValue, true)); + "", + ""); + /// issue: can't tell which is the payment and which is the change anymore + // FormatMoney(nNet - nValue, true), + // FormatMoney(nValue, true)); } else if (fAllFromMe) { @@ -1028,6 +1055,9 @@ void CMainFrame::OnPaintListCtrl(wxPaintEvent& event) string strStatus = strprintf(" %d connections %d blocks %d transactions", vNodes.size(), nBestHeight + 1, nTransactionCount); m_statusBar->SetStatusText(strStatus, 2); + if (fDebug && GetTime() - nThreadSocketHandlerHeartbeat > 60) + m_statusBar->SetStatusText(" ERROR: ThreadSocketHandler has stopped", 0); + // Pass through to listctrl to actually do the paint, we're just hooking the message m_listCtrl->Disconnect(wxEVT_PAINT, (wxObjectEventFunction)NULL, NULL, this); m_listCtrl->GetEventHandler()->ProcessEvent(event); @@ -1237,7 +1267,19 @@ CTxDetailsDialog::CTxDetailsDialog(wxWindow* parent, CWalletTx wtx) : CTxDetails - strHTML += "Status: " + FormatTxStatus(wtx) + "
"; + strHTML += "Status: " + 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 += "
"; + strHTML += "Date: " + (nTime ? DateTimeStr(nTime) : "") + "
"; @@ -1366,9 +1408,10 @@ CTxDetailsDialog::CTxDetailsDialog(wxWindow* parent, CWalletTx wtx) : CTxDetails if (fAllToMe) { // Payment to self - int64 nValue = wtx.vout[0].nValue; - strHTML += "Debit: " + FormatMoney(-nValue) + "
"; - strHTML += "Credit: " + FormatMoney(nValue) + "
"; + /// issue: can't tell which is the payment and which is the change anymore + //int64 nValue = wtx.vout[0].nValue; + //strHTML += "Debit: " + FormatMoney(-nValue) + "
"; + //strHTML += "Credit: " + FormatMoney(nValue) + "
"; } int64 nTxFee = nDebit - wtx.GetValueOut(); @@ -1469,6 +1512,9 @@ COptionsDialog::COptionsDialog(wxWindow* parent) : COptionsDialogBase(parent) //m_listBox->Append("Test 2"); m_listBox->SetSelection(0); SelectPage(0); +#ifndef __WXMSW__ + m_checkBoxMinimizeOnClose->SetLabel("&Minimize on close"); +#endif // Init values m_textCtrlTransactionFee->SetValue(FormatMoney(nTransactionFee)); @@ -1481,9 +1527,7 @@ COptionsDialog::COptionsDialog(wxWindow* parent) : COptionsDialogBase(parent) m_spinCtrlLimitProcessors->SetRange(1, nProcessors); m_checkBoxStartOnSystemStartup->SetValue(fTmpStartOnSystemStartup = GetStartOnSystemStartup()); m_checkBoxMinimizeToTray->SetValue(fMinimizeToTray); - m_checkBoxMinimizeOnClose->Enable(fMinimizeToTray); - m_checkBoxMinimizeOnClose->SetValue(fMinimizeToTray && fMinimizeOnClose); - fTmpMinimizeOnClose = fMinimizeOnClose; + m_checkBoxMinimizeOnClose->SetValue(fMinimizeOnClose); m_checkBoxUseProxy->SetValue(fUseProxy); m_textCtrlProxyIP->Enable(fUseProxy); m_textCtrlProxyPort->Enable(fUseProxy); @@ -1521,22 +1565,6 @@ void COptionsDialog::OnCheckBoxLimitProcessors(wxCommandEvent& event) m_spinCtrlLimitProcessors->Enable(event.IsChecked()); } -void COptionsDialog::OnCheckBoxMinimizeToTray(wxCommandEvent& event) -{ - m_checkBoxMinimizeOnClose->Enable(event.IsChecked()); - - // Save the value in fTmpMinimizeOnClose so we can - // show the checkbox unchecked when its parent is unchecked - if (event.IsChecked()) - m_checkBoxMinimizeOnClose->SetValue(fTmpMinimizeOnClose); - else - { - fTmpMinimizeOnClose = m_checkBoxMinimizeOnClose->GetValue(); - m_checkBoxMinimizeOnClose->SetValue(false); - } - -} - void COptionsDialog::OnCheckBoxUseProxy(wxCommandEvent& event) { m_textCtrlProxyIP->Enable(event.IsChecked()); @@ -1608,12 +1636,12 @@ void COptionsDialog::OnButtonApply(wxCommandEvent& event) { fMinimizeToTray = m_checkBoxMinimizeToTray->GetValue(); walletdb.WriteSetting("fMinimizeToTray", fMinimizeToTray); - ptaskbaricon->Show(fMinimizeToTray); + ptaskbaricon->Show(fMinimizeToTray || fClosedToTray); } - if (fMinimizeOnClose != (fMinimizeToTray ? m_checkBoxMinimizeOnClose->GetValue() : fTmpMinimizeOnClose)) + if (fMinimizeOnClose != m_checkBoxMinimizeOnClose->GetValue()) { - fMinimizeOnClose = (fMinimizeToTray ? m_checkBoxMinimizeOnClose->GetValue() : fTmpMinimizeOnClose); + fMinimizeOnClose = m_checkBoxMinimizeOnClose->GetValue(); walletdb.WriteSetting("fMinimizeOnClose", fMinimizeOnClose); } @@ -1643,6 +1671,9 @@ CAboutDialog::CAboutDialog(wxWindow* parent) : CAboutDialogBase(parent) if (str.Find('Â') != wxNOT_FOUND) str.Remove(str.Find('Â'), 1); m_staticTextMain->SetLabel(str); +#ifndef __WXMSW__ + SetSize(510, 380); +#endif } void CAboutDialog::OnButtonOK(wxCommandEvent& event) @@ -1849,7 +1880,7 @@ CSendingDialog::CSendingDialog(wxWindow* parent, const CAddress& addrIn, int64 n SetTitle(strprintf("Sending %s to %s", FormatMoney(nPrice).c_str(), wtx.mapValue["to"].c_str())); m_textCtrlStatus->SetValue(""); - _beginthread(SendingDialogStartTransfer, 0, this); + CreateThread(SendingDialogStartTransfer, this); } CSendingDialog::~CSendingDialog() @@ -2856,7 +2887,7 @@ CViewProductDialog::CViewProductDialog(wxWindow* parent, const CProduct& product this->Layout(); // Request details from seller - _beginthread(ThreadRequestProductDetails, 0, new pair(product, GetEventHandler())); + CreateThread(ThreadRequestProductDetails, new pair(product, GetEventHandler())); } CViewProductDialog::~CViewProductDialog() @@ -3256,6 +3287,7 @@ void CEditReviewDialog::GetReview(CReview& review) enum { ID_TASKBAR_RESTORE = 10001, + ID_TASKBAR_OPTIONS, ID_TASKBAR_GENERATE, ID_TASKBAR_EXIT, }; @@ -3263,6 +3295,7 @@ enum BEGIN_EVENT_TABLE(CMyTaskBarIcon, wxTaskBarIcon) EVT_TASKBAR_LEFT_DCLICK(CMyTaskBarIcon::OnLeftButtonDClick) EVT_MENU(ID_TASKBAR_RESTORE, CMyTaskBarIcon::OnMenuRestore) + EVT_MENU(ID_TASKBAR_OPTIONS, CMyTaskBarIcon::OnMenuOptions) EVT_MENU(ID_TASKBAR_GENERATE, CMyTaskBarIcon::OnMenuGenerate) EVT_UPDATE_UI(ID_TASKBAR_GENERATE, CMyTaskBarIcon::OnUpdateUIGenerate) EVT_MENU(ID_TASKBAR_EXIT, CMyTaskBarIcon::OnMenuExit) @@ -3312,9 +3345,18 @@ void CMyTaskBarIcon::OnMenuRestore(wxCommandEvent& event) Restore(); } +void CMyTaskBarIcon::OnMenuOptions(wxCommandEvent& event) +{ + // Since it's modal, get the main window to do it + wxCommandEvent event2(wxEVT_COMMAND_MENU_SELECTED, wxID_MENUOPTIONSOPTIONS); + pframeMain->AddPendingEvent(event2); +} + void CMyTaskBarIcon::Restore() { pframeMain->Show(); + wxIconizeEvent event(0, false); + pframeMain->AddPendingEvent(event); pframeMain->Iconize(false); pframeMain->Raise(); } @@ -3344,6 +3386,7 @@ wxMenu* CMyTaskBarIcon::CreatePopupMenu() { wxMenu* pmenu = new wxMenu; pmenu->Append(ID_TASKBAR_RESTORE, "&Open Bitcoin"); + pmenu->Append(ID_TASKBAR_OPTIONS, "O&ptions..."); pmenu->AppendCheckItem(ID_TASKBAR_GENERATE, "&Generate Coins")->Check(fGenerateBitcoins); #ifndef __WXMAC_OSX__ // Mac has built-in quit menu pmenu->AppendSeparator(); @@ -3582,7 +3625,7 @@ bool CMyApp::OnInit2() { CBlockIndex* pindex = (*mi).second; CBlock block; - block.ReadFromDisk(pindex, true); + block.ReadFromDisk(pindex); block.BuildMerkleTree(); block.print(); printf("\n"); @@ -3632,20 +3675,20 @@ bool CMyApp::OnInit2() if (mapArgs.count("-min")) pframeMain->Iconize(true); pframeMain->Show(true); // have to show first to get taskbar button to hide - pframeMain->Show(!fMinimizeToTray || !pframeMain->IsIconized()); - ptaskbaricon->Show(fMinimizeToTray); + if (fMinimizeToTray && pframeMain->IsIconized()) + fClosedToTray = true; + pframeMain->Show(!fClosedToTray); + ptaskbaricon->Show(fMinimizeToTray || fClosedToTray); - _beginthread(ThreadDelayedRepaint, 0, NULL); + CreateThread(ThreadDelayedRepaint, NULL); if (!CheckDiskSpace()) return false; RandAddSeedPerfmon(); - if (!StartNode(strErrors)) - wxMessageBox(strErrors, "Bitcoin"); - - GenerateBitcoins(fGenerateBitcoins); + if (!CreateThread(StartNode, NULL)) + wxMessageBox("Error: CreateThread(StartNode) failed", "Bitcoin"); if (fFirstRun) SetStartOnSystemStartup(true); diff --git a/ui.h b/ui.h index a919c3668d..c4bf8b66f1 100644 --- a/ui.h +++ b/ui.h @@ -112,7 +112,6 @@ protected: void OnListBox(wxCommandEvent& event); void OnKillFocusTransactionFee(wxFocusEvent& event); void OnCheckBoxLimitProcessors(wxCommandEvent& event); - void OnCheckBoxMinimizeToTray(wxCommandEvent& event); void OnCheckBoxUseProxy(wxCommandEvent& event); void OnKillFocusProxy(wxFocusEvent& event); @@ -447,6 +446,7 @@ protected: // Event handlers void OnLeftButtonDClick(wxTaskBarIconEvent& event); void OnMenuRestore(wxCommandEvent& event); + void OnMenuOptions(wxCommandEvent& event); void OnUpdateUIGenerate(wxUpdateUIEvent& event); void OnMenuGenerate(wxCommandEvent& event); void OnMenuExit(wxCommandEvent& event); diff --git a/uibase.cpp b/uibase.cpp index 7bc8081f09..f05f1095fb 100644 --- a/uibase.cpp +++ b/uibase.cpp @@ -45,7 +45,7 @@ CMainFrameBase::CMainFrameBase( wxWindow* parent, wxWindowID id, const wxString& m_menuOptions->Append( m_menuOptionsChangeYourAddress ); wxMenuItem* m_menuOptionsOptions; - m_menuOptionsOptions = new wxMenuItem( m_menuOptions, wxID_ANY, wxString( wxT("&Options...") ) , wxEmptyString, wxITEM_NORMAL ); + m_menuOptionsOptions = new wxMenuItem( m_menuOptions, wxID_MENUOPTIONSOPTIONS, wxString( wxT("&Options...") ) , wxEmptyString, wxITEM_NORMAL ); m_menuOptions->Append( m_menuOptionsOptions ); m_menubar->Append( m_menuOptions, wxT("&Options") ); @@ -428,21 +428,13 @@ COptionsDialogBase::COptionsDialogBase( wxWindow* parent, wxWindowID id, const w bSizer69->Add( m_checkBoxStartOnSystemStartup, 0, wxALL, 5 ); - m_checkBoxMinimizeToTray = new wxCheckBox( m_panelMain, wxID_ANY, wxT("&Minimize to the system tray instead of the taskbar"), wxDefaultPosition, wxDefaultSize, 0 ); + m_checkBoxMinimizeToTray = new wxCheckBox( m_panelMain, wxID_ANY, wxT("&Minimize to the tray instead of the taskbar"), wxDefaultPosition, wxDefaultSize, 0 ); bSizer69->Add( m_checkBoxMinimizeToTray, 0, wxALL, 5 ); - wxBoxSizer* bSizer101; - bSizer101 = new wxBoxSizer( wxHORIZONTAL ); + m_checkBoxMinimizeOnClose = new wxCheckBox( m_panelMain, wxID_ANY, wxT("M&inimize to the tray on close"), wxDefaultPosition, wxDefaultSize, 0 ); - - bSizer101->Add( 16, 0, 0, 0, 5 ); - - m_checkBoxMinimizeOnClose = new wxCheckBox( m_panelMain, wxID_ANY, wxT("Mi&nimize to system tray on close"), wxDefaultPosition, wxDefaultSize, 0 ); - - bSizer101->Add( m_checkBoxMinimizeOnClose, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); - - bSizer69->Add( bSizer101, 1, wxEXPAND, 5 ); + bSizer69->Add( m_checkBoxMinimizeOnClose, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); wxBoxSizer* bSizer102; bSizer102 = new wxBoxSizer( wxHORIZONTAL ); diff --git a/uibase.h b/uibase.h index 2cb99e9a59..e0c152185c 100644 --- a/uibase.h +++ b/uibase.h @@ -43,51 +43,52 @@ #define wxID_MAINFRAME 1000 #define wxID_VIEWSHOWGENERATED 1001 #define wxID_OPTIONSGENERATEBITCOINS 1002 -#define wxID_BUTTONSEND 1003 -#define wxID_BUTTONRECEIVE 1004 -#define wxID_TEXTCTRLADDRESS 1005 -#define wxID_BUTTONCOPY 1006 -#define wxID_BUTTONCHANGE 1007 -#define wxID_TRANSACTIONFEE 1008 -#define wxID_PROXYIP 1009 -#define wxID_PROXYPORT 1010 -#define wxID_TEXTCTRLPAYTO 1011 -#define wxID_BUTTONPASTE 1012 -#define wxID_BUTTONADDRESSBOOK 1013 -#define wxID_TEXTCTRLAMOUNT 1014 -#define wxID_CHOICETRANSFERTYPE 1015 -#define wxID_LISTCTRL 1016 -#define wxID_BUTTONRENAME 1017 -#define wxID_BUTTONNEW 1018 -#define wxID_BUTTONEDIT 1019 -#define wxID_BUTTONDELETE 1020 -#define wxID_DEL0 1021 -#define wxID_DEL1 1022 -#define wxID_DEL2 1023 -#define wxID_DEL3 1024 -#define wxID_DEL4 1025 -#define wxID_DEL5 1026 -#define wxID_DEL6 1027 -#define wxID_DEL7 1028 -#define wxID_DEL8 1029 -#define wxID_DEL9 1030 -#define wxID_DEL10 1031 -#define wxID_DEL11 1032 -#define wxID_DEL12 1033 -#define wxID_DEL13 1034 -#define wxID_DEL14 1035 -#define wxID_DEL15 1036 -#define wxID_DEL16 1037 -#define wxID_DEL17 1038 -#define wxID_DEL18 1039 -#define wxID_DEL19 1040 -#define wxID_BUTTONPREVIEW 1041 -#define wxID_BUTTONSAMPLE 1042 -#define wxID_CANCEL2 1043 -#define wxID_BUTTONBACK 1044 -#define wxID_BUTTONNEXT 1045 -#define wxID_SUBMIT 1046 -#define wxID_TEXTCTRL 1047 +#define wxID_MENUOPTIONSOPTIONS 1003 +#define wxID_BUTTONSEND 1004 +#define wxID_BUTTONRECEIVE 1005 +#define wxID_TEXTCTRLADDRESS 1006 +#define wxID_BUTTONCOPY 1007 +#define wxID_BUTTONCHANGE 1008 +#define wxID_TRANSACTIONFEE 1009 +#define wxID_PROXYIP 1010 +#define wxID_PROXYPORT 1011 +#define wxID_TEXTCTRLPAYTO 1012 +#define wxID_BUTTONPASTE 1013 +#define wxID_BUTTONADDRESSBOOK 1014 +#define wxID_TEXTCTRLAMOUNT 1015 +#define wxID_CHOICETRANSFERTYPE 1016 +#define wxID_LISTCTRL 1017 +#define wxID_BUTTONRENAME 1018 +#define wxID_BUTTONNEW 1019 +#define wxID_BUTTONEDIT 1020 +#define wxID_BUTTONDELETE 1021 +#define wxID_DEL0 1022 +#define wxID_DEL1 1023 +#define wxID_DEL2 1024 +#define wxID_DEL3 1025 +#define wxID_DEL4 1026 +#define wxID_DEL5 1027 +#define wxID_DEL6 1028 +#define wxID_DEL7 1029 +#define wxID_DEL8 1030 +#define wxID_DEL9 1031 +#define wxID_DEL10 1032 +#define wxID_DEL11 1033 +#define wxID_DEL12 1034 +#define wxID_DEL13 1035 +#define wxID_DEL14 1036 +#define wxID_DEL15 1037 +#define wxID_DEL16 1038 +#define wxID_DEL17 1039 +#define wxID_DEL18 1040 +#define wxID_DEL19 1041 +#define wxID_BUTTONPREVIEW 1042 +#define wxID_BUTTONSAMPLE 1043 +#define wxID_CANCEL2 1044 +#define wxID_BUTTONBACK 1045 +#define wxID_BUTTONNEXT 1046 +#define wxID_SUBMIT 1047 +#define wxID_TEXTCTRL 1048 /////////////////////////////////////////////////////////////////////////////// /// Class CMainFrameBase @@ -203,7 +204,6 @@ class COptionsDialogBase : public wxDialog wxStaticText* m_staticText35; wxCheckBox* m_checkBoxStartOnSystemStartup; wxCheckBox* m_checkBoxMinimizeToTray; - wxCheckBox* m_checkBoxMinimizeOnClose; wxCheckBox* m_checkBoxUseProxy; diff --git a/uiproject.fbp b/uiproject.fbp index 3aa1c86bcf..58a99bddd8 100644 --- a/uiproject.fbp +++ b/uiproject.fbp @@ -70,7 +70,7 @@ - + 240,240,240 1 @@ -193,7 +193,7 @@ 0 1 - wxID_ANY + wxID_MENUOPTIONSOPTIONS wxITEM_NORMAL &Options... m_menuOptionsOptions @@ -2319,7 +2319,7 @@ 0 wxID_ANY - &Minimize to the system tray instead of the taskbar + &Minimize to the tray instead of the taskbar m_checkBoxMinimizeToTray @@ -2360,75 +2360,54 @@ 5 - wxEXPAND - 1 - + wxALL|wxALIGN_CENTER_VERTICAL + 0 + + + 0 + + 1 + + + 0 + wxID_ANY + M&inimize to the tray on close + - bSizer101 - wxHORIZONTAL - none - - 5 - - 0 - - 0 - protected - 16 - - - - 5 - wxALL|wxALIGN_CENTER_VERTICAL - 0 - - - 0 - - 1 - - - 0 - wxID_ANY - Mi&nimize to system tray on close - - - m_checkBoxMinimizeOnClose - protected - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + m_checkBoxMinimizeOnClose + protected + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/util.cpp b/util.cpp index 4a5b983d22..7a947730ce 100644 --- a/util.cpp +++ b/util.cpp @@ -85,14 +85,14 @@ void RandAddSeed() void RandAddSeedPerfmon() { -#ifdef __WXMSW__ - // Don't need this on Linux, OpenSSL automatically uses /dev/urandom // This can take up to 2 seconds, so only do it every 10 minutes static int64 nLastPerfmon; if (GetTime() < nLastPerfmon + 10 * 60) return; nLastPerfmon = GetTime(); +#ifdef __WXMSW__ + // Don't need this on Linux, OpenSSL automatically uses /dev/urandom // Seed with the entire set of perfmon data unsigned char pdata[250000]; memset(pdata, 0, sizeof(pdata)); @@ -109,9 +109,30 @@ void RandAddSeedPerfmon() printf("%s RandAddSeed() %d bytes\n", DateTimeStrFormat("%x %H:%M:%S", GetTime()).c_str(), nSize); } +#else + printf("%s RandAddSeed()\n", DateTimeStrFormat("%x %H:%M:%S", GetTime()).c_str()); #endif } +uint64 GetRand(uint64 nMax) +{ + if (nMax == 0) + return 0; + + // The range of the random source must be a multiple of the modulus + // to give every possible output value an equal possibility + uint64 nRange = (UINT64_MAX / nMax) * nMax; + uint64 nRand = 0; + do + RAND_bytes((unsigned char*)&nRand, sizeof(nRand)); + while (nRand >= nRange); + return (nRand % nMax); +} + + + + + @@ -449,28 +470,6 @@ string GetDataDir() -uint64 GetRand(uint64 nMax) -{ - if (nMax == 0) - return 0; - - // The range of the random source must be a multiple of the modulus - // to give every possible output value an equal possibility - uint64 nRange = (_UI64_MAX / nMax) * nMax; - uint64 nRand = 0; - do - RAND_bytes((unsigned char*)&nRand, sizeof(nRand)); - while (nRand >= nRange); - return (nRand % nMax); -} - - - - - - - - // @@ -483,7 +482,6 @@ uint64 GetRand(uint64 nMax) // note: NTP isn't implemented yet, so until then we just use the median // of other nodes clocks to correct ours. // - int64 GetTime() { return time(NULL); diff --git a/util.h b/util.h index 8fcfcd0dc9..ddac449441 100644 --- a/util.h +++ b/util.h @@ -54,9 +54,13 @@ inline T& REF(const T& val) return (T&)val; } -#ifndef __WXMSW__ -#define _UI64_MAX UINT64_MAX -#define _I64_MAX INT64_MAX +#ifdef __WXMSW__ +#define MSG_NOSIGNAL 0 +#define MSG_DONTWAIT 0 +#define UINT64_MAX _UI64_MAX +#define INT64_MAX _I64_MAX +#define INT64_MIN _I64_MIN +#else #define WSAGetLastError() errno #define WSAEWOULDBLOCK EWOULDBLOCK #define WSAEMSGSIZE EMSGSIZE @@ -74,18 +78,6 @@ typedef u_int SOCKET; #define MAX_PATH 1024 #define Sleep(n) wxMilliSleep(n) #define Beep(n1,n2) (0) -inline int _beginthread(void(*pfn)(void*), unsigned nStack, void* parg) { thread(bind(pfn, parg)); return 0; } -inline void _endthread() { pthread_exit(NULL); } -inline int GetCurrentThread() { return 0; } -// threads are processes on linux, so setpriority affects just the one thread -inline void SetThreadPriority(int nThread, int nPriority) { setpriority(PRIO_PROCESS, getpid(), nPriority); } -#define THREAD_PRIORITY_LOWEST PRIO_MIN -#define THREAD_PRIORITY_BELOW_NORMAL 2 -#define THREAD_PRIORITY_NORMAL 0 -#define THREAD_PRIORITY_ABOVE_NORMAL 0 -#endif -#ifndef MSG_NOSIGNAL -#define MSG_NOSIGNAL 0 #endif @@ -133,6 +125,7 @@ void AddTimeData(unsigned int ip, int64 nTime); + // Wrapper to automatically initialize critical sections class CCriticalSection { @@ -201,8 +194,6 @@ public: - - inline int OutputDebugStringF(const char* pszFormat, ...) { int ret = 0; @@ -498,3 +489,83 @@ inline uint160 Hash160(const vector& vch) RIPEMD160((unsigned char*)&hash1, sizeof(hash1), (unsigned char*)&hash2); return hash2; } + + + + + + + + + + + +// Note: It turns out we might have been able to use boost::thread +// by using TerminateThread(boost::thread.native_handle(), 0); +#ifdef __WXMSW__ +typedef HANDLE pthread_t; + +inline pthread_t CreateThread(void(*pfn)(void*), void* parg, bool fWantHandle=false) +{ + DWORD nUnused = 0; + HANDLE hthread = + CreateThread( + NULL, // default security + 0, // inherit stack size from parent + (LPTHREAD_START_ROUTINE)pfn, // function pointer + parg, // argument + 0, // creation option, start immediately + &nUnused); // thread identifier + if (hthread == NULL) + { + printf("Error: CreateThread() returned %d\n", GetLastError()); + return (pthread_t)0; + } + if (!fWantHandle) + { + CloseHandle(hthread); + return (pthread_t)-1; + } + return hthread; +} + +inline void SetThreadPriority(int nPriority) +{ + SetThreadPriority(GetCurrentThread(), nPriority); +} +#else +inline pthread_t CreateThread(void(*pfn)(void*), void* parg, bool fWantHandle=false) +{ + pthread_t hthread = 0; + int ret = pthread_create(&hthread, NULL, (void*(*)(void*))pfn, parg); + if (ret != 0) + { + printf("Error: pthread_create() returned %d\n", ret); + return (pthread_t)0; + } + if (!fWantHandle) + return (pthread_t)-1; + return hthread; +} + +#define THREAD_PRIORITY_LOWEST PRIO_MIN +#define THREAD_PRIORITY_BELOW_NORMAL 2 +#define THREAD_PRIORITY_NORMAL 0 +#define THREAD_PRIORITY_ABOVE_NORMAL 0 + +inline void SetThreadPriority(int nPriority) +{ + // threads are processes on linux, so PRIO_PROCESS affects just the one thread + setpriority(PRIO_PROCESS, getpid(), nPriority); +} + +inline bool TerminateThread(pthread_t hthread, unsigned int nExitCode) +{ + return (pthread_cancel(hthread) == 0); +} + +inline void ExitThread(unsigned int nExitCode) +{ + pthread_exit((void*)nExitCode); +} +#endif -- cgit v1.2.3 From 01fe1d2137d5e0a1d38f4c3be241b69ceccc578c Mon Sep 17 00:00:00 2001 From: s_nakamoto Date: Sat, 14 Nov 2009 18:04:08 +0000 Subject: misc compile error --- net.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net.h b/net.h index 6300d3efcf..65bbb96077 100644 --- a/net.h +++ b/net.h @@ -550,7 +550,7 @@ public: CAddress addrYou = (fUseProxy ? CAddress("0.0.0.0") : addr); CAddress addrMe = (fUseProxy ? CAddress("0.0.0.0") : addrLocalHost); RAND_bytes((unsigned char*)&nLocalHostNonce, sizeof(nLocalHostNonce)); - PushMessage("version", VERSION, nLocalServices, nTime, addrYou, addrMe, nLocalHostNonce, "linux-test5"); + PushMessage("version", VERSION, nLocalServices, nTime, addrYou, addrMe, nLocalHostNonce, string("test5")); } ~CNode() -- cgit v1.2.3 From b349e3dca89dfff5fe70669f9fd3f3a1ec60a498 Mon Sep 17 00:00:00 2001 From: s_nakamoto Date: Sat, 14 Nov 2009 18:04:08 +0000 Subject: misc compile error git-svn-id: https://bitcoin.svn.sourceforge.net/svnroot/bitcoin/trunk@39 1a98c847-1fd6-4fd8-948a-caf3550aa51b --- net.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net.h b/net.h index 6300d3efcf..65bbb96077 100644 --- a/net.h +++ b/net.h @@ -550,7 +550,7 @@ public: CAddress addrYou = (fUseProxy ? CAddress("0.0.0.0") : addr); CAddress addrMe = (fUseProxy ? CAddress("0.0.0.0") : addrLocalHost); RAND_bytes((unsigned char*)&nLocalHostNonce, sizeof(nLocalHostNonce)); - PushMessage("version", VERSION, nLocalServices, nTime, addrYou, addrMe, nLocalHostNonce, "linux-test5"); + PushMessage("version", VERSION, nLocalServices, nTime, addrYou, addrMe, nLocalHostNonce, string("test5")); } ~CNode() -- cgit v1.2.3 From e4db374421cac4c6fd0d9f9b337d9073e5207c21 Mon Sep 17 00:00:00 2001 From: s_nakamoto Date: Wed, 18 Nov 2009 19:19:41 +0000 Subject: bugfix Db::open/close and zombie sockets bugs fix double-close of socket handle, keep databases open, close db cursors, initial block download in batches of 500 blocks, fix misc warnings, subver linux-test8 --- build-unix.txt | 16 ++---- db.cpp | 130 +++++++++++++++++++++++++++++++++---------------- db.h | 17 ++++--- irc.cpp | 14 ++++-- main.cpp | 87 +++++++++++++++++++++------------ main.h | 10 ++-- makefile.unix | 7 +-- net.cpp | 110 ++++++++++++++++++++++++----------------- net.h | 16 ++++-- serialize.h | 1 + ui.cpp | 27 +++++----- util.cpp | 10 ++-- util.h | 23 ++++++++- xpm/addressbook16.xpm | 2 +- xpm/addressbook20.xpm | 2 +- xpm/bitcoin16.xpm | 2 +- xpm/bitcoin20.xpm | 2 +- xpm/bitcoin32.xpm | 2 +- xpm/bitcoin48.xpm | 2 +- xpm/check.xpm | 2 +- xpm/send16.xpm | 2 +- xpm/send16noshadow.xpm | 2 +- xpm/send20.xpm | 2 +- 23 files changed, 304 insertions(+), 184 deletions(-) diff --git a/build-unix.txt b/build-unix.txt index ceb61ad545..f863b6a98c 100644 --- a/build-unix.txt +++ b/build-unix.txt @@ -13,18 +13,18 @@ UNIX BUILD NOTES Dependencies ------------ -Install the dev files for the shared libraries: apt-get install build-essential apt-get install libgtk2.0-dev apt-get install libssl-dev +apt-get install libdb4.7-dev +apt-get install libdb4.7++-dev +apt-get install libboost-dev Libraries you need to obtain separately and build: default path download wxWidgets \wxwidgets http://www.wxwidgets.org/downloads/ -Berkeley DB \db http://www.oracle.com/technology/software/products/berkeley-db/index.html -Boost \boost http://www.boost.org/users/download/ -Their licenses: +Licenses: 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 @@ -59,15 +59,9 @@ make install ldconfig -Berkeley DB ------------ -cd /usr/local/db-4.7.25.NC/build_unix -../dist/configure --enable-cxx -make - - Boost ----- +If you download and build Boost yourself cd /usr/local/boost_1_40_0 su ./bootstrap.sh diff --git a/db.cpp b/db.cpp index a9c42880ab..947aed2970 100644 --- a/db.cpp +++ b/db.cpp @@ -20,6 +20,7 @@ static CCriticalSection cs_db; static bool fDbEnvInit = false; DbEnv dbenv(0); static map mapFileUseCount; +static map mapDb; class CDBInit { @@ -39,21 +40,17 @@ public: instance_of_cdbinit; -CDB::CDB(const char* pszFile, const char* pszMode, bool fTxn) : pdb(NULL) +CDB::CDB(const char* pszFile, const char* pszMode) : pdb(NULL) { int ret; if (pszFile == NULL) return; + fReadOnly = (!strchr(pszMode, '+') && !strchr(pszMode, 'w')); bool fCreate = strchr(pszMode, 'c'); - bool fReadOnly = (!strchr(pszMode, '+') && !strchr(pszMode, 'w')); unsigned int nFlags = DB_THREAD; if (fCreate) nFlags |= DB_CREATE; - else if (fReadOnly) - nFlags |= DB_RDONLY; - if (!fReadOnly || fTxn) - nFlags |= DB_AUTO_COMMIT; CRITICAL_BLOCK(cs_db) { @@ -72,7 +69,7 @@ CDB::CDB(const char* pszFile, const char* pszMode, bool fTxn) : pdb(NULL) dbenv.set_lk_max_locks(10000); dbenv.set_lk_max_objects(10000); dbenv.set_errfile(fopen(strErrorFile.c_str(), "a")); /// debug - ///dbenv.log_set_config(DB_LOG_AUTO_REMOVE, 1); /// causes corruption + dbenv.set_flags(DB_AUTO_COMMIT, 1); ret = dbenv.open(strDataDir.c_str(), DB_CREATE | DB_INIT_LOCK | @@ -90,31 +87,39 @@ CDB::CDB(const char* pszFile, const char* pszMode, bool fTxn) : pdb(NULL) strFile = pszFile; ++mapFileUseCount[strFile]; - } - - pdb = new Db(&dbenv, 0); + pdb = mapDb[strFile]; + if (pdb == NULL) + { + pdb = new Db(&dbenv, 0); - ret = pdb->open(NULL, // Txn pointer - pszFile, // Filename - "main", // Logical db name - DB_BTREE, // Database type - nFlags, // Flags - 0); + ret = pdb->open(NULL, // Txn pointer + pszFile, // Filename + "main", // Logical db name + DB_BTREE, // Database type + nFlags, // Flags + 0); - if (ret > 0) - { - delete pdb; - pdb = NULL; - CRITICAL_BLOCK(cs_db) - --mapFileUseCount[strFile]; - strFile = ""; - throw runtime_error(strprintf("CDB() : can't open database file %s, error %d\n", pszFile, ret)); - } + if (ret > 0) + { + delete pdb; + pdb = NULL; + CRITICAL_BLOCK(cs_db) + --mapFileUseCount[strFile]; + strFile = ""; + throw runtime_error(strprintf("CDB() : can't open database file %s, error %d\n", pszFile, ret)); + } - if (fCreate && !Exists(string("version"))) - WriteVersion(VERSION); + if (fCreate && !Exists(string("version"))) + { + bool fTmp = fReadOnly; + fReadOnly = false; + WriteVersion(VERSION); + fReadOnly = fTmp; + } - RandAddSeed(); + mapDb[strFile] = pdb; + } + } } void CDB::Close() @@ -124,8 +129,6 @@ void CDB::Close() if (!vTxn.empty()) vTxn.front()->abort(); vTxn.clear(); - pdb->close(0); - delete pdb; pdb = NULL; dbenv.txn_checkpoint(0, 0, 0); @@ -135,6 +138,21 @@ void CDB::Close() RandAddSeed(); } +void CloseDb(const string& strFile) +{ + CRITICAL_BLOCK(cs_db) + { + if (mapDb[strFile] != NULL) + { + // Close the database handle + Db* pdb = mapDb[strFile]; + pdb->close(0); + delete pdb; + mapDb[strFile] = NULL; + } + } +} + void DBFlush(bool fShutdown) { // Flush log data to the actual data file @@ -144,14 +162,18 @@ void DBFlush(bool fShutdown) return; CRITICAL_BLOCK(cs_db) { - dbenv.txn_checkpoint(0, 0, 0); map::iterator mi = mapFileUseCount.begin(); while (mi != mapFileUseCount.end()) { string strFile = (*mi).first; int nRefCount = (*mi).second; + printf("%s refcount=%d\n", strFile.c_str(), nRefCount); if (nRefCount == 0) { + // Move log data to the dat file + CloseDb(strFile); + dbenv.txn_checkpoint(0, 0, 0); + printf("%s flush\n", strFile.c_str()); dbenv.lsn_reset(strFile.c_str(), 0); mapFileUseCount.erase(mi++); } @@ -238,7 +260,10 @@ bool CTxDB::ReadOwnerTxes(uint160 hash160, int nMinHeight, vector& if (ret == DB_NOTFOUND) break; else if (ret != 0) + { + pcursor->close(); return false; + } // Unserialize string strType; @@ -255,9 +280,14 @@ bool CTxDB::ReadOwnerTxes(uint160 hash160, int nMinHeight, vector& { vtx.resize(vtx.size()+1); if (!vtx.back().ReadFromDisk(pos)) + { + pcursor->close(); return false; + } } } + + pcursor->close(); return true; } @@ -379,6 +409,7 @@ bool CTxDB::LoadBlockIndex() break; } } + pcursor->close(); if (!ReadHashBestChain(hashBestChain)) { @@ -391,7 +422,7 @@ bool CTxDB::LoadBlockIndex() return error("CTxDB::LoadBlockIndex() : blockindex for hashBestChain not found"); pindexBest = mapBlockIndex[hashBestChain]; nBestHeight = pindexBest->nHeight; - printf("LoadBlockIndex(): hashBestChain=%s height=%d\n", hashBestChain.ToString().substr(0,14).c_str(), nBestHeight); + printf("LoadBlockIndex(): hashBestChain=%s height=%d\n", hashBestChain.ToString().substr(0,16).c_str(), nBestHeight); return true; } @@ -456,6 +487,7 @@ bool CAddrDB::LoadAddresses() mapAddresses.insert(make_pair(addr.GetKey(), addr)); } } + pcursor->close(); printf("Loaded %d addresses\n", mapAddresses.size()); @@ -558,7 +590,7 @@ bool CWalletDB::LoadWallet(vector& vchDefaultKeyRet) //printf(" %12I64d %s %s %s\n", // wtx.vout[0].nValue, // DateTimeStrFormat("%x %H:%M:%S", wtx.nTime).c_str(), - // wtx.hashBlock.ToString().substr(0,14).c_str(), + // wtx.hashBlock.ToString().substr(0,16).c_str(), // wtx.mapValue["message"].c_str()); } else if (strType == "key") @@ -596,6 +628,7 @@ bool CWalletDB::LoadWallet(vector& vchDefaultKeyRet) } } + pcursor->close(); } printf("fShowGenerated = %d\n", fShowGenerated); @@ -655,6 +688,8 @@ void ThreadFlushWalletDB(void* parg) if (fOneThread) return; fOneThread = true; + if (mapArgs.count("-noflushwallet")) + return; unsigned int nLastSeen = nWalletDBUpdated; unsigned int nLastFlushed = nWalletDBUpdated; @@ -669,24 +704,37 @@ void ThreadFlushWalletDB(void* parg) nLastWalletUpdate = GetTime(); } - if (nLastFlushed != nWalletDBUpdated && nLastWalletUpdate < GetTime() - 1) + if (nLastFlushed != nWalletDBUpdated && GetTime() - nLastWalletUpdate >= 2) { TRY_CRITICAL_BLOCK(cs_db) { - string strFile = "wallet.dat"; - map::iterator mi = mapFileUseCount.find(strFile); - if (mi != mapFileUseCount.end()) + // Don't do this if any databases are in use + int nRefCount = 0; + map::iterator mi = mapFileUseCount.begin(); + while (mi != mapFileUseCount.end()) { - int nRefCount = (*mi).second; - if (nRefCount == 0 && !fShutdown) + nRefCount += (*mi).second; + mi++; + } + + if (nRefCount == 0 && !fShutdown) + { + string strFile = "wallet.dat"; + map::iterator mi = mapFileUseCount.find(strFile); + if (mi != mapFileUseCount.end()) { - // Flush wallet.dat so it's self contained + printf("%s ", DateTimeStrFormat("%x %H:%M:%S", GetTime()).c_str()); + printf("Flushing wallet.dat\n"); nLastFlushed = nWalletDBUpdated; int64 nStart = GetTimeMillis(); + + // Flush wallet.dat so it's self contained + CloseDb(strFile); dbenv.txn_checkpoint(0, 0, 0); dbenv.lsn_reset(strFile.c_str(), 0); - printf("Flushed wallet.dat %"PRI64d"ms\n", GetTimeMillis() - nStart); + mapFileUseCount.erase(mi++); + printf("Flushed wallet.dat %"PRI64d"ms\n", GetTimeMillis() - nStart); } } } diff --git a/db.h b/db.h index d11b397eba..d32d2d5d2f 100644 --- a/db.h +++ b/db.h @@ -32,8 +32,9 @@ protected: Db* pdb; string strFile; vector vTxn; + bool fReadOnly; - explicit CDB(const char* pszFile, const char* pszMode="r+", bool fTxn=false); + explicit CDB(const char* pszFile, const char* pszMode="r+"); ~CDB() { Close(); } public: void Close(); @@ -77,6 +78,8 @@ protected: { if (!pdb) return false; + if (fReadOnly) + assert(("Write called on database in read-only mode", false)); // Key CDataStream ssKey(SER_DISK); @@ -104,6 +107,8 @@ protected: { if (!pdb) return false; + if (fReadOnly) + assert(("Erase called on database in read-only mode", false)); // Key CDataStream ssKey(SER_DISK); @@ -254,7 +259,7 @@ public: class CTxDB : public CDB { public: - CTxDB(const char* pszMode="r+", bool fTxn=false) : CDB(!fClient ? "blkindex.dat" : NULL, pszMode, fTxn) { } + CTxDB(const char* pszMode="r+") : CDB(!fClient ? "blkindex.dat" : NULL, pszMode) { } private: CTxDB(const CTxDB&); void operator=(const CTxDB&); @@ -283,7 +288,7 @@ public: class CReviewDB : public CDB { public: - CReviewDB(const char* pszMode="r+", bool fTxn=false) : CDB("reviews.dat", pszMode, fTxn) { } + CReviewDB(const char* pszMode="r+") : CDB("reviews.dat", pszMode) { } private: CReviewDB(const CReviewDB&); void operator=(const CReviewDB&); @@ -309,7 +314,7 @@ public: class CMarketDB : public CDB { public: - CMarketDB(const char* pszMode="r+", bool fTxn=false) : CDB("market.dat", pszMode, fTxn) { } + CMarketDB(const char* pszMode="r+") : CDB("market.dat", pszMode) { } private: CMarketDB(const CMarketDB&); void operator=(const CMarketDB&); @@ -322,7 +327,7 @@ private: class CAddrDB : public CDB { public: - CAddrDB(const char* pszMode="r+", bool fTxn=false) : CDB("addr.dat", pszMode, fTxn) { } + CAddrDB(const char* pszMode="r+") : CDB("addr.dat", pszMode) { } private: CAddrDB(const CAddrDB&); void operator=(const CAddrDB&); @@ -341,7 +346,7 @@ bool LoadAddresses(); class CWalletDB : public CDB { public: - CWalletDB(const char* pszMode="r+", bool fTxn=false) : CDB("wallet.dat", pszMode, fTxn) { } + CWalletDB(const char* pszMode="r+") : CDB("wallet.dat", pszMode) { } private: CWalletDB(const CWalletDB&); void operator=(const CWalletDB&); diff --git a/irc.cpp b/irc.cpp index 8432c6d145..8ac38380eb 100644 --- a/irc.cpp +++ b/irc.cpp @@ -159,15 +159,12 @@ void ThreadIRCSeed(void* parg) SetThreadPriority(THREAD_PRIORITY_NORMAL); int nErrorWait = 10; int nRetryWait = 10; - - // IRC server blocks TOR users - if (fUseProxy && addrProxy.port == htons(9050)) - return; + bool fTOR = (fUseProxy && addrProxy.port == htons(9050)); while (!fShutdown) { CAddress addrConnect("216.155.130.130:6667"); - if (!(fUseProxy && addrProxy.port == htons(9050))) + if (!fTOR) { struct hostent* phostent = gethostbyname("chat.freenode.net"); if (phostent && phostent->h_addr_list && phostent->h_addr_list[0]) @@ -188,6 +185,7 @@ void ThreadIRCSeed(void* parg) if (!RecvUntil(hSocket, "Found your hostname", "using your IP address instead", "Couldn't look up your hostname")) { closesocket(hSocket); + hSocket = INVALID_SOCKET; nErrorWait = nErrorWait * 11 / 10; if (Wait(nErrorWait += 60)) continue; @@ -208,6 +206,7 @@ void ThreadIRCSeed(void* parg) if (!RecvUntil(hSocket, " 004 ")) { closesocket(hSocket); + hSocket = INVALID_SOCKET; nErrorWait = nErrorWait * 11 / 10; if (Wait(nErrorWait += 60)) continue; @@ -269,6 +268,11 @@ void ThreadIRCSeed(void* parg) } } closesocket(hSocket); + hSocket = INVALID_SOCKET; + + // IRC usually blocks TOR, so only try once + if (fTOR) + return; if (GetTime() - nStart > 20 * 60) { diff --git a/main.cpp b/main.cpp index 13a9f9b72a..89b42f76e0 100644 --- a/main.cpp +++ b/main.cpp @@ -760,7 +760,7 @@ unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast) bnNew = bnProofOfWorkLimit; /// debug print - printf("\n\n\nGetNextWorkRequired RETARGET *****\n"); + printf("GetNextWorkRequired RETARGET\n"); printf("nTargetTimespan = %d nActualTimespan = %d\n", nTargetTimespan, nActualTimespan); printf("Before: %08x %s\n", pindexLast->nBits, CBigNum().SetCompact(pindexLast->nBits).getuint256().ToString().c_str()); printf("After: %08x %s\n", bnNew.GetCompact(), bnNew.getuint256().ToString().c_str()); @@ -1013,7 +1013,7 @@ bool CBlock::ConnectBlock(CTxDB& txdb, CBlockIndex* pindex) bool Reorganize(CTxDB& txdb, CBlockIndex* pindexNew) { - printf("*** REORGANIZE ***\n"); + printf("REORGANIZE\n"); // Find the fork CBlockIndex* pfork = pindexBest; @@ -1114,7 +1114,7 @@ bool CBlock::AddToBlockIndex(unsigned int nFile, unsigned int nBlockPos) // Check for duplicate uint256 hash = GetHash(); if (mapBlockIndex.count(hash)) - return error("AddToBlockIndex() : %s already exists", hash.ToString().substr(0,14).c_str()); + return error("AddToBlockIndex() : %s already exists", hash.ToString().substr(0,16).c_str()); // Construct new block index object CBlockIndex* pindexNew = new CBlockIndex(nFile, nBlockPos, *this); @@ -1174,7 +1174,7 @@ bool CBlock::AddToBlockIndex(unsigned int nFile, unsigned int nBlockPos) pindexBest = pindexNew; nBestHeight = pindexBest->nHeight; nTransactionsUpdated++; - printf("AddToBlockIndex: new best=%s height=%d\n", hashBestChain.ToString().substr(0,14).c_str(), nBestHeight); + printf("AddToBlockIndex: new best=%s height=%d\n", hashBestChain.ToString().substr(0,16).c_str(), nBestHeight); } txdb.TxnCommit(); @@ -1294,9 +1294,9 @@ bool ProcessBlock(CNode* pfrom, CBlock* pblock) // Check for duplicate uint256 hash = pblock->GetHash(); if (mapBlockIndex.count(hash)) - return error("ProcessBlock() : already have block %d %s", mapBlockIndex[hash]->nHeight, hash.ToString().substr(0,14).c_str()); + return error("ProcessBlock() : already have block %d %s", mapBlockIndex[hash]->nHeight, hash.ToString().substr(0,16).c_str()); if (mapOrphanBlocks.count(hash)) - return error("ProcessBlock() : already have block (orphan) %s", hash.ToString().substr(0,14).c_str()); + return error("ProcessBlock() : already have block (orphan) %s", hash.ToString().substr(0,16).c_str()); // Preliminary checks if (!pblock->CheckBlock()) @@ -1308,7 +1308,7 @@ bool ProcessBlock(CNode* pfrom, CBlock* pblock) // If don't already have its previous block, shunt it off to holding area until we get it if (!mapBlockIndex.count(pblock->hashPrevBlock)) { - printf("ProcessBlock: ORPHAN BLOCK, prev=%s\n", pblock->hashPrevBlock.ToString().substr(0,14).c_str()); + printf("ProcessBlock: ORPHAN BLOCK, prev=%s\n", pblock->hashPrevBlock.ToString().substr(0,16).c_str()); mapOrphanBlocks.insert(make_pair(hash, pblock)); mapOrphanBlocksByPrev.insert(make_pair(pblock->hashPrevBlock, pblock)); @@ -1503,11 +1503,11 @@ bool LoadBlockIndex(bool fAllowNew) // vMerkleTree: 4a5e1e // Genesis block - char* pszTimestamp = "The Times 03/Jan/2009 Chancellor on brink of second bailout for banks"; + const char* pszTimestamp = "The Times 03/Jan/2009 Chancellor on brink of second bailout for banks"; CTransaction txNew; txNew.vin.resize(1); txNew.vout.resize(1); - txNew.vin[0].scriptSig = CScript() << 486604799 << CBigNum(4) << vector((unsigned char*)pszTimestamp, (unsigned char*)pszTimestamp + strlen(pszTimestamp)); + txNew.vin[0].scriptSig = CScript() << 486604799 << CBigNum(4) << vector((const unsigned char*)pszTimestamp, (const unsigned char*)pszTimestamp + strlen(pszTimestamp)); txNew.vout[0].nValue = 50 * COIN; txNew.vout[0].scriptPubKey = CScript() << CBigNum("0x5F1DF16B2B704C8A578D0BBAF74D385CDE12C11EE50455F3C438EF4C3FBCF649B6DE611FEAE06279A60939E028A8D65C10B73071A6F16719274855FEB0FD8A6704") << OP_CHECKSIG; CBlock block; @@ -1519,7 +1519,7 @@ bool LoadBlockIndex(bool fAllowNew) block.nBits = 0x1d00ffff; block.nNonce = 2083236893; - //// debug print, delete this later + //// debug print printf("%s\n", block.GetHash().ToString().c_str()); printf("%s\n", block.hashMerkleRoot.ToString().c_str()); printf("%s\n", hashGenesisBlock.ToString().c_str()); @@ -1592,7 +1592,7 @@ void PrintBlockTree() pindex->nHeight, pindex->nFile, pindex->nBlockPos, - block.GetHash().ToString().substr(0,14).c_str(), + block.GetHash().ToString().substr(0,16).c_str(), DateTimeStrFormat("%x %H:%M:%S", block.nTime).c_str(), block.vtx.size()); @@ -1912,6 +1912,18 @@ bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) CBlock block; block.ReadFromDisk((*mi).second, !pfrom->fClient); pfrom->PushMessage("block", block); + + // Trigger them to send a getblocks request for the next batch of inventory + if (inv.hash == pfrom->hashContinue) + { + // Bypass PushInventory, this must send even if redundant, + // and we want it right after the last block so they don't + // wait for other stuff first. + vector vInv; + vInv.push_back(CInv(MSG_BLOCK, hashBestChain)); + pfrom->PushMessage("inv", vInv); + pfrom->hashContinue = 0; + } } } else if (inv.IsKnownType()) @@ -1948,25 +1960,23 @@ bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) // Send the rest of the chain if (pindex) pindex = pindex->pnext; - printf("getblocks %d to %s\n", (pindex ? pindex->nHeight : -1), hashStop.ToString().substr(0,14).c_str()); + printf("getblocks %d to %s\n", (pindex ? pindex->nHeight : -1), hashStop.ToString().substr(0,16).c_str()); + int nLimit = 500; for (; pindex; pindex = pindex->pnext) { if (pindex->GetBlockHash() == hashStop) { - printf(" getblocks stopping at %d %s\n", pindex->nHeight, pindex->GetBlockHash().ToString().substr(0,14).c_str()); + printf(" getblocks stopping at %d %s\n", pindex->nHeight, pindex->GetBlockHash().ToString().substr(0,16).c_str()); break; } - - // Bypass setInventoryKnown in case an inventory message got lost - CRITICAL_BLOCK(pfrom->cs_inventory) + pfrom->PushInventory(CInv(MSG_BLOCK, pindex->GetBlockHash())); + if (--nLimit <= 0) { - CInv inv(MSG_BLOCK, pindex->GetBlockHash()); - // returns true if wasn't already contained in the set - if (pfrom->setInventoryKnown2.insert(inv).second) - { - pfrom->setInventoryKnown.erase(inv); - pfrom->vInventoryToSend.push_back(inv); - } + // When this block is requested, we'll send an inv that'll make them + // getblocks the next batch of inventory. + printf(" getblocks stopping at limit %d %s\n", pindex->nHeight, pindex->GetBlockHash().ToString().substr(0,16).c_str()); + pfrom->hashContinue = pindex->GetBlockHash(); + break; } } } @@ -2049,7 +2059,13 @@ bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) vRecv >> *pblock; //// debug print - printf("received block:\n"); pblock->print(); + if (false) + { + printf("received block:\n"); + pblock->print(); + } + else + printf("received block %s\n", pblock->GetHash().ToString().substr(0,16).c_str()); CInv inv(MSG_BLOCK, pblock->GetHash()); pfrom->AddInventoryKnown(inv); @@ -2175,9 +2191,13 @@ bool SendMessages(CNode* pto) if (pto->nVersion == 0) return true; + // Keep-alive ping + if (pto->nLastSend && GetTime() - pto->nLastSend > 12 * 60 && pto->vSend.empty()) + pto->PushMessage("ping"); + // Address refresh broadcast static int64 nLastRebroadcast; - if (nLastRebroadcast < GetTime() - 24 * 60 * 60) // every 24 hours + if (GetTime() - nLastRebroadcast > 24 * 60 * 60) // every 24 hours { nLastRebroadcast = GetTime(); CRITICAL_BLOCK(cs_vNodes) @@ -2194,9 +2214,16 @@ bool SendMessages(CNode* pto) } } - // Keep-alive ping - if (pto->nLastSend && GetTime() - pto->nLastSend > 12 * 60 && pto->vSend.empty()) - pto->PushMessage("ping"); + // Clear inventory known periodically in case an inv message was missed, + // although usually they would just get it from another node. + static int64 nLastInventoryKnownClear; + if (GetTime() - nLastInventoryKnownClear > 2 * 60 * 60) // every 2 hours + { + nLastInventoryKnownClear = GetTime(); + CRITICAL_BLOCK(cs_vNodes) + foreach(CNode* pnode, vNodes) + pnode->setInventoryKnown.clear(); + } // @@ -2243,7 +2270,6 @@ bool SendMessages(CNode* pto) } } pto->vInventoryToSend.clear(); - pto->setInventoryKnown2.clear(); } if (!vInventoryToSend.empty()) pto->PushMessage("inv", vInventoryToSend); @@ -2817,8 +2843,7 @@ bool CommitTransactionSpent(const CWalletTx& wtxNew, const CKey& key) // 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 - // maybe makes sense; please don't do it anywhere else. Keeping databases - // open longer than necessary can create deadlocks. + // maybe makes sense; please don't do it anywhere else. CWalletDB walletdb("r"); // Add the change's private key to wallet diff --git a/main.h b/main.h index 8bb1e19e8a..79f14c6861 100644 --- a/main.h +++ b/main.h @@ -1009,9 +1009,9 @@ public: void print() const { printf("CBlock(hash=%s, ver=%d, hashPrevBlock=%s, hashMerkleRoot=%s, nTime=%u, nBits=%08x, nNonce=%u, vtx=%d)\n", - GetHash().ToString().substr(0,14).c_str(), + GetHash().ToString().substr(0,16).c_str(), nVersion, - hashPrevBlock.ToString().substr(0,14).c_str(), + hashPrevBlock.ToString().substr(0,16).c_str(), hashMerkleRoot.ToString().substr(0,6).c_str(), nTime, nBits, nNonce, vtx.size()); @@ -1159,7 +1159,7 @@ public: return strprintf("CBlockIndex(nprev=%08x, pnext=%08x, nFile=%d, nBlockPos=%-6d nHeight=%d, merkle=%s, hashBlock=%s)", pprev, pnext, nFile, nBlockPos, nHeight, hashMerkleRoot.ToString().substr(0,6).c_str(), - GetBlockHash().ToString().substr(0,14).c_str()); + GetBlockHash().ToString().substr(0,16).c_str()); } void print() const @@ -1229,8 +1229,8 @@ public: str += CBlockIndex::ToString(); str += strprintf("\n hashBlock=%s, hashPrev=%s, hashNext=%s)", GetBlockHash().ToString().c_str(), - hashPrev.ToString().substr(0,14).c_str(), - hashNext.ToString().substr(0,14).c_str()); + hashPrev.ToString().substr(0,16).c_str(), + hashNext.ToString().substr(0,16).c_str()); return str; } diff --git a/makefile.unix b/makefile.unix index 24aa8bfe4f..c0d0ee1d00 100644 --- a/makefile.unix +++ b/makefile.unix @@ -17,24 +17,21 @@ endif INCLUDEPATHS= \ -I"/usr/include" \ - -I"/usr/local/boost_1_40_0" \ - -I"/usr/local/db-4.7.25.NC/build_unix" \ -I"/usr/local/include/wx-2.8" \ -I"/usr/local/lib/wx/include/gtk2-ansi-debug-static-2.8" LIBPATHS= \ -L"/usr/lib" \ -L"/usr/local/lib" \ - -L"/usr/local/db-4.7.25.NC/build_unix" LIBS= \ - -Wl,-Bstatic -l boost_thread -l boost_system -l boost_filesystem -Wl,-Bdynamic \ + -Wl,-Bstatic -l boost_system -l boost_filesystem -Wl,-Bdynamic \ -Wl,-Bstatic -l db_cxx -l wx_gtk2$(D)-2.8 -Wl,-Bdynamic \ -l crypto \ -l gtk-x11-2.0 -l gthread-2.0 -l SM WXDEFS=-D__WXGTK__ -DNOPCH -CFLAGS=-O0 -w -Wno-invalid-offsetof -Wformat $(DEBUGFLAGS) $(WXDEFS) $(INCLUDEPATHS) +CFLAGS=-O0 -Wno-invalid-offsetof -Wformat $(DEBUGFLAGS) $(WXDEFS) $(INCLUDEPATHS) HEADERS=headers.h util.h main.h serialize.h uint256.h key.h bignum.h script.h db.h base58.h diff --git a/net.cpp b/net.cpp index 71295d5dee..9f4060b9da 100644 --- a/net.cpp +++ b/net.cpp @@ -148,8 +148,8 @@ bool GetMyExternalIP2(const CAddress& addrConnect, const char* pszGet, const cha bool GetMyExternalIP(unsigned int& ipRet) { CAddress addrConnect; - char* pszGet; - char* pszKeyword; + const char* pszGet; + const char* pszKeyword; if (fUseProxy) return false; @@ -463,14 +463,21 @@ CNode* ConnectNode(CAddress addrConnect, int64 nTimeout) } } -void CNode::DoDisconnect() +void CNode::CloseSocketDisconnect() { - if (fDebug) - printf("%s ", DateTimeStrFormat("%x %H:%M:%S", GetTime()).c_str()); - printf("disconnecting node %s\n", addr.ToStringLog().c_str()); - - closesocket(hSocket); + fDisconnect = true; + if (hSocket != INVALID_SOCKET) + { + if (fDebug) + printf("%s ", DateTimeStrFormat("%x %H:%M:%S", GetTime()).c_str()); + printf("disconnecting node %s\n", addr.ToStringLog().c_str()); + closesocket(hSocket); + hSocket = INVALID_SOCKET; + } +} +void CNode::Cleanup() +{ // All of a nodes broadcasts and subscriptions are automatically torn down // when it goes down, so a node has to stay up to keep its broadcast going. @@ -540,11 +547,12 @@ void ThreadSocketHandler2(void* parg) // remove from vNodes vNodes.erase(remove(vNodes.begin(), vNodes.end(), pnode), vNodes.end()); - // close socket - pnode->DoDisconnect(); + // close socket and cleanup + pnode->CloseSocketDisconnect(); + pnode->Cleanup(); // hold in disconnected pool until all refs are released - pnode->nReleaseTime = max(pnode->nReleaseTime, GetTime() + 5 * 60); + pnode->nReleaseTime = max(pnode->nReleaseTime, GetTime() + 15 * 60); if (pnode->fNetworkNode || pnode->fInbound) pnode->Release(); vNodesDisconnected.push_back(pnode); @@ -599,6 +607,8 @@ void ThreadSocketHandler2(void* parg) { foreach(CNode* pnode, vNodes) { + if (pnode->hSocket == INVALID_SOCKET || pnode->hSocket < 0) + continue; FD_SET(pnode->hSocket, &fdsetRecv); FD_SET(pnode->hSocket, &fdsetError); hSocketMax = max(hSocketMax, pnode->hSocket); @@ -659,17 +669,22 @@ void ThreadSocketHandler2(void* parg) // vector vNodesCopy; CRITICAL_BLOCK(cs_vNodes) + { vNodesCopy = vNodes; + foreach(CNode* pnode, vNodesCopy) + pnode->AddRef(); + } foreach(CNode* pnode, vNodesCopy) { if (fShutdown) return; - SOCKET hSocket = pnode->hSocket; // // Receive // - if (FD_ISSET(hSocket, &fdsetRecv) || FD_ISSET(hSocket, &fdsetError)) + if (pnode->hSocket == INVALID_SOCKET) + continue; + if (FD_ISSET(pnode->hSocket, &fdsetRecv) || FD_ISSET(pnode->hSocket, &fdsetError)) { TRY_CRITICAL_BLOCK(pnode->cs_vRecv) { @@ -678,7 +693,7 @@ void ThreadSocketHandler2(void* parg) // typical socket buffer is 8K-64K char pchBuf[0x10000]; - int nBytes = recv(hSocket, pchBuf, sizeof(pchBuf), MSG_DONTWAIT); + int nBytes = recv(pnode->hSocket, pchBuf, sizeof(pchBuf), MSG_DONTWAIT); if (nBytes > 0) { vRecv.resize(nPos + nBytes); @@ -690,7 +705,7 @@ void ThreadSocketHandler2(void* parg) // socket closed gracefully if (!pnode->fDisconnect) printf("socket closed\n"); - pnode->fDisconnect = true; + pnode->CloseSocketDisconnect(); } else if (nBytes < 0) { @@ -700,7 +715,7 @@ void ThreadSocketHandler2(void* parg) { if (!pnode->fDisconnect) printf("socket recv error %d\n", nErr); - pnode->fDisconnect = true; + pnode->CloseSocketDisconnect(); } } } @@ -709,14 +724,16 @@ void ThreadSocketHandler2(void* parg) // // Send // - if (FD_ISSET(hSocket, &fdsetSend)) + if (pnode->hSocket == INVALID_SOCKET) + continue; + if (FD_ISSET(pnode->hSocket, &fdsetSend)) { TRY_CRITICAL_BLOCK(pnode->cs_vSend) { CDataStream& vSend = pnode->vSend; if (!vSend.empty()) { - int nBytes = send(hSocket, &vSend[0], vSend.size(), MSG_NOSIGNAL | MSG_DONTWAIT); + int nBytes = send(pnode->hSocket, &vSend[0], vSend.size(), MSG_NOSIGNAL | MSG_DONTWAIT); if (nBytes > 0) { vSend.erase(vSend.begin(), vSend.begin() + nBytes); @@ -729,7 +746,7 @@ void ThreadSocketHandler2(void* parg) if (nErr != WSAEWOULDBLOCK && nErr != WSAEMSGSIZE && nErr != WSAEINTR && nErr != WSAEINPROGRESS) { printf("socket send error %d\n", nErr); - pnode->fDisconnect = true; + pnode->CloseSocketDisconnect(); } } } @@ -760,18 +777,12 @@ void ThreadSocketHandler2(void* parg) } } } - - - //// debug heartbeat - static int64 nHeartbeat1; - if (GetTime() - nHeartbeat1 >= 5 * 60) + CRITICAL_BLOCK(cs_vNodes) { - printf("%s sendrecv\n", DateTimeStrFormat("%x %H:%M:%S", GetTime()).c_str()); - nHeartbeat1 = GetTime(); - fDebug = true; + foreach(CNode* pnode, vNodesCopy) + pnode->Release(); } - nThreadSocketHandlerHeartbeat = GetTime(); Sleep(10); } @@ -812,18 +823,21 @@ void ThreadOpenConnections2(void* parg) printf("ThreadOpenConnections started\n"); // Connect to specific addresses - while (mapArgs.count("-connect")) + if (mapArgs.count("-connect")) { - foreach(string strAddr, mapMultiArgs["-connect"]) + for (int64 nLoop = 0;; nLoop++) { - CAddress addr(strAddr, NODE_NETWORK); - if (addr.IsValid()) - OpenNetworkConnection(addr); - for (int i = 0; i < 10; i++) + foreach(string strAddr, mapMultiArgs["-connect"]) { - Sleep(1000); - if (fShutdown) - return; + CAddress addr(strAddr, NODE_NETWORK); + if (addr.IsValid()) + OpenNetworkConnection(addr); + for (int i = 0; i < 10 && i < nLoop; i++) + { + Sleep(500); + if (fShutdown) + return; + } } } } @@ -837,7 +851,7 @@ void ThreadOpenConnections2(void* parg) if (addr.IsValid()) { OpenNetworkConnection(addr); - Sleep(1000); + Sleep(500); if (fShutdown) return; } @@ -898,7 +912,7 @@ void ThreadOpenConnections2(void* parg) // 30 days 27 hours // 90 days 46 hours // 365 days 93 hours - int64 nDelay = 3600.0 * sqrt(fabs(nSinceLastSeen) / 3600.0) + nRandomizer; + int64 nDelay = (int64)(3600.0 * sqrt(fabs(nSinceLastSeen) / 3600.0) + nRandomizer); // Fast reconnect for one hour after last seen if (nSinceLastSeen < 60 * 60) @@ -1013,11 +1027,13 @@ void ThreadMessageHandler2(void* parg) // Poll the connected nodes for messages vector vNodesCopy; CRITICAL_BLOCK(cs_vNodes) + { vNodesCopy = vNodes; + foreach(CNode* pnode, vNodesCopy) + pnode->AddRef(); + } foreach(CNode* pnode, vNodesCopy) { - pnode->AddRef(); - // Receive messages TRY_CRITICAL_BLOCK(pnode->cs_vRecv) ProcessMessages(pnode); @@ -1029,8 +1045,11 @@ void ThreadMessageHandler2(void* parg) SendMessages(pnode); if (fShutdown) return; - - pnode->Release(); + } + CRITICAL_BLOCK(cs_vNodes) + { + foreach(CNode* pnode, vNodesCopy) + pnode->Release(); } // Wait and allow messages to bunch up @@ -1257,8 +1276,7 @@ void StartNode(void* parg) if (!fGot) { printf("*** closing socket\n"); - closesocket(pnode->hSocket); - pnode->fDisconnect = true; + pnode->CloseSocketDisconnect(); } } } @@ -1292,7 +1310,7 @@ bool StopNode() int64 nStart = GetTime(); while (vnThreadsRunning[0] > 0 || vnThreadsRunning[2] > 0 || vnThreadsRunning[3] > 0) { - if (GetTime() - nStart > 15) + if (GetTime() - nStart > 20) break; Sleep(20); } diff --git a/net.h b/net.h index 65bbb96077..7d71be49da 100644 --- a/net.h +++ b/net.h @@ -414,7 +414,7 @@ public: string ToString() const { - return strprintf("%s %s", GetCommand(), hash.ToString().substr(0,14).c_str()); + return strprintf("%s %s", GetCommand(), hash.ToString().substr(0,16).c_str()); } void print() const @@ -504,6 +504,7 @@ public: int64 nReleaseTime; map mapRequests; CCriticalSection cs_mapRequests; + uint256 hashContinue; // flood vector vAddrToSend; @@ -512,7 +513,6 @@ public: // inventory based relay set setInventoryKnown; - set setInventoryKnown2; vector vInventoryToSend; CCriticalSection cs_inventory; multimap mapAskFor; @@ -541,6 +541,7 @@ public: fDisconnect = false; nRefCount = 0; nReleaseTime = 0; + hashContinue = 0; fGetAddr = false; vfSubscribe.assign(256, false); @@ -550,13 +551,16 @@ public: CAddress addrYou = (fUseProxy ? CAddress("0.0.0.0") : addr); CAddress addrMe = (fUseProxy ? CAddress("0.0.0.0") : addrLocalHost); RAND_bytes((unsigned char*)&nLocalHostNonce, sizeof(nLocalHostNonce)); - PushMessage("version", VERSION, nLocalServices, nTime, addrYou, addrMe, nLocalHostNonce, string("test5")); + PushMessage("version", VERSION, nLocalServices, nTime, addrYou, addrMe, nLocalHostNonce, string(pszSubVer)); } ~CNode() { if (hSocket != INVALID_SOCKET) + { closesocket(hSocket); + hSocket = INVALID_SOCKET; + } } private: @@ -570,12 +574,13 @@ public: return max(nRefCount, 0) + (GetTime() < nReleaseTime ? 1 : 0); } - void AddRef(int64 nTimeout=0) + CNode* AddRef(int64 nTimeout=0) { if (nTimeout != 0) nReleaseTime = max(nReleaseTime, GetTime() + nTimeout); else nRefCount++; + return this; } void Release() @@ -899,7 +904,8 @@ public: bool IsSubscribed(unsigned int nChannel); void Subscribe(unsigned int nChannel, unsigned int nHops=0); void CancelSubscribe(unsigned int nChannel); - void DoDisconnect(); + void CloseSocketDisconnect(); + void Cleanup(); }; diff --git a/serialize.h b/serialize.h index 9b20e2a0f6..aae821b6d2 100644 --- a/serialize.h +++ b/serialize.h @@ -20,6 +20,7 @@ class CDataStream; class CAutoFile; static const int VERSION = 106; +static const char* pszSubVer = " linux-test8"; diff --git a/ui.cpp b/ui.cpp index 9d7556cb57..aaa26adf00 100644 --- a/ui.cpp +++ b/ui.cpp @@ -1664,7 +1664,7 @@ void COptionsDialog::OnButtonApply(wxCommandEvent& event) CAboutDialog::CAboutDialog(wxWindow* parent) : CAboutDialogBase(parent) { - m_staticTextVersion->SetLabel(strprintf("version 0.%d.%d Beta", VERSION/100, VERSION%100)); + m_staticTextVersion->SetLabel(strprintf("version 0.%d.%d beta", VERSION/100, VERSION%100)); // Workaround until upgrade to wxWidgets supporting UTF-8 wxString str = m_staticTextMain->GetLabel(); @@ -2030,7 +2030,7 @@ void CSendingDialog::StartTransfer() // We may have connected already for product details if (!Status("Connecting...")) return; - CNode* pnode = ConnectNode(addr, 5 * 60); + CNode* pnode = ConnectNode(addr, 15 * 60); if (!pnode) { Error("Unable to connect"); @@ -2075,14 +2075,6 @@ void CSendingDialog::OnReply2(CDataStream& vRecv) return; } - // Should already be connected - CNode* pnode = ConnectNode(addr, 5 * 60); - if (!pnode) - { - Error("Lost connection"); - return; - } - // Pause to give the user a chance to cancel while (wxDateTime::UNow() < start + wxTimeSpan(0, 0, 0, 2 * 1000)) { @@ -2112,6 +2104,14 @@ void CSendingDialog::OnReply2(CDataStream& vRecv) 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()) @@ -3495,12 +3495,14 @@ bool CMyApp::OnInit2() if (mapArgs.count("-debug")) fDebug = true; + if (strstr(pszSubVer, "test")) + fDebug = true; if (mapArgs.count("-printtodebugger")) fPrintToDebugger = true; printf("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"); - printf("Bitcoin version %d, OS version %s\n", VERSION, wxGetOsDescription().mb_str()); + printf("Bitcoin version %d%s, OS version %s\n", VERSION, pszSubVer, wxGetOsDescription().mb_str()); if (mapArgs.count("-loadblockindextest")) { @@ -3843,9 +3845,8 @@ void SetStartOnSystemStartup(bool fAutoStart) CoInitialize(NULL); // Get a pointer to the IShellLink interface. - HRESULT hres = NULL; IShellLink* psl = NULL; - hres = CoCreateInstance(CLSID_ShellLink, NULL, + HRESULT hres = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, reinterpret_cast(&psl)); diff --git a/util.cpp b/util.cpp index 7a947730ce..305db5ceeb 100644 --- a/util.cpp +++ b/util.cpp @@ -56,9 +56,11 @@ public: // Close sockets foreach(CNode* pnode, vNodes) - closesocket(pnode->hSocket); - if (closesocket(hListenSocket) == SOCKET_ERROR) - printf("closesocket(hListenSocket) failed with error %d\n", WSAGetLastError()); + if (pnode->hSocket != INVALID_SOCKET) + closesocket(pnode->hSocket); + if (hListenSocket != INVALID_SOCKET) + if (closesocket(hListenSocket) == SOCKET_ERROR) + printf("closesocket(hListenSocket) failed with error %d\n", WSAGetLastError()); #ifdef __WXMSW__ // Shutdown Windows Sockets @@ -348,7 +350,7 @@ void ParseParameters(int argc, char* argv[]) { char psz[10000]; strlcpy(psz, argv[i], sizeof(psz)); - char* pszValue = ""; + char* pszValue = (char*)""; if (strchr(psz, '=')) { pszValue = strchr(psz, '='); diff --git a/util.h b/util.h index ddac449441..9366e66e93 100644 --- a/util.h +++ b/util.h @@ -57,9 +57,11 @@ inline T& REF(const T& val) #ifdef __WXMSW__ #define MSG_NOSIGNAL 0 #define MSG_DONTWAIT 0 +#ifndef UINT64_MAX #define UINT64_MAX _UI64_MAX #define INT64_MAX _I64_MAX #define INT64_MIN _I64_MIN +#endif #else #define WSAGetLastError() errno #define WSAEWOULDBLOCK EWOULDBLOCK @@ -67,7 +69,7 @@ inline T& REF(const T& val) #define WSAEINTR EINTR #define WSAEINPROGRESS EINPROGRESS #define WSAEADDRINUSE EADDRINUSE -#define closesocket(s) close(s) +#define WSAENOTSOCK EBADF #define INVALID_SOCKET (SOCKET)(~0) #define SOCKET_ERROR -1 typedef u_int SOCKET; @@ -80,6 +82,23 @@ typedef u_int SOCKET; #define Beep(n1,n2) (0) #endif +inline int myclosesocket(SOCKET& hSocket) +{ + if (hSocket == INVALID_SOCKET) + return WSAENOTSOCK; +#ifdef __WXMSW__ + int ret = closesocket(hSocket); +#else + int ret = close(hSocket); +#endif + hSocket = INVALID_SOCKET; + return ret; +} +#define closesocket(s) myclosesocket(s) + + + + @@ -149,7 +168,7 @@ public: bool TryEnter() { return mutex.TryLock() == wxMUTEX_NO_ERROR; } #endif public: - char* pszFile; + const char* pszFile; int nLine; }; diff --git a/xpm/addressbook16.xpm b/xpm/addressbook16.xpm index 471f700c70..e00944ef7a 100644 --- a/xpm/addressbook16.xpm +++ b/xpm/addressbook16.xpm @@ -1,5 +1,5 @@ /* XPM */ -static char * addressbook16_xpm[] = { +static const char * addressbook16_xpm[] = { /* columns rows colors chars-per-pixel */ "16 16 256 2", " c #FFFFFF", diff --git a/xpm/addressbook20.xpm b/xpm/addressbook20.xpm index 48df12d801..7ebd73fb2f 100644 --- a/xpm/addressbook20.xpm +++ b/xpm/addressbook20.xpm @@ -1,5 +1,5 @@ /* XPM */ -static char * addressbook20_xpm[] = { +static const char * addressbook20_xpm[] = { /* columns rows colors chars-per-pixel */ "20 20 256 2", " c #FFFFFF", diff --git a/xpm/bitcoin16.xpm b/xpm/bitcoin16.xpm index 8bec142c8b..a1397522a5 100644 --- a/xpm/bitcoin16.xpm +++ b/xpm/bitcoin16.xpm @@ -1,5 +1,5 @@ /* XPM */ -static char * bitcoin16_xpm[] = { +static const char * bitcoin16_xpm[] = { /* columns rows colors chars-per-pixel */ "16 16 181 2", " c #775605", diff --git a/xpm/bitcoin20.xpm b/xpm/bitcoin20.xpm index 2dd61a59dc..93b34ba70c 100644 --- a/xpm/bitcoin20.xpm +++ b/xpm/bitcoin20.xpm @@ -1,5 +1,5 @@ /* XPM */ -static char * bitcoin20_xpm[] = { +static const char * bitcoin20_xpm[] = { /* columns rows colors chars-per-pixel */ "20 20 200 2", " c #7B5500", diff --git a/xpm/bitcoin32.xpm b/xpm/bitcoin32.xpm index 25da102f6a..0ac49f61a9 100644 --- a/xpm/bitcoin32.xpm +++ b/xpm/bitcoin32.xpm @@ -1,5 +1,5 @@ /* XPM */ -static char * bitcoin32_xpm[] = { +static const char * bitcoin32_xpm[] = { /* columns rows colors chars-per-pixel */ "32 32 185 2", " c #715103", diff --git a/xpm/bitcoin48.xpm b/xpm/bitcoin48.xpm index 788e855ddd..bc388bdcb7 100644 --- a/xpm/bitcoin48.xpm +++ b/xpm/bitcoin48.xpm @@ -1,5 +1,5 @@ /* XPM */ -static char * bitcoin48_xpm[] = { +static const char * bitcoin48_xpm[] = { /* columns rows colors chars-per-pixel */ "48 48 224 2", " c #715103", diff --git a/xpm/check.xpm b/xpm/check.xpm index 8f0b9d28ec..e62b656961 100644 --- a/xpm/check.xpm +++ b/xpm/check.xpm @@ -1,5 +1,5 @@ /* XPM */ -static char * check_xpm[] = { +static const char * check_xpm[] = { /* columns rows colors chars-per-pixel */ "32 32 3 1", " c #008000", diff --git a/xpm/send16.xpm b/xpm/send16.xpm index 1eeceb4ec7..7da44d9c56 100644 --- a/xpm/send16.xpm +++ b/xpm/send16.xpm @@ -1,5 +1,5 @@ /* XPM */ -static char * send16_xpm[] = { +static const char * send16_xpm[] = { /* columns rows colors chars-per-pixel */ "16 16 256 2", " c #ADF7AD", diff --git a/xpm/send16noshadow.xpm b/xpm/send16noshadow.xpm index d1b482ef97..f6cef45e0d 100644 --- a/xpm/send16noshadow.xpm +++ b/xpm/send16noshadow.xpm @@ -1,5 +1,5 @@ /* XPM */ -static char * send16noshadow_xpm[] = { +static const char * send16noshadow_xpm[] = { /* columns rows colors chars-per-pixel */ "16 16 256 2", " c #ADF7AD", diff --git a/xpm/send20.xpm b/xpm/send20.xpm index 597ea146d1..68e7b1379a 100644 --- a/xpm/send20.xpm +++ b/xpm/send20.xpm @@ -1,5 +1,5 @@ /* XPM */ -static char * send20_xpm[] = { +static const char * send20_xpm[] = { /* columns rows colors chars-per-pixel */ "20 20 256 2", " c #CEFFCE", -- cgit v1.2.3 From c5c7911dab8732861affbe66849a100da62f7464 Mon Sep 17 00:00:00 2001 From: s_nakamoto Date: Wed, 18 Nov 2009 19:19:41 +0000 Subject: bugfix Db::open/close and zombie sockets bugs fix double-close of socket handle, keep databases open, close db cursors, initial block download in batches of 500 blocks, fix misc warnings, subver linux-test8 git-svn-id: https://bitcoin.svn.sourceforge.net/svnroot/bitcoin/trunk@40 1a98c847-1fd6-4fd8-948a-caf3550aa51b --- build-unix.txt | 16 ++---- db.cpp | 130 +++++++++++++++++++++++++++++++++---------------- db.h | 17 ++++--- irc.cpp | 14 ++++-- main.cpp | 87 +++++++++++++++++++++------------ main.h | 10 ++-- makefile.unix | 7 +-- net.cpp | 110 ++++++++++++++++++++++++----------------- net.h | 16 ++++-- serialize.h | 1 + ui.cpp | 27 +++++----- util.cpp | 10 ++-- util.h | 23 ++++++++- xpm/addressbook16.xpm | 2 +- xpm/addressbook20.xpm | 2 +- xpm/bitcoin16.xpm | 2 +- xpm/bitcoin20.xpm | 2 +- xpm/bitcoin32.xpm | 2 +- xpm/bitcoin48.xpm | 2 +- xpm/check.xpm | 2 +- xpm/send16.xpm | 2 +- xpm/send16noshadow.xpm | 2 +- xpm/send20.xpm | 2 +- 23 files changed, 304 insertions(+), 184 deletions(-) diff --git a/build-unix.txt b/build-unix.txt index ceb61ad545..f863b6a98c 100644 --- a/build-unix.txt +++ b/build-unix.txt @@ -13,18 +13,18 @@ UNIX BUILD NOTES Dependencies ------------ -Install the dev files for the shared libraries: apt-get install build-essential apt-get install libgtk2.0-dev apt-get install libssl-dev +apt-get install libdb4.7-dev +apt-get install libdb4.7++-dev +apt-get install libboost-dev Libraries you need to obtain separately and build: default path download wxWidgets \wxwidgets http://www.wxwidgets.org/downloads/ -Berkeley DB \db http://www.oracle.com/technology/software/products/berkeley-db/index.html -Boost \boost http://www.boost.org/users/download/ -Their licenses: +Licenses: 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 @@ -59,15 +59,9 @@ make install ldconfig -Berkeley DB ------------ -cd /usr/local/db-4.7.25.NC/build_unix -../dist/configure --enable-cxx -make - - Boost ----- +If you download and build Boost yourself cd /usr/local/boost_1_40_0 su ./bootstrap.sh diff --git a/db.cpp b/db.cpp index a9c42880ab..947aed2970 100644 --- a/db.cpp +++ b/db.cpp @@ -20,6 +20,7 @@ static CCriticalSection cs_db; static bool fDbEnvInit = false; DbEnv dbenv(0); static map mapFileUseCount; +static map mapDb; class CDBInit { @@ -39,21 +40,17 @@ public: instance_of_cdbinit; -CDB::CDB(const char* pszFile, const char* pszMode, bool fTxn) : pdb(NULL) +CDB::CDB(const char* pszFile, const char* pszMode) : pdb(NULL) { int ret; if (pszFile == NULL) return; + fReadOnly = (!strchr(pszMode, '+') && !strchr(pszMode, 'w')); bool fCreate = strchr(pszMode, 'c'); - bool fReadOnly = (!strchr(pszMode, '+') && !strchr(pszMode, 'w')); unsigned int nFlags = DB_THREAD; if (fCreate) nFlags |= DB_CREATE; - else if (fReadOnly) - nFlags |= DB_RDONLY; - if (!fReadOnly || fTxn) - nFlags |= DB_AUTO_COMMIT; CRITICAL_BLOCK(cs_db) { @@ -72,7 +69,7 @@ CDB::CDB(const char* pszFile, const char* pszMode, bool fTxn) : pdb(NULL) dbenv.set_lk_max_locks(10000); dbenv.set_lk_max_objects(10000); dbenv.set_errfile(fopen(strErrorFile.c_str(), "a")); /// debug - ///dbenv.log_set_config(DB_LOG_AUTO_REMOVE, 1); /// causes corruption + dbenv.set_flags(DB_AUTO_COMMIT, 1); ret = dbenv.open(strDataDir.c_str(), DB_CREATE | DB_INIT_LOCK | @@ -90,31 +87,39 @@ CDB::CDB(const char* pszFile, const char* pszMode, bool fTxn) : pdb(NULL) strFile = pszFile; ++mapFileUseCount[strFile]; - } - - pdb = new Db(&dbenv, 0); + pdb = mapDb[strFile]; + if (pdb == NULL) + { + pdb = new Db(&dbenv, 0); - ret = pdb->open(NULL, // Txn pointer - pszFile, // Filename - "main", // Logical db name - DB_BTREE, // Database type - nFlags, // Flags - 0); + ret = pdb->open(NULL, // Txn pointer + pszFile, // Filename + "main", // Logical db name + DB_BTREE, // Database type + nFlags, // Flags + 0); - if (ret > 0) - { - delete pdb; - pdb = NULL; - CRITICAL_BLOCK(cs_db) - --mapFileUseCount[strFile]; - strFile = ""; - throw runtime_error(strprintf("CDB() : can't open database file %s, error %d\n", pszFile, ret)); - } + if (ret > 0) + { + delete pdb; + pdb = NULL; + CRITICAL_BLOCK(cs_db) + --mapFileUseCount[strFile]; + strFile = ""; + throw runtime_error(strprintf("CDB() : can't open database file %s, error %d\n", pszFile, ret)); + } - if (fCreate && !Exists(string("version"))) - WriteVersion(VERSION); + if (fCreate && !Exists(string("version"))) + { + bool fTmp = fReadOnly; + fReadOnly = false; + WriteVersion(VERSION); + fReadOnly = fTmp; + } - RandAddSeed(); + mapDb[strFile] = pdb; + } + } } void CDB::Close() @@ -124,8 +129,6 @@ void CDB::Close() if (!vTxn.empty()) vTxn.front()->abort(); vTxn.clear(); - pdb->close(0); - delete pdb; pdb = NULL; dbenv.txn_checkpoint(0, 0, 0); @@ -135,6 +138,21 @@ void CDB::Close() RandAddSeed(); } +void CloseDb(const string& strFile) +{ + CRITICAL_BLOCK(cs_db) + { + if (mapDb[strFile] != NULL) + { + // Close the database handle + Db* pdb = mapDb[strFile]; + pdb->close(0); + delete pdb; + mapDb[strFile] = NULL; + } + } +} + void DBFlush(bool fShutdown) { // Flush log data to the actual data file @@ -144,14 +162,18 @@ void DBFlush(bool fShutdown) return; CRITICAL_BLOCK(cs_db) { - dbenv.txn_checkpoint(0, 0, 0); map::iterator mi = mapFileUseCount.begin(); while (mi != mapFileUseCount.end()) { string strFile = (*mi).first; int nRefCount = (*mi).second; + printf("%s refcount=%d\n", strFile.c_str(), nRefCount); if (nRefCount == 0) { + // Move log data to the dat file + CloseDb(strFile); + dbenv.txn_checkpoint(0, 0, 0); + printf("%s flush\n", strFile.c_str()); dbenv.lsn_reset(strFile.c_str(), 0); mapFileUseCount.erase(mi++); } @@ -238,7 +260,10 @@ bool CTxDB::ReadOwnerTxes(uint160 hash160, int nMinHeight, vector& if (ret == DB_NOTFOUND) break; else if (ret != 0) + { + pcursor->close(); return false; + } // Unserialize string strType; @@ -255,9 +280,14 @@ bool CTxDB::ReadOwnerTxes(uint160 hash160, int nMinHeight, vector& { vtx.resize(vtx.size()+1); if (!vtx.back().ReadFromDisk(pos)) + { + pcursor->close(); return false; + } } } + + pcursor->close(); return true; } @@ -379,6 +409,7 @@ bool CTxDB::LoadBlockIndex() break; } } + pcursor->close(); if (!ReadHashBestChain(hashBestChain)) { @@ -391,7 +422,7 @@ bool CTxDB::LoadBlockIndex() return error("CTxDB::LoadBlockIndex() : blockindex for hashBestChain not found"); pindexBest = mapBlockIndex[hashBestChain]; nBestHeight = pindexBest->nHeight; - printf("LoadBlockIndex(): hashBestChain=%s height=%d\n", hashBestChain.ToString().substr(0,14).c_str(), nBestHeight); + printf("LoadBlockIndex(): hashBestChain=%s height=%d\n", hashBestChain.ToString().substr(0,16).c_str(), nBestHeight); return true; } @@ -456,6 +487,7 @@ bool CAddrDB::LoadAddresses() mapAddresses.insert(make_pair(addr.GetKey(), addr)); } } + pcursor->close(); printf("Loaded %d addresses\n", mapAddresses.size()); @@ -558,7 +590,7 @@ bool CWalletDB::LoadWallet(vector& vchDefaultKeyRet) //printf(" %12I64d %s %s %s\n", // wtx.vout[0].nValue, // DateTimeStrFormat("%x %H:%M:%S", wtx.nTime).c_str(), - // wtx.hashBlock.ToString().substr(0,14).c_str(), + // wtx.hashBlock.ToString().substr(0,16).c_str(), // wtx.mapValue["message"].c_str()); } else if (strType == "key") @@ -596,6 +628,7 @@ bool CWalletDB::LoadWallet(vector& vchDefaultKeyRet) } } + pcursor->close(); } printf("fShowGenerated = %d\n", fShowGenerated); @@ -655,6 +688,8 @@ void ThreadFlushWalletDB(void* parg) if (fOneThread) return; fOneThread = true; + if (mapArgs.count("-noflushwallet")) + return; unsigned int nLastSeen = nWalletDBUpdated; unsigned int nLastFlushed = nWalletDBUpdated; @@ -669,24 +704,37 @@ void ThreadFlushWalletDB(void* parg) nLastWalletUpdate = GetTime(); } - if (nLastFlushed != nWalletDBUpdated && nLastWalletUpdate < GetTime() - 1) + if (nLastFlushed != nWalletDBUpdated && GetTime() - nLastWalletUpdate >= 2) { TRY_CRITICAL_BLOCK(cs_db) { - string strFile = "wallet.dat"; - map::iterator mi = mapFileUseCount.find(strFile); - if (mi != mapFileUseCount.end()) + // Don't do this if any databases are in use + int nRefCount = 0; + map::iterator mi = mapFileUseCount.begin(); + while (mi != mapFileUseCount.end()) { - int nRefCount = (*mi).second; - if (nRefCount == 0 && !fShutdown) + nRefCount += (*mi).second; + mi++; + } + + if (nRefCount == 0 && !fShutdown) + { + string strFile = "wallet.dat"; + map::iterator mi = mapFileUseCount.find(strFile); + if (mi != mapFileUseCount.end()) { - // Flush wallet.dat so it's self contained + printf("%s ", DateTimeStrFormat("%x %H:%M:%S", GetTime()).c_str()); + printf("Flushing wallet.dat\n"); nLastFlushed = nWalletDBUpdated; int64 nStart = GetTimeMillis(); + + // Flush wallet.dat so it's self contained + CloseDb(strFile); dbenv.txn_checkpoint(0, 0, 0); dbenv.lsn_reset(strFile.c_str(), 0); - printf("Flushed wallet.dat %"PRI64d"ms\n", GetTimeMillis() - nStart); + mapFileUseCount.erase(mi++); + printf("Flushed wallet.dat %"PRI64d"ms\n", GetTimeMillis() - nStart); } } } diff --git a/db.h b/db.h index d11b397eba..d32d2d5d2f 100644 --- a/db.h +++ b/db.h @@ -32,8 +32,9 @@ protected: Db* pdb; string strFile; vector vTxn; + bool fReadOnly; - explicit CDB(const char* pszFile, const char* pszMode="r+", bool fTxn=false); + explicit CDB(const char* pszFile, const char* pszMode="r+"); ~CDB() { Close(); } public: void Close(); @@ -77,6 +78,8 @@ protected: { if (!pdb) return false; + if (fReadOnly) + assert(("Write called on database in read-only mode", false)); // Key CDataStream ssKey(SER_DISK); @@ -104,6 +107,8 @@ protected: { if (!pdb) return false; + if (fReadOnly) + assert(("Erase called on database in read-only mode", false)); // Key CDataStream ssKey(SER_DISK); @@ -254,7 +259,7 @@ public: class CTxDB : public CDB { public: - CTxDB(const char* pszMode="r+", bool fTxn=false) : CDB(!fClient ? "blkindex.dat" : NULL, pszMode, fTxn) { } + CTxDB(const char* pszMode="r+") : CDB(!fClient ? "blkindex.dat" : NULL, pszMode) { } private: CTxDB(const CTxDB&); void operator=(const CTxDB&); @@ -283,7 +288,7 @@ public: class CReviewDB : public CDB { public: - CReviewDB(const char* pszMode="r+", bool fTxn=false) : CDB("reviews.dat", pszMode, fTxn) { } + CReviewDB(const char* pszMode="r+") : CDB("reviews.dat", pszMode) { } private: CReviewDB(const CReviewDB&); void operator=(const CReviewDB&); @@ -309,7 +314,7 @@ public: class CMarketDB : public CDB { public: - CMarketDB(const char* pszMode="r+", bool fTxn=false) : CDB("market.dat", pszMode, fTxn) { } + CMarketDB(const char* pszMode="r+") : CDB("market.dat", pszMode) { } private: CMarketDB(const CMarketDB&); void operator=(const CMarketDB&); @@ -322,7 +327,7 @@ private: class CAddrDB : public CDB { public: - CAddrDB(const char* pszMode="r+", bool fTxn=false) : CDB("addr.dat", pszMode, fTxn) { } + CAddrDB(const char* pszMode="r+") : CDB("addr.dat", pszMode) { } private: CAddrDB(const CAddrDB&); void operator=(const CAddrDB&); @@ -341,7 +346,7 @@ bool LoadAddresses(); class CWalletDB : public CDB { public: - CWalletDB(const char* pszMode="r+", bool fTxn=false) : CDB("wallet.dat", pszMode, fTxn) { } + CWalletDB(const char* pszMode="r+") : CDB("wallet.dat", pszMode) { } private: CWalletDB(const CWalletDB&); void operator=(const CWalletDB&); diff --git a/irc.cpp b/irc.cpp index 8432c6d145..8ac38380eb 100644 --- a/irc.cpp +++ b/irc.cpp @@ -159,15 +159,12 @@ void ThreadIRCSeed(void* parg) SetThreadPriority(THREAD_PRIORITY_NORMAL); int nErrorWait = 10; int nRetryWait = 10; - - // IRC server blocks TOR users - if (fUseProxy && addrProxy.port == htons(9050)) - return; + bool fTOR = (fUseProxy && addrProxy.port == htons(9050)); while (!fShutdown) { CAddress addrConnect("216.155.130.130:6667"); - if (!(fUseProxy && addrProxy.port == htons(9050))) + if (!fTOR) { struct hostent* phostent = gethostbyname("chat.freenode.net"); if (phostent && phostent->h_addr_list && phostent->h_addr_list[0]) @@ -188,6 +185,7 @@ void ThreadIRCSeed(void* parg) if (!RecvUntil(hSocket, "Found your hostname", "using your IP address instead", "Couldn't look up your hostname")) { closesocket(hSocket); + hSocket = INVALID_SOCKET; nErrorWait = nErrorWait * 11 / 10; if (Wait(nErrorWait += 60)) continue; @@ -208,6 +206,7 @@ void ThreadIRCSeed(void* parg) if (!RecvUntil(hSocket, " 004 ")) { closesocket(hSocket); + hSocket = INVALID_SOCKET; nErrorWait = nErrorWait * 11 / 10; if (Wait(nErrorWait += 60)) continue; @@ -269,6 +268,11 @@ void ThreadIRCSeed(void* parg) } } closesocket(hSocket); + hSocket = INVALID_SOCKET; + + // IRC usually blocks TOR, so only try once + if (fTOR) + return; if (GetTime() - nStart > 20 * 60) { diff --git a/main.cpp b/main.cpp index 13a9f9b72a..89b42f76e0 100644 --- a/main.cpp +++ b/main.cpp @@ -760,7 +760,7 @@ unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast) bnNew = bnProofOfWorkLimit; /// debug print - printf("\n\n\nGetNextWorkRequired RETARGET *****\n"); + printf("GetNextWorkRequired RETARGET\n"); printf("nTargetTimespan = %d nActualTimespan = %d\n", nTargetTimespan, nActualTimespan); printf("Before: %08x %s\n", pindexLast->nBits, CBigNum().SetCompact(pindexLast->nBits).getuint256().ToString().c_str()); printf("After: %08x %s\n", bnNew.GetCompact(), bnNew.getuint256().ToString().c_str()); @@ -1013,7 +1013,7 @@ bool CBlock::ConnectBlock(CTxDB& txdb, CBlockIndex* pindex) bool Reorganize(CTxDB& txdb, CBlockIndex* pindexNew) { - printf("*** REORGANIZE ***\n"); + printf("REORGANIZE\n"); // Find the fork CBlockIndex* pfork = pindexBest; @@ -1114,7 +1114,7 @@ bool CBlock::AddToBlockIndex(unsigned int nFile, unsigned int nBlockPos) // Check for duplicate uint256 hash = GetHash(); if (mapBlockIndex.count(hash)) - return error("AddToBlockIndex() : %s already exists", hash.ToString().substr(0,14).c_str()); + return error("AddToBlockIndex() : %s already exists", hash.ToString().substr(0,16).c_str()); // Construct new block index object CBlockIndex* pindexNew = new CBlockIndex(nFile, nBlockPos, *this); @@ -1174,7 +1174,7 @@ bool CBlock::AddToBlockIndex(unsigned int nFile, unsigned int nBlockPos) pindexBest = pindexNew; nBestHeight = pindexBest->nHeight; nTransactionsUpdated++; - printf("AddToBlockIndex: new best=%s height=%d\n", hashBestChain.ToString().substr(0,14).c_str(), nBestHeight); + printf("AddToBlockIndex: new best=%s height=%d\n", hashBestChain.ToString().substr(0,16).c_str(), nBestHeight); } txdb.TxnCommit(); @@ -1294,9 +1294,9 @@ bool ProcessBlock(CNode* pfrom, CBlock* pblock) // Check for duplicate uint256 hash = pblock->GetHash(); if (mapBlockIndex.count(hash)) - return error("ProcessBlock() : already have block %d %s", mapBlockIndex[hash]->nHeight, hash.ToString().substr(0,14).c_str()); + return error("ProcessBlock() : already have block %d %s", mapBlockIndex[hash]->nHeight, hash.ToString().substr(0,16).c_str()); if (mapOrphanBlocks.count(hash)) - return error("ProcessBlock() : already have block (orphan) %s", hash.ToString().substr(0,14).c_str()); + return error("ProcessBlock() : already have block (orphan) %s", hash.ToString().substr(0,16).c_str()); // Preliminary checks if (!pblock->CheckBlock()) @@ -1308,7 +1308,7 @@ bool ProcessBlock(CNode* pfrom, CBlock* pblock) // If don't already have its previous block, shunt it off to holding area until we get it if (!mapBlockIndex.count(pblock->hashPrevBlock)) { - printf("ProcessBlock: ORPHAN BLOCK, prev=%s\n", pblock->hashPrevBlock.ToString().substr(0,14).c_str()); + printf("ProcessBlock: ORPHAN BLOCK, prev=%s\n", pblock->hashPrevBlock.ToString().substr(0,16).c_str()); mapOrphanBlocks.insert(make_pair(hash, pblock)); mapOrphanBlocksByPrev.insert(make_pair(pblock->hashPrevBlock, pblock)); @@ -1503,11 +1503,11 @@ bool LoadBlockIndex(bool fAllowNew) // vMerkleTree: 4a5e1e // Genesis block - char* pszTimestamp = "The Times 03/Jan/2009 Chancellor on brink of second bailout for banks"; + const char* pszTimestamp = "The Times 03/Jan/2009 Chancellor on brink of second bailout for banks"; CTransaction txNew; txNew.vin.resize(1); txNew.vout.resize(1); - txNew.vin[0].scriptSig = CScript() << 486604799 << CBigNum(4) << vector((unsigned char*)pszTimestamp, (unsigned char*)pszTimestamp + strlen(pszTimestamp)); + txNew.vin[0].scriptSig = CScript() << 486604799 << CBigNum(4) << vector((const unsigned char*)pszTimestamp, (const unsigned char*)pszTimestamp + strlen(pszTimestamp)); txNew.vout[0].nValue = 50 * COIN; txNew.vout[0].scriptPubKey = CScript() << CBigNum("0x5F1DF16B2B704C8A578D0BBAF74D385CDE12C11EE50455F3C438EF4C3FBCF649B6DE611FEAE06279A60939E028A8D65C10B73071A6F16719274855FEB0FD8A6704") << OP_CHECKSIG; CBlock block; @@ -1519,7 +1519,7 @@ bool LoadBlockIndex(bool fAllowNew) block.nBits = 0x1d00ffff; block.nNonce = 2083236893; - //// debug print, delete this later + //// debug print printf("%s\n", block.GetHash().ToString().c_str()); printf("%s\n", block.hashMerkleRoot.ToString().c_str()); printf("%s\n", hashGenesisBlock.ToString().c_str()); @@ -1592,7 +1592,7 @@ void PrintBlockTree() pindex->nHeight, pindex->nFile, pindex->nBlockPos, - block.GetHash().ToString().substr(0,14).c_str(), + block.GetHash().ToString().substr(0,16).c_str(), DateTimeStrFormat("%x %H:%M:%S", block.nTime).c_str(), block.vtx.size()); @@ -1912,6 +1912,18 @@ bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) CBlock block; block.ReadFromDisk((*mi).second, !pfrom->fClient); pfrom->PushMessage("block", block); + + // Trigger them to send a getblocks request for the next batch of inventory + if (inv.hash == pfrom->hashContinue) + { + // Bypass PushInventory, this must send even if redundant, + // and we want it right after the last block so they don't + // wait for other stuff first. + vector vInv; + vInv.push_back(CInv(MSG_BLOCK, hashBestChain)); + pfrom->PushMessage("inv", vInv); + pfrom->hashContinue = 0; + } } } else if (inv.IsKnownType()) @@ -1948,25 +1960,23 @@ bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) // Send the rest of the chain if (pindex) pindex = pindex->pnext; - printf("getblocks %d to %s\n", (pindex ? pindex->nHeight : -1), hashStop.ToString().substr(0,14).c_str()); + printf("getblocks %d to %s\n", (pindex ? pindex->nHeight : -1), hashStop.ToString().substr(0,16).c_str()); + int nLimit = 500; for (; pindex; pindex = pindex->pnext) { if (pindex->GetBlockHash() == hashStop) { - printf(" getblocks stopping at %d %s\n", pindex->nHeight, pindex->GetBlockHash().ToString().substr(0,14).c_str()); + printf(" getblocks stopping at %d %s\n", pindex->nHeight, pindex->GetBlockHash().ToString().substr(0,16).c_str()); break; } - - // Bypass setInventoryKnown in case an inventory message got lost - CRITICAL_BLOCK(pfrom->cs_inventory) + pfrom->PushInventory(CInv(MSG_BLOCK, pindex->GetBlockHash())); + if (--nLimit <= 0) { - CInv inv(MSG_BLOCK, pindex->GetBlockHash()); - // returns true if wasn't already contained in the set - if (pfrom->setInventoryKnown2.insert(inv).second) - { - pfrom->setInventoryKnown.erase(inv); - pfrom->vInventoryToSend.push_back(inv); - } + // When this block is requested, we'll send an inv that'll make them + // getblocks the next batch of inventory. + printf(" getblocks stopping at limit %d %s\n", pindex->nHeight, pindex->GetBlockHash().ToString().substr(0,16).c_str()); + pfrom->hashContinue = pindex->GetBlockHash(); + break; } } } @@ -2049,7 +2059,13 @@ bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) vRecv >> *pblock; //// debug print - printf("received block:\n"); pblock->print(); + if (false) + { + printf("received block:\n"); + pblock->print(); + } + else + printf("received block %s\n", pblock->GetHash().ToString().substr(0,16).c_str()); CInv inv(MSG_BLOCK, pblock->GetHash()); pfrom->AddInventoryKnown(inv); @@ -2175,9 +2191,13 @@ bool SendMessages(CNode* pto) if (pto->nVersion == 0) return true; + // Keep-alive ping + if (pto->nLastSend && GetTime() - pto->nLastSend > 12 * 60 && pto->vSend.empty()) + pto->PushMessage("ping"); + // Address refresh broadcast static int64 nLastRebroadcast; - if (nLastRebroadcast < GetTime() - 24 * 60 * 60) // every 24 hours + if (GetTime() - nLastRebroadcast > 24 * 60 * 60) // every 24 hours { nLastRebroadcast = GetTime(); CRITICAL_BLOCK(cs_vNodes) @@ -2194,9 +2214,16 @@ bool SendMessages(CNode* pto) } } - // Keep-alive ping - if (pto->nLastSend && GetTime() - pto->nLastSend > 12 * 60 && pto->vSend.empty()) - pto->PushMessage("ping"); + // Clear inventory known periodically in case an inv message was missed, + // although usually they would just get it from another node. + static int64 nLastInventoryKnownClear; + if (GetTime() - nLastInventoryKnownClear > 2 * 60 * 60) // every 2 hours + { + nLastInventoryKnownClear = GetTime(); + CRITICAL_BLOCK(cs_vNodes) + foreach(CNode* pnode, vNodes) + pnode->setInventoryKnown.clear(); + } // @@ -2243,7 +2270,6 @@ bool SendMessages(CNode* pto) } } pto->vInventoryToSend.clear(); - pto->setInventoryKnown2.clear(); } if (!vInventoryToSend.empty()) pto->PushMessage("inv", vInventoryToSend); @@ -2817,8 +2843,7 @@ bool CommitTransactionSpent(const CWalletTx& wtxNew, const CKey& key) // 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 - // maybe makes sense; please don't do it anywhere else. Keeping databases - // open longer than necessary can create deadlocks. + // maybe makes sense; please don't do it anywhere else. CWalletDB walletdb("r"); // Add the change's private key to wallet diff --git a/main.h b/main.h index 8bb1e19e8a..79f14c6861 100644 --- a/main.h +++ b/main.h @@ -1009,9 +1009,9 @@ public: void print() const { printf("CBlock(hash=%s, ver=%d, hashPrevBlock=%s, hashMerkleRoot=%s, nTime=%u, nBits=%08x, nNonce=%u, vtx=%d)\n", - GetHash().ToString().substr(0,14).c_str(), + GetHash().ToString().substr(0,16).c_str(), nVersion, - hashPrevBlock.ToString().substr(0,14).c_str(), + hashPrevBlock.ToString().substr(0,16).c_str(), hashMerkleRoot.ToString().substr(0,6).c_str(), nTime, nBits, nNonce, vtx.size()); @@ -1159,7 +1159,7 @@ public: return strprintf("CBlockIndex(nprev=%08x, pnext=%08x, nFile=%d, nBlockPos=%-6d nHeight=%d, merkle=%s, hashBlock=%s)", pprev, pnext, nFile, nBlockPos, nHeight, hashMerkleRoot.ToString().substr(0,6).c_str(), - GetBlockHash().ToString().substr(0,14).c_str()); + GetBlockHash().ToString().substr(0,16).c_str()); } void print() const @@ -1229,8 +1229,8 @@ public: str += CBlockIndex::ToString(); str += strprintf("\n hashBlock=%s, hashPrev=%s, hashNext=%s)", GetBlockHash().ToString().c_str(), - hashPrev.ToString().substr(0,14).c_str(), - hashNext.ToString().substr(0,14).c_str()); + hashPrev.ToString().substr(0,16).c_str(), + hashNext.ToString().substr(0,16).c_str()); return str; } diff --git a/makefile.unix b/makefile.unix index 24aa8bfe4f..c0d0ee1d00 100644 --- a/makefile.unix +++ b/makefile.unix @@ -17,24 +17,21 @@ endif INCLUDEPATHS= \ -I"/usr/include" \ - -I"/usr/local/boost_1_40_0" \ - -I"/usr/local/db-4.7.25.NC/build_unix" \ -I"/usr/local/include/wx-2.8" \ -I"/usr/local/lib/wx/include/gtk2-ansi-debug-static-2.8" LIBPATHS= \ -L"/usr/lib" \ -L"/usr/local/lib" \ - -L"/usr/local/db-4.7.25.NC/build_unix" LIBS= \ - -Wl,-Bstatic -l boost_thread -l boost_system -l boost_filesystem -Wl,-Bdynamic \ + -Wl,-Bstatic -l boost_system -l boost_filesystem -Wl,-Bdynamic \ -Wl,-Bstatic -l db_cxx -l wx_gtk2$(D)-2.8 -Wl,-Bdynamic \ -l crypto \ -l gtk-x11-2.0 -l gthread-2.0 -l SM WXDEFS=-D__WXGTK__ -DNOPCH -CFLAGS=-O0 -w -Wno-invalid-offsetof -Wformat $(DEBUGFLAGS) $(WXDEFS) $(INCLUDEPATHS) +CFLAGS=-O0 -Wno-invalid-offsetof -Wformat $(DEBUGFLAGS) $(WXDEFS) $(INCLUDEPATHS) HEADERS=headers.h util.h main.h serialize.h uint256.h key.h bignum.h script.h db.h base58.h diff --git a/net.cpp b/net.cpp index 71295d5dee..9f4060b9da 100644 --- a/net.cpp +++ b/net.cpp @@ -148,8 +148,8 @@ bool GetMyExternalIP2(const CAddress& addrConnect, const char* pszGet, const cha bool GetMyExternalIP(unsigned int& ipRet) { CAddress addrConnect; - char* pszGet; - char* pszKeyword; + const char* pszGet; + const char* pszKeyword; if (fUseProxy) return false; @@ -463,14 +463,21 @@ CNode* ConnectNode(CAddress addrConnect, int64 nTimeout) } } -void CNode::DoDisconnect() +void CNode::CloseSocketDisconnect() { - if (fDebug) - printf("%s ", DateTimeStrFormat("%x %H:%M:%S", GetTime()).c_str()); - printf("disconnecting node %s\n", addr.ToStringLog().c_str()); - - closesocket(hSocket); + fDisconnect = true; + if (hSocket != INVALID_SOCKET) + { + if (fDebug) + printf("%s ", DateTimeStrFormat("%x %H:%M:%S", GetTime()).c_str()); + printf("disconnecting node %s\n", addr.ToStringLog().c_str()); + closesocket(hSocket); + hSocket = INVALID_SOCKET; + } +} +void CNode::Cleanup() +{ // All of a nodes broadcasts and subscriptions are automatically torn down // when it goes down, so a node has to stay up to keep its broadcast going. @@ -540,11 +547,12 @@ void ThreadSocketHandler2(void* parg) // remove from vNodes vNodes.erase(remove(vNodes.begin(), vNodes.end(), pnode), vNodes.end()); - // close socket - pnode->DoDisconnect(); + // close socket and cleanup + pnode->CloseSocketDisconnect(); + pnode->Cleanup(); // hold in disconnected pool until all refs are released - pnode->nReleaseTime = max(pnode->nReleaseTime, GetTime() + 5 * 60); + pnode->nReleaseTime = max(pnode->nReleaseTime, GetTime() + 15 * 60); if (pnode->fNetworkNode || pnode->fInbound) pnode->Release(); vNodesDisconnected.push_back(pnode); @@ -599,6 +607,8 @@ void ThreadSocketHandler2(void* parg) { foreach(CNode* pnode, vNodes) { + if (pnode->hSocket == INVALID_SOCKET || pnode->hSocket < 0) + continue; FD_SET(pnode->hSocket, &fdsetRecv); FD_SET(pnode->hSocket, &fdsetError); hSocketMax = max(hSocketMax, pnode->hSocket); @@ -659,17 +669,22 @@ void ThreadSocketHandler2(void* parg) // vector vNodesCopy; CRITICAL_BLOCK(cs_vNodes) + { vNodesCopy = vNodes; + foreach(CNode* pnode, vNodesCopy) + pnode->AddRef(); + } foreach(CNode* pnode, vNodesCopy) { if (fShutdown) return; - SOCKET hSocket = pnode->hSocket; // // Receive // - if (FD_ISSET(hSocket, &fdsetRecv) || FD_ISSET(hSocket, &fdsetError)) + if (pnode->hSocket == INVALID_SOCKET) + continue; + if (FD_ISSET(pnode->hSocket, &fdsetRecv) || FD_ISSET(pnode->hSocket, &fdsetError)) { TRY_CRITICAL_BLOCK(pnode->cs_vRecv) { @@ -678,7 +693,7 @@ void ThreadSocketHandler2(void* parg) // typical socket buffer is 8K-64K char pchBuf[0x10000]; - int nBytes = recv(hSocket, pchBuf, sizeof(pchBuf), MSG_DONTWAIT); + int nBytes = recv(pnode->hSocket, pchBuf, sizeof(pchBuf), MSG_DONTWAIT); if (nBytes > 0) { vRecv.resize(nPos + nBytes); @@ -690,7 +705,7 @@ void ThreadSocketHandler2(void* parg) // socket closed gracefully if (!pnode->fDisconnect) printf("socket closed\n"); - pnode->fDisconnect = true; + pnode->CloseSocketDisconnect(); } else if (nBytes < 0) { @@ -700,7 +715,7 @@ void ThreadSocketHandler2(void* parg) { if (!pnode->fDisconnect) printf("socket recv error %d\n", nErr); - pnode->fDisconnect = true; + pnode->CloseSocketDisconnect(); } } } @@ -709,14 +724,16 @@ void ThreadSocketHandler2(void* parg) // // Send // - if (FD_ISSET(hSocket, &fdsetSend)) + if (pnode->hSocket == INVALID_SOCKET) + continue; + if (FD_ISSET(pnode->hSocket, &fdsetSend)) { TRY_CRITICAL_BLOCK(pnode->cs_vSend) { CDataStream& vSend = pnode->vSend; if (!vSend.empty()) { - int nBytes = send(hSocket, &vSend[0], vSend.size(), MSG_NOSIGNAL | MSG_DONTWAIT); + int nBytes = send(pnode->hSocket, &vSend[0], vSend.size(), MSG_NOSIGNAL | MSG_DONTWAIT); if (nBytes > 0) { vSend.erase(vSend.begin(), vSend.begin() + nBytes); @@ -729,7 +746,7 @@ void ThreadSocketHandler2(void* parg) if (nErr != WSAEWOULDBLOCK && nErr != WSAEMSGSIZE && nErr != WSAEINTR && nErr != WSAEINPROGRESS) { printf("socket send error %d\n", nErr); - pnode->fDisconnect = true; + pnode->CloseSocketDisconnect(); } } } @@ -760,18 +777,12 @@ void ThreadSocketHandler2(void* parg) } } } - - - //// debug heartbeat - static int64 nHeartbeat1; - if (GetTime() - nHeartbeat1 >= 5 * 60) + CRITICAL_BLOCK(cs_vNodes) { - printf("%s sendrecv\n", DateTimeStrFormat("%x %H:%M:%S", GetTime()).c_str()); - nHeartbeat1 = GetTime(); - fDebug = true; + foreach(CNode* pnode, vNodesCopy) + pnode->Release(); } - nThreadSocketHandlerHeartbeat = GetTime(); Sleep(10); } @@ -812,18 +823,21 @@ void ThreadOpenConnections2(void* parg) printf("ThreadOpenConnections started\n"); // Connect to specific addresses - while (mapArgs.count("-connect")) + if (mapArgs.count("-connect")) { - foreach(string strAddr, mapMultiArgs["-connect"]) + for (int64 nLoop = 0;; nLoop++) { - CAddress addr(strAddr, NODE_NETWORK); - if (addr.IsValid()) - OpenNetworkConnection(addr); - for (int i = 0; i < 10; i++) + foreach(string strAddr, mapMultiArgs["-connect"]) { - Sleep(1000); - if (fShutdown) - return; + CAddress addr(strAddr, NODE_NETWORK); + if (addr.IsValid()) + OpenNetworkConnection(addr); + for (int i = 0; i < 10 && i < nLoop; i++) + { + Sleep(500); + if (fShutdown) + return; + } } } } @@ -837,7 +851,7 @@ void ThreadOpenConnections2(void* parg) if (addr.IsValid()) { OpenNetworkConnection(addr); - Sleep(1000); + Sleep(500); if (fShutdown) return; } @@ -898,7 +912,7 @@ void ThreadOpenConnections2(void* parg) // 30 days 27 hours // 90 days 46 hours // 365 days 93 hours - int64 nDelay = 3600.0 * sqrt(fabs(nSinceLastSeen) / 3600.0) + nRandomizer; + int64 nDelay = (int64)(3600.0 * sqrt(fabs(nSinceLastSeen) / 3600.0) + nRandomizer); // Fast reconnect for one hour after last seen if (nSinceLastSeen < 60 * 60) @@ -1013,11 +1027,13 @@ void ThreadMessageHandler2(void* parg) // Poll the connected nodes for messages vector vNodesCopy; CRITICAL_BLOCK(cs_vNodes) + { vNodesCopy = vNodes; + foreach(CNode* pnode, vNodesCopy) + pnode->AddRef(); + } foreach(CNode* pnode, vNodesCopy) { - pnode->AddRef(); - // Receive messages TRY_CRITICAL_BLOCK(pnode->cs_vRecv) ProcessMessages(pnode); @@ -1029,8 +1045,11 @@ void ThreadMessageHandler2(void* parg) SendMessages(pnode); if (fShutdown) return; - - pnode->Release(); + } + CRITICAL_BLOCK(cs_vNodes) + { + foreach(CNode* pnode, vNodesCopy) + pnode->Release(); } // Wait and allow messages to bunch up @@ -1257,8 +1276,7 @@ void StartNode(void* parg) if (!fGot) { printf("*** closing socket\n"); - closesocket(pnode->hSocket); - pnode->fDisconnect = true; + pnode->CloseSocketDisconnect(); } } } @@ -1292,7 +1310,7 @@ bool StopNode() int64 nStart = GetTime(); while (vnThreadsRunning[0] > 0 || vnThreadsRunning[2] > 0 || vnThreadsRunning[3] > 0) { - if (GetTime() - nStart > 15) + if (GetTime() - nStart > 20) break; Sleep(20); } diff --git a/net.h b/net.h index 65bbb96077..7d71be49da 100644 --- a/net.h +++ b/net.h @@ -414,7 +414,7 @@ public: string ToString() const { - return strprintf("%s %s", GetCommand(), hash.ToString().substr(0,14).c_str()); + return strprintf("%s %s", GetCommand(), hash.ToString().substr(0,16).c_str()); } void print() const @@ -504,6 +504,7 @@ public: int64 nReleaseTime; map mapRequests; CCriticalSection cs_mapRequests; + uint256 hashContinue; // flood vector vAddrToSend; @@ -512,7 +513,6 @@ public: // inventory based relay set setInventoryKnown; - set setInventoryKnown2; vector vInventoryToSend; CCriticalSection cs_inventory; multimap mapAskFor; @@ -541,6 +541,7 @@ public: fDisconnect = false; nRefCount = 0; nReleaseTime = 0; + hashContinue = 0; fGetAddr = false; vfSubscribe.assign(256, false); @@ -550,13 +551,16 @@ public: CAddress addrYou = (fUseProxy ? CAddress("0.0.0.0") : addr); CAddress addrMe = (fUseProxy ? CAddress("0.0.0.0") : addrLocalHost); RAND_bytes((unsigned char*)&nLocalHostNonce, sizeof(nLocalHostNonce)); - PushMessage("version", VERSION, nLocalServices, nTime, addrYou, addrMe, nLocalHostNonce, string("test5")); + PushMessage("version", VERSION, nLocalServices, nTime, addrYou, addrMe, nLocalHostNonce, string(pszSubVer)); } ~CNode() { if (hSocket != INVALID_SOCKET) + { closesocket(hSocket); + hSocket = INVALID_SOCKET; + } } private: @@ -570,12 +574,13 @@ public: return max(nRefCount, 0) + (GetTime() < nReleaseTime ? 1 : 0); } - void AddRef(int64 nTimeout=0) + CNode* AddRef(int64 nTimeout=0) { if (nTimeout != 0) nReleaseTime = max(nReleaseTime, GetTime() + nTimeout); else nRefCount++; + return this; } void Release() @@ -899,7 +904,8 @@ public: bool IsSubscribed(unsigned int nChannel); void Subscribe(unsigned int nChannel, unsigned int nHops=0); void CancelSubscribe(unsigned int nChannel); - void DoDisconnect(); + void CloseSocketDisconnect(); + void Cleanup(); }; diff --git a/serialize.h b/serialize.h index 9b20e2a0f6..aae821b6d2 100644 --- a/serialize.h +++ b/serialize.h @@ -20,6 +20,7 @@ class CDataStream; class CAutoFile; static const int VERSION = 106; +static const char* pszSubVer = " linux-test8"; diff --git a/ui.cpp b/ui.cpp index 9d7556cb57..aaa26adf00 100644 --- a/ui.cpp +++ b/ui.cpp @@ -1664,7 +1664,7 @@ void COptionsDialog::OnButtonApply(wxCommandEvent& event) CAboutDialog::CAboutDialog(wxWindow* parent) : CAboutDialogBase(parent) { - m_staticTextVersion->SetLabel(strprintf("version 0.%d.%d Beta", VERSION/100, VERSION%100)); + m_staticTextVersion->SetLabel(strprintf("version 0.%d.%d beta", VERSION/100, VERSION%100)); // Workaround until upgrade to wxWidgets supporting UTF-8 wxString str = m_staticTextMain->GetLabel(); @@ -2030,7 +2030,7 @@ void CSendingDialog::StartTransfer() // We may have connected already for product details if (!Status("Connecting...")) return; - CNode* pnode = ConnectNode(addr, 5 * 60); + CNode* pnode = ConnectNode(addr, 15 * 60); if (!pnode) { Error("Unable to connect"); @@ -2075,14 +2075,6 @@ void CSendingDialog::OnReply2(CDataStream& vRecv) return; } - // Should already be connected - CNode* pnode = ConnectNode(addr, 5 * 60); - if (!pnode) - { - Error("Lost connection"); - return; - } - // Pause to give the user a chance to cancel while (wxDateTime::UNow() < start + wxTimeSpan(0, 0, 0, 2 * 1000)) { @@ -2112,6 +2104,14 @@ void CSendingDialog::OnReply2(CDataStream& vRecv) 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()) @@ -3495,12 +3495,14 @@ bool CMyApp::OnInit2() if (mapArgs.count("-debug")) fDebug = true; + if (strstr(pszSubVer, "test")) + fDebug = true; if (mapArgs.count("-printtodebugger")) fPrintToDebugger = true; printf("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"); - printf("Bitcoin version %d, OS version %s\n", VERSION, wxGetOsDescription().mb_str()); + printf("Bitcoin version %d%s, OS version %s\n", VERSION, pszSubVer, wxGetOsDescription().mb_str()); if (mapArgs.count("-loadblockindextest")) { @@ -3843,9 +3845,8 @@ void SetStartOnSystemStartup(bool fAutoStart) CoInitialize(NULL); // Get a pointer to the IShellLink interface. - HRESULT hres = NULL; IShellLink* psl = NULL; - hres = CoCreateInstance(CLSID_ShellLink, NULL, + HRESULT hres = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, reinterpret_cast(&psl)); diff --git a/util.cpp b/util.cpp index 7a947730ce..305db5ceeb 100644 --- a/util.cpp +++ b/util.cpp @@ -56,9 +56,11 @@ public: // Close sockets foreach(CNode* pnode, vNodes) - closesocket(pnode->hSocket); - if (closesocket(hListenSocket) == SOCKET_ERROR) - printf("closesocket(hListenSocket) failed with error %d\n", WSAGetLastError()); + if (pnode->hSocket != INVALID_SOCKET) + closesocket(pnode->hSocket); + if (hListenSocket != INVALID_SOCKET) + if (closesocket(hListenSocket) == SOCKET_ERROR) + printf("closesocket(hListenSocket) failed with error %d\n", WSAGetLastError()); #ifdef __WXMSW__ // Shutdown Windows Sockets @@ -348,7 +350,7 @@ void ParseParameters(int argc, char* argv[]) { char psz[10000]; strlcpy(psz, argv[i], sizeof(psz)); - char* pszValue = ""; + char* pszValue = (char*)""; if (strchr(psz, '=')) { pszValue = strchr(psz, '='); diff --git a/util.h b/util.h index ddac449441..9366e66e93 100644 --- a/util.h +++ b/util.h @@ -57,9 +57,11 @@ inline T& REF(const T& val) #ifdef __WXMSW__ #define MSG_NOSIGNAL 0 #define MSG_DONTWAIT 0 +#ifndef UINT64_MAX #define UINT64_MAX _UI64_MAX #define INT64_MAX _I64_MAX #define INT64_MIN _I64_MIN +#endif #else #define WSAGetLastError() errno #define WSAEWOULDBLOCK EWOULDBLOCK @@ -67,7 +69,7 @@ inline T& REF(const T& val) #define WSAEINTR EINTR #define WSAEINPROGRESS EINPROGRESS #define WSAEADDRINUSE EADDRINUSE -#define closesocket(s) close(s) +#define WSAENOTSOCK EBADF #define INVALID_SOCKET (SOCKET)(~0) #define SOCKET_ERROR -1 typedef u_int SOCKET; @@ -80,6 +82,23 @@ typedef u_int SOCKET; #define Beep(n1,n2) (0) #endif +inline int myclosesocket(SOCKET& hSocket) +{ + if (hSocket == INVALID_SOCKET) + return WSAENOTSOCK; +#ifdef __WXMSW__ + int ret = closesocket(hSocket); +#else + int ret = close(hSocket); +#endif + hSocket = INVALID_SOCKET; + return ret; +} +#define closesocket(s) myclosesocket(s) + + + + @@ -149,7 +168,7 @@ public: bool TryEnter() { return mutex.TryLock() == wxMUTEX_NO_ERROR; } #endif public: - char* pszFile; + const char* pszFile; int nLine; }; diff --git a/xpm/addressbook16.xpm b/xpm/addressbook16.xpm index 471f700c70..e00944ef7a 100644 --- a/xpm/addressbook16.xpm +++ b/xpm/addressbook16.xpm @@ -1,5 +1,5 @@ /* XPM */ -static char * addressbook16_xpm[] = { +static const char * addressbook16_xpm[] = { /* columns rows colors chars-per-pixel */ "16 16 256 2", " c #FFFFFF", diff --git a/xpm/addressbook20.xpm b/xpm/addressbook20.xpm index 48df12d801..7ebd73fb2f 100644 --- a/xpm/addressbook20.xpm +++ b/xpm/addressbook20.xpm @@ -1,5 +1,5 @@ /* XPM */ -static char * addressbook20_xpm[] = { +static const char * addressbook20_xpm[] = { /* columns rows colors chars-per-pixel */ "20 20 256 2", " c #FFFFFF", diff --git a/xpm/bitcoin16.xpm b/xpm/bitcoin16.xpm index 8bec142c8b..a1397522a5 100644 --- a/xpm/bitcoin16.xpm +++ b/xpm/bitcoin16.xpm @@ -1,5 +1,5 @@ /* XPM */ -static char * bitcoin16_xpm[] = { +static const char * bitcoin16_xpm[] = { /* columns rows colors chars-per-pixel */ "16 16 181 2", " c #775605", diff --git a/xpm/bitcoin20.xpm b/xpm/bitcoin20.xpm index 2dd61a59dc..93b34ba70c 100644 --- a/xpm/bitcoin20.xpm +++ b/xpm/bitcoin20.xpm @@ -1,5 +1,5 @@ /* XPM */ -static char * bitcoin20_xpm[] = { +static const char * bitcoin20_xpm[] = { /* columns rows colors chars-per-pixel */ "20 20 200 2", " c #7B5500", diff --git a/xpm/bitcoin32.xpm b/xpm/bitcoin32.xpm index 25da102f6a..0ac49f61a9 100644 --- a/xpm/bitcoin32.xpm +++ b/xpm/bitcoin32.xpm @@ -1,5 +1,5 @@ /* XPM */ -static char * bitcoin32_xpm[] = { +static const char * bitcoin32_xpm[] = { /* columns rows colors chars-per-pixel */ "32 32 185 2", " c #715103", diff --git a/xpm/bitcoin48.xpm b/xpm/bitcoin48.xpm index 788e855ddd..bc388bdcb7 100644 --- a/xpm/bitcoin48.xpm +++ b/xpm/bitcoin48.xpm @@ -1,5 +1,5 @@ /* XPM */ -static char * bitcoin48_xpm[] = { +static const char * bitcoin48_xpm[] = { /* columns rows colors chars-per-pixel */ "48 48 224 2", " c #715103", diff --git a/xpm/check.xpm b/xpm/check.xpm index 8f0b9d28ec..e62b656961 100644 --- a/xpm/check.xpm +++ b/xpm/check.xpm @@ -1,5 +1,5 @@ /* XPM */ -static char * check_xpm[] = { +static const char * check_xpm[] = { /* columns rows colors chars-per-pixel */ "32 32 3 1", " c #008000", diff --git a/xpm/send16.xpm b/xpm/send16.xpm index 1eeceb4ec7..7da44d9c56 100644 --- a/xpm/send16.xpm +++ b/xpm/send16.xpm @@ -1,5 +1,5 @@ /* XPM */ -static char * send16_xpm[] = { +static const char * send16_xpm[] = { /* columns rows colors chars-per-pixel */ "16 16 256 2", " c #ADF7AD", diff --git a/xpm/send16noshadow.xpm b/xpm/send16noshadow.xpm index d1b482ef97..f6cef45e0d 100644 --- a/xpm/send16noshadow.xpm +++ b/xpm/send16noshadow.xpm @@ -1,5 +1,5 @@ /* XPM */ -static char * send16noshadow_xpm[] = { +static const char * send16noshadow_xpm[] = { /* columns rows colors chars-per-pixel */ "16 16 256 2", " c #ADF7AD", diff --git a/xpm/send20.xpm b/xpm/send20.xpm index 597ea146d1..68e7b1379a 100644 --- a/xpm/send20.xpm +++ b/xpm/send20.xpm @@ -1,5 +1,5 @@ /* XPM */ -static char * send20_xpm[] = { +static const char * send20_xpm[] = { /* columns rows colors chars-per-pixel */ "20 20 256 2", " c #CEFFCE", -- cgit v1.2.3 From 70918a6645a324c635925fb68a0d41f7c7b40403 Mon Sep 17 00:00:00 2001 From: s_nakamoto Date: Tue, 24 Nov 2009 21:04:50 +0000 Subject: minor fix to batched initial download in case requester has more than 500 block non-main branch --- main.cpp | 4 ++-- main.h | 21 +++++++++++++++++++++ serialize.h | 2 +- 3 files changed, 24 insertions(+), 3 deletions(-) diff --git a/main.cpp b/main.cpp index 89b42f76e0..ae20e08dd0 100644 --- a/main.cpp +++ b/main.cpp @@ -1960,8 +1960,8 @@ bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) // Send the rest of the chain if (pindex) pindex = pindex->pnext; - printf("getblocks %d to %s\n", (pindex ? pindex->nHeight : -1), hashStop.ToString().substr(0,16).c_str()); - int nLimit = 500; + int nLimit = 500 + locator.GetDistanceBack(); + printf("getblocks %d to %s limit %d\n", (pindex ? pindex->nHeight : -1), hashStop.ToString().substr(0,16).c_str(), nLimit); for (; pindex; pindex = pindex->pnext) { if (pindex->GetBlockHash() == hashStop) diff --git a/main.h b/main.h index 79f14c6861..822045a573 100644 --- a/main.h +++ b/main.h @@ -1298,6 +1298,27 @@ public: vHave.push_back(hashGenesisBlock); } + int GetDistanceBack() + { + // Retrace how far back it was in the sender's branch + int nDistance = 0; + int nStep = 1; + foreach(const uint256& hash, vHave) + { + map::iterator mi = mapBlockIndex.find(hash); + if (mi != mapBlockIndex.end()) + { + CBlockIndex* pindex = (*mi).second; + if (pindex->IsInMainChain()) + return nDistance; + } + nDistance += nStep; + if (nDistance > 10) + nStep *= 2; + } + return nDistance; + } + CBlockIndex* GetBlockIndex() { // Find the first block the caller has in the main chain diff --git a/serialize.h b/serialize.h index aae821b6d2..b2d948df96 100644 --- a/serialize.h +++ b/serialize.h @@ -20,7 +20,7 @@ class CDataStream; class CAutoFile; static const int VERSION = 106; -static const char* pszSubVer = " linux-test8"; +static const char* pszSubVer = " linux-test9"; -- cgit v1.2.3 From 52f4cb48590a706caf7a492e8d94b85620d5cd33 Mon Sep 17 00:00:00 2001 From: s_nakamoto Date: Tue, 24 Nov 2009 21:04:50 +0000 Subject: minor fix to batched initial download in case requester has more than 500 block non-main branch git-svn-id: https://bitcoin.svn.sourceforge.net/svnroot/bitcoin/trunk@41 1a98c847-1fd6-4fd8-948a-caf3550aa51b --- main.cpp | 4 ++-- main.h | 21 +++++++++++++++++++++ serialize.h | 2 +- 3 files changed, 24 insertions(+), 3 deletions(-) diff --git a/main.cpp b/main.cpp index 89b42f76e0..ae20e08dd0 100644 --- a/main.cpp +++ b/main.cpp @@ -1960,8 +1960,8 @@ bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) // Send the rest of the chain if (pindex) pindex = pindex->pnext; - printf("getblocks %d to %s\n", (pindex ? pindex->nHeight : -1), hashStop.ToString().substr(0,16).c_str()); - int nLimit = 500; + int nLimit = 500 + locator.GetDistanceBack(); + printf("getblocks %d to %s limit %d\n", (pindex ? pindex->nHeight : -1), hashStop.ToString().substr(0,16).c_str(), nLimit); for (; pindex; pindex = pindex->pnext) { if (pindex->GetBlockHash() == hashStop) diff --git a/main.h b/main.h index 79f14c6861..822045a573 100644 --- a/main.h +++ b/main.h @@ -1298,6 +1298,27 @@ public: vHave.push_back(hashGenesisBlock); } + int GetDistanceBack() + { + // Retrace how far back it was in the sender's branch + int nDistance = 0; + int nStep = 1; + foreach(const uint256& hash, vHave) + { + map::iterator mi = mapBlockIndex.find(hash); + if (mi != mapBlockIndex.end()) + { + CBlockIndex* pindex = (*mi).second; + if (pindex->IsInMainChain()) + return nDistance; + } + nDistance += nStep; + if (nDistance > 10) + nStep *= 2; + } + return nDistance; + } + CBlockIndex* GetBlockIndex() { // Find the first block the caller has in the main chain diff --git a/serialize.h b/serialize.h index aae821b6d2..b2d948df96 100644 --- a/serialize.h +++ b/serialize.h @@ -20,7 +20,7 @@ class CDataStream; class CAutoFile; static const int VERSION = 106; -static const char* pszSubVer = " linux-test8"; +static const char* pszSubVer = " linux-test9"; -- cgit v1.2.3 From 658b5b414afd7ec4d73d2b0140037778c66c18d1 Mon Sep 17 00:00:00 2001 From: s_nakamoto Date: Sun, 6 Dec 2009 00:29:09 +0000 Subject: fix transaction fee bug in CreateTransaction, higher size cutoff for free transactions in GetMinFee --- main.cpp | 18 ++++++++---------- main.h | 11 ++++++++--- serialize.h | 2 +- 3 files changed, 17 insertions(+), 14 deletions(-) diff --git a/main.cpp b/main.cpp index ae20e08dd0..6575099f59 100644 --- a/main.cpp +++ b/main.cpp @@ -2479,10 +2479,8 @@ void BitcoinMiner() if (tx.IsCoinBase() || !tx.IsFinal()) continue; - // Transaction fee requirements, mainly only needed for flood control - // Under 10K (about 80 inputs) is free for first 100 transactions - // Base rate is 0.01 per KB - int64 nMinFee = tx.GetMinFee(pblock->vtx.size() < 100); + // Transaction fee based on block size + int64 nMinFee = tx.GetMinFee(nBlockSize); map mapTestPoolTmp(mapTestPool); if (!tx.ConnectInputs(txdb, mapTestPoolTmp, CDiskTxPos(1,1,1), 0, nFees, false, true, nMinFee)) @@ -2768,11 +2766,11 @@ bool CreateTransaction(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew, CK if (nValue < 0) return false; int64 nValueOut = nValue; - nValue += nFee; + int64 nTotalValue = nValue + nFee; // Choose coins to use set setCoins; - if (!SelectCoins(nValue, setCoins)) + if (!SelectCoins(nTotalValue, setCoins)) return false; int64 nValueIn = 0; foreach(CWalletTx* pcoin, setCoins) @@ -2784,7 +2782,7 @@ bool CreateTransaction(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew, CK wtxNew.vout.push_back(CTxOut(nValueOut, scriptPubKey)); // Fill a vout back to self with any change - if (nValueIn > nValue) + if (nValueIn > nTotalValue) { // New private key if (keyRet.IsNull()) @@ -2793,7 +2791,7 @@ bool CreateTransaction(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew, CK // Fill a vout to ourself CScript scriptPubKey; scriptPubKey << keyRet.GetPubKey() << OP_CHECKSIG; - wtxNew.vout.push_back(CTxOut(nValueIn - nValue, scriptPubKey)); + wtxNew.vout.push_back(CTxOut(nValueIn - nTotalValue, scriptPubKey)); } // Fill a vout to the payee @@ -2814,9 +2812,9 @@ bool CreateTransaction(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew, CK SignSignature(*pcoin, wtxNew, nIn++); // Check that enough fee is included - if (nFee < wtxNew.GetMinFee(true)) + if (nFee < wtxNew.GetMinFee()) { - nFee = nFeeRequiredRet = wtxNew.GetMinFee(true); + nFee = nFeeRequiredRet = wtxNew.GetMinFee(); continue; } diff --git a/main.h b/main.h index 822045a573..716485e93d 100644 --- a/main.h +++ b/main.h @@ -512,14 +512,19 @@ public: return nValueOut; } - int64 GetMinFee(bool fDiscount=false) const + int64 GetMinFee(unsigned int nBlockSize=1) const { // Base fee is 1 cent per kilobyte unsigned int nBytes = ::GetSerializeSize(*this, SER_NETWORK); int64 nMinFee = (1 + (int64)nBytes / 1000) * CENT; - // First 100 transactions in a block are free - if (fDiscount && nBytes < 10000) + // Transactions under 60K are free as long as block size is under 80K + // (about 27,000bc if made of 50bc inputs) + if (nBytes < 60000 && nBlockSize < 80000) + nMinFee = 0; + + // Transactions under 3K are free as long as block size is under 200K + if (nBytes < 3000 && nBlockSize < 200000) nMinFee = 0; // To limit dust spam, require a 0.01 fee if any output is less than 0.01 diff --git a/serialize.h b/serialize.h index b2d948df96..14a2bed7ec 100644 --- a/serialize.h +++ b/serialize.h @@ -20,7 +20,7 @@ class CDataStream; class CAutoFile; static const int VERSION = 106; -static const char* pszSubVer = " linux-test9"; +static const char* pszSubVer = " test10"; -- cgit v1.2.3 From 107d9e288df8207e83f4273a8dcd631412f89889 Mon Sep 17 00:00:00 2001 From: s_nakamoto Date: Sun, 6 Dec 2009 00:29:09 +0000 Subject: fix transaction fee bug in CreateTransaction, higher size cutoff for free transactions in GetMinFee git-svn-id: https://bitcoin.svn.sourceforge.net/svnroot/bitcoin/trunk@42 1a98c847-1fd6-4fd8-948a-caf3550aa51b --- main.cpp | 18 ++++++++---------- main.h | 11 ++++++++--- serialize.h | 2 +- 3 files changed, 17 insertions(+), 14 deletions(-) diff --git a/main.cpp b/main.cpp index ae20e08dd0..6575099f59 100644 --- a/main.cpp +++ b/main.cpp @@ -2479,10 +2479,8 @@ void BitcoinMiner() if (tx.IsCoinBase() || !tx.IsFinal()) continue; - // Transaction fee requirements, mainly only needed for flood control - // Under 10K (about 80 inputs) is free for first 100 transactions - // Base rate is 0.01 per KB - int64 nMinFee = tx.GetMinFee(pblock->vtx.size() < 100); + // Transaction fee based on block size + int64 nMinFee = tx.GetMinFee(nBlockSize); map mapTestPoolTmp(mapTestPool); if (!tx.ConnectInputs(txdb, mapTestPoolTmp, CDiskTxPos(1,1,1), 0, nFees, false, true, nMinFee)) @@ -2768,11 +2766,11 @@ bool CreateTransaction(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew, CK if (nValue < 0) return false; int64 nValueOut = nValue; - nValue += nFee; + int64 nTotalValue = nValue + nFee; // Choose coins to use set setCoins; - if (!SelectCoins(nValue, setCoins)) + if (!SelectCoins(nTotalValue, setCoins)) return false; int64 nValueIn = 0; foreach(CWalletTx* pcoin, setCoins) @@ -2784,7 +2782,7 @@ bool CreateTransaction(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew, CK wtxNew.vout.push_back(CTxOut(nValueOut, scriptPubKey)); // Fill a vout back to self with any change - if (nValueIn > nValue) + if (nValueIn > nTotalValue) { // New private key if (keyRet.IsNull()) @@ -2793,7 +2791,7 @@ bool CreateTransaction(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew, CK // Fill a vout to ourself CScript scriptPubKey; scriptPubKey << keyRet.GetPubKey() << OP_CHECKSIG; - wtxNew.vout.push_back(CTxOut(nValueIn - nValue, scriptPubKey)); + wtxNew.vout.push_back(CTxOut(nValueIn - nTotalValue, scriptPubKey)); } // Fill a vout to the payee @@ -2814,9 +2812,9 @@ bool CreateTransaction(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew, CK SignSignature(*pcoin, wtxNew, nIn++); // Check that enough fee is included - if (nFee < wtxNew.GetMinFee(true)) + if (nFee < wtxNew.GetMinFee()) { - nFee = nFeeRequiredRet = wtxNew.GetMinFee(true); + nFee = nFeeRequiredRet = wtxNew.GetMinFee(); continue; } diff --git a/main.h b/main.h index 822045a573..716485e93d 100644 --- a/main.h +++ b/main.h @@ -512,14 +512,19 @@ public: return nValueOut; } - int64 GetMinFee(bool fDiscount=false) const + int64 GetMinFee(unsigned int nBlockSize=1) const { // Base fee is 1 cent per kilobyte unsigned int nBytes = ::GetSerializeSize(*this, SER_NETWORK); int64 nMinFee = (1 + (int64)nBytes / 1000) * CENT; - // First 100 transactions in a block are free - if (fDiscount && nBytes < 10000) + // Transactions under 60K are free as long as block size is under 80K + // (about 27,000bc if made of 50bc inputs) + if (nBytes < 60000 && nBlockSize < 80000) + nMinFee = 0; + + // Transactions under 3K are free as long as block size is under 200K + if (nBytes < 3000 && nBlockSize < 200000) nMinFee = 0; // To limit dust spam, require a 0.01 fee if any output is less than 0.01 diff --git a/serialize.h b/serialize.h index b2d948df96..14a2bed7ec 100644 --- a/serialize.h +++ b/serialize.h @@ -20,7 +20,7 @@ class CDataStream; class CAutoFile; static const int VERSION = 106; -static const char* pszSubVer = " linux-test9"; +static const char* pszSubVer = " test10"; -- cgit v1.2.3 From ba0909e96afd15a56420456595f4b201c1582c16 Mon Sep 17 00:00:00 2001 From: s_nakamoto Date: Sun, 6 Dec 2009 00:38:11 +0000 Subject: misc --- main.cpp | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/main.cpp b/main.cpp index 6575099f59..46e7475246 100644 --- a/main.cpp +++ b/main.cpp @@ -1254,8 +1254,8 @@ bool CBlock::AcceptBlock() if (nTime <= pindexPrev->GetMedianTimePast()) return error("AcceptBlock() : block's timestamp is too early"); - // Check that all transactions are finalized (starting around Dec 2009) - if (nBestHeight > 31000) + // Check that all transactions are finalized (starting around Mar 2010) + if (nBestHeight > 36000) foreach(const CTransaction& tx, vtx) if (!tx.IsFinal(nTime)) return error("AcceptBlock() : contains a non-final transaction"); @@ -2059,13 +2059,9 @@ bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) vRecv >> *pblock; //// debug print - if (false) - { - printf("received block:\n"); - pblock->print(); - } - else - printf("received block %s\n", pblock->GetHash().ToString().substr(0,16).c_str()); + // printf("received block:\n"); + // pblock->print(); + printf("received block %s\n", pblock->GetHash().ToString().substr(0,16).c_str()); CInv inv(MSG_BLOCK, pblock->GetHash()); pfrom->AddInventoryKnown(inv); -- cgit v1.2.3 From b075bbf9862df41cdf5265026ba787b7d0fecb07 Mon Sep 17 00:00:00 2001 From: s_nakamoto Date: Sun, 6 Dec 2009 00:38:11 +0000 Subject: misc git-svn-id: https://bitcoin.svn.sourceforge.net/svnroot/bitcoin/trunk@43 1a98c847-1fd6-4fd8-948a-caf3550aa51b --- main.cpp | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/main.cpp b/main.cpp index 6575099f59..46e7475246 100644 --- a/main.cpp +++ b/main.cpp @@ -1254,8 +1254,8 @@ bool CBlock::AcceptBlock() if (nTime <= pindexPrev->GetMedianTimePast()) return error("AcceptBlock() : block's timestamp is too early"); - // Check that all transactions are finalized (starting around Dec 2009) - if (nBestHeight > 31000) + // Check that all transactions are finalized (starting around Mar 2010) + if (nBestHeight > 36000) foreach(const CTransaction& tx, vtx) if (!tx.IsFinal(nTime)) return error("AcceptBlock() : contains a non-final transaction"); @@ -2059,13 +2059,9 @@ bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) vRecv >> *pblock; //// debug print - if (false) - { - printf("received block:\n"); - pblock->print(); - } - else - printf("received block %s\n", pblock->GetHash().ToString().substr(0,16).c_str()); + // printf("received block:\n"); + // pblock->print(); + printf("received block %s\n", pblock->GetHash().ToString().substr(0,16).c_str()); CInv inv(MSG_BLOCK, pblock->GetHash()); pfrom->AddInventoryKnown(inv); -- cgit v1.2.3 From 0bbbee96b742e4ad0fd5e1d3c33e4bd2247e4445 Mon Sep 17 00:00:00 2001 From: s_nakamoto Date: Fri, 11 Dec 2009 16:49:21 +0000 Subject: retry IRC if name in use, resize to fit ubuntu's giant default font, scroll debug.log, pause gen during initial block download --- build-msw.txt | 6 +++--- build-unix.txt | 13 ++++++------- db.cpp | 21 ++++++++++++++++++--- irc.cpp | 23 ++++++++++++++++------- main.cpp | 21 +++++++++++++++++---- makefile | 26 ++++++++++++-------------- makefile.unix | 35 +++++++++++++++++++---------------- net.cpp | 25 ++++++++++++++++++++++++- net.h | 1 - serialize.h | 2 +- ui.cpp | 46 +++++++++++++++++++++++++++++++++++++--------- util.cpp | 55 ++++++++++++++++++++++++++++++++----------------------- util.h | 2 ++ 13 files changed, 187 insertions(+), 89 deletions(-) diff --git a/build-msw.txt b/build-msw.txt index a159a71aeb..56a38b0286 100644 --- a/build-msw.txt +++ b/build-msw.txt @@ -9,7 +9,7 @@ cryptographic software written by Eric Young (eay@cryptsoft.com). WINDOWS BUILD NOTES - +=================== Compilers Supported ------------------- @@ -19,7 +19,7 @@ Microsoft Visual C++ 6.0 SP6 Dependencies ------------ -Libraries you need to obtain separately to build: +Libraries you need to download separately and build: default path download wxWidgets \wxwidgets http://www.wxwidgets.org/downloads/ @@ -44,7 +44,7 @@ Boost 1.34.1 Notes ----- -The UI layout is edited with wxFormBuilder. Open the project file +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. diff --git a/build-unix.txt b/build-unix.txt index f863b6a98c..7c650589a4 100644 --- a/build-unix.txt +++ b/build-unix.txt @@ -9,7 +9,7 @@ cryptographic software written by Eric Young (eay@cryptsoft.com). UNIX BUILD NOTES - +================ Dependencies ------------ @@ -20,11 +20,10 @@ apt-get install libdb4.7-dev apt-get install libdb4.7++-dev apt-get install libboost-dev -Libraries you need to obtain separately and build: - default path download -wxWidgets \wxwidgets http://www.wxwidgets.org/downloads/ +You need to download wxWidgets from http://www.wxwidgets.org/downloads/ +and build it yourself. -Licenses: +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 @@ -39,7 +38,7 @@ Boost 1.40.0 Notes ----- -The UI layout is edited with wxFormBuilder. Open the project file +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. @@ -61,7 +60,7 @@ ldconfig Boost ----- -If you download and build Boost yourself +If you want to build Boost yourself, cd /usr/local/boost_1_40_0 su ./bootstrap.sh diff --git a/db.cpp b/db.cpp index 947aed2970..6fbd4b9c4f 100644 --- a/db.cpp +++ b/db.cpp @@ -445,7 +445,7 @@ bool CAddrDB::LoadAddresses() CRITICAL_BLOCK(cs_mapAddresses) { // Load user provided addresses - CAutoFile filein = fopen("addr.txt", "rt"); + CAutoFile filein = fopen((GetDataDir() + "/addr.txt").c_str(), "rt"); if (filein) { try @@ -536,10 +536,11 @@ bool CReviewDB::WriteReviews(uint256 hash, const vector& vReviews) bool CWalletDB::LoadWallet(vector& vchDefaultKeyRet) { vchDefaultKeyRet.clear(); + int nFileVersion = 0; // Modify defaults #ifndef __WXMSW__ - // Reports that tray icon can disappear on gnome, leaving no way to access the program + // Tray icon sometimes disappears on 9.10 karmic koala 64-bit, leaving no way to access the program fMinimizeToTray = false; fMinimizeOnClose = false; #endif @@ -607,6 +608,10 @@ bool CWalletDB::LoadWallet(vector& vchDefaultKeyRet) { ssValue >> vchDefaultKeyRet; } + else if (strType == "version") + { + ssValue >> nFileVersion; + } else if (strType == "setting") { string strKey; @@ -649,6 +654,16 @@ bool CWalletDB::LoadWallet(vector& vchDefaultKeyRet) WriteSetting("nTransactionFee", nTransactionFee); } + // Upgrade + if (nFileVersion < VERSION) + { + // Get rid of old debug.log file in current directory + if (nFileVersion <= 105 && !pszSetDataDir[0]) + unlink("debug.log"); + + WriteVersion(VERSION); + } + return true; } @@ -656,7 +671,7 @@ bool LoadWallet(bool& fFirstRunRet) { fFirstRunRet = false; vector vchDefaultKey; - if (!CWalletDB("cr").LoadWallet(vchDefaultKey)) + if (!CWalletDB("cr+").LoadWallet(vchDefaultKey)) return false; fFirstRunRet = vchDefaultKey.empty(); diff --git a/irc.cpp b/irc.cpp index 8ac38380eb..8e8510859f 100644 --- a/irc.cpp +++ b/irc.cpp @@ -121,20 +121,20 @@ bool RecvLineIRC(SOCKET hSocket, string& strLine) } } -bool RecvUntil(SOCKET hSocket, const char* psz1, const char* psz2=NULL, const char* psz3=NULL) +int RecvUntil(SOCKET hSocket, const char* psz1, const char* psz2=NULL, const char* psz3=NULL) { loop { string strLine; if (!RecvLineIRC(hSocket, strLine)) - return false; + return 0; printf("IRC %s\n", strLine.c_str()); if (psz1 && strLine.find(psz1) != -1) - return true; + return 1; if (psz2 && strLine.find(psz2) != -1) - return true; + return 2; if (psz3 && strLine.find(psz3) != -1) - return true; + return 3; } } @@ -159,6 +159,7 @@ void ThreadIRCSeed(void* parg) SetThreadPriority(THREAD_PRIORITY_NORMAL); int nErrorWait = 10; int nRetryWait = 10; + bool fNameInUse = false; bool fTOR = (fUseProxy && addrProxy.port == htons(9050)); while (!fShutdown) @@ -194,7 +195,7 @@ void ThreadIRCSeed(void* parg) } string strMyName; - if (addrLocalHost.IsRoutable() && !fUseProxy) + if (addrLocalHost.IsRoutable() && !fUseProxy && !fNameInUse) strMyName = EncodeAddress(addrLocalHost); else strMyName = strprintf("x%u", GetRand(1000000000)); @@ -203,10 +204,18 @@ void ThreadIRCSeed(void* parg) Send(hSocket, strprintf("NICK %s\r", strMyName.c_str()).c_str()); Send(hSocket, strprintf("USER %s 8 * : %s\r", strMyName.c_str(), strMyName.c_str()).c_str()); - if (!RecvUntil(hSocket, " 004 ")) + int nRet = RecvUntil(hSocket, " 004 ", " 433 "); + if (nRet != 1) { closesocket(hSocket); hSocket = INVALID_SOCKET; + if (nRet == 2) + { + printf("IRC name already in use\n"); + fNameInUse = true; + Wait(10); + continue; + } nErrorWait = nErrorWait * 11 / 10; if (Wait(nErrorWait += 60)) continue; diff --git a/main.cpp b/main.cpp index 46e7475246..cb93e5486f 100644 --- a/main.cpp +++ b/main.cpp @@ -2530,7 +2530,7 @@ void BitcoinMiner() // // Search // - unsigned int nStart = GetTime(); + int64 nStart = GetTime(); uint256 hashTarget = CBigNum().SetCompact(pblock->nBits).getuint256(); uint256 hash; loop @@ -2582,14 +2582,27 @@ void BitcoinMiner() return; if (fLimitProcessors && vnThreadsRunning[3] > nLimitProcessors) return; - if (tmp.block.nNonce == 0) + if (vNodes.empty()) break; - if (pindexPrev != pindexBest) + if (tmp.block.nNonce == 0) break; if (nTransactionsUpdated != nTransactionsUpdatedLast && GetTime() - nStart > 60) break; - if (vNodes.empty()) + if (pindexPrev != pindexBest) + { + // Pause generating during initial download + if (GetTime() - nStart < 20) + { + CBlockIndex* pindexTmp; + do + { + pindexTmp = pindexBest; + Sleep(10000); + } + while (pindexTmp != pindexBest); + } break; + } tmp.block.nTime = pblock->nTime = max(pindexPrev->GetMedianTimePast()+1, GetAdjustedTime()); } } diff --git a/makefile b/makefile index 2d932f02cd..0dd622106e 100644 --- a/makefile +++ b/makefile @@ -10,8 +10,6 @@ endif endif ifeq "$(BUILD)" "debug" D=d -# note: gcc 3.x profile doesn't work -#DEBUGFLAGS=-O0 -g -pg -D__WXDEBUG__ DEBUGFLAGS=-g -D__WXDEBUG__ endif @@ -36,34 +34,34 @@ all: bitcoin.exe headers.h.gch: headers.h $(HEADERS) net.h irc.h market.h uibase.h ui.h g++ -c $(CFLAGS) -o $@ $< -obj/util.o: util.cpp $(HEADERS) +obj/util.o: util.cpp $(HEADERS) g++ -c $(CFLAGS) -o $@ $< -obj/script.o: script.cpp $(HEADERS) +obj/script.o: script.cpp $(HEADERS) g++ -c $(CFLAGS) -o $@ $< -obj/db.o: db.cpp $(HEADERS) market.h +obj/db.o: db.cpp $(HEADERS) market.h g++ -c $(CFLAGS) -o $@ $< -obj/net.o: net.cpp $(HEADERS) net.h +obj/net.o: net.cpp $(HEADERS) net.h g++ -c $(CFLAGS) -o $@ $< -obj/main.o: main.cpp $(HEADERS) net.h market.h sha.h +obj/main.o: main.cpp $(HEADERS) net.h market.h sha.h g++ -c $(CFLAGS) -o $@ $< -obj/market.o: market.cpp $(HEADERS) market.h +obj/market.o: market.cpp $(HEADERS) market.h g++ -c $(CFLAGS) -o $@ $< -obj/ui.o: ui.cpp $(HEADERS) net.h uibase.h ui.h market.h +obj/ui.o: ui.cpp $(HEADERS) net.h uibase.h ui.h market.h g++ -c $(CFLAGS) -o $@ $< -obj/uibase.o: uibase.cpp uibase.h +obj/uibase.o: uibase.cpp uibase.h g++ -c $(CFLAGS) -o $@ $< -obj/sha.o: sha.cpp sha.h +obj/sha.o: sha.cpp sha.h g++ -c $(CFLAGS) -O3 -o $@ $< -obj/irc.o: irc.cpp $(HEADERS) +obj/irc.o: irc.cpp $(HEADERS) g++ -c $(CFLAGS) -o $@ $< obj/ui_res.o: ui.rc rc/bitcoin.ico rc/check.ico rc/send16.bmp rc/send16mask.bmp rc/send16masknoshadow.bmp rc/send20.bmp rc/send20mask.bmp rc/addressbook16.bmp rc/addressbook16mask.bmp rc/addressbook20.bmp rc/addressbook20mask.bmp @@ -71,8 +69,8 @@ obj/ui_res.o: ui.rc rc/bitcoin.ico rc/check.ico rc/send16.bmp rc/send16mask.bmp -OBJS=obj/util.o obj/script.o obj/db.o obj/net.o obj/main.o obj/market.o \ - obj/ui.o obj/uibase.o obj/sha.o obj/irc.o obj/ui_res.o +OBJS=obj/util.o obj/script.o obj/db.o obj/net.o obj/main.o obj/market.o \ + obj/ui.o obj/uibase.o obj/sha.o obj/irc.o obj/ui_res.o bitcoin.exe: headers.h.gch $(OBJS) -kill /f bitcoin.exe diff --git a/makefile.unix b/makefile.unix index c0d0ee1d00..b9826d6ccb 100644 --- a/makefile.unix +++ b/makefile.unix @@ -22,13 +22,16 @@ INCLUDEPATHS= \ LIBPATHS= \ -L"/usr/lib" \ - -L"/usr/local/lib" \ + -L"/usr/local/lib" LIBS= \ - -Wl,-Bstatic -l boost_system -l boost_filesystem -Wl,-Bdynamic \ - -Wl,-Bstatic -l db_cxx -l wx_gtk2$(D)-2.8 -Wl,-Bdynamic \ - -l crypto \ - -l gtk-x11-2.0 -l gthread-2.0 -l SM + -Wl,-Bstatic \ + -l boost_system -l boost_filesystem \ + -l db_cxx \ + -l wx_gtk2$(D)-2.8 \ + -Wl,-Bdynamic \ + -l crypto \ + -l gtk-x11-2.0 -l gthread-2.0 -l SM WXDEFS=-D__WXGTK__ -DNOPCH CFLAGS=-O0 -Wno-invalid-offsetof -Wformat $(DEBUGFLAGS) $(WXDEFS) $(INCLUDEPATHS) @@ -42,41 +45,41 @@ all: bitcoin headers.h.gch: headers.h $(HEADERS) net.h irc.h market.h uibase.h ui.h g++ -c $(CFLAGS) -o $@ $< -obj/util.o: util.cpp $(HEADERS) +obj/util.o: util.cpp $(HEADERS) g++ -c $(CFLAGS) -o $@ $< -obj/script.o: script.cpp $(HEADERS) +obj/script.o: script.cpp $(HEADERS) g++ -c $(CFLAGS) -o $@ $< -obj/db.o: db.cpp $(HEADERS) market.h +obj/db.o: db.cpp $(HEADERS) market.h g++ -c $(CFLAGS) -o $@ $< -obj/net.o: net.cpp $(HEADERS) net.h +obj/net.o: net.cpp $(HEADERS) net.h g++ -c $(CFLAGS) -o $@ $< -obj/main.o: main.cpp $(HEADERS) net.h market.h sha.h +obj/main.o: main.cpp $(HEADERS) net.h market.h sha.h g++ -c $(CFLAGS) -o $@ $< -obj/market.o: market.cpp $(HEADERS) market.h +obj/market.o: market.cpp $(HEADERS) market.h g++ -c $(CFLAGS) -o $@ $< -obj/ui.o: ui.cpp $(HEADERS) net.h uibase.h ui.h market.h +obj/ui.o: ui.cpp $(HEADERS) net.h uibase.h ui.h market.h g++ -c $(CFLAGS) -o $@ $< -obj/uibase.o: uibase.cpp uibase.h +obj/uibase.o: uibase.cpp uibase.h g++ -c $(CFLAGS) -o $@ $< -obj/sha.o: sha.cpp sha.h +obj/sha.o: sha.cpp sha.h g++ -c $(CFLAGS) -O3 -o $@ $< -obj/irc.o: irc.cpp $(HEADERS) +obj/irc.o: irc.cpp $(HEADERS) g++ -c $(CFLAGS) -o $@ $< OBJS=obj/util.o obj/script.o obj/db.o obj/net.o obj/main.o obj/market.o \ - obj/ui.o obj/uibase.o obj/sha.o obj/irc.o + obj/ui.o obj/uibase.o obj/sha.o obj/irc.o bitcoin: headers.h.gch $(OBJS) g++ $(CFLAGS) -o $@ $(LIBPATHS) $(OBJS) $(LIBS) diff --git a/net.cpp b/net.cpp index 9f4060b9da..436a5abf7b 100644 --- a/net.cpp +++ b/net.cpp @@ -21,7 +21,6 @@ uint64 nLocalServices = (fClient ? 0 : NODE_NETWORK); CAddress addrLocalHost(0, DEFAULT_PORT, nLocalServices); CNode* pnodeLocalHost = NULL; uint64 nLocalHostNonce = 0; -bool fShutdown = false; array vnThreadsRunning; SOCKET hListenSocket = INVALID_SOCKET; int64 nThreadSocketHandlerHeartbeat = INT64_MAX; @@ -1324,3 +1323,27 @@ bool StopNode() return true; } + +class CNetCleanup +{ +public: + CNetCleanup() + { + } + ~CNetCleanup() + { + // Close sockets + foreach(CNode* pnode, vNodes) + if (pnode->hSocket != INVALID_SOCKET) + closesocket(pnode->hSocket); + if (hListenSocket != INVALID_SOCKET) + if (closesocket(hListenSocket) == SOCKET_ERROR) + printf("closesocket(hListenSocket) failed with error %d\n", WSAGetLastError()); + +#ifdef __WXMSW__ + // Shutdown Windows Sockets + WSACleanup(); +#endif + } +} +instance_of_cnetcleanup; diff --git a/net.h b/net.h index 7d71be49da..7fe4a7c7d7 100644 --- a/net.h +++ b/net.h @@ -454,7 +454,6 @@ extern uint64 nLocalServices; extern CAddress addrLocalHost; extern CNode* pnodeLocalHost; extern uint64 nLocalHostNonce; -extern bool fShutdown; extern array vnThreadsRunning; extern SOCKET hListenSocket; extern int64 nThreadSocketHandlerHeartbeat; diff --git a/serialize.h b/serialize.h index 14a2bed7ec..63291c6b74 100644 --- a/serialize.h +++ b/serialize.h @@ -20,7 +20,7 @@ class CDataStream; class CAutoFile; static const int VERSION = 106; -static const char* pszSubVer = " test10"; +static const char* pszSubVer = " test11"; diff --git a/ui.cpp b/ui.cpp index aaa26adf00..262f2a8837 100644 --- a/ui.cpp +++ b/ui.cpp @@ -317,6 +317,7 @@ CMainFrame::CMainFrame(wxWindow* parent) : CMainFrameBase(parent) fOnSetFocusAddress = false; fRefresh = false; m_choiceFilter->SetSelection(0); + double dResize = 1.0; #ifdef __WXMSW__ SetIcon(wxICON(bitcoin)); #else @@ -330,6 +331,10 @@ CMainFrame::CMainFrame(wxWindow* parent) : CMainFrameBase(parent) 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(); + // resize to fit ubuntu's huge default font + dResize = 1.19; + SetSize(dResize * GetSize().GetWidth(), 1.1 * GetSize().GetHeight()); + dResize = 1.20; #endif m_staticTextBalance->SetLabel(FormatMoney(GetBalance()) + " "); m_listCtrl->SetFocus(); @@ -339,13 +344,13 @@ CMainFrame::CMainFrame(wxWindow* parent) : CMainFrameBase(parent) int nDateWidth = DateTimeStr(1229413914).size() * 6 + 8; if (!strstr(DateTimeStr(1229413914).c_str(), "2008")) nDateWidth += 12; - m_listCtrl->InsertColumn(0, "", wxLIST_FORMAT_LEFT, 0); - m_listCtrl->InsertColumn(1, "", wxLIST_FORMAT_LEFT, 0); - m_listCtrl->InsertColumn(2, "Status", wxLIST_FORMAT_LEFT, 90); - m_listCtrl->InsertColumn(3, "Date", wxLIST_FORMAT_LEFT, nDateWidth); - m_listCtrl->InsertColumn(4, "Description", wxLIST_FORMAT_LEFT, 409 - nDateWidth); - m_listCtrl->InsertColumn(5, "Debit", wxLIST_FORMAT_RIGHT, 79); - m_listCtrl->InsertColumn(6, "Credit", wxLIST_FORMAT_RIGHT, 79); + m_listCtrl->InsertColumn(0, "", wxLIST_FORMAT_LEFT, dResize * 0); + m_listCtrl->InsertColumn(1, "", wxLIST_FORMAT_LEFT, dResize * 0); + m_listCtrl->InsertColumn(2, "Status", wxLIST_FORMAT_LEFT, dResize * 90); + m_listCtrl->InsertColumn(3, "Date", wxLIST_FORMAT_LEFT, dResize * nDateWidth); + m_listCtrl->InsertColumn(4, "Description", wxLIST_FORMAT_LEFT, dResize * 409 - nDateWidth); + m_listCtrl->InsertColumn(5, "Debit", wxLIST_FORMAT_RIGHT, dResize * 79); + m_listCtrl->InsertColumn(6, "Credit", wxLIST_FORMAT_RIGHT, dResize * 79); //m_listCtrlProductsSent->InsertColumn(0, "Category", wxLIST_FORMAT_LEFT, 100); //m_listCtrlProductsSent->InsertColumn(1, "Title", wxLIST_FORMAT_LEFT, 100); @@ -367,6 +372,10 @@ CMainFrame::CMainFrame(wxWindow* parent) : CMainFrameBase(parent) // Init status bar int pnWidths[3] = { -100, 88, 290 }; +#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 @@ -1514,6 +1523,7 @@ COptionsDialog::COptionsDialog(wxWindow* parent) : COptionsDialogBase(parent) SelectPage(0); #ifndef __WXMSW__ m_checkBoxMinimizeOnClose->SetLabel("&Minimize on close"); + m_checkBoxStartOnSystemStartup->Enable(false); // not implemented yet #endif // Init values @@ -1876,6 +1886,9 @@ CSendingDialog::CSendingDialog(wxWindow* parent, const CAddress& addrIn, int64 n fSuccess = false; fUIDone = false; fWorkDone = false; +#ifndef __WXMSW__ + SetSize(1.2 * GetSize().GetWidth(), 1.05 * GetSize().GetHeight()); +#endif SetTitle(strprintf("Sending %s to %s", FormatMoney(nPrice).c_str(), wtx.mapValue["to"].c_str())); m_textCtrlStatus->SetValue(""); @@ -3475,6 +3488,7 @@ bool CMyApp::OnInit2() ParseParameters(argc, argv); if (mapArgs.count("-?") || mapArgs.count("--help")) { +#ifdef __WXMSW__ string strUsage = "Usage: bitcoin [options]\t\t\t\t\t\t\n" "Options:\n" @@ -3487,6 +3501,20 @@ bool CMyApp::OnInit2() " -connect=\t Connect only to the specified node\n" " -?\t\t This help message\n"; wxMessageBox(strUsage, "Bitcoin", wxOK); +#else + string strUsage = + "Usage: bitcoin [options]\n" + "Options:\n" + " -gen Generate coins\n" + " -gen=0 Don't generate coins\n" + " -min Start minimized\n" + " -datadir= Specify data directory\n" + " -proxy= Connect through socks4 proxy\n" + " -addnode= Add a node to connect to\n" + " -connect= Connect only to the specified node\n" + " -? This help message\n"; + fprintf(stderr, "%s", strUsage.c_str()); +#endif return false; } @@ -3495,12 +3523,12 @@ bool CMyApp::OnInit2() if (mapArgs.count("-debug")) fDebug = true; - if (strstr(pszSubVer, "test")) - fDebug = true; if (mapArgs.count("-printtodebugger")) fPrintToDebugger = true; + if (!fDebug && !pszSetDataDir[0]) + 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 %d%s, OS version %s\n", VERSION, pszSubVer, wxGetOsDescription().mb_str()); diff --git a/util.cpp b/util.cpp index 305db5ceeb..f5f2797fec 100644 --- a/util.cpp +++ b/util.cpp @@ -11,6 +11,7 @@ bool fDebug = false; bool fPrintToDebugger = false; bool fPrintToConsole = false; char pszSetDataDir[MAX_PATH] = ""; +bool fShutdown = false; @@ -53,19 +54,6 @@ public: for (int i = 0; i < CRYPTO_num_locks(); i++) delete ppmutexOpenSSL[i]; OPENSSL_free(ppmutexOpenSSL); - - // Close sockets - foreach(CNode* pnode, vNodes) - if (pnode->hSocket != INVALID_SOCKET) - closesocket(pnode->hSocket); - if (hListenSocket != INVALID_SOCKET) - if (closesocket(hListenSocket) == SOCKET_ERROR) - printf("closesocket(hListenSocket) failed with error %d\n", WSAGetLastError()); - -#ifdef __WXMSW__ - // Shutdown Windows Sockets - WSACleanup(); -#endif } } instance_of_cinit; @@ -416,16 +404,6 @@ void PrintException(std::exception* pex, const char* pszThread) -int GetFilesize(FILE* file) -{ - int nSavePos = ftell(file); - int nFilesize = -1; - if (fseek(file, 0, SEEK_END) == 0) - nFilesize = ftell(file); - fseek(file, nSavePos, SEEK_SET); - return nFilesize; -} - void GetDataDir(char* pszDir) { // pszDir must be at least MAX_PATH length. @@ -465,6 +443,37 @@ string GetDataDir() return pszDir; } +int GetFilesize(FILE* file) +{ + int nSavePos = ftell(file); + int nFilesize = -1; + if (fseek(file, 0, SEEK_END) == 0) + nFilesize = ftell(file); + fseek(file, nSavePos, SEEK_SET); + return nFilesize; +} + +void ShrinkDebugFile() +{ + // Scroll debug.log if it's getting too big + string strFile = GetDataDir() + "/debug.log"; + FILE* file = fopen(strFile.c_str(), "r"); + if (file && GetFilesize(file) > 10 * 1000000) + { + // Restart the file with some of the end + char pch[200000]; + fseek(file, -sizeof(pch), SEEK_END); + int nBytes = fread(pch, 1, sizeof(pch), file); + fclose(file); + if (file = fopen(strFile.c_str(), "w")) + { + fwrite(pch, 1, nBytes, file); + fclose(file); + } + } +} + + diff --git a/util.h b/util.h index 9366e66e93..ae53bfedbe 100644 --- a/util.h +++ b/util.h @@ -111,6 +111,7 @@ extern bool fDebug; extern bool fPrintToDebugger; extern bool fPrintToConsole; extern char pszSetDataDir[MAX_PATH]; +extern bool fShutdown; void RandAddSeed(); void RandAddSeedPerfmon(); @@ -128,6 +129,7 @@ void ParseParameters(int argc, char* argv[]); int GetFilesize(FILE* file); void GetDataDir(char* pszDirRet); string GetDataDir(); +void ShrinkDebugFile(); uint64 GetRand(uint64 nMax); int64 GetTime(); int64 GetAdjustedTime(); -- cgit v1.2.3 From 4ea3f3da1a0c00ea74e85c31a22ea94d18bbdf06 Mon Sep 17 00:00:00 2001 From: s_nakamoto Date: Fri, 11 Dec 2009 16:49:21 +0000 Subject: retry IRC if name in use, resize to fit ubuntu's giant default font, scroll debug.log, pause gen during initial block download git-svn-id: https://bitcoin.svn.sourceforge.net/svnroot/bitcoin/trunk@44 1a98c847-1fd6-4fd8-948a-caf3550aa51b --- build-msw.txt | 6 +++--- build-unix.txt | 13 ++++++------- db.cpp | 21 ++++++++++++++++++--- irc.cpp | 23 ++++++++++++++++------- main.cpp | 21 +++++++++++++++++---- makefile | 26 ++++++++++++-------------- makefile.unix | 35 +++++++++++++++++++---------------- net.cpp | 25 ++++++++++++++++++++++++- net.h | 1 - serialize.h | 2 +- ui.cpp | 46 +++++++++++++++++++++++++++++++++++++--------- util.cpp | 55 ++++++++++++++++++++++++++++++++----------------------- util.h | 2 ++ 13 files changed, 187 insertions(+), 89 deletions(-) diff --git a/build-msw.txt b/build-msw.txt index a159a71aeb..56a38b0286 100644 --- a/build-msw.txt +++ b/build-msw.txt @@ -9,7 +9,7 @@ cryptographic software written by Eric Young (eay@cryptsoft.com). WINDOWS BUILD NOTES - +=================== Compilers Supported ------------------- @@ -19,7 +19,7 @@ Microsoft Visual C++ 6.0 SP6 Dependencies ------------ -Libraries you need to obtain separately to build: +Libraries you need to download separately and build: default path download wxWidgets \wxwidgets http://www.wxwidgets.org/downloads/ @@ -44,7 +44,7 @@ Boost 1.34.1 Notes ----- -The UI layout is edited with wxFormBuilder. Open the project file +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. diff --git a/build-unix.txt b/build-unix.txt index f863b6a98c..7c650589a4 100644 --- a/build-unix.txt +++ b/build-unix.txt @@ -9,7 +9,7 @@ cryptographic software written by Eric Young (eay@cryptsoft.com). UNIX BUILD NOTES - +================ Dependencies ------------ @@ -20,11 +20,10 @@ apt-get install libdb4.7-dev apt-get install libdb4.7++-dev apt-get install libboost-dev -Libraries you need to obtain separately and build: - default path download -wxWidgets \wxwidgets http://www.wxwidgets.org/downloads/ +You need to download wxWidgets from http://www.wxwidgets.org/downloads/ +and build it yourself. -Licenses: +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 @@ -39,7 +38,7 @@ Boost 1.40.0 Notes ----- -The UI layout is edited with wxFormBuilder. Open the project file +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. @@ -61,7 +60,7 @@ ldconfig Boost ----- -If you download and build Boost yourself +If you want to build Boost yourself, cd /usr/local/boost_1_40_0 su ./bootstrap.sh diff --git a/db.cpp b/db.cpp index 947aed2970..6fbd4b9c4f 100644 --- a/db.cpp +++ b/db.cpp @@ -445,7 +445,7 @@ bool CAddrDB::LoadAddresses() CRITICAL_BLOCK(cs_mapAddresses) { // Load user provided addresses - CAutoFile filein = fopen("addr.txt", "rt"); + CAutoFile filein = fopen((GetDataDir() + "/addr.txt").c_str(), "rt"); if (filein) { try @@ -536,10 +536,11 @@ bool CReviewDB::WriteReviews(uint256 hash, const vector& vReviews) bool CWalletDB::LoadWallet(vector& vchDefaultKeyRet) { vchDefaultKeyRet.clear(); + int nFileVersion = 0; // Modify defaults #ifndef __WXMSW__ - // Reports that tray icon can disappear on gnome, leaving no way to access the program + // Tray icon sometimes disappears on 9.10 karmic koala 64-bit, leaving no way to access the program fMinimizeToTray = false; fMinimizeOnClose = false; #endif @@ -607,6 +608,10 @@ bool CWalletDB::LoadWallet(vector& vchDefaultKeyRet) { ssValue >> vchDefaultKeyRet; } + else if (strType == "version") + { + ssValue >> nFileVersion; + } else if (strType == "setting") { string strKey; @@ -649,6 +654,16 @@ bool CWalletDB::LoadWallet(vector& vchDefaultKeyRet) WriteSetting("nTransactionFee", nTransactionFee); } + // Upgrade + if (nFileVersion < VERSION) + { + // Get rid of old debug.log file in current directory + if (nFileVersion <= 105 && !pszSetDataDir[0]) + unlink("debug.log"); + + WriteVersion(VERSION); + } + return true; } @@ -656,7 +671,7 @@ bool LoadWallet(bool& fFirstRunRet) { fFirstRunRet = false; vector vchDefaultKey; - if (!CWalletDB("cr").LoadWallet(vchDefaultKey)) + if (!CWalletDB("cr+").LoadWallet(vchDefaultKey)) return false; fFirstRunRet = vchDefaultKey.empty(); diff --git a/irc.cpp b/irc.cpp index 8ac38380eb..8e8510859f 100644 --- a/irc.cpp +++ b/irc.cpp @@ -121,20 +121,20 @@ bool RecvLineIRC(SOCKET hSocket, string& strLine) } } -bool RecvUntil(SOCKET hSocket, const char* psz1, const char* psz2=NULL, const char* psz3=NULL) +int RecvUntil(SOCKET hSocket, const char* psz1, const char* psz2=NULL, const char* psz3=NULL) { loop { string strLine; if (!RecvLineIRC(hSocket, strLine)) - return false; + return 0; printf("IRC %s\n", strLine.c_str()); if (psz1 && strLine.find(psz1) != -1) - return true; + return 1; if (psz2 && strLine.find(psz2) != -1) - return true; + return 2; if (psz3 && strLine.find(psz3) != -1) - return true; + return 3; } } @@ -159,6 +159,7 @@ void ThreadIRCSeed(void* parg) SetThreadPriority(THREAD_PRIORITY_NORMAL); int nErrorWait = 10; int nRetryWait = 10; + bool fNameInUse = false; bool fTOR = (fUseProxy && addrProxy.port == htons(9050)); while (!fShutdown) @@ -194,7 +195,7 @@ void ThreadIRCSeed(void* parg) } string strMyName; - if (addrLocalHost.IsRoutable() && !fUseProxy) + if (addrLocalHost.IsRoutable() && !fUseProxy && !fNameInUse) strMyName = EncodeAddress(addrLocalHost); else strMyName = strprintf("x%u", GetRand(1000000000)); @@ -203,10 +204,18 @@ void ThreadIRCSeed(void* parg) Send(hSocket, strprintf("NICK %s\r", strMyName.c_str()).c_str()); Send(hSocket, strprintf("USER %s 8 * : %s\r", strMyName.c_str(), strMyName.c_str()).c_str()); - if (!RecvUntil(hSocket, " 004 ")) + int nRet = RecvUntil(hSocket, " 004 ", " 433 "); + if (nRet != 1) { closesocket(hSocket); hSocket = INVALID_SOCKET; + if (nRet == 2) + { + printf("IRC name already in use\n"); + fNameInUse = true; + Wait(10); + continue; + } nErrorWait = nErrorWait * 11 / 10; if (Wait(nErrorWait += 60)) continue; diff --git a/main.cpp b/main.cpp index 46e7475246..cb93e5486f 100644 --- a/main.cpp +++ b/main.cpp @@ -2530,7 +2530,7 @@ void BitcoinMiner() // // Search // - unsigned int nStart = GetTime(); + int64 nStart = GetTime(); uint256 hashTarget = CBigNum().SetCompact(pblock->nBits).getuint256(); uint256 hash; loop @@ -2582,14 +2582,27 @@ void BitcoinMiner() return; if (fLimitProcessors && vnThreadsRunning[3] > nLimitProcessors) return; - if (tmp.block.nNonce == 0) + if (vNodes.empty()) break; - if (pindexPrev != pindexBest) + if (tmp.block.nNonce == 0) break; if (nTransactionsUpdated != nTransactionsUpdatedLast && GetTime() - nStart > 60) break; - if (vNodes.empty()) + if (pindexPrev != pindexBest) + { + // Pause generating during initial download + if (GetTime() - nStart < 20) + { + CBlockIndex* pindexTmp; + do + { + pindexTmp = pindexBest; + Sleep(10000); + } + while (pindexTmp != pindexBest); + } break; + } tmp.block.nTime = pblock->nTime = max(pindexPrev->GetMedianTimePast()+1, GetAdjustedTime()); } } diff --git a/makefile b/makefile index 2d932f02cd..0dd622106e 100644 --- a/makefile +++ b/makefile @@ -10,8 +10,6 @@ endif endif ifeq "$(BUILD)" "debug" D=d -# note: gcc 3.x profile doesn't work -#DEBUGFLAGS=-O0 -g -pg -D__WXDEBUG__ DEBUGFLAGS=-g -D__WXDEBUG__ endif @@ -36,34 +34,34 @@ all: bitcoin.exe headers.h.gch: headers.h $(HEADERS) net.h irc.h market.h uibase.h ui.h g++ -c $(CFLAGS) -o $@ $< -obj/util.o: util.cpp $(HEADERS) +obj/util.o: util.cpp $(HEADERS) g++ -c $(CFLAGS) -o $@ $< -obj/script.o: script.cpp $(HEADERS) +obj/script.o: script.cpp $(HEADERS) g++ -c $(CFLAGS) -o $@ $< -obj/db.o: db.cpp $(HEADERS) market.h +obj/db.o: db.cpp $(HEADERS) market.h g++ -c $(CFLAGS) -o $@ $< -obj/net.o: net.cpp $(HEADERS) net.h +obj/net.o: net.cpp $(HEADERS) net.h g++ -c $(CFLAGS) -o $@ $< -obj/main.o: main.cpp $(HEADERS) net.h market.h sha.h +obj/main.o: main.cpp $(HEADERS) net.h market.h sha.h g++ -c $(CFLAGS) -o $@ $< -obj/market.o: market.cpp $(HEADERS) market.h +obj/market.o: market.cpp $(HEADERS) market.h g++ -c $(CFLAGS) -o $@ $< -obj/ui.o: ui.cpp $(HEADERS) net.h uibase.h ui.h market.h +obj/ui.o: ui.cpp $(HEADERS) net.h uibase.h ui.h market.h g++ -c $(CFLAGS) -o $@ $< -obj/uibase.o: uibase.cpp uibase.h +obj/uibase.o: uibase.cpp uibase.h g++ -c $(CFLAGS) -o $@ $< -obj/sha.o: sha.cpp sha.h +obj/sha.o: sha.cpp sha.h g++ -c $(CFLAGS) -O3 -o $@ $< -obj/irc.o: irc.cpp $(HEADERS) +obj/irc.o: irc.cpp $(HEADERS) g++ -c $(CFLAGS) -o $@ $< obj/ui_res.o: ui.rc rc/bitcoin.ico rc/check.ico rc/send16.bmp rc/send16mask.bmp rc/send16masknoshadow.bmp rc/send20.bmp rc/send20mask.bmp rc/addressbook16.bmp rc/addressbook16mask.bmp rc/addressbook20.bmp rc/addressbook20mask.bmp @@ -71,8 +69,8 @@ obj/ui_res.o: ui.rc rc/bitcoin.ico rc/check.ico rc/send16.bmp rc/send16mask.bmp -OBJS=obj/util.o obj/script.o obj/db.o obj/net.o obj/main.o obj/market.o \ - obj/ui.o obj/uibase.o obj/sha.o obj/irc.o obj/ui_res.o +OBJS=obj/util.o obj/script.o obj/db.o obj/net.o obj/main.o obj/market.o \ + obj/ui.o obj/uibase.o obj/sha.o obj/irc.o obj/ui_res.o bitcoin.exe: headers.h.gch $(OBJS) -kill /f bitcoin.exe diff --git a/makefile.unix b/makefile.unix index c0d0ee1d00..b9826d6ccb 100644 --- a/makefile.unix +++ b/makefile.unix @@ -22,13 +22,16 @@ INCLUDEPATHS= \ LIBPATHS= \ -L"/usr/lib" \ - -L"/usr/local/lib" \ + -L"/usr/local/lib" LIBS= \ - -Wl,-Bstatic -l boost_system -l boost_filesystem -Wl,-Bdynamic \ - -Wl,-Bstatic -l db_cxx -l wx_gtk2$(D)-2.8 -Wl,-Bdynamic \ - -l crypto \ - -l gtk-x11-2.0 -l gthread-2.0 -l SM + -Wl,-Bstatic \ + -l boost_system -l boost_filesystem \ + -l db_cxx \ + -l wx_gtk2$(D)-2.8 \ + -Wl,-Bdynamic \ + -l crypto \ + -l gtk-x11-2.0 -l gthread-2.0 -l SM WXDEFS=-D__WXGTK__ -DNOPCH CFLAGS=-O0 -Wno-invalid-offsetof -Wformat $(DEBUGFLAGS) $(WXDEFS) $(INCLUDEPATHS) @@ -42,41 +45,41 @@ all: bitcoin headers.h.gch: headers.h $(HEADERS) net.h irc.h market.h uibase.h ui.h g++ -c $(CFLAGS) -o $@ $< -obj/util.o: util.cpp $(HEADERS) +obj/util.o: util.cpp $(HEADERS) g++ -c $(CFLAGS) -o $@ $< -obj/script.o: script.cpp $(HEADERS) +obj/script.o: script.cpp $(HEADERS) g++ -c $(CFLAGS) -o $@ $< -obj/db.o: db.cpp $(HEADERS) market.h +obj/db.o: db.cpp $(HEADERS) market.h g++ -c $(CFLAGS) -o $@ $< -obj/net.o: net.cpp $(HEADERS) net.h +obj/net.o: net.cpp $(HEADERS) net.h g++ -c $(CFLAGS) -o $@ $< -obj/main.o: main.cpp $(HEADERS) net.h market.h sha.h +obj/main.o: main.cpp $(HEADERS) net.h market.h sha.h g++ -c $(CFLAGS) -o $@ $< -obj/market.o: market.cpp $(HEADERS) market.h +obj/market.o: market.cpp $(HEADERS) market.h g++ -c $(CFLAGS) -o $@ $< -obj/ui.o: ui.cpp $(HEADERS) net.h uibase.h ui.h market.h +obj/ui.o: ui.cpp $(HEADERS) net.h uibase.h ui.h market.h g++ -c $(CFLAGS) -o $@ $< -obj/uibase.o: uibase.cpp uibase.h +obj/uibase.o: uibase.cpp uibase.h g++ -c $(CFLAGS) -o $@ $< -obj/sha.o: sha.cpp sha.h +obj/sha.o: sha.cpp sha.h g++ -c $(CFLAGS) -O3 -o $@ $< -obj/irc.o: irc.cpp $(HEADERS) +obj/irc.o: irc.cpp $(HEADERS) g++ -c $(CFLAGS) -o $@ $< OBJS=obj/util.o obj/script.o obj/db.o obj/net.o obj/main.o obj/market.o \ - obj/ui.o obj/uibase.o obj/sha.o obj/irc.o + obj/ui.o obj/uibase.o obj/sha.o obj/irc.o bitcoin: headers.h.gch $(OBJS) g++ $(CFLAGS) -o $@ $(LIBPATHS) $(OBJS) $(LIBS) diff --git a/net.cpp b/net.cpp index 9f4060b9da..436a5abf7b 100644 --- a/net.cpp +++ b/net.cpp @@ -21,7 +21,6 @@ uint64 nLocalServices = (fClient ? 0 : NODE_NETWORK); CAddress addrLocalHost(0, DEFAULT_PORT, nLocalServices); CNode* pnodeLocalHost = NULL; uint64 nLocalHostNonce = 0; -bool fShutdown = false; array vnThreadsRunning; SOCKET hListenSocket = INVALID_SOCKET; int64 nThreadSocketHandlerHeartbeat = INT64_MAX; @@ -1324,3 +1323,27 @@ bool StopNode() return true; } + +class CNetCleanup +{ +public: + CNetCleanup() + { + } + ~CNetCleanup() + { + // Close sockets + foreach(CNode* pnode, vNodes) + if (pnode->hSocket != INVALID_SOCKET) + closesocket(pnode->hSocket); + if (hListenSocket != INVALID_SOCKET) + if (closesocket(hListenSocket) == SOCKET_ERROR) + printf("closesocket(hListenSocket) failed with error %d\n", WSAGetLastError()); + +#ifdef __WXMSW__ + // Shutdown Windows Sockets + WSACleanup(); +#endif + } +} +instance_of_cnetcleanup; diff --git a/net.h b/net.h index 7d71be49da..7fe4a7c7d7 100644 --- a/net.h +++ b/net.h @@ -454,7 +454,6 @@ extern uint64 nLocalServices; extern CAddress addrLocalHost; extern CNode* pnodeLocalHost; extern uint64 nLocalHostNonce; -extern bool fShutdown; extern array vnThreadsRunning; extern SOCKET hListenSocket; extern int64 nThreadSocketHandlerHeartbeat; diff --git a/serialize.h b/serialize.h index 14a2bed7ec..63291c6b74 100644 --- a/serialize.h +++ b/serialize.h @@ -20,7 +20,7 @@ class CDataStream; class CAutoFile; static const int VERSION = 106; -static const char* pszSubVer = " test10"; +static const char* pszSubVer = " test11"; diff --git a/ui.cpp b/ui.cpp index aaa26adf00..262f2a8837 100644 --- a/ui.cpp +++ b/ui.cpp @@ -317,6 +317,7 @@ CMainFrame::CMainFrame(wxWindow* parent) : CMainFrameBase(parent) fOnSetFocusAddress = false; fRefresh = false; m_choiceFilter->SetSelection(0); + double dResize = 1.0; #ifdef __WXMSW__ SetIcon(wxICON(bitcoin)); #else @@ -330,6 +331,10 @@ CMainFrame::CMainFrame(wxWindow* parent) : CMainFrameBase(parent) 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(); + // resize to fit ubuntu's huge default font + dResize = 1.19; + SetSize(dResize * GetSize().GetWidth(), 1.1 * GetSize().GetHeight()); + dResize = 1.20; #endif m_staticTextBalance->SetLabel(FormatMoney(GetBalance()) + " "); m_listCtrl->SetFocus(); @@ -339,13 +344,13 @@ CMainFrame::CMainFrame(wxWindow* parent) : CMainFrameBase(parent) int nDateWidth = DateTimeStr(1229413914).size() * 6 + 8; if (!strstr(DateTimeStr(1229413914).c_str(), "2008")) nDateWidth += 12; - m_listCtrl->InsertColumn(0, "", wxLIST_FORMAT_LEFT, 0); - m_listCtrl->InsertColumn(1, "", wxLIST_FORMAT_LEFT, 0); - m_listCtrl->InsertColumn(2, "Status", wxLIST_FORMAT_LEFT, 90); - m_listCtrl->InsertColumn(3, "Date", wxLIST_FORMAT_LEFT, nDateWidth); - m_listCtrl->InsertColumn(4, "Description", wxLIST_FORMAT_LEFT, 409 - nDateWidth); - m_listCtrl->InsertColumn(5, "Debit", wxLIST_FORMAT_RIGHT, 79); - m_listCtrl->InsertColumn(6, "Credit", wxLIST_FORMAT_RIGHT, 79); + m_listCtrl->InsertColumn(0, "", wxLIST_FORMAT_LEFT, dResize * 0); + m_listCtrl->InsertColumn(1, "", wxLIST_FORMAT_LEFT, dResize * 0); + m_listCtrl->InsertColumn(2, "Status", wxLIST_FORMAT_LEFT, dResize * 90); + m_listCtrl->InsertColumn(3, "Date", wxLIST_FORMAT_LEFT, dResize * nDateWidth); + m_listCtrl->InsertColumn(4, "Description", wxLIST_FORMAT_LEFT, dResize * 409 - nDateWidth); + m_listCtrl->InsertColumn(5, "Debit", wxLIST_FORMAT_RIGHT, dResize * 79); + m_listCtrl->InsertColumn(6, "Credit", wxLIST_FORMAT_RIGHT, dResize * 79); //m_listCtrlProductsSent->InsertColumn(0, "Category", wxLIST_FORMAT_LEFT, 100); //m_listCtrlProductsSent->InsertColumn(1, "Title", wxLIST_FORMAT_LEFT, 100); @@ -367,6 +372,10 @@ CMainFrame::CMainFrame(wxWindow* parent) : CMainFrameBase(parent) // Init status bar int pnWidths[3] = { -100, 88, 290 }; +#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 @@ -1514,6 +1523,7 @@ COptionsDialog::COptionsDialog(wxWindow* parent) : COptionsDialogBase(parent) SelectPage(0); #ifndef __WXMSW__ m_checkBoxMinimizeOnClose->SetLabel("&Minimize on close"); + m_checkBoxStartOnSystemStartup->Enable(false); // not implemented yet #endif // Init values @@ -1876,6 +1886,9 @@ CSendingDialog::CSendingDialog(wxWindow* parent, const CAddress& addrIn, int64 n fSuccess = false; fUIDone = false; fWorkDone = false; +#ifndef __WXMSW__ + SetSize(1.2 * GetSize().GetWidth(), 1.05 * GetSize().GetHeight()); +#endif SetTitle(strprintf("Sending %s to %s", FormatMoney(nPrice).c_str(), wtx.mapValue["to"].c_str())); m_textCtrlStatus->SetValue(""); @@ -3475,6 +3488,7 @@ bool CMyApp::OnInit2() ParseParameters(argc, argv); if (mapArgs.count("-?") || mapArgs.count("--help")) { +#ifdef __WXMSW__ string strUsage = "Usage: bitcoin [options]\t\t\t\t\t\t\n" "Options:\n" @@ -3487,6 +3501,20 @@ bool CMyApp::OnInit2() " -connect=\t Connect only to the specified node\n" " -?\t\t This help message\n"; wxMessageBox(strUsage, "Bitcoin", wxOK); +#else + string strUsage = + "Usage: bitcoin [options]\n" + "Options:\n" + " -gen Generate coins\n" + " -gen=0 Don't generate coins\n" + " -min Start minimized\n" + " -datadir= Specify data directory\n" + " -proxy= Connect through socks4 proxy\n" + " -addnode= Add a node to connect to\n" + " -connect= Connect only to the specified node\n" + " -? This help message\n"; + fprintf(stderr, "%s", strUsage.c_str()); +#endif return false; } @@ -3495,12 +3523,12 @@ bool CMyApp::OnInit2() if (mapArgs.count("-debug")) fDebug = true; - if (strstr(pszSubVer, "test")) - fDebug = true; if (mapArgs.count("-printtodebugger")) fPrintToDebugger = true; + if (!fDebug && !pszSetDataDir[0]) + 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 %d%s, OS version %s\n", VERSION, pszSubVer, wxGetOsDescription().mb_str()); diff --git a/util.cpp b/util.cpp index 305db5ceeb..f5f2797fec 100644 --- a/util.cpp +++ b/util.cpp @@ -11,6 +11,7 @@ bool fDebug = false; bool fPrintToDebugger = false; bool fPrintToConsole = false; char pszSetDataDir[MAX_PATH] = ""; +bool fShutdown = false; @@ -53,19 +54,6 @@ public: for (int i = 0; i < CRYPTO_num_locks(); i++) delete ppmutexOpenSSL[i]; OPENSSL_free(ppmutexOpenSSL); - - // Close sockets - foreach(CNode* pnode, vNodes) - if (pnode->hSocket != INVALID_SOCKET) - closesocket(pnode->hSocket); - if (hListenSocket != INVALID_SOCKET) - if (closesocket(hListenSocket) == SOCKET_ERROR) - printf("closesocket(hListenSocket) failed with error %d\n", WSAGetLastError()); - -#ifdef __WXMSW__ - // Shutdown Windows Sockets - WSACleanup(); -#endif } } instance_of_cinit; @@ -416,16 +404,6 @@ void PrintException(std::exception* pex, const char* pszThread) -int GetFilesize(FILE* file) -{ - int nSavePos = ftell(file); - int nFilesize = -1; - if (fseek(file, 0, SEEK_END) == 0) - nFilesize = ftell(file); - fseek(file, nSavePos, SEEK_SET); - return nFilesize; -} - void GetDataDir(char* pszDir) { // pszDir must be at least MAX_PATH length. @@ -465,6 +443,37 @@ string GetDataDir() return pszDir; } +int GetFilesize(FILE* file) +{ + int nSavePos = ftell(file); + int nFilesize = -1; + if (fseek(file, 0, SEEK_END) == 0) + nFilesize = ftell(file); + fseek(file, nSavePos, SEEK_SET); + return nFilesize; +} + +void ShrinkDebugFile() +{ + // Scroll debug.log if it's getting too big + string strFile = GetDataDir() + "/debug.log"; + FILE* file = fopen(strFile.c_str(), "r"); + if (file && GetFilesize(file) > 10 * 1000000) + { + // Restart the file with some of the end + char pch[200000]; + fseek(file, -sizeof(pch), SEEK_END); + int nBytes = fread(pch, 1, sizeof(pch), file); + fclose(file); + if (file = fopen(strFile.c_str(), "w")) + { + fwrite(pch, 1, nBytes, file); + fclose(file); + } + } +} + + diff --git a/util.h b/util.h index 9366e66e93..ae53bfedbe 100644 --- a/util.h +++ b/util.h @@ -111,6 +111,7 @@ extern bool fDebug; extern bool fPrintToDebugger; extern bool fPrintToConsole; extern char pszSetDataDir[MAX_PATH]; +extern bool fShutdown; void RandAddSeed(); void RandAddSeedPerfmon(); @@ -128,6 +129,7 @@ void ParseParameters(int argc, char* argv[]); int GetFilesize(FILE* file); void GetDataDir(char* pszDirRet); string GetDataDir(); +void ShrinkDebugFile(); uint64 GetRand(uint64 nMax); int64 GetTime(); int64 GetAdjustedTime(); -- cgit v1.2.3 From 433fb54b25397d2df117e81345507c08832dfb06 Mon Sep 17 00:00:00 2001 From: s_nakamoto Date: Fri, 11 Dec 2009 17:19:51 +0000 Subject: misc --- db.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/db.cpp b/db.cpp index 6fbd4b9c4f..1d68bef655 100644 --- a/db.cpp +++ b/db.cpp @@ -454,6 +454,7 @@ bool CAddrDB::LoadAddresses() 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(*this, addr); } -- cgit v1.2.3 From 651d33556982d038d39f04373b9f63913bf03187 Mon Sep 17 00:00:00 2001 From: s_nakamoto Date: Fri, 11 Dec 2009 17:19:51 +0000 Subject: misc git-svn-id: https://bitcoin.svn.sourceforge.net/svnroot/bitcoin/trunk@45 1a98c847-1fd6-4fd8-948a-caf3550aa51b --- db.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/db.cpp b/db.cpp index 6fbd4b9c4f..1d68bef655 100644 --- a/db.cpp +++ b/db.cpp @@ -454,6 +454,7 @@ bool CAddrDB::LoadAddresses() 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(*this, addr); } -- cgit v1.2.3 From 25b12b8839be4fc5a051656aad82870c083cce4d Mon Sep 17 00:00:00 2001 From: s_nakamoto Date: Sun, 13 Dec 2009 00:13:16 +0000 Subject: misc exit code, updated setup.nsi --- db.cpp | 1 + net.cpp | 11 ++++++++--- serialize.h | 4 ++-- setup.nsi | 24 ++++++++++++++++-------- ui.cpp | 18 ++++++++++++++++-- 5 files changed, 43 insertions(+), 15 deletions(-) diff --git a/db.cpp b/db.cpp index 1d68bef655..b21d1e3a21 100644 --- a/db.cpp +++ b/db.cpp @@ -637,6 +637,7 @@ bool CWalletDB::LoadWallet(vector& vchDefaultKeyRet) pcursor->close(); } + printf("nFileVersion = %d\n", nFileVersion); printf("fShowGenerated = %d\n", fShowGenerated); printf("fGenerateBitcoins = %d\n", fGenerateBitcoins); printf("nTransactionFee = %"PRI64d"\n", nTransactionFee); diff --git a/net.cpp b/net.cpp index 436a5abf7b..941e7c4dc9 100644 --- a/net.cpp +++ b/net.cpp @@ -929,7 +929,7 @@ void ThreadOpenConnections2(void* parg) // Only try the old stuff if we don't have enough connections if (vNodes.size() >= 2 && nSinceLastSeen > 7 * 24 * 60 * 60) continue; - if (vNodes.size() >= 4 && nSinceLastSeen > 24 * 60 * 60) + if (vNodes.size() >= 5 && nSinceLastSeen > 24 * 60 * 60) continue; // If multiple addresses are ready, prioritize by time since @@ -1256,11 +1256,14 @@ void StartNode(void* parg) // // Thread monitoring + // Not really needed anymore, the cause of the hanging was fixed // loop { - Sleep(15000); - if (GetTime() - nThreadSocketHandlerHeartbeat > 4 * 60) + Sleep(1000); + if (fShutdown) + return; + if (GetTime() - nThreadSocketHandlerHeartbeat > 15 * 60) { // First see if closing sockets will free it printf("*** ThreadSocketHandler is stopped ***\n"); @@ -1280,6 +1283,8 @@ void StartNode(void* parg) } } Sleep(10000); + if (fShutdown) + return; if (GetTime() - nThreadSocketHandlerHeartbeat < 60) continue; diff --git a/serialize.h b/serialize.h index 63291c6b74..8f925103b1 100644 --- a/serialize.h +++ b/serialize.h @@ -19,8 +19,8 @@ class CScript; class CDataStream; class CAutoFile; -static const int VERSION = 106; -static const char* pszSubVer = " test11"; +static const int VERSION = 200; +static const char* pszSubVer = " rc1"; diff --git a/setup.nsi b/setup.nsi index e30ff13cc4..a5a73366a3 100644 --- a/setup.nsi +++ b/setup.nsi @@ -7,12 +7,12 @@ RequestExecutionLevel highest # General Symbol Definitions !define REGKEY "SOFTWARE\$(^Name)" -!define VERSION 0.1.6 +!define VERSION 0.2.0 !define COMPANY "Bitcoin project" -!define URL http://bitcoin.sourceforge.net/ +!define URL http://www.bitcoin.org/ # MUI Symbol Definitions -!define MUI_ICON "rc\bitcoin.ico" +!define MUI_ICON "src\rc\bitcoin.ico" !define MUI_FINISHPAGE_NOAUTOCLOSE !define MUI_STARTMENUPAGE_REGISTRY_ROOT HKLM !define MUI_STARTMENUPAGE_REGISTRY_KEY ${REGKEY} @@ -42,12 +42,12 @@ Var StartMenuGroup !insertmacro MUI_LANGUAGE English # Installer attributes -OutFile Bitcoin_0.1.6_setup.exe +OutFile bitcoin-0.2.0-setup.exe InstallDir $PROGRAMFILES\Bitcoin CRCCheck on XPStyle on ShowInstDetails show -VIProductVersion 0.1.6.0 +VIProductVersion 0.2.0.0 VIAddVersionKey ProductName Bitcoin VIAddVersionKey ProductVersion "${VERSION}" VIAddVersionKey CompanyName "${COMPANY}" @@ -65,6 +65,11 @@ Section -Main SEC0000 File bitcoin.exe File libeay32.dll File mingwm10.dll + File license.txt + File readme.txt + SetOutPath $INSTDIR\src + File /r src\*.* + SetOutPath $INSTDIR WriteRegStr HKCU "${REGKEY}\Components" Main 1 SectionEnd @@ -102,9 +107,12 @@ done${UNSECTION_ID}: # Uninstaller sections Section /o -un.Main UNSEC0000 - Delete /REBOOTOK $INSTDIR\mingwm10.dll - Delete /REBOOTOK $INSTDIR\libeay32.dll Delete /REBOOTOK $INSTDIR\bitcoin.exe + Delete /REBOOTOK $INSTDIR\libeay32.dll + Delete /REBOOTOK $INSTDIR\mingwm10.dll + Delete /REBOOTOK $INSTDIR\license.txt + Delete /REBOOTOK $INSTDIR\readme.txt + RMDir /r /REBOOTOK $INSTDIR\src DeleteRegValue HKCU "${REGKEY}\Components" Main SectionEnd @@ -114,6 +122,7 @@ Section -un.post UNSEC0001 Delete /REBOOTOK "$SMPROGRAMS\$StartMenuGroup\Bitcoin.lnk" Delete /REBOOTOK "$SMSTARTUP\Bitcoin.lnk" Delete /REBOOTOK $INSTDIR\uninstall.exe + Delete /REBOOTOK $INSTDIR\debug.log Delete /REBOOTOK $INSTDIR\db.log DeleteRegValue HKCU "${REGKEY}" StartMenuGroup DeleteRegValue HKCU "${REGKEY}" Path @@ -139,4 +148,3 @@ Function un.onInit !insertmacro MUI_STARTMENU_GETFOLDER Application $StartMenuGroup !insertmacro SELECT_UNSECTION Main ${UNSEC0000} FunctionEnd - diff --git a/ui.cpp b/ui.cpp index 262f2a8837..7432302854 100644 --- a/ui.cpp +++ b/ui.cpp @@ -394,6 +394,14 @@ CMainFrame::~CMainFrame() ptaskbaricon = NULL; } +void ExitTimeout(void* parg) +{ +#ifdef __WXMSW__ + Sleep(5000); + ExitProcess(0); +#endif +} + void Shutdown(void* parg) { static CCriticalSection cs_Shutdown; @@ -404,6 +412,7 @@ void Shutdown(void* parg) fFirstThread = !fTaken; fTaken = true; } + static bool fExit; if (fFirstThread) { fShutdown = true; @@ -411,13 +420,18 @@ void Shutdown(void* parg) DBFlush(false); StopNode(); DBFlush(true); + CreateThread(ExitTimeout, NULL); + Sleep(10); printf("Bitcoin exiting\n\n"); + fExit = true; exit(0); } else { - loop - Sleep(100000); + while (!fExit) + Sleep(500); + Sleep(100); + ExitThread(0); } } -- cgit v1.2.3 From e39bc50eb4dd4f0a34ee4c264af83043f13543dd Mon Sep 17 00:00:00 2001 From: s_nakamoto Date: Sun, 13 Dec 2009 00:13:16 +0000 Subject: misc exit code, updated setup.nsi git-svn-id: https://bitcoin.svn.sourceforge.net/svnroot/bitcoin/trunk@46 1a98c847-1fd6-4fd8-948a-caf3550aa51b --- db.cpp | 1 + net.cpp | 11 ++++++++--- serialize.h | 4 ++-- setup.nsi | 24 ++++++++++++++++-------- ui.cpp | 18 ++++++++++++++++-- 5 files changed, 43 insertions(+), 15 deletions(-) diff --git a/db.cpp b/db.cpp index 1d68bef655..b21d1e3a21 100644 --- a/db.cpp +++ b/db.cpp @@ -637,6 +637,7 @@ bool CWalletDB::LoadWallet(vector& vchDefaultKeyRet) pcursor->close(); } + printf("nFileVersion = %d\n", nFileVersion); printf("fShowGenerated = %d\n", fShowGenerated); printf("fGenerateBitcoins = %d\n", fGenerateBitcoins); printf("nTransactionFee = %"PRI64d"\n", nTransactionFee); diff --git a/net.cpp b/net.cpp index 436a5abf7b..941e7c4dc9 100644 --- a/net.cpp +++ b/net.cpp @@ -929,7 +929,7 @@ void ThreadOpenConnections2(void* parg) // Only try the old stuff if we don't have enough connections if (vNodes.size() >= 2 && nSinceLastSeen > 7 * 24 * 60 * 60) continue; - if (vNodes.size() >= 4 && nSinceLastSeen > 24 * 60 * 60) + if (vNodes.size() >= 5 && nSinceLastSeen > 24 * 60 * 60) continue; // If multiple addresses are ready, prioritize by time since @@ -1256,11 +1256,14 @@ void StartNode(void* parg) // // Thread monitoring + // Not really needed anymore, the cause of the hanging was fixed // loop { - Sleep(15000); - if (GetTime() - nThreadSocketHandlerHeartbeat > 4 * 60) + Sleep(1000); + if (fShutdown) + return; + if (GetTime() - nThreadSocketHandlerHeartbeat > 15 * 60) { // First see if closing sockets will free it printf("*** ThreadSocketHandler is stopped ***\n"); @@ -1280,6 +1283,8 @@ void StartNode(void* parg) } } Sleep(10000); + if (fShutdown) + return; if (GetTime() - nThreadSocketHandlerHeartbeat < 60) continue; diff --git a/serialize.h b/serialize.h index 63291c6b74..8f925103b1 100644 --- a/serialize.h +++ b/serialize.h @@ -19,8 +19,8 @@ class CScript; class CDataStream; class CAutoFile; -static const int VERSION = 106; -static const char* pszSubVer = " test11"; +static const int VERSION = 200; +static const char* pszSubVer = " rc1"; diff --git a/setup.nsi b/setup.nsi index e30ff13cc4..a5a73366a3 100644 --- a/setup.nsi +++ b/setup.nsi @@ -7,12 +7,12 @@ RequestExecutionLevel highest # General Symbol Definitions !define REGKEY "SOFTWARE\$(^Name)" -!define VERSION 0.1.6 +!define VERSION 0.2.0 !define COMPANY "Bitcoin project" -!define URL http://bitcoin.sourceforge.net/ +!define URL http://www.bitcoin.org/ # MUI Symbol Definitions -!define MUI_ICON "rc\bitcoin.ico" +!define MUI_ICON "src\rc\bitcoin.ico" !define MUI_FINISHPAGE_NOAUTOCLOSE !define MUI_STARTMENUPAGE_REGISTRY_ROOT HKLM !define MUI_STARTMENUPAGE_REGISTRY_KEY ${REGKEY} @@ -42,12 +42,12 @@ Var StartMenuGroup !insertmacro MUI_LANGUAGE English # Installer attributes -OutFile Bitcoin_0.1.6_setup.exe +OutFile bitcoin-0.2.0-setup.exe InstallDir $PROGRAMFILES\Bitcoin CRCCheck on XPStyle on ShowInstDetails show -VIProductVersion 0.1.6.0 +VIProductVersion 0.2.0.0 VIAddVersionKey ProductName Bitcoin VIAddVersionKey ProductVersion "${VERSION}" VIAddVersionKey CompanyName "${COMPANY}" @@ -65,6 +65,11 @@ Section -Main SEC0000 File bitcoin.exe File libeay32.dll File mingwm10.dll + File license.txt + File readme.txt + SetOutPath $INSTDIR\src + File /r src\*.* + SetOutPath $INSTDIR WriteRegStr HKCU "${REGKEY}\Components" Main 1 SectionEnd @@ -102,9 +107,12 @@ done${UNSECTION_ID}: # Uninstaller sections Section /o -un.Main UNSEC0000 - Delete /REBOOTOK $INSTDIR\mingwm10.dll - Delete /REBOOTOK $INSTDIR\libeay32.dll Delete /REBOOTOK $INSTDIR\bitcoin.exe + Delete /REBOOTOK $INSTDIR\libeay32.dll + Delete /REBOOTOK $INSTDIR\mingwm10.dll + Delete /REBOOTOK $INSTDIR\license.txt + Delete /REBOOTOK $INSTDIR\readme.txt + RMDir /r /REBOOTOK $INSTDIR\src DeleteRegValue HKCU "${REGKEY}\Components" Main SectionEnd @@ -114,6 +122,7 @@ Section -un.post UNSEC0001 Delete /REBOOTOK "$SMPROGRAMS\$StartMenuGroup\Bitcoin.lnk" Delete /REBOOTOK "$SMSTARTUP\Bitcoin.lnk" Delete /REBOOTOK $INSTDIR\uninstall.exe + Delete /REBOOTOK $INSTDIR\debug.log Delete /REBOOTOK $INSTDIR\db.log DeleteRegValue HKCU "${REGKEY}" StartMenuGroup DeleteRegValue HKCU "${REGKEY}" Path @@ -139,4 +148,3 @@ Function un.onInit !insertmacro MUI_STARTMENU_GETFOLDER Application $StartMenuGroup !insertmacro SELECT_UNSECTION Main ${UNSEC0000} FunctionEnd - diff --git a/ui.cpp b/ui.cpp index 262f2a8837..7432302854 100644 --- a/ui.cpp +++ b/ui.cpp @@ -394,6 +394,14 @@ CMainFrame::~CMainFrame() ptaskbaricon = NULL; } +void ExitTimeout(void* parg) +{ +#ifdef __WXMSW__ + Sleep(5000); + ExitProcess(0); +#endif +} + void Shutdown(void* parg) { static CCriticalSection cs_Shutdown; @@ -404,6 +412,7 @@ void Shutdown(void* parg) fFirstThread = !fTaken; fTaken = true; } + static bool fExit; if (fFirstThread) { fShutdown = true; @@ -411,13 +420,18 @@ void Shutdown(void* parg) DBFlush(false); StopNode(); DBFlush(true); + CreateThread(ExitTimeout, NULL); + Sleep(10); printf("Bitcoin exiting\n\n"); + fExit = true; exit(0); } else { - loop - Sleep(100000); + while (!fExit) + Sleep(500); + Sleep(100); + ExitThread(0); } } -- cgit v1.2.3 From bd336ba27283106a5ae6b77f8a77561c644f114c Mon Sep 17 00:00:00 2001 From: s_nakamoto Date: Sun, 13 Dec 2009 02:13:43 +0000 Subject: restrict file permissions on linux to the user only --- db.cpp | 2 +- ui.cpp | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/db.cpp b/db.cpp index b21d1e3a21..c33f71ef79 100644 --- a/db.cpp +++ b/db.cpp @@ -79,7 +79,7 @@ CDB::CDB(const char* pszFile, const char* pszMode) : pdb(NULL) DB_THREAD | DB_PRIVATE | DB_RECOVER, - 0); + S_IRUSR | S_IWUSR); if (ret > 0) throw runtime_error(strprintf("CDB() : error %d opening database environment\n", ret)); fDbEnvInit = true; diff --git a/ui.cpp b/ui.cpp index 7432302854..6d65720d76 100644 --- a/ui.cpp +++ b/ui.cpp @@ -3494,6 +3494,7 @@ bool CMyApp::OnInit2() SetAppName("Bitcoin"); #else SetAppName("bitcoin"); + umask(077); #endif // -- cgit v1.2.3 From e899779450bcd940dcdb0108d27c35eae92cc1e1 Mon Sep 17 00:00:00 2001 From: s_nakamoto Date: Sun, 13 Dec 2009 02:13:43 +0000 Subject: restrict file permissions on linux to the user only git-svn-id: https://bitcoin.svn.sourceforge.net/svnroot/bitcoin/trunk@47 1a98c847-1fd6-4fd8-948a-caf3550aa51b --- db.cpp | 2 +- ui.cpp | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/db.cpp b/db.cpp index b21d1e3a21..c33f71ef79 100644 --- a/db.cpp +++ b/db.cpp @@ -79,7 +79,7 @@ CDB::CDB(const char* pszFile, const char* pszMode) : pdb(NULL) DB_THREAD | DB_PRIVATE | DB_RECOVER, - 0); + S_IRUSR | S_IWUSR); if (ret > 0) throw runtime_error(strprintf("CDB() : error %d opening database environment\n", ret)); fDbEnvInit = true; diff --git a/ui.cpp b/ui.cpp index 7432302854..6d65720d76 100644 --- a/ui.cpp +++ b/ui.cpp @@ -3494,6 +3494,7 @@ bool CMyApp::OnInit2() SetAppName("Bitcoin"); #else SetAppName("bitcoin"); + umask(077); #endif // -- cgit v1.2.3 From 2ed2b9a3e42110beb657efb51360cb545c6a72f8 Mon Sep 17 00:00:00 2001 From: s_nakamoto Date: Sun, 13 Dec 2009 02:34:45 +0000 Subject: misc --- util.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/util.h b/util.h index ae53bfedbe..b9c3658f76 100644 --- a/util.h +++ b/util.h @@ -62,6 +62,10 @@ inline T& REF(const T& val) #define INT64_MAX _I64_MAX #define INT64_MIN _I64_MIN #endif +#ifndef S_IRUSR +#define S_IRUSR 0400 +#define S_IWUSR 0200 +#endif #else #define WSAGetLastError() errno #define WSAEWOULDBLOCK EWOULDBLOCK -- cgit v1.2.3 From adb50ffe32c5c37c84ff35d94bb486004e14a7cc Mon Sep 17 00:00:00 2001 From: s_nakamoto Date: Sun, 13 Dec 2009 02:34:45 +0000 Subject: misc git-svn-id: https://bitcoin.svn.sourceforge.net/svnroot/bitcoin/trunk@48 1a98c847-1fd6-4fd8-948a-caf3550aa51b --- util.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/util.h b/util.h index ae53bfedbe..b9c3658f76 100644 --- a/util.h +++ b/util.h @@ -62,6 +62,10 @@ inline T& REF(const T& val) #define INT64_MAX _I64_MAX #define INT64_MIN _I64_MIN #endif +#ifndef S_IRUSR +#define S_IRUSR 0400 +#define S_IWUSR 0200 +#endif #else #define WSAGetLastError() errno #define WSAEWOULDBLOCK EWOULDBLOCK -- cgit v1.2.3 From 2da02dd7749060b55fd5e14696277b64583b8100 Mon Sep 17 00:00:00 2001 From: s_nakamoto Date: Mon, 14 Dec 2009 02:12:01 +0000 Subject: filter out duplicate getblocks and don't relay inv messages during initial block download -- 0.2 rc2 --- main.cpp | 25 ++++++++++--------------- net.cpp | 21 +++++++++++++++++++-- net.h | 7 +++++++ serialize.h | 2 +- setup.nsi | 2 +- 5 files changed, 38 insertions(+), 19 deletions(-) diff --git a/main.cpp b/main.cpp index cb93e5486f..4cc91cb1b8 100644 --- a/main.cpp +++ b/main.cpp @@ -1274,7 +1274,7 @@ bool CBlock::AcceptBlock() if (!AddToBlockIndex(nFile, nBlockPos)) return error("AcceptBlock() : AddToBlockIndex failed"); - if (hashBestChain == hash) + if (hashBestChain == hash && nBestHeight > 28000) RelayInventory(CInv(MSG_BLOCK, hash)); // // Add atoms to user reviews for coins created @@ -1314,7 +1314,7 @@ bool ProcessBlock(CNode* pfrom, CBlock* pblock) // Ask this guy to fill in what we're missing if (pfrom) - pfrom->PushMessage("getblocks", CBlockLocator(pindexBest), GetOrphanRoot(pblock)); + pfrom->PushGetBlocks(pindexBest, GetOrphanRoot(pblock)); return true; } @@ -1816,7 +1816,7 @@ bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) if (!fAskedForBlocks && !pfrom->fClient) { fAskedForBlocks = true; - pfrom->PushMessage("getblocks", CBlockLocator(pindexBest), uint256(0)); + pfrom->PushGetBlocks(pindexBest, uint256(0)); } pfrom->fSuccessfullyConnected = true; @@ -1836,6 +1836,8 @@ bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) { vector vAddr; vRecv >> vAddr; + if (vAddr.size() > 50000) // lower this to 1000 later + return error("message addr size() = %d", vAddr.size()); // Store the new addresses CAddrDB addrdb; @@ -1864,6 +1866,8 @@ bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) { vector vInv; vRecv >> vInv; + if (vInv.size() > 50000) + return error("message inv size() = %d", vInv.size()); CTxDB txdb("r"); foreach(const CInv& inv, vInv) @@ -1878,7 +1882,7 @@ bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) if (!fAlreadyHave) pfrom->AskFor(inv); else if (inv.type == MSG_BLOCK && mapOrphanBlocks.count(inv.hash)) - pfrom->PushMessage("getblocks", CBlockLocator(pindexBest), GetOrphanRoot(mapOrphanBlocks[inv.hash])); + pfrom->PushGetBlocks(pindexBest, GetOrphanRoot(mapOrphanBlocks[inv.hash])); // Track requests for our stuff CRITICAL_BLOCK(cs_mapRequestCount) @@ -1895,6 +1899,8 @@ bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) { vector vInv; vRecv >> vInv; + if (vInv.size() > 50000) + return error("message getdata size() = %d", vInv.size()); foreach(const CInv& inv, vInv) { @@ -2210,17 +2216,6 @@ bool SendMessages(CNode* pto) } } - // Clear inventory known periodically in case an inv message was missed, - // although usually they would just get it from another node. - static int64 nLastInventoryKnownClear; - if (GetTime() - nLastInventoryKnownClear > 2 * 60 * 60) // every 2 hours - { - nLastInventoryKnownClear = GetTime(); - CRITICAL_BLOCK(cs_vNodes) - foreach(CNode* pnode, vNodes) - pnode->setInventoryKnown.clear(); - } - // // Message: addr diff --git a/net.cpp b/net.cpp index 941e7c4dc9..168651ca2e 100644 --- a/net.cpp +++ b/net.cpp @@ -40,6 +40,23 @@ CAddress addrProxy("127.0.0.1:9050"); + + +void CNode::PushGetBlocks(CBlockIndex* pindexBegin, uint256 hashEnd) +{ + // Filter out duplicate requests + if (pindexBegin == pindexLastGetBlocksBegin && hashEnd == hashLastGetBlocksEnd) + return; + pindexLastGetBlocksBegin = pindexBegin; + hashLastGetBlocksEnd = hashEnd; + + PushMessage("getblocks", CBlockLocator(pindexBegin), hashEnd); +} + + + + + bool ConnectSocket(const CAddress& addrConnect, SOCKET& hSocketRet) { hSocketRet = INVALID_SOCKET; @@ -764,12 +781,12 @@ void ThreadSocketHandler2(void* parg) printf("socket no message in first 60 seconds, %d %d\n", pnode->nLastRecv != 0, pnode->nLastSend != 0); pnode->fDisconnect = true; } - else if (GetTime() - pnode->nLastSend > 10 * 60 && GetTime() - pnode->nLastSendEmpty > 10 * 60) + else if (GetTime() - pnode->nLastSend > 90*60 && GetTime() - pnode->nLastSendEmpty > 90*60) { printf("socket not sending\n"); pnode->fDisconnect = true; } - else if (GetTime() - pnode->nLastRecv > (pnode->nVersion >= 107 ? 15*60 : 90*60)) + else if (GetTime() - pnode->nLastRecv > 90*60) { printf("socket inactivity timeout\n"); pnode->fDisconnect = true; diff --git a/net.h b/net.h index 7fe4a7c7d7..90af3b4b10 100644 --- a/net.h +++ b/net.h @@ -7,6 +7,7 @@ class CAddress; class CInv; class CRequestTracker; class CNode; +class CBlockIndex; @@ -504,6 +505,8 @@ public: map mapRequests; CCriticalSection cs_mapRequests; uint256 hashContinue; + CBlockIndex* pindexLastGetBlocksBegin; + uint256 hashLastGetBlocksEnd; // flood vector vAddrToSend; @@ -541,6 +544,8 @@ public: nRefCount = 0; nReleaseTime = 0; hashContinue = 0; + pindexLastGetBlocksBegin = 0; + hashLastGetBlocksEnd = 0; fGetAddr = false; vfSubscribe.assign(256, false); @@ -635,6 +640,7 @@ public: } + void BeginMessage(const char* pszCommand) { cs_vSend.Enter(); @@ -900,6 +906,7 @@ public: + void PushGetBlocks(CBlockIndex* pindexBegin, uint256 hashEnd); bool IsSubscribed(unsigned int nChannel); void Subscribe(unsigned int nChannel, unsigned int nHops=0); void CancelSubscribe(unsigned int nChannel); diff --git a/serialize.h b/serialize.h index 8f925103b1..ce4aff3cda 100644 --- a/serialize.h +++ b/serialize.h @@ -20,7 +20,7 @@ class CDataStream; class CAutoFile; static const int VERSION = 200; -static const char* pszSubVer = " rc1"; +static const char* pszSubVer = " rc2"; diff --git a/setup.nsi b/setup.nsi index a5a73366a3..03322877a4 100644 --- a/setup.nsi +++ b/setup.nsi @@ -42,7 +42,7 @@ Var StartMenuGroup !insertmacro MUI_LANGUAGE English # Installer attributes -OutFile bitcoin-0.2.0-setup.exe +OutFile bitcoin-0.2.0-win32-setup.exe InstallDir $PROGRAMFILES\Bitcoin CRCCheck on XPStyle on -- cgit v1.2.3 From e2c2648c14f4b87d331dbc30f0f2bd4aab9ce7e6 Mon Sep 17 00:00:00 2001 From: s_nakamoto Date: Mon, 14 Dec 2009 02:12:01 +0000 Subject: filter out duplicate getblocks and don't relay inv messages during initial block download -- 0.2 rc2 git-svn-id: https://bitcoin.svn.sourceforge.net/svnroot/bitcoin/trunk@49 1a98c847-1fd6-4fd8-948a-caf3550aa51b --- main.cpp | 25 ++++++++++--------------- net.cpp | 21 +++++++++++++++++++-- net.h | 7 +++++++ serialize.h | 2 +- setup.nsi | 2 +- 5 files changed, 38 insertions(+), 19 deletions(-) diff --git a/main.cpp b/main.cpp index cb93e5486f..4cc91cb1b8 100644 --- a/main.cpp +++ b/main.cpp @@ -1274,7 +1274,7 @@ bool CBlock::AcceptBlock() if (!AddToBlockIndex(nFile, nBlockPos)) return error("AcceptBlock() : AddToBlockIndex failed"); - if (hashBestChain == hash) + if (hashBestChain == hash && nBestHeight > 28000) RelayInventory(CInv(MSG_BLOCK, hash)); // // Add atoms to user reviews for coins created @@ -1314,7 +1314,7 @@ bool ProcessBlock(CNode* pfrom, CBlock* pblock) // Ask this guy to fill in what we're missing if (pfrom) - pfrom->PushMessage("getblocks", CBlockLocator(pindexBest), GetOrphanRoot(pblock)); + pfrom->PushGetBlocks(pindexBest, GetOrphanRoot(pblock)); return true; } @@ -1816,7 +1816,7 @@ bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) if (!fAskedForBlocks && !pfrom->fClient) { fAskedForBlocks = true; - pfrom->PushMessage("getblocks", CBlockLocator(pindexBest), uint256(0)); + pfrom->PushGetBlocks(pindexBest, uint256(0)); } pfrom->fSuccessfullyConnected = true; @@ -1836,6 +1836,8 @@ bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) { vector vAddr; vRecv >> vAddr; + if (vAddr.size() > 50000) // lower this to 1000 later + return error("message addr size() = %d", vAddr.size()); // Store the new addresses CAddrDB addrdb; @@ -1864,6 +1866,8 @@ bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) { vector vInv; vRecv >> vInv; + if (vInv.size() > 50000) + return error("message inv size() = %d", vInv.size()); CTxDB txdb("r"); foreach(const CInv& inv, vInv) @@ -1878,7 +1882,7 @@ bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) if (!fAlreadyHave) pfrom->AskFor(inv); else if (inv.type == MSG_BLOCK && mapOrphanBlocks.count(inv.hash)) - pfrom->PushMessage("getblocks", CBlockLocator(pindexBest), GetOrphanRoot(mapOrphanBlocks[inv.hash])); + pfrom->PushGetBlocks(pindexBest, GetOrphanRoot(mapOrphanBlocks[inv.hash])); // Track requests for our stuff CRITICAL_BLOCK(cs_mapRequestCount) @@ -1895,6 +1899,8 @@ bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) { vector vInv; vRecv >> vInv; + if (vInv.size() > 50000) + return error("message getdata size() = %d", vInv.size()); foreach(const CInv& inv, vInv) { @@ -2210,17 +2216,6 @@ bool SendMessages(CNode* pto) } } - // Clear inventory known periodically in case an inv message was missed, - // although usually they would just get it from another node. - static int64 nLastInventoryKnownClear; - if (GetTime() - nLastInventoryKnownClear > 2 * 60 * 60) // every 2 hours - { - nLastInventoryKnownClear = GetTime(); - CRITICAL_BLOCK(cs_vNodes) - foreach(CNode* pnode, vNodes) - pnode->setInventoryKnown.clear(); - } - // // Message: addr diff --git a/net.cpp b/net.cpp index 941e7c4dc9..168651ca2e 100644 --- a/net.cpp +++ b/net.cpp @@ -40,6 +40,23 @@ CAddress addrProxy("127.0.0.1:9050"); + + +void CNode::PushGetBlocks(CBlockIndex* pindexBegin, uint256 hashEnd) +{ + // Filter out duplicate requests + if (pindexBegin == pindexLastGetBlocksBegin && hashEnd == hashLastGetBlocksEnd) + return; + pindexLastGetBlocksBegin = pindexBegin; + hashLastGetBlocksEnd = hashEnd; + + PushMessage("getblocks", CBlockLocator(pindexBegin), hashEnd); +} + + + + + bool ConnectSocket(const CAddress& addrConnect, SOCKET& hSocketRet) { hSocketRet = INVALID_SOCKET; @@ -764,12 +781,12 @@ void ThreadSocketHandler2(void* parg) printf("socket no message in first 60 seconds, %d %d\n", pnode->nLastRecv != 0, pnode->nLastSend != 0); pnode->fDisconnect = true; } - else if (GetTime() - pnode->nLastSend > 10 * 60 && GetTime() - pnode->nLastSendEmpty > 10 * 60) + else if (GetTime() - pnode->nLastSend > 90*60 && GetTime() - pnode->nLastSendEmpty > 90*60) { printf("socket not sending\n"); pnode->fDisconnect = true; } - else if (GetTime() - pnode->nLastRecv > (pnode->nVersion >= 107 ? 15*60 : 90*60)) + else if (GetTime() - pnode->nLastRecv > 90*60) { printf("socket inactivity timeout\n"); pnode->fDisconnect = true; diff --git a/net.h b/net.h index 7fe4a7c7d7..90af3b4b10 100644 --- a/net.h +++ b/net.h @@ -7,6 +7,7 @@ class CAddress; class CInv; class CRequestTracker; class CNode; +class CBlockIndex; @@ -504,6 +505,8 @@ public: map mapRequests; CCriticalSection cs_mapRequests; uint256 hashContinue; + CBlockIndex* pindexLastGetBlocksBegin; + uint256 hashLastGetBlocksEnd; // flood vector vAddrToSend; @@ -541,6 +544,8 @@ public: nRefCount = 0; nReleaseTime = 0; hashContinue = 0; + pindexLastGetBlocksBegin = 0; + hashLastGetBlocksEnd = 0; fGetAddr = false; vfSubscribe.assign(256, false); @@ -635,6 +640,7 @@ public: } + void BeginMessage(const char* pszCommand) { cs_vSend.Enter(); @@ -900,6 +906,7 @@ public: + void PushGetBlocks(CBlockIndex* pindexBegin, uint256 hashEnd); bool IsSubscribed(unsigned int nChannel); void Subscribe(unsigned int nChannel, unsigned int nHops=0); void CancelSubscribe(unsigned int nChannel); diff --git a/serialize.h b/serialize.h index 8f925103b1..ce4aff3cda 100644 --- a/serialize.h +++ b/serialize.h @@ -20,7 +20,7 @@ class CDataStream; class CAutoFile; static const int VERSION = 200; -static const char* pszSubVer = " rc1"; +static const char* pszSubVer = " rc2"; diff --git a/setup.nsi b/setup.nsi index a5a73366a3..03322877a4 100644 --- a/setup.nsi +++ b/setup.nsi @@ -42,7 +42,7 @@ Var StartMenuGroup !insertmacro MUI_LANGUAGE English # Installer attributes -OutFile bitcoin-0.2.0-setup.exe +OutFile bitcoin-0.2.0-win32-setup.exe InstallDir $PROGRAMFILES\Bitcoin CRCCheck on XPStyle on -- cgit v1.2.3 From 9228c53cf59b8b24bddb04dbc0485d583e79bf4a Mon Sep 17 00:00:00 2001 From: s_nakamoto Date: Thu, 17 Dec 2009 18:15:50 +0000 Subject: a few header changes for freebsd from madhatter --- headers.h | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/headers.h b/headers.h index 22bb830f72..73a0b43af4 100644 --- a/headers.h +++ b/headers.h @@ -35,9 +35,7 @@ #include #include #include -#include #include -#define BOUNDSCHECK 1 #include #include #include @@ -64,6 +62,7 @@ #include #include #include +#include #else #include #include @@ -77,6 +76,10 @@ #include #include #endif +#ifdef __BSD__ +#include +#endif + #pragma hdrstop using namespace std; -- cgit v1.2.3 From 312c2c42b6d38dc7bfeef849722c8e231c38e8e4 Mon Sep 17 00:00:00 2001 From: s_nakamoto Date: Thu, 17 Dec 2009 18:15:50 +0000 Subject: a few header changes for freebsd from madhatter git-svn-id: https://bitcoin.svn.sourceforge.net/svnroot/bitcoin/trunk@51 1a98c847-1fd6-4fd8-948a-caf3550aa51b --- headers.h | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/headers.h b/headers.h index 22bb830f72..73a0b43af4 100644 --- a/headers.h +++ b/headers.h @@ -35,9 +35,7 @@ #include #include #include -#include #include -#define BOUNDSCHECK 1 #include #include #include @@ -64,6 +62,7 @@ #include #include #include +#include #else #include #include @@ -77,6 +76,10 @@ #include #include #endif +#ifdef __BSD__ +#include +#endif + #pragma hdrstop using namespace std; -- cgit v1.2.3 From 95d839f15c2ae418939bbecdc95228f00ea4466d Mon Sep 17 00:00:00 2001 From: s_nakamoto Date: Thu, 17 Dec 2009 23:16:27 +0000 Subject: command line switch -noui --- ui.cpp | 34 +++++++++++++++------------------- 1 file changed, 15 insertions(+), 19 deletions(-) diff --git a/ui.cpp b/ui.cpp index 6d65720d76..67895c127b 100644 --- a/ui.cpp +++ b/ui.cpp @@ -190,6 +190,9 @@ void CalledMessageBox(const string& message, const string& caption, int style, w int ThreadSafeMessageBox(const string& message, const string& caption, int style, wxWindow* parent, int x, int y) { + if (mapArgs.count("-noui")) + return wxOK; + #ifdef __WXMSW__ return wxMessageBox(message, caption, style, parent, x, y); #else @@ -3716,16 +3719,19 @@ bool CMyApp::OnInit2() // // Create the main frame window // - pframeMain = new CMainFrame(NULL); - if (mapArgs.count("-min")) - pframeMain->Iconize(true); - 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); + if (!mapArgs.count("-noui")) + { + pframeMain = new CMainFrame(NULL); + if (mapArgs.count("-min")) + pframeMain->Iconize(true); + 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); + CreateThread(ThreadDelayedRepaint, NULL); + } if (!CheckDiskSpace()) return false; @@ -3928,13 +3934,3 @@ void SetStartOnSystemStartup(bool fAutoStart) bool GetStartOnSystemStartup() { return false; } void SetStartOnSystemStartup(bool fAutoStart) { } #endif - - - - - - - - - - -- cgit v1.2.3 From 9a36562347122482fd1e6e77c74df66ad8cf2c3f Mon Sep 17 00:00:00 2001 From: s_nakamoto Date: Thu, 17 Dec 2009 23:16:27 +0000 Subject: command line switch -noui git-svn-id: https://bitcoin.svn.sourceforge.net/svnroot/bitcoin/trunk@52 1a98c847-1fd6-4fd8-948a-caf3550aa51b --- ui.cpp | 34 +++++++++++++++------------------- 1 file changed, 15 insertions(+), 19 deletions(-) diff --git a/ui.cpp b/ui.cpp index 6d65720d76..67895c127b 100644 --- a/ui.cpp +++ b/ui.cpp @@ -190,6 +190,9 @@ void CalledMessageBox(const string& message, const string& caption, int style, w int ThreadSafeMessageBox(const string& message, const string& caption, int style, wxWindow* parent, int x, int y) { + if (mapArgs.count("-noui")) + return wxOK; + #ifdef __WXMSW__ return wxMessageBox(message, caption, style, parent, x, y); #else @@ -3716,16 +3719,19 @@ bool CMyApp::OnInit2() // // Create the main frame window // - pframeMain = new CMainFrame(NULL); - if (mapArgs.count("-min")) - pframeMain->Iconize(true); - 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); + if (!mapArgs.count("-noui")) + { + pframeMain = new CMainFrame(NULL); + if (mapArgs.count("-min")) + pframeMain->Iconize(true); + 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); + CreateThread(ThreadDelayedRepaint, NULL); + } if (!CheckDiskSpace()) return false; @@ -3928,13 +3934,3 @@ void SetStartOnSystemStartup(bool fAutoStart) bool GetStartOnSystemStartup() { return false; } void SetStartOnSystemStartup(bool fAutoStart) { } #endif - - - - - - - - - - -- cgit v1.2.3 From 80264be428b7ec7692e6633a0f21232c63a0b62c Mon Sep 17 00:00:00 2001 From: s_nakamoto Date: Thu, 28 Jan 2010 00:31:00 +0000 Subject: simplify AddAddress, readcompactsize limit, fixed a 64-bit compile error in serialize.h, change status "# blocks" to "# confirmations" and widen the column. --- db.cpp | 4 +-- irc.cpp | 3 +- main.cpp | 8 +++-- net.cpp | 10 +++--- net.h | 4 +-- serialize.h | 16 ++++++---- ui.cpp | 17 +++++++--- uibase.h | 2 +- uiproject.fbp | 4 +-- util.cpp | 77 +++++++++++++++++++++++++++++++++++++++++++- util.h | 101 +++++++--------------------------------------------------- 11 files changed, 129 insertions(+), 117 deletions(-) diff --git a/db.cpp b/db.cpp index c33f71ef79..77f8e1e0dd 100644 --- a/db.cpp +++ b/db.cpp @@ -134,8 +134,6 @@ void CDB::Close() CRITICAL_BLOCK(cs_db) --mapFileUseCount[strFile]; - - RandAddSeed(); } void CloseDb(const string& strFile) @@ -456,7 +454,7 @@ bool CAddrDB::LoadAddresses() CAddress addr(psz, NODE_NETWORK); addr.nTime = 0; // so it won't relay unless successfully connected if (addr.IsValid()) - AddAddress(*this, addr); + AddAddress(addr); } } catch (...) { } diff --git a/irc.cpp b/irc.cpp index 8e8510859f..f38db6bbb0 100644 --- a/irc.cpp +++ b/irc.cpp @@ -265,8 +265,7 @@ void ThreadIRCSeed(void* parg) if (DecodeAddress(pszName, addr)) { addr.nTime = GetAdjustedTime() - 51 * 60; - CAddrDB addrdb; - if (AddAddress(addrdb, addr)) + if (AddAddress(addr)) printf("IRC got new address\n"); nGotIRCAddresses++; } diff --git a/main.cpp b/main.cpp index 4cc91cb1b8..416c616ad1 100644 --- a/main.cpp +++ b/main.cpp @@ -1734,6 +1734,11 @@ bool ProcessMessages(CNode* pfrom) // Allow exceptions from underlength message on vRecv printf("ProcessMessage(%s, %d bytes) : Exception '%s' caught, normally caused by a message being shorter than its stated length\n", strCommand.c_str(), nMessageSize, e.what()); } + else if (strstr(e.what(), ": size too large")) + { + // Allow exceptions from overlong size + printf("ProcessMessage(%s, %d bytes) : Exception '%s' caught\n", strCommand.c_str(), nMessageSize, e.what()); + } else { PrintException(&e, "ProcessMessage()"); @@ -1840,7 +1845,6 @@ bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) return error("message addr size() = %d", vAddr.size()); // Store the new addresses - CAddrDB addrdb; foreach(CAddress& addr, vAddr) { if (fShutdown) @@ -1848,7 +1852,7 @@ bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) addr.nTime = GetAdjustedTime() - 2 * 60 * 60; if (pfrom->fGetAddr) addr.nTime -= 5 * 24 * 60 * 60; - AddAddress(addrdb, addr, false); + AddAddress(addr, false); pfrom->AddAddressKnown(addr); if (!pfrom->fGetAddr && addr.IsRoutable()) { diff --git a/net.cpp b/net.cpp index 168651ca2e..38d05de1ab 100644 --- a/net.cpp +++ b/net.cpp @@ -223,7 +223,7 @@ bool GetMyExternalIP(unsigned int& ipRet) -bool AddAddress(CAddrDB& addrdb, CAddress addr, bool fCurrentlyOnline) +bool AddAddress(CAddress addr, bool fCurrentlyOnline) { if (!addr.IsRoutable()) return false; @@ -239,7 +239,7 @@ bool AddAddress(CAddrDB& addrdb, CAddress addr, bool fCurrentlyOnline) // New address printf("AddAddress(%s)\n", addr.ToStringLog().c_str()); mapAddresses.insert(make_pair(addr.GetKey(), addr)); - addrdb.WriteAddress(addr); + CAddrDB().WriteAddress(addr); return true; } else @@ -260,7 +260,7 @@ bool AddAddress(CAddrDB& addrdb, CAddress addr, bool fCurrentlyOnline) fUpdated = true; } if (fUpdated) - addrdb.WriteAddress(addrFound); + CAddrDB().WriteAddress(addrFound); } } return false; @@ -881,11 +881,11 @@ void ThreadOpenConnections2(void* parg) vnThreadsRunning[1]--; Sleep(500); const int nMaxConnections = 15; - while (vNodes.size() >= nMaxConnections || vNodes.size() >= mapAddresses.size()) + while (vNodes.size() >= nMaxConnections) { + Sleep(2000); if (fShutdown) return; - Sleep(2000); } vnThreadsRunning[1]++; if (fShutdown) diff --git a/net.h b/net.h index 90af3b4b10..ba4607a558 100644 --- a/net.h +++ b/net.h @@ -23,7 +23,7 @@ enum bool ConnectSocket(const CAddress& addrConnect, SOCKET& hSocketRet); bool GetMyExternalIP(unsigned int& ipRet); -bool AddAddress(CAddrDB& addrdb, CAddress addr, bool fCurrentlyOnline=true); +bool AddAddress(CAddress addr, bool fCurrentlyOnline=true); void AddressCurrentlyConnected(const CAddress& addr); CNode* FindNode(unsigned int ip); CNode* ConnectNode(CAddress addrConnect, int64 nTimeout=0); @@ -627,7 +627,7 @@ public: // We're using mapAskFor as a priority queue, // the key is the earliest time the request can be sent int64& nRequestTime = mapAlreadyAskedFor[inv]; - printf("askfor %s %"PRI64d"\n", inv.ToString().c_str(), nRequestTime); + printf("askfor %s %"PRI64d"\n", inv.ToString().c_str(), nRequestTime); // Make sure not to reuse time indexes to keep things in the same order int64 nNow = (GetTime() - 1) * 1000000; diff --git a/serialize.h b/serialize.h index ce4aff3cda..263a22677d 100644 --- a/serialize.h +++ b/serialize.h @@ -20,7 +20,7 @@ class CDataStream; class CAutoFile; static const int VERSION = 200; -static const char* pszSubVer = " rc2"; +static const char* pszSubVer = " test1"; @@ -194,28 +194,32 @@ uint64 ReadCompactSize(Stream& is) { unsigned char chSize; READDATA(is, chSize); + uint64 nSizeRet = 0; if (chSize < UCHAR_MAX-2) { - return chSize; + nSizeRet = chSize; } else if (chSize == UCHAR_MAX-2) { unsigned short nSize; READDATA(is, nSize); - return nSize; + nSizeRet = nSize; } else if (chSize == UCHAR_MAX-1) { unsigned int nSize; READDATA(is, nSize); - return nSize; + nSizeRet = nSize; } else { uint64 nSize; READDATA(is, nSize); - return nSize; + nSizeRet = nSize; } + if (nSizeRet > (uint64)INT_MAX) + throw std::ios_base::failure("ReadCompactSize() : size too large"); + return nSizeRet; } @@ -460,7 +464,7 @@ void Unserialize_impl(Stream& is, std::vector& v, int nType, int nVersion, unsigned int i = 0; while (i < nSize) { - unsigned int blk = min(nSize - i, 1 + 4999999 / sizeof(T)); + unsigned int blk = min(nSize - i, (unsigned int)(1 + 4999999 / sizeof(T))); v.resize(i + blk); is.read((char*)&v[i], blk * sizeof(T)); i += blk; diff --git a/ui.cpp b/ui.cpp index 67895c127b..994cc7e214 100644 --- a/ui.cpp +++ b/ui.cpp @@ -349,7 +349,7 @@ CMainFrame::CMainFrame(wxWindow* parent) : CMainFrameBase(parent) nDateWidth += 12; m_listCtrl->InsertColumn(0, "", wxLIST_FORMAT_LEFT, dResize * 0); m_listCtrl->InsertColumn(1, "", wxLIST_FORMAT_LEFT, dResize * 0); - m_listCtrl->InsertColumn(2, "Status", wxLIST_FORMAT_LEFT, dResize * 90); + m_listCtrl->InsertColumn(2, "Status", wxLIST_FORMAT_LEFT, dResize * 110); m_listCtrl->InsertColumn(3, "Date", wxLIST_FORMAT_LEFT, dResize * nDateWidth); m_listCtrl->InsertColumn(4, "Description", wxLIST_FORMAT_LEFT, dResize * 409 - nDateWidth); m_listCtrl->InsertColumn(5, "Debit", wxLIST_FORMAT_RIGHT, dResize * 79); @@ -579,7 +579,7 @@ string FormatTxStatus(const CWalletTx& wtx) else if (nDepth < 6) return strprintf("%d/unconfirmed", nDepth); else - return strprintf("%d blocks", nDepth); + return strprintf("%d confirmations", nDepth); } } @@ -3706,13 +3706,12 @@ bool CMyApp::OnInit2() if (mapArgs.count("-addnode")) { - CAddrDB addrdb; foreach(string strAddr, mapMultiArgs["-addnode"]) { CAddress addr(strAddr, NODE_NETWORK); addr.nTime = 0; // so it won't relay unless successfully connected if (addr.IsValid()) - AddAddress(addrdb, addr); + AddAddress(addr); } } @@ -3934,3 +3933,13 @@ void SetStartOnSystemStartup(bool fAutoStart) bool GetStartOnSystemStartup() { return false; } void SetStartOnSystemStartup(bool fAutoStart) { } #endif + + + + + + + + + + diff --git a/uibase.h b/uibase.h index e0c152185c..7620a24e53 100644 --- a/uibase.h +++ b/uibase.h @@ -158,7 +158,7 @@ class CMainFrameBase : public wxFrame wxListCtrl* m_listCtrlOrdersSent; wxListCtrl* m_listCtrlProductsSent; wxListCtrl* m_listCtrlOrdersReceived; - CMainFrameBase( wxWindow* parent, wxWindowID id = wxID_MAINFRAME, const wxString& title = wxT("Bitcoin"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 705,484 ), long style = wxDEFAULT_FRAME_STYLE|wxRESIZE_BORDER|wxTAB_TRAVERSAL ); + CMainFrameBase( wxWindow* parent, wxWindowID id = wxID_MAINFRAME, const wxString& title = wxT("Bitcoin"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 725,484 ), long style = wxDEFAULT_FRAME_STYLE|wxRESIZE_BORDER|wxTAB_TRAVERSAL ); ~CMainFrameBase(); }; diff --git a/uiproject.fbp b/uiproject.fbp index 58a99bddd8..34fde78148 100644 --- a/uiproject.fbp +++ b/uiproject.fbp @@ -32,7 +32,7 @@ CMainFrameBase - 705,484 + 725,484 wxDEFAULT_FRAME_STYLE|wxRESIZE_BORDER Bitcoin @@ -1737,7 +1737,7 @@ - + bSizer55 wxVERTICAL diff --git a/util.cpp b/util.cpp index f5f2797fec..4292246762 100644 --- a/util.cpp +++ b/util.cpp @@ -8,8 +8,8 @@ map mapArgs; map > mapMultiArgs; bool fDebug = false; -bool fPrintToDebugger = false; bool fPrintToConsole = false; +bool fPrintToDebugger = false; char pszSetDataDir[MAX_PATH] = ""; bool fShutdown = false; @@ -75,6 +75,8 @@ void RandAddSeed() void RandAddSeedPerfmon() { + RandAddSeed(); + // This can take up to 2 seconds, so only do it every 10 minutes static int64 nLastPerfmon; if (GetTime() < nLastPerfmon + 10 * 60) @@ -129,6 +131,79 @@ uint64 GetRand(uint64 nMax) +inline int OutputDebugStringF(const char* pszFormat, ...) +{ + int ret = 0; + if (fPrintToConsole || wxTheApp == NULL) + { + // print to console + va_list arg_ptr; + va_start(arg_ptr, pszFormat); + ret = vprintf(pszFormat, arg_ptr); + va_end(arg_ptr); + } + else + { + // print to debug.log + char pszFile[MAX_PATH+100]; + GetDataDir(pszFile); + strlcat(pszFile, "/debug.log", sizeof(pszFile)); + FILE* fileout = fopen(pszFile, "a"); + if (fileout) + { + //// Debug print useful for profiling + //fprintf(fileout, " %"PRI64d" ", wxGetLocalTimeMillis().GetValue()); + va_list arg_ptr; + va_start(arg_ptr, pszFormat); + ret = vfprintf(fileout, pszFormat, arg_ptr); + va_end(arg_ptr); + fclose(fileout); + } + } + +#ifdef __WXMSW__ + if (fPrintToDebugger) + { + // accumulate a line at a time + static CCriticalSection cs_OutputDebugStringF; + CRITICAL_BLOCK(cs_OutputDebugStringF) + { + static char pszBuffer[50000]; + static char* pend; + if (pend == NULL) + pend = pszBuffer; + va_list arg_ptr; + va_start(arg_ptr, pszFormat); + int limit = END(pszBuffer) - pend - 2; + int ret = _vsnprintf(pend, limit, pszFormat, arg_ptr); + va_end(arg_ptr); + if (ret < 0 || ret >= limit) + { + pend = END(pszBuffer) - 2; + *pend++ = '\n'; + } + else + pend += ret; + *pend = '\0'; + char* p1 = pszBuffer; + char* p2; + while (p2 = strchr(p1, '\n')) + { + p2++; + char c = *p2; + *p2 = '\0'; + OutputDebugString(p1); + *p2 = c; + p1 = p2; + } + if (p1 != pszBuffer) + memmove(pszBuffer, p1, pend - p1 + 1); + pend -= (p1 - pszBuffer); + } + } +#endif + return ret; +} // Safer snprintf diff --git a/util.h b/util.h index b9c3658f76..d20648bcd3 100644 --- a/util.h +++ b/util.h @@ -112,13 +112,14 @@ inline int myclosesocket(SOCKET& hSocket) extern map mapArgs; extern map > mapMultiArgs; extern bool fDebug; -extern bool fPrintToDebugger; extern bool fPrintToConsole; +extern bool fPrintToDebugger; extern char pszSetDataDir[MAX_PATH]; extern bool fShutdown; void RandAddSeed(); void RandAddSeedPerfmon(); +int OutputDebugStringF(const char* pszFormat, ...); int my_snprintf(char* buffer, size_t limit, const char* format, ...); string strprintf(const char* format, ...); bool error(const char* format, ...); @@ -219,92 +220,6 @@ public: -inline int OutputDebugStringF(const char* pszFormat, ...) -{ - int ret = 0; -#ifdef __WXDEBUG__ - if (!fPrintToConsole) - { - // print to debug.log - char pszFile[MAX_PATH+100]; - GetDataDir(pszFile); - strlcat(pszFile, "/debug.log", sizeof(pszFile)); - FILE* fileout = fopen(pszFile, "a"); - if (fileout) - { - //// Debug print useful for profiling - //fprintf(fileout, " %"PRI64d" ", wxGetLocalTimeMillis().GetValue()); - va_list arg_ptr; - va_start(arg_ptr, pszFormat); - ret = vfprintf(fileout, pszFormat, arg_ptr); - va_end(arg_ptr); - fclose(fileout); - } - } - -#ifdef __WXMSW__ - if (fPrintToDebugger) - { - // accumulate a line at a time - static CCriticalSection cs_OutputDebugStringF; - CRITICAL_BLOCK(cs_OutputDebugStringF) - { - static char pszBuffer[50000]; - static char* pend; - if (pend == NULL) - pend = pszBuffer; - va_list arg_ptr; - va_start(arg_ptr, pszFormat); - int limit = END(pszBuffer) - pend - 2; - int ret = _vsnprintf(pend, limit, pszFormat, arg_ptr); - va_end(arg_ptr); - if (ret < 0 || ret >= limit) - { - pend = END(pszBuffer) - 2; - *pend++ = '\n'; - } - else - pend += ret; - *pend = '\0'; - char* p1 = pszBuffer; - char* p2; - while (p2 = strchr(p1, '\n')) - { - p2++; - char c = *p2; - *p2 = '\0'; - OutputDebugString(p1); - *p2 = c; - p1 = p2; - } - if (p1 != pszBuffer) - memmove(pszBuffer, p1, pend - p1 + 1); - pend -= (p1 - pszBuffer); - } - } -#endif -#endif - - if (fPrintToConsole) - { - // print to console - va_list arg_ptr; - va_start(arg_ptr, pszFormat); - ret = vprintf(pszFormat, arg_ptr); - va_end(arg_ptr); - } - return ret; -} - - - - - - - - - - inline string i64tostr(int64 n) { return strprintf("%"PRI64d, n); @@ -415,11 +330,19 @@ inline string DateTimeStrFormat(const char* pszFormat, int64 nTime) + + + + + + + inline void heapchk() { #ifdef __WXMSW__ - if (_heapchk() != _HEAPOK) - DebugBreak(); + /// for debugging + //if (_heapchk() != _HEAPOK) + // DebugBreak(); #endif } -- cgit v1.2.3 From cb0f89646f065800d38d7cfc10ba1e855563296a Mon Sep 17 00:00:00 2001 From: s_nakamoto Date: Thu, 28 Jan 2010 00:31:00 +0000 Subject: simplify AddAddress, readcompactsize limit, fixed a 64-bit compile error in serialize.h, change status "# blocks" to "# confirmations" and widen the column. git-svn-id: https://bitcoin.svn.sourceforge.net/svnroot/bitcoin/trunk@53 1a98c847-1fd6-4fd8-948a-caf3550aa51b --- db.cpp | 4 +-- irc.cpp | 3 +- main.cpp | 8 +++-- net.cpp | 10 +++--- net.h | 4 +-- serialize.h | 16 ++++++---- ui.cpp | 17 +++++++--- uibase.h | 2 +- uiproject.fbp | 4 +-- util.cpp | 77 +++++++++++++++++++++++++++++++++++++++++++- util.h | 101 +++++++--------------------------------------------------- 11 files changed, 129 insertions(+), 117 deletions(-) diff --git a/db.cpp b/db.cpp index c33f71ef79..77f8e1e0dd 100644 --- a/db.cpp +++ b/db.cpp @@ -134,8 +134,6 @@ void CDB::Close() CRITICAL_BLOCK(cs_db) --mapFileUseCount[strFile]; - - RandAddSeed(); } void CloseDb(const string& strFile) @@ -456,7 +454,7 @@ bool CAddrDB::LoadAddresses() CAddress addr(psz, NODE_NETWORK); addr.nTime = 0; // so it won't relay unless successfully connected if (addr.IsValid()) - AddAddress(*this, addr); + AddAddress(addr); } } catch (...) { } diff --git a/irc.cpp b/irc.cpp index 8e8510859f..f38db6bbb0 100644 --- a/irc.cpp +++ b/irc.cpp @@ -265,8 +265,7 @@ void ThreadIRCSeed(void* parg) if (DecodeAddress(pszName, addr)) { addr.nTime = GetAdjustedTime() - 51 * 60; - CAddrDB addrdb; - if (AddAddress(addrdb, addr)) + if (AddAddress(addr)) printf("IRC got new address\n"); nGotIRCAddresses++; } diff --git a/main.cpp b/main.cpp index 4cc91cb1b8..416c616ad1 100644 --- a/main.cpp +++ b/main.cpp @@ -1734,6 +1734,11 @@ bool ProcessMessages(CNode* pfrom) // Allow exceptions from underlength message on vRecv printf("ProcessMessage(%s, %d bytes) : Exception '%s' caught, normally caused by a message being shorter than its stated length\n", strCommand.c_str(), nMessageSize, e.what()); } + else if (strstr(e.what(), ": size too large")) + { + // Allow exceptions from overlong size + printf("ProcessMessage(%s, %d bytes) : Exception '%s' caught\n", strCommand.c_str(), nMessageSize, e.what()); + } else { PrintException(&e, "ProcessMessage()"); @@ -1840,7 +1845,6 @@ bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) return error("message addr size() = %d", vAddr.size()); // Store the new addresses - CAddrDB addrdb; foreach(CAddress& addr, vAddr) { if (fShutdown) @@ -1848,7 +1852,7 @@ bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) addr.nTime = GetAdjustedTime() - 2 * 60 * 60; if (pfrom->fGetAddr) addr.nTime -= 5 * 24 * 60 * 60; - AddAddress(addrdb, addr, false); + AddAddress(addr, false); pfrom->AddAddressKnown(addr); if (!pfrom->fGetAddr && addr.IsRoutable()) { diff --git a/net.cpp b/net.cpp index 168651ca2e..38d05de1ab 100644 --- a/net.cpp +++ b/net.cpp @@ -223,7 +223,7 @@ bool GetMyExternalIP(unsigned int& ipRet) -bool AddAddress(CAddrDB& addrdb, CAddress addr, bool fCurrentlyOnline) +bool AddAddress(CAddress addr, bool fCurrentlyOnline) { if (!addr.IsRoutable()) return false; @@ -239,7 +239,7 @@ bool AddAddress(CAddrDB& addrdb, CAddress addr, bool fCurrentlyOnline) // New address printf("AddAddress(%s)\n", addr.ToStringLog().c_str()); mapAddresses.insert(make_pair(addr.GetKey(), addr)); - addrdb.WriteAddress(addr); + CAddrDB().WriteAddress(addr); return true; } else @@ -260,7 +260,7 @@ bool AddAddress(CAddrDB& addrdb, CAddress addr, bool fCurrentlyOnline) fUpdated = true; } if (fUpdated) - addrdb.WriteAddress(addrFound); + CAddrDB().WriteAddress(addrFound); } } return false; @@ -881,11 +881,11 @@ void ThreadOpenConnections2(void* parg) vnThreadsRunning[1]--; Sleep(500); const int nMaxConnections = 15; - while (vNodes.size() >= nMaxConnections || vNodes.size() >= mapAddresses.size()) + while (vNodes.size() >= nMaxConnections) { + Sleep(2000); if (fShutdown) return; - Sleep(2000); } vnThreadsRunning[1]++; if (fShutdown) diff --git a/net.h b/net.h index 90af3b4b10..ba4607a558 100644 --- a/net.h +++ b/net.h @@ -23,7 +23,7 @@ enum bool ConnectSocket(const CAddress& addrConnect, SOCKET& hSocketRet); bool GetMyExternalIP(unsigned int& ipRet); -bool AddAddress(CAddrDB& addrdb, CAddress addr, bool fCurrentlyOnline=true); +bool AddAddress(CAddress addr, bool fCurrentlyOnline=true); void AddressCurrentlyConnected(const CAddress& addr); CNode* FindNode(unsigned int ip); CNode* ConnectNode(CAddress addrConnect, int64 nTimeout=0); @@ -627,7 +627,7 @@ public: // We're using mapAskFor as a priority queue, // the key is the earliest time the request can be sent int64& nRequestTime = mapAlreadyAskedFor[inv]; - printf("askfor %s %"PRI64d"\n", inv.ToString().c_str(), nRequestTime); + printf("askfor %s %"PRI64d"\n", inv.ToString().c_str(), nRequestTime); // Make sure not to reuse time indexes to keep things in the same order int64 nNow = (GetTime() - 1) * 1000000; diff --git a/serialize.h b/serialize.h index ce4aff3cda..263a22677d 100644 --- a/serialize.h +++ b/serialize.h @@ -20,7 +20,7 @@ class CDataStream; class CAutoFile; static const int VERSION = 200; -static const char* pszSubVer = " rc2"; +static const char* pszSubVer = " test1"; @@ -194,28 +194,32 @@ uint64 ReadCompactSize(Stream& is) { unsigned char chSize; READDATA(is, chSize); + uint64 nSizeRet = 0; if (chSize < UCHAR_MAX-2) { - return chSize; + nSizeRet = chSize; } else if (chSize == UCHAR_MAX-2) { unsigned short nSize; READDATA(is, nSize); - return nSize; + nSizeRet = nSize; } else if (chSize == UCHAR_MAX-1) { unsigned int nSize; READDATA(is, nSize); - return nSize; + nSizeRet = nSize; } else { uint64 nSize; READDATA(is, nSize); - return nSize; + nSizeRet = nSize; } + if (nSizeRet > (uint64)INT_MAX) + throw std::ios_base::failure("ReadCompactSize() : size too large"); + return nSizeRet; } @@ -460,7 +464,7 @@ void Unserialize_impl(Stream& is, std::vector& v, int nType, int nVersion, unsigned int i = 0; while (i < nSize) { - unsigned int blk = min(nSize - i, 1 + 4999999 / sizeof(T)); + unsigned int blk = min(nSize - i, (unsigned int)(1 + 4999999 / sizeof(T))); v.resize(i + blk); is.read((char*)&v[i], blk * sizeof(T)); i += blk; diff --git a/ui.cpp b/ui.cpp index 67895c127b..994cc7e214 100644 --- a/ui.cpp +++ b/ui.cpp @@ -349,7 +349,7 @@ CMainFrame::CMainFrame(wxWindow* parent) : CMainFrameBase(parent) nDateWidth += 12; m_listCtrl->InsertColumn(0, "", wxLIST_FORMAT_LEFT, dResize * 0); m_listCtrl->InsertColumn(1, "", wxLIST_FORMAT_LEFT, dResize * 0); - m_listCtrl->InsertColumn(2, "Status", wxLIST_FORMAT_LEFT, dResize * 90); + m_listCtrl->InsertColumn(2, "Status", wxLIST_FORMAT_LEFT, dResize * 110); m_listCtrl->InsertColumn(3, "Date", wxLIST_FORMAT_LEFT, dResize * nDateWidth); m_listCtrl->InsertColumn(4, "Description", wxLIST_FORMAT_LEFT, dResize * 409 - nDateWidth); m_listCtrl->InsertColumn(5, "Debit", wxLIST_FORMAT_RIGHT, dResize * 79); @@ -579,7 +579,7 @@ string FormatTxStatus(const CWalletTx& wtx) else if (nDepth < 6) return strprintf("%d/unconfirmed", nDepth); else - return strprintf("%d blocks", nDepth); + return strprintf("%d confirmations", nDepth); } } @@ -3706,13 +3706,12 @@ bool CMyApp::OnInit2() if (mapArgs.count("-addnode")) { - CAddrDB addrdb; foreach(string strAddr, mapMultiArgs["-addnode"]) { CAddress addr(strAddr, NODE_NETWORK); addr.nTime = 0; // so it won't relay unless successfully connected if (addr.IsValid()) - AddAddress(addrdb, addr); + AddAddress(addr); } } @@ -3934,3 +3933,13 @@ void SetStartOnSystemStartup(bool fAutoStart) bool GetStartOnSystemStartup() { return false; } void SetStartOnSystemStartup(bool fAutoStart) { } #endif + + + + + + + + + + diff --git a/uibase.h b/uibase.h index e0c152185c..7620a24e53 100644 --- a/uibase.h +++ b/uibase.h @@ -158,7 +158,7 @@ class CMainFrameBase : public wxFrame wxListCtrl* m_listCtrlOrdersSent; wxListCtrl* m_listCtrlProductsSent; wxListCtrl* m_listCtrlOrdersReceived; - CMainFrameBase( wxWindow* parent, wxWindowID id = wxID_MAINFRAME, const wxString& title = wxT("Bitcoin"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 705,484 ), long style = wxDEFAULT_FRAME_STYLE|wxRESIZE_BORDER|wxTAB_TRAVERSAL ); + CMainFrameBase( wxWindow* parent, wxWindowID id = wxID_MAINFRAME, const wxString& title = wxT("Bitcoin"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 725,484 ), long style = wxDEFAULT_FRAME_STYLE|wxRESIZE_BORDER|wxTAB_TRAVERSAL ); ~CMainFrameBase(); }; diff --git a/uiproject.fbp b/uiproject.fbp index 58a99bddd8..34fde78148 100644 --- a/uiproject.fbp +++ b/uiproject.fbp @@ -32,7 +32,7 @@ CMainFrameBase - 705,484 + 725,484 wxDEFAULT_FRAME_STYLE|wxRESIZE_BORDER Bitcoin @@ -1737,7 +1737,7 @@ - + bSizer55 wxVERTICAL diff --git a/util.cpp b/util.cpp index f5f2797fec..4292246762 100644 --- a/util.cpp +++ b/util.cpp @@ -8,8 +8,8 @@ map mapArgs; map > mapMultiArgs; bool fDebug = false; -bool fPrintToDebugger = false; bool fPrintToConsole = false; +bool fPrintToDebugger = false; char pszSetDataDir[MAX_PATH] = ""; bool fShutdown = false; @@ -75,6 +75,8 @@ void RandAddSeed() void RandAddSeedPerfmon() { + RandAddSeed(); + // This can take up to 2 seconds, so only do it every 10 minutes static int64 nLastPerfmon; if (GetTime() < nLastPerfmon + 10 * 60) @@ -129,6 +131,79 @@ uint64 GetRand(uint64 nMax) +inline int OutputDebugStringF(const char* pszFormat, ...) +{ + int ret = 0; + if (fPrintToConsole || wxTheApp == NULL) + { + // print to console + va_list arg_ptr; + va_start(arg_ptr, pszFormat); + ret = vprintf(pszFormat, arg_ptr); + va_end(arg_ptr); + } + else + { + // print to debug.log + char pszFile[MAX_PATH+100]; + GetDataDir(pszFile); + strlcat(pszFile, "/debug.log", sizeof(pszFile)); + FILE* fileout = fopen(pszFile, "a"); + if (fileout) + { + //// Debug print useful for profiling + //fprintf(fileout, " %"PRI64d" ", wxGetLocalTimeMillis().GetValue()); + va_list arg_ptr; + va_start(arg_ptr, pszFormat); + ret = vfprintf(fileout, pszFormat, arg_ptr); + va_end(arg_ptr); + fclose(fileout); + } + } + +#ifdef __WXMSW__ + if (fPrintToDebugger) + { + // accumulate a line at a time + static CCriticalSection cs_OutputDebugStringF; + CRITICAL_BLOCK(cs_OutputDebugStringF) + { + static char pszBuffer[50000]; + static char* pend; + if (pend == NULL) + pend = pszBuffer; + va_list arg_ptr; + va_start(arg_ptr, pszFormat); + int limit = END(pszBuffer) - pend - 2; + int ret = _vsnprintf(pend, limit, pszFormat, arg_ptr); + va_end(arg_ptr); + if (ret < 0 || ret >= limit) + { + pend = END(pszBuffer) - 2; + *pend++ = '\n'; + } + else + pend += ret; + *pend = '\0'; + char* p1 = pszBuffer; + char* p2; + while (p2 = strchr(p1, '\n')) + { + p2++; + char c = *p2; + *p2 = '\0'; + OutputDebugString(p1); + *p2 = c; + p1 = p2; + } + if (p1 != pszBuffer) + memmove(pszBuffer, p1, pend - p1 + 1); + pend -= (p1 - pszBuffer); + } + } +#endif + return ret; +} // Safer snprintf diff --git a/util.h b/util.h index b9c3658f76..d20648bcd3 100644 --- a/util.h +++ b/util.h @@ -112,13 +112,14 @@ inline int myclosesocket(SOCKET& hSocket) extern map mapArgs; extern map > mapMultiArgs; extern bool fDebug; -extern bool fPrintToDebugger; extern bool fPrintToConsole; +extern bool fPrintToDebugger; extern char pszSetDataDir[MAX_PATH]; extern bool fShutdown; void RandAddSeed(); void RandAddSeedPerfmon(); +int OutputDebugStringF(const char* pszFormat, ...); int my_snprintf(char* buffer, size_t limit, const char* format, ...); string strprintf(const char* format, ...); bool error(const char* format, ...); @@ -219,92 +220,6 @@ public: -inline int OutputDebugStringF(const char* pszFormat, ...) -{ - int ret = 0; -#ifdef __WXDEBUG__ - if (!fPrintToConsole) - { - // print to debug.log - char pszFile[MAX_PATH+100]; - GetDataDir(pszFile); - strlcat(pszFile, "/debug.log", sizeof(pszFile)); - FILE* fileout = fopen(pszFile, "a"); - if (fileout) - { - //// Debug print useful for profiling - //fprintf(fileout, " %"PRI64d" ", wxGetLocalTimeMillis().GetValue()); - va_list arg_ptr; - va_start(arg_ptr, pszFormat); - ret = vfprintf(fileout, pszFormat, arg_ptr); - va_end(arg_ptr); - fclose(fileout); - } - } - -#ifdef __WXMSW__ - if (fPrintToDebugger) - { - // accumulate a line at a time - static CCriticalSection cs_OutputDebugStringF; - CRITICAL_BLOCK(cs_OutputDebugStringF) - { - static char pszBuffer[50000]; - static char* pend; - if (pend == NULL) - pend = pszBuffer; - va_list arg_ptr; - va_start(arg_ptr, pszFormat); - int limit = END(pszBuffer) - pend - 2; - int ret = _vsnprintf(pend, limit, pszFormat, arg_ptr); - va_end(arg_ptr); - if (ret < 0 || ret >= limit) - { - pend = END(pszBuffer) - 2; - *pend++ = '\n'; - } - else - pend += ret; - *pend = '\0'; - char* p1 = pszBuffer; - char* p2; - while (p2 = strchr(p1, '\n')) - { - p2++; - char c = *p2; - *p2 = '\0'; - OutputDebugString(p1); - *p2 = c; - p1 = p2; - } - if (p1 != pszBuffer) - memmove(pszBuffer, p1, pend - p1 + 1); - pend -= (p1 - pszBuffer); - } - } -#endif -#endif - - if (fPrintToConsole) - { - // print to console - va_list arg_ptr; - va_start(arg_ptr, pszFormat); - ret = vprintf(pszFormat, arg_ptr); - va_end(arg_ptr); - } - return ret; -} - - - - - - - - - - inline string i64tostr(int64 n) { return strprintf("%"PRI64d, n); @@ -415,11 +330,19 @@ inline string DateTimeStrFormat(const char* pszFormat, int64 nTime) + + + + + + + inline void heapchk() { #ifdef __WXMSW__ - if (_heapchk() != _HEAPOK) - DebugBreak(); + /// for debugging + //if (_heapchk() != _HEAPOK) + // DebugBreak(); #endif } -- cgit v1.2.3 From 9e56521b4b79a90cfae63c658ed2ecb67acebfca Mon Sep 17 00:00:00 2001 From: s_nakamoto Date: Thu, 28 Jan 2010 21:49:20 +0000 Subject: now compiles on 64-bit Ubuntu Karmic with wxWidgets-2.9.0, fixes for wxWidgets-2.9.0, added superfluous GetEventHandler()'s, there's still a bug on wx2.9.0 that the status number is mashed up for some reason otherwise seems to run fine --- build-unix.txt | 25 +++++++++------ makefile.unix | 89 ----------------------------------------------------- makefile.unix.wx2.8 | 89 +++++++++++++++++++++++++++++++++++++++++++++++++++++ makefile.unix.wx2.9 | 89 +++++++++++++++++++++++++++++++++++++++++++++++++++++ ui.cpp | 54 ++++++++++++++++++-------------- uibase.cpp | 6 +++- uibase.h | 6 +++- uiproject.fbp | 14 ++++----- 8 files changed, 242 insertions(+), 130 deletions(-) delete mode 100644 makefile.unix create mode 100644 makefile.unix.wx2.8 create mode 100644 makefile.unix.wx2.9 diff --git a/build-unix.txt b/build-unix.txt index 7c650589a4..5467bbea17 100644 --- a/build-unix.txt +++ b/build-unix.txt @@ -1,6 +1,6 @@ Bitcoin v0.2.0 BETA -Copyright (c) 2009 Satoshi Nakamoto +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. This product includes software developed by the OpenSSL Project for use in @@ -13,15 +13,22 @@ UNIX BUILD NOTES Dependencies ------------ -apt-get install build-essential -apt-get install libgtk2.0-dev -apt-get install libssl-dev -apt-get install libdb4.7-dev -apt-get install libdb4.7++-dev -apt-get install libboost-dev +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 libboost-dev + +There is currently no libwxgtk2.8-ansi-dev debian package for Karmic. +libwxgtk2.8-dev is the "unicode" build, but for wxWidgets 2.8 "unicode" +means wchar, not UTF-8. wchar wxString doesn't convert to std::string. + +In wxWidgets 2.9, unicode is UTF-8 and that's the only version. You need to download wxWidgets from http://www.wxwidgets.org/downloads/ -and build it yourself. +and build it yourself. See the build instructions and configure parameters +below. Licenses of statically linked libraries: wxWidgets LGPL 2.1 with very liberal exceptions @@ -48,7 +55,7 @@ symbols, which reduces the executable size by about 90%. wxWidgets --------- -cd /usr/local/wxWidgets-2.8.9 +cd /usr/local/wxWidgets-2.8.9 or 2.9.0 mkdir buildgtk cd buildgtk ../configure --with-gtk --enable-debug --disable-shared --enable-monolithic diff --git a/makefile.unix b/makefile.unix deleted file mode 100644 index b9826d6ccb..0000000000 --- a/makefile.unix +++ /dev/null @@ -1,89 +0,0 @@ -# Copyright (c) 2009 Satoshi Nakamoto -# Distributed under the MIT/X11 software license, see the accompanying -# file license.txt or http://www.opensource.org/licenses/mit-license.php. - - -ifneq "$(BUILD)" "debug" -ifneq "$(BUILD)" "release" -BUILD=debug -endif -endif -ifeq "$(BUILD)" "debug" -D=d -DEBUGFLAGS=-g -D__WXDEBUG__ -endif - - - -INCLUDEPATHS= \ - -I"/usr/include" \ - -I"/usr/local/include/wx-2.8" \ - -I"/usr/local/lib/wx/include/gtk2-ansi-debug-static-2.8" - -LIBPATHS= \ - -L"/usr/lib" \ - -L"/usr/local/lib" - -LIBS= \ - -Wl,-Bstatic \ - -l boost_system -l boost_filesystem \ - -l db_cxx \ - -l wx_gtk2$(D)-2.8 \ - -Wl,-Bdynamic \ - -l crypto \ - -l gtk-x11-2.0 -l gthread-2.0 -l SM - -WXDEFS=-D__WXGTK__ -DNOPCH -CFLAGS=-O0 -Wno-invalid-offsetof -Wformat $(DEBUGFLAGS) $(WXDEFS) $(INCLUDEPATHS) -HEADERS=headers.h util.h main.h serialize.h uint256.h key.h bignum.h script.h db.h base58.h - - - -all: bitcoin - - -headers.h.gch: headers.h $(HEADERS) net.h irc.h market.h uibase.h ui.h - g++ -c $(CFLAGS) -o $@ $< - -obj/util.o: util.cpp $(HEADERS) - g++ -c $(CFLAGS) -o $@ $< - -obj/script.o: script.cpp $(HEADERS) - g++ -c $(CFLAGS) -o $@ $< - -obj/db.o: db.cpp $(HEADERS) market.h - g++ -c $(CFLAGS) -o $@ $< - -obj/net.o: net.cpp $(HEADERS) net.h - g++ -c $(CFLAGS) -o $@ $< - -obj/main.o: main.cpp $(HEADERS) net.h market.h sha.h - g++ -c $(CFLAGS) -o $@ $< - -obj/market.o: market.cpp $(HEADERS) market.h - g++ -c $(CFLAGS) -o $@ $< - -obj/ui.o: ui.cpp $(HEADERS) net.h uibase.h ui.h market.h - g++ -c $(CFLAGS) -o $@ $< - -obj/uibase.o: uibase.cpp uibase.h - g++ -c $(CFLAGS) -o $@ $< - -obj/sha.o: sha.cpp sha.h - g++ -c $(CFLAGS) -O3 -o $@ $< - -obj/irc.o: irc.cpp $(HEADERS) - g++ -c $(CFLAGS) -o $@ $< - - - - -OBJS=obj/util.o obj/script.o obj/db.o obj/net.o obj/main.o obj/market.o \ - obj/ui.o obj/uibase.o obj/sha.o obj/irc.o - -bitcoin: headers.h.gch $(OBJS) - g++ $(CFLAGS) -o $@ $(LIBPATHS) $(OBJS) $(LIBS) - -clean: - -rm obj/* - -rm headers.h.gch diff --git a/makefile.unix.wx2.8 b/makefile.unix.wx2.8 new file mode 100644 index 0000000000..b9826d6ccb --- /dev/null +++ b/makefile.unix.wx2.8 @@ -0,0 +1,89 @@ +# Copyright (c) 2009 Satoshi Nakamoto +# Distributed under the MIT/X11 software license, see the accompanying +# file license.txt or http://www.opensource.org/licenses/mit-license.php. + + +ifneq "$(BUILD)" "debug" +ifneq "$(BUILD)" "release" +BUILD=debug +endif +endif +ifeq "$(BUILD)" "debug" +D=d +DEBUGFLAGS=-g -D__WXDEBUG__ +endif + + + +INCLUDEPATHS= \ + -I"/usr/include" \ + -I"/usr/local/include/wx-2.8" \ + -I"/usr/local/lib/wx/include/gtk2-ansi-debug-static-2.8" + +LIBPATHS= \ + -L"/usr/lib" \ + -L"/usr/local/lib" + +LIBS= \ + -Wl,-Bstatic \ + -l boost_system -l boost_filesystem \ + -l db_cxx \ + -l wx_gtk2$(D)-2.8 \ + -Wl,-Bdynamic \ + -l crypto \ + -l gtk-x11-2.0 -l gthread-2.0 -l SM + +WXDEFS=-D__WXGTK__ -DNOPCH +CFLAGS=-O0 -Wno-invalid-offsetof -Wformat $(DEBUGFLAGS) $(WXDEFS) $(INCLUDEPATHS) +HEADERS=headers.h util.h main.h serialize.h uint256.h key.h bignum.h script.h db.h base58.h + + + +all: bitcoin + + +headers.h.gch: headers.h $(HEADERS) net.h irc.h market.h uibase.h ui.h + g++ -c $(CFLAGS) -o $@ $< + +obj/util.o: util.cpp $(HEADERS) + g++ -c $(CFLAGS) -o $@ $< + +obj/script.o: script.cpp $(HEADERS) + g++ -c $(CFLAGS) -o $@ $< + +obj/db.o: db.cpp $(HEADERS) market.h + g++ -c $(CFLAGS) -o $@ $< + +obj/net.o: net.cpp $(HEADERS) net.h + g++ -c $(CFLAGS) -o $@ $< + +obj/main.o: main.cpp $(HEADERS) net.h market.h sha.h + g++ -c $(CFLAGS) -o $@ $< + +obj/market.o: market.cpp $(HEADERS) market.h + g++ -c $(CFLAGS) -o $@ $< + +obj/ui.o: ui.cpp $(HEADERS) net.h uibase.h ui.h market.h + g++ -c $(CFLAGS) -o $@ $< + +obj/uibase.o: uibase.cpp uibase.h + g++ -c $(CFLAGS) -o $@ $< + +obj/sha.o: sha.cpp sha.h + g++ -c $(CFLAGS) -O3 -o $@ $< + +obj/irc.o: irc.cpp $(HEADERS) + g++ -c $(CFLAGS) -o $@ $< + + + + +OBJS=obj/util.o obj/script.o obj/db.o obj/net.o obj/main.o obj/market.o \ + obj/ui.o obj/uibase.o obj/sha.o obj/irc.o + +bitcoin: headers.h.gch $(OBJS) + g++ $(CFLAGS) -o $@ $(LIBPATHS) $(OBJS) $(LIBS) + +clean: + -rm obj/* + -rm headers.h.gch diff --git a/makefile.unix.wx2.9 b/makefile.unix.wx2.9 new file mode 100644 index 0000000000..81dcbd70e9 --- /dev/null +++ b/makefile.unix.wx2.9 @@ -0,0 +1,89 @@ +# Copyright (c) 2009 Satoshi Nakamoto +# Distributed under the MIT/X11 software license, see the accompanying +# file license.txt or http://www.opensource.org/licenses/mit-license.php. + + +ifneq "$(BUILD)" "debug" +ifneq "$(BUILD)" "release" +BUILD=debug +endif +endif +ifeq "$(BUILD)" "debug" +D=d +DEBUGFLAGS=-g -D__WXDEBUG__ +endif + + + +INCLUDEPATHS= \ + -I"/usr/include" \ + -I"/usr/local/include/wx-2.9" \ + -I"/usr/local/lib/wx/include/gtk2-unicode-debug-static-2.9" + +LIBPATHS= \ + -L"/usr/lib" \ + -L"/usr/local/lib" + +LIBS= \ + -Wl,-Bstatic \ + -l boost_system-mt -l boost_filesystem-mt \ + -l db_cxx \ + -l wx_gtk2u$(D)-2.9 \ + -Wl,-Bdynamic \ + -l crypto \ + -l gtk-x11-2.0 -l gthread-2.0 -l SM + +WXDEFS=-D__WXGTK__ -DNOPCH +CFLAGS=-O0 -Wno-invalid-offsetof -Wformat $(DEBUGFLAGS) $(WXDEFS) $(INCLUDEPATHS) +HEADERS=headers.h util.h main.h serialize.h uint256.h key.h bignum.h script.h db.h base58.h + + + +all: bitcoin + + +headers.h.gch: headers.h $(HEADERS) net.h irc.h market.h uibase.h ui.h + g++ -c $(CFLAGS) -o $@ $< + +obj/util.o: util.cpp $(HEADERS) + g++ -c $(CFLAGS) -o $@ $< + +obj/script.o: script.cpp $(HEADERS) + g++ -c $(CFLAGS) -o $@ $< + +obj/db.o: db.cpp $(HEADERS) market.h + g++ -c $(CFLAGS) -o $@ $< + +obj/net.o: net.cpp $(HEADERS) net.h + g++ -c $(CFLAGS) -o $@ $< + +obj/main.o: main.cpp $(HEADERS) net.h market.h sha.h + g++ -c $(CFLAGS) -o $@ $< + +obj/market.o: market.cpp $(HEADERS) market.h + g++ -c $(CFLAGS) -o $@ $< + +obj/ui.o: ui.cpp $(HEADERS) net.h uibase.h ui.h market.h + g++ -c $(CFLAGS) -o $@ $< + +obj/uibase.o: uibase.cpp uibase.h + g++ -c $(CFLAGS) -o $@ $< + +obj/sha.o: sha.cpp sha.h + g++ -c $(CFLAGS) -O3 -o $@ $< + +obj/irc.o: irc.cpp $(HEADERS) + g++ -c $(CFLAGS) -o $@ $< + + + + +OBJS=obj/util.o obj/script.o obj/db.o obj/net.o obj/main.o obj/market.o \ + obj/ui.o obj/uibase.o obj/sha.o obj/irc.o + +bitcoin: headers.h.gch $(OBJS) + g++ $(CFLAGS) -o $@ $(LIBPATHS) $(OBJS) $(LIBS) + +clean: + -rm obj/* + -rm headers.h.gch diff --git a/ui.cpp b/ui.cpp index 994cc7e214..d1163aa5bf 100644 --- a/ui.cpp +++ b/ui.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2009 Satoshi Nakamoto +// 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. @@ -252,18 +252,23 @@ bool IsCallbackAvailable(void* p) template void AddPendingCustomEvent(wxEvtHandler* pevthandler, int nEventID, const T pbeginIn, const T pendIn) { - if (!pevthandler) - return; - - const char* pbegin = (pendIn != pbeginIn) ? &pbeginIn[0] : NULL; - const char* pend = pbegin + (pendIn - pbeginIn) * sizeof(pbeginIn[0]); - wxCommandEvent event(nEventID); - wxString strData(wxChar(0), (pend - pbegin) / sizeof(wxChar) + 1); - memcpy(&strData[0], pbegin, pend - pbegin); - event.SetString(strData); - event.SetInt(pend - pbegin); - - pevthandler->AddPendingEvent(event); + // Need to rewrite with something like UIThreadCall + // I'm tired of maintaining this hack that's only called by unfinished unused code, + // but I'm not willing to delete it because it serves as documentation of what the + // unfinished code was trying to do. + assert(("Unimplemented", 0)); + //if (!pevthandler) + // return; + // + //const char* pbegin = (pendIn != pbeginIn) ? &pbeginIn[0] : NULL; + //const char* pend = pbegin + (pendIn - pbeginIn) * sizeof(pbeginIn[0]); + //wxCommandEvent event(nEventID); + //wxString strData(wxChar(0), (pend - pbegin) / sizeof(wxChar) + 1); + //memcpy(&strData[0], pbegin, pend - pbegin); + //event.SetString(strData); + //event.SetInt(pend - pbegin); + // + //pevthandler->AddPendingEvent(event); } template @@ -335,9 +340,8 @@ CMainFrame::CMainFrame(wxWindow* parent) : CMainFrameBase(parent) m_toolBar->AddTool(wxID_BUTTONRECEIVE, "Address Book", wxBitmap(addressbook20_xpm), wxNullBitmap, wxITEM_NORMAL, wxEmptyString, wxEmptyString); m_toolBar->Realize(); // resize to fit ubuntu's huge default font - dResize = 1.19; - SetSize(dResize * GetSize().GetWidth(), 1.1 * GetSize().GetHeight()); dResize = 1.20; + SetSize(dResize * GetSize().GetWidth(), 1.1 * GetSize().GetHeight()); #endif m_staticTextBalance->SetLabel(FormatMoney(GetBalance()) + " "); m_listCtrl->SetFocus(); @@ -458,6 +462,8 @@ void CMainFrame::OnIconize(wxIconizeEvent& event) { // 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; #ifndef __WXMSW__ @@ -985,7 +991,7 @@ void ThreadDelayedRepaint(void* parg) printf("DelayedRepaint\n"); wxPaintEvent event; pframeMain->fRefresh = true; - pframeMain->AddPendingEvent(event); + pframeMain->GetEventHandler()->AddPendingEvent(event); } } Sleep(nRepaintInterval); @@ -1010,7 +1016,7 @@ void MainFrameRepaint() printf("MainFrameRepaint\n"); wxPaintEvent event; pframeMain->fRefresh = true; - pframeMain->AddPendingEvent(event); + pframeMain->GetEventHandler()->AddPendingEvent(event); } } @@ -1695,12 +1701,14 @@ CAboutDialog::CAboutDialog(wxWindow* parent) : CAboutDialogBase(parent) // Workaround until upgrade to wxWidgets supporting UTF-8 wxString str = m_staticTextMain->GetLabel(); +#if !wxUSE_UNICODE if (str.Find('Â') != wxNOT_FOUND) str.Remove(str.Find('Â'), 1); - m_staticTextMain->SetLabel(str); +#endif #ifndef __WXMSW__ SetSize(510, 380); #endif + m_staticTextMain->SetLabel(str); } void CAboutDialog::OnButtonOK(wxCommandEvent& event) @@ -1732,7 +1740,7 @@ CSendDialog::CSendDialog(wxWindow* parent, const wxString& strAddress) : CSendDi if (fontTmp.GetPointSize() > 9); fontTmp.SetPointSize(9); m_staticTextInstructions->SetFont(fontTmp); - SetSize(725, wxDefaultCoord); + SetSize(725, 380); #endif // Set Icon @@ -2000,7 +2008,7 @@ void CSendingDialog::Repaint() { Refresh(); wxPaintEvent event; - AddPendingEvent(event); + GetEventHandler()->AddPendingEvent(event); } bool CSendingDialog::Status() @@ -3379,14 +3387,14 @@ void CMyTaskBarIcon::OnMenuOptions(wxCommandEvent& event) { // Since it's modal, get the main window to do it wxCommandEvent event2(wxEVT_COMMAND_MENU_SELECTED, wxID_MENUOPTIONSOPTIONS); - pframeMain->AddPendingEvent(event2); + pframeMain->GetEventHandler()->AddPendingEvent(event2); } void CMyTaskBarIcon::Restore() { pframeMain->Show(); wxIconizeEvent event(0, false); - pframeMain->AddPendingEvent(event); + pframeMain->GetEventHandler()->AddPendingEvent(event); pframeMain->Iconize(false); pframeMain->Raise(); } @@ -3548,7 +3556,7 @@ bool CMyApp::OnInit2() if (!fDebug && !pszSetDataDir[0]) 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 %d%s, OS version %s\n", VERSION, pszSubVer, wxGetOsDescription().mb_str()); + printf("Bitcoin version %d%s, OS version %s\n", VERSION, pszSubVer, ((string)wxGetOsDescription()).c_str()); if (mapArgs.count("-loadblockindextest")) { diff --git a/uibase.cpp b/uibase.cpp index f05f1095fb..fb4f1ed08c 100644 --- a/uibase.cpp +++ b/uibase.cpp @@ -1,3 +1,7 @@ +// 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. + /////////////////////////////////////////////////////////////////////////// // C++ code generated with wxFormBuilder (version Apr 16 2008) // http://www.wxformbuilder.org/ @@ -639,7 +643,7 @@ CSendDialogBase::CSendDialogBase( wxWindow* parent, wxWindowID id, const wxStrin bSizer21->Add( 0, 5, 0, wxEXPAND, 5 ); wxFlexGridSizer* fgSizer1; - fgSizer1 = new wxFlexGridSizer( 3, 2, 0, 0 ); + fgSizer1 = new wxFlexGridSizer( 0, 2, 0, 0 ); fgSizer1->AddGrowableCol( 1 ); fgSizer1->SetFlexibleDirection( wxBOTH ); fgSizer1->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED ); diff --git a/uibase.h b/uibase.h index 7620a24e53..97bb1bdc3c 100644 --- a/uibase.h +++ b/uibase.h @@ -1,3 +1,7 @@ +// 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. + /////////////////////////////////////////////////////////////////////////// // C++ code generated with wxFormBuilder (version Apr 16 2008) // http://www.wxformbuilder.org/ @@ -158,7 +162,7 @@ class CMainFrameBase : public wxFrame wxListCtrl* m_listCtrlOrdersSent; wxListCtrl* m_listCtrlProductsSent; wxListCtrl* m_listCtrlOrdersReceived; - CMainFrameBase( wxWindow* parent, wxWindowID id = wxID_MAINFRAME, const wxString& title = wxT("Bitcoin"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 725,484 ), long style = wxDEFAULT_FRAME_STYLE|wxRESIZE_BORDER|wxTAB_TRAVERSAL ); + CMainFrameBase( wxWindow* parent, wxWindowID id = wxID_MAINFRAME, const wxString& title = wxT("Bitcoin"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 727,484 ), long style = wxDEFAULT_FRAME_STYLE|wxRESIZE_BORDER|wxTAB_TRAVERSAL ); ~CMainFrameBase(); }; diff --git a/uiproject.fbp b/uiproject.fbp index 34fde78148..3c489ae633 100644 --- a/uiproject.fbp +++ b/uiproject.fbp @@ -32,7 +32,7 @@ CMainFrameBase - 725,484 + 727,484 wxDEFAULT_FRAME_STYLE|wxRESIZE_BORDER Bitcoin @@ -3509,7 +3509,7 @@ - + @@ -3580,7 +3580,7 @@ 5 wxEXPAND|wxLEFT 0 - + 2 wxBOTH 1 @@ -3590,7 +3590,7 @@ fgSizer1 wxFLEX_GROWMODE_SPECIFIED none - 3 + 0 0 5 @@ -4189,7 +4189,7 @@ 5 wxEXPAND 0 - + bSizer672 wxHORIZONTAL @@ -4317,7 +4317,7 @@ 5 wxEXPAND 1 - + bSizer67 wxHORIZONTAL @@ -4445,7 +4445,7 @@ 5 wxEXPAND 0 - + bSizer23 wxHORIZONTAL -- cgit v1.2.3 From 8be979d9aef606f2a196a2addcf80473d571185b Mon Sep 17 00:00:00 2001 From: s_nakamoto Date: Thu, 28 Jan 2010 21:49:20 +0000 Subject: now compiles on 64-bit Ubuntu Karmic with wxWidgets-2.9.0, fixes for wxWidgets-2.9.0, added superfluous GetEventHandler()'s, there's still a bug on wx2.9.0 that the status number is mashed up for some reason otherwise seems to run fine git-svn-id: https://bitcoin.svn.sourceforge.net/svnroot/bitcoin/trunk@54 1a98c847-1fd6-4fd8-948a-caf3550aa51b --- build-unix.txt | 25 +++++++++------ makefile.unix | 89 ----------------------------------------------------- makefile.unix.wx2.8 | 89 +++++++++++++++++++++++++++++++++++++++++++++++++++++ makefile.unix.wx2.9 | 89 +++++++++++++++++++++++++++++++++++++++++++++++++++++ ui.cpp | 54 ++++++++++++++++++-------------- uibase.cpp | 6 +++- uibase.h | 6 +++- uiproject.fbp | 14 ++++----- 8 files changed, 242 insertions(+), 130 deletions(-) delete mode 100644 makefile.unix create mode 100644 makefile.unix.wx2.8 create mode 100644 makefile.unix.wx2.9 diff --git a/build-unix.txt b/build-unix.txt index 7c650589a4..5467bbea17 100644 --- a/build-unix.txt +++ b/build-unix.txt @@ -1,6 +1,6 @@ Bitcoin v0.2.0 BETA -Copyright (c) 2009 Satoshi Nakamoto +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. This product includes software developed by the OpenSSL Project for use in @@ -13,15 +13,22 @@ UNIX BUILD NOTES Dependencies ------------ -apt-get install build-essential -apt-get install libgtk2.0-dev -apt-get install libssl-dev -apt-get install libdb4.7-dev -apt-get install libdb4.7++-dev -apt-get install libboost-dev +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 libboost-dev + +There is currently no libwxgtk2.8-ansi-dev debian package for Karmic. +libwxgtk2.8-dev is the "unicode" build, but for wxWidgets 2.8 "unicode" +means wchar, not UTF-8. wchar wxString doesn't convert to std::string. + +In wxWidgets 2.9, unicode is UTF-8 and that's the only version. You need to download wxWidgets from http://www.wxwidgets.org/downloads/ -and build it yourself. +and build it yourself. See the build instructions and configure parameters +below. Licenses of statically linked libraries: wxWidgets LGPL 2.1 with very liberal exceptions @@ -48,7 +55,7 @@ symbols, which reduces the executable size by about 90%. wxWidgets --------- -cd /usr/local/wxWidgets-2.8.9 +cd /usr/local/wxWidgets-2.8.9 or 2.9.0 mkdir buildgtk cd buildgtk ../configure --with-gtk --enable-debug --disable-shared --enable-monolithic diff --git a/makefile.unix b/makefile.unix deleted file mode 100644 index b9826d6ccb..0000000000 --- a/makefile.unix +++ /dev/null @@ -1,89 +0,0 @@ -# Copyright (c) 2009 Satoshi Nakamoto -# Distributed under the MIT/X11 software license, see the accompanying -# file license.txt or http://www.opensource.org/licenses/mit-license.php. - - -ifneq "$(BUILD)" "debug" -ifneq "$(BUILD)" "release" -BUILD=debug -endif -endif -ifeq "$(BUILD)" "debug" -D=d -DEBUGFLAGS=-g -D__WXDEBUG__ -endif - - - -INCLUDEPATHS= \ - -I"/usr/include" \ - -I"/usr/local/include/wx-2.8" \ - -I"/usr/local/lib/wx/include/gtk2-ansi-debug-static-2.8" - -LIBPATHS= \ - -L"/usr/lib" \ - -L"/usr/local/lib" - -LIBS= \ - -Wl,-Bstatic \ - -l boost_system -l boost_filesystem \ - -l db_cxx \ - -l wx_gtk2$(D)-2.8 \ - -Wl,-Bdynamic \ - -l crypto \ - -l gtk-x11-2.0 -l gthread-2.0 -l SM - -WXDEFS=-D__WXGTK__ -DNOPCH -CFLAGS=-O0 -Wno-invalid-offsetof -Wformat $(DEBUGFLAGS) $(WXDEFS) $(INCLUDEPATHS) -HEADERS=headers.h util.h main.h serialize.h uint256.h key.h bignum.h script.h db.h base58.h - - - -all: bitcoin - - -headers.h.gch: headers.h $(HEADERS) net.h irc.h market.h uibase.h ui.h - g++ -c $(CFLAGS) -o $@ $< - -obj/util.o: util.cpp $(HEADERS) - g++ -c $(CFLAGS) -o $@ $< - -obj/script.o: script.cpp $(HEADERS) - g++ -c $(CFLAGS) -o $@ $< - -obj/db.o: db.cpp $(HEADERS) market.h - g++ -c $(CFLAGS) -o $@ $< - -obj/net.o: net.cpp $(HEADERS) net.h - g++ -c $(CFLAGS) -o $@ $< - -obj/main.o: main.cpp $(HEADERS) net.h market.h sha.h - g++ -c $(CFLAGS) -o $@ $< - -obj/market.o: market.cpp $(HEADERS) market.h - g++ -c $(CFLAGS) -o $@ $< - -obj/ui.o: ui.cpp $(HEADERS) net.h uibase.h ui.h market.h - g++ -c $(CFLAGS) -o $@ $< - -obj/uibase.o: uibase.cpp uibase.h - g++ -c $(CFLAGS) -o $@ $< - -obj/sha.o: sha.cpp sha.h - g++ -c $(CFLAGS) -O3 -o $@ $< - -obj/irc.o: irc.cpp $(HEADERS) - g++ -c $(CFLAGS) -o $@ $< - - - - -OBJS=obj/util.o obj/script.o obj/db.o obj/net.o obj/main.o obj/market.o \ - obj/ui.o obj/uibase.o obj/sha.o obj/irc.o - -bitcoin: headers.h.gch $(OBJS) - g++ $(CFLAGS) -o $@ $(LIBPATHS) $(OBJS) $(LIBS) - -clean: - -rm obj/* - -rm headers.h.gch diff --git a/makefile.unix.wx2.8 b/makefile.unix.wx2.8 new file mode 100644 index 0000000000..b9826d6ccb --- /dev/null +++ b/makefile.unix.wx2.8 @@ -0,0 +1,89 @@ +# Copyright (c) 2009 Satoshi Nakamoto +# Distributed under the MIT/X11 software license, see the accompanying +# file license.txt or http://www.opensource.org/licenses/mit-license.php. + + +ifneq "$(BUILD)" "debug" +ifneq "$(BUILD)" "release" +BUILD=debug +endif +endif +ifeq "$(BUILD)" "debug" +D=d +DEBUGFLAGS=-g -D__WXDEBUG__ +endif + + + +INCLUDEPATHS= \ + -I"/usr/include" \ + -I"/usr/local/include/wx-2.8" \ + -I"/usr/local/lib/wx/include/gtk2-ansi-debug-static-2.8" + +LIBPATHS= \ + -L"/usr/lib" \ + -L"/usr/local/lib" + +LIBS= \ + -Wl,-Bstatic \ + -l boost_system -l boost_filesystem \ + -l db_cxx \ + -l wx_gtk2$(D)-2.8 \ + -Wl,-Bdynamic \ + -l crypto \ + -l gtk-x11-2.0 -l gthread-2.0 -l SM + +WXDEFS=-D__WXGTK__ -DNOPCH +CFLAGS=-O0 -Wno-invalid-offsetof -Wformat $(DEBUGFLAGS) $(WXDEFS) $(INCLUDEPATHS) +HEADERS=headers.h util.h main.h serialize.h uint256.h key.h bignum.h script.h db.h base58.h + + + +all: bitcoin + + +headers.h.gch: headers.h $(HEADERS) net.h irc.h market.h uibase.h ui.h + g++ -c $(CFLAGS) -o $@ $< + +obj/util.o: util.cpp $(HEADERS) + g++ -c $(CFLAGS) -o $@ $< + +obj/script.o: script.cpp $(HEADERS) + g++ -c $(CFLAGS) -o $@ $< + +obj/db.o: db.cpp $(HEADERS) market.h + g++ -c $(CFLAGS) -o $@ $< + +obj/net.o: net.cpp $(HEADERS) net.h + g++ -c $(CFLAGS) -o $@ $< + +obj/main.o: main.cpp $(HEADERS) net.h market.h sha.h + g++ -c $(CFLAGS) -o $@ $< + +obj/market.o: market.cpp $(HEADERS) market.h + g++ -c $(CFLAGS) -o $@ $< + +obj/ui.o: ui.cpp $(HEADERS) net.h uibase.h ui.h market.h + g++ -c $(CFLAGS) -o $@ $< + +obj/uibase.o: uibase.cpp uibase.h + g++ -c $(CFLAGS) -o $@ $< + +obj/sha.o: sha.cpp sha.h + g++ -c $(CFLAGS) -O3 -o $@ $< + +obj/irc.o: irc.cpp $(HEADERS) + g++ -c $(CFLAGS) -o $@ $< + + + + +OBJS=obj/util.o obj/script.o obj/db.o obj/net.o obj/main.o obj/market.o \ + obj/ui.o obj/uibase.o obj/sha.o obj/irc.o + +bitcoin: headers.h.gch $(OBJS) + g++ $(CFLAGS) -o $@ $(LIBPATHS) $(OBJS) $(LIBS) + +clean: + -rm obj/* + -rm headers.h.gch diff --git a/makefile.unix.wx2.9 b/makefile.unix.wx2.9 new file mode 100644 index 0000000000..81dcbd70e9 --- /dev/null +++ b/makefile.unix.wx2.9 @@ -0,0 +1,89 @@ +# Copyright (c) 2009 Satoshi Nakamoto +# Distributed under the MIT/X11 software license, see the accompanying +# file license.txt or http://www.opensource.org/licenses/mit-license.php. + + +ifneq "$(BUILD)" "debug" +ifneq "$(BUILD)" "release" +BUILD=debug +endif +endif +ifeq "$(BUILD)" "debug" +D=d +DEBUGFLAGS=-g -D__WXDEBUG__ +endif + + + +INCLUDEPATHS= \ + -I"/usr/include" \ + -I"/usr/local/include/wx-2.9" \ + -I"/usr/local/lib/wx/include/gtk2-unicode-debug-static-2.9" + +LIBPATHS= \ + -L"/usr/lib" \ + -L"/usr/local/lib" + +LIBS= \ + -Wl,-Bstatic \ + -l boost_system-mt -l boost_filesystem-mt \ + -l db_cxx \ + -l wx_gtk2u$(D)-2.9 \ + -Wl,-Bdynamic \ + -l crypto \ + -l gtk-x11-2.0 -l gthread-2.0 -l SM + +WXDEFS=-D__WXGTK__ -DNOPCH +CFLAGS=-O0 -Wno-invalid-offsetof -Wformat $(DEBUGFLAGS) $(WXDEFS) $(INCLUDEPATHS) +HEADERS=headers.h util.h main.h serialize.h uint256.h key.h bignum.h script.h db.h base58.h + + + +all: bitcoin + + +headers.h.gch: headers.h $(HEADERS) net.h irc.h market.h uibase.h ui.h + g++ -c $(CFLAGS) -o $@ $< + +obj/util.o: util.cpp $(HEADERS) + g++ -c $(CFLAGS) -o $@ $< + +obj/script.o: script.cpp $(HEADERS) + g++ -c $(CFLAGS) -o $@ $< + +obj/db.o: db.cpp $(HEADERS) market.h + g++ -c $(CFLAGS) -o $@ $< + +obj/net.o: net.cpp $(HEADERS) net.h + g++ -c $(CFLAGS) -o $@ $< + +obj/main.o: main.cpp $(HEADERS) net.h market.h sha.h + g++ -c $(CFLAGS) -o $@ $< + +obj/market.o: market.cpp $(HEADERS) market.h + g++ -c $(CFLAGS) -o $@ $< + +obj/ui.o: ui.cpp $(HEADERS) net.h uibase.h ui.h market.h + g++ -c $(CFLAGS) -o $@ $< + +obj/uibase.o: uibase.cpp uibase.h + g++ -c $(CFLAGS) -o $@ $< + +obj/sha.o: sha.cpp sha.h + g++ -c $(CFLAGS) -O3 -o $@ $< + +obj/irc.o: irc.cpp $(HEADERS) + g++ -c $(CFLAGS) -o $@ $< + + + + +OBJS=obj/util.o obj/script.o obj/db.o obj/net.o obj/main.o obj/market.o \ + obj/ui.o obj/uibase.o obj/sha.o obj/irc.o + +bitcoin: headers.h.gch $(OBJS) + g++ $(CFLAGS) -o $@ $(LIBPATHS) $(OBJS) $(LIBS) + +clean: + -rm obj/* + -rm headers.h.gch diff --git a/ui.cpp b/ui.cpp index 994cc7e214..d1163aa5bf 100644 --- a/ui.cpp +++ b/ui.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2009 Satoshi Nakamoto +// 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. @@ -252,18 +252,23 @@ bool IsCallbackAvailable(void* p) template void AddPendingCustomEvent(wxEvtHandler* pevthandler, int nEventID, const T pbeginIn, const T pendIn) { - if (!pevthandler) - return; - - const char* pbegin = (pendIn != pbeginIn) ? &pbeginIn[0] : NULL; - const char* pend = pbegin + (pendIn - pbeginIn) * sizeof(pbeginIn[0]); - wxCommandEvent event(nEventID); - wxString strData(wxChar(0), (pend - pbegin) / sizeof(wxChar) + 1); - memcpy(&strData[0], pbegin, pend - pbegin); - event.SetString(strData); - event.SetInt(pend - pbegin); - - pevthandler->AddPendingEvent(event); + // Need to rewrite with something like UIThreadCall + // I'm tired of maintaining this hack that's only called by unfinished unused code, + // but I'm not willing to delete it because it serves as documentation of what the + // unfinished code was trying to do. + assert(("Unimplemented", 0)); + //if (!pevthandler) + // return; + // + //const char* pbegin = (pendIn != pbeginIn) ? &pbeginIn[0] : NULL; + //const char* pend = pbegin + (pendIn - pbeginIn) * sizeof(pbeginIn[0]); + //wxCommandEvent event(nEventID); + //wxString strData(wxChar(0), (pend - pbegin) / sizeof(wxChar) + 1); + //memcpy(&strData[0], pbegin, pend - pbegin); + //event.SetString(strData); + //event.SetInt(pend - pbegin); + // + //pevthandler->AddPendingEvent(event); } template @@ -335,9 +340,8 @@ CMainFrame::CMainFrame(wxWindow* parent) : CMainFrameBase(parent) m_toolBar->AddTool(wxID_BUTTONRECEIVE, "Address Book", wxBitmap(addressbook20_xpm), wxNullBitmap, wxITEM_NORMAL, wxEmptyString, wxEmptyString); m_toolBar->Realize(); // resize to fit ubuntu's huge default font - dResize = 1.19; - SetSize(dResize * GetSize().GetWidth(), 1.1 * GetSize().GetHeight()); dResize = 1.20; + SetSize(dResize * GetSize().GetWidth(), 1.1 * GetSize().GetHeight()); #endif m_staticTextBalance->SetLabel(FormatMoney(GetBalance()) + " "); m_listCtrl->SetFocus(); @@ -458,6 +462,8 @@ void CMainFrame::OnIconize(wxIconizeEvent& event) { // 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; #ifndef __WXMSW__ @@ -985,7 +991,7 @@ void ThreadDelayedRepaint(void* parg) printf("DelayedRepaint\n"); wxPaintEvent event; pframeMain->fRefresh = true; - pframeMain->AddPendingEvent(event); + pframeMain->GetEventHandler()->AddPendingEvent(event); } } Sleep(nRepaintInterval); @@ -1010,7 +1016,7 @@ void MainFrameRepaint() printf("MainFrameRepaint\n"); wxPaintEvent event; pframeMain->fRefresh = true; - pframeMain->AddPendingEvent(event); + pframeMain->GetEventHandler()->AddPendingEvent(event); } } @@ -1695,12 +1701,14 @@ CAboutDialog::CAboutDialog(wxWindow* parent) : CAboutDialogBase(parent) // Workaround until upgrade to wxWidgets supporting UTF-8 wxString str = m_staticTextMain->GetLabel(); +#if !wxUSE_UNICODE if (str.Find('Â') != wxNOT_FOUND) str.Remove(str.Find('Â'), 1); - m_staticTextMain->SetLabel(str); +#endif #ifndef __WXMSW__ SetSize(510, 380); #endif + m_staticTextMain->SetLabel(str); } void CAboutDialog::OnButtonOK(wxCommandEvent& event) @@ -1732,7 +1740,7 @@ CSendDialog::CSendDialog(wxWindow* parent, const wxString& strAddress) : CSendDi if (fontTmp.GetPointSize() > 9); fontTmp.SetPointSize(9); m_staticTextInstructions->SetFont(fontTmp); - SetSize(725, wxDefaultCoord); + SetSize(725, 380); #endif // Set Icon @@ -2000,7 +2008,7 @@ void CSendingDialog::Repaint() { Refresh(); wxPaintEvent event; - AddPendingEvent(event); + GetEventHandler()->AddPendingEvent(event); } bool CSendingDialog::Status() @@ -3379,14 +3387,14 @@ void CMyTaskBarIcon::OnMenuOptions(wxCommandEvent& event) { // Since it's modal, get the main window to do it wxCommandEvent event2(wxEVT_COMMAND_MENU_SELECTED, wxID_MENUOPTIONSOPTIONS); - pframeMain->AddPendingEvent(event2); + pframeMain->GetEventHandler()->AddPendingEvent(event2); } void CMyTaskBarIcon::Restore() { pframeMain->Show(); wxIconizeEvent event(0, false); - pframeMain->AddPendingEvent(event); + pframeMain->GetEventHandler()->AddPendingEvent(event); pframeMain->Iconize(false); pframeMain->Raise(); } @@ -3548,7 +3556,7 @@ bool CMyApp::OnInit2() if (!fDebug && !pszSetDataDir[0]) 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 %d%s, OS version %s\n", VERSION, pszSubVer, wxGetOsDescription().mb_str()); + printf("Bitcoin version %d%s, OS version %s\n", VERSION, pszSubVer, ((string)wxGetOsDescription()).c_str()); if (mapArgs.count("-loadblockindextest")) { diff --git a/uibase.cpp b/uibase.cpp index f05f1095fb..fb4f1ed08c 100644 --- a/uibase.cpp +++ b/uibase.cpp @@ -1,3 +1,7 @@ +// 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. + /////////////////////////////////////////////////////////////////////////// // C++ code generated with wxFormBuilder (version Apr 16 2008) // http://www.wxformbuilder.org/ @@ -639,7 +643,7 @@ CSendDialogBase::CSendDialogBase( wxWindow* parent, wxWindowID id, const wxStrin bSizer21->Add( 0, 5, 0, wxEXPAND, 5 ); wxFlexGridSizer* fgSizer1; - fgSizer1 = new wxFlexGridSizer( 3, 2, 0, 0 ); + fgSizer1 = new wxFlexGridSizer( 0, 2, 0, 0 ); fgSizer1->AddGrowableCol( 1 ); fgSizer1->SetFlexibleDirection( wxBOTH ); fgSizer1->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED ); diff --git a/uibase.h b/uibase.h index 7620a24e53..97bb1bdc3c 100644 --- a/uibase.h +++ b/uibase.h @@ -1,3 +1,7 @@ +// 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. + /////////////////////////////////////////////////////////////////////////// // C++ code generated with wxFormBuilder (version Apr 16 2008) // http://www.wxformbuilder.org/ @@ -158,7 +162,7 @@ class CMainFrameBase : public wxFrame wxListCtrl* m_listCtrlOrdersSent; wxListCtrl* m_listCtrlProductsSent; wxListCtrl* m_listCtrlOrdersReceived; - CMainFrameBase( wxWindow* parent, wxWindowID id = wxID_MAINFRAME, const wxString& title = wxT("Bitcoin"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 725,484 ), long style = wxDEFAULT_FRAME_STYLE|wxRESIZE_BORDER|wxTAB_TRAVERSAL ); + CMainFrameBase( wxWindow* parent, wxWindowID id = wxID_MAINFRAME, const wxString& title = wxT("Bitcoin"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 727,484 ), long style = wxDEFAULT_FRAME_STYLE|wxRESIZE_BORDER|wxTAB_TRAVERSAL ); ~CMainFrameBase(); }; diff --git a/uiproject.fbp b/uiproject.fbp index 34fde78148..3c489ae633 100644 --- a/uiproject.fbp +++ b/uiproject.fbp @@ -32,7 +32,7 @@ CMainFrameBase - 725,484 + 727,484 wxDEFAULT_FRAME_STYLE|wxRESIZE_BORDER Bitcoin @@ -3509,7 +3509,7 @@ - + @@ -3580,7 +3580,7 @@ 5 wxEXPAND|wxLEFT 0 - + 2 wxBOTH 1 @@ -3590,7 +3590,7 @@ fgSizer1 wxFLEX_GROWMODE_SPECIFIED none - 3 + 0 0 5 @@ -4189,7 +4189,7 @@ 5 wxEXPAND 0 - + bSizer672 wxHORIZONTAL @@ -4317,7 +4317,7 @@ 5 wxEXPAND 1 - + bSizer67 wxHORIZONTAL @@ -4445,7 +4445,7 @@ 5 wxEXPAND 0 - + bSizer23 wxHORIZONTAL -- cgit v1.2.3 From 2939cab06d65548abdaeb1ff218550eb47b93362 Mon Sep 17 00:00:00 2001 From: s_nakamoto Date: Wed, 3 Feb 2010 22:58:40 +0000 Subject: update fSpent flag on wallet transactions if they're seen spent in case copy of wallet.dat was used elsewhere or restored from backup, better error dialog box if try to spend already spent coins, got rid of unused notebook with only one tab on main dialog, nicer looking About dialog, resize About dialog better on linux --- db.cpp | 13 +- headers.h | 3 +- main.cpp | 67 ++- main.h | 28 +- script.cpp | 12 +- serialize.h | 4 +- ui.cpp | 46 +- ui.h | 4 +- uibase.cpp | 124 +---- uibase.h | 23 +- uiproject.fbp | 1449 ++++++++++++++++++--------------------------------------- xpm/about.xpm | 665 ++++++++++++++++++++++++++ 12 files changed, 1275 insertions(+), 1163 deletions(-) create mode 100644 xpm/about.xpm diff --git a/db.cpp b/db.cpp index 77f8e1e0dd..ff9ece52b1 100644 --- a/db.cpp +++ b/db.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2009 Satoshi Nakamoto +// 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. @@ -593,14 +593,17 @@ bool CWalletDB::LoadWallet(vector& vchDefaultKeyRet) // wtx.hashBlock.ToString().substr(0,16).c_str(), // wtx.mapValue["message"].c_str()); } - else if (strType == "key") + else if (strType == "key" || strType == "wkey") { vector vchPubKey; ssKey >> vchPubKey; - CPrivKey vchPrivKey; - ssValue >> vchPrivKey; + CWalletKey wkey; + if (strType == "key") + ssValue >> wkey.vchPrivKey; + else + ssValue >> wkey; - mapKeys[vchPubKey] = vchPrivKey; + mapKeys[vchPubKey] = wkey.vchPrivKey; mapPubKeys[Hash160(vchPubKey)] = vchPubKey; } else if (strType == "defaultkey") diff --git a/headers.h b/headers.h index 73a0b43af4..45be4b65d1 100644 --- a/headers.h +++ b/headers.h @@ -1,4 +1,4 @@ -// Copyright (c) 2009 Satoshi Nakamoto +// 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. @@ -113,3 +113,4 @@ using namespace boost; #include "xpm/send16.xpm" #include "xpm/send16noshadow.xpm" #include "xpm/send20.xpm" +#include "xpm/about.xpm" diff --git a/main.cpp b/main.cpp index 416c616ad1..53acf8a753 100644 --- a/main.cpp +++ b/main.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2009 Satoshi Nakamoto +// 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. @@ -168,6 +168,27 @@ bool EraseFromWallet(uint256 hash) return true; } +void WalletUpdateSpent(const COutPoint& prevout) +{ + // 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) + { + map::iterator mi = mapWallet.find(prevout.hash); + if (mi != mapWallet.end()) + { + CWalletTx& wtx = (*mi).second; + if (!wtx.fSpent && wtx.vout[prevout.n].IsMine()) + { + printf("WalletUpdateSpent found spent coin %sbc %s\n", FormatMoney(wtx.GetCredit()).c_str(), wtx.GetHash().ToString().c_str()); + wtx.fSpent = true; + wtx.WriteToDisk(); + vWalletUpdated.push_back(prevout.hash); + } + } + } +} @@ -622,15 +643,44 @@ bool CWalletTx::AcceptWalletTransaction(CTxDB& txdb, bool fCheckInputs) void ReacceptWalletTransactions() { - // Reaccept any txes of ours that aren't already in a block CTxDB txdb("r"); CRITICAL_BLOCK(cs_mapWallet) { foreach(PAIRTYPE(const uint256, CWalletTx)& item, mapWallet) { CWalletTx& wtx = item.second; - if (!wtx.IsCoinBase() && !txdb.ContainsTx(wtx.GetHash())) - wtx.AcceptWalletTransaction(txdb, false); + if (wtx.fSpent && wtx.IsCoinBase()) + continue; + + CTxIndex txindex; + if (txdb.ReadTxIndex(wtx.GetHash(), txindex)) + { + // Update fSpent if a tx got spent somewhere else by a copy of wallet.dat + if (!wtx.fSpent) + { + if (txindex.vSpent.size() != wtx.vout.size()) + { + printf("ERROR: ReacceptWalletTransactions() : txindex.vSpent.size() %d != wtx.vout.size() %d\n", txindex.vSpent.size(), wtx.vout.size()); + continue; + } + for (int i = 0; i < txindex.vSpent.size(); i++) + { + if (!txindex.vSpent[i].IsNull() && wtx.vout[i].IsMine()) + { + printf("ReacceptWalletTransactions found spent coin %sbc %s\n", FormatMoney(wtx.GetCredit()).c_str(), wtx.GetHash().ToString().c_str()); + wtx.fSpent = true; + wtx.WriteToDisk(); + break; + } + } + } + } + else + { + // Reaccept any txes of ours that aren't already in a block + if (!wtx.IsCoinBase()) + wtx.AcceptWalletTransaction(txdb, false); + } } } } @@ -2843,9 +2893,13 @@ bool CommitTransactionSpent(const CWalletTx& wtxNew, const CKey& key) CRITICAL_BLOCK(cs_main) CRITICAL_BLOCK(cs_mapWallet) { - //// todo: eventually should make this transactional, never want to add a + //// old: eventually should make this transactional, never want to add a //// transaction without marking spent transactions, although the risk of //// interruption during this step is remote. + //// update: This matters even less now that fSpent can get corrected + //// when transactions are seen in VerifySignature. The remote chance of + //// unmarked fSpent will be handled by that. Don't need to make this + //// transactional. // 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 @@ -2910,8 +2964,7 @@ bool SendMoney(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew) if (!wtxNew.AcceptTransaction()) { // This must not fail. The transaction has already been signed and recorded. - throw runtime_error("SendMoney() : wtxNew.AcceptTransaction() failed\n"); - wxMessageBox("Error: Transaction not valid ", "Sending..."); + wxMessageBox("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.", "Sending..."); return error("SendMoney() : Error: Transaction not valid"); } wtxNew.RelayWalletTransaction(); diff --git a/main.h b/main.h index 716485e93d..14c445c70e 100644 --- a/main.h +++ b/main.h @@ -1,4 +1,4 @@ -// Copyright (c) 2009 Satoshi Nakamoto +// 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. @@ -56,6 +56,7 @@ FILE* AppendBlockFile(unsigned int& nFileRet); bool AddKey(const CKey& key); vector GenerateNewKey(); bool AddToWallet(const CWalletTx& wtxIn); +void WalletUpdateSpent(const COutPoint& prevout); void ReacceptWalletTransactions(); void RelayWalletTransactions(); bool LoadBlockIndex(bool fAllowNew=true); @@ -1370,6 +1371,31 @@ public: +// +// Private key that includes an expiration date in case it never gets used. +// +class CWalletKey +{ +public: + CPrivKey vchPrivKey; + int64 nTimeCreated; + int64 nTimeExpires; + + CWalletKey(int64 nTimeExpiresIn=0) + { + nTimeCreated = (nTimeExpiresIn ? GetTime() : 0); + nTimeExpires = nTimeExpiresIn; + } + + IMPLEMENT_SERIALIZE + ( + if (!(nType & SER_GETHASH)) + READWRITE(nVersion); + READWRITE(vchPrivKey); + READWRITE(nTimeCreated); + READWRITE(nTimeExpires); + ) +}; diff --git a/script.cpp b/script.cpp index 0e95af503c..a41de2aa76 100644 --- a/script.cpp +++ b/script.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2009 Satoshi Nakamoto +// 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. @@ -1123,5 +1123,13 @@ bool VerifySignature(const CTransaction& txFrom, const CTransaction& txTo, unsig if (txin.prevout.hash != txFrom.GetHash()) return false; - return EvalScript(txin.scriptSig + CScript(OP_CODESEPARATOR) + txout.scriptPubKey, txTo, nIn, nHashType); + if (!EvalScript(txin.scriptSig + CScript(OP_CODESEPARATOR) + txout.scriptPubKey, txTo, nIn, nHashType)) + return false; + + // Anytime a signature is successfully verified, it's proof the outpoint is spent, + // so lets 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. + WalletUpdateSpent(txin.prevout); + + return true; } diff --git a/serialize.h b/serialize.h index 263a22677d..439ef64125 100644 --- a/serialize.h +++ b/serialize.h @@ -1,4 +1,4 @@ -// Copyright (c) 2009 Satoshi Nakamoto +// 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. @@ -20,7 +20,7 @@ class CDataStream; class CAutoFile; static const int VERSION = 200; -static const char* pszSubVer = " test1"; +static const char* pszSubVer = " test2"; diff --git a/ui.cpp b/ui.cpp index d1163aa5bf..5d93ad227f 100644 --- a/ui.cpp +++ b/ui.cpp @@ -134,7 +134,6 @@ int GetSelection(wxListCtrl* listCtrl) return -1; } - string HtmlEscape(const char* psz, bool fMultiLine=false) { int len = 0; @@ -170,18 +169,6 @@ string HtmlEscape(const string& str, bool fMultiLine=false) return HtmlEscape(str.c_str(), fMultiLine); } -void AddToMyProducts(CProduct product) -{ - CProduct& productInsert = mapMyProducts[product.GetHash()]; - productInsert = product; - InsertLine(pframeMain->m_listCtrlProductsSent, &productInsert, - product.mapValue["category"], - product.mapValue["title"].substr(0, 100), - product.mapValue["description"].substr(0, 100), - product.mapValue["price"], - ""); -} - 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); @@ -253,9 +240,7 @@ template void AddPendingCustomEvent(wxEvtHandler* pevthandler, int nEventID, const T pbeginIn, const T pendIn) { // Need to rewrite with something like UIThreadCall - // I'm tired of maintaining this hack that's only called by unfinished unused code, - // but I'm not willing to delete it because it serves as documentation of what the - // unfinished code was trying to do. + // I'm tired of maintaining this hack that's only called by unfinished unused code. assert(("Unimplemented", 0)); //if (!pevthandler) // return; @@ -1233,7 +1218,7 @@ void CMainFrame::OnButtonChange(wxCommandEvent& event) } } -void CMainFrame::OnListItemActivatedAllTransactions(wxListEvent& event) +void CMainFrame::OnListItemActivated(wxListEvent& event) { uint256 hash((string)GetItemText(m_listCtrl, event.GetIndex(), 1)); CWalletTx wtx; @@ -1242,7 +1227,7 @@ void CMainFrame::OnListItemActivatedAllTransactions(wxListEvent& event) map::iterator mi = mapWallet.find(hash); if (mi == mapWallet.end()) { - printf("CMainFrame::OnListItemActivatedAllTransactions() : tx not found in mapWallet\n"); + printf("CMainFrame::OnListItemActivated() : tx not found in mapWallet\n"); return; } wtx = (*mi).second; @@ -1699,16 +1684,23 @@ CAboutDialog::CAboutDialog(wxWindow* parent) : CAboutDialogBase(parent) { m_staticTextVersion->SetLabel(strprintf("version 0.%d.%d beta", VERSION/100, VERSION%100)); +#if !wxUSE_UNICODE // Workaround until upgrade to wxWidgets supporting UTF-8 wxString str = m_staticTextMain->GetLabel(); -#if !wxUSE_UNICODE if (str.Find('Â') != wxNOT_FOUND) str.Remove(str.Find('Â'), 1); + m_staticTextMain->SetLabel(str); #endif #ifndef __WXMSW__ - SetSize(510, 380); + // 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() - 4); #endif - m_staticTextMain->SetLabel(str); } void CAboutDialog::OnButtonOK(wxCommandEvent& event) @@ -2789,6 +2781,18 @@ void CEditProductDialog::OnButtonAddField(wxCommandEvent& event) } } +void AddToMyProducts(CProduct product) +{ + CProduct& productInsert = mapMyProducts[product.GetHash()]; + productInsert = product; + //InsertLine(pframeMain->m_listCtrlProductsSent, &productInsert, + // product.mapValue["category"], + // product.mapValue["title"].substr(0, 100), + // product.mapValue["description"].substr(0, 100), + // product.mapValue["price"], + // ""); +} + void CEditProductDialog::OnButtonSend(wxCommandEvent& event) { CProduct product; diff --git a/ui.h b/ui.h index c4bf8b66f1..43e056596a 100644 --- a/ui.h +++ b/ui.h @@ -1,4 +1,4 @@ -// Copyright (c) 2009 Satoshi Nakamoto +// 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. @@ -60,7 +60,7 @@ protected: void OnButtonCopy(wxCommandEvent& event); void OnButtonChange(wxCommandEvent& event); void OnListColBeginDrag(wxListEvent& event); - void OnListItemActivatedAllTransactions(wxListEvent& event); + void OnListItemActivated(wxListEvent& event); void OnListItemActivatedProductsSent(wxListEvent& event); void OnListItemActivatedOrdersSent(wxListEvent& event); void OnListItemActivatedOrdersReceived(wxListEvent& event); diff --git a/uibase.cpp b/uibase.cpp index fb4f1ed08c..08c025facb 100644 --- a/uibase.cpp +++ b/uibase.cpp @@ -1,7 +1,6 @@ // 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. - /////////////////////////////////////////////////////////////////////////// // C++ code generated with wxFormBuilder (version Apr 16 2008) // http://www.wxformbuilder.org/ @@ -11,6 +10,7 @@ #include "uibase.h" +#include "xpm/about.xpm" #include "xpm/addressbook20.xpm" #include "xpm/check.xpm" #include "xpm/send20.xpm" @@ -142,81 +142,8 @@ CMainFrameBase::CMainFrameBase( wxWindow* parent, wxWindowID id, const wxString& bSizer2->Add( bSizer3, 0, wxEXPAND, 5 ); - m_notebook = new wxNotebook( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 ); - m_panel7 = new wxPanel( m_notebook, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL ); - wxBoxSizer* bSizer157; - bSizer157 = new wxBoxSizer( wxVERTICAL ); - - m_listCtrl = new wxListCtrl( m_panel7, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_NO_SORT_HEADER|wxLC_REPORT|wxLC_SORT_DESCENDING|wxVSCROLL ); - bSizer157->Add( m_listCtrl, 1, wxEXPAND|wxALL, 5 ); - - m_panel7->SetSizer( bSizer157 ); - m_panel7->Layout(); - bSizer157->Fit( m_panel7 ); - m_notebook->AddPage( m_panel7, wxT("All Transactions"), false ); - - bSizer2->Add( m_notebook, 1, wxEXPAND, 5 ); - - wxBoxSizer* bSizer_TabsForFutureUse; - bSizer_TabsForFutureUse = new wxBoxSizer( wxVERTICAL ); - - m_panel9 = new wxPanel( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL ); - m_panel9->Hide(); - - wxBoxSizer* bSizer159; - bSizer159 = new wxBoxSizer( wxVERTICAL ); - - m_listCtrlEscrows = new wxListCtrl( m_panel9, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_NO_SORT_HEADER|wxLC_REPORT ); - bSizer159->Add( m_listCtrlEscrows, 1, wxALL|wxEXPAND, 5 ); - - m_panel9->SetSizer( bSizer159 ); - m_panel9->Layout(); - bSizer159->Fit( m_panel9 ); - bSizer_TabsForFutureUse->Add( m_panel9, 1, wxEXPAND | wxALL, 5 ); - - m_panel8 = new wxPanel( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL ); - m_panel8->Hide(); - - wxBoxSizer* bSizer158; - bSizer158 = new wxBoxSizer( wxVERTICAL ); - - m_listCtrlOrdersSent = new wxListCtrl( m_panel8, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_NO_SORT_HEADER|wxLC_REPORT ); - bSizer158->Add( m_listCtrlOrdersSent, 1, wxALL|wxEXPAND, 5 ); - - m_panel8->SetSizer( bSizer158 ); - m_panel8->Layout(); - bSizer158->Fit( m_panel8 ); - bSizer_TabsForFutureUse->Add( m_panel8, 1, wxEXPAND | wxALL, 5 ); - - m_panel10 = new wxPanel( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL ); - m_panel10->Hide(); - - wxBoxSizer* bSizer160; - bSizer160 = new wxBoxSizer( wxVERTICAL ); - - m_listCtrlProductsSent = new wxListCtrl( m_panel10, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_NO_SORT_HEADER|wxLC_REPORT ); - bSizer160->Add( m_listCtrlProductsSent, 1, wxALL|wxEXPAND, 5 ); - - m_panel10->SetSizer( bSizer160 ); - m_panel10->Layout(); - bSizer160->Fit( m_panel10 ); - bSizer_TabsForFutureUse->Add( m_panel10, 1, wxEXPAND | wxALL, 5 ); - - m_panel11 = new wxPanel( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL ); - m_panel11->Hide(); - - wxBoxSizer* bSizer161; - bSizer161 = new wxBoxSizer( wxVERTICAL ); - - m_listCtrlOrdersReceived = new wxListCtrl( m_panel11, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_NO_SORT_HEADER|wxLC_REPORT ); - bSizer161->Add( m_listCtrlOrdersReceived, 1, wxALL|wxEXPAND, 5 ); - - m_panel11->SetSizer( bSizer161 ); - m_panel11->Layout(); - bSizer161->Fit( m_panel11 ); - bSizer_TabsForFutureUse->Add( m_panel11, 1, wxEXPAND | wxALL, 5 ); - - bSizer2->Add( bSizer_TabsForFutureUse, 1, wxEXPAND, 5 ); + m_listCtrl = new wxListCtrl( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_NO_SORT_HEADER|wxLC_REPORT|wxLC_SORT_DESCENDING|wxVSCROLL ); + bSizer2->Add( m_listCtrl, 1, wxEXPAND, 5 ); this->SetSizer( bSizer2 ); this->Layout(); @@ -267,11 +194,8 @@ CMainFrameBase::CMainFrameBase( wxWindow* parent, wxWindowID id, const wxString& m_buttonCopy->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CMainFrameBase::OnButtonCopy ), NULL, this ); m_button91->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CMainFrameBase::OnButtonChange ), NULL, this ); m_listCtrl->Connect( wxEVT_COMMAND_LIST_COL_BEGIN_DRAG, wxListEventHandler( CMainFrameBase::OnListColBeginDrag ), NULL, this ); - m_listCtrl->Connect( wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler( CMainFrameBase::OnListItemActivatedAllTransactions ), NULL, this ); + m_listCtrl->Connect( wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler( CMainFrameBase::OnListItemActivated ), NULL, this ); m_listCtrl->Connect( wxEVT_PAINT, wxPaintEventHandler( CMainFrameBase::OnPaintListCtrl ), NULL, this ); - m_listCtrlOrdersSent->Connect( wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler( CMainFrameBase::OnListItemActivatedOrdersSent ), NULL, this ); - m_listCtrlProductsSent->Connect( wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler( CMainFrameBase::OnListItemActivatedProductsSent ), NULL, this ); - m_listCtrlOrdersReceived->Connect( wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler( CMainFrameBase::OnListItemActivatedOrdersReceived ), NULL, this ); } CMainFrameBase::~CMainFrameBase() @@ -322,11 +246,8 @@ CMainFrameBase::~CMainFrameBase() m_buttonCopy->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CMainFrameBase::OnButtonCopy ), NULL, this ); m_button91->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CMainFrameBase::OnButtonChange ), NULL, this ); m_listCtrl->Disconnect( wxEVT_COMMAND_LIST_COL_BEGIN_DRAG, wxListEventHandler( CMainFrameBase::OnListColBeginDrag ), NULL, this ); - m_listCtrl->Disconnect( wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler( CMainFrameBase::OnListItemActivatedAllTransactions ), NULL, this ); + m_listCtrl->Disconnect( wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler( CMainFrameBase::OnListItemActivated ), NULL, this ); m_listCtrl->Disconnect( wxEVT_PAINT, wxPaintEventHandler( CMainFrameBase::OnPaintListCtrl ), NULL, this ); - m_listCtrlOrdersSent->Disconnect( wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler( CMainFrameBase::OnListItemActivatedOrdersSent ), NULL, this ); - m_listCtrlProductsSent->Disconnect( wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler( CMainFrameBase::OnListItemActivatedProductsSent ), NULL, this ); - m_listCtrlOrdersReceived->Disconnect( wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler( CMainFrameBase::OnListItemActivatedOrdersReceived ), 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 ) @@ -562,20 +483,23 @@ CAboutDialogBase::CAboutDialogBase( wxWindow* parent, wxWindowID id, const wxStr { 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 ); - bSizer62->Add( 60, 0, 0, wxEXPAND, 5 ); - wxBoxSizer* bSizer63; - bSizer63 = new wxBoxSizer( wxVERTICAL ); - - - bSizer63->Add( 0, 50, 0, wxEXPAND, 5 ); + bSizer631->Add( 0, 65, 0, wxEXPAND, 5 ); wxBoxSizer* bSizer64; bSizer64 = new wxBoxSizer( wxHORIZONTAL ); @@ -592,19 +516,19 @@ CAboutDialogBase::CAboutDialogBase( wxWindow* parent, wxWindowID id, const wxStr bSizer64->Add( m_staticTextVersion, 0, wxALIGN_BOTTOM|wxTOP|wxBOTTOM|wxRIGHT, 5 ); - bSizer63->Add( bSizer64, 0, wxEXPAND, 5 ); + bSizer631->Add( bSizer64, 0, wxEXPAND, 5 ); - bSizer63->Add( 0, 4, 0, wxEXPAND, 5 ); + bSizer631->Add( 0, 4, 0, wxEXPAND, 5 ); - m_staticTextMain = new wxStaticText( this, wxID_ANY, wxT("Copyright © 2009 Satoshi Nakamoto.\n\nThis is experimental software. Do not rely on it for actual financial transactions.\n\nDistributed under the MIT/X11 software license, see the accompanying file license.txt or http://www.opensource.org/licenses/mit-license.php.\n\nThis 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)."), wxDefaultPosition, wxDefaultSize, 0 ); - m_staticTextMain->Wrap( 400 ); - bSizer63->Add( m_staticTextMain, 0, wxALL, 5 ); + m_staticTextMain = new wxStaticText( this, wxID_ANY, wxT("Copyright © 2009-2010 Satoshi Nakamoto.\n\nThis is experimental software. Do not rely on it for actual financial transactions.\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)."), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticTextMain->Wrap( -1 ); + bSizer631->Add( m_staticTextMain, 0, wxALL, 5 ); - bSizer63->Add( 0, 0, 1, wxEXPAND, 5 ); + bSizer631->Add( 0, 0, 1, wxEXPAND, 5 ); - bSizer62->Add( bSizer63, 1, wxEXPAND, 5 ); + bSizer62->Add( bSizer631, 1, wxEXPAND, 5 ); bSizer60->Add( bSizer62, 1, wxEXPAND, 5 ); @@ -617,9 +541,11 @@ CAboutDialogBase::CAboutDialogBase( wxWindow* parent, wxWindowID id, const wxStr m_buttonOK = new wxButton( this, wxID_OK, wxT("OK"), wxDefaultPosition, wxSize( -1,-1 ), 0 ); bSizer61->Add( m_buttonOK, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); - bSizer60->Add( bSizer61, 0, wxALIGN_RIGHT|wxEXPAND, 5 ); + bSizer60->Add( bSizer61, 0, wxALIGN_RIGHT|wxEXPAND|wxRIGHT, 5 ); + + bSizer63->Add( bSizer60, 1, wxEXPAND|wxLEFT, 5 ); - this->SetSizer( bSizer60 ); + this->SetSizer( bSizer63 ); this->Layout(); // Connect Events diff --git a/uibase.h b/uibase.h index 97bb1bdc3c..faef982989 100644 --- a/uibase.h +++ b/uibase.h @@ -1,7 +1,6 @@ // 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. - /////////////////////////////////////////////////////////////////////////// // C++ code generated with wxFormBuilder (version Apr 16 2008) // http://www.wxformbuilder.org/ @@ -30,7 +29,6 @@ #include #include #include -#include #include #include #include @@ -119,12 +117,6 @@ class CMainFrameBase : public wxFrame wxStaticText* m_staticTextBalance; wxChoice* m_choiceFilter; - wxNotebook* m_notebook; - wxPanel* m_panel7; - wxPanel* m_panel9; - wxPanel* m_panel8; - wxPanel* m_panel10; - wxPanel* m_panel11; // Virtual event handlers, overide them in your derived class virtual void OnClose( wxCloseEvent& event ){ event.Skip(); } @@ -148,21 +140,14 @@ class CMainFrameBase : public wxFrame virtual void OnButtonCopy( wxCommandEvent& event ){ event.Skip(); } virtual void OnButtonChange( wxCommandEvent& event ){ event.Skip(); } virtual void OnListColBeginDrag( wxListEvent& event ){ event.Skip(); } - virtual void OnListItemActivatedAllTransactions( wxListEvent& event ){ event.Skip(); } + virtual void OnListItemActivated( wxListEvent& event ){ event.Skip(); } virtual void OnPaintListCtrl( wxPaintEvent& event ){ event.Skip(); } - virtual void OnListItemActivatedOrdersSent( wxListEvent& event ){ event.Skip(); } - virtual void OnListItemActivatedProductsSent( wxListEvent& event ){ event.Skip(); } - virtual void OnListItemActivatedOrdersReceived( wxListEvent& event ){ event.Skip(); } public: wxMenu* m_menuOptions; wxListCtrl* m_listCtrl; - wxListCtrl* m_listCtrlEscrows; - wxListCtrl* m_listCtrlOrdersSent; - wxListCtrl* m_listCtrlProductsSent; - wxListCtrl* m_listCtrlOrdersReceived; - CMainFrameBase( wxWindow* parent, wxWindowID id = wxID_MAINFRAME, const wxString& title = wxT("Bitcoin"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 727,484 ), long style = wxDEFAULT_FRAME_STYLE|wxRESIZE_BORDER|wxTAB_TRAVERSAL ); + CMainFrameBase( wxWindow* parent, wxWindowID id = wxID_MAINFRAME, const wxString& title = wxT("Bitcoin"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 712,484 ), long style = wxDEFAULT_FRAME_STYLE|wxRESIZE_BORDER|wxTAB_TRAVERSAL ); ~CMainFrameBase(); }; @@ -251,7 +236,7 @@ class CAboutDialogBase : public wxDialog private: protected: - + wxStaticBitmap* m_bitmap; wxStaticText* m_staticText40; @@ -266,7 +251,7 @@ class CAboutDialogBase : public wxDialog public: wxStaticText* m_staticTextVersion; - CAboutDialogBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxT("About Bitcoin"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 507,298 ), long style = wxDEFAULT_DIALOG_STYLE ); + CAboutDialogBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxT("About Bitcoin"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 532,329 ), long style = wxDEFAULT_DIALOG_STYLE ); ~CAboutDialogBase(); }; diff --git a/uiproject.fbp b/uiproject.fbp index 3c489ae633..c24f6962b9 100644 --- a/uiproject.fbp +++ b/uiproject.fbp @@ -18,7 +18,7 @@ 1 0 0 - + wxSYS_COLOUR_BTNFACE @@ -32,7 +32,7 @@ CMainFrameBase - 727,484 + 712,484 wxDEFAULT_FRAME_STYLE|wxRESIZE_BORDER Bitcoin @@ -824,9 +824,8 @@ 5 wxEXPAND 1 - + - 1 @@ -835,16 +834,16 @@ wxID_ANY - m_notebook - protected + m_listCtrl + public - + wxLC_NO_SORT_HEADER|wxLC_REPORT|wxLC_SORT_DESCENDING - + wxVSCROLL @@ -855,26 +854,114 @@ + + + + + OnListColBeginDrag + + + + + + + + + OnListItemActivated + + + + + + - - - + OnPaintListCtrl - - - All Transactions - 0 - + + + + + + + + + 1 + + + + 0 + wxID_ANY + + + CTxDetailsDialogBase + + 620,450 + wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER + + Transaction Details + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + bSizer64 + wxVERTICAL + none + + 5 + wxEXPAND + 1 + + + bSizer66 + wxVERTICAL + none + + 5 + wxALL|wxEXPAND + 1 + 1 @@ -884,18 +971,22 @@ wxID_ANY - m_panel7 + m_htmlWin protected + wxHW_SCROLLBAR_AUTO - wxTAB_TRAVERSAL + + + + @@ -916,117 +1007,46 @@ - - - bSizer157 - wxVERTICAL - none - - 5 - wxEXPAND|wxALL - 1 - - - - 1 - - - 0 - wxID_ANY - - - m_listCtrl - public - - - wxLC_NO_SORT_HEADER|wxLC_REPORT|wxLC_SORT_DESCENDING - - - - - wxVSCROLL - - - - - - - - - - - - - - - OnListColBeginDrag - - - - - - - - - OnListItemActivatedAllTransactions - - - - - - - - - - - - - OnPaintListCtrl - - - - - - - - - 5 - wxEXPAND - 1 + wxALIGN_RIGHT + 0 - bSizer_TabsForFutureUse - wxVERTICAL + bSizer65 + wxHORIZONTAL none 5 - wxEXPAND | wxALL - 1 - + wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND + 0 + + 0 1 - 1 - wxID_ANY + 0 + wxID_OK + OK - m_panel9 + m_buttonOK protected - + -1,-1 + - wxTAB_TRAVERSAL + + OnButtonOK @@ -1050,229 +1070,103 @@ - - - bSizer159 - wxVERTICAL - none - - 5 - wxALL|wxEXPAND - 1 - - - - 1 - - - 0 - wxID_ANY - - - m_listCtrlEscrows - public - - - wxLC_NO_SORT_HEADER|wxLC_REPORT - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxEXPAND | wxALL - 1 - - - - 1 - - - 1 - wxID_ANY - - - m_panel8 - protected - - - - - - - wxTAB_TRAVERSAL - - - - - - - - - - - - - - - - - - - - - - - - - - bSizer158 - wxVERTICAL - none - - 5 - wxALL|wxEXPAND - 1 - - - - 1 - - - 0 - wxID_ANY - - - m_listCtrlOrdersSent - public - - - wxLC_NO_SORT_HEADER|wxLC_REPORT - - - - - - - - - - - - - - - - - - - - - - - - - - - - - OnListItemActivatedOrdersSent - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + 1 + + + + 0 + wxID_ANY + + + COptionsDialogBase + + 540,360 + wxDEFAULT_DIALOG_STYLE + + Options + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + bSizer55 + wxVERTICAL + none + + 9 + wxEXPAND|wxALL + 1 + + + bSizer66 + wxHORIZONTAL + none 5 - wxEXPAND | wxALL - 1 - + wxEXPAND|wxRIGHT + 0 + + 1 - 1 + 0 wxID_ANY - m_panel10 + m_listBox protected - + 110,-1 + wxLB_NEEDED_SB|wxLB_SINGLE - wxTAB_TRAVERSAL + @@ -1283,6 +1177,8 @@ + OnListBox + @@ -1296,106 +1192,33 @@ - - - bSizer160 - wxVERTICAL - none - - 5 - wxALL|wxEXPAND - 1 - - - - 1 - - - 0 - wxID_ANY - - - m_listCtrlProductsSent - public - - - wxLC_NO_SORT_HEADER|wxLC_REPORT - - - - - - - - - - - - - - - - - - - - - - - - - - - - - OnListItemActivatedProductsSent - - - - - - - - - - - - - - - - - - - - - - 5 - wxEXPAND | wxALL + wxEXPAND|wxLEFT 1 - + 1 - 1 + 0 wxID_ANY - m_panel11 + m_scrolledWindow protected + 5 + 5 - wxTAB_TRAVERSAL + @@ -1421,14 +1244,14 @@ - bSizer161 + bSizer63 wxVERTICAL none 5 - wxALL|wxEXPAND - 1 - + wxEXPAND + 0 + 1 @@ -1438,447 +1261,15 @@ wxID_ANY - m_listCtrlOrdersReceived - public + m_panelMain + protected - wxLC_NO_SORT_HEADER|wxLC_REPORT - - - - - - - - - - - - - - - - - - - - - - - - - OnListItemActivatedOrdersReceived - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1 - - - - 0 - wxID_ANY - - - CTxDetailsDialogBase - - 620,450 - wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER - - Transaction Details - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - bSizer64 - wxVERTICAL - none - - 5 - wxEXPAND - 1 - - - bSizer66 - wxVERTICAL - none - - 5 - wxALL|wxEXPAND - 1 - - - - 1 - - - 0 - wxID_ANY - - - m_htmlWin - protected - - - wxHW_SCROLLBAR_AUTO - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALIGN_RIGHT - 0 - - - bSizer65 - wxHORIZONTAL - none - - 5 - wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND - 0 - - - - 0 - 1 - - - 0 - wxID_OK - OK - - - m_buttonOK - protected - - -1,-1 - - - - - - - OnButtonOK - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1 - - - - 0 - wxID_ANY - - - COptionsDialogBase - - 540,360 - wxDEFAULT_DIALOG_STYLE - - Options - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - bSizer55 - wxVERTICAL - none - - 9 - wxEXPAND|wxALL - 1 - - - bSizer66 - wxHORIZONTAL - none - - 5 - wxEXPAND|wxRIGHT - 0 - - - - - 1 - - - 0 - wxID_ANY - - - m_listBox - protected - - 110,-1 - wxLB_NEEDED_SB|wxLB_SINGLE - - - - - - - - - - - - - - - - OnListBox - - - - - - - - - - - - - - - - - - 5 - wxEXPAND|wxLEFT - 1 - - - - 1 - - - 0 - wxID_ANY - - - m_scrolledWindow - protected - - 5 - 5 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - bSizer63 - wxVERTICAL - none - - 5 - wxEXPAND - 0 - - - - 1 - - - 0 - wxID_ANY - - - m_panelMain - protected - - - - - - - wxTAB_TRAVERSAL + wxTAB_TRAVERSAL @@ -3165,7 +2556,7 @@ CAboutDialogBase - 507,298 + 532,329 wxDEFAULT_DIALOG_STYLE About Bitcoin @@ -3203,126 +2594,237 @@ - + - bSizer60 - wxVERTICAL + bSizer63 + wxHORIZONTAL none 5 - wxEXPAND + + 0 + + + xpm/about.xpm; Load From File + + 1 + + + 0 + wxID_ANY + + + m_bitmap + protected + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND|wxLEFT 1 - bSizer62 - wxHORIZONTAL + bSizer60 + wxVERTICAL none - - 5 - wxEXPAND - 0 - - 0 - protected - 60 - - 5 wxEXPAND 1 - bSizer63 - wxVERTICAL - none - - 5 - wxEXPAND - 0 - - 50 - protected - 0 - - + bSizer62 + wxHORIZONTAL + none 5 wxEXPAND - 0 + 1 - bSizer64 - wxHORIZONTAL + bSizer631 + wxVERTICAL none 5 - wxALIGN_BOTTOM|wxTOP|wxBOTTOM|wxLEFT + wxEXPAND 0 - - - - 1 - - Tahoma,90,92,10,74,0 - 0 - wxID_ANY - Bitcoin - + + 65 + protected + 0 + + + + 5 + wxEXPAND + 0 + - m_staticText40 + bSizer64 + wxHORIZONTAL + none + + 5 + wxALIGN_BOTTOM|wxTOP|wxBOTTOM|wxLEFT + 0 + + + + 1 + + Tahoma,90,92,10,74,0 + 0 + wxID_ANY + Bitcoin + + + m_staticText40 + protected + + + + + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALIGN_BOTTOM|wxTOP|wxBOTTOM|wxRIGHT + 0 + + + + 1 + + Tahoma,90,90,10,74,0 + 0 + wxID_ANY + version + + + m_staticTextVersion + public + + + + + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND + 0 + + 4 protected - - - - - - - - - -1 - - - - - - - - - - - - - - - - - - - - - - - + 0 5 - wxALIGN_BOTTOM|wxTOP|wxBOTTOM|wxRIGHT + wxALL 0 1 - Tahoma,90,90,10,74,0 + 0 wxID_ANY - version + Copyright © 2009-2010 Satoshi Nakamoto. This is experimental software. Do not rely on it for actual financial transactions. 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). - m_staticTextVersion - public + m_staticTextMain + protected @@ -3357,44 +2859,66 @@ + + 5 + wxEXPAND + 1 + + 0 + protected + 0 + + + + + + 5 + wxALIGN_RIGHT|wxEXPAND|wxRIGHT + 0 + + + bSizer61 + wxHORIZONTAL + none 5 wxEXPAND - 0 + 1 - 4 + 0 protected 0 5 - wxALL + wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND 0 - + + 0 1 0 - wxID_ANY - Copyright © 2009 Satoshi Nakamoto. This is experimental software. Do not rely on it for actual financial transactions. 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). + wxID_OK + OK - m_staticTextMain + m_buttonOK protected - + -1,-1 - 400 + OnButtonOK @@ -3420,96 +2944,13 @@ - - 5 - wxEXPAND - 1 - - 0 - protected - 0 - - - - - - - - 5 - wxALIGN_RIGHT|wxEXPAND - 0 - - - bSizer61 - wxHORIZONTAL - none - - 5 - wxEXPAND - 1 - - 0 - protected - 0 - - - - 5 - wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND - 0 - - - - 0 - 1 - - - 0 - wxID_OK - OK - - - m_buttonOK - protected - - -1,-1 - - - - - - - OnButtonOK - - - - - - - - - - - - - - - - - - - - - - - - + diff --git a/xpm/about.xpm b/xpm/about.xpm new file mode 100644 index 0000000000..3fa868ca76 --- /dev/null +++ b/xpm/about.xpm @@ -0,0 +1,665 @@ +// 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<<<<<<<<<<<>>>>>>>>>>>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````````````''''''''''''{{{{{{{{{{{{" +}; -- cgit v1.2.3 From 53d508072b02d522371bde148dcc3e925f472be7 Mon Sep 17 00:00:00 2001 From: s_nakamoto Date: Wed, 3 Feb 2010 22:58:40 +0000 Subject: update fSpent flag on wallet transactions if they're seen spent in case copy of wallet.dat was used elsewhere or restored from backup, better error dialog box if try to spend already spent coins, got rid of unused notebook with only one tab on main dialog, nicer looking About dialog, resize About dialog better on linux git-svn-id: https://bitcoin.svn.sourceforge.net/svnroot/bitcoin/trunk@55 1a98c847-1fd6-4fd8-948a-caf3550aa51b --- db.cpp | 13 +- headers.h | 3 +- main.cpp | 67 ++- main.h | 28 +- script.cpp | 12 +- serialize.h | 4 +- ui.cpp | 46 +- ui.h | 4 +- uibase.cpp | 124 +---- uibase.h | 23 +- uiproject.fbp | 1449 ++++++++++++++++++--------------------------------------- xpm/about.xpm | 665 ++++++++++++++++++++++++++ 12 files changed, 1275 insertions(+), 1163 deletions(-) create mode 100644 xpm/about.xpm diff --git a/db.cpp b/db.cpp index 77f8e1e0dd..ff9ece52b1 100644 --- a/db.cpp +++ b/db.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2009 Satoshi Nakamoto +// 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. @@ -593,14 +593,17 @@ bool CWalletDB::LoadWallet(vector& vchDefaultKeyRet) // wtx.hashBlock.ToString().substr(0,16).c_str(), // wtx.mapValue["message"].c_str()); } - else if (strType == "key") + else if (strType == "key" || strType == "wkey") { vector vchPubKey; ssKey >> vchPubKey; - CPrivKey vchPrivKey; - ssValue >> vchPrivKey; + CWalletKey wkey; + if (strType == "key") + ssValue >> wkey.vchPrivKey; + else + ssValue >> wkey; - mapKeys[vchPubKey] = vchPrivKey; + mapKeys[vchPubKey] = wkey.vchPrivKey; mapPubKeys[Hash160(vchPubKey)] = vchPubKey; } else if (strType == "defaultkey") diff --git a/headers.h b/headers.h index 73a0b43af4..45be4b65d1 100644 --- a/headers.h +++ b/headers.h @@ -1,4 +1,4 @@ -// Copyright (c) 2009 Satoshi Nakamoto +// 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. @@ -113,3 +113,4 @@ using namespace boost; #include "xpm/send16.xpm" #include "xpm/send16noshadow.xpm" #include "xpm/send20.xpm" +#include "xpm/about.xpm" diff --git a/main.cpp b/main.cpp index 416c616ad1..53acf8a753 100644 --- a/main.cpp +++ b/main.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2009 Satoshi Nakamoto +// 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. @@ -168,6 +168,27 @@ bool EraseFromWallet(uint256 hash) return true; } +void WalletUpdateSpent(const COutPoint& prevout) +{ + // 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) + { + map::iterator mi = mapWallet.find(prevout.hash); + if (mi != mapWallet.end()) + { + CWalletTx& wtx = (*mi).second; + if (!wtx.fSpent && wtx.vout[prevout.n].IsMine()) + { + printf("WalletUpdateSpent found spent coin %sbc %s\n", FormatMoney(wtx.GetCredit()).c_str(), wtx.GetHash().ToString().c_str()); + wtx.fSpent = true; + wtx.WriteToDisk(); + vWalletUpdated.push_back(prevout.hash); + } + } + } +} @@ -622,15 +643,44 @@ bool CWalletTx::AcceptWalletTransaction(CTxDB& txdb, bool fCheckInputs) void ReacceptWalletTransactions() { - // Reaccept any txes of ours that aren't already in a block CTxDB txdb("r"); CRITICAL_BLOCK(cs_mapWallet) { foreach(PAIRTYPE(const uint256, CWalletTx)& item, mapWallet) { CWalletTx& wtx = item.second; - if (!wtx.IsCoinBase() && !txdb.ContainsTx(wtx.GetHash())) - wtx.AcceptWalletTransaction(txdb, false); + if (wtx.fSpent && wtx.IsCoinBase()) + continue; + + CTxIndex txindex; + if (txdb.ReadTxIndex(wtx.GetHash(), txindex)) + { + // Update fSpent if a tx got spent somewhere else by a copy of wallet.dat + if (!wtx.fSpent) + { + if (txindex.vSpent.size() != wtx.vout.size()) + { + printf("ERROR: ReacceptWalletTransactions() : txindex.vSpent.size() %d != wtx.vout.size() %d\n", txindex.vSpent.size(), wtx.vout.size()); + continue; + } + for (int i = 0; i < txindex.vSpent.size(); i++) + { + if (!txindex.vSpent[i].IsNull() && wtx.vout[i].IsMine()) + { + printf("ReacceptWalletTransactions found spent coin %sbc %s\n", FormatMoney(wtx.GetCredit()).c_str(), wtx.GetHash().ToString().c_str()); + wtx.fSpent = true; + wtx.WriteToDisk(); + break; + } + } + } + } + else + { + // Reaccept any txes of ours that aren't already in a block + if (!wtx.IsCoinBase()) + wtx.AcceptWalletTransaction(txdb, false); + } } } } @@ -2843,9 +2893,13 @@ bool CommitTransactionSpent(const CWalletTx& wtxNew, const CKey& key) CRITICAL_BLOCK(cs_main) CRITICAL_BLOCK(cs_mapWallet) { - //// todo: eventually should make this transactional, never want to add a + //// old: eventually should make this transactional, never want to add a //// transaction without marking spent transactions, although the risk of //// interruption during this step is remote. + //// update: This matters even less now that fSpent can get corrected + //// when transactions are seen in VerifySignature. The remote chance of + //// unmarked fSpent will be handled by that. Don't need to make this + //// transactional. // 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 @@ -2910,8 +2964,7 @@ bool SendMoney(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew) if (!wtxNew.AcceptTransaction()) { // This must not fail. The transaction has already been signed and recorded. - throw runtime_error("SendMoney() : wtxNew.AcceptTransaction() failed\n"); - wxMessageBox("Error: Transaction not valid ", "Sending..."); + wxMessageBox("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.", "Sending..."); return error("SendMoney() : Error: Transaction not valid"); } wtxNew.RelayWalletTransaction(); diff --git a/main.h b/main.h index 716485e93d..14c445c70e 100644 --- a/main.h +++ b/main.h @@ -1,4 +1,4 @@ -// Copyright (c) 2009 Satoshi Nakamoto +// 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. @@ -56,6 +56,7 @@ FILE* AppendBlockFile(unsigned int& nFileRet); bool AddKey(const CKey& key); vector GenerateNewKey(); bool AddToWallet(const CWalletTx& wtxIn); +void WalletUpdateSpent(const COutPoint& prevout); void ReacceptWalletTransactions(); void RelayWalletTransactions(); bool LoadBlockIndex(bool fAllowNew=true); @@ -1370,6 +1371,31 @@ public: +// +// Private key that includes an expiration date in case it never gets used. +// +class CWalletKey +{ +public: + CPrivKey vchPrivKey; + int64 nTimeCreated; + int64 nTimeExpires; + + CWalletKey(int64 nTimeExpiresIn=0) + { + nTimeCreated = (nTimeExpiresIn ? GetTime() : 0); + nTimeExpires = nTimeExpiresIn; + } + + IMPLEMENT_SERIALIZE + ( + if (!(nType & SER_GETHASH)) + READWRITE(nVersion); + READWRITE(vchPrivKey); + READWRITE(nTimeCreated); + READWRITE(nTimeExpires); + ) +}; diff --git a/script.cpp b/script.cpp index 0e95af503c..a41de2aa76 100644 --- a/script.cpp +++ b/script.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2009 Satoshi Nakamoto +// 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. @@ -1123,5 +1123,13 @@ bool VerifySignature(const CTransaction& txFrom, const CTransaction& txTo, unsig if (txin.prevout.hash != txFrom.GetHash()) return false; - return EvalScript(txin.scriptSig + CScript(OP_CODESEPARATOR) + txout.scriptPubKey, txTo, nIn, nHashType); + if (!EvalScript(txin.scriptSig + CScript(OP_CODESEPARATOR) + txout.scriptPubKey, txTo, nIn, nHashType)) + return false; + + // Anytime a signature is successfully verified, it's proof the outpoint is spent, + // so lets 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. + WalletUpdateSpent(txin.prevout); + + return true; } diff --git a/serialize.h b/serialize.h index 263a22677d..439ef64125 100644 --- a/serialize.h +++ b/serialize.h @@ -1,4 +1,4 @@ -// Copyright (c) 2009 Satoshi Nakamoto +// 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. @@ -20,7 +20,7 @@ class CDataStream; class CAutoFile; static const int VERSION = 200; -static const char* pszSubVer = " test1"; +static const char* pszSubVer = " test2"; diff --git a/ui.cpp b/ui.cpp index d1163aa5bf..5d93ad227f 100644 --- a/ui.cpp +++ b/ui.cpp @@ -134,7 +134,6 @@ int GetSelection(wxListCtrl* listCtrl) return -1; } - string HtmlEscape(const char* psz, bool fMultiLine=false) { int len = 0; @@ -170,18 +169,6 @@ string HtmlEscape(const string& str, bool fMultiLine=false) return HtmlEscape(str.c_str(), fMultiLine); } -void AddToMyProducts(CProduct product) -{ - CProduct& productInsert = mapMyProducts[product.GetHash()]; - productInsert = product; - InsertLine(pframeMain->m_listCtrlProductsSent, &productInsert, - product.mapValue["category"], - product.mapValue["title"].substr(0, 100), - product.mapValue["description"].substr(0, 100), - product.mapValue["price"], - ""); -} - 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); @@ -253,9 +240,7 @@ template void AddPendingCustomEvent(wxEvtHandler* pevthandler, int nEventID, const T pbeginIn, const T pendIn) { // Need to rewrite with something like UIThreadCall - // I'm tired of maintaining this hack that's only called by unfinished unused code, - // but I'm not willing to delete it because it serves as documentation of what the - // unfinished code was trying to do. + // I'm tired of maintaining this hack that's only called by unfinished unused code. assert(("Unimplemented", 0)); //if (!pevthandler) // return; @@ -1233,7 +1218,7 @@ void CMainFrame::OnButtonChange(wxCommandEvent& event) } } -void CMainFrame::OnListItemActivatedAllTransactions(wxListEvent& event) +void CMainFrame::OnListItemActivated(wxListEvent& event) { uint256 hash((string)GetItemText(m_listCtrl, event.GetIndex(), 1)); CWalletTx wtx; @@ -1242,7 +1227,7 @@ void CMainFrame::OnListItemActivatedAllTransactions(wxListEvent& event) map::iterator mi = mapWallet.find(hash); if (mi == mapWallet.end()) { - printf("CMainFrame::OnListItemActivatedAllTransactions() : tx not found in mapWallet\n"); + printf("CMainFrame::OnListItemActivated() : tx not found in mapWallet\n"); return; } wtx = (*mi).second; @@ -1699,16 +1684,23 @@ CAboutDialog::CAboutDialog(wxWindow* parent) : CAboutDialogBase(parent) { m_staticTextVersion->SetLabel(strprintf("version 0.%d.%d beta", VERSION/100, VERSION%100)); +#if !wxUSE_UNICODE // Workaround until upgrade to wxWidgets supporting UTF-8 wxString str = m_staticTextMain->GetLabel(); -#if !wxUSE_UNICODE if (str.Find('Â') != wxNOT_FOUND) str.Remove(str.Find('Â'), 1); + m_staticTextMain->SetLabel(str); #endif #ifndef __WXMSW__ - SetSize(510, 380); + // 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() - 4); #endif - m_staticTextMain->SetLabel(str); } void CAboutDialog::OnButtonOK(wxCommandEvent& event) @@ -2789,6 +2781,18 @@ void CEditProductDialog::OnButtonAddField(wxCommandEvent& event) } } +void AddToMyProducts(CProduct product) +{ + CProduct& productInsert = mapMyProducts[product.GetHash()]; + productInsert = product; + //InsertLine(pframeMain->m_listCtrlProductsSent, &productInsert, + // product.mapValue["category"], + // product.mapValue["title"].substr(0, 100), + // product.mapValue["description"].substr(0, 100), + // product.mapValue["price"], + // ""); +} + void CEditProductDialog::OnButtonSend(wxCommandEvent& event) { CProduct product; diff --git a/ui.h b/ui.h index c4bf8b66f1..43e056596a 100644 --- a/ui.h +++ b/ui.h @@ -1,4 +1,4 @@ -// Copyright (c) 2009 Satoshi Nakamoto +// 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. @@ -60,7 +60,7 @@ protected: void OnButtonCopy(wxCommandEvent& event); void OnButtonChange(wxCommandEvent& event); void OnListColBeginDrag(wxListEvent& event); - void OnListItemActivatedAllTransactions(wxListEvent& event); + void OnListItemActivated(wxListEvent& event); void OnListItemActivatedProductsSent(wxListEvent& event); void OnListItemActivatedOrdersSent(wxListEvent& event); void OnListItemActivatedOrdersReceived(wxListEvent& event); diff --git a/uibase.cpp b/uibase.cpp index fb4f1ed08c..08c025facb 100644 --- a/uibase.cpp +++ b/uibase.cpp @@ -1,7 +1,6 @@ // 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. - /////////////////////////////////////////////////////////////////////////// // C++ code generated with wxFormBuilder (version Apr 16 2008) // http://www.wxformbuilder.org/ @@ -11,6 +10,7 @@ #include "uibase.h" +#include "xpm/about.xpm" #include "xpm/addressbook20.xpm" #include "xpm/check.xpm" #include "xpm/send20.xpm" @@ -142,81 +142,8 @@ CMainFrameBase::CMainFrameBase( wxWindow* parent, wxWindowID id, const wxString& bSizer2->Add( bSizer3, 0, wxEXPAND, 5 ); - m_notebook = new wxNotebook( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 ); - m_panel7 = new wxPanel( m_notebook, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL ); - wxBoxSizer* bSizer157; - bSizer157 = new wxBoxSizer( wxVERTICAL ); - - m_listCtrl = new wxListCtrl( m_panel7, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_NO_SORT_HEADER|wxLC_REPORT|wxLC_SORT_DESCENDING|wxVSCROLL ); - bSizer157->Add( m_listCtrl, 1, wxEXPAND|wxALL, 5 ); - - m_panel7->SetSizer( bSizer157 ); - m_panel7->Layout(); - bSizer157->Fit( m_panel7 ); - m_notebook->AddPage( m_panel7, wxT("All Transactions"), false ); - - bSizer2->Add( m_notebook, 1, wxEXPAND, 5 ); - - wxBoxSizer* bSizer_TabsForFutureUse; - bSizer_TabsForFutureUse = new wxBoxSizer( wxVERTICAL ); - - m_panel9 = new wxPanel( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL ); - m_panel9->Hide(); - - wxBoxSizer* bSizer159; - bSizer159 = new wxBoxSizer( wxVERTICAL ); - - m_listCtrlEscrows = new wxListCtrl( m_panel9, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_NO_SORT_HEADER|wxLC_REPORT ); - bSizer159->Add( m_listCtrlEscrows, 1, wxALL|wxEXPAND, 5 ); - - m_panel9->SetSizer( bSizer159 ); - m_panel9->Layout(); - bSizer159->Fit( m_panel9 ); - bSizer_TabsForFutureUse->Add( m_panel9, 1, wxEXPAND | wxALL, 5 ); - - m_panel8 = new wxPanel( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL ); - m_panel8->Hide(); - - wxBoxSizer* bSizer158; - bSizer158 = new wxBoxSizer( wxVERTICAL ); - - m_listCtrlOrdersSent = new wxListCtrl( m_panel8, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_NO_SORT_HEADER|wxLC_REPORT ); - bSizer158->Add( m_listCtrlOrdersSent, 1, wxALL|wxEXPAND, 5 ); - - m_panel8->SetSizer( bSizer158 ); - m_panel8->Layout(); - bSizer158->Fit( m_panel8 ); - bSizer_TabsForFutureUse->Add( m_panel8, 1, wxEXPAND | wxALL, 5 ); - - m_panel10 = new wxPanel( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL ); - m_panel10->Hide(); - - wxBoxSizer* bSizer160; - bSizer160 = new wxBoxSizer( wxVERTICAL ); - - m_listCtrlProductsSent = new wxListCtrl( m_panel10, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_NO_SORT_HEADER|wxLC_REPORT ); - bSizer160->Add( m_listCtrlProductsSent, 1, wxALL|wxEXPAND, 5 ); - - m_panel10->SetSizer( bSizer160 ); - m_panel10->Layout(); - bSizer160->Fit( m_panel10 ); - bSizer_TabsForFutureUse->Add( m_panel10, 1, wxEXPAND | wxALL, 5 ); - - m_panel11 = new wxPanel( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL ); - m_panel11->Hide(); - - wxBoxSizer* bSizer161; - bSizer161 = new wxBoxSizer( wxVERTICAL ); - - m_listCtrlOrdersReceived = new wxListCtrl( m_panel11, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_NO_SORT_HEADER|wxLC_REPORT ); - bSizer161->Add( m_listCtrlOrdersReceived, 1, wxALL|wxEXPAND, 5 ); - - m_panel11->SetSizer( bSizer161 ); - m_panel11->Layout(); - bSizer161->Fit( m_panel11 ); - bSizer_TabsForFutureUse->Add( m_panel11, 1, wxEXPAND | wxALL, 5 ); - - bSizer2->Add( bSizer_TabsForFutureUse, 1, wxEXPAND, 5 ); + m_listCtrl = new wxListCtrl( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_NO_SORT_HEADER|wxLC_REPORT|wxLC_SORT_DESCENDING|wxVSCROLL ); + bSizer2->Add( m_listCtrl, 1, wxEXPAND, 5 ); this->SetSizer( bSizer2 ); this->Layout(); @@ -267,11 +194,8 @@ CMainFrameBase::CMainFrameBase( wxWindow* parent, wxWindowID id, const wxString& m_buttonCopy->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CMainFrameBase::OnButtonCopy ), NULL, this ); m_button91->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CMainFrameBase::OnButtonChange ), NULL, this ); m_listCtrl->Connect( wxEVT_COMMAND_LIST_COL_BEGIN_DRAG, wxListEventHandler( CMainFrameBase::OnListColBeginDrag ), NULL, this ); - m_listCtrl->Connect( wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler( CMainFrameBase::OnListItemActivatedAllTransactions ), NULL, this ); + m_listCtrl->Connect( wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler( CMainFrameBase::OnListItemActivated ), NULL, this ); m_listCtrl->Connect( wxEVT_PAINT, wxPaintEventHandler( CMainFrameBase::OnPaintListCtrl ), NULL, this ); - m_listCtrlOrdersSent->Connect( wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler( CMainFrameBase::OnListItemActivatedOrdersSent ), NULL, this ); - m_listCtrlProductsSent->Connect( wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler( CMainFrameBase::OnListItemActivatedProductsSent ), NULL, this ); - m_listCtrlOrdersReceived->Connect( wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler( CMainFrameBase::OnListItemActivatedOrdersReceived ), NULL, this ); } CMainFrameBase::~CMainFrameBase() @@ -322,11 +246,8 @@ CMainFrameBase::~CMainFrameBase() m_buttonCopy->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CMainFrameBase::OnButtonCopy ), NULL, this ); m_button91->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CMainFrameBase::OnButtonChange ), NULL, this ); m_listCtrl->Disconnect( wxEVT_COMMAND_LIST_COL_BEGIN_DRAG, wxListEventHandler( CMainFrameBase::OnListColBeginDrag ), NULL, this ); - m_listCtrl->Disconnect( wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler( CMainFrameBase::OnListItemActivatedAllTransactions ), NULL, this ); + m_listCtrl->Disconnect( wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler( CMainFrameBase::OnListItemActivated ), NULL, this ); m_listCtrl->Disconnect( wxEVT_PAINT, wxPaintEventHandler( CMainFrameBase::OnPaintListCtrl ), NULL, this ); - m_listCtrlOrdersSent->Disconnect( wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler( CMainFrameBase::OnListItemActivatedOrdersSent ), NULL, this ); - m_listCtrlProductsSent->Disconnect( wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler( CMainFrameBase::OnListItemActivatedProductsSent ), NULL, this ); - m_listCtrlOrdersReceived->Disconnect( wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler( CMainFrameBase::OnListItemActivatedOrdersReceived ), 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 ) @@ -562,20 +483,23 @@ CAboutDialogBase::CAboutDialogBase( wxWindow* parent, wxWindowID id, const wxStr { 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 ); - bSizer62->Add( 60, 0, 0, wxEXPAND, 5 ); - wxBoxSizer* bSizer63; - bSizer63 = new wxBoxSizer( wxVERTICAL ); - - - bSizer63->Add( 0, 50, 0, wxEXPAND, 5 ); + bSizer631->Add( 0, 65, 0, wxEXPAND, 5 ); wxBoxSizer* bSizer64; bSizer64 = new wxBoxSizer( wxHORIZONTAL ); @@ -592,19 +516,19 @@ CAboutDialogBase::CAboutDialogBase( wxWindow* parent, wxWindowID id, const wxStr bSizer64->Add( m_staticTextVersion, 0, wxALIGN_BOTTOM|wxTOP|wxBOTTOM|wxRIGHT, 5 ); - bSizer63->Add( bSizer64, 0, wxEXPAND, 5 ); + bSizer631->Add( bSizer64, 0, wxEXPAND, 5 ); - bSizer63->Add( 0, 4, 0, wxEXPAND, 5 ); + bSizer631->Add( 0, 4, 0, wxEXPAND, 5 ); - m_staticTextMain = new wxStaticText( this, wxID_ANY, wxT("Copyright © 2009 Satoshi Nakamoto.\n\nThis is experimental software. Do not rely on it for actual financial transactions.\n\nDistributed under the MIT/X11 software license, see the accompanying file license.txt or http://www.opensource.org/licenses/mit-license.php.\n\nThis 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)."), wxDefaultPosition, wxDefaultSize, 0 ); - m_staticTextMain->Wrap( 400 ); - bSizer63->Add( m_staticTextMain, 0, wxALL, 5 ); + m_staticTextMain = new wxStaticText( this, wxID_ANY, wxT("Copyright © 2009-2010 Satoshi Nakamoto.\n\nThis is experimental software. Do not rely on it for actual financial transactions.\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)."), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticTextMain->Wrap( -1 ); + bSizer631->Add( m_staticTextMain, 0, wxALL, 5 ); - bSizer63->Add( 0, 0, 1, wxEXPAND, 5 ); + bSizer631->Add( 0, 0, 1, wxEXPAND, 5 ); - bSizer62->Add( bSizer63, 1, wxEXPAND, 5 ); + bSizer62->Add( bSizer631, 1, wxEXPAND, 5 ); bSizer60->Add( bSizer62, 1, wxEXPAND, 5 ); @@ -617,9 +541,11 @@ CAboutDialogBase::CAboutDialogBase( wxWindow* parent, wxWindowID id, const wxStr m_buttonOK = new wxButton( this, wxID_OK, wxT("OK"), wxDefaultPosition, wxSize( -1,-1 ), 0 ); bSizer61->Add( m_buttonOK, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); - bSizer60->Add( bSizer61, 0, wxALIGN_RIGHT|wxEXPAND, 5 ); + bSizer60->Add( bSizer61, 0, wxALIGN_RIGHT|wxEXPAND|wxRIGHT, 5 ); + + bSizer63->Add( bSizer60, 1, wxEXPAND|wxLEFT, 5 ); - this->SetSizer( bSizer60 ); + this->SetSizer( bSizer63 ); this->Layout(); // Connect Events diff --git a/uibase.h b/uibase.h index 97bb1bdc3c..faef982989 100644 --- a/uibase.h +++ b/uibase.h @@ -1,7 +1,6 @@ // 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. - /////////////////////////////////////////////////////////////////////////// // C++ code generated with wxFormBuilder (version Apr 16 2008) // http://www.wxformbuilder.org/ @@ -30,7 +29,6 @@ #include #include #include -#include #include #include #include @@ -119,12 +117,6 @@ class CMainFrameBase : public wxFrame wxStaticText* m_staticTextBalance; wxChoice* m_choiceFilter; - wxNotebook* m_notebook; - wxPanel* m_panel7; - wxPanel* m_panel9; - wxPanel* m_panel8; - wxPanel* m_panel10; - wxPanel* m_panel11; // Virtual event handlers, overide them in your derived class virtual void OnClose( wxCloseEvent& event ){ event.Skip(); } @@ -148,21 +140,14 @@ class CMainFrameBase : public wxFrame virtual void OnButtonCopy( wxCommandEvent& event ){ event.Skip(); } virtual void OnButtonChange( wxCommandEvent& event ){ event.Skip(); } virtual void OnListColBeginDrag( wxListEvent& event ){ event.Skip(); } - virtual void OnListItemActivatedAllTransactions( wxListEvent& event ){ event.Skip(); } + virtual void OnListItemActivated( wxListEvent& event ){ event.Skip(); } virtual void OnPaintListCtrl( wxPaintEvent& event ){ event.Skip(); } - virtual void OnListItemActivatedOrdersSent( wxListEvent& event ){ event.Skip(); } - virtual void OnListItemActivatedProductsSent( wxListEvent& event ){ event.Skip(); } - virtual void OnListItemActivatedOrdersReceived( wxListEvent& event ){ event.Skip(); } public: wxMenu* m_menuOptions; wxListCtrl* m_listCtrl; - wxListCtrl* m_listCtrlEscrows; - wxListCtrl* m_listCtrlOrdersSent; - wxListCtrl* m_listCtrlProductsSent; - wxListCtrl* m_listCtrlOrdersReceived; - CMainFrameBase( wxWindow* parent, wxWindowID id = wxID_MAINFRAME, const wxString& title = wxT("Bitcoin"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 727,484 ), long style = wxDEFAULT_FRAME_STYLE|wxRESIZE_BORDER|wxTAB_TRAVERSAL ); + CMainFrameBase( wxWindow* parent, wxWindowID id = wxID_MAINFRAME, const wxString& title = wxT("Bitcoin"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 712,484 ), long style = wxDEFAULT_FRAME_STYLE|wxRESIZE_BORDER|wxTAB_TRAVERSAL ); ~CMainFrameBase(); }; @@ -251,7 +236,7 @@ class CAboutDialogBase : public wxDialog private: protected: - + wxStaticBitmap* m_bitmap; wxStaticText* m_staticText40; @@ -266,7 +251,7 @@ class CAboutDialogBase : public wxDialog public: wxStaticText* m_staticTextVersion; - CAboutDialogBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxT("About Bitcoin"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 507,298 ), long style = wxDEFAULT_DIALOG_STYLE ); + CAboutDialogBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxT("About Bitcoin"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 532,329 ), long style = wxDEFAULT_DIALOG_STYLE ); ~CAboutDialogBase(); }; diff --git a/uiproject.fbp b/uiproject.fbp index 3c489ae633..c24f6962b9 100644 --- a/uiproject.fbp +++ b/uiproject.fbp @@ -18,7 +18,7 @@ 1 0 0 - + wxSYS_COLOUR_BTNFACE @@ -32,7 +32,7 @@ CMainFrameBase - 727,484 + 712,484 wxDEFAULT_FRAME_STYLE|wxRESIZE_BORDER Bitcoin @@ -824,9 +824,8 @@ 5 wxEXPAND 1 - + - 1 @@ -835,16 +834,16 @@ wxID_ANY - m_notebook - protected + m_listCtrl + public - + wxLC_NO_SORT_HEADER|wxLC_REPORT|wxLC_SORT_DESCENDING - + wxVSCROLL @@ -855,26 +854,114 @@ + + + + + OnListColBeginDrag + + + + + + + + + OnListItemActivated + + + + + + - - - + OnPaintListCtrl - - - All Transactions - 0 - + + + + + + + + + 1 + + + + 0 + wxID_ANY + + + CTxDetailsDialogBase + + 620,450 + wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER + + Transaction Details + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + bSizer64 + wxVERTICAL + none + + 5 + wxEXPAND + 1 + + + bSizer66 + wxVERTICAL + none + + 5 + wxALL|wxEXPAND + 1 + 1 @@ -884,18 +971,22 @@ wxID_ANY - m_panel7 + m_htmlWin protected + wxHW_SCROLLBAR_AUTO - wxTAB_TRAVERSAL + + + + @@ -916,117 +1007,46 @@ - - - bSizer157 - wxVERTICAL - none - - 5 - wxEXPAND|wxALL - 1 - - - - 1 - - - 0 - wxID_ANY - - - m_listCtrl - public - - - wxLC_NO_SORT_HEADER|wxLC_REPORT|wxLC_SORT_DESCENDING - - - - - wxVSCROLL - - - - - - - - - - - - - - - OnListColBeginDrag - - - - - - - - - OnListItemActivatedAllTransactions - - - - - - - - - - - - - OnPaintListCtrl - - - - - - - - - 5 - wxEXPAND - 1 + wxALIGN_RIGHT + 0 - bSizer_TabsForFutureUse - wxVERTICAL + bSizer65 + wxHORIZONTAL none 5 - wxEXPAND | wxALL - 1 - + wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND + 0 + + 0 1 - 1 - wxID_ANY + 0 + wxID_OK + OK - m_panel9 + m_buttonOK protected - + -1,-1 + - wxTAB_TRAVERSAL + + OnButtonOK @@ -1050,229 +1070,103 @@ - - - bSizer159 - wxVERTICAL - none - - 5 - wxALL|wxEXPAND - 1 - - - - 1 - - - 0 - wxID_ANY - - - m_listCtrlEscrows - public - - - wxLC_NO_SORT_HEADER|wxLC_REPORT - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxEXPAND | wxALL - 1 - - - - 1 - - - 1 - wxID_ANY - - - m_panel8 - protected - - - - - - - wxTAB_TRAVERSAL - - - - - - - - - - - - - - - - - - - - - - - - - - bSizer158 - wxVERTICAL - none - - 5 - wxALL|wxEXPAND - 1 - - - - 1 - - - 0 - wxID_ANY - - - m_listCtrlOrdersSent - public - - - wxLC_NO_SORT_HEADER|wxLC_REPORT - - - - - - - - - - - - - - - - - - - - - - - - - - - - - OnListItemActivatedOrdersSent - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + 1 + + + + 0 + wxID_ANY + + + COptionsDialogBase + + 540,360 + wxDEFAULT_DIALOG_STYLE + + Options + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + bSizer55 + wxVERTICAL + none + + 9 + wxEXPAND|wxALL + 1 + + + bSizer66 + wxHORIZONTAL + none 5 - wxEXPAND | wxALL - 1 - + wxEXPAND|wxRIGHT + 0 + + 1 - 1 + 0 wxID_ANY - m_panel10 + m_listBox protected - + 110,-1 + wxLB_NEEDED_SB|wxLB_SINGLE - wxTAB_TRAVERSAL + @@ -1283,6 +1177,8 @@ + OnListBox + @@ -1296,106 +1192,33 @@ - - - bSizer160 - wxVERTICAL - none - - 5 - wxALL|wxEXPAND - 1 - - - - 1 - - - 0 - wxID_ANY - - - m_listCtrlProductsSent - public - - - wxLC_NO_SORT_HEADER|wxLC_REPORT - - - - - - - - - - - - - - - - - - - - - - - - - - - - - OnListItemActivatedProductsSent - - - - - - - - - - - - - - - - - - - - - - 5 - wxEXPAND | wxALL + wxEXPAND|wxLEFT 1 - + 1 - 1 + 0 wxID_ANY - m_panel11 + m_scrolledWindow protected + 5 + 5 - wxTAB_TRAVERSAL + @@ -1421,14 +1244,14 @@ - bSizer161 + bSizer63 wxVERTICAL none 5 - wxALL|wxEXPAND - 1 - + wxEXPAND + 0 + 1 @@ -1438,447 +1261,15 @@ wxID_ANY - m_listCtrlOrdersReceived - public + m_panelMain + protected - wxLC_NO_SORT_HEADER|wxLC_REPORT - - - - - - - - - - - - - - - - - - - - - - - - - OnListItemActivatedOrdersReceived - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1 - - - - 0 - wxID_ANY - - - CTxDetailsDialogBase - - 620,450 - wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER - - Transaction Details - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - bSizer64 - wxVERTICAL - none - - 5 - wxEXPAND - 1 - - - bSizer66 - wxVERTICAL - none - - 5 - wxALL|wxEXPAND - 1 - - - - 1 - - - 0 - wxID_ANY - - - m_htmlWin - protected - - - wxHW_SCROLLBAR_AUTO - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALIGN_RIGHT - 0 - - - bSizer65 - wxHORIZONTAL - none - - 5 - wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND - 0 - - - - 0 - 1 - - - 0 - wxID_OK - OK - - - m_buttonOK - protected - - -1,-1 - - - - - - - OnButtonOK - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1 - - - - 0 - wxID_ANY - - - COptionsDialogBase - - 540,360 - wxDEFAULT_DIALOG_STYLE - - Options - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - bSizer55 - wxVERTICAL - none - - 9 - wxEXPAND|wxALL - 1 - - - bSizer66 - wxHORIZONTAL - none - - 5 - wxEXPAND|wxRIGHT - 0 - - - - - 1 - - - 0 - wxID_ANY - - - m_listBox - protected - - 110,-1 - wxLB_NEEDED_SB|wxLB_SINGLE - - - - - - - - - - - - - - - - OnListBox - - - - - - - - - - - - - - - - - - 5 - wxEXPAND|wxLEFT - 1 - - - - 1 - - - 0 - wxID_ANY - - - m_scrolledWindow - protected - - 5 - 5 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - bSizer63 - wxVERTICAL - none - - 5 - wxEXPAND - 0 - - - - 1 - - - 0 - wxID_ANY - - - m_panelMain - protected - - - - - - - wxTAB_TRAVERSAL + wxTAB_TRAVERSAL @@ -3165,7 +2556,7 @@ CAboutDialogBase - 507,298 + 532,329 wxDEFAULT_DIALOG_STYLE About Bitcoin @@ -3203,126 +2594,237 @@ - + - bSizer60 - wxVERTICAL + bSizer63 + wxHORIZONTAL none 5 - wxEXPAND + + 0 + + + xpm/about.xpm; Load From File + + 1 + + + 0 + wxID_ANY + + + m_bitmap + protected + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND|wxLEFT 1 - bSizer62 - wxHORIZONTAL + bSizer60 + wxVERTICAL none - - 5 - wxEXPAND - 0 - - 0 - protected - 60 - - 5 wxEXPAND 1 - bSizer63 - wxVERTICAL - none - - 5 - wxEXPAND - 0 - - 50 - protected - 0 - - + bSizer62 + wxHORIZONTAL + none 5 wxEXPAND - 0 + 1 - bSizer64 - wxHORIZONTAL + bSizer631 + wxVERTICAL none 5 - wxALIGN_BOTTOM|wxTOP|wxBOTTOM|wxLEFT + wxEXPAND 0 - - - - 1 - - Tahoma,90,92,10,74,0 - 0 - wxID_ANY - Bitcoin - + + 65 + protected + 0 + + + + 5 + wxEXPAND + 0 + - m_staticText40 + bSizer64 + wxHORIZONTAL + none + + 5 + wxALIGN_BOTTOM|wxTOP|wxBOTTOM|wxLEFT + 0 + + + + 1 + + Tahoma,90,92,10,74,0 + 0 + wxID_ANY + Bitcoin + + + m_staticText40 + protected + + + + + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALIGN_BOTTOM|wxTOP|wxBOTTOM|wxRIGHT + 0 + + + + 1 + + Tahoma,90,90,10,74,0 + 0 + wxID_ANY + version + + + m_staticTextVersion + public + + + + + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND + 0 + + 4 protected - - - - - - - - - -1 - - - - - - - - - - - - - - - - - - - - - - - + 0 5 - wxALIGN_BOTTOM|wxTOP|wxBOTTOM|wxRIGHT + wxALL 0 1 - Tahoma,90,90,10,74,0 + 0 wxID_ANY - version + Copyright © 2009-2010 Satoshi Nakamoto. This is experimental software. Do not rely on it for actual financial transactions. 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). - m_staticTextVersion - public + m_staticTextMain + protected @@ -3357,44 +2859,66 @@ + + 5 + wxEXPAND + 1 + + 0 + protected + 0 + + + + + + 5 + wxALIGN_RIGHT|wxEXPAND|wxRIGHT + 0 + + + bSizer61 + wxHORIZONTAL + none 5 wxEXPAND - 0 + 1 - 4 + 0 protected 0 5 - wxALL + wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND 0 - + + 0 1 0 - wxID_ANY - Copyright © 2009 Satoshi Nakamoto. This is experimental software. Do not rely on it for actual financial transactions. 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). + wxID_OK + OK - m_staticTextMain + m_buttonOK protected - + -1,-1 - 400 + OnButtonOK @@ -3420,96 +2944,13 @@ - - 5 - wxEXPAND - 1 - - 0 - protected - 0 - - - - - - - - 5 - wxALIGN_RIGHT|wxEXPAND - 0 - - - bSizer61 - wxHORIZONTAL - none - - 5 - wxEXPAND - 1 - - 0 - protected - 0 - - - - 5 - wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND - 0 - - - - 0 - 1 - - - 0 - wxID_OK - OK - - - m_buttonOK - protected - - -1,-1 - - - - - - - OnButtonOK - - - - - - - - - - - - - - - - - - - - - - - - + diff --git a/xpm/about.xpm b/xpm/about.xpm new file mode 100644 index 0000000000..3fa868ca76 --- /dev/null +++ b/xpm/about.xpm @@ -0,0 +1,665 @@ +// 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<<<<<<<<<<<>>>>>>>>>>>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````````````''''''''''''{{{{{{{{{{{{" +}; -- cgit v1.2.3 From a43c00c56944ca69dcf319cd85754dc0fb1f2260 Mon Sep 17 00:00:00 2001 From: sirius-m Date: Thu, 4 Feb 2010 15:31:46 +0000 Subject: Added some basic IPC functionality using wxServer, wxClient and wxConnection. Added the -blockamount command line option for an example of usage. --- headers.h | 3 +++ ipc.cpp | 33 +++++++++++++++++++++++++++++++++ ipc.h | 28 ++++++++++++++++++++++++++++ makefile | 4 +++- makefile.unix.wx2.8 | 5 +++-- makefile.unix.wx2.9 | 7 ++++--- ui.cpp | 29 +++++++++++++++++++++++++++-- 7 files changed, 101 insertions(+), 8 deletions(-) create mode 100644 ipc.cpp create mode 100644 ipc.h diff --git a/headers.h b/headers.h index 45be4b65d1..fb5e3eccc3 100644 --- a/headers.h +++ b/headers.h @@ -24,6 +24,8 @@ #include #include #include +#include +#include #include #include #include @@ -102,6 +104,7 @@ using namespace boost; #include "market.h" #include "uibase.h" #include "ui.h" +#include "ipc.h" #include "xpm/addressbook16.xpm" #include "xpm/addressbook20.xpm" diff --git a/ipc.cpp b/ipc.cpp new file mode 100644 index 0000000000..86e57674e2 --- /dev/null +++ b/ipc.cpp @@ -0,0 +1,33 @@ +/* + * Inter-process calling functionality + */ + +#include "headers.h" + +wxConnectionBase * CServer::OnAcceptConnection (const wxString &topic) { + return new CServerConnection; +} + +wxConnectionBase * CClient::OnMakeConnection () { + return new CClientConnection; +} + +// For request based handling +const void * CServerConnection::OnRequest (const wxString &topic, const wxString &item, size_t *size, wxIPCFormat format) { + const char * output; + + if (item == "blockamount") { + stringstream stream; + stream << nBestHeight + 1; + output = stream.str().c_str(); + } + else + output = "Unknown identifier"; + + return output; +} + +// For event based handling +bool CClientConnection::OnAdvise (const wxString &topic, const wxString &item, const void *data, size_t size, wxIPCFormat format) { + return false; +} \ No newline at end of file diff --git a/ipc.h b/ipc.h new file mode 100644 index 0000000000..777d31b2b7 --- /dev/null +++ b/ipc.h @@ -0,0 +1,28 @@ +#ifndef _IPC_H +#define _IPC_H + +class CServer : public wxServer { +public: + wxConnectionBase * OnAcceptConnection (const wxString &topic); +}; + +class CClient : public wxClient { +public: + wxConnectionBase * OnMakeConnection (); +}; + +class CServerConnection : public wxConnection { +public: + const void * OnRequest (const wxString &topic, const wxString &item, size_t *size, wxIPCFormat format); +}; + +class CClientConnection : public wxConnection { +public: + CClientConnection() : wxConnection() {} + ~CClientConnection() {} + + bool OnAdvise (const wxString &topic, const wxString &item, const void *data, size_t size, wxIPCFormat format); +}; + +#endif /* _IPC_H */ + diff --git a/makefile b/makefile index 0dd622106e..efdfc7aeeb 100644 --- a/makefile +++ b/makefile @@ -67,10 +67,12 @@ obj/irc.o: irc.cpp $(HEADERS) obj/ui_res.o: ui.rc rc/bitcoin.ico rc/check.ico rc/send16.bmp rc/send16mask.bmp rc/send16masknoshadow.bmp rc/send20.bmp rc/send20mask.bmp rc/addressbook16.bmp rc/addressbook16mask.bmp rc/addressbook20.bmp rc/addressbook20mask.bmp windres $(WXDEFS) $(INCLUDEPATHS) -o $@ -i $< +obj/ipc.o: ipc.cpp $(HEADERS) + g++ -c $(CFLAGS) -o $@ $< OBJS=obj/util.o obj/script.o obj/db.o obj/net.o obj/main.o obj/market.o \ - obj/ui.o obj/uibase.o obj/sha.o obj/irc.o obj/ui_res.o + obj/ui.o obj/uibase.o obj/sha.o obj/irc.o obj/ui_res.o obj/ipc.o bitcoin.exe: headers.h.gch $(OBJS) -kill /f bitcoin.exe diff --git a/makefile.unix.wx2.8 b/makefile.unix.wx2.8 index b9826d6ccb..899ce29543 100644 --- a/makefile.unix.wx2.8 +++ b/makefile.unix.wx2.8 @@ -75,11 +75,12 @@ obj/sha.o: sha.cpp sha.h obj/irc.o: irc.cpp $(HEADERS) g++ -c $(CFLAGS) -o $@ $< - +obj/ipc.o: ipc.cpp $(HEADERS) + g++ -c $(CFLAGS) -o $@ $< OBJS=obj/util.o obj/script.o obj/db.o obj/net.o obj/main.o obj/market.o \ - obj/ui.o obj/uibase.o obj/sha.o obj/irc.o + obj/ui.o obj/uibase.o obj/sha.o obj/irc.o obj/ipc.o bitcoin: headers.h.gch $(OBJS) g++ $(CFLAGS) -o $@ $(LIBPATHS) $(OBJS) $(LIBS) diff --git a/makefile.unix.wx2.9 b/makefile.unix.wx2.9 index 81dcbd70e9..d2c4eb5ea1 100644 --- a/makefile.unix.wx2.9 +++ b/makefile.unix.wx2.9 @@ -31,7 +31,7 @@ LIBS= \ -l wx_gtk2u$(D)-2.9 \ -Wl,-Bdynamic \ -l crypto \ - -l gtk-x11-2.0 -l gthread-2.0 -l SM + -l gtk-x11-2.0 -l gthread-2.0 -l SM \ WXDEFS=-D__WXGTK__ -DNOPCH CFLAGS=-O0 -Wno-invalid-offsetof -Wformat $(DEBUGFLAGS) $(WXDEFS) $(INCLUDEPATHS) @@ -75,11 +75,12 @@ obj/sha.o: sha.cpp sha.h obj/irc.o: irc.cpp $(HEADERS) g++ -c $(CFLAGS) -o $@ $< - +obj/ipc.o: ipc.cpp $(HEADERS) + g++ -c $(CFLAGS) -o $@ $< OBJS=obj/util.o obj/script.o obj/db.o obj/net.o obj/main.o obj/market.o \ - obj/ui.o obj/uibase.o obj/sha.o obj/irc.o + obj/ui.o obj/uibase.o obj/sha.o obj/irc.o obj/ipc.o bitcoin: headers.h.gch $(OBJS) g++ $(CFLAGS) -o $@ $(LIBPATHS) $(OBJS) $(LIBS) diff --git a/ui.cpp b/ui.cpp index 5d93ad227f..1f22170302 100644 --- a/ui.cpp +++ b/ui.cpp @@ -21,6 +21,7 @@ DEFINE_EVENT_TYPE(wxEVT_REPLY3) CMainFrame* pframeMain = NULL; CMyTaskBarIcon* ptaskbaricon = NULL; +CServer* pserver = NULL; map mapAddressBook; bool fRandSendTest = false; void RandSend(); @@ -384,6 +385,8 @@ CMainFrame::~CMainFrame() pframeMain = NULL; delete ptaskbaricon; ptaskbaricon = NULL; + delete pserver; + pserver = NULL; } void ExitTimeout(void* parg) @@ -1687,8 +1690,8 @@ CAboutDialog::CAboutDialog(wxWindow* parent) : CAboutDialogBase(parent) #if !wxUSE_UNICODE // Workaround until upgrade to wxWidgets supporting UTF-8 wxString str = m_staticTextMain->GetLabel(); - if (str.Find('Â') != wxNOT_FOUND) - str.Remove(str.Find('Â'), 1); + if (str.Find('�') != wxNOT_FOUND) + str.Remove(str.Find('�'), 1); m_staticTextMain->SetLabel(str); #endif #ifndef __WXMSW__ @@ -3548,6 +3551,26 @@ bool CMyApp::OnInit2() return false; } + if (mapArgs.count("-blockamount")) { + CClient client; + wxString hostname = "localhost"; + wxString server = GetDataDir() + "service"; + CClientConnection * pconnection = (CClientConnection *)client.MakeConnection(hostname, server, "ipc test"); + string output = ""; + if (pconnection) { + char * pbuffer = (char *)pconnection->Request("blockamount"); + while (*pbuffer != '\n') { + output += *pbuffer; + pbuffer++; + } + } + else { + output = "Cannot access Bitcoin. Are you sure the program is running?\n"; + } + fprintf(stderr, "%s", output.c_str()); + return false; + } + if (mapArgs.count("-datadir")) strlcpy(pszSetDataDir, mapArgs["-datadir"].c_str(), sizeof(pszSetDataDir)); @@ -3755,6 +3778,8 @@ bool CMyApp::OnInit2() if (fFirstRun) SetStartOnSystemStartup(true); + pserver = new CServer; + pserver->Create(GetDataDir() + "service"); // // Tests -- cgit v1.2.3 From 082e725b33addda32ec4b31eba60b47f0dc6879f Mon Sep 17 00:00:00 2001 From: sirius-m Date: Thu, 4 Feb 2010 15:31:46 +0000 Subject: Added some basic IPC functionality using wxServer, wxClient and wxConnection. Added the -blockamount command line option for an example of usage. git-svn-id: https://bitcoin.svn.sourceforge.net/svnroot/bitcoin/trunk@56 1a98c847-1fd6-4fd8-948a-caf3550aa51b --- headers.h | 3 +++ ipc.cpp | 33 +++++++++++++++++++++++++++++++++ ipc.h | 28 ++++++++++++++++++++++++++++ makefile | 4 +++- makefile.unix.wx2.8 | 5 +++-- makefile.unix.wx2.9 | 7 ++++--- ui.cpp | 29 +++++++++++++++++++++++++++-- 7 files changed, 101 insertions(+), 8 deletions(-) create mode 100644 ipc.cpp create mode 100644 ipc.h diff --git a/headers.h b/headers.h index 45be4b65d1..fb5e3eccc3 100644 --- a/headers.h +++ b/headers.h @@ -24,6 +24,8 @@ #include #include #include +#include +#include #include #include #include @@ -102,6 +104,7 @@ using namespace boost; #include "market.h" #include "uibase.h" #include "ui.h" +#include "ipc.h" #include "xpm/addressbook16.xpm" #include "xpm/addressbook20.xpm" diff --git a/ipc.cpp b/ipc.cpp new file mode 100644 index 0000000000..86e57674e2 --- /dev/null +++ b/ipc.cpp @@ -0,0 +1,33 @@ +/* + * Inter-process calling functionality + */ + +#include "headers.h" + +wxConnectionBase * CServer::OnAcceptConnection (const wxString &topic) { + return new CServerConnection; +} + +wxConnectionBase * CClient::OnMakeConnection () { + return new CClientConnection; +} + +// For request based handling +const void * CServerConnection::OnRequest (const wxString &topic, const wxString &item, size_t *size, wxIPCFormat format) { + const char * output; + + if (item == "blockamount") { + stringstream stream; + stream << nBestHeight + 1; + output = stream.str().c_str(); + } + else + output = "Unknown identifier"; + + return output; +} + +// For event based handling +bool CClientConnection::OnAdvise (const wxString &topic, const wxString &item, const void *data, size_t size, wxIPCFormat format) { + return false; +} \ No newline at end of file diff --git a/ipc.h b/ipc.h new file mode 100644 index 0000000000..777d31b2b7 --- /dev/null +++ b/ipc.h @@ -0,0 +1,28 @@ +#ifndef _IPC_H +#define _IPC_H + +class CServer : public wxServer { +public: + wxConnectionBase * OnAcceptConnection (const wxString &topic); +}; + +class CClient : public wxClient { +public: + wxConnectionBase * OnMakeConnection (); +}; + +class CServerConnection : public wxConnection { +public: + const void * OnRequest (const wxString &topic, const wxString &item, size_t *size, wxIPCFormat format); +}; + +class CClientConnection : public wxConnection { +public: + CClientConnection() : wxConnection() {} + ~CClientConnection() {} + + bool OnAdvise (const wxString &topic, const wxString &item, const void *data, size_t size, wxIPCFormat format); +}; + +#endif /* _IPC_H */ + diff --git a/makefile b/makefile index 0dd622106e..efdfc7aeeb 100644 --- a/makefile +++ b/makefile @@ -67,10 +67,12 @@ obj/irc.o: irc.cpp $(HEADERS) obj/ui_res.o: ui.rc rc/bitcoin.ico rc/check.ico rc/send16.bmp rc/send16mask.bmp rc/send16masknoshadow.bmp rc/send20.bmp rc/send20mask.bmp rc/addressbook16.bmp rc/addressbook16mask.bmp rc/addressbook20.bmp rc/addressbook20mask.bmp windres $(WXDEFS) $(INCLUDEPATHS) -o $@ -i $< +obj/ipc.o: ipc.cpp $(HEADERS) + g++ -c $(CFLAGS) -o $@ $< OBJS=obj/util.o obj/script.o obj/db.o obj/net.o obj/main.o obj/market.o \ - obj/ui.o obj/uibase.o obj/sha.o obj/irc.o obj/ui_res.o + obj/ui.o obj/uibase.o obj/sha.o obj/irc.o obj/ui_res.o obj/ipc.o bitcoin.exe: headers.h.gch $(OBJS) -kill /f bitcoin.exe diff --git a/makefile.unix.wx2.8 b/makefile.unix.wx2.8 index b9826d6ccb..899ce29543 100644 --- a/makefile.unix.wx2.8 +++ b/makefile.unix.wx2.8 @@ -75,11 +75,12 @@ obj/sha.o: sha.cpp sha.h obj/irc.o: irc.cpp $(HEADERS) g++ -c $(CFLAGS) -o $@ $< - +obj/ipc.o: ipc.cpp $(HEADERS) + g++ -c $(CFLAGS) -o $@ $< OBJS=obj/util.o obj/script.o obj/db.o obj/net.o obj/main.o obj/market.o \ - obj/ui.o obj/uibase.o obj/sha.o obj/irc.o + obj/ui.o obj/uibase.o obj/sha.o obj/irc.o obj/ipc.o bitcoin: headers.h.gch $(OBJS) g++ $(CFLAGS) -o $@ $(LIBPATHS) $(OBJS) $(LIBS) diff --git a/makefile.unix.wx2.9 b/makefile.unix.wx2.9 index 81dcbd70e9..d2c4eb5ea1 100644 --- a/makefile.unix.wx2.9 +++ b/makefile.unix.wx2.9 @@ -31,7 +31,7 @@ LIBS= \ -l wx_gtk2u$(D)-2.9 \ -Wl,-Bdynamic \ -l crypto \ - -l gtk-x11-2.0 -l gthread-2.0 -l SM + -l gtk-x11-2.0 -l gthread-2.0 -l SM \ WXDEFS=-D__WXGTK__ -DNOPCH CFLAGS=-O0 -Wno-invalid-offsetof -Wformat $(DEBUGFLAGS) $(WXDEFS) $(INCLUDEPATHS) @@ -75,11 +75,12 @@ obj/sha.o: sha.cpp sha.h obj/irc.o: irc.cpp $(HEADERS) g++ -c $(CFLAGS) -o $@ $< - +obj/ipc.o: ipc.cpp $(HEADERS) + g++ -c $(CFLAGS) -o $@ $< OBJS=obj/util.o obj/script.o obj/db.o obj/net.o obj/main.o obj/market.o \ - obj/ui.o obj/uibase.o obj/sha.o obj/irc.o + obj/ui.o obj/uibase.o obj/sha.o obj/irc.o obj/ipc.o bitcoin: headers.h.gch $(OBJS) g++ $(CFLAGS) -o $@ $(LIBPATHS) $(OBJS) $(LIBS) diff --git a/ui.cpp b/ui.cpp index 5d93ad227f..1f22170302 100644 --- a/ui.cpp +++ b/ui.cpp @@ -21,6 +21,7 @@ DEFINE_EVENT_TYPE(wxEVT_REPLY3) CMainFrame* pframeMain = NULL; CMyTaskBarIcon* ptaskbaricon = NULL; +CServer* pserver = NULL; map mapAddressBook; bool fRandSendTest = false; void RandSend(); @@ -384,6 +385,8 @@ CMainFrame::~CMainFrame() pframeMain = NULL; delete ptaskbaricon; ptaskbaricon = NULL; + delete pserver; + pserver = NULL; } void ExitTimeout(void* parg) @@ -1687,8 +1690,8 @@ CAboutDialog::CAboutDialog(wxWindow* parent) : CAboutDialogBase(parent) #if !wxUSE_UNICODE // Workaround until upgrade to wxWidgets supporting UTF-8 wxString str = m_staticTextMain->GetLabel(); - if (str.Find('Â') != wxNOT_FOUND) - str.Remove(str.Find('Â'), 1); + if (str.Find('�') != wxNOT_FOUND) + str.Remove(str.Find('�'), 1); m_staticTextMain->SetLabel(str); #endif #ifndef __WXMSW__ @@ -3548,6 +3551,26 @@ bool CMyApp::OnInit2() return false; } + if (mapArgs.count("-blockamount")) { + CClient client; + wxString hostname = "localhost"; + wxString server = GetDataDir() + "service"; + CClientConnection * pconnection = (CClientConnection *)client.MakeConnection(hostname, server, "ipc test"); + string output = ""; + if (pconnection) { + char * pbuffer = (char *)pconnection->Request("blockamount"); + while (*pbuffer != '\n') { + output += *pbuffer; + pbuffer++; + } + } + else { + output = "Cannot access Bitcoin. Are you sure the program is running?\n"; + } + fprintf(stderr, "%s", output.c_str()); + return false; + } + if (mapArgs.count("-datadir")) strlcpy(pszSetDataDir, mapArgs["-datadir"].c_str(), sizeof(pszSetDataDir)); @@ -3755,6 +3778,8 @@ bool CMyApp::OnInit2() if (fFirstRun) SetStartOnSystemStartup(true); + pserver = new CServer; + pserver->Create(GetDataDir() + "service"); // // Tests -- cgit v1.2.3 From 1c5d5e58c67e63fd83afd945c7db1190de62514a Mon Sep 17 00:00:00 2001 From: s_nakamoto Date: Wed, 10 Feb 2010 19:33:04 +0000 Subject: revert revision 56, going in different direction with boost::asio and JSON-RPC --- headers.h | 3 --- ipc.cpp | 33 --------------------------------- ipc.h | 28 ---------------------------- makefile | 4 +--- makefile.unix.wx2.8 | 5 ++--- makefile.unix.wx2.9 | 7 +++---- ui.cpp | 29 ++--------------------------- 7 files changed, 8 insertions(+), 101 deletions(-) delete mode 100644 ipc.cpp delete mode 100644 ipc.h diff --git a/headers.h b/headers.h index fb5e3eccc3..45be4b65d1 100644 --- a/headers.h +++ b/headers.h @@ -24,8 +24,6 @@ #include #include #include -#include -#include #include #include #include @@ -104,7 +102,6 @@ using namespace boost; #include "market.h" #include "uibase.h" #include "ui.h" -#include "ipc.h" #include "xpm/addressbook16.xpm" #include "xpm/addressbook20.xpm" diff --git a/ipc.cpp b/ipc.cpp deleted file mode 100644 index 86e57674e2..0000000000 --- a/ipc.cpp +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Inter-process calling functionality - */ - -#include "headers.h" - -wxConnectionBase * CServer::OnAcceptConnection (const wxString &topic) { - return new CServerConnection; -} - -wxConnectionBase * CClient::OnMakeConnection () { - return new CClientConnection; -} - -// For request based handling -const void * CServerConnection::OnRequest (const wxString &topic, const wxString &item, size_t *size, wxIPCFormat format) { - const char * output; - - if (item == "blockamount") { - stringstream stream; - stream << nBestHeight + 1; - output = stream.str().c_str(); - } - else - output = "Unknown identifier"; - - return output; -} - -// For event based handling -bool CClientConnection::OnAdvise (const wxString &topic, const wxString &item, const void *data, size_t size, wxIPCFormat format) { - return false; -} \ No newline at end of file diff --git a/ipc.h b/ipc.h deleted file mode 100644 index 777d31b2b7..0000000000 --- a/ipc.h +++ /dev/null @@ -1,28 +0,0 @@ -#ifndef _IPC_H -#define _IPC_H - -class CServer : public wxServer { -public: - wxConnectionBase * OnAcceptConnection (const wxString &topic); -}; - -class CClient : public wxClient { -public: - wxConnectionBase * OnMakeConnection (); -}; - -class CServerConnection : public wxConnection { -public: - const void * OnRequest (const wxString &topic, const wxString &item, size_t *size, wxIPCFormat format); -}; - -class CClientConnection : public wxConnection { -public: - CClientConnection() : wxConnection() {} - ~CClientConnection() {} - - bool OnAdvise (const wxString &topic, const wxString &item, const void *data, size_t size, wxIPCFormat format); -}; - -#endif /* _IPC_H */ - diff --git a/makefile b/makefile index efdfc7aeeb..0dd622106e 100644 --- a/makefile +++ b/makefile @@ -67,12 +67,10 @@ obj/irc.o: irc.cpp $(HEADERS) obj/ui_res.o: ui.rc rc/bitcoin.ico rc/check.ico rc/send16.bmp rc/send16mask.bmp rc/send16masknoshadow.bmp rc/send20.bmp rc/send20mask.bmp rc/addressbook16.bmp rc/addressbook16mask.bmp rc/addressbook20.bmp rc/addressbook20mask.bmp windres $(WXDEFS) $(INCLUDEPATHS) -o $@ -i $< -obj/ipc.o: ipc.cpp $(HEADERS) - g++ -c $(CFLAGS) -o $@ $< OBJS=obj/util.o obj/script.o obj/db.o obj/net.o obj/main.o obj/market.o \ - obj/ui.o obj/uibase.o obj/sha.o obj/irc.o obj/ui_res.o obj/ipc.o + obj/ui.o obj/uibase.o obj/sha.o obj/irc.o obj/ui_res.o bitcoin.exe: headers.h.gch $(OBJS) -kill /f bitcoin.exe diff --git a/makefile.unix.wx2.8 b/makefile.unix.wx2.8 index 899ce29543..b9826d6ccb 100644 --- a/makefile.unix.wx2.8 +++ b/makefile.unix.wx2.8 @@ -75,12 +75,11 @@ obj/sha.o: sha.cpp sha.h obj/irc.o: irc.cpp $(HEADERS) g++ -c $(CFLAGS) -o $@ $< -obj/ipc.o: ipc.cpp $(HEADERS) - g++ -c $(CFLAGS) -o $@ $< + OBJS=obj/util.o obj/script.o obj/db.o obj/net.o obj/main.o obj/market.o \ - obj/ui.o obj/uibase.o obj/sha.o obj/irc.o obj/ipc.o + obj/ui.o obj/uibase.o obj/sha.o obj/irc.o bitcoin: headers.h.gch $(OBJS) g++ $(CFLAGS) -o $@ $(LIBPATHS) $(OBJS) $(LIBS) diff --git a/makefile.unix.wx2.9 b/makefile.unix.wx2.9 index d2c4eb5ea1..81dcbd70e9 100644 --- a/makefile.unix.wx2.9 +++ b/makefile.unix.wx2.9 @@ -31,7 +31,7 @@ LIBS= \ -l wx_gtk2u$(D)-2.9 \ -Wl,-Bdynamic \ -l crypto \ - -l gtk-x11-2.0 -l gthread-2.0 -l SM \ + -l gtk-x11-2.0 -l gthread-2.0 -l SM WXDEFS=-D__WXGTK__ -DNOPCH CFLAGS=-O0 -Wno-invalid-offsetof -Wformat $(DEBUGFLAGS) $(WXDEFS) $(INCLUDEPATHS) @@ -75,12 +75,11 @@ obj/sha.o: sha.cpp sha.h obj/irc.o: irc.cpp $(HEADERS) g++ -c $(CFLAGS) -o $@ $< -obj/ipc.o: ipc.cpp $(HEADERS) - g++ -c $(CFLAGS) -o $@ $< + OBJS=obj/util.o obj/script.o obj/db.o obj/net.o obj/main.o obj/market.o \ - obj/ui.o obj/uibase.o obj/sha.o obj/irc.o obj/ipc.o + obj/ui.o obj/uibase.o obj/sha.o obj/irc.o bitcoin: headers.h.gch $(OBJS) g++ $(CFLAGS) -o $@ $(LIBPATHS) $(OBJS) $(LIBS) diff --git a/ui.cpp b/ui.cpp index 1f22170302..5d93ad227f 100644 --- a/ui.cpp +++ b/ui.cpp @@ -21,7 +21,6 @@ DEFINE_EVENT_TYPE(wxEVT_REPLY3) CMainFrame* pframeMain = NULL; CMyTaskBarIcon* ptaskbaricon = NULL; -CServer* pserver = NULL; map mapAddressBook; bool fRandSendTest = false; void RandSend(); @@ -385,8 +384,6 @@ CMainFrame::~CMainFrame() pframeMain = NULL; delete ptaskbaricon; ptaskbaricon = NULL; - delete pserver; - pserver = NULL; } void ExitTimeout(void* parg) @@ -1690,8 +1687,8 @@ CAboutDialog::CAboutDialog(wxWindow* parent) : CAboutDialogBase(parent) #if !wxUSE_UNICODE // Workaround until upgrade to wxWidgets supporting UTF-8 wxString str = m_staticTextMain->GetLabel(); - if (str.Find('�') != wxNOT_FOUND) - str.Remove(str.Find('�'), 1); + if (str.Find('Â') != wxNOT_FOUND) + str.Remove(str.Find('Â'), 1); m_staticTextMain->SetLabel(str); #endif #ifndef __WXMSW__ @@ -3551,26 +3548,6 @@ bool CMyApp::OnInit2() return false; } - if (mapArgs.count("-blockamount")) { - CClient client; - wxString hostname = "localhost"; - wxString server = GetDataDir() + "service"; - CClientConnection * pconnection = (CClientConnection *)client.MakeConnection(hostname, server, "ipc test"); - string output = ""; - if (pconnection) { - char * pbuffer = (char *)pconnection->Request("blockamount"); - while (*pbuffer != '\n') { - output += *pbuffer; - pbuffer++; - } - } - else { - output = "Cannot access Bitcoin. Are you sure the program is running?\n"; - } - fprintf(stderr, "%s", output.c_str()); - return false; - } - if (mapArgs.count("-datadir")) strlcpy(pszSetDataDir, mapArgs["-datadir"].c_str(), sizeof(pszSetDataDir)); @@ -3778,8 +3755,6 @@ bool CMyApp::OnInit2() if (fFirstRun) SetStartOnSystemStartup(true); - pserver = new CServer; - pserver->Create(GetDataDir() + "service"); // // Tests -- cgit v1.2.3 From c41226d847c7d32ade7f02c0d53c85b0800fc71b Mon Sep 17 00:00:00 2001 From: s_nakamoto Date: Wed, 10 Feb 2010 19:33:04 +0000 Subject: revert revision 56, going in different direction with boost::asio and JSON-RPC git-svn-id: https://bitcoin.svn.sourceforge.net/svnroot/bitcoin/trunk@57 1a98c847-1fd6-4fd8-948a-caf3550aa51b --- headers.h | 3 --- ipc.cpp | 33 --------------------------------- ipc.h | 28 ---------------------------- makefile | 4 +--- makefile.unix.wx2.8 | 5 ++--- makefile.unix.wx2.9 | 7 +++---- ui.cpp | 29 ++--------------------------- 7 files changed, 8 insertions(+), 101 deletions(-) delete mode 100644 ipc.cpp delete mode 100644 ipc.h diff --git a/headers.h b/headers.h index fb5e3eccc3..45be4b65d1 100644 --- a/headers.h +++ b/headers.h @@ -24,8 +24,6 @@ #include #include #include -#include -#include #include #include #include @@ -104,7 +102,6 @@ using namespace boost; #include "market.h" #include "uibase.h" #include "ui.h" -#include "ipc.h" #include "xpm/addressbook16.xpm" #include "xpm/addressbook20.xpm" diff --git a/ipc.cpp b/ipc.cpp deleted file mode 100644 index 86e57674e2..0000000000 --- a/ipc.cpp +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Inter-process calling functionality - */ - -#include "headers.h" - -wxConnectionBase * CServer::OnAcceptConnection (const wxString &topic) { - return new CServerConnection; -} - -wxConnectionBase * CClient::OnMakeConnection () { - return new CClientConnection; -} - -// For request based handling -const void * CServerConnection::OnRequest (const wxString &topic, const wxString &item, size_t *size, wxIPCFormat format) { - const char * output; - - if (item == "blockamount") { - stringstream stream; - stream << nBestHeight + 1; - output = stream.str().c_str(); - } - else - output = "Unknown identifier"; - - return output; -} - -// For event based handling -bool CClientConnection::OnAdvise (const wxString &topic, const wxString &item, const void *data, size_t size, wxIPCFormat format) { - return false; -} \ No newline at end of file diff --git a/ipc.h b/ipc.h deleted file mode 100644 index 777d31b2b7..0000000000 --- a/ipc.h +++ /dev/null @@ -1,28 +0,0 @@ -#ifndef _IPC_H -#define _IPC_H - -class CServer : public wxServer { -public: - wxConnectionBase * OnAcceptConnection (const wxString &topic); -}; - -class CClient : public wxClient { -public: - wxConnectionBase * OnMakeConnection (); -}; - -class CServerConnection : public wxConnection { -public: - const void * OnRequest (const wxString &topic, const wxString &item, size_t *size, wxIPCFormat format); -}; - -class CClientConnection : public wxConnection { -public: - CClientConnection() : wxConnection() {} - ~CClientConnection() {} - - bool OnAdvise (const wxString &topic, const wxString &item, const void *data, size_t size, wxIPCFormat format); -}; - -#endif /* _IPC_H */ - diff --git a/makefile b/makefile index efdfc7aeeb..0dd622106e 100644 --- a/makefile +++ b/makefile @@ -67,12 +67,10 @@ obj/irc.o: irc.cpp $(HEADERS) obj/ui_res.o: ui.rc rc/bitcoin.ico rc/check.ico rc/send16.bmp rc/send16mask.bmp rc/send16masknoshadow.bmp rc/send20.bmp rc/send20mask.bmp rc/addressbook16.bmp rc/addressbook16mask.bmp rc/addressbook20.bmp rc/addressbook20mask.bmp windres $(WXDEFS) $(INCLUDEPATHS) -o $@ -i $< -obj/ipc.o: ipc.cpp $(HEADERS) - g++ -c $(CFLAGS) -o $@ $< OBJS=obj/util.o obj/script.o obj/db.o obj/net.o obj/main.o obj/market.o \ - obj/ui.o obj/uibase.o obj/sha.o obj/irc.o obj/ui_res.o obj/ipc.o + obj/ui.o obj/uibase.o obj/sha.o obj/irc.o obj/ui_res.o bitcoin.exe: headers.h.gch $(OBJS) -kill /f bitcoin.exe diff --git a/makefile.unix.wx2.8 b/makefile.unix.wx2.8 index 899ce29543..b9826d6ccb 100644 --- a/makefile.unix.wx2.8 +++ b/makefile.unix.wx2.8 @@ -75,12 +75,11 @@ obj/sha.o: sha.cpp sha.h obj/irc.o: irc.cpp $(HEADERS) g++ -c $(CFLAGS) -o $@ $< -obj/ipc.o: ipc.cpp $(HEADERS) - g++ -c $(CFLAGS) -o $@ $< + OBJS=obj/util.o obj/script.o obj/db.o obj/net.o obj/main.o obj/market.o \ - obj/ui.o obj/uibase.o obj/sha.o obj/irc.o obj/ipc.o + obj/ui.o obj/uibase.o obj/sha.o obj/irc.o bitcoin: headers.h.gch $(OBJS) g++ $(CFLAGS) -o $@ $(LIBPATHS) $(OBJS) $(LIBS) diff --git a/makefile.unix.wx2.9 b/makefile.unix.wx2.9 index d2c4eb5ea1..81dcbd70e9 100644 --- a/makefile.unix.wx2.9 +++ b/makefile.unix.wx2.9 @@ -31,7 +31,7 @@ LIBS= \ -l wx_gtk2u$(D)-2.9 \ -Wl,-Bdynamic \ -l crypto \ - -l gtk-x11-2.0 -l gthread-2.0 -l SM \ + -l gtk-x11-2.0 -l gthread-2.0 -l SM WXDEFS=-D__WXGTK__ -DNOPCH CFLAGS=-O0 -Wno-invalid-offsetof -Wformat $(DEBUGFLAGS) $(WXDEFS) $(INCLUDEPATHS) @@ -75,12 +75,11 @@ obj/sha.o: sha.cpp sha.h obj/irc.o: irc.cpp $(HEADERS) g++ -c $(CFLAGS) -o $@ $< -obj/ipc.o: ipc.cpp $(HEADERS) - g++ -c $(CFLAGS) -o $@ $< + OBJS=obj/util.o obj/script.o obj/db.o obj/net.o obj/main.o obj/market.o \ - obj/ui.o obj/uibase.o obj/sha.o obj/irc.o obj/ipc.o + obj/ui.o obj/uibase.o obj/sha.o obj/irc.o bitcoin: headers.h.gch $(OBJS) g++ $(CFLAGS) -o $@ $(LIBPATHS) $(OBJS) $(LIBS) diff --git a/ui.cpp b/ui.cpp index 1f22170302..5d93ad227f 100644 --- a/ui.cpp +++ b/ui.cpp @@ -21,7 +21,6 @@ DEFINE_EVENT_TYPE(wxEVT_REPLY3) CMainFrame* pframeMain = NULL; CMyTaskBarIcon* ptaskbaricon = NULL; -CServer* pserver = NULL; map mapAddressBook; bool fRandSendTest = false; void RandSend(); @@ -385,8 +384,6 @@ CMainFrame::~CMainFrame() pframeMain = NULL; delete ptaskbaricon; ptaskbaricon = NULL; - delete pserver; - pserver = NULL; } void ExitTimeout(void* parg) @@ -1690,8 +1687,8 @@ CAboutDialog::CAboutDialog(wxWindow* parent) : CAboutDialogBase(parent) #if !wxUSE_UNICODE // Workaround until upgrade to wxWidgets supporting UTF-8 wxString str = m_staticTextMain->GetLabel(); - if (str.Find('�') != wxNOT_FOUND) - str.Remove(str.Find('�'), 1); + if (str.Find('Â') != wxNOT_FOUND) + str.Remove(str.Find('Â'), 1); m_staticTextMain->SetLabel(str); #endif #ifndef __WXMSW__ @@ -3551,26 +3548,6 @@ bool CMyApp::OnInit2() return false; } - if (mapArgs.count("-blockamount")) { - CClient client; - wxString hostname = "localhost"; - wxString server = GetDataDir() + "service"; - CClientConnection * pconnection = (CClientConnection *)client.MakeConnection(hostname, server, "ipc test"); - string output = ""; - if (pconnection) { - char * pbuffer = (char *)pconnection->Request("blockamount"); - while (*pbuffer != '\n') { - output += *pbuffer; - pbuffer++; - } - } - else { - output = "Cannot access Bitcoin. Are you sure the program is running?\n"; - } - fprintf(stderr, "%s", output.c_str()); - return false; - } - if (mapArgs.count("-datadir")) strlcpy(pszSetDataDir, mapArgs["-datadir"].c_str(), sizeof(pszSetDataDir)); @@ -3778,8 +3755,6 @@ bool CMyApp::OnInit2() if (fFirstRun) SetStartOnSystemStartup(true); - pserver = new CServer; - pserver->Create(GetDataDir() + "service"); // // Tests -- cgit v1.2.3 From 40d324f102295b8eea70ec9ac6b42be417cbbfb8 Mon Sep 17 00:00:00 2001 From: s_nakamoto Date: Wed, 10 Feb 2010 19:41:22 +0000 Subject: JSON Spirit library from http://www.codeproject.com/KB/recipes/JSON_Spirit.aspx, MIT license --- json/LICENSE.txt | 24 ++ json/json_spirit.h | 18 ++ json/json_spirit_error_position.h | 54 ++++ json/json_spirit_reader.cpp | 137 +++++++++ json/json_spirit_reader.h | 62 ++++ json/json_spirit_reader_template.h | 612 +++++++++++++++++++++++++++++++++++++ json/json_spirit_stream_reader.h | 70 +++++ json/json_spirit_utils.h | 61 ++++ json/json_spirit_value.cpp | 8 + json/json_spirit_value.h | 532 ++++++++++++++++++++++++++++++++ json/json_spirit_writer.cpp | 95 ++++++ json/json_spirit_writer.h | 50 +++ json/json_spirit_writer_template.h | 245 +++++++++++++++ 13 files changed, 1968 insertions(+) create mode 100644 json/LICENSE.txt create mode 100644 json/json_spirit.h create mode 100644 json/json_spirit_error_position.h create mode 100644 json/json_spirit_reader.cpp create mode 100644 json/json_spirit_reader.h create mode 100644 json/json_spirit_reader_template.h create mode 100644 json/json_spirit_stream_reader.h create mode 100644 json/json_spirit_utils.h create mode 100644 json/json_spirit_value.cpp create mode 100644 json/json_spirit_value.h create mode 100644 json/json_spirit_writer.cpp create mode 100644 json/json_spirit_writer.h create mode 100644 json/json_spirit_writer_template.h diff --git a/json/LICENSE.txt b/json/LICENSE.txt new file mode 100644 index 0000000000..fa193fe7b7 --- /dev/null +++ b/json/LICENSE.txt @@ -0,0 +1,24 @@ +The MIT License + +Copyright (c) 2007 - 2009 John W. Wilkinson + +Permission is hereby granted, free of charge, to any person +obtaining a copy of this software and associated documentation +files (the "Software"), to deal in the Software without +restriction, including without limitation the rights to use, +copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. diff --git a/json/json_spirit.h b/json/json_spirit.h new file mode 100644 index 0000000000..7dac05c360 --- /dev/null +++ b/json/json_spirit.h @@ -0,0 +1,18 @@ +#ifndef JSON_SPIRIT +#define JSON_SPIRIT + +// Copyright John W. Wilkinson 2007 - 2009. +// Distributed under the MIT License, see accompanying file LICENSE.txt + +// json spirit version 4.03 + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +#include "json_spirit_value.h" +#include "json_spirit_reader.h" +#include "json_spirit_writer.h" +#include "json_spirit_utils.h" + +#endif diff --git a/json/json_spirit_error_position.h b/json/json_spirit_error_position.h new file mode 100644 index 0000000000..4a535ff517 --- /dev/null +++ b/json/json_spirit_error_position.h @@ -0,0 +1,54 @@ +#ifndef JSON_SPIRIT_ERROR_POSITION +#define JSON_SPIRIT_ERROR_POSITION + +// Copyright John W. Wilkinson 2007 - 2009. +// Distributed under the MIT License, see accompanying file LICENSE.txt + +// json spirit version 4.03 + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +#include + +namespace json_spirit +{ + // An Error_position exception is thrown by the "read_or_throw" functions below on finding an error. + // Note the "read_or_throw" functions are around 3 times slower than the standard functions "read" + // functions that return a bool. + // + struct Error_position + { + Error_position(); + Error_position( unsigned int line, unsigned int column, const std::string& reason ); + bool operator==( const Error_position& lhs ) const; + unsigned int line_; + unsigned int column_; + std::string reason_; + }; + + inline Error_position::Error_position() + : line_( 0 ) + , column_( 0 ) + { + } + + inline Error_position::Error_position( unsigned int line, unsigned int column, const std::string& reason ) + : line_( line ) + , column_( column ) + , reason_( reason ) + { + } + + inline bool Error_position::operator==( const Error_position& lhs ) const + { + if( this == &lhs ) return true; + + return ( reason_ == lhs.reason_ ) && + ( line_ == lhs.line_ ) && + ( column_ == lhs.column_ ); +} +} + +#endif diff --git a/json/json_spirit_reader.cpp b/json/json_spirit_reader.cpp new file mode 100644 index 0000000000..8e2fb5e2ab --- /dev/null +++ b/json/json_spirit_reader.cpp @@ -0,0 +1,137 @@ +// Copyright John W. Wilkinson 2007 - 2009. +// Distributed under the MIT License, see accompanying file LICENSE.txt + +// json spirit version 4.03 + +#include "json_spirit_reader.h" +#include "json_spirit_reader_template.h" + +using namespace json_spirit; + +bool json_spirit::read( const std::string& s, Value& value ) +{ + return read_string( s, value ); +} + +void json_spirit::read_or_throw( const std::string& s, Value& value ) +{ + read_string_or_throw( s, value ); +} + +bool json_spirit::read( std::istream& is, Value& value ) +{ + return read_stream( is, value ); +} + +void json_spirit::read_or_throw( std::istream& is, Value& value ) +{ + read_stream_or_throw( is, value ); +} + +bool json_spirit::read( std::string::const_iterator& begin, std::string::const_iterator end, Value& value ) +{ + return read_range( begin, end, value ); +} + +void json_spirit::read_or_throw( std::string::const_iterator& begin, std::string::const_iterator end, Value& value ) +{ + begin = read_range_or_throw( begin, end, value ); +} + +#ifndef BOOST_NO_STD_WSTRING + +bool json_spirit::read( const std::wstring& s, wValue& value ) +{ + return read_string( s, value ); +} + +void json_spirit::read_or_throw( const std::wstring& s, wValue& value ) +{ + read_string_or_throw( s, value ); +} + +bool json_spirit::read( std::wistream& is, wValue& value ) +{ + return read_stream( is, value ); +} + +void json_spirit::read_or_throw( std::wistream& is, wValue& value ) +{ + read_stream_or_throw( is, value ); +} + +bool json_spirit::read( std::wstring::const_iterator& begin, std::wstring::const_iterator end, wValue& value ) +{ + return read_range( begin, end, value ); +} + +void json_spirit::read_or_throw( std::wstring::const_iterator& begin, std::wstring::const_iterator end, wValue& value ) +{ + begin = read_range_or_throw( begin, end, value ); +} + +#endif + +bool json_spirit::read( const std::string& s, mValue& value ) +{ + return read_string( s, value ); +} + +void json_spirit::read_or_throw( const std::string& s, mValue& value ) +{ + read_string_or_throw( s, value ); +} + +bool json_spirit::read( std::istream& is, mValue& value ) +{ + return read_stream( is, value ); +} + +void json_spirit::read_or_throw( std::istream& is, mValue& value ) +{ + read_stream_or_throw( is, value ); +} + +bool json_spirit::read( std::string::const_iterator& begin, std::string::const_iterator end, mValue& value ) +{ + return read_range( begin, end, value ); +} + +void json_spirit::read_or_throw( std::string::const_iterator& begin, std::string::const_iterator end, mValue& value ) +{ + begin = read_range_or_throw( begin, end, value ); +} + +#ifndef BOOST_NO_STD_WSTRING + +bool json_spirit::read( const std::wstring& s, wmValue& value ) +{ + return read_string( s, value ); +} + +void json_spirit::read_or_throw( const std::wstring& s, wmValue& value ) +{ + read_string_or_throw( s, value ); +} + +bool json_spirit::read( std::wistream& is, wmValue& value ) +{ + return read_stream( is, value ); +} + +void json_spirit::read_or_throw( std::wistream& is, wmValue& value ) +{ + read_stream_or_throw( is, value ); +} + +bool json_spirit::read( std::wstring::const_iterator& begin, std::wstring::const_iterator end, wmValue& value ) +{ + return read_range( begin, end, value ); +} + +void json_spirit::read_or_throw( std::wstring::const_iterator& begin, std::wstring::const_iterator end, wmValue& value ) +{ + begin = read_range_or_throw( begin, end, value ); +} + +#endif diff --git a/json/json_spirit_reader.h b/json/json_spirit_reader.h new file mode 100644 index 0000000000..a58bfc10fe --- /dev/null +++ b/json/json_spirit_reader.h @@ -0,0 +1,62 @@ +#ifndef JSON_SPIRIT_READER +#define JSON_SPIRIT_READER + +// Copyright John W. Wilkinson 2007 - 2009. +// Distributed under the MIT License, see accompanying file LICENSE.txt + +// json spirit version 4.03 + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +#include "json_spirit_value.h" +#include "json_spirit_error_position.h" +#include + +namespace json_spirit +{ + // functions to reads a JSON values + + bool read( const std::string& s, Value& value ); + bool read( std::istream& is, Value& value ); + bool read( std::string::const_iterator& begin, std::string::const_iterator end, Value& value ); + + void read_or_throw( const std::string& s, Value& value ); + void read_or_throw( std::istream& is, Value& value ); + void read_or_throw( std::string::const_iterator& begin, std::string::const_iterator end, Value& value ); + +#ifndef BOOST_NO_STD_WSTRING + + bool read( const std::wstring& s, wValue& value ); + bool read( std::wistream& is, wValue& value ); + bool read( std::wstring::const_iterator& begin, std::wstring::const_iterator end, wValue& value ); + + void read_or_throw( const std::wstring& s, wValue& value ); + void read_or_throw( std::wistream& is, wValue& value ); + void read_or_throw( std::wstring::const_iterator& begin, std::wstring::const_iterator end, wValue& value ); + +#endif + + bool read( const std::string& s, mValue& value ); + bool read( std::istream& is, mValue& value ); + bool read( std::string::const_iterator& begin, std::string::const_iterator end, mValue& value ); + + void read_or_throw( const std::string& s, mValue& value ); + void read_or_throw( std::istream& is, mValue& value ); + void read_or_throw( std::string::const_iterator& begin, std::string::const_iterator end, mValue& value ); + +#ifndef BOOST_NO_STD_WSTRING + + bool read( const std::wstring& s, wmValue& value ); + bool read( std::wistream& is, wmValue& value ); + bool read( std::wstring::const_iterator& begin, std::wstring::const_iterator end, wmValue& value ); + + void read_or_throw( const std::wstring& s, wmValue& value ); + void read_or_throw( std::wistream& is, wmValue& value ); + void read_or_throw( std::wstring::const_iterator& begin, std::wstring::const_iterator end, wmValue& value ); + +#endif +} + +#endif diff --git a/json/json_spirit_reader_template.h b/json/json_spirit_reader_template.h new file mode 100644 index 0000000000..81cded4346 --- /dev/null +++ b/json/json_spirit_reader_template.h @@ -0,0 +1,612 @@ +#ifndef JSON_SPIRIT_READER_TEMPLATE +#define JSON_SPIRIT_READER_TEMPLATE + +// Copyright John W. Wilkinson 2007 - 2009. +// Distributed under the MIT License, see accompanying file LICENSE.txt + +// json spirit version 4.03 + +#include "json_spirit_value.h" +#include "json_spirit_error_position.h" + +//#define BOOST_SPIRIT_THREADSAFE // uncomment for multithreaded use, requires linking to boost.thread + +#include +#include +#include + +#if BOOST_VERSION >= 103800 + #include + #include + #include + #include + #include + #define spirit_namespace boost::spirit::classic +#else + #include + #include + #include + #include + #include + #define spirit_namespace boost::spirit +#endif + +namespace json_spirit +{ + const spirit_namespace::int_parser < boost::int64_t > int64_p = spirit_namespace::int_parser < boost::int64_t >(); + const spirit_namespace::uint_parser< boost::uint64_t > uint64_p = spirit_namespace::uint_parser< boost::uint64_t >(); + + template< class Iter_type > + bool is_eq( Iter_type first, Iter_type last, const char* c_str ) + { + for( Iter_type i = first; i != last; ++i, ++c_str ) + { + if( *c_str == 0 ) return false; + + if( *i != *c_str ) return false; + } + + return true; + } + + template< class Char_type > + Char_type hex_to_num( const Char_type c ) + { + if( ( c >= '0' ) && ( c <= '9' ) ) return c - '0'; + if( ( c >= 'a' ) && ( c <= 'f' ) ) return c - 'a' + 10; + if( ( c >= 'A' ) && ( c <= 'F' ) ) return c - 'A' + 10; + return 0; + } + + template< class Char_type, class Iter_type > + Char_type hex_str_to_char( Iter_type& begin ) + { + const Char_type c1( *( ++begin ) ); + const Char_type c2( *( ++begin ) ); + + return ( hex_to_num( c1 ) << 4 ) + hex_to_num( c2 ); + } + + template< class Char_type, class Iter_type > + Char_type unicode_str_to_char( Iter_type& begin ) + { + const Char_type c1( *( ++begin ) ); + const Char_type c2( *( ++begin ) ); + const Char_type c3( *( ++begin ) ); + const Char_type c4( *( ++begin ) ); + + return ( hex_to_num( c1 ) << 12 ) + + ( hex_to_num( c2 ) << 8 ) + + ( hex_to_num( c3 ) << 4 ) + + hex_to_num( c4 ); + } + + template< class String_type > + void append_esc_char_and_incr_iter( String_type& s, + typename String_type::const_iterator& begin, + typename String_type::const_iterator end ) + { + typedef typename String_type::value_type Char_type; + + const Char_type c2( *begin ); + + switch( c2 ) + { + case 't': s += '\t'; break; + case 'b': s += '\b'; break; + case 'f': s += '\f'; break; + case 'n': s += '\n'; break; + case 'r': s += '\r'; break; + case '\\': s += '\\'; break; + case '/': s += '/'; break; + case '"': s += '"'; break; + case 'x': + { + if( end - begin >= 3 ) // expecting "xHH..." + { + s += hex_str_to_char< Char_type >( begin ); + } + break; + } + case 'u': + { + if( end - begin >= 5 ) // expecting "uHHHH..." + { + s += unicode_str_to_char< Char_type >( begin ); + } + break; + } + } + } + + template< class String_type > + String_type substitute_esc_chars( typename String_type::const_iterator begin, + typename String_type::const_iterator end ) + { + typedef typename String_type::const_iterator Iter_type; + + if( end - begin < 2 ) return String_type( begin, end ); + + String_type result; + + result.reserve( end - begin ); + + const Iter_type end_minus_1( end - 1 ); + + Iter_type substr_start = begin; + Iter_type i = begin; + + for( ; i < end_minus_1; ++i ) + { + if( *i == '\\' ) + { + result.append( substr_start, i ); + + ++i; // skip the '\' + + append_esc_char_and_incr_iter( result, i, end ); + + substr_start = i + 1; + } + } + + result.append( substr_start, end ); + + return result; + } + + template< class String_type > + String_type get_str_( typename String_type::const_iterator begin, + typename String_type::const_iterator end ) + { + assert( end - begin >= 2 ); + + typedef typename String_type::const_iterator Iter_type; + + Iter_type str_without_quotes( ++begin ); + Iter_type end_without_quotes( --end ); + + return substitute_esc_chars< String_type >( str_without_quotes, end_without_quotes ); + } + + inline std::string get_str( std::string::const_iterator begin, std::string::const_iterator end ) + { + return get_str_< std::string >( begin, end ); + } + + inline std::wstring get_str( std::wstring::const_iterator begin, std::wstring::const_iterator end ) + { + return get_str_< std::wstring >( begin, end ); + } + + template< class String_type, class Iter_type > + String_type get_str( Iter_type begin, Iter_type end ) + { + const String_type tmp( begin, end ); // convert multipass iterators to string iterators + + return get_str( tmp.begin(), tmp.end() ); + } + + // this class's methods get called by the spirit parse resulting + // in the creation of a JSON object or array + // + // NB Iter_type could be a std::string iterator, wstring iterator, a position iterator or a multipass iterator + // + template< class Value_type, class Iter_type > + class Semantic_actions + { + public: + + typedef typename Value_type::Config_type Config_type; + typedef typename Config_type::String_type String_type; + typedef typename Config_type::Object_type Object_type; + typedef typename Config_type::Array_type Array_type; + typedef typename String_type::value_type Char_type; + + Semantic_actions( Value_type& value ) + : value_( value ) + , current_p_( 0 ) + { + } + + void begin_obj( Char_type c ) + { + assert( c == '{' ); + + begin_compound< Object_type >(); + } + + void end_obj( Char_type c ) + { + assert( c == '}' ); + + end_compound(); + } + + void begin_array( Char_type c ) + { + assert( c == '[' ); + + begin_compound< Array_type >(); + } + + void end_array( Char_type c ) + { + assert( c == ']' ); + + end_compound(); + } + + void new_name( Iter_type begin, Iter_type end ) + { + assert( current_p_->type() == obj_type ); + + name_ = get_str< String_type >( begin, end ); + } + + void new_str( Iter_type begin, Iter_type end ) + { + add_to_current( get_str< String_type >( begin, end ) ); + } + + void new_true( Iter_type begin, Iter_type end ) + { + assert( is_eq( begin, end, "true" ) ); + + add_to_current( true ); + } + + void new_false( Iter_type begin, Iter_type end ) + { + assert( is_eq( begin, end, "false" ) ); + + add_to_current( false ); + } + + void new_null( Iter_type begin, Iter_type end ) + { + assert( is_eq( begin, end, "null" ) ); + + add_to_current( Value_type() ); + } + + void new_int( boost::int64_t i ) + { + add_to_current( i ); + } + + void new_uint64( boost::uint64_t ui ) + { + add_to_current( ui ); + } + + void new_real( double d ) + { + add_to_current( d ); + } + + private: + + Semantic_actions& operator=( const Semantic_actions& ); + // to prevent "assignment operator could not be generated" warning + + Value_type* add_first( const Value_type& value ) + { + assert( current_p_ == 0 ); + + value_ = value; + current_p_ = &value_; + return current_p_; + } + + template< class Array_or_obj > + void begin_compound() + { + if( current_p_ == 0 ) + { + add_first( Array_or_obj() ); + } + else + { + stack_.push_back( current_p_ ); + + Array_or_obj new_array_or_obj; // avoid copy by building new array or object in place + + current_p_ = add_to_current( new_array_or_obj ); + } + } + + void end_compound() + { + if( current_p_ != &value_ ) + { + current_p_ = stack_.back(); + + stack_.pop_back(); + } + } + + Value_type* add_to_current( const Value_type& value ) + { + if( current_p_ == 0 ) + { + return add_first( value ); + } + else if( current_p_->type() == array_type ) + { + current_p_->get_array().push_back( value ); + + return ¤t_p_->get_array().back(); + } + + assert( current_p_->type() == obj_type ); + + return &Config_type::add( current_p_->get_obj(), name_, value ); + } + + Value_type& value_; // this is the object or array that is being created + Value_type* current_p_; // the child object or array that is currently being constructed + + std::vector< Value_type* > stack_; // previous child objects and arrays + + String_type name_; // of current name/value pair + }; + + template< typename Iter_type > + void throw_error( spirit_namespace::position_iterator< Iter_type > i, const std::string& reason ) + { + throw Error_position( i.get_position().line, i.get_position().column, reason ); + } + + template< typename Iter_type > + void throw_error( Iter_type i, const std::string& reason ) + { + throw reason; + } + + // the spirit grammer + // + template< class Value_type, class Iter_type > + class Json_grammer : public spirit_namespace::grammar< Json_grammer< Value_type, Iter_type > > + { + public: + + typedef Semantic_actions< Value_type, Iter_type > Semantic_actions_t; + + Json_grammer( Semantic_actions_t& semantic_actions ) + : actions_( semantic_actions ) + { + } + + static void throw_not_value( Iter_type begin, Iter_type end ) + { + throw_error( begin, "not a value" ); + } + + static void throw_not_array( Iter_type begin, Iter_type end ) + { + throw_error( begin, "not an array" ); + } + + static void throw_not_object( Iter_type begin, Iter_type end ) + { + throw_error( begin, "not an object" ); + } + + static void throw_not_pair( Iter_type begin, Iter_type end ) + { + throw_error( begin, "not a pair" ); + } + + static void throw_not_colon( Iter_type begin, Iter_type end ) + { + throw_error( begin, "no colon in pair" ); + } + + static void throw_not_string( Iter_type begin, Iter_type end ) + { + throw_error( begin, "not a string" ); + } + + template< typename ScannerT > + class definition + { + public: + + definition( const Json_grammer& self ) + { + using namespace spirit_namespace; + + typedef typename Value_type::String_type::value_type Char_type; + + // first we convert the semantic action class methods to functors with the + // parameter signature expected by spirit + + typedef boost::function< void( Char_type ) > Char_action; + typedef boost::function< void( Iter_type, Iter_type ) > Str_action; + typedef boost::function< void( double ) > Real_action; + typedef boost::function< void( boost::int64_t ) > Int_action; + typedef boost::function< void( boost::uint64_t ) > Uint64_action; + + Char_action begin_obj ( boost::bind( &Semantic_actions_t::begin_obj, &self.actions_, _1 ) ); + Char_action end_obj ( boost::bind( &Semantic_actions_t::end_obj, &self.actions_, _1 ) ); + Char_action begin_array( boost::bind( &Semantic_actions_t::begin_array, &self.actions_, _1 ) ); + Char_action end_array ( boost::bind( &Semantic_actions_t::end_array, &self.actions_, _1 ) ); + Str_action new_name ( boost::bind( &Semantic_actions_t::new_name, &self.actions_, _1, _2 ) ); + Str_action new_str ( boost::bind( &Semantic_actions_t::new_str, &self.actions_, _1, _2 ) ); + Str_action new_true ( boost::bind( &Semantic_actions_t::new_true, &self.actions_, _1, _2 ) ); + Str_action new_false ( boost::bind( &Semantic_actions_t::new_false, &self.actions_, _1, _2 ) ); + Str_action new_null ( boost::bind( &Semantic_actions_t::new_null, &self.actions_, _1, _2 ) ); + Real_action new_real ( boost::bind( &Semantic_actions_t::new_real, &self.actions_, _1 ) ); + Int_action new_int ( boost::bind( &Semantic_actions_t::new_int, &self.actions_, _1 ) ); + Uint64_action new_uint64 ( boost::bind( &Semantic_actions_t::new_uint64, &self.actions_, _1 ) ); + + // actual grammer + + json_ + = value_ | eps_p[ &throw_not_value ] + ; + + value_ + = string_[ new_str ] + | number_ + | object_ + | array_ + | str_p( "true" ) [ new_true ] + | str_p( "false" )[ new_false ] + | str_p( "null" ) [ new_null ] + ; + + object_ + = ch_p('{')[ begin_obj ] + >> !members_ + >> ( ch_p('}')[ end_obj ] | eps_p[ &throw_not_object ] ) + ; + + members_ + = pair_ >> *( ',' >> pair_ ) + ; + + pair_ + = string_[ new_name ] + >> ( ':' | eps_p[ &throw_not_colon ] ) + >> ( value_ | eps_p[ &throw_not_value ] ) + ; + + array_ + = ch_p('[')[ begin_array ] + >> !elements_ + >> ( ch_p(']')[ end_array ] | eps_p[ &throw_not_array ] ) + ; + + elements_ + = value_ >> *( ',' >> value_ ) + ; + + string_ + = lexeme_d // this causes white space inside a string to be retained + [ + confix_p + ( + '"', + *lex_escape_ch_p, + '"' + ) + ] + ; + + number_ + = strict_real_p[ new_real ] + | int64_p [ new_int ] + | uint64_p [ new_uint64 ] + ; + } + + spirit_namespace::rule< ScannerT > json_, object_, members_, pair_, array_, elements_, value_, string_, number_; + + const spirit_namespace::rule< ScannerT >& start() const { return json_; } + }; + + private: + + Json_grammer& operator=( const Json_grammer& ); // to prevent "assignment operator could not be generated" warning + + Semantic_actions_t& actions_; + }; + + template< class Iter_type, class Value_type > + Iter_type read_range_or_throw( Iter_type begin, Iter_type end, Value_type& value ) + { + Semantic_actions< Value_type, Iter_type > semantic_actions( value ); + + const spirit_namespace::parse_info< Iter_type > info = + spirit_namespace::parse( begin, end, + Json_grammer< Value_type, Iter_type >( semantic_actions ), + spirit_namespace::space_p ); + + if( !info.hit ) + { + assert( false ); // in theory exception should already have been thrown + throw_error( info.stop, "error" ); + } + + return info.stop; + } + + template< class Iter_type, class Value_type > + void add_posn_iter_and_read_range_or_throw( Iter_type begin, Iter_type end, Value_type& value ) + { + typedef spirit_namespace::position_iterator< Iter_type > Posn_iter_t; + + const Posn_iter_t posn_begin( begin, end ); + const Posn_iter_t posn_end( end, end ); + + read_range_or_throw( posn_begin, posn_end, value ); + } + + template< class Iter_type, class Value_type > + bool read_range( Iter_type& begin, Iter_type end, Value_type& value ) + { + try + { + begin = read_range_or_throw( begin, end, value ); + + return true; + } + catch( ... ) + { + return false; + } + } + + template< class String_type, class Value_type > + void read_string_or_throw( const String_type& s, Value_type& value ) + { + add_posn_iter_and_read_range_or_throw( s.begin(), s.end(), value ); + } + + template< class String_type, class Value_type > + bool read_string( const String_type& s, Value_type& value ) + { + typename String_type::const_iterator begin = s.begin(); + + return read_range( begin, s.end(), value ); + } + + template< class Istream_type > + struct Multi_pass_iters + { + typedef typename Istream_type::char_type Char_type; + typedef std::istream_iterator< Char_type, Char_type > istream_iter; + typedef spirit_namespace::multi_pass< istream_iter > Mp_iter; + + Multi_pass_iters( Istream_type& is ) + { + is.unsetf( std::ios::skipws ); + + begin_ = spirit_namespace::make_multi_pass( istream_iter( is ) ); + end_ = spirit_namespace::make_multi_pass( istream_iter() ); + } + + Mp_iter begin_; + Mp_iter end_; + }; + + template< class Istream_type, class Value_type > + bool read_stream( Istream_type& is, Value_type& value ) + { + Multi_pass_iters< Istream_type > mp_iters( is ); + + return read_range( mp_iters.begin_, mp_iters.end_, value ); + } + + template< class Istream_type, class Value_type > + void read_stream_or_throw( Istream_type& is, Value_type& value ) + { + const Multi_pass_iters< Istream_type > mp_iters( is ); + + add_posn_iter_and_read_range_or_throw( mp_iters.begin_, mp_iters.end_, value ); + } +} + +#endif diff --git a/json/json_spirit_stream_reader.h b/json/json_spirit_stream_reader.h new file mode 100644 index 0000000000..a9ceeacf00 --- /dev/null +++ b/json/json_spirit_stream_reader.h @@ -0,0 +1,70 @@ +#ifndef JSON_SPIRIT_READ_STREAM +#define JSON_SPIRIT_READ_STREAM + +// Copyright John W. Wilkinson 2007 - 2009. +// Distributed under the MIT License, see accompanying file LICENSE.txt + +// json spirit version 4.03 + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +#include "json_spirit_reader_template.h" + +namespace json_spirit +{ + // these classes allows you to read multiple top level contiguous values from a stream, + // the normal stream read functions have a bug that prevent multiple top level values + // from being read unless they are separated by spaces + + template< class Istream_type, class Value_type > + class Stream_reader + { + public: + + Stream_reader( Istream_type& is ) + : iters_( is ) + { + } + + bool read_next( Value_type& value ) + { + return read_range( iters_.begin_, iters_.end_, value ); + } + + private: + + typedef Multi_pass_iters< Istream_type > Mp_iters; + + Mp_iters iters_; + }; + + template< class Istream_type, class Value_type > + class Stream_reader_thrower + { + public: + + Stream_reader_thrower( Istream_type& is ) + : iters_( is ) + , posn_begin_( iters_.begin_, iters_.end_ ) + , posn_end_( iters_.end_, iters_.end_ ) + { + } + + void read_next( Value_type& value ) + { + posn_begin_ = read_range_or_throw( posn_begin_, posn_end_, value ); + } + + private: + + typedef Multi_pass_iters< Istream_type > Mp_iters; + typedef spirit_namespace::position_iterator< typename Mp_iters::Mp_iter > Posn_iter_t; + + Mp_iters iters_; + Posn_iter_t posn_begin_, posn_end_; + }; +} + +#endif diff --git a/json/json_spirit_utils.h b/json/json_spirit_utils.h new file mode 100644 index 0000000000..7eb338e7c5 --- /dev/null +++ b/json/json_spirit_utils.h @@ -0,0 +1,61 @@ +#ifndef JSON_SPIRIT_UTILS +#define JSON_SPIRIT_UTILS + +// Copyright John W. Wilkinson 2007 - 2009. +// Distributed under the MIT License, see accompanying file LICENSE.txt + +// json spirit version 4.03 + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +#include "json_spirit_value.h" +#include + +namespace json_spirit +{ + template< class Obj_t, class Map_t > + void obj_to_map( const Obj_t& obj, Map_t& mp_obj ) + { + mp_obj.clear(); + + for( typename Obj_t::const_iterator i = obj.begin(); i != obj.end(); ++i ) + { + mp_obj[ i->name_ ] = i->value_; + } + } + + template< class Obj_t, class Map_t > + void map_to_obj( const Map_t& mp_obj, Obj_t& obj ) + { + obj.clear(); + + for( typename Map_t::const_iterator i = mp_obj.begin(); i != mp_obj.end(); ++i ) + { + obj.push_back( typename Obj_t::value_type( i->first, i->second ) ); + } + } + + typedef std::map< std::string, Value > Mapped_obj; + +#ifndef BOOST_NO_STD_WSTRING + typedef std::map< std::wstring, wValue > wMapped_obj; +#endif + + template< class Object_type, class String_type > + const typename Object_type::value_type::Value_type& find_value( const Object_type& obj, const String_type& name ) + { + for( typename Object_type::const_iterator i = obj.begin(); i != obj.end(); ++i ) + { + if( i->name_ == name ) + { + return i->value_; + } + } + + return Object_type::value_type::Value_type::null; + } +} + +#endif diff --git a/json/json_spirit_value.cpp b/json/json_spirit_value.cpp new file mode 100644 index 0000000000..dd5b50e5d5 --- /dev/null +++ b/json/json_spirit_value.cpp @@ -0,0 +1,8 @@ +/* Copyright (c) 2007 John W Wilkinson + + This source code can be used for any purpose as long as + this comment is retained. */ + +// json spirit version 2.00 + +#include "json_spirit_value.h" diff --git a/json/json_spirit_value.h b/json/json_spirit_value.h new file mode 100644 index 0000000000..e8be355300 --- /dev/null +++ b/json/json_spirit_value.h @@ -0,0 +1,532 @@ +#ifndef JSON_SPIRIT_VALUE +#define JSON_SPIRIT_VALUE + +// Copyright John W. Wilkinson 2007 - 2009. +// Distributed under the MIT License, see accompanying file LICENSE.txt + +// json spirit version 4.03 + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace json_spirit +{ + enum Value_type{ obj_type, array_type, str_type, bool_type, int_type, real_type, null_type }; + + template< class Config > // Config determines whether the value uses std::string or std::wstring and + // whether JSON Objects are represented as vectors or maps + class Value_impl + { + public: + + typedef Config Config_type; + typedef typename Config::String_type String_type; + typedef typename Config::Object_type Object; + typedef typename Config::Array_type Array; + typedef typename String_type::const_pointer Const_str_ptr; // eg const char* + + Value_impl(); // creates null value + Value_impl( Const_str_ptr value ); + Value_impl( const String_type& value ); + Value_impl( const Object& value ); + Value_impl( const Array& value ); + Value_impl( bool value ); + Value_impl( int value ); + Value_impl( boost::int64_t value ); + Value_impl( boost::uint64_t value ); + Value_impl( double value ); + + Value_impl( const Value_impl& other ); + + bool operator==( const Value_impl& lhs ) const; + + Value_impl& operator=( const Value_impl& lhs ); + + Value_type type() const; + + bool is_uint64() const; + bool is_null() const; + + const String_type& get_str() const; + const Object& get_obj() const; + const Array& get_array() const; + bool get_bool() const; + int get_int() const; + boost::int64_t get_int64() const; + boost::uint64_t get_uint64() const; + double get_real() const; + + Object& get_obj(); + Array& get_array(); + + template< typename T > T get_value() const; // example usage: int i = value.get_value< int >(); + // or double d = value.get_value< double >(); + + static const Value_impl null; + + private: + + void check_type( const Value_type vtype ) const; + + typedef boost::variant< String_type, + boost::recursive_wrapper< Object >, boost::recursive_wrapper< Array >, + bool, boost::int64_t, double > Variant; + + Value_type type_; + Variant v_; + bool is_uint64_; + }; + + // vector objects + + template< class Config > + struct Pair_impl + { + typedef typename Config::String_type String_type; + typedef typename Config::Value_type Value_type; + + Pair_impl( const String_type& name, const Value_type& value ); + + bool operator==( const Pair_impl& lhs ) const; + + String_type name_; + Value_type value_; + }; + + template< class String > + struct Config_vector + { + typedef String String_type; + typedef Value_impl< Config_vector > Value_type; + typedef Pair_impl < Config_vector > Pair_type; + typedef std::vector< Value_type > Array_type; + typedef std::vector< Pair_type > Object_type; + + static Value_type& add( Object_type& obj, const String_type& name, const Value_type& value ) + { + obj.push_back( Pair_type( name , value ) ); + + return obj.back().value_; + } + + static String_type get_name( const Pair_type& pair ) + { + return pair.name_; + } + + static Value_type get_value( const Pair_type& pair ) + { + return pair.value_; + } + }; + + // typedefs for ASCII + + typedef Config_vector< std::string > Config; + + typedef Config::Value_type Value; + typedef Config::Pair_type Pair; + typedef Config::Object_type Object; + typedef Config::Array_type Array; + + // typedefs for Unicode + +#ifndef BOOST_NO_STD_WSTRING + + typedef Config_vector< std::wstring > wConfig; + + typedef wConfig::Value_type wValue; + typedef wConfig::Pair_type wPair; + typedef wConfig::Object_type wObject; + typedef wConfig::Array_type wArray; +#endif + + // map objects + + template< class String > + struct Config_map + { + typedef String String_type; + typedef Value_impl< Config_map > Value_type; + typedef std::vector< Value_type > Array_type; + typedef std::map< String_type, Value_type > Object_type; + typedef typename Object_type::value_type Pair_type; + + static Value_type& add( Object_type& obj, const String_type& name, const Value_type& value ) + { + return obj[ name ] = value; + } + + static String_type get_name( const Pair_type& pair ) + { + return pair.first; + } + + static Value_type get_value( const Pair_type& pair ) + { + return pair.second; + } + }; + + // typedefs for ASCII + + typedef Config_map< std::string > mConfig; + + typedef mConfig::Value_type mValue; + typedef mConfig::Object_type mObject; + typedef mConfig::Array_type mArray; + + // typedefs for Unicode + +#ifndef BOOST_NO_STD_WSTRING + + typedef Config_map< std::wstring > wmConfig; + + typedef wmConfig::Value_type wmValue; + typedef wmConfig::Object_type wmObject; + typedef wmConfig::Array_type wmArray; + +#endif + + /////////////////////////////////////////////////////////////////////////////////////////////// + // + // implementation + + template< class Config > + const Value_impl< Config > Value_impl< Config >::null; + + template< class Config > + Value_impl< Config >::Value_impl() + : type_( null_type ) + , is_uint64_( false ) + { + } + + template< class Config > + Value_impl< Config >::Value_impl( const Const_str_ptr value ) + : type_( str_type ) + , v_( String_type( value ) ) + , is_uint64_( false ) + { + } + + template< class Config > + Value_impl< Config >::Value_impl( const String_type& value ) + : type_( str_type ) + , v_( value ) + , is_uint64_( false ) + { + } + + template< class Config > + Value_impl< Config >::Value_impl( const Object& value ) + : type_( obj_type ) + , v_( value ) + , is_uint64_( false ) + { + } + + template< class Config > + Value_impl< Config >::Value_impl( const Array& value ) + : type_( array_type ) + , v_( value ) + , is_uint64_( false ) + { + } + + template< class Config > + Value_impl< Config >::Value_impl( bool value ) + : type_( bool_type ) + , v_( value ) + , is_uint64_( false ) + { + } + + template< class Config > + Value_impl< Config >::Value_impl( int value ) + : type_( int_type ) + , v_( static_cast< boost::int64_t >( value ) ) + , is_uint64_( false ) + { + } + + template< class Config > + Value_impl< Config >::Value_impl( boost::int64_t value ) + : type_( int_type ) + , v_( value ) + , is_uint64_( false ) + { + } + + template< class Config > + Value_impl< Config >::Value_impl( boost::uint64_t value ) + : type_( int_type ) + , v_( static_cast< boost::int64_t >( value ) ) + , is_uint64_( true ) + { + } + + template< class Config > + Value_impl< Config >::Value_impl( double value ) + : type_( real_type ) + , v_( value ) + , is_uint64_( false ) + { + } + + template< class Config > + Value_impl< Config >::Value_impl( const Value_impl< Config >& other ) + : type_( other.type() ) + , v_( other.v_ ) + , is_uint64_( other.is_uint64_ ) + { + } + + template< class Config > + Value_impl< Config >& Value_impl< Config >::operator=( const Value_impl& lhs ) + { + Value_impl tmp( lhs ); + + std::swap( type_, tmp.type_ ); + std::swap( v_, tmp.v_ ); + std::swap( is_uint64_, tmp.is_uint64_ ); + + return *this; + } + + template< class Config > + bool Value_impl< Config >::operator==( const Value_impl& lhs ) const + { + if( this == &lhs ) return true; + + if( type() != lhs.type() ) return false; + + return v_ == lhs.v_; + } + + template< class Config > + Value_type Value_impl< Config >::type() const + { + return type_; + } + + template< class Config > + bool Value_impl< Config >::is_uint64() const + { + return is_uint64_; + } + + template< class Config > + bool Value_impl< Config >::is_null() const + { + return type() == null_type; + } + + template< class Config > + void Value_impl< Config >::check_type( const Value_type vtype ) const + { + if( type() != vtype ) + { + std::ostringstream os; + + os << "value type is " << type() << " not " << vtype; + + throw std::runtime_error( os.str() ); + } + } + + template< class Config > + const typename Config::String_type& Value_impl< Config >::get_str() const + { + check_type( str_type ); + + return *boost::get< String_type >( &v_ ); + } + + template< class Config > + const typename Value_impl< Config >::Object& Value_impl< Config >::get_obj() const + { + check_type( obj_type ); + + return *boost::get< Object >( &v_ ); + } + + template< class Config > + const typename Value_impl< Config >::Array& Value_impl< Config >::get_array() const + { + check_type( array_type ); + + return *boost::get< Array >( &v_ ); + } + + template< class Config > + bool Value_impl< Config >::get_bool() const + { + check_type( bool_type ); + + return boost::get< bool >( v_ ); + } + + template< class Config > + int Value_impl< Config >::get_int() const + { + check_type( int_type ); + + return static_cast< int >( get_int64() ); + } + + template< class Config > + boost::int64_t Value_impl< Config >::get_int64() const + { + check_type( int_type ); + + return boost::get< boost::int64_t >( v_ ); + } + + template< class Config > + boost::uint64_t Value_impl< Config >::get_uint64() const + { + check_type( int_type ); + + return static_cast< boost::uint64_t >( get_int64() ); + } + + template< class Config > + double Value_impl< Config >::get_real() const + { + if( type() == int_type ) + { + return is_uint64() ? static_cast< double >( get_uint64() ) + : static_cast< double >( get_int64() ); + } + + check_type( real_type ); + + return boost::get< double >( v_ ); + } + + template< class Config > + typename Value_impl< Config >::Object& Value_impl< Config >::get_obj() + { + check_type( obj_type ); + + return *boost::get< Object >( &v_ ); + } + + template< class Config > + typename Value_impl< Config >::Array& Value_impl< Config >::get_array() + { + check_type( array_type ); + + return *boost::get< Array >( &v_ ); + } + + template< class Config > + Pair_impl< Config >::Pair_impl( const String_type& name, const Value_type& value ) + : name_( name ) + , value_( value ) + { + } + + template< class Config > + bool Pair_impl< Config >::operator==( const Pair_impl< Config >& lhs ) const + { + if( this == &lhs ) return true; + + return ( name_ == lhs.name_ ) && ( value_ == lhs.value_ ); + } + + // converts a C string, ie. 8 bit char array, to a string object + // + template < class String_type > + String_type to_str( const char* c_str ) + { + String_type result; + + for( const char* p = c_str; *p != 0; ++p ) + { + result += *p; + } + + return result; + } + + // + + namespace internal_ + { + template< typename T > + struct Type_to_type + { + }; + + template< class Value > + int get_value( const Value& value, Type_to_type< int > ) + { + return value.get_int(); + } + + template< class Value > + boost::int64_t get_value( const Value& value, Type_to_type< boost::int64_t > ) + { + return value.get_int64(); + } + + template< class Value > + boost::uint64_t get_value( const Value& value, Type_to_type< boost::uint64_t > ) + { + return value.get_uint64(); + } + + template< class Value > + double get_value( const Value& value, Type_to_type< double > ) + { + return value.get_real(); + } + + template< class Value > + typename Value::String_type get_value( const Value& value, Type_to_type< typename Value::String_type > ) + { + return value.get_str(); + } + + template< class Value > + typename Value::Array get_value( const Value& value, Type_to_type< typename Value::Array > ) + { + return value.get_array(); + } + + template< class Value > + typename Value::Object get_value( const Value& value, Type_to_type< typename Value::Object > ) + { + return value.get_obj(); + } + + template< class Value > + bool get_value( const Value& value, Type_to_type< bool > ) + { + return value.get_bool(); + } + } + + template< class Config > + template< typename T > + T Value_impl< Config >::get_value() const + { + return internal_::get_value( *this, internal_::Type_to_type< T >() ); + } +} + +#endif diff --git a/json/json_spirit_writer.cpp b/json/json_spirit_writer.cpp new file mode 100644 index 0000000000..f3367b68de --- /dev/null +++ b/json/json_spirit_writer.cpp @@ -0,0 +1,95 @@ +// Copyright John W. Wilkinson 2007 - 2009. +// Distributed under the MIT License, see accompanying file LICENSE.txt + +// json spirit version 4.03 + +#include "json_spirit_writer.h" +#include "json_spirit_writer_template.h" + +void json_spirit::write( const Value& value, std::ostream& os ) +{ + write_stream( value, os, false ); +} + +void json_spirit::write_formatted( const Value& value, std::ostream& os ) +{ + write_stream( value, os, true ); +} + +std::string json_spirit::write( const Value& value ) +{ + return write_string( value, false ); +} + +std::string json_spirit::write_formatted( const Value& value ) +{ + return write_string( value, true ); +} + +#ifndef BOOST_NO_STD_WSTRING + +void json_spirit::write( const wValue& value, std::wostream& os ) +{ + write_stream( value, os, false ); +} + +void json_spirit::write_formatted( const wValue& value, std::wostream& os ) +{ + write_stream( value, os, true ); +} + +std::wstring json_spirit::write( const wValue& value ) +{ + return write_string( value, false ); +} + +std::wstring json_spirit::write_formatted( const wValue& value ) +{ + return write_string( value, true ); +} + +#endif + +void json_spirit::write( const mValue& value, std::ostream& os ) +{ + write_stream( value, os, false ); +} + +void json_spirit::write_formatted( const mValue& value, std::ostream& os ) +{ + write_stream( value, os, true ); +} + +std::string json_spirit::write( const mValue& value ) +{ + return write_string( value, false ); +} + +std::string json_spirit::write_formatted( const mValue& value ) +{ + return write_string( value, true ); +} + +#ifndef BOOST_NO_STD_WSTRING + +void json_spirit::write( const wmValue& value, std::wostream& os ) +{ + write_stream( value, os, false ); +} + +void json_spirit::write_formatted( const wmValue& value, std::wostream& os ) +{ + write_stream( value, os, true ); +} + +std::wstring json_spirit::write( const wmValue& value ) +{ + return write_string( value, false ); +} + +std::wstring json_spirit::write_formatted( const wmValue& value ) +{ + return write_string( value, true ); +} + +#endif diff --git a/json/json_spirit_writer.h b/json/json_spirit_writer.h new file mode 100644 index 0000000000..1b67b512df --- /dev/null +++ b/json/json_spirit_writer.h @@ -0,0 +1,50 @@ +#ifndef JSON_SPIRIT_WRITER +#define JSON_SPIRIT_WRITER + +// Copyright John W. Wilkinson 2007 - 2009. +// Distributed under the MIT License, see accompanying file LICENSE.txt + +// json spirit version 4.03 + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +#include "json_spirit_value.h" +#include + +namespace json_spirit +{ + // functions to convert JSON Values to text, + // the "formatted" versions add whitespace to format the output nicely + + void write ( const Value& value, std::ostream& os ); + void write_formatted( const Value& value, std::ostream& os ); + std::string write ( const Value& value ); + std::string write_formatted( const Value& value ); + +#ifndef BOOST_NO_STD_WSTRING + + void write ( const wValue& value, std::wostream& os ); + void write_formatted( const wValue& value, std::wostream& os ); + std::wstring write ( const wValue& value ); + std::wstring write_formatted( const wValue& value ); + +#endif + + void write ( const mValue& value, std::ostream& os ); + void write_formatted( const mValue& value, std::ostream& os ); + std::string write ( const mValue& value ); + std::string write_formatted( const mValue& value ); + +#ifndef BOOST_NO_STD_WSTRING + + void write ( const wmValue& value, std::wostream& os ); + void write_formatted( const wmValue& value, std::wostream& os ); + std::wstring write ( const wmValue& value ); + std::wstring write_formatted( const wmValue& value ); + +#endif +} + +#endif diff --git a/json/json_spirit_writer_template.h b/json/json_spirit_writer_template.h new file mode 100644 index 0000000000..c993756555 --- /dev/null +++ b/json/json_spirit_writer_template.h @@ -0,0 +1,245 @@ +#ifndef JSON_SPIRIT_WRITER_TEMPLATE +#define JSON_SPIRIT_WRITER_TEMPLATE + +// Copyright John W. Wilkinson 2007 - 2009. +// Distributed under the MIT License, see accompanying file LICENSE.txt + +// json spirit version 4.03 + +#include "json_spirit_value.h" + +#include +#include +#include + +namespace json_spirit +{ + inline char to_hex_char( unsigned int c ) + { + assert( c <= 0xF ); + + const char ch = static_cast< char >( c ); + + if( ch < 10 ) return '0' + ch; + + return 'A' - 10 + ch; + } + + template< class String_type > + String_type non_printable_to_string( unsigned int c ) + { + typedef typename String_type::value_type Char_type; + + String_type result( 6, '\\' ); + + result[1] = 'u'; + + result[ 5 ] = to_hex_char( c & 0x000F ); c >>= 4; + result[ 4 ] = to_hex_char( c & 0x000F ); c >>= 4; + result[ 3 ] = to_hex_char( c & 0x000F ); c >>= 4; + result[ 2 ] = to_hex_char( c & 0x000F ); + + return result; + } + + template< typename Char_type, class String_type > + bool add_esc_char( Char_type c, String_type& s ) + { + switch( c ) + { + case '"': s += to_str< String_type >( "\\\"" ); return true; + case '\\': s += to_str< String_type >( "\\\\" ); return true; + case '\b': s += to_str< String_type >( "\\b" ); return true; + case '\f': s += to_str< String_type >( "\\f" ); return true; + case '\n': s += to_str< String_type >( "\\n" ); return true; + case '\r': s += to_str< String_type >( "\\r" ); return true; + case '\t': s += to_str< String_type >( "\\t" ); return true; + } + + return false; + } + + template< class String_type > + String_type add_esc_chars( const String_type& s ) + { + typedef typename String_type::const_iterator Iter_type; + typedef typename String_type::value_type Char_type; + + String_type result; + + const Iter_type end( s.end() ); + + for( Iter_type i = s.begin(); i != end; ++i ) + { + const Char_type c( *i ); + + if( add_esc_char( c, result ) ) continue; + + const wint_t unsigned_c( ( c >= 0 ) ? c : 256 + c ); + + if( iswprint( unsigned_c ) ) + { + result += c; + } + else + { + result += non_printable_to_string< String_type >( unsigned_c ); + } + } + + return result; + } + + // this class generates the JSON text, + // it keeps track of the indentation level etc. + // + template< class Value_type, class Ostream_type > + class Generator + { + typedef typename Value_type::Config_type Config_type; + typedef typename Config_type::String_type String_type; + typedef typename Config_type::Object_type Object_type; + typedef typename Config_type::Array_type Array_type; + typedef typename String_type::value_type Char_type; + typedef typename Object_type::value_type Obj_member_type; + + public: + + Generator( const Value_type& value, Ostream_type& os, bool pretty ) + : os_( os ) + , indentation_level_( 0 ) + , pretty_( pretty ) + { + output( value ); + } + + private: + + void output( const Value_type& value ) + { + switch( value.type() ) + { + case obj_type: output( value.get_obj() ); break; + case array_type: output( value.get_array() ); break; + case str_type: output( value.get_str() ); break; + case bool_type: output( value.get_bool() ); break; + case int_type: output_int( value ); break; + case real_type: os_ << std::showpoint << std::setprecision( 16 ) + << value.get_real(); break; + case null_type: os_ << "null"; break; + default: assert( false ); + } + } + + void output( const Object_type& obj ) + { + output_array_or_obj( obj, '{', '}' ); + } + + void output( const Array_type& arr ) + { + output_array_or_obj( arr, '[', ']' ); + } + + void output( const Obj_member_type& member ) + { + output( Config_type::get_name( member ) ); space(); + os_ << ':'; space(); + output( Config_type::get_value( member ) ); + } + + void output_int( const Value_type& value ) + { + if( value.is_uint64() ) + { + os_ << value.get_uint64(); + } + else + { + os_ << value.get_int64(); + } + } + + void output( const String_type& s ) + { + os_ << '"' << add_esc_chars( s ) << '"'; + } + + void output( bool b ) + { + os_ << to_str< String_type >( b ? "true" : "false" ); + } + + template< class T > + void output_array_or_obj( const T& t, Char_type start_char, Char_type end_char ) + { + os_ << start_char; new_line(); + + ++indentation_level_; + + for( typename T::const_iterator i = t.begin(); i != t.end(); ++i ) + { + indent(); output( *i ); + + typename T::const_iterator next = i; + + if( ++next != t.end()) + { + os_ << ','; + } + + new_line(); + } + + --indentation_level_; + + indent(); os_ << end_char; + } + + void indent() + { + if( !pretty_ ) return; + + for( int i = 0; i < indentation_level_; ++i ) + { + os_ << " "; + } + } + + void space() + { + if( pretty_ ) os_ << ' '; + } + + void new_line() + { + if( pretty_ ) os_ << '\n'; + } + + Generator& operator=( const Generator& ); // to prevent "assignment operator could not be generated" warning + + Ostream_type& os_; + int indentation_level_; + bool pretty_; + }; + + template< class Value_type, class Ostream_type > + void write_stream( const Value_type& value, Ostream_type& os, bool pretty ) + { + Generator< Value_type, Ostream_type >( value, os, pretty ); + } + + template< class Value_type > + typename Value_type::String_type write_string( const Value_type& value, bool pretty ) + { + typedef typename Value_type::String_type::value_type Char_type; + + std::basic_ostringstream< Char_type > os; + + write_stream( value, os, pretty ); + + return os.str(); + } +} + +#endif -- cgit v1.2.3 From 75990a46a7e4999729ff67c4268c2241c98e486f Mon Sep 17 00:00:00 2001 From: s_nakamoto Date: Wed, 10 Feb 2010 19:41:22 +0000 Subject: JSON Spirit library from http://www.codeproject.com/KB/recipes/JSON_Spirit.aspx, MIT license git-svn-id: https://bitcoin.svn.sourceforge.net/svnroot/bitcoin/trunk@58 1a98c847-1fd6-4fd8-948a-caf3550aa51b --- json/LICENSE.txt | 24 ++ json/json_spirit.h | 18 ++ json/json_spirit_error_position.h | 54 ++++ json/json_spirit_reader.cpp | 137 +++++++++ json/json_spirit_reader.h | 62 ++++ json/json_spirit_reader_template.h | 612 +++++++++++++++++++++++++++++++++++++ json/json_spirit_stream_reader.h | 70 +++++ json/json_spirit_utils.h | 61 ++++ json/json_spirit_value.cpp | 8 + json/json_spirit_value.h | 532 ++++++++++++++++++++++++++++++++ json/json_spirit_writer.cpp | 95 ++++++ json/json_spirit_writer.h | 50 +++ json/json_spirit_writer_template.h | 245 +++++++++++++++ 13 files changed, 1968 insertions(+) create mode 100644 json/LICENSE.txt create mode 100644 json/json_spirit.h create mode 100644 json/json_spirit_error_position.h create mode 100644 json/json_spirit_reader.cpp create mode 100644 json/json_spirit_reader.h create mode 100644 json/json_spirit_reader_template.h create mode 100644 json/json_spirit_stream_reader.h create mode 100644 json/json_spirit_utils.h create mode 100644 json/json_spirit_value.cpp create mode 100644 json/json_spirit_value.h create mode 100644 json/json_spirit_writer.cpp create mode 100644 json/json_spirit_writer.h create mode 100644 json/json_spirit_writer_template.h diff --git a/json/LICENSE.txt b/json/LICENSE.txt new file mode 100644 index 0000000000..fa193fe7b7 --- /dev/null +++ b/json/LICENSE.txt @@ -0,0 +1,24 @@ +The MIT License + +Copyright (c) 2007 - 2009 John W. Wilkinson + +Permission is hereby granted, free of charge, to any person +obtaining a copy of this software and associated documentation +files (the "Software"), to deal in the Software without +restriction, including without limitation the rights to use, +copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. diff --git a/json/json_spirit.h b/json/json_spirit.h new file mode 100644 index 0000000000..7dac05c360 --- /dev/null +++ b/json/json_spirit.h @@ -0,0 +1,18 @@ +#ifndef JSON_SPIRIT +#define JSON_SPIRIT + +// Copyright John W. Wilkinson 2007 - 2009. +// Distributed under the MIT License, see accompanying file LICENSE.txt + +// json spirit version 4.03 + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +#include "json_spirit_value.h" +#include "json_spirit_reader.h" +#include "json_spirit_writer.h" +#include "json_spirit_utils.h" + +#endif diff --git a/json/json_spirit_error_position.h b/json/json_spirit_error_position.h new file mode 100644 index 0000000000..4a535ff517 --- /dev/null +++ b/json/json_spirit_error_position.h @@ -0,0 +1,54 @@ +#ifndef JSON_SPIRIT_ERROR_POSITION +#define JSON_SPIRIT_ERROR_POSITION + +// Copyright John W. Wilkinson 2007 - 2009. +// Distributed under the MIT License, see accompanying file LICENSE.txt + +// json spirit version 4.03 + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +#include + +namespace json_spirit +{ + // An Error_position exception is thrown by the "read_or_throw" functions below on finding an error. + // Note the "read_or_throw" functions are around 3 times slower than the standard functions "read" + // functions that return a bool. + // + struct Error_position + { + Error_position(); + Error_position( unsigned int line, unsigned int column, const std::string& reason ); + bool operator==( const Error_position& lhs ) const; + unsigned int line_; + unsigned int column_; + std::string reason_; + }; + + inline Error_position::Error_position() + : line_( 0 ) + , column_( 0 ) + { + } + + inline Error_position::Error_position( unsigned int line, unsigned int column, const std::string& reason ) + : line_( line ) + , column_( column ) + , reason_( reason ) + { + } + + inline bool Error_position::operator==( const Error_position& lhs ) const + { + if( this == &lhs ) return true; + + return ( reason_ == lhs.reason_ ) && + ( line_ == lhs.line_ ) && + ( column_ == lhs.column_ ); +} +} + +#endif diff --git a/json/json_spirit_reader.cpp b/json/json_spirit_reader.cpp new file mode 100644 index 0000000000..8e2fb5e2ab --- /dev/null +++ b/json/json_spirit_reader.cpp @@ -0,0 +1,137 @@ +// Copyright John W. Wilkinson 2007 - 2009. +// Distributed under the MIT License, see accompanying file LICENSE.txt + +// json spirit version 4.03 + +#include "json_spirit_reader.h" +#include "json_spirit_reader_template.h" + +using namespace json_spirit; + +bool json_spirit::read( const std::string& s, Value& value ) +{ + return read_string( s, value ); +} + +void json_spirit::read_or_throw( const std::string& s, Value& value ) +{ + read_string_or_throw( s, value ); +} + +bool json_spirit::read( std::istream& is, Value& value ) +{ + return read_stream( is, value ); +} + +void json_spirit::read_or_throw( std::istream& is, Value& value ) +{ + read_stream_or_throw( is, value ); +} + +bool json_spirit::read( std::string::const_iterator& begin, std::string::const_iterator end, Value& value ) +{ + return read_range( begin, end, value ); +} + +void json_spirit::read_or_throw( std::string::const_iterator& begin, std::string::const_iterator end, Value& value ) +{ + begin = read_range_or_throw( begin, end, value ); +} + +#ifndef BOOST_NO_STD_WSTRING + +bool json_spirit::read( const std::wstring& s, wValue& value ) +{ + return read_string( s, value ); +} + +void json_spirit::read_or_throw( const std::wstring& s, wValue& value ) +{ + read_string_or_throw( s, value ); +} + +bool json_spirit::read( std::wistream& is, wValue& value ) +{ + return read_stream( is, value ); +} + +void json_spirit::read_or_throw( std::wistream& is, wValue& value ) +{ + read_stream_or_throw( is, value ); +} + +bool json_spirit::read( std::wstring::const_iterator& begin, std::wstring::const_iterator end, wValue& value ) +{ + return read_range( begin, end, value ); +} + +void json_spirit::read_or_throw( std::wstring::const_iterator& begin, std::wstring::const_iterator end, wValue& value ) +{ + begin = read_range_or_throw( begin, end, value ); +} + +#endif + +bool json_spirit::read( const std::string& s, mValue& value ) +{ + return read_string( s, value ); +} + +void json_spirit::read_or_throw( const std::string& s, mValue& value ) +{ + read_string_or_throw( s, value ); +} + +bool json_spirit::read( std::istream& is, mValue& value ) +{ + return read_stream( is, value ); +} + +void json_spirit::read_or_throw( std::istream& is, mValue& value ) +{ + read_stream_or_throw( is, value ); +} + +bool json_spirit::read( std::string::const_iterator& begin, std::string::const_iterator end, mValue& value ) +{ + return read_range( begin, end, value ); +} + +void json_spirit::read_or_throw( std::string::const_iterator& begin, std::string::const_iterator end, mValue& value ) +{ + begin = read_range_or_throw( begin, end, value ); +} + +#ifndef BOOST_NO_STD_WSTRING + +bool json_spirit::read( const std::wstring& s, wmValue& value ) +{ + return read_string( s, value ); +} + +void json_spirit::read_or_throw( const std::wstring& s, wmValue& value ) +{ + read_string_or_throw( s, value ); +} + +bool json_spirit::read( std::wistream& is, wmValue& value ) +{ + return read_stream( is, value ); +} + +void json_spirit::read_or_throw( std::wistream& is, wmValue& value ) +{ + read_stream_or_throw( is, value ); +} + +bool json_spirit::read( std::wstring::const_iterator& begin, std::wstring::const_iterator end, wmValue& value ) +{ + return read_range( begin, end, value ); +} + +void json_spirit::read_or_throw( std::wstring::const_iterator& begin, std::wstring::const_iterator end, wmValue& value ) +{ + begin = read_range_or_throw( begin, end, value ); +} + +#endif diff --git a/json/json_spirit_reader.h b/json/json_spirit_reader.h new file mode 100644 index 0000000000..a58bfc10fe --- /dev/null +++ b/json/json_spirit_reader.h @@ -0,0 +1,62 @@ +#ifndef JSON_SPIRIT_READER +#define JSON_SPIRIT_READER + +// Copyright John W. Wilkinson 2007 - 2009. +// Distributed under the MIT License, see accompanying file LICENSE.txt + +// json spirit version 4.03 + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +#include "json_spirit_value.h" +#include "json_spirit_error_position.h" +#include + +namespace json_spirit +{ + // functions to reads a JSON values + + bool read( const std::string& s, Value& value ); + bool read( std::istream& is, Value& value ); + bool read( std::string::const_iterator& begin, std::string::const_iterator end, Value& value ); + + void read_or_throw( const std::string& s, Value& value ); + void read_or_throw( std::istream& is, Value& value ); + void read_or_throw( std::string::const_iterator& begin, std::string::const_iterator end, Value& value ); + +#ifndef BOOST_NO_STD_WSTRING + + bool read( const std::wstring& s, wValue& value ); + bool read( std::wistream& is, wValue& value ); + bool read( std::wstring::const_iterator& begin, std::wstring::const_iterator end, wValue& value ); + + void read_or_throw( const std::wstring& s, wValue& value ); + void read_or_throw( std::wistream& is, wValue& value ); + void read_or_throw( std::wstring::const_iterator& begin, std::wstring::const_iterator end, wValue& value ); + +#endif + + bool read( const std::string& s, mValue& value ); + bool read( std::istream& is, mValue& value ); + bool read( std::string::const_iterator& begin, std::string::const_iterator end, mValue& value ); + + void read_or_throw( const std::string& s, mValue& value ); + void read_or_throw( std::istream& is, mValue& value ); + void read_or_throw( std::string::const_iterator& begin, std::string::const_iterator end, mValue& value ); + +#ifndef BOOST_NO_STD_WSTRING + + bool read( const std::wstring& s, wmValue& value ); + bool read( std::wistream& is, wmValue& value ); + bool read( std::wstring::const_iterator& begin, std::wstring::const_iterator end, wmValue& value ); + + void read_or_throw( const std::wstring& s, wmValue& value ); + void read_or_throw( std::wistream& is, wmValue& value ); + void read_or_throw( std::wstring::const_iterator& begin, std::wstring::const_iterator end, wmValue& value ); + +#endif +} + +#endif diff --git a/json/json_spirit_reader_template.h b/json/json_spirit_reader_template.h new file mode 100644 index 0000000000..81cded4346 --- /dev/null +++ b/json/json_spirit_reader_template.h @@ -0,0 +1,612 @@ +#ifndef JSON_SPIRIT_READER_TEMPLATE +#define JSON_SPIRIT_READER_TEMPLATE + +// Copyright John W. Wilkinson 2007 - 2009. +// Distributed under the MIT License, see accompanying file LICENSE.txt + +// json spirit version 4.03 + +#include "json_spirit_value.h" +#include "json_spirit_error_position.h" + +//#define BOOST_SPIRIT_THREADSAFE // uncomment for multithreaded use, requires linking to boost.thread + +#include +#include +#include + +#if BOOST_VERSION >= 103800 + #include + #include + #include + #include + #include + #define spirit_namespace boost::spirit::classic +#else + #include + #include + #include + #include + #include + #define spirit_namespace boost::spirit +#endif + +namespace json_spirit +{ + const spirit_namespace::int_parser < boost::int64_t > int64_p = spirit_namespace::int_parser < boost::int64_t >(); + const spirit_namespace::uint_parser< boost::uint64_t > uint64_p = spirit_namespace::uint_parser< boost::uint64_t >(); + + template< class Iter_type > + bool is_eq( Iter_type first, Iter_type last, const char* c_str ) + { + for( Iter_type i = first; i != last; ++i, ++c_str ) + { + if( *c_str == 0 ) return false; + + if( *i != *c_str ) return false; + } + + return true; + } + + template< class Char_type > + Char_type hex_to_num( const Char_type c ) + { + if( ( c >= '0' ) && ( c <= '9' ) ) return c - '0'; + if( ( c >= 'a' ) && ( c <= 'f' ) ) return c - 'a' + 10; + if( ( c >= 'A' ) && ( c <= 'F' ) ) return c - 'A' + 10; + return 0; + } + + template< class Char_type, class Iter_type > + Char_type hex_str_to_char( Iter_type& begin ) + { + const Char_type c1( *( ++begin ) ); + const Char_type c2( *( ++begin ) ); + + return ( hex_to_num( c1 ) << 4 ) + hex_to_num( c2 ); + } + + template< class Char_type, class Iter_type > + Char_type unicode_str_to_char( Iter_type& begin ) + { + const Char_type c1( *( ++begin ) ); + const Char_type c2( *( ++begin ) ); + const Char_type c3( *( ++begin ) ); + const Char_type c4( *( ++begin ) ); + + return ( hex_to_num( c1 ) << 12 ) + + ( hex_to_num( c2 ) << 8 ) + + ( hex_to_num( c3 ) << 4 ) + + hex_to_num( c4 ); + } + + template< class String_type > + void append_esc_char_and_incr_iter( String_type& s, + typename String_type::const_iterator& begin, + typename String_type::const_iterator end ) + { + typedef typename String_type::value_type Char_type; + + const Char_type c2( *begin ); + + switch( c2 ) + { + case 't': s += '\t'; break; + case 'b': s += '\b'; break; + case 'f': s += '\f'; break; + case 'n': s += '\n'; break; + case 'r': s += '\r'; break; + case '\\': s += '\\'; break; + case '/': s += '/'; break; + case '"': s += '"'; break; + case 'x': + { + if( end - begin >= 3 ) // expecting "xHH..." + { + s += hex_str_to_char< Char_type >( begin ); + } + break; + } + case 'u': + { + if( end - begin >= 5 ) // expecting "uHHHH..." + { + s += unicode_str_to_char< Char_type >( begin ); + } + break; + } + } + } + + template< class String_type > + String_type substitute_esc_chars( typename String_type::const_iterator begin, + typename String_type::const_iterator end ) + { + typedef typename String_type::const_iterator Iter_type; + + if( end - begin < 2 ) return String_type( begin, end ); + + String_type result; + + result.reserve( end - begin ); + + const Iter_type end_minus_1( end - 1 ); + + Iter_type substr_start = begin; + Iter_type i = begin; + + for( ; i < end_minus_1; ++i ) + { + if( *i == '\\' ) + { + result.append( substr_start, i ); + + ++i; // skip the '\' + + append_esc_char_and_incr_iter( result, i, end ); + + substr_start = i + 1; + } + } + + result.append( substr_start, end ); + + return result; + } + + template< class String_type > + String_type get_str_( typename String_type::const_iterator begin, + typename String_type::const_iterator end ) + { + assert( end - begin >= 2 ); + + typedef typename String_type::const_iterator Iter_type; + + Iter_type str_without_quotes( ++begin ); + Iter_type end_without_quotes( --end ); + + return substitute_esc_chars< String_type >( str_without_quotes, end_without_quotes ); + } + + inline std::string get_str( std::string::const_iterator begin, std::string::const_iterator end ) + { + return get_str_< std::string >( begin, end ); + } + + inline std::wstring get_str( std::wstring::const_iterator begin, std::wstring::const_iterator end ) + { + return get_str_< std::wstring >( begin, end ); + } + + template< class String_type, class Iter_type > + String_type get_str( Iter_type begin, Iter_type end ) + { + const String_type tmp( begin, end ); // convert multipass iterators to string iterators + + return get_str( tmp.begin(), tmp.end() ); + } + + // this class's methods get called by the spirit parse resulting + // in the creation of a JSON object or array + // + // NB Iter_type could be a std::string iterator, wstring iterator, a position iterator or a multipass iterator + // + template< class Value_type, class Iter_type > + class Semantic_actions + { + public: + + typedef typename Value_type::Config_type Config_type; + typedef typename Config_type::String_type String_type; + typedef typename Config_type::Object_type Object_type; + typedef typename Config_type::Array_type Array_type; + typedef typename String_type::value_type Char_type; + + Semantic_actions( Value_type& value ) + : value_( value ) + , current_p_( 0 ) + { + } + + void begin_obj( Char_type c ) + { + assert( c == '{' ); + + begin_compound< Object_type >(); + } + + void end_obj( Char_type c ) + { + assert( c == '}' ); + + end_compound(); + } + + void begin_array( Char_type c ) + { + assert( c == '[' ); + + begin_compound< Array_type >(); + } + + void end_array( Char_type c ) + { + assert( c == ']' ); + + end_compound(); + } + + void new_name( Iter_type begin, Iter_type end ) + { + assert( current_p_->type() == obj_type ); + + name_ = get_str< String_type >( begin, end ); + } + + void new_str( Iter_type begin, Iter_type end ) + { + add_to_current( get_str< String_type >( begin, end ) ); + } + + void new_true( Iter_type begin, Iter_type end ) + { + assert( is_eq( begin, end, "true" ) ); + + add_to_current( true ); + } + + void new_false( Iter_type begin, Iter_type end ) + { + assert( is_eq( begin, end, "false" ) ); + + add_to_current( false ); + } + + void new_null( Iter_type begin, Iter_type end ) + { + assert( is_eq( begin, end, "null" ) ); + + add_to_current( Value_type() ); + } + + void new_int( boost::int64_t i ) + { + add_to_current( i ); + } + + void new_uint64( boost::uint64_t ui ) + { + add_to_current( ui ); + } + + void new_real( double d ) + { + add_to_current( d ); + } + + private: + + Semantic_actions& operator=( const Semantic_actions& ); + // to prevent "assignment operator could not be generated" warning + + Value_type* add_first( const Value_type& value ) + { + assert( current_p_ == 0 ); + + value_ = value; + current_p_ = &value_; + return current_p_; + } + + template< class Array_or_obj > + void begin_compound() + { + if( current_p_ == 0 ) + { + add_first( Array_or_obj() ); + } + else + { + stack_.push_back( current_p_ ); + + Array_or_obj new_array_or_obj; // avoid copy by building new array or object in place + + current_p_ = add_to_current( new_array_or_obj ); + } + } + + void end_compound() + { + if( current_p_ != &value_ ) + { + current_p_ = stack_.back(); + + stack_.pop_back(); + } + } + + Value_type* add_to_current( const Value_type& value ) + { + if( current_p_ == 0 ) + { + return add_first( value ); + } + else if( current_p_->type() == array_type ) + { + current_p_->get_array().push_back( value ); + + return ¤t_p_->get_array().back(); + } + + assert( current_p_->type() == obj_type ); + + return &Config_type::add( current_p_->get_obj(), name_, value ); + } + + Value_type& value_; // this is the object or array that is being created + Value_type* current_p_; // the child object or array that is currently being constructed + + std::vector< Value_type* > stack_; // previous child objects and arrays + + String_type name_; // of current name/value pair + }; + + template< typename Iter_type > + void throw_error( spirit_namespace::position_iterator< Iter_type > i, const std::string& reason ) + { + throw Error_position( i.get_position().line, i.get_position().column, reason ); + } + + template< typename Iter_type > + void throw_error( Iter_type i, const std::string& reason ) + { + throw reason; + } + + // the spirit grammer + // + template< class Value_type, class Iter_type > + class Json_grammer : public spirit_namespace::grammar< Json_grammer< Value_type, Iter_type > > + { + public: + + typedef Semantic_actions< Value_type, Iter_type > Semantic_actions_t; + + Json_grammer( Semantic_actions_t& semantic_actions ) + : actions_( semantic_actions ) + { + } + + static void throw_not_value( Iter_type begin, Iter_type end ) + { + throw_error( begin, "not a value" ); + } + + static void throw_not_array( Iter_type begin, Iter_type end ) + { + throw_error( begin, "not an array" ); + } + + static void throw_not_object( Iter_type begin, Iter_type end ) + { + throw_error( begin, "not an object" ); + } + + static void throw_not_pair( Iter_type begin, Iter_type end ) + { + throw_error( begin, "not a pair" ); + } + + static void throw_not_colon( Iter_type begin, Iter_type end ) + { + throw_error( begin, "no colon in pair" ); + } + + static void throw_not_string( Iter_type begin, Iter_type end ) + { + throw_error( begin, "not a string" ); + } + + template< typename ScannerT > + class definition + { + public: + + definition( const Json_grammer& self ) + { + using namespace spirit_namespace; + + typedef typename Value_type::String_type::value_type Char_type; + + // first we convert the semantic action class methods to functors with the + // parameter signature expected by spirit + + typedef boost::function< void( Char_type ) > Char_action; + typedef boost::function< void( Iter_type, Iter_type ) > Str_action; + typedef boost::function< void( double ) > Real_action; + typedef boost::function< void( boost::int64_t ) > Int_action; + typedef boost::function< void( boost::uint64_t ) > Uint64_action; + + Char_action begin_obj ( boost::bind( &Semantic_actions_t::begin_obj, &self.actions_, _1 ) ); + Char_action end_obj ( boost::bind( &Semantic_actions_t::end_obj, &self.actions_, _1 ) ); + Char_action begin_array( boost::bind( &Semantic_actions_t::begin_array, &self.actions_, _1 ) ); + Char_action end_array ( boost::bind( &Semantic_actions_t::end_array, &self.actions_, _1 ) ); + Str_action new_name ( boost::bind( &Semantic_actions_t::new_name, &self.actions_, _1, _2 ) ); + Str_action new_str ( boost::bind( &Semantic_actions_t::new_str, &self.actions_, _1, _2 ) ); + Str_action new_true ( boost::bind( &Semantic_actions_t::new_true, &self.actions_, _1, _2 ) ); + Str_action new_false ( boost::bind( &Semantic_actions_t::new_false, &self.actions_, _1, _2 ) ); + Str_action new_null ( boost::bind( &Semantic_actions_t::new_null, &self.actions_, _1, _2 ) ); + Real_action new_real ( boost::bind( &Semantic_actions_t::new_real, &self.actions_, _1 ) ); + Int_action new_int ( boost::bind( &Semantic_actions_t::new_int, &self.actions_, _1 ) ); + Uint64_action new_uint64 ( boost::bind( &Semantic_actions_t::new_uint64, &self.actions_, _1 ) ); + + // actual grammer + + json_ + = value_ | eps_p[ &throw_not_value ] + ; + + value_ + = string_[ new_str ] + | number_ + | object_ + | array_ + | str_p( "true" ) [ new_true ] + | str_p( "false" )[ new_false ] + | str_p( "null" ) [ new_null ] + ; + + object_ + = ch_p('{')[ begin_obj ] + >> !members_ + >> ( ch_p('}')[ end_obj ] | eps_p[ &throw_not_object ] ) + ; + + members_ + = pair_ >> *( ',' >> pair_ ) + ; + + pair_ + = string_[ new_name ] + >> ( ':' | eps_p[ &throw_not_colon ] ) + >> ( value_ | eps_p[ &throw_not_value ] ) + ; + + array_ + = ch_p('[')[ begin_array ] + >> !elements_ + >> ( ch_p(']')[ end_array ] | eps_p[ &throw_not_array ] ) + ; + + elements_ + = value_ >> *( ',' >> value_ ) + ; + + string_ + = lexeme_d // this causes white space inside a string to be retained + [ + confix_p + ( + '"', + *lex_escape_ch_p, + '"' + ) + ] + ; + + number_ + = strict_real_p[ new_real ] + | int64_p [ new_int ] + | uint64_p [ new_uint64 ] + ; + } + + spirit_namespace::rule< ScannerT > json_, object_, members_, pair_, array_, elements_, value_, string_, number_; + + const spirit_namespace::rule< ScannerT >& start() const { return json_; } + }; + + private: + + Json_grammer& operator=( const Json_grammer& ); // to prevent "assignment operator could not be generated" warning + + Semantic_actions_t& actions_; + }; + + template< class Iter_type, class Value_type > + Iter_type read_range_or_throw( Iter_type begin, Iter_type end, Value_type& value ) + { + Semantic_actions< Value_type, Iter_type > semantic_actions( value ); + + const spirit_namespace::parse_info< Iter_type > info = + spirit_namespace::parse( begin, end, + Json_grammer< Value_type, Iter_type >( semantic_actions ), + spirit_namespace::space_p ); + + if( !info.hit ) + { + assert( false ); // in theory exception should already have been thrown + throw_error( info.stop, "error" ); + } + + return info.stop; + } + + template< class Iter_type, class Value_type > + void add_posn_iter_and_read_range_or_throw( Iter_type begin, Iter_type end, Value_type& value ) + { + typedef spirit_namespace::position_iterator< Iter_type > Posn_iter_t; + + const Posn_iter_t posn_begin( begin, end ); + const Posn_iter_t posn_end( end, end ); + + read_range_or_throw( posn_begin, posn_end, value ); + } + + template< class Iter_type, class Value_type > + bool read_range( Iter_type& begin, Iter_type end, Value_type& value ) + { + try + { + begin = read_range_or_throw( begin, end, value ); + + return true; + } + catch( ... ) + { + return false; + } + } + + template< class String_type, class Value_type > + void read_string_or_throw( const String_type& s, Value_type& value ) + { + add_posn_iter_and_read_range_or_throw( s.begin(), s.end(), value ); + } + + template< class String_type, class Value_type > + bool read_string( const String_type& s, Value_type& value ) + { + typename String_type::const_iterator begin = s.begin(); + + return read_range( begin, s.end(), value ); + } + + template< class Istream_type > + struct Multi_pass_iters + { + typedef typename Istream_type::char_type Char_type; + typedef std::istream_iterator< Char_type, Char_type > istream_iter; + typedef spirit_namespace::multi_pass< istream_iter > Mp_iter; + + Multi_pass_iters( Istream_type& is ) + { + is.unsetf( std::ios::skipws ); + + begin_ = spirit_namespace::make_multi_pass( istream_iter( is ) ); + end_ = spirit_namespace::make_multi_pass( istream_iter() ); + } + + Mp_iter begin_; + Mp_iter end_; + }; + + template< class Istream_type, class Value_type > + bool read_stream( Istream_type& is, Value_type& value ) + { + Multi_pass_iters< Istream_type > mp_iters( is ); + + return read_range( mp_iters.begin_, mp_iters.end_, value ); + } + + template< class Istream_type, class Value_type > + void read_stream_or_throw( Istream_type& is, Value_type& value ) + { + const Multi_pass_iters< Istream_type > mp_iters( is ); + + add_posn_iter_and_read_range_or_throw( mp_iters.begin_, mp_iters.end_, value ); + } +} + +#endif diff --git a/json/json_spirit_stream_reader.h b/json/json_spirit_stream_reader.h new file mode 100644 index 0000000000..a9ceeacf00 --- /dev/null +++ b/json/json_spirit_stream_reader.h @@ -0,0 +1,70 @@ +#ifndef JSON_SPIRIT_READ_STREAM +#define JSON_SPIRIT_READ_STREAM + +// Copyright John W. Wilkinson 2007 - 2009. +// Distributed under the MIT License, see accompanying file LICENSE.txt + +// json spirit version 4.03 + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +#include "json_spirit_reader_template.h" + +namespace json_spirit +{ + // these classes allows you to read multiple top level contiguous values from a stream, + // the normal stream read functions have a bug that prevent multiple top level values + // from being read unless they are separated by spaces + + template< class Istream_type, class Value_type > + class Stream_reader + { + public: + + Stream_reader( Istream_type& is ) + : iters_( is ) + { + } + + bool read_next( Value_type& value ) + { + return read_range( iters_.begin_, iters_.end_, value ); + } + + private: + + typedef Multi_pass_iters< Istream_type > Mp_iters; + + Mp_iters iters_; + }; + + template< class Istream_type, class Value_type > + class Stream_reader_thrower + { + public: + + Stream_reader_thrower( Istream_type& is ) + : iters_( is ) + , posn_begin_( iters_.begin_, iters_.end_ ) + , posn_end_( iters_.end_, iters_.end_ ) + { + } + + void read_next( Value_type& value ) + { + posn_begin_ = read_range_or_throw( posn_begin_, posn_end_, value ); + } + + private: + + typedef Multi_pass_iters< Istream_type > Mp_iters; + typedef spirit_namespace::position_iterator< typename Mp_iters::Mp_iter > Posn_iter_t; + + Mp_iters iters_; + Posn_iter_t posn_begin_, posn_end_; + }; +} + +#endif diff --git a/json/json_spirit_utils.h b/json/json_spirit_utils.h new file mode 100644 index 0000000000..7eb338e7c5 --- /dev/null +++ b/json/json_spirit_utils.h @@ -0,0 +1,61 @@ +#ifndef JSON_SPIRIT_UTILS +#define JSON_SPIRIT_UTILS + +// Copyright John W. Wilkinson 2007 - 2009. +// Distributed under the MIT License, see accompanying file LICENSE.txt + +// json spirit version 4.03 + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +#include "json_spirit_value.h" +#include + +namespace json_spirit +{ + template< class Obj_t, class Map_t > + void obj_to_map( const Obj_t& obj, Map_t& mp_obj ) + { + mp_obj.clear(); + + for( typename Obj_t::const_iterator i = obj.begin(); i != obj.end(); ++i ) + { + mp_obj[ i->name_ ] = i->value_; + } + } + + template< class Obj_t, class Map_t > + void map_to_obj( const Map_t& mp_obj, Obj_t& obj ) + { + obj.clear(); + + for( typename Map_t::const_iterator i = mp_obj.begin(); i != mp_obj.end(); ++i ) + { + obj.push_back( typename Obj_t::value_type( i->first, i->second ) ); + } + } + + typedef std::map< std::string, Value > Mapped_obj; + +#ifndef BOOST_NO_STD_WSTRING + typedef std::map< std::wstring, wValue > wMapped_obj; +#endif + + template< class Object_type, class String_type > + const typename Object_type::value_type::Value_type& find_value( const Object_type& obj, const String_type& name ) + { + for( typename Object_type::const_iterator i = obj.begin(); i != obj.end(); ++i ) + { + if( i->name_ == name ) + { + return i->value_; + } + } + + return Object_type::value_type::Value_type::null; + } +} + +#endif diff --git a/json/json_spirit_value.cpp b/json/json_spirit_value.cpp new file mode 100644 index 0000000000..dd5b50e5d5 --- /dev/null +++ b/json/json_spirit_value.cpp @@ -0,0 +1,8 @@ +/* Copyright (c) 2007 John W Wilkinson + + This source code can be used for any purpose as long as + this comment is retained. */ + +// json spirit version 2.00 + +#include "json_spirit_value.h" diff --git a/json/json_spirit_value.h b/json/json_spirit_value.h new file mode 100644 index 0000000000..e8be355300 --- /dev/null +++ b/json/json_spirit_value.h @@ -0,0 +1,532 @@ +#ifndef JSON_SPIRIT_VALUE +#define JSON_SPIRIT_VALUE + +// Copyright John W. Wilkinson 2007 - 2009. +// Distributed under the MIT License, see accompanying file LICENSE.txt + +// json spirit version 4.03 + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace json_spirit +{ + enum Value_type{ obj_type, array_type, str_type, bool_type, int_type, real_type, null_type }; + + template< class Config > // Config determines whether the value uses std::string or std::wstring and + // whether JSON Objects are represented as vectors or maps + class Value_impl + { + public: + + typedef Config Config_type; + typedef typename Config::String_type String_type; + typedef typename Config::Object_type Object; + typedef typename Config::Array_type Array; + typedef typename String_type::const_pointer Const_str_ptr; // eg const char* + + Value_impl(); // creates null value + Value_impl( Const_str_ptr value ); + Value_impl( const String_type& value ); + Value_impl( const Object& value ); + Value_impl( const Array& value ); + Value_impl( bool value ); + Value_impl( int value ); + Value_impl( boost::int64_t value ); + Value_impl( boost::uint64_t value ); + Value_impl( double value ); + + Value_impl( const Value_impl& other ); + + bool operator==( const Value_impl& lhs ) const; + + Value_impl& operator=( const Value_impl& lhs ); + + Value_type type() const; + + bool is_uint64() const; + bool is_null() const; + + const String_type& get_str() const; + const Object& get_obj() const; + const Array& get_array() const; + bool get_bool() const; + int get_int() const; + boost::int64_t get_int64() const; + boost::uint64_t get_uint64() const; + double get_real() const; + + Object& get_obj(); + Array& get_array(); + + template< typename T > T get_value() const; // example usage: int i = value.get_value< int >(); + // or double d = value.get_value< double >(); + + static const Value_impl null; + + private: + + void check_type( const Value_type vtype ) const; + + typedef boost::variant< String_type, + boost::recursive_wrapper< Object >, boost::recursive_wrapper< Array >, + bool, boost::int64_t, double > Variant; + + Value_type type_; + Variant v_; + bool is_uint64_; + }; + + // vector objects + + template< class Config > + struct Pair_impl + { + typedef typename Config::String_type String_type; + typedef typename Config::Value_type Value_type; + + Pair_impl( const String_type& name, const Value_type& value ); + + bool operator==( const Pair_impl& lhs ) const; + + String_type name_; + Value_type value_; + }; + + template< class String > + struct Config_vector + { + typedef String String_type; + typedef Value_impl< Config_vector > Value_type; + typedef Pair_impl < Config_vector > Pair_type; + typedef std::vector< Value_type > Array_type; + typedef std::vector< Pair_type > Object_type; + + static Value_type& add( Object_type& obj, const String_type& name, const Value_type& value ) + { + obj.push_back( Pair_type( name , value ) ); + + return obj.back().value_; + } + + static String_type get_name( const Pair_type& pair ) + { + return pair.name_; + } + + static Value_type get_value( const Pair_type& pair ) + { + return pair.value_; + } + }; + + // typedefs for ASCII + + typedef Config_vector< std::string > Config; + + typedef Config::Value_type Value; + typedef Config::Pair_type Pair; + typedef Config::Object_type Object; + typedef Config::Array_type Array; + + // typedefs for Unicode + +#ifndef BOOST_NO_STD_WSTRING + + typedef Config_vector< std::wstring > wConfig; + + typedef wConfig::Value_type wValue; + typedef wConfig::Pair_type wPair; + typedef wConfig::Object_type wObject; + typedef wConfig::Array_type wArray; +#endif + + // map objects + + template< class String > + struct Config_map + { + typedef String String_type; + typedef Value_impl< Config_map > Value_type; + typedef std::vector< Value_type > Array_type; + typedef std::map< String_type, Value_type > Object_type; + typedef typename Object_type::value_type Pair_type; + + static Value_type& add( Object_type& obj, const String_type& name, const Value_type& value ) + { + return obj[ name ] = value; + } + + static String_type get_name( const Pair_type& pair ) + { + return pair.first; + } + + static Value_type get_value( const Pair_type& pair ) + { + return pair.second; + } + }; + + // typedefs for ASCII + + typedef Config_map< std::string > mConfig; + + typedef mConfig::Value_type mValue; + typedef mConfig::Object_type mObject; + typedef mConfig::Array_type mArray; + + // typedefs for Unicode + +#ifndef BOOST_NO_STD_WSTRING + + typedef Config_map< std::wstring > wmConfig; + + typedef wmConfig::Value_type wmValue; + typedef wmConfig::Object_type wmObject; + typedef wmConfig::Array_type wmArray; + +#endif + + /////////////////////////////////////////////////////////////////////////////////////////////// + // + // implementation + + template< class Config > + const Value_impl< Config > Value_impl< Config >::null; + + template< class Config > + Value_impl< Config >::Value_impl() + : type_( null_type ) + , is_uint64_( false ) + { + } + + template< class Config > + Value_impl< Config >::Value_impl( const Const_str_ptr value ) + : type_( str_type ) + , v_( String_type( value ) ) + , is_uint64_( false ) + { + } + + template< class Config > + Value_impl< Config >::Value_impl( const String_type& value ) + : type_( str_type ) + , v_( value ) + , is_uint64_( false ) + { + } + + template< class Config > + Value_impl< Config >::Value_impl( const Object& value ) + : type_( obj_type ) + , v_( value ) + , is_uint64_( false ) + { + } + + template< class Config > + Value_impl< Config >::Value_impl( const Array& value ) + : type_( array_type ) + , v_( value ) + , is_uint64_( false ) + { + } + + template< class Config > + Value_impl< Config >::Value_impl( bool value ) + : type_( bool_type ) + , v_( value ) + , is_uint64_( false ) + { + } + + template< class Config > + Value_impl< Config >::Value_impl( int value ) + : type_( int_type ) + , v_( static_cast< boost::int64_t >( value ) ) + , is_uint64_( false ) + { + } + + template< class Config > + Value_impl< Config >::Value_impl( boost::int64_t value ) + : type_( int_type ) + , v_( value ) + , is_uint64_( false ) + { + } + + template< class Config > + Value_impl< Config >::Value_impl( boost::uint64_t value ) + : type_( int_type ) + , v_( static_cast< boost::int64_t >( value ) ) + , is_uint64_( true ) + { + } + + template< class Config > + Value_impl< Config >::Value_impl( double value ) + : type_( real_type ) + , v_( value ) + , is_uint64_( false ) + { + } + + template< class Config > + Value_impl< Config >::Value_impl( const Value_impl< Config >& other ) + : type_( other.type() ) + , v_( other.v_ ) + , is_uint64_( other.is_uint64_ ) + { + } + + template< class Config > + Value_impl< Config >& Value_impl< Config >::operator=( const Value_impl& lhs ) + { + Value_impl tmp( lhs ); + + std::swap( type_, tmp.type_ ); + std::swap( v_, tmp.v_ ); + std::swap( is_uint64_, tmp.is_uint64_ ); + + return *this; + } + + template< class Config > + bool Value_impl< Config >::operator==( const Value_impl& lhs ) const + { + if( this == &lhs ) return true; + + if( type() != lhs.type() ) return false; + + return v_ == lhs.v_; + } + + template< class Config > + Value_type Value_impl< Config >::type() const + { + return type_; + } + + template< class Config > + bool Value_impl< Config >::is_uint64() const + { + return is_uint64_; + } + + template< class Config > + bool Value_impl< Config >::is_null() const + { + return type() == null_type; + } + + template< class Config > + void Value_impl< Config >::check_type( const Value_type vtype ) const + { + if( type() != vtype ) + { + std::ostringstream os; + + os << "value type is " << type() << " not " << vtype; + + throw std::runtime_error( os.str() ); + } + } + + template< class Config > + const typename Config::String_type& Value_impl< Config >::get_str() const + { + check_type( str_type ); + + return *boost::get< String_type >( &v_ ); + } + + template< class Config > + const typename Value_impl< Config >::Object& Value_impl< Config >::get_obj() const + { + check_type( obj_type ); + + return *boost::get< Object >( &v_ ); + } + + template< class Config > + const typename Value_impl< Config >::Array& Value_impl< Config >::get_array() const + { + check_type( array_type ); + + return *boost::get< Array >( &v_ ); + } + + template< class Config > + bool Value_impl< Config >::get_bool() const + { + check_type( bool_type ); + + return boost::get< bool >( v_ ); + } + + template< class Config > + int Value_impl< Config >::get_int() const + { + check_type( int_type ); + + return static_cast< int >( get_int64() ); + } + + template< class Config > + boost::int64_t Value_impl< Config >::get_int64() const + { + check_type( int_type ); + + return boost::get< boost::int64_t >( v_ ); + } + + template< class Config > + boost::uint64_t Value_impl< Config >::get_uint64() const + { + check_type( int_type ); + + return static_cast< boost::uint64_t >( get_int64() ); + } + + template< class Config > + double Value_impl< Config >::get_real() const + { + if( type() == int_type ) + { + return is_uint64() ? static_cast< double >( get_uint64() ) + : static_cast< double >( get_int64() ); + } + + check_type( real_type ); + + return boost::get< double >( v_ ); + } + + template< class Config > + typename Value_impl< Config >::Object& Value_impl< Config >::get_obj() + { + check_type( obj_type ); + + return *boost::get< Object >( &v_ ); + } + + template< class Config > + typename Value_impl< Config >::Array& Value_impl< Config >::get_array() + { + check_type( array_type ); + + return *boost::get< Array >( &v_ ); + } + + template< class Config > + Pair_impl< Config >::Pair_impl( const String_type& name, const Value_type& value ) + : name_( name ) + , value_( value ) + { + } + + template< class Config > + bool Pair_impl< Config >::operator==( const Pair_impl< Config >& lhs ) const + { + if( this == &lhs ) return true; + + return ( name_ == lhs.name_ ) && ( value_ == lhs.value_ ); + } + + // converts a C string, ie. 8 bit char array, to a string object + // + template < class String_type > + String_type to_str( const char* c_str ) + { + String_type result; + + for( const char* p = c_str; *p != 0; ++p ) + { + result += *p; + } + + return result; + } + + // + + namespace internal_ + { + template< typename T > + struct Type_to_type + { + }; + + template< class Value > + int get_value( const Value& value, Type_to_type< int > ) + { + return value.get_int(); + } + + template< class Value > + boost::int64_t get_value( const Value& value, Type_to_type< boost::int64_t > ) + { + return value.get_int64(); + } + + template< class Value > + boost::uint64_t get_value( const Value& value, Type_to_type< boost::uint64_t > ) + { + return value.get_uint64(); + } + + template< class Value > + double get_value( const Value& value, Type_to_type< double > ) + { + return value.get_real(); + } + + template< class Value > + typename Value::String_type get_value( const Value& value, Type_to_type< typename Value::String_type > ) + { + return value.get_str(); + } + + template< class Value > + typename Value::Array get_value( const Value& value, Type_to_type< typename Value::Array > ) + { + return value.get_array(); + } + + template< class Value > + typename Value::Object get_value( const Value& value, Type_to_type< typename Value::Object > ) + { + return value.get_obj(); + } + + template< class Value > + bool get_value( const Value& value, Type_to_type< bool > ) + { + return value.get_bool(); + } + } + + template< class Config > + template< typename T > + T Value_impl< Config >::get_value() const + { + return internal_::get_value( *this, internal_::Type_to_type< T >() ); + } +} + +#endif diff --git a/json/json_spirit_writer.cpp b/json/json_spirit_writer.cpp new file mode 100644 index 0000000000..f3367b68de --- /dev/null +++ b/json/json_spirit_writer.cpp @@ -0,0 +1,95 @@ +// Copyright John W. Wilkinson 2007 - 2009. +// Distributed under the MIT License, see accompanying file LICENSE.txt + +// json spirit version 4.03 + +#include "json_spirit_writer.h" +#include "json_spirit_writer_template.h" + +void json_spirit::write( const Value& value, std::ostream& os ) +{ + write_stream( value, os, false ); +} + +void json_spirit::write_formatted( const Value& value, std::ostream& os ) +{ + write_stream( value, os, true ); +} + +std::string json_spirit::write( const Value& value ) +{ + return write_string( value, false ); +} + +std::string json_spirit::write_formatted( const Value& value ) +{ + return write_string( value, true ); +} + +#ifndef BOOST_NO_STD_WSTRING + +void json_spirit::write( const wValue& value, std::wostream& os ) +{ + write_stream( value, os, false ); +} + +void json_spirit::write_formatted( const wValue& value, std::wostream& os ) +{ + write_stream( value, os, true ); +} + +std::wstring json_spirit::write( const wValue& value ) +{ + return write_string( value, false ); +} + +std::wstring json_spirit::write_formatted( const wValue& value ) +{ + return write_string( value, true ); +} + +#endif + +void json_spirit::write( const mValue& value, std::ostream& os ) +{ + write_stream( value, os, false ); +} + +void json_spirit::write_formatted( const mValue& value, std::ostream& os ) +{ + write_stream( value, os, true ); +} + +std::string json_spirit::write( const mValue& value ) +{ + return write_string( value, false ); +} + +std::string json_spirit::write_formatted( const mValue& value ) +{ + return write_string( value, true ); +} + +#ifndef BOOST_NO_STD_WSTRING + +void json_spirit::write( const wmValue& value, std::wostream& os ) +{ + write_stream( value, os, false ); +} + +void json_spirit::write_formatted( const wmValue& value, std::wostream& os ) +{ + write_stream( value, os, true ); +} + +std::wstring json_spirit::write( const wmValue& value ) +{ + return write_string( value, false ); +} + +std::wstring json_spirit::write_formatted( const wmValue& value ) +{ + return write_string( value, true ); +} + +#endif diff --git a/json/json_spirit_writer.h b/json/json_spirit_writer.h new file mode 100644 index 0000000000..1b67b512df --- /dev/null +++ b/json/json_spirit_writer.h @@ -0,0 +1,50 @@ +#ifndef JSON_SPIRIT_WRITER +#define JSON_SPIRIT_WRITER + +// Copyright John W. Wilkinson 2007 - 2009. +// Distributed under the MIT License, see accompanying file LICENSE.txt + +// json spirit version 4.03 + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +#include "json_spirit_value.h" +#include + +namespace json_spirit +{ + // functions to convert JSON Values to text, + // the "formatted" versions add whitespace to format the output nicely + + void write ( const Value& value, std::ostream& os ); + void write_formatted( const Value& value, std::ostream& os ); + std::string write ( const Value& value ); + std::string write_formatted( const Value& value ); + +#ifndef BOOST_NO_STD_WSTRING + + void write ( const wValue& value, std::wostream& os ); + void write_formatted( const wValue& value, std::wostream& os ); + std::wstring write ( const wValue& value ); + std::wstring write_formatted( const wValue& value ); + +#endif + + void write ( const mValue& value, std::ostream& os ); + void write_formatted( const mValue& value, std::ostream& os ); + std::string write ( const mValue& value ); + std::string write_formatted( const mValue& value ); + +#ifndef BOOST_NO_STD_WSTRING + + void write ( const wmValue& value, std::wostream& os ); + void write_formatted( const wmValue& value, std::wostream& os ); + std::wstring write ( const wmValue& value ); + std::wstring write_formatted( const wmValue& value ); + +#endif +} + +#endif diff --git a/json/json_spirit_writer_template.h b/json/json_spirit_writer_template.h new file mode 100644 index 0000000000..c993756555 --- /dev/null +++ b/json/json_spirit_writer_template.h @@ -0,0 +1,245 @@ +#ifndef JSON_SPIRIT_WRITER_TEMPLATE +#define JSON_SPIRIT_WRITER_TEMPLATE + +// Copyright John W. Wilkinson 2007 - 2009. +// Distributed under the MIT License, see accompanying file LICENSE.txt + +// json spirit version 4.03 + +#include "json_spirit_value.h" + +#include +#include +#include + +namespace json_spirit +{ + inline char to_hex_char( unsigned int c ) + { + assert( c <= 0xF ); + + const char ch = static_cast< char >( c ); + + if( ch < 10 ) return '0' + ch; + + return 'A' - 10 + ch; + } + + template< class String_type > + String_type non_printable_to_string( unsigned int c ) + { + typedef typename String_type::value_type Char_type; + + String_type result( 6, '\\' ); + + result[1] = 'u'; + + result[ 5 ] = to_hex_char( c & 0x000F ); c >>= 4; + result[ 4 ] = to_hex_char( c & 0x000F ); c >>= 4; + result[ 3 ] = to_hex_char( c & 0x000F ); c >>= 4; + result[ 2 ] = to_hex_char( c & 0x000F ); + + return result; + } + + template< typename Char_type, class String_type > + bool add_esc_char( Char_type c, String_type& s ) + { + switch( c ) + { + case '"': s += to_str< String_type >( "\\\"" ); return true; + case '\\': s += to_str< String_type >( "\\\\" ); return true; + case '\b': s += to_str< String_type >( "\\b" ); return true; + case '\f': s += to_str< String_type >( "\\f" ); return true; + case '\n': s += to_str< String_type >( "\\n" ); return true; + case '\r': s += to_str< String_type >( "\\r" ); return true; + case '\t': s += to_str< String_type >( "\\t" ); return true; + } + + return false; + } + + template< class String_type > + String_type add_esc_chars( const String_type& s ) + { + typedef typename String_type::const_iterator Iter_type; + typedef typename String_type::value_type Char_type; + + String_type result; + + const Iter_type end( s.end() ); + + for( Iter_type i = s.begin(); i != end; ++i ) + { + const Char_type c( *i ); + + if( add_esc_char( c, result ) ) continue; + + const wint_t unsigned_c( ( c >= 0 ) ? c : 256 + c ); + + if( iswprint( unsigned_c ) ) + { + result += c; + } + else + { + result += non_printable_to_string< String_type >( unsigned_c ); + } + } + + return result; + } + + // this class generates the JSON text, + // it keeps track of the indentation level etc. + // + template< class Value_type, class Ostream_type > + class Generator + { + typedef typename Value_type::Config_type Config_type; + typedef typename Config_type::String_type String_type; + typedef typename Config_type::Object_type Object_type; + typedef typename Config_type::Array_type Array_type; + typedef typename String_type::value_type Char_type; + typedef typename Object_type::value_type Obj_member_type; + + public: + + Generator( const Value_type& value, Ostream_type& os, bool pretty ) + : os_( os ) + , indentation_level_( 0 ) + , pretty_( pretty ) + { + output( value ); + } + + private: + + void output( const Value_type& value ) + { + switch( value.type() ) + { + case obj_type: output( value.get_obj() ); break; + case array_type: output( value.get_array() ); break; + case str_type: output( value.get_str() ); break; + case bool_type: output( value.get_bool() ); break; + case int_type: output_int( value ); break; + case real_type: os_ << std::showpoint << std::setprecision( 16 ) + << value.get_real(); break; + case null_type: os_ << "null"; break; + default: assert( false ); + } + } + + void output( const Object_type& obj ) + { + output_array_or_obj( obj, '{', '}' ); + } + + void output( const Array_type& arr ) + { + output_array_or_obj( arr, '[', ']' ); + } + + void output( const Obj_member_type& member ) + { + output( Config_type::get_name( member ) ); space(); + os_ << ':'; space(); + output( Config_type::get_value( member ) ); + } + + void output_int( const Value_type& value ) + { + if( value.is_uint64() ) + { + os_ << value.get_uint64(); + } + else + { + os_ << value.get_int64(); + } + } + + void output( const String_type& s ) + { + os_ << '"' << add_esc_chars( s ) << '"'; + } + + void output( bool b ) + { + os_ << to_str< String_type >( b ? "true" : "false" ); + } + + template< class T > + void output_array_or_obj( const T& t, Char_type start_char, Char_type end_char ) + { + os_ << start_char; new_line(); + + ++indentation_level_; + + for( typename T::const_iterator i = t.begin(); i != t.end(); ++i ) + { + indent(); output( *i ); + + typename T::const_iterator next = i; + + if( ++next != t.end()) + { + os_ << ','; + } + + new_line(); + } + + --indentation_level_; + + indent(); os_ << end_char; + } + + void indent() + { + if( !pretty_ ) return; + + for( int i = 0; i < indentation_level_; ++i ) + { + os_ << " "; + } + } + + void space() + { + if( pretty_ ) os_ << ' '; + } + + void new_line() + { + if( pretty_ ) os_ << '\n'; + } + + Generator& operator=( const Generator& ); // to prevent "assignment operator could not be generated" warning + + Ostream_type& os_; + int indentation_level_; + bool pretty_; + }; + + template< class Value_type, class Ostream_type > + void write_stream( const Value_type& value, Ostream_type& os, bool pretty ) + { + Generator< Value_type, Ostream_type >( value, os, pretty ); + } + + template< class Value_type > + typename Value_type::String_type write_string( const Value_type& value, bool pretty ) + { + typedef typename Value_type::String_type::value_type Char_type; + + std::basic_ostringstream< Char_type > os; + + write_stream( value, os, pretty ); + + return os.str(); + } +} + +#endif -- cgit v1.2.3 From 73278c0a16cf0d68fb9011203a2112c3499df195 Mon Sep 17 00:00:00 2001 From: s_nakamoto Date: Wed, 10 Feb 2010 19:46:04 +0000 Subject: better error message in check_type(), tell the types by name instead of by number --- json/json_spirit_value.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/json/json_spirit_value.h b/json/json_spirit_value.h index e8be355300..e9bcd36b80 100644 --- a/json/json_spirit_value.h +++ b/json/json_spirit_value.h @@ -24,6 +24,7 @@ namespace json_spirit { enum Value_type{ obj_type, array_type, str_type, bool_type, int_type, real_type, null_type }; + static const char* Value_type_name[]={"obj", "array", "str", "bool", "int", "real", "null"}; template< class Config > // Config determines whether the value uses std::string or std::wstring and // whether JSON Objects are represented as vectors or maps @@ -341,7 +342,8 @@ namespace json_spirit { std::ostringstream os; - os << "value type is " << type() << " not " << vtype; + /// satoshi: tell the types by name instead of by number + os << "value is type " << Value_type_name[type()] << ", expected " << Value_type_name[vtype]; throw std::runtime_error( os.str() ); } -- cgit v1.2.3 From fa9dbd6b62ab161c29c9b8cf97b9c8da8ef4346e Mon Sep 17 00:00:00 2001 From: s_nakamoto Date: Wed, 10 Feb 2010 19:46:04 +0000 Subject: better error message in check_type(), tell the types by name instead of by number git-svn-id: https://bitcoin.svn.sourceforge.net/svnroot/bitcoin/trunk@59 1a98c847-1fd6-4fd8-948a-caf3550aa51b --- json/json_spirit_value.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/json/json_spirit_value.h b/json/json_spirit_value.h index e8be355300..e9bcd36b80 100644 --- a/json/json_spirit_value.h +++ b/json/json_spirit_value.h @@ -24,6 +24,7 @@ namespace json_spirit { enum Value_type{ obj_type, array_type, str_type, bool_type, int_type, real_type, null_type }; + static const char* Value_type_name[]={"obj", "array", "str", "bool", "int", "real", "null"}; template< class Config > // Config determines whether the value uses std::string or std::wstring and // whether JSON Objects are represented as vectors or maps @@ -341,7 +342,8 @@ namespace json_spirit { std::ostringstream os; - os << "value type is " << type() << " not " << vtype; + /// satoshi: tell the types by name instead of by number + os << "value is type " << Value_type_name[type()] << ", expected " << Value_type_name[vtype]; throw std::runtime_error( os.str() ); } -- cgit v1.2.3 From 22f721dbf23cf5ce9e3ded9bcfb65a3894cc0f8c Mon Sep 17 00:00:00 2001 From: s_nakamoto Date: Fri, 12 Feb 2010 20:38:44 +0000 Subject: command line and JSON-RPC first draft, requires Boost 1.35 or higher for boost::asio, added SetBitcoinAddress and GetBitcoinAddress methods on CScript, critsect interlocks around mapAddressBook, added some random delays in tx broadcast to improve privacy, now compiles with MSVC 8.0 --- bignum.h | 33 ++- build-msw.txt | 27 ++- db.h | 10 +- headers.h | 9 +- irc.cpp | 2 +- irc.h | 6 +- license.txt | 2 +- main.cpp | 151 +++++++++---- main.h | 9 +- makefile | 25 +- makefile.unix.wx2.8 | 20 +- makefile.unix.wx2.9 | 20 +- makefile.vc | 25 +- net.cpp | 15 +- net.h | 3 +- rpc.cpp | 641 ++++++++++++++++++++++++++++++++++++++++++++++++++++ rpc.h | 6 + script.cpp | 9 +- script.h | 44 +++- serialize.h | 4 +- ui.cpp | 436 ++++++++++++++++++----------------- util.cpp | 3 +- util.h | 18 +- 23 files changed, 1186 insertions(+), 332 deletions(-) create mode 100644 rpc.cpp create mode 100644 rpc.h diff --git a/bignum.h b/bignum.h index 8aa4e9c4ff..e1ab165b2c 100644 --- a/bignum.h +++ b/bignum.h @@ -1,4 +1,4 @@ -// Copyright (c) 2009 Satoshi Nakamoto +// 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. @@ -309,6 +309,37 @@ public: *this = 0 - *this; } + std::string ToString(int nBase=10) const + { + CAutoBN_CTX pctx; + CBigNum bnBase = nBase; + CBigNum bn0 = 0; + string str; + CBigNum bn = *this; + BN_set_negative(&bn, false); + CBigNum dv; + CBigNum rem; + if (BN_cmp(&bn, &bn0) == 0) + return "0"; + while (BN_cmp(&bn, &bn0) > 0) + { + if (!BN_div(&dv, &rem, &bn, &bnBase, pctx)) + throw bignum_error("CBigNum::ToString() : BN_div failed"); + bn = dv; + unsigned int c = rem.getulong(); + str += "0123456789abcdef"[c]; + } + if (BN_is_negative(this)) + str += "-"; + reverse(str.begin(), str.end()); + return str; + } + + std::string GetHex() const + { + return ToString(16); + } + unsigned int GetSerializeSize(int nType=0, int nVersion=VERSION) const { return ::GetSerializeSize(getvch(), nType, nVersion); diff --git a/build-msw.txt b/build-msw.txt index 56a38b0286..9786255e1f 100644 --- a/build-msw.txt +++ b/build-msw.txt @@ -1,6 +1,6 @@ Bitcoin v0.2.0 BETA -Copyright (c) 2009 Satoshi Nakamoto +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. This product includes software developed by the OpenSSL Project for use in @@ -13,8 +13,16 @@ WINDOWS BUILD NOTES Compilers Supported ------------------- -MinGW GCC -Microsoft Visual C++ 6.0 SP6 +MinGW GCC (recommended) + +MSVC 6.0 SP6: You'll need Boost version 1.34 because they dropped support +for MSVC 6.0 after that. However, they didn't add Asio until 1.35. +You should still be able to build with MSVC 6.0 by adding Asio to 1.34 by +unpacking boost_asio_*.zip into the boost directory: +http://sourceforge.net/projects/asio/files/asio + +MSVC 8.0 (2005) SP1 has been tested. Note: MSVC 7.0 and up have a habit of +linking to runtime DLLs that are not installed on XP by default. Dependencies @@ -22,8 +30,7 @@ Dependencies Libraries you need to download separately and build: default path download -wxWidgets \wxwidgets http://www.wxwidgets.org/downloads/ - or prebuilt: http://wxpack.sourceforge.net +wxWidgets \wxwidgets prebuilt: http://wxpack.sourceforge.net OpenSSL \openssl http://www.openssl.org/source/ Berkeley DB \db http://www.oracle.com/technology/software/products/berkeley-db/index.html Boost \boost http://www.boost.org/users/download/ @@ -89,3 +96,13 @@ Using MinGW and MSYS: cd \db\build_unix sh ../dist/configure --enable-mingw --enable-cxx make + + +Boost +----- +download bjam.exe from +http://sourceforge.net/project/showfiles.php?group_id=7586&package_id=72941 +cd \boost +bjam toolset=gcc --build-type=complete stage +or +bjam toolset=msvc --build-type=complete stage diff --git a/db.h b/db.h index d32d2d5d2f..538076b5aa 100644 --- a/db.h +++ b/db.h @@ -1,8 +1,7 @@ -// Copyright (c) 2009 Satoshi Nakamoto +// 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 class CTransaction; class CTxIndex; class CDiskBlockIndex; @@ -14,6 +13,7 @@ class CAddress; class CWalletTx; extern map mapAddressBook; +extern CCriticalSection cs_mapAddressBook; extern bool fClient; @@ -359,15 +359,17 @@ public: bool WriteName(const string& strAddress, const string& strName) { + CRITICAL_BLOCK(cs_mapAddressBook) + mapAddressBook[strAddress] = strName; nWalletDBUpdated++; - mapAddressBook[strAddress] = strName; return Write(make_pair(string("name"), strAddress), strName); } bool EraseName(const string& strAddress) { + CRITICAL_BLOCK(cs_mapAddressBook) + mapAddressBook.erase(strAddress); nWalletDBUpdated++; - mapAddressBook.erase(strAddress); return Erase(make_pair(string("name"), strAddress)); } diff --git a/headers.h b/headers.h index 45be4b65d1..dda4f9caf2 100644 --- a/headers.h +++ b/headers.h @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include @@ -36,6 +37,7 @@ #include #include #include +#include #include #include #include @@ -53,6 +55,8 @@ #include #include #include +#include +#include #ifdef __WXMSW__ #include @@ -73,8 +77,6 @@ #include #include #include -#include -#include #endif #ifdef __BSD__ #include @@ -85,8 +87,6 @@ using namespace std; using namespace boost; - - #include "strlcpy.h" #include "serialize.h" #include "uint256.h" @@ -100,6 +100,7 @@ using namespace boost; #include "irc.h" #include "main.h" #include "market.h" +#include "rpc.h" #include "uibase.h" #include "ui.h" diff --git a/irc.cpp b/irc.cpp index f38db6bbb0..9d563cce8d 100644 --- a/irc.cpp +++ b/irc.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2009 Satoshi Nakamoto +// 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. diff --git a/irc.h b/irc.h index c69fd9ee97..13de570b16 100644 --- a/irc.h +++ b/irc.h @@ -1,8 +1,8 @@ -// Copyright (c) 2009 Satoshi Nakamoto +// 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. -extern bool RecvLine(SOCKET hSocket, string& strLine); -extern void ThreadIRCSeed(void* parg); +bool RecvLine(SOCKET hSocket, string& strLine); +void ThreadIRCSeed(void* parg); extern int nGotIRCAddresses; diff --git a/license.txt b/license.txt index 3844dfb429..f96fa98f4c 100644 --- a/license.txt +++ b/license.txt @@ -1,4 +1,4 @@ -Copyright (c) 2009 Satoshi Nakamoto +Copyright (c) 2009-2010 Satoshi Nakamoto Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/main.cpp b/main.cpp index 53acf8a753..90d239fa0f 100644 --- a/main.cpp +++ b/main.cpp @@ -26,6 +26,7 @@ CBlockIndex* pindexGenesisBlock = NULL; int nBestHeight = -1; uint256 hashBestChain = 0; CBlockIndex* pindexBest = NULL; +int64 nTimeBestReceived = 0; map mapOrphanBlocks; multimap mapOrphanBlocksByPrev; @@ -45,6 +46,9 @@ CKey keyUser; map mapRequestCount; CCriticalSection cs_mapRequestCount; +map mapAddressBook; +CCriticalSection cs_mapAddressBook; + // Settings int fGenerateBitcoins = false; int64 nTransactionFee = 0; @@ -573,7 +577,7 @@ bool CTransaction::RemoveFromMemoryPool() -int CMerkleTx::GetDepthInMainChain() const +int CMerkleTx::GetDepthInMainChain(int& nHeightRet) const { if (hashBlock == 0 || nIndex == -1) return 0; @@ -594,6 +598,7 @@ int CMerkleTx::GetDepthInMainChain() const fMerkleVerified = true; } + nHeightRet = pindex->nHeight; return pindexBest->nHeight - pindex->nHeight + 1; } @@ -708,15 +713,20 @@ void CWalletTx::RelayWalletTransaction(CTxDB& txdb) } } -void RelayWalletTransactions() +void ResendWalletTransactions() { - static int64 nLastTime; - if (GetTime() - nLastTime < 10 * 60) + // Do this infrequently and randomly to avoid giving away + // that these are our transactions. + static int64 nNextTime; + if (GetTime() < nNextTime) + return; + bool fFirst = (nNextTime == 0); + nNextTime = GetTime() + GetRand(120 * 60); + if (fFirst) return; - nLastTime = GetTime(); // Rebroadcast any of our txes that aren't in a block yet - printf("RelayWalletTransactions()\n"); + printf("ResendWalletTransactions()\n"); CTxDB txdb("r"); CRITICAL_BLOCK(cs_mapWallet) { @@ -725,7 +735,10 @@ void RelayWalletTransactions() foreach(PAIRTYPE(const uint256, CWalletTx)& item, mapWallet) { CWalletTx& wtx = item.second; - mapSorted.insert(make_pair(wtx.nTimeReceived, &wtx)); + // Don't rebroadcast until it's had plenty of time that + // it should have gotten in already by now. + if (nTimeBestReceived - wtx.nTimeReceived > 60 * 60) + mapSorted.insert(make_pair(wtx.nTimeReceived, &wtx)); } foreach(PAIRTYPE(const unsigned int, CWalletTx*)& item, mapSorted) { @@ -1219,10 +1232,11 @@ bool CBlock::AddToBlockIndex(unsigned int nFile, unsigned int nBlockPos) } } - // New best link + // New best block hashBestChain = hash; pindexBest = pindexNew; nBestHeight = pindexBest->nHeight; + nTimeBestReceived = GetTime(); nTransactionsUpdated++; printf("AddToBlockIndex: new best=%s height=%d\n", hashBestChain.ToString().substr(0,16).c_str(), nBestHeight); } @@ -1232,9 +1246,6 @@ bool CBlock::AddToBlockIndex(unsigned int nFile, unsigned int nBlockPos) if (pindexNew == pindexBest) { - // Relay wallet transactions that haven't gotten in yet - RelayWalletTransactions(); - // Notify UI to display prev block's coinbase if it was ours static uint256 hashPrevBestCoinBase; CRITICAL_BLOCK(cs_mapWallet) @@ -2248,7 +2259,7 @@ bool SendMessages(CNode* pto) return true; // Keep-alive ping - if (pto->nLastSend && GetTime() - pto->nLastSend > 12 * 60 && pto->vSend.empty()) + if (pto->nLastSend && GetTime() - pto->nLastSend > 30 * 60 && pto->vSend.empty()) pto->PushMessage("ping"); // Address refresh broadcast @@ -2270,60 +2281,81 @@ bool SendMessages(CNode* pto) } } + // Delay tx inv messages to protect privacy, + // trickle them out to a few nodes at a time. + bool fSendTxInv = false; + if (GetTimeMillis() - pto->nLastSentTxInv > 1800 + GetRand(200)) + { + pto->nLastSentTxInv = GetTimeMillis(); + fSendTxInv = true; + } + + // Resend wallet transactions that haven't gotten in a block yet + ResendWalletTransactions(); + // // Message: addr // - vector vAddrToSend; - vAddrToSend.reserve(pto->vAddrToSend.size()); + vector vAddr; + vAddr.reserve(pto->vAddrToSend.size()); foreach(const CAddress& addr, pto->vAddrToSend) { // returns true if wasn't already contained in the set if (pto->setAddrKnown.insert(addr).second) { - vAddrToSend.push_back(addr); - if (vAddrToSend.size() >= 1000) + vAddr.push_back(addr); + if (vAddr.size() >= 1000) { - pto->PushMessage("addr", vAddrToSend); - vAddrToSend.clear(); + pto->PushMessage("addr", vAddr); + vAddr.clear(); } } } pto->vAddrToSend.clear(); - if (!vAddrToSend.empty()) - pto->PushMessage("addr", vAddrToSend); + if (!vAddr.empty()) + pto->PushMessage("addr", vAddr); // // Message: inventory // - vector vInventoryToSend; + vector vInv; + vector vInvWait; CRITICAL_BLOCK(pto->cs_inventory) { - vInventoryToSend.reserve(pto->vInventoryToSend.size()); + vInv.reserve(pto->vInventoryToSend.size()); + vInvWait.reserve(pto->vInventoryToSend.size()); foreach(const CInv& inv, pto->vInventoryToSend) { + // delay txes + if (!fSendTxInv && inv.type == MSG_TX) + { + vInvWait.push_back(inv); + continue; + } + // returns true if wasn't already contained in the set if (pto->setInventoryKnown.insert(inv).second) { - vInventoryToSend.push_back(inv); - if (vInventoryToSend.size() >= 1000) + vInv.push_back(inv); + if (vInv.size() >= 1000) { - pto->PushMessage("inv", vInventoryToSend); - vInventoryToSend.clear(); + pto->PushMessage("inv", vInv); + vInv.clear(); } } } - pto->vInventoryToSend.clear(); + pto->vInventoryToSend = vInvWait; } - if (!vInventoryToSend.empty()) - pto->PushMessage("inv", vInventoryToSend); + if (!vInv.empty()) + pto->PushMessage("inv", vInv); // // Message: getdata // - vector vAskFor; + vector vGetData; int64 nNow = GetTime() * 1000000; CTxDB txdb("r"); while (!pto->mapAskFor.empty() && (*pto->mapAskFor.begin()).first <= nNow) @@ -2332,17 +2364,17 @@ bool SendMessages(CNode* pto) if (!AlreadyHave(txdb, inv)) { printf("sending getdata: %s\n", inv.ToString().c_str()); - vAskFor.push_back(inv); - if (vAskFor.size() >= 1000) + vGetData.push_back(inv); + if (vGetData.size() >= 1000) { - pto->PushMessage("getdata", vAskFor); - vAskFor.clear(); + pto->PushMessage("getdata", vGetData); + vGetData.clear(); } } pto->mapAskFor.erase(pto->mapAskFor.begin()); } - if (!vAskFor.empty()) - pto->PushMessage("getdata", vAskFor); + if (!vGetData.empty()) + pto->PushMessage("getdata", vGetData); } return true; @@ -2405,7 +2437,6 @@ void ThreadBitcoinMiner(void* parg) vnThreadsRunning[3]--; PrintException(NULL, "ThreadBitcoinMiner()"); } - printf("ThreadBitcoinMiner exiting, %d threads remaining\n", vnThreadsRunning[3]); } @@ -2842,6 +2873,13 @@ bool CreateTransaction(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew, CK // Fill a vout back to self with any change if (nValueIn > nTotalValue) { + // 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 + // backup is restored, if the backup doesn't have the new private key for the change. + // If we reused the old key, it would be possible to add code to look for and + // rediscover unknown transactions that were written with keys of ours to recover + // post-backup change. + // New private key if (keyRet.IsNull()) keyRet.MakeNewKey(); @@ -2899,7 +2937,7 @@ bool CommitTransactionSpent(const CWalletTx& wtxNew, const CKey& key) //// update: This matters even less now that fSpent can get corrected //// when transactions are seen in VerifySignature. The remote chance of //// unmarked fSpent will be handled by that. Don't need to make this - //// transactional. + //// transactional. Pls delete this comment block later. // 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 @@ -2932,7 +2970,7 @@ bool CommitTransactionSpent(const CWalletTx& wtxNew, const CKey& key) -bool SendMoney(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew) +string SendMoney(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew) { CRITICAL_BLOCK(cs_main) { @@ -2945,13 +2983,13 @@ bool SendMoney(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew) strError = strprintf("Error: This is an oversized transaction that requires a transaction fee of %s ", FormatMoney(nFeeRequired).c_str()); else strError = "Error: Transaction creation failed "; - wxMessageBox(strError, "Sending..."); - return error("SendMoney() : %s", strError.c_str()); + printf("SendMoney() : %s", strError.c_str()); + return strError; } if (!CommitTransactionSpent(wtxNew, key)) { - wxMessageBox("Error finalizing transaction ", "Sending..."); - return error("SendMoney() : Error finalizing transaction"); + printf("SendMoney() : Error finalizing transaction"); + return "Error finalizing transaction"; } // Track how many getdata requests our transaction gets @@ -2964,11 +3002,32 @@ bool SendMoney(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew) if (!wtxNew.AcceptTransaction()) { // This must not fail. The transaction has already been signed and recorded. - wxMessageBox("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.", "Sending..."); - return error("SendMoney() : Error: Transaction not valid"); + printf("SendMoney() : Error: Transaction not valid"); + return "Error: The transaction was rejected. This might happen if some of the coins in your wallet were already spent, such as if you used a copy of wallet.dat and coins were spent in the copy but not marked as spent here."; } wtxNew.RelayWalletTransaction(); } MainFrameRepaint(); - return true; + return ""; +} + + + +string SendMoneyToBitcoinAddress(string strAddress, int64 nValue, CWalletTx& wtxNew) +{ + // Check amount + if (nValue <= 0) + return "Invalid amount"; + if (nValue + nTransactionFee > GetBalance()) + return "You don't have enough money"; + + // Parse bitcoin address + uint160 hash160; + if (!AddressToHash160(strAddress, hash160)) + return "Invalid bitcoin address"; + + // Send to bitcoin address + CScript scriptPubKey; + scriptPubKey.SetBitcoinAddress(hash160); + return SendMoney(scriptPubKey, nValue, wtxNew); } diff --git a/main.h b/main.h index 14c445c70e..bcb6ec7dcc 100644 --- a/main.h +++ b/main.h @@ -36,6 +36,8 @@ extern CBlockIndex* pindexBest; extern unsigned int nTransactionsUpdated; extern map mapRequestCount; extern CCriticalSection cs_mapRequestCount; +extern map mapAddressBook; +extern CCriticalSection cs_mapAddressBook; // Settings extern int fGenerateBitcoins; @@ -58,7 +60,6 @@ vector GenerateNewKey(); bool AddToWallet(const CWalletTx& wtxIn); void WalletUpdateSpent(const COutPoint& prevout); void ReacceptWalletTransactions(); -void RelayWalletTransactions(); bool LoadBlockIndex(bool fAllowNew=true); void PrintBlockTree(); bool ProcessMessages(CNode* pfrom); @@ -67,7 +68,8 @@ bool SendMessages(CNode* pto); int64 GetBalance(); bool CreateTransaction(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew, CKey& keyRet, int64& nFeeRequiredRet); bool CommitTransactionSpent(const CWalletTx& wtxNew, const CKey& key); -bool SendMoney(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew); +string SendMoney(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew); +string SendMoneyToBitcoinAddress(string strAddress, int64 nValue, CWalletTx& wtxNew); void GenerateBitcoins(bool fGenerate); void ThreadBitcoinMiner(void* parg); void BitcoinMiner(); @@ -680,7 +682,8 @@ public: int SetMerkleBranch(const CBlock* pblock=NULL); - int GetDepthInMainChain() const; + int GetDepthInMainChain(int& nHeightRet) const; + int GetDepthInMainChain() const { int nHeight; return GetDepthInMainChain(nHeight); } bool IsInMainChain() const { return GetDepthInMainChain() > 0; } int GetBlocksToMaturity() const; bool AcceptTransaction(CTxDB& txdb, bool fCheckInputs=true); diff --git a/makefile b/makefile index 0dd622106e..affbe517c7 100644 --- a/makefile +++ b/makefile @@ -1,4 +1,4 @@ -# Copyright (c) 2009 Satoshi Nakamoto +# 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. @@ -16,22 +16,23 @@ endif INCLUDEPATHS=-I"/boost" -I"/db/build_unix" -I"/openssl/include" -I"/wxwidgets/lib/vc_lib/mswd" -I"/wxwidgets/include" -LIBPATHS=-L"/db/build_unix" -L"/openssl/out" -L"/wxwidgets/lib/gcc_lib" +LIBPATHS=-L"/boost/stage/lib" -L"/db/build_unix" -L"/openssl/out" -L"/wxwidgets/lib/gcc_lib" LIBS= \ + -l libboost_system-mgw34-mt-d -l libboost_filesystem-mgw34-mt-d \ -l db_cxx \ -l eay32 \ -l wxmsw28$(D)_richtext -l wxmsw28$(D)_html -l wxmsw28$(D)_core -l wxmsw28$(D)_adv -l wxbase28$(D) -l wxtiff$(D) -l wxjpeg$(D) -l wxpng$(D) -l wxzlib$(D) -l wxregex$(D) -l wxexpat$(D) \ -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 WXDEFS=-DWIN32 -D__WXMSW__ -D_WINDOWS -DNOPCH CFLAGS=-mthreads -O0 -w -Wno-invalid-offsetof -Wformat $(DEBUGFLAGS) $(WXDEFS) $(INCLUDEPATHS) -HEADERS=headers.h util.h main.h serialize.h uint256.h key.h bignum.h script.h db.h base58.h +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 market.h rpc.h uibase.h ui.h all: bitcoin.exe -headers.h.gch: headers.h $(HEADERS) net.h irc.h market.h uibase.h ui.h +headers.h.gch: headers.h $(HEADERS) g++ -c $(CFLAGS) -o $@ $< obj/util.o: util.cpp $(HEADERS) @@ -40,19 +41,19 @@ obj/util.o: util.cpp $(HEADERS) obj/script.o: script.cpp $(HEADERS) g++ -c $(CFLAGS) -o $@ $< -obj/db.o: db.cpp $(HEADERS) market.h +obj/db.o: db.cpp $(HEADERS) g++ -c $(CFLAGS) -o $@ $< -obj/net.o: net.cpp $(HEADERS) net.h +obj/net.o: net.cpp $(HEADERS) g++ -c $(CFLAGS) -o $@ $< -obj/main.o: main.cpp $(HEADERS) net.h market.h sha.h +obj/main.o: main.cpp $(HEADERS) sha.h g++ -c $(CFLAGS) -o $@ $< -obj/market.o: market.cpp $(HEADERS) market.h +obj/market.o: market.cpp $(HEADERS) g++ -c $(CFLAGS) -o $@ $< -obj/ui.o: ui.cpp $(HEADERS) net.h uibase.h ui.h market.h +obj/ui.o: ui.cpp $(HEADERS) g++ -c $(CFLAGS) -o $@ $< obj/uibase.o: uibase.cpp uibase.h @@ -64,13 +65,17 @@ obj/sha.o: sha.cpp sha.h obj/irc.o: irc.cpp $(HEADERS) g++ -c $(CFLAGS) -o $@ $< +obj/rpc.o: rpc.cpp $(HEADERS) + g++ -c $(CFLAGS) -o $@ $< + obj/ui_res.o: ui.rc rc/bitcoin.ico rc/check.ico rc/send16.bmp rc/send16mask.bmp rc/send16masknoshadow.bmp rc/send20.bmp rc/send20mask.bmp rc/addressbook16.bmp rc/addressbook16mask.bmp rc/addressbook20.bmp rc/addressbook20mask.bmp windres $(WXDEFS) $(INCLUDEPATHS) -o $@ -i $< OBJS=obj/util.o obj/script.o obj/db.o obj/net.o obj/main.o obj/market.o \ - obj/ui.o obj/uibase.o obj/sha.o obj/irc.o obj/ui_res.o + obj/ui.o obj/uibase.o obj/sha.o obj/irc.o obj/rpc.o \ + obj/ui_res.o bitcoin.exe: headers.h.gch $(OBJS) -kill /f bitcoin.exe diff --git a/makefile.unix.wx2.8 b/makefile.unix.wx2.8 index b9826d6ccb..d3358ab2df 100644 --- a/makefile.unix.wx2.8 +++ b/makefile.unix.wx2.8 @@ -1,4 +1,4 @@ -# Copyright (c) 2009 Satoshi Nakamoto +# 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. @@ -35,14 +35,14 @@ LIBS= \ WXDEFS=-D__WXGTK__ -DNOPCH CFLAGS=-O0 -Wno-invalid-offsetof -Wformat $(DEBUGFLAGS) $(WXDEFS) $(INCLUDEPATHS) -HEADERS=headers.h util.h main.h serialize.h uint256.h key.h bignum.h script.h db.h base58.h +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 market.h rpc.h uibase.h ui.h all: bitcoin -headers.h.gch: headers.h $(HEADERS) net.h irc.h market.h uibase.h ui.h +headers.h.gch: headers.h $(HEADERS) g++ -c $(CFLAGS) -o $@ $< obj/util.o: util.cpp $(HEADERS) @@ -51,19 +51,19 @@ obj/util.o: util.cpp $(HEADERS) obj/script.o: script.cpp $(HEADERS) g++ -c $(CFLAGS) -o $@ $< -obj/db.o: db.cpp $(HEADERS) market.h +obj/db.o: db.cpp $(HEADERS) g++ -c $(CFLAGS) -o $@ $< -obj/net.o: net.cpp $(HEADERS) net.h +obj/net.o: net.cpp $(HEADERS) g++ -c $(CFLAGS) -o $@ $< -obj/main.o: main.cpp $(HEADERS) net.h market.h sha.h +obj/main.o: main.cpp $(HEADERS) sha.h g++ -c $(CFLAGS) -o $@ $< -obj/market.o: market.cpp $(HEADERS) market.h +obj/market.o: market.cpp $(HEADERS) g++ -c $(CFLAGS) -o $@ $< -obj/ui.o: ui.cpp $(HEADERS) net.h uibase.h ui.h market.h +obj/ui.o: ui.cpp $(HEADERS) g++ -c $(CFLAGS) -o $@ $< obj/uibase.o: uibase.cpp uibase.h @@ -75,11 +75,13 @@ obj/sha.o: sha.cpp sha.h obj/irc.o: irc.cpp $(HEADERS) g++ -c $(CFLAGS) -o $@ $< +obj/rpc.o: rpc.cpp $(HEADERS) + g++ -c $(CFLAGS) -o $@ $< OBJS=obj/util.o obj/script.o obj/db.o obj/net.o obj/main.o obj/market.o \ - obj/ui.o obj/uibase.o obj/sha.o obj/irc.o + obj/ui.o obj/uibase.o obj/sha.o obj/irc.o obj/rpc.o bitcoin: headers.h.gch $(OBJS) g++ $(CFLAGS) -o $@ $(LIBPATHS) $(OBJS) $(LIBS) diff --git a/makefile.unix.wx2.9 b/makefile.unix.wx2.9 index 81dcbd70e9..8defcbb6fc 100644 --- a/makefile.unix.wx2.9 +++ b/makefile.unix.wx2.9 @@ -1,4 +1,4 @@ -# Copyright (c) 2009 Satoshi Nakamoto +# 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. @@ -35,14 +35,14 @@ LIBS= \ WXDEFS=-D__WXGTK__ -DNOPCH CFLAGS=-O0 -Wno-invalid-offsetof -Wformat $(DEBUGFLAGS) $(WXDEFS) $(INCLUDEPATHS) -HEADERS=headers.h util.h main.h serialize.h uint256.h key.h bignum.h script.h db.h base58.h +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 market.h rpc.h uibase.h ui.h all: bitcoin -headers.h.gch: headers.h $(HEADERS) net.h irc.h market.h uibase.h ui.h +headers.h.gch: headers.h $(HEADERS) g++ -c $(CFLAGS) -o $@ $< obj/util.o: util.cpp $(HEADERS) @@ -51,19 +51,19 @@ obj/util.o: util.cpp $(HEADERS) obj/script.o: script.cpp $(HEADERS) g++ -c $(CFLAGS) -o $@ $< -obj/db.o: db.cpp $(HEADERS) market.h +obj/db.o: db.cpp $(HEADERS) g++ -c $(CFLAGS) -o $@ $< -obj/net.o: net.cpp $(HEADERS) net.h +obj/net.o: net.cpp $(HEADERS) g++ -c $(CFLAGS) -o $@ $< -obj/main.o: main.cpp $(HEADERS) net.h market.h sha.h +obj/main.o: main.cpp $(HEADERS) sha.h g++ -c $(CFLAGS) -o $@ $< -obj/market.o: market.cpp $(HEADERS) market.h +obj/market.o: market.cpp $(HEADERS) g++ -c $(CFLAGS) -o $@ $< -obj/ui.o: ui.cpp $(HEADERS) net.h uibase.h ui.h market.h +obj/ui.o: ui.cpp $(HEADERS) g++ -c $(CFLAGS) -o $@ $< obj/uibase.o: uibase.cpp uibase.h @@ -75,11 +75,13 @@ obj/sha.o: sha.cpp sha.h obj/irc.o: irc.cpp $(HEADERS) g++ -c $(CFLAGS) -o $@ $< +obj/rpc.o: rpc.cpp $(HEADERS) + g++ -c $(CFLAGS) -o $@ $< OBJS=obj/util.o obj/script.o obj/db.o obj/net.o obj/main.o obj/market.o \ - obj/ui.o obj/uibase.o obj/sha.o obj/irc.o + obj/ui.o obj/uibase.o obj/sha.o obj/irc.o obj/rpc.o bitcoin: headers.h.gch $(OBJS) g++ $(CFLAGS) -o $@ $(LIBPATHS) $(OBJS) $(LIBS) diff --git a/makefile.vc b/makefile.vc index fb7f3086e3..73fd1cfd9a 100644 --- a/makefile.vc +++ b/makefile.vc @@ -1,4 +1,4 @@ -# Copyright (c) 2009 Satoshi Nakamoto +# 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. @@ -14,15 +14,16 @@ DEBUGFLAGS=/Zi /Od /D__WXDEBUG__ INCLUDEPATHS=/I"/boost" /I"/db/build_windows" /I"/openssl/include" /I"/wxwidgets/lib/vc_lib/mswd" /I"/wxwidgets/include" -LIBPATHS=/LIBPATH:"/db/build_windows/$(BUILD)" /LIBPATH:"/openssl/out" /LIBPATH:"/wxwidgets/lib/vc_lib" +LIBPATHS=/LIBPATH:"/boost/stage/lib" /LIBPATH:"/db/build_windows/$(BUILD)" /LIBPATH:"/openssl/out" /LIBPATH:"/wxwidgets/lib/vc_lib" LIBS= \ + libboost_system-vc80-mt-gd.lib libboost_filesystem-vc80-mt-gd.lib \ libdb47s$(D).lib \ libeay32.lib \ wxmsw28$(D)_richtext.lib wxmsw28$(D)_html.lib wxmsw28$(D)_core.lib wxmsw28$(D)_adv.lib wxbase28$(D).lib wxtiff$(D).lib wxjpeg$(D).lib wxpng$(D).lib wxzlib$(D).lib wxregex$(D).lib wxexpat$(D).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 WXDEFS=/DWIN32 /D__WXMSW__ /D_WINDOWS /DNOPCH CFLAGS=/c /nologo /Ob0 /MD$(D) /EHsc /GR /Zm300 /YX /Fpobj/headers.pch $(DEBUGFLAGS) $(WXDEFS) $(INCLUDEPATHS) -HEADERS=headers.h util.h main.h serialize.h uint256.h key.h bignum.h script.h db.h base58.h +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 market.h rpc.h uibase.h ui.h @@ -35,37 +36,41 @@ obj\util.obj: util.cpp $(HEADERS) obj\script.obj: script.cpp $(HEADERS) cl $(CFLAGS) /Fo$@ %s -obj\db.obj: db.cpp $(HEADERS) market.h +obj\db.obj: db.cpp $(HEADERS) cl $(CFLAGS) /Fo$@ %s -obj\net.obj: net.cpp $(HEADERS) net.h +obj\net.obj: net.cpp $(HEADERS) cl $(CFLAGS) /Fo$@ %s -obj\main.obj: main.cpp $(HEADERS) net.h market.h +obj\main.obj: main.cpp $(HEADERS) sha.h cl $(CFLAGS) /Fo$@ %s -obj\market.obj: market.cpp $(HEADERS) market.h +obj\market.obj: market.cpp $(HEADERS) cl $(CFLAGS) /Fo$@ %s -obj\ui.obj: ui.cpp $(HEADERS) net.h uibase.h ui.h market.h +obj\ui.obj: ui.cpp $(HEADERS) cl $(CFLAGS) /Fo$@ %s obj\uibase.obj: uibase.cpp uibase.h cl $(CFLAGS) /Fo$@ %s -obj\sha.obj: sha.cpp sha.h +obj\sha.obj: sha.cpp sha.h cl $(CFLAGS) /O2 /Fo$@ %s obj\irc.obj: irc.cpp $(HEADERS) cl $(CFLAGS) /Fo$@ %s +obj\rpc.obj: rpc.cpp $(HEADERS) + cl $(CFLAGS) /Fo$@ %s + obj\ui.res: ui.rc rc/bitcoin.ico rc/check.ico rc/send16.bmp rc/send16mask.bmp rc/send16masknoshadow.bmp rc/send20.bmp rc/send20mask.bmp rc/addressbook16.bmp rc/addressbook16mask.bmp rc/addressbook20.bmp rc/addressbook20mask.bmp rc $(INCLUDEPATHS) $(WXDEFS) /Fo$@ %s OBJS=obj\util.obj obj\script.obj obj\db.obj obj\net.obj obj\main.obj obj\market.obj \ - obj\ui.obj obj\uibase.obj obj\sha.obj obj\irc.obj obj\ui.res + obj\ui.obj obj\uibase.obj obj\sha.obj obj\irc.obj obj\rpc.obj \ + obj\ui.res bitcoin.exe: $(OBJS) -kill /f bitcoin.exe & sleep 1 diff --git a/net.cpp b/net.cpp index 38d05de1ab..ada78eb366 100644 --- a/net.cpp +++ b/net.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2009 Satoshi Nakamoto +// 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. @@ -522,7 +522,6 @@ void CNode::Cleanup() void ThreadSocketHandler(void* parg) { IMPLEMENT_RANDOMIZE_STACK(ThreadSocketHandler(parg)); - try { vnThreadsRunning[0]++; @@ -536,7 +535,6 @@ void ThreadSocketHandler(void* parg) vnThreadsRunning[0]--; throw; // support pthread_cancel() } - printf("ThreadSocketHandler exiting\n"); } @@ -816,7 +814,6 @@ void ThreadSocketHandler2(void* parg) void ThreadOpenConnections(void* parg) { IMPLEMENT_RANDOMIZE_STACK(ThreadOpenConnections(parg)); - try { vnThreadsRunning[1]++; @@ -830,7 +827,6 @@ void ThreadOpenConnections(void* parg) vnThreadsRunning[1]--; PrintException(NULL, "ThreadOpenConnections()"); } - printf("ThreadOpenConnections exiting\n"); } @@ -928,7 +924,7 @@ void ThreadOpenConnections2(void* parg) // 30 days 27 hours // 90 days 46 hours // 365 days 93 hours - int64 nDelay = (int64)(3600.0 * sqrt(fabs(nSinceLastSeen) / 3600.0) + nRandomizer); + int64 nDelay = (int64)(3600.0 * sqrt(fabs((double)nSinceLastSeen) / 3600.0) + nRandomizer); // Fast reconnect for one hour after last seen if (nSinceLastSeen < 60 * 60) @@ -1016,7 +1012,6 @@ bool OpenNetworkConnection(const CAddress& addrConnect) void ThreadMessageHandler(void* parg) { IMPLEMENT_RANDOMIZE_STACK(ThreadMessageHandler(parg)); - try { vnThreadsRunning[2]++; @@ -1030,7 +1025,6 @@ void ThreadMessageHandler(void* parg) vnThreadsRunning[2]--; PrintException(NULL, "ThreadMessageHandler()"); } - printf("ThreadMessageHandler exiting\n"); } @@ -1329,7 +1323,7 @@ bool StopNode() fShutdown = true; nTransactionsUpdated++; int64 nStart = GetTime(); - while (vnThreadsRunning[0] > 0 || vnThreadsRunning[2] > 0 || vnThreadsRunning[3] > 0) + while (vnThreadsRunning[0] > 0 || vnThreadsRunning[2] > 0 || vnThreadsRunning[3] > 0 || vnThreadsRunning[4] > 0) { if (GetTime() - nStart > 20) break; @@ -1339,7 +1333,8 @@ bool StopNode() if (vnThreadsRunning[1] > 0) printf("ThreadOpenConnections still running\n"); if (vnThreadsRunning[2] > 0) printf("ThreadMessageHandler still running\n"); if (vnThreadsRunning[3] > 0) printf("ThreadBitcoinMiner still running\n"); - while (vnThreadsRunning[2] > 0) + if (vnThreadsRunning[4] > 0) printf("ThreadRPCServer still running\n"); + while (vnThreadsRunning[2] > 0 || vnThreadsRunning[4] > 0) Sleep(20); Sleep(50); diff --git a/net.h b/net.h index ba4607a558..ce6f772f49 100644 --- a/net.h +++ b/net.h @@ -1,4 +1,4 @@ -// Copyright (c) 2009 Satoshi Nakamoto +// 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. @@ -518,6 +518,7 @@ public: vector vInventoryToSend; CCriticalSection cs_inventory; multimap mapAskFor; + int64 nLastSentTxInv; // publish and subscription vector vfSubscribe; diff --git a/rpc.cpp b/rpc.cpp new file mode 100644 index 0000000000..9f28e7ec74 --- /dev/null +++ b/rpc.cpp @@ -0,0 +1,641 @@ +// 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. + +#include "headers.h" +#undef printf +#include +#include "json/json_spirit_reader_template.h" +#include "json/json_spirit_writer_template.h" +#include "json/json_spirit_utils.h" +#define printf OutputDebugStringF +// MinGW 3.4.5 gets "fatal error: had to relocate PCH" if the json headers are +// precompiled in headers.h. The problem might be when the pch file goes over +// a certain size around 145MB. If we need access to json_spirit outside this +// file, we could use the compiled json_spirit option. + +using boost::asio::ip::tcp; +using namespace json_spirit; + +void ThreadRPCServer2(void* parg); + + + + + + + +/// +/// Note: I'm not finished designing this interface, it's still subject to change. +/// + + + +Value stop(const Array& params) +{ + if (params.size() != 0) + throw runtime_error( + "stop (no parameters)\n" + "Stop bitcoin server."); + + // Shutdown will take long enough that the response should get back + CreateThread(Shutdown, NULL); + return "bitcoin server stopping"; +} + + +Value getblockcount(const Array& params) +{ + if (params.size() != 0) + throw runtime_error( + "getblockcount (no parameters)\n" + "Returns the number of blocks in the longest block chain."); + + return nBestHeight + 1; +} + + +Value getblocknumber(const Array& params) +{ + if (params.size() != 0) + throw runtime_error( + "getblocknumber (no parameters)\n" + "Returns the block number of the latest block in the longest block chain."); + + return nBestHeight; +} + + +Value getdifficulty(const Array& params) +{ + if (params.size() != 0) + throw runtime_error( + "getdifficulty (no parameters)\n" + "Returns the proof-of-work difficulty as a multiple of the minimum difficulty."); + + if (pindexBest == NULL) + throw runtime_error("block chain not loaded"); + + // Floating point number that is a multiple of the minimum difficulty, + // minimum difficulty = 1.0. + int nShift = 256 - 32 - 31; // to fit in a uint + double dMinimum = (CBigNum().SetCompact(bnProofOfWorkLimit.GetCompact()) >> nShift).getuint(); + double dCurrently = (CBigNum().SetCompact(pindexBest->nBits) >> nShift).getuint(); + return dMinimum / dCurrently; +} + + +Value getnewaddress(const Array& params) +{ + if (params.size() > 1) + throw runtime_error( + "getnewaddress [label]\n" + "Returns a new bitcoin address for receiving payments. " + "If [label] is specified (recommended), it is added to the address book " + "so payments received with the address will be labeled."); + + // Parse the label first so we don't generate a key if there's an error + string strLabel; + if (params.size() > 0) + strLabel = params[0].get_str(); + + // Generate a new key that is added to wallet + string strAddress = PubKeyToAddress(GenerateNewKey()); + + if (params.size() > 0) + SetAddressBookName(strAddress, strLabel); + return strAddress; +} + + +Value sendtoaddress(const Array& params) +{ + if (params.size() < 2 || params.size() > 4) + throw runtime_error( + "sendtoaddress [comment] [comment-to]\n" + " is a real and is rounded to the nearest 0.01"); + + string strAddress = params[0].get_str(); + + // Amount + if (params[1].get_real() <= 0.0 || params[1].get_real() > 21000000.0) + throw runtime_error("Invalid amount"); + int64 nAmount = roundint64(params[1].get_real() * 100.00) * CENT; + + // Wallet comments + CWalletTx wtx; + if (params.size() > 2 && params[2].type() != null_type && !params[2].get_str().empty()) + wtx.mapValue["message"] = params[2].get_str(); + if (params.size() > 3 && params[3].type() != null_type && !params[3].get_str().empty()) + wtx.mapValue["to"] = params[3].get_str(); + + string strError = SendMoneyToBitcoinAddress(strAddress, nAmount, wtx); + if (strError != "") + throw runtime_error(strError); + return "sent"; +} + + +Value listtransactions(const Array& params) +{ + if (params.size() > 2) + throw runtime_error( + "listtransactions [count=10] [includegenerated=false]\n" + "Returns up to [count] most recent transactions."); + + int64 nCount = 10; + if (params.size() > 0) + nCount = params[0].get_int64(); + bool fGenerated = false; + if (params.size() > 1) + fGenerated = params[1].get_bool(); + + Array ret; + //// not finished + ret.push_back("not implemented yet"); + return ret; +} + + +Value getamountpaid(const Array& params) +{ + if (params.size() < 1 || params.size() > 2) + throw runtime_error( + "getamountpaid [minconf=1]\n" + "Returns the total amount paid to in transactions with at least [minconf] confirmations."); + + // Bitcoin address + string strAddress = params[0].get_str(); + CScript scriptPubKey; + if (!scriptPubKey.SetBitcoinAddress(strAddress)) + throw runtime_error("Invalid bitcoin address"); + + // Minimum confirmations + int nMinDepth = 1; + if (params.size() > 1) + nMinDepth = params[1].get_int(); + + // Tally + int64 nAmount = 0; + CRITICAL_BLOCK(cs_mapWallet) + { + for (map::iterator it = mapWallet.begin(); it != mapWallet.end(); ++it) + { + const CWalletTx& wtx = (*it).second; + if (wtx.IsCoinBase() || !wtx.IsFinal()) + continue; + + foreach(const CTxOut& txout, wtx.vout) + if (txout.scriptPubKey == scriptPubKey) + if (wtx.GetDepthInMainChain() >= nMinDepth) + nAmount += txout.nValue; + } + } + + return (double)nAmount / (double)COIN; +} + + +struct tallyitem +{ + int64 nAmount; + int nConf; + tallyitem() + { + nAmount = 0; + nConf = INT_MAX; + } +}; + +Value getallpayments(const Array& params) +{ + if (params.size() > 1) + throw runtime_error( + "getallpayments [minconf=1]\n" + "[minconf] is the minimum number of confirmations before payments are included.\n" + "Returns an array of objects containing:\n" + " \"address\" : bitcoin address\n" + " \"amount\" : total amount paid to the address\n" + " \"conf\" : number of confirmations\n" + " \"label\" : the label set for this address when it was created by getnewaddress"); + + // Minimum confirmations + int nMinDepth = 1; + if (params.size() > 0) + nMinDepth = params[0].get_int(); + + // Tally + map mapTally; + CRITICAL_BLOCK(cs_mapWallet) + { + for (map::iterator it = mapWallet.begin(); it != mapWallet.end(); ++it) + { + const CWalletTx& wtx = (*it).second; + if (wtx.IsCoinBase() || !wtx.IsFinal()) + continue; + + int nDepth = wtx.GetDepthInMainChain(); + if (nDepth >= nMinDepth) + { + foreach(const CTxOut& txout, wtx.vout) + { + uint160 hash160 = txout.scriptPubKey.GetBitcoinAddressHash160(); + if (hash160 == 0 || !mapPubKeys.count(hash160)) + continue; + + tallyitem& item = mapTally[hash160]; + item.nAmount += txout.nValue; + item.nConf = min(item.nConf, nDepth); + } + } + } + } + + // Reply + Array ret; + CRITICAL_BLOCK(cs_mapAddressBook) + { + for (map::iterator it = mapTally.begin(); it != mapTally.end(); ++it) + { + string strAddress = Hash160ToAddress((*it).first); + string strLabel; + map::iterator mi = mapAddressBook.find(strAddress); + if (mi != mapAddressBook.end()) + strLabel = (*mi).second; + + Object obj; + obj.push_back(Pair("address", strAddress)); + obj.push_back(Pair("amount", (double)(*it).second.nAmount / (double)COIN)); + obj.push_back(Pair("conf", (*it).second.nConf)); + obj.push_back(Pair("label", strLabel)); + ret.push_back(obj); + } + } + return ret; +} + + + + + + + +// +// Call Table +// + +typedef Value(*rpcfn_type)(const Array& params); +pair pCallTable[] = +{ + make_pair("stop", &stop), + make_pair("getblockcount", &getblockcount), + make_pair("getblocknumber", &getblocknumber), + make_pair("getdifficulty", &getdifficulty), + make_pair("getnewaddress", &getnewaddress), + make_pair("sendtoaddress", &sendtoaddress), + make_pair("listtransactions", &listtransactions), + make_pair("getamountpaid", &getamountpaid), + make_pair("getallpayments", &getallpayments), +}; +map mapCallTable(pCallTable, pCallTable + sizeof(pCallTable)/sizeof(pCallTable[0])); + + + + +// +// HTTP protocol +// +// This ain't Apache. We're just using HTTP header for the length field +// and to be compatible with other JSON-RPC implementations. +// + +string HTTPPost(const string& strMsg) +{ + return strprintf( + "POST / HTTP/1.1\r\n" + "User-Agent: json-rpc/1.0\r\n" + "Host: 127.0.0.1\r\n" + "Content-Type: application/json\r\n" + "Content-Length: %d\r\n" + "Accept: application/json\r\n" + "\r\n" + "%s", + strMsg.size(), + strMsg.c_str()); +} + +string HTTPReply(const string& strMsg, int nStatus=200) +{ + string strStatus; + if (nStatus == 200) strStatus = "OK"; + if (nStatus == 500) strStatus = "Internal Server Error"; + return strprintf( + "HTTP/1.1 %d %s\r\n" + "Connection: close\r\n" + "Content-Length: %d\r\n" + "Content-Type: application/json\r\n" + "Date: Sat, 08 Jul 2006 12:04:08 GMT\r\n" + "Server: json-rpc/1.0\r\n" + "\r\n" + "%s", + nStatus, + strStatus.c_str(), + strMsg.size(), + strMsg.c_str()); +} + +int ReadHTTPHeader(tcp::iostream& stream) +{ + int nLen = 0; + loop + { + string str; + std::getline(stream, str); + if (str.empty() || str == "\r") + break; + if (str.substr(0,15) == "Content-Length:") + nLen = atoi(str.substr(15)); + } + return nLen; +} + +inline string ReadHTTP(tcp::iostream& stream) +{ + // Read header + int nLen = ReadHTTPHeader(stream); + if (nLen <= 0) + return string(); + + // Read message + vector vch(nLen); + stream.read(&vch[0], nLen); + return string(vch.begin(), vch.end()); +} + + + +// +// JSON-RPC protocol +// +// http://json-rpc.org/wiki/specification +// http://www.codeproject.com/KB/recipes/JSON_Spirit.aspx +// + +string JSONRPCRequest(const string& strMethod, const Array& params, const Value& id) +{ + Object request; + request.push_back(Pair("method", strMethod)); + request.push_back(Pair("params", params)); + request.push_back(Pair("id", id)); + return write_string(Value(request), false) + "\n"; +} + +string JSONRPCReply(const Value& result, const Value& error, const Value& id) +{ + Object reply; + if (error.type() != null_type) + reply.push_back(Pair("result", Value::null)); + else + reply.push_back(Pair("result", result)); + reply.push_back(Pair("error", error)); + reply.push_back(Pair("id", id)); + return write_string(Value(reply), false) + "\n"; +} + + + + +void ThreadRPCServer(void* parg) +{ + IMPLEMENT_RANDOMIZE_STACK(ThreadRPCServer(parg)); + try + { + vnThreadsRunning[4]++; + ThreadRPCServer2(parg); + vnThreadsRunning[4]--; + } + catch (std::exception& e) { + vnThreadsRunning[4]--; + PrintException(&e, "ThreadRPCServer()"); + } catch (...) { + vnThreadsRunning[4]--; + PrintException(NULL, "ThreadRPCServer()"); + } + printf("ThreadRPCServer exiting\n"); +} + +void ThreadRPCServer2(void* parg) +{ + printf("ThreadRPCServer started\n"); + + // Bind to loopback 127.0.0.1 so the socket can only be accessed locally + boost::asio::io_service io_service; + tcp::endpoint endpoint(boost::asio::ip::address_v4::loopback(), 8332); + tcp::acceptor acceptor(io_service, endpoint); + + loop + { + // Accept connection + tcp::iostream stream; + tcp::endpoint peer; + vnThreadsRunning[4]--; + acceptor.accept(*stream.rdbuf(), peer); + vnThreadsRunning[4]++; + if (fShutdown) + return; + + // Shouldn't be possible for anyone else to connect, but just in case + if (peer.address().to_string() != "127.0.0.1") + continue; + + // Receive request + string strRequest = ReadHTTP(stream); + printf("ThreadRPCServer request=%s", strRequest.c_str()); + + // Handle multiple invocations per request + string::iterator begin = strRequest.begin(); + while (skipspaces(begin), begin != strRequest.end()) + { + string::iterator prev = begin; + Value id; + try + { + // Parse request + Value valRequest; + if (!read_range(begin, strRequest.end(), valRequest)) + throw runtime_error("Parse error."); + const Object& request = valRequest.get_obj(); + if (find_value(request, "method").type() != str_type || + find_value(request, "params").type() != array_type) + throw runtime_error("Invalid request."); + + string strMethod = find_value(request, "method").get_str(); + const Array& params = find_value(request, "params").get_array(); + id = find_value(request, "id"); + + // Execute + map::iterator mi = mapCallTable.find(strMethod); + if (mi == mapCallTable.end()) + throw runtime_error("Method not found."); + Value result = (*(*mi).second)(params); + + // Send reply + string strReply = JSONRPCReply(result, Value::null, id); + stream << HTTPReply(strReply, 200) << std::flush; + } + catch (std::exception& e) + { + // Send error reply + string strReply = JSONRPCReply(Value::null, e.what(), id); + stream << HTTPReply(strReply, 500) << std::flush; + } + if (begin == prev) + break; + } + } +} + + + + +Value CallRPC(const string& strMethod, const Array& params) +{ + // Connect to localhost + tcp::iostream stream("127.0.0.1", "8332"); + if (stream.fail()) + throw runtime_error("unable to connect to server"); + + // Send request + string strRequest = JSONRPCRequest(strMethod, params, 1); + stream << HTTPPost(strRequest) << std::flush; + + // Receive reply + string strReply = ReadHTTP(stream); + if (strReply.empty()) + throw runtime_error("no response from server"); + + // Parse reply + Value valReply; + if (!read_string(strReply, valReply)) + throw runtime_error("couldn't parse reply from server"); + const Object& reply = valReply.get_obj(); + if (reply.empty()) + throw runtime_error("expected reply to have result, error and id properties"); + + const Value& result = find_value(reply, "result"); + const Value& error = find_value(reply, "error"); + const Value& id = find_value(reply, "id"); + + if (error.type() == str_type) + throw runtime_error(error.get_str()); + else if (error.type() != null_type) + throw runtime_error(write_string(error, false)); + return result; +} + + + + +template +void ConvertTo(Value& value) +{ + if (value.type() == str_type) + { + // reinterpret string as unquoted json value + Value value2; + if (!read_string(value.get_str(), value2)) + throw runtime_error("type mismatch"); + value = value2.get_value(); + } + else + { + value = value.get_value(); + } +} + +int CommandLineRPC(int argc, char *argv[]) +{ + try + { + // Check that method exists + if (argc < 2) + throw runtime_error("too few parameters"); + string strMethod = argv[1]; + if (!mapCallTable.count(strMethod)) + throw runtime_error(strprintf("unknown command: %s", strMethod.c_str())); + + // Parameters default to strings + Array params; + for (int i = 2; i < argc; i++) + params.push_back(argv[i]); + + // Special case other types + int n = params.size(); + if (strMethod == "sendtoaddress" && n > 1) ConvertTo(params[1]); + if (strMethod == "listtransactions" && n > 0) ConvertTo(params[0]); + if (strMethod == "listtransactions" && n > 1) ConvertTo(params[1]); + if (strMethod == "getamountpaid" && n > 1) ConvertTo(params[1]); + if (strMethod == "getallpayments" && n > 0) ConvertTo(params[0]); + + // Execute + Value result = CallRPC(strMethod, params); + + // Print result + string strResult = (result.type() == str_type ? result.get_str() : write_string(result, true)); + if (result.type() != null_type) + { + if (fWindows) + // Windows GUI apps can't print to command line, + // so for now settle for a message box yuck + wxMessageBox(strResult.c_str(), "Bitcoin", wxOK); + else + fprintf(stdout, "%s\n", strResult.c_str()); + } + return 0; + } + catch (std::exception& e) { + if (fWindows) + wxMessageBox(strprintf("error: %s\n", e.what()).c_str(), "Bitcoin", wxOK); + else + fprintf(stderr, "error: %s\n", e.what()); + } catch (...) { + PrintException(NULL, "CommandLineRPC()"); + } + return 1; +} + + + + +#ifdef TEST +int main(int argc, char *argv[]) +{ +#ifdef _MSC_VER + // Turn off microsoft heap dump noise + _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE); + _CrtSetReportFile(_CRT_WARN, CreateFile("NUL", GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0)); +#endif + setbuf(stdin, NULL); + setbuf(stdout, NULL); + setbuf(stderr, NULL); + + try + { + if (argc >= 2 && string(argv[1]) == "-server") + { + printf("server ready\n"); + ThreadRPCServer(NULL); + } + else + { + return CommandLineRPC(argc, argv); + } + } + catch (std::exception& e) { + PrintException(&e, "main()"); + } catch (...) { + PrintException(NULL, "main()"); + } + return 0; +} +#endif diff --git a/rpc.h b/rpc.h new file mode 100644 index 0000000000..81ad840c4a --- /dev/null +++ b/rpc.h @@ -0,0 +1,6 @@ +// 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. + +void ThreadRPCServer(void* parg); +int CommandLineRPC(int argc, char *argv[]); diff --git a/script.cpp b/script.cpp index a41de2aa76..98f5afd5a7 100644 --- a/script.cpp +++ b/script.cpp @@ -660,7 +660,7 @@ bool EvalScript(const CScript& script, const CTransaction& txTo, unsigned int nI if (stack.size() < 1) return false; valtype& vch = stacktop(-1); - valtype vchHash(opcode == OP_RIPEMD160 || opcode == OP_SHA1 || opcode == OP_HASH160 ? 20 : 32); + valtype vchHash((opcode == OP_RIPEMD160 || opcode == OP_SHA1 || opcode == OP_HASH160) ? 20 : 32); if (opcode == OP_RIPEMD160) RIPEMD160(&vch[0], vch.size(), &vchHash[0]); else if (opcode == OP_SHA1) @@ -753,9 +753,9 @@ bool EvalScript(const CScript& script, const CTransaction& txTo, unsigned int nI CScript scriptCode(pbegincodehash, pend); // Drop the signatures, since there's no way for a signature to sign itself - for (int i = 0; i < nSigsCount; i++) + for (int k = 0; k < nSigsCount; k++) { - valtype& vchSig = stacktop(-isig-i); + valtype& vchSig = stacktop(-isig-k); scriptCode.FindAndDelete(CScript(vchSig)); } @@ -909,7 +909,6 @@ bool CheckSig(vector vchSig, vector vchPubKey, CSc - bool Solver(const CScript& scriptPubKey, vector >& vSolutionRet) { // Templates @@ -919,7 +918,7 @@ bool Solver(const CScript& scriptPubKey, vector >& vSo // Standard tx, sender provides pubkey, receiver adds signature vTemplates.push_back(CScript() << OP_PUBKEY << OP_CHECKSIG); - // Short account number tx, sender provides hash of pubkey, receiver provides signature and pubkey + // Bitcoin address tx, sender provides hash of pubkey, receiver provides signature and pubkey vTemplates.push_back(CScript() << OP_DUP << OP_HASH160 << OP_PUBKEYHASH << OP_EQUALVERIFY << OP_CHECKSIG); } diff --git a/script.h b/script.h index 0d977734b9..9e41889150 100644 --- a/script.h +++ b/script.h @@ -1,4 +1,4 @@ -// Copyright (c) 2009 Satoshi Nakamoto +// 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. @@ -472,7 +472,7 @@ public: bool GetOp(iterator& pc, opcodetype& opcodeRet, vector& vchRet) { - // This is why people hate C++ + // Wrapper so it can be called with either iterator or const_iterator const_iterator pc2 = pc; bool fRet = GetOp(pc2, opcodeRet, vchRet); pc = begin() + (pc2 - begin()); @@ -551,6 +551,46 @@ public: } + uint160 GetBitcoinAddressHash160() const + { + opcodetype opcode; + vector vch; + CScript::const_iterator pc = begin(); + if (!GetOp(pc, opcode, vch) || opcode != OP_DUP) return 0; + if (!GetOp(pc, opcode, vch) || opcode != OP_HASH160) return 0; + if (!GetOp(pc, opcode, vch) || vch.size() != sizeof(uint160)) return 0; + uint160 hash160 = uint160(vch); + 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; + } + + string GetBitcoinAddress() const + { + uint160 hash160 = GetBitcoinAddressHash160(); + if (hash160 == 0) + return ""; + return Hash160ToAddress(hash160); + } + + void SetBitcoinAddress(const uint160& hash160) + { + this->clear(); + *this << OP_DUP << OP_HASH160 << hash160 << OP_EQUALVERIFY << OP_CHECKSIG; + } + + bool SetBitcoinAddress(const string& strAddress) + { + this->clear(); + uint160 hash160; + if (!AddressToHash160(strAddress, hash160)) + return false; + SetBitcoinAddress(hash160); + return true; + } + + void PrintHex() const { printf("CScript(%s)\n", HexStr(begin(), end()).c_str()); diff --git a/serialize.h b/serialize.h index 439ef64125..eb090ae2e6 100644 --- a/serialize.h +++ b/serialize.h @@ -19,8 +19,8 @@ class CScript; class CDataStream; class CAutoFile; -static const int VERSION = 200; -static const char* pszSubVer = " test2"; +static const int VERSION = 201; +static const char* pszSubVer = ".0"; diff --git a/ui.cpp b/ui.cpp index 5d93ad227f..586200d6ef 100644 --- a/ui.cpp +++ b/ui.cpp @@ -21,7 +21,6 @@ DEFINE_EVENT_TYPE(wxEVT_REPLY3) CMainFrame* pframeMain = NULL; CMyTaskBarIcon* ptaskbaricon = NULL; -map mapAddressBook; bool fRandSendTest = false; void RandSend(); extern int g_isPainting; @@ -177,8 +176,11 @@ void CalledMessageBox(const string& message, const string& caption, int style, w int ThreadSafeMessageBox(const string& message, const string& caption, int style, wxWindow* parent, int x, int y) { - if (mapArgs.count("-noui")) + if (fDaemon) + { + printf("wxMessageBox %s: %s\n", caption.c_str(), message.c_str()); return wxOK; + } #ifdef __WXMSW__ return wxMessageBox(message, caption, style, parent, x, y); @@ -413,7 +415,7 @@ void Shutdown(void* parg) StopNode(); DBFlush(true); CreateThread(ExitTimeout, NULL); - Sleep(10); + Sleep(50); printf("Bitcoin exiting\n\n"); fExit = true; exit(0); @@ -697,19 +699,22 @@ bool CMainFrame::InsertTransaction(const CWalletTx& wtx, bool fNew, int nIndex) vector vchPubKey; if (ExtractPubKey(txout.scriptPubKey, true, vchPubKey)) { - string strAddress = PubKeyToAddress(vchPubKey); - if (mapAddressBook.count(strAddress)) + CRITICAL_BLOCK(cs_mapAddressBook) { - //strDescription += "Received payment to "; - //strDescription += "Received with address "; - strDescription += "From: unknown, To: "; - strDescription += strAddress; - /// The labeling feature is just too confusing, so I hid it - /// by putting it at the end where it runs off the screen. - /// It can still be seen by widening the column, or in the - /// details dialog. - if (!mapAddressBook[strAddress].empty()) - strDescription += " (" + mapAddressBook[strAddress] + ")"; + string strAddress = PubKeyToAddress(vchPubKey); + if (mapAddressBook.count(strAddress)) + { + //strDescription += "Received payment to "; + //strDescription += "Received with address "; + strDescription += "From: unknown, To: "; + strDescription += strAddress; + /// The labeling feature is just too confusing, so I hid it + /// by putting it at the end where it runs off the screen. + /// It can still be seen by widening the column, or in the + /// details dialog. + if (!mapAddressBook[strAddress].empty()) + strDescription += " (" + mapAddressBook[strAddress] + ")"; + } } } break; @@ -776,8 +781,9 @@ bool CMainFrame::InsertTransaction(const CWalletTx& wtx, bool fNew, int nIndex) } string strDescription = "To: "; - if (mapAddressBook.count(strAddress) && !mapAddressBook[strAddress].empty()) - strDescription += mapAddressBook[strAddress] + " "; + CRITICAL_BLOCK(cs_mapAddressBook) + if (mapAddressBook.count(strAddress) && !mapAddressBook[strAddress].empty()) + strDescription += mapAddressBook[strAddress] + " "; strDescription += strAddress; if (!mapValue["message"].empty()) { @@ -1273,238 +1279,241 @@ void CMainFrame::OnListItemActivatedOrdersReceived(wxListEvent& event) CTxDetailsDialog::CTxDetailsDialog(wxWindow* parent, CWalletTx wtx) : CTxDetailsDialogBase(parent) { - string strHTML; - strHTML.reserve(4000); - strHTML += ""; + CRITICAL_BLOCK(cs_mapAddressBook) + { + string strHTML; + strHTML.reserve(4000); + strHTML += ""; - int64 nTime = wtx.GetTxTime(); - int64 nCredit = wtx.GetCredit(); - int64 nDebit = wtx.GetDebit(); - int64 nNet = nCredit - nDebit; + int64 nTime = wtx.GetTxTime(); + int64 nCredit = wtx.GetCredit(); + int64 nDebit = wtx.GetDebit(); + int64 nNet = nCredit - nDebit; - strHTML += "Status: " + 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 += "
"; + strHTML += "Status: " + 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 += "
"; - strHTML += "Date: " + (nTime ? DateTimeStr(nTime) : "") + "
"; + strHTML += "Date: " + (nTime ? DateTimeStr(nTime) : "") + "
"; - // - // From - // - if (wtx.IsCoinBase()) - { - strHTML += "Source: Generated
"; - } - else if (!wtx.mapValue["from"].empty()) - { - // Online transaction - if (!wtx.mapValue["from"].empty()) - strHTML += "From: " + HtmlEscape(wtx.mapValue["from"]) + "
"; - } - else - { - // Offline transaction - if (nNet > 0) + // + // From + // + if (wtx.IsCoinBase()) { - // Credit - foreach(const CTxOut& txout, wtx.vout) + strHTML += "Source: Generated
"; + } + else if (!wtx.mapValue["from"].empty()) + { + // Online transaction + if (!wtx.mapValue["from"].empty()) + strHTML += "From: " + HtmlEscape(wtx.mapValue["from"]) + "
"; + } + else + { + // Offline transaction + if (nNet > 0) { - if (txout.IsMine()) + // Credit + foreach(const CTxOut& txout, wtx.vout) { - vector vchPubKey; - if (ExtractPubKey(txout.scriptPubKey, true, vchPubKey)) + if (txout.IsMine()) { - string strAddress = PubKeyToAddress(vchPubKey); - if (mapAddressBook.count(strAddress)) + vector vchPubKey; + if (ExtractPubKey(txout.scriptPubKey, true, vchPubKey)) { - strHTML += "From: unknown
"; - strHTML += "To: "; - strHTML += HtmlEscape(strAddress); - if (!mapAddressBook[strAddress].empty()) - strHTML += " (yours, label: " + mapAddressBook[strAddress] + ")"; - else - strHTML += " (yours)"; - strHTML += "
"; + string strAddress = PubKeyToAddress(vchPubKey); + if (mapAddressBook.count(strAddress)) + { + strHTML += "From: unknown
"; + strHTML += "To: "; + strHTML += HtmlEscape(strAddress); + if (!mapAddressBook[strAddress].empty()) + strHTML += " (yours, label: " + mapAddressBook[strAddress] + ")"; + else + strHTML += " (yours)"; + strHTML += "
"; + } } + break; } - break; } } } - } - // - // To - // - string strAddress; - if (!wtx.mapValue["to"].empty()) - { - // Online transaction - strAddress = wtx.mapValue["to"]; - strHTML += "To: "; - if (mapAddressBook.count(strAddress) && !mapAddressBook[strAddress].empty()) - strHTML += mapAddressBook[strAddress] + " "; - strHTML += HtmlEscape(strAddress) + "
"; - } - - - // - // Amount - // - if (wtx.IsCoinBase() && nCredit == 0) - { - // - // Coinbase - // - int64 nUnmatured = 0; - foreach(const CTxOut& txout, wtx.vout) - nUnmatured += txout.GetCredit(); - if (wtx.IsInMainChain()) - strHTML += strprintf("Credit: (%s matures in %d more blocks)
", FormatMoney(nUnmatured).c_str(), wtx.GetBlocksToMaturity()); - else - strHTML += "Credit: (not accepted)
"; - } - else if (nNet > 0) - { // - // Credit + // To // - strHTML += "Credit: " + FormatMoney(nNet) + "
"; - } - else - { - bool fAllFromMe = true; - foreach(const CTxIn& txin, wtx.vin) - fAllFromMe = fAllFromMe && txin.IsMine(); + string strAddress; + if (!wtx.mapValue["to"].empty()) + { + // Online transaction + strAddress = wtx.mapValue["to"]; + strHTML += "To: "; + if (mapAddressBook.count(strAddress) && !mapAddressBook[strAddress].empty()) + strHTML += mapAddressBook[strAddress] + " "; + strHTML += HtmlEscape(strAddress) + "
"; + } - bool fAllToMe = true; - foreach(const CTxOut& txout, wtx.vout) - fAllToMe = fAllToMe && txout.IsMine(); - if (fAllFromMe) + // + // Amount + // + if (wtx.IsCoinBase() && nCredit == 0) { // - // Debit + // Coinbase // + int64 nUnmatured = 0; foreach(const CTxOut& txout, wtx.vout) - { - if (txout.IsMine()) - continue; + nUnmatured += txout.GetCredit(); + if (wtx.IsInMainChain()) + strHTML += strprintf("Credit: (%s matures in %d more blocks)
", FormatMoney(nUnmatured).c_str(), wtx.GetBlocksToMaturity()); + else + strHTML += "Credit: (not accepted)
"; + } + else if (nNet > 0) + { + // + // Credit + // + strHTML += "Credit: " + FormatMoney(nNet) + "
"; + } + else + { + bool fAllFromMe = true; + foreach(const CTxIn& txin, wtx.vin) + fAllFromMe = fAllFromMe && txin.IsMine(); + + bool fAllToMe = true; + foreach(const CTxOut& txout, wtx.vout) + fAllToMe = fAllToMe && txout.IsMine(); - if (wtx.mapValue["to"].empty()) + if (fAllFromMe) + { + // + // Debit + // + foreach(const CTxOut& txout, wtx.vout) { - // Offline transaction - uint160 hash160; - if (ExtractHash160(txout.scriptPubKey, hash160)) + if (txout.IsMine()) + continue; + + if (wtx.mapValue["to"].empty()) { - string strAddress = Hash160ToAddress(hash160); - strHTML += "To: "; - if (mapAddressBook.count(strAddress) && !mapAddressBook[strAddress].empty()) - strHTML += mapAddressBook[strAddress] + " "; - strHTML += strAddress; - strHTML += "
"; + // Offline transaction + uint160 hash160; + if (ExtractHash160(txout.scriptPubKey, hash160)) + { + string strAddress = Hash160ToAddress(hash160); + strHTML += "To: "; + if (mapAddressBook.count(strAddress) && !mapAddressBook[strAddress].empty()) + strHTML += mapAddressBook[strAddress] + " "; + strHTML += strAddress; + strHTML += "
"; + } } + + strHTML += "Debit: " + FormatMoney(-txout.nValue) + "
"; } - strHTML += "Debit: " + FormatMoney(-txout.nValue) + "
"; - } + if (fAllToMe) + { + // Payment to self + /// issue: can't tell which is the payment and which is the change anymore + //int64 nValue = wtx.vout[0].nValue; + //strHTML += "Debit: " + FormatMoney(-nValue) + "
"; + //strHTML += "Credit: " + FormatMoney(nValue) + "
"; + } - if (fAllToMe) + int64 nTxFee = nDebit - wtx.GetValueOut(); + if (nTxFee > 0) + strHTML += "Transaction fee: " + FormatMoney(-nTxFee) + "
"; + } + else { - // Payment to self - /// issue: can't tell which is the payment and which is the change anymore - //int64 nValue = wtx.vout[0].nValue; - //strHTML += "Debit: " + FormatMoney(-nValue) + "
"; - //strHTML += "Credit: " + FormatMoney(nValue) + "
"; + // + // Mixed debit transaction + // + foreach(const CTxIn& txin, wtx.vin) + if (txin.IsMine()) + strHTML += "Debit: " + FormatMoney(-txin.GetDebit()) + "
"; + foreach(const CTxOut& txout, wtx.vout) + if (txout.IsMine()) + strHTML += "Credit: " + FormatMoney(txout.GetCredit()) + "
"; } - - int64 nTxFee = nDebit - wtx.GetValueOut(); - if (nTxFee > 0) - strHTML += "Transaction fee: " + FormatMoney(-nTxFee) + "
"; } - else - { - // - // Mixed debit transaction - // - foreach(const CTxIn& txin, wtx.vin) - if (txin.IsMine()) - strHTML += "Debit: " + FormatMoney(-txin.GetDebit()) + "
"; - foreach(const CTxOut& txout, wtx.vout) - if (txout.IsMine()) - strHTML += "Credit: " + FormatMoney(txout.GetCredit()) + "
"; - } - } - strHTML += "Net amount: " + FormatMoney(nNet, true) + "
"; + strHTML += "Net amount: " + FormatMoney(nNet, true) + "
"; - // - // Message - // - if (!wtx.mapValue["message"].empty()) - strHTML += "
Message:
" + HtmlEscape(wtx.mapValue["message"], true) + "
"; - - if (wtx.IsCoinBase()) - strHTML += "
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.
"; + // + // Message + // + if (!wtx.mapValue["message"].empty()) + strHTML += "
Message:
" + HtmlEscape(wtx.mapValue["message"], true) + "
"; + if (wtx.IsCoinBase()) + strHTML += "
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.
"; - // - // Debug view - // - if (fDebug) - { - strHTML += "

debug print

"; - foreach(const CTxIn& txin, wtx.vin) - if (txin.IsMine()) - strHTML += "Debit: " + FormatMoney(-txin.GetDebit()) + "
"; - foreach(const CTxOut& txout, wtx.vout) - if (txout.IsMine()) - strHTML += "Credit: " + FormatMoney(txout.GetCredit()) + "
"; - strHTML += "Inputs:
"; - CRITICAL_BLOCK(cs_mapWallet) + // + // Debug view + // + if (fDebug) { + strHTML += "

debug print

"; foreach(const CTxIn& txin, wtx.vin) + if (txin.IsMine()) + strHTML += "Debit: " + FormatMoney(-txin.GetDebit()) + "
"; + foreach(const CTxOut& txout, wtx.vout) + if (txout.IsMine()) + strHTML += "Credit: " + FormatMoney(txout.GetCredit()) + "
"; + + strHTML += "Inputs:
"; + CRITICAL_BLOCK(cs_mapWallet) { - COutPoint prevout = txin.prevout; - map::iterator mi = mapWallet.find(prevout.hash); - if (mi != mapWallet.end()) + foreach(const CTxIn& txin, wtx.vin) { - const CWalletTx& prev = (*mi).second; - if (prevout.n < prev.vout.size()) + COutPoint prevout = txin.prevout; + map::iterator mi = mapWallet.find(prevout.hash); + if (mi != mapWallet.end()) { - strHTML += HtmlEscape(prev.ToString(), true); - strHTML += "    " + FormatTxStatus(prev) + ", "; - strHTML = strHTML + "IsMine=" + (prev.vout[prevout.n].IsMine() ? "true" : "false") + "
"; + const CWalletTx& prev = (*mi).second; + if (prevout.n < prev.vout.size()) + { + strHTML += HtmlEscape(prev.ToString(), true); + strHTML += "    " + FormatTxStatus(prev) + ", "; + strHTML = strHTML + "IsMine=" + (prev.vout[prevout.n].IsMine() ? "true" : "false") + "
"; + } } } } - } - strHTML += "


Transaction:
"; - strHTML += HtmlEscape(wtx.ToString(), true); - } + strHTML += "


Transaction:
"; + strHTML += HtmlEscape(wtx.ToString(), true); + } - strHTML += "
"; - string(strHTML.begin(), strHTML.end()).swap(strHTML); - m_htmlWin->SetPage(strHTML); - m_buttonOK->SetFocus(); + strHTML += "
"; + string(strHTML.begin(), strHTML.end()).swap(strHTML); + m_htmlWin->SetPage(strHTML); + m_buttonOK->SetFocus(); + } } void CTxDetailsDialog::OnButtonOK(wxCommandEvent& event) @@ -1686,9 +1695,10 @@ CAboutDialog::CAboutDialog(wxWindow* parent) : CAboutDialogBase(parent) #if !wxUSE_UNICODE // Workaround until upgrade to wxWidgets supporting UTF-8 + // Hack to change the (c) character from UTF-8 back to ANSI wxString str = m_staticTextMain->GetLabel(); - if (str.Find('Â') != wxNOT_FOUND) - str.Remove(str.Find('Â'), 1); + if (str.Find('\xC2') != wxNOT_FOUND) + str.Remove(str.Find('\xC2'), 1); m_staticTextMain->SetLabel(str); #endif #ifndef __WXMSW__ @@ -1843,10 +1853,11 @@ void CSendDialog::OnButtonSend(wxCommandEvent& event) CScript scriptPubKey; scriptPubKey << OP_DUP << OP_HASH160 << hash160 << OP_EQUALVERIFY << OP_CHECKSIG; - if (!SendMoney(scriptPubKey, nValue, wtx)) - return; - - wxMessageBox("Payment sent ", "Sending..."); + string strError = SendMoney(scriptPubKey, nValue, wtx); + if (strError != "") + wxMessageBox(strError + " ", "Sending..."); + else + wxMessageBox("Payment sent ", "Sending..."); } else { @@ -1869,8 +1880,9 @@ void CSendDialog::OnButtonSend(wxCommandEvent& event) return; } - if (!mapAddressBook.count(strAddress)) - SetAddressBookName(strAddress, ""); + CRITICAL_BLOCK(cs_mapAddressBook) + if (!mapAddressBook.count(strAddress)) + SetAddressBookName(strAddress, ""); EndModal(true); } @@ -2227,6 +2239,7 @@ CYourAddressDialog::CYourAddressDialog(wxWindow* parent, const string& strInitSe // Fill listctrl with address book data CRITICAL_BLOCK(cs_mapKeys) + CRITICAL_BLOCK(cs_mapAddressBook) { foreach(const PAIRTYPE(string, string)& item, mapAddressBook) { @@ -2366,6 +2379,7 @@ CAddressBookDialog::CAddressBookDialog(wxWindow* parent, const wxString& strInit // Fill listctrl with address book data CRITICAL_BLOCK(cs_mapKeys) + CRITICAL_BLOCK(cs_mapAddressBook) { foreach(const PAIRTYPE(string, string)& item, mapAddressBook) { @@ -3515,6 +3529,12 @@ bool CMyApp::OnInit2() // // Parameters // + if (argc > 1 && argv[1][0] != '-' && argv[1][0] != '/') + { + int ret = CommandLineRPC(argc, argv); + exit(ret); + } + ParseParameters(argc, argv); if (mapArgs.count("-?") || mapArgs.count("--help")) { @@ -3557,6 +3577,13 @@ bool CMyApp::OnInit2() if (mapArgs.count("-printtodebugger")) fPrintToDebugger = true; + if (mapArgs.count("-daemon") || mapArgs.count("-d")) + { + fDaemon = true; + /// todo: need to fork + /// should it fork after the bind/single instance stuff? + } + if (!fDebug && !pszSetDataDir[0]) ShrinkDebugFile(); printf("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"); @@ -3730,7 +3757,7 @@ bool CMyApp::OnInit2() // // Create the main frame window // - if (!mapArgs.count("-noui")) + if (!fDaemon) { pframeMain = new CMainFrame(NULL); if (mapArgs.count("-min")) @@ -3752,6 +3779,9 @@ bool CMyApp::OnInit2() if (!CreateThread(StartNode, NULL)) wxMessageBox("Error: CreateThread(StartNode) failed", "Bitcoin"); + if (mapArgs.count("-server") || fDaemon) + CreateThread(ThreadRPCServer, NULL); + if (fFirstRun) SetStartOnSystemStartup(true); diff --git a/util.cpp b/util.cpp index 4292246762..2f5be2227f 100644 --- a/util.cpp +++ b/util.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2009 Satoshi Nakamoto +// 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. @@ -12,6 +12,7 @@ bool fPrintToConsole = false; bool fPrintToDebugger = false; char pszSetDataDir[MAX_PATH] = ""; bool fShutdown = false; +bool fDaemon = false; diff --git a/util.h b/util.h index d20648bcd3..6a7fabc5e9 100644 --- a/util.h +++ b/util.h @@ -1,4 +1,4 @@ -// Copyright (c) 2009 Satoshi Nakamoto +// 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. @@ -55,6 +55,7 @@ inline T& REF(const T& val) } #ifdef __WXMSW__ +static const bool fWindows = true; #define MSG_NOSIGNAL 0 #define MSG_DONTWAIT 0 #ifndef UINT64_MAX @@ -66,7 +67,9 @@ inline T& REF(const T& val) #define S_IRUSR 0400 #define S_IWUSR 0200 #endif +#define unlink _unlink #else +static const bool fWindows = false; #define WSAGetLastError() errno #define WSAEWOULDBLOCK EWOULDBLOCK #define WSAEMSGSIZE EMSGSIZE @@ -116,6 +119,7 @@ extern bool fPrintToConsole; extern bool fPrintToDebugger; extern char pszSetDataDir[MAX_PATH]; extern bool fShutdown; +extern bool fDaemon; void RandAddSeed(); void RandAddSeedPerfmon(); @@ -258,6 +262,11 @@ inline int roundint(double d) return (int)(d > 0 ? d + 0.5 : d - 0.5); } +inline int64 roundint64(double d) +{ + return (int64)(d > 0 ? d + 0.5 : d - 0.5); +} + template string HexStr(const T itbegin, const T itend, bool fSpaces=true) { @@ -323,7 +332,12 @@ inline string DateTimeStrFormat(const char* pszFormat, int64 nTime) return pszTime; } - +template +void skipspaces(T& it) +{ + while (isspace(*it)) + ++it; +} -- cgit v1.2.3 From 98500d70a8cf25af4bab80526fd128ccdc36ceeb Mon Sep 17 00:00:00 2001 From: s_nakamoto Date: Fri, 12 Feb 2010 20:38:44 +0000 Subject: command line and JSON-RPC first draft, requires Boost 1.35 or higher for boost::asio, added SetBitcoinAddress and GetBitcoinAddress methods on CScript, critsect interlocks around mapAddressBook, added some random delays in tx broadcast to improve privacy, now compiles with MSVC 8.0 git-svn-id: https://bitcoin.svn.sourceforge.net/svnroot/bitcoin/trunk@60 1a98c847-1fd6-4fd8-948a-caf3550aa51b --- bignum.h | 33 ++- build-msw.txt | 27 ++- db.h | 10 +- headers.h | 9 +- irc.cpp | 2 +- irc.h | 6 +- license.txt | 2 +- main.cpp | 151 +++++++++---- main.h | 9 +- makefile | 25 +- makefile.unix.wx2.8 | 20 +- makefile.unix.wx2.9 | 20 +- makefile.vc | 25 +- net.cpp | 15 +- net.h | 3 +- rpc.cpp | 641 ++++++++++++++++++++++++++++++++++++++++++++++++++++ rpc.h | 6 + script.cpp | 9 +- script.h | 44 +++- serialize.h | 4 +- ui.cpp | 436 ++++++++++++++++++----------------- util.cpp | 3 +- util.h | 18 +- 23 files changed, 1186 insertions(+), 332 deletions(-) create mode 100644 rpc.cpp create mode 100644 rpc.h diff --git a/bignum.h b/bignum.h index 8aa4e9c4ff..e1ab165b2c 100644 --- a/bignum.h +++ b/bignum.h @@ -1,4 +1,4 @@ -// Copyright (c) 2009 Satoshi Nakamoto +// 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. @@ -309,6 +309,37 @@ public: *this = 0 - *this; } + std::string ToString(int nBase=10) const + { + CAutoBN_CTX pctx; + CBigNum bnBase = nBase; + CBigNum bn0 = 0; + string str; + CBigNum bn = *this; + BN_set_negative(&bn, false); + CBigNum dv; + CBigNum rem; + if (BN_cmp(&bn, &bn0) == 0) + return "0"; + while (BN_cmp(&bn, &bn0) > 0) + { + if (!BN_div(&dv, &rem, &bn, &bnBase, pctx)) + throw bignum_error("CBigNum::ToString() : BN_div failed"); + bn = dv; + unsigned int c = rem.getulong(); + str += "0123456789abcdef"[c]; + } + if (BN_is_negative(this)) + str += "-"; + reverse(str.begin(), str.end()); + return str; + } + + std::string GetHex() const + { + return ToString(16); + } + unsigned int GetSerializeSize(int nType=0, int nVersion=VERSION) const { return ::GetSerializeSize(getvch(), nType, nVersion); diff --git a/build-msw.txt b/build-msw.txt index 56a38b0286..9786255e1f 100644 --- a/build-msw.txt +++ b/build-msw.txt @@ -1,6 +1,6 @@ Bitcoin v0.2.0 BETA -Copyright (c) 2009 Satoshi Nakamoto +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. This product includes software developed by the OpenSSL Project for use in @@ -13,8 +13,16 @@ WINDOWS BUILD NOTES Compilers Supported ------------------- -MinGW GCC -Microsoft Visual C++ 6.0 SP6 +MinGW GCC (recommended) + +MSVC 6.0 SP6: You'll need Boost version 1.34 because they dropped support +for MSVC 6.0 after that. However, they didn't add Asio until 1.35. +You should still be able to build with MSVC 6.0 by adding Asio to 1.34 by +unpacking boost_asio_*.zip into the boost directory: +http://sourceforge.net/projects/asio/files/asio + +MSVC 8.0 (2005) SP1 has been tested. Note: MSVC 7.0 and up have a habit of +linking to runtime DLLs that are not installed on XP by default. Dependencies @@ -22,8 +30,7 @@ Dependencies Libraries you need to download separately and build: default path download -wxWidgets \wxwidgets http://www.wxwidgets.org/downloads/ - or prebuilt: http://wxpack.sourceforge.net +wxWidgets \wxwidgets prebuilt: http://wxpack.sourceforge.net OpenSSL \openssl http://www.openssl.org/source/ Berkeley DB \db http://www.oracle.com/technology/software/products/berkeley-db/index.html Boost \boost http://www.boost.org/users/download/ @@ -89,3 +96,13 @@ Using MinGW and MSYS: cd \db\build_unix sh ../dist/configure --enable-mingw --enable-cxx make + + +Boost +----- +download bjam.exe from +http://sourceforge.net/project/showfiles.php?group_id=7586&package_id=72941 +cd \boost +bjam toolset=gcc --build-type=complete stage +or +bjam toolset=msvc --build-type=complete stage diff --git a/db.h b/db.h index d32d2d5d2f..538076b5aa 100644 --- a/db.h +++ b/db.h @@ -1,8 +1,7 @@ -// Copyright (c) 2009 Satoshi Nakamoto +// 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 class CTransaction; class CTxIndex; class CDiskBlockIndex; @@ -14,6 +13,7 @@ class CAddress; class CWalletTx; extern map mapAddressBook; +extern CCriticalSection cs_mapAddressBook; extern bool fClient; @@ -359,15 +359,17 @@ public: bool WriteName(const string& strAddress, const string& strName) { + CRITICAL_BLOCK(cs_mapAddressBook) + mapAddressBook[strAddress] = strName; nWalletDBUpdated++; - mapAddressBook[strAddress] = strName; return Write(make_pair(string("name"), strAddress), strName); } bool EraseName(const string& strAddress) { + CRITICAL_BLOCK(cs_mapAddressBook) + mapAddressBook.erase(strAddress); nWalletDBUpdated++; - mapAddressBook.erase(strAddress); return Erase(make_pair(string("name"), strAddress)); } diff --git a/headers.h b/headers.h index 45be4b65d1..dda4f9caf2 100644 --- a/headers.h +++ b/headers.h @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include @@ -36,6 +37,7 @@ #include #include #include +#include #include #include #include @@ -53,6 +55,8 @@ #include #include #include +#include +#include #ifdef __WXMSW__ #include @@ -73,8 +77,6 @@ #include #include #include -#include -#include #endif #ifdef __BSD__ #include @@ -85,8 +87,6 @@ using namespace std; using namespace boost; - - #include "strlcpy.h" #include "serialize.h" #include "uint256.h" @@ -100,6 +100,7 @@ using namespace boost; #include "irc.h" #include "main.h" #include "market.h" +#include "rpc.h" #include "uibase.h" #include "ui.h" diff --git a/irc.cpp b/irc.cpp index f38db6bbb0..9d563cce8d 100644 --- a/irc.cpp +++ b/irc.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2009 Satoshi Nakamoto +// 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. diff --git a/irc.h b/irc.h index c69fd9ee97..13de570b16 100644 --- a/irc.h +++ b/irc.h @@ -1,8 +1,8 @@ -// Copyright (c) 2009 Satoshi Nakamoto +// 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. -extern bool RecvLine(SOCKET hSocket, string& strLine); -extern void ThreadIRCSeed(void* parg); +bool RecvLine(SOCKET hSocket, string& strLine); +void ThreadIRCSeed(void* parg); extern int nGotIRCAddresses; diff --git a/license.txt b/license.txt index 3844dfb429..f96fa98f4c 100644 --- a/license.txt +++ b/license.txt @@ -1,4 +1,4 @@ -Copyright (c) 2009 Satoshi Nakamoto +Copyright (c) 2009-2010 Satoshi Nakamoto Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/main.cpp b/main.cpp index 53acf8a753..90d239fa0f 100644 --- a/main.cpp +++ b/main.cpp @@ -26,6 +26,7 @@ CBlockIndex* pindexGenesisBlock = NULL; int nBestHeight = -1; uint256 hashBestChain = 0; CBlockIndex* pindexBest = NULL; +int64 nTimeBestReceived = 0; map mapOrphanBlocks; multimap mapOrphanBlocksByPrev; @@ -45,6 +46,9 @@ CKey keyUser; map mapRequestCount; CCriticalSection cs_mapRequestCount; +map mapAddressBook; +CCriticalSection cs_mapAddressBook; + // Settings int fGenerateBitcoins = false; int64 nTransactionFee = 0; @@ -573,7 +577,7 @@ bool CTransaction::RemoveFromMemoryPool() -int CMerkleTx::GetDepthInMainChain() const +int CMerkleTx::GetDepthInMainChain(int& nHeightRet) const { if (hashBlock == 0 || nIndex == -1) return 0; @@ -594,6 +598,7 @@ int CMerkleTx::GetDepthInMainChain() const fMerkleVerified = true; } + nHeightRet = pindex->nHeight; return pindexBest->nHeight - pindex->nHeight + 1; } @@ -708,15 +713,20 @@ void CWalletTx::RelayWalletTransaction(CTxDB& txdb) } } -void RelayWalletTransactions() +void ResendWalletTransactions() { - static int64 nLastTime; - if (GetTime() - nLastTime < 10 * 60) + // Do this infrequently and randomly to avoid giving away + // that these are our transactions. + static int64 nNextTime; + if (GetTime() < nNextTime) + return; + bool fFirst = (nNextTime == 0); + nNextTime = GetTime() + GetRand(120 * 60); + if (fFirst) return; - nLastTime = GetTime(); // Rebroadcast any of our txes that aren't in a block yet - printf("RelayWalletTransactions()\n"); + printf("ResendWalletTransactions()\n"); CTxDB txdb("r"); CRITICAL_BLOCK(cs_mapWallet) { @@ -725,7 +735,10 @@ void RelayWalletTransactions() foreach(PAIRTYPE(const uint256, CWalletTx)& item, mapWallet) { CWalletTx& wtx = item.second; - mapSorted.insert(make_pair(wtx.nTimeReceived, &wtx)); + // Don't rebroadcast until it's had plenty of time that + // it should have gotten in already by now. + if (nTimeBestReceived - wtx.nTimeReceived > 60 * 60) + mapSorted.insert(make_pair(wtx.nTimeReceived, &wtx)); } foreach(PAIRTYPE(const unsigned int, CWalletTx*)& item, mapSorted) { @@ -1219,10 +1232,11 @@ bool CBlock::AddToBlockIndex(unsigned int nFile, unsigned int nBlockPos) } } - // New best link + // New best block hashBestChain = hash; pindexBest = pindexNew; nBestHeight = pindexBest->nHeight; + nTimeBestReceived = GetTime(); nTransactionsUpdated++; printf("AddToBlockIndex: new best=%s height=%d\n", hashBestChain.ToString().substr(0,16).c_str(), nBestHeight); } @@ -1232,9 +1246,6 @@ bool CBlock::AddToBlockIndex(unsigned int nFile, unsigned int nBlockPos) if (pindexNew == pindexBest) { - // Relay wallet transactions that haven't gotten in yet - RelayWalletTransactions(); - // Notify UI to display prev block's coinbase if it was ours static uint256 hashPrevBestCoinBase; CRITICAL_BLOCK(cs_mapWallet) @@ -2248,7 +2259,7 @@ bool SendMessages(CNode* pto) return true; // Keep-alive ping - if (pto->nLastSend && GetTime() - pto->nLastSend > 12 * 60 && pto->vSend.empty()) + if (pto->nLastSend && GetTime() - pto->nLastSend > 30 * 60 && pto->vSend.empty()) pto->PushMessage("ping"); // Address refresh broadcast @@ -2270,60 +2281,81 @@ bool SendMessages(CNode* pto) } } + // Delay tx inv messages to protect privacy, + // trickle them out to a few nodes at a time. + bool fSendTxInv = false; + if (GetTimeMillis() - pto->nLastSentTxInv > 1800 + GetRand(200)) + { + pto->nLastSentTxInv = GetTimeMillis(); + fSendTxInv = true; + } + + // Resend wallet transactions that haven't gotten in a block yet + ResendWalletTransactions(); + // // Message: addr // - vector vAddrToSend; - vAddrToSend.reserve(pto->vAddrToSend.size()); + vector vAddr; + vAddr.reserve(pto->vAddrToSend.size()); foreach(const CAddress& addr, pto->vAddrToSend) { // returns true if wasn't already contained in the set if (pto->setAddrKnown.insert(addr).second) { - vAddrToSend.push_back(addr); - if (vAddrToSend.size() >= 1000) + vAddr.push_back(addr); + if (vAddr.size() >= 1000) { - pto->PushMessage("addr", vAddrToSend); - vAddrToSend.clear(); + pto->PushMessage("addr", vAddr); + vAddr.clear(); } } } pto->vAddrToSend.clear(); - if (!vAddrToSend.empty()) - pto->PushMessage("addr", vAddrToSend); + if (!vAddr.empty()) + pto->PushMessage("addr", vAddr); // // Message: inventory // - vector vInventoryToSend; + vector vInv; + vector vInvWait; CRITICAL_BLOCK(pto->cs_inventory) { - vInventoryToSend.reserve(pto->vInventoryToSend.size()); + vInv.reserve(pto->vInventoryToSend.size()); + vInvWait.reserve(pto->vInventoryToSend.size()); foreach(const CInv& inv, pto->vInventoryToSend) { + // delay txes + if (!fSendTxInv && inv.type == MSG_TX) + { + vInvWait.push_back(inv); + continue; + } + // returns true if wasn't already contained in the set if (pto->setInventoryKnown.insert(inv).second) { - vInventoryToSend.push_back(inv); - if (vInventoryToSend.size() >= 1000) + vInv.push_back(inv); + if (vInv.size() >= 1000) { - pto->PushMessage("inv", vInventoryToSend); - vInventoryToSend.clear(); + pto->PushMessage("inv", vInv); + vInv.clear(); } } } - pto->vInventoryToSend.clear(); + pto->vInventoryToSend = vInvWait; } - if (!vInventoryToSend.empty()) - pto->PushMessage("inv", vInventoryToSend); + if (!vInv.empty()) + pto->PushMessage("inv", vInv); // // Message: getdata // - vector vAskFor; + vector vGetData; int64 nNow = GetTime() * 1000000; CTxDB txdb("r"); while (!pto->mapAskFor.empty() && (*pto->mapAskFor.begin()).first <= nNow) @@ -2332,17 +2364,17 @@ bool SendMessages(CNode* pto) if (!AlreadyHave(txdb, inv)) { printf("sending getdata: %s\n", inv.ToString().c_str()); - vAskFor.push_back(inv); - if (vAskFor.size() >= 1000) + vGetData.push_back(inv); + if (vGetData.size() >= 1000) { - pto->PushMessage("getdata", vAskFor); - vAskFor.clear(); + pto->PushMessage("getdata", vGetData); + vGetData.clear(); } } pto->mapAskFor.erase(pto->mapAskFor.begin()); } - if (!vAskFor.empty()) - pto->PushMessage("getdata", vAskFor); + if (!vGetData.empty()) + pto->PushMessage("getdata", vGetData); } return true; @@ -2405,7 +2437,6 @@ void ThreadBitcoinMiner(void* parg) vnThreadsRunning[3]--; PrintException(NULL, "ThreadBitcoinMiner()"); } - printf("ThreadBitcoinMiner exiting, %d threads remaining\n", vnThreadsRunning[3]); } @@ -2842,6 +2873,13 @@ bool CreateTransaction(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew, CK // Fill a vout back to self with any change if (nValueIn > nTotalValue) { + // 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 + // backup is restored, if the backup doesn't have the new private key for the change. + // If we reused the old key, it would be possible to add code to look for and + // rediscover unknown transactions that were written with keys of ours to recover + // post-backup change. + // New private key if (keyRet.IsNull()) keyRet.MakeNewKey(); @@ -2899,7 +2937,7 @@ bool CommitTransactionSpent(const CWalletTx& wtxNew, const CKey& key) //// update: This matters even less now that fSpent can get corrected //// when transactions are seen in VerifySignature. The remote chance of //// unmarked fSpent will be handled by that. Don't need to make this - //// transactional. + //// transactional. Pls delete this comment block later. // 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 @@ -2932,7 +2970,7 @@ bool CommitTransactionSpent(const CWalletTx& wtxNew, const CKey& key) -bool SendMoney(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew) +string SendMoney(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew) { CRITICAL_BLOCK(cs_main) { @@ -2945,13 +2983,13 @@ bool SendMoney(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew) strError = strprintf("Error: This is an oversized transaction that requires a transaction fee of %s ", FormatMoney(nFeeRequired).c_str()); else strError = "Error: Transaction creation failed "; - wxMessageBox(strError, "Sending..."); - return error("SendMoney() : %s", strError.c_str()); + printf("SendMoney() : %s", strError.c_str()); + return strError; } if (!CommitTransactionSpent(wtxNew, key)) { - wxMessageBox("Error finalizing transaction ", "Sending..."); - return error("SendMoney() : Error finalizing transaction"); + printf("SendMoney() : Error finalizing transaction"); + return "Error finalizing transaction"; } // Track how many getdata requests our transaction gets @@ -2964,11 +3002,32 @@ bool SendMoney(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew) if (!wtxNew.AcceptTransaction()) { // This must not fail. The transaction has already been signed and recorded. - wxMessageBox("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.", "Sending..."); - return error("SendMoney() : Error: Transaction not valid"); + printf("SendMoney() : Error: Transaction not valid"); + return "Error: The transaction was rejected. This might happen if some of the coins in your wallet were already spent, such as if you used a copy of wallet.dat and coins were spent in the copy but not marked as spent here."; } wtxNew.RelayWalletTransaction(); } MainFrameRepaint(); - return true; + return ""; +} + + + +string SendMoneyToBitcoinAddress(string strAddress, int64 nValue, CWalletTx& wtxNew) +{ + // Check amount + if (nValue <= 0) + return "Invalid amount"; + if (nValue + nTransactionFee > GetBalance()) + return "You don't have enough money"; + + // Parse bitcoin address + uint160 hash160; + if (!AddressToHash160(strAddress, hash160)) + return "Invalid bitcoin address"; + + // Send to bitcoin address + CScript scriptPubKey; + scriptPubKey.SetBitcoinAddress(hash160); + return SendMoney(scriptPubKey, nValue, wtxNew); } diff --git a/main.h b/main.h index 14c445c70e..bcb6ec7dcc 100644 --- a/main.h +++ b/main.h @@ -36,6 +36,8 @@ extern CBlockIndex* pindexBest; extern unsigned int nTransactionsUpdated; extern map mapRequestCount; extern CCriticalSection cs_mapRequestCount; +extern map mapAddressBook; +extern CCriticalSection cs_mapAddressBook; // Settings extern int fGenerateBitcoins; @@ -58,7 +60,6 @@ vector GenerateNewKey(); bool AddToWallet(const CWalletTx& wtxIn); void WalletUpdateSpent(const COutPoint& prevout); void ReacceptWalletTransactions(); -void RelayWalletTransactions(); bool LoadBlockIndex(bool fAllowNew=true); void PrintBlockTree(); bool ProcessMessages(CNode* pfrom); @@ -67,7 +68,8 @@ bool SendMessages(CNode* pto); int64 GetBalance(); bool CreateTransaction(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew, CKey& keyRet, int64& nFeeRequiredRet); bool CommitTransactionSpent(const CWalletTx& wtxNew, const CKey& key); -bool SendMoney(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew); +string SendMoney(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew); +string SendMoneyToBitcoinAddress(string strAddress, int64 nValue, CWalletTx& wtxNew); void GenerateBitcoins(bool fGenerate); void ThreadBitcoinMiner(void* parg); void BitcoinMiner(); @@ -680,7 +682,8 @@ public: int SetMerkleBranch(const CBlock* pblock=NULL); - int GetDepthInMainChain() const; + int GetDepthInMainChain(int& nHeightRet) const; + int GetDepthInMainChain() const { int nHeight; return GetDepthInMainChain(nHeight); } bool IsInMainChain() const { return GetDepthInMainChain() > 0; } int GetBlocksToMaturity() const; bool AcceptTransaction(CTxDB& txdb, bool fCheckInputs=true); diff --git a/makefile b/makefile index 0dd622106e..affbe517c7 100644 --- a/makefile +++ b/makefile @@ -1,4 +1,4 @@ -# Copyright (c) 2009 Satoshi Nakamoto +# 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. @@ -16,22 +16,23 @@ endif INCLUDEPATHS=-I"/boost" -I"/db/build_unix" -I"/openssl/include" -I"/wxwidgets/lib/vc_lib/mswd" -I"/wxwidgets/include" -LIBPATHS=-L"/db/build_unix" -L"/openssl/out" -L"/wxwidgets/lib/gcc_lib" +LIBPATHS=-L"/boost/stage/lib" -L"/db/build_unix" -L"/openssl/out" -L"/wxwidgets/lib/gcc_lib" LIBS= \ + -l libboost_system-mgw34-mt-d -l libboost_filesystem-mgw34-mt-d \ -l db_cxx \ -l eay32 \ -l wxmsw28$(D)_richtext -l wxmsw28$(D)_html -l wxmsw28$(D)_core -l wxmsw28$(D)_adv -l wxbase28$(D) -l wxtiff$(D) -l wxjpeg$(D) -l wxpng$(D) -l wxzlib$(D) -l wxregex$(D) -l wxexpat$(D) \ -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 WXDEFS=-DWIN32 -D__WXMSW__ -D_WINDOWS -DNOPCH CFLAGS=-mthreads -O0 -w -Wno-invalid-offsetof -Wformat $(DEBUGFLAGS) $(WXDEFS) $(INCLUDEPATHS) -HEADERS=headers.h util.h main.h serialize.h uint256.h key.h bignum.h script.h db.h base58.h +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 market.h rpc.h uibase.h ui.h all: bitcoin.exe -headers.h.gch: headers.h $(HEADERS) net.h irc.h market.h uibase.h ui.h +headers.h.gch: headers.h $(HEADERS) g++ -c $(CFLAGS) -o $@ $< obj/util.o: util.cpp $(HEADERS) @@ -40,19 +41,19 @@ obj/util.o: util.cpp $(HEADERS) obj/script.o: script.cpp $(HEADERS) g++ -c $(CFLAGS) -o $@ $< -obj/db.o: db.cpp $(HEADERS) market.h +obj/db.o: db.cpp $(HEADERS) g++ -c $(CFLAGS) -o $@ $< -obj/net.o: net.cpp $(HEADERS) net.h +obj/net.o: net.cpp $(HEADERS) g++ -c $(CFLAGS) -o $@ $< -obj/main.o: main.cpp $(HEADERS) net.h market.h sha.h +obj/main.o: main.cpp $(HEADERS) sha.h g++ -c $(CFLAGS) -o $@ $< -obj/market.o: market.cpp $(HEADERS) market.h +obj/market.o: market.cpp $(HEADERS) g++ -c $(CFLAGS) -o $@ $< -obj/ui.o: ui.cpp $(HEADERS) net.h uibase.h ui.h market.h +obj/ui.o: ui.cpp $(HEADERS) g++ -c $(CFLAGS) -o $@ $< obj/uibase.o: uibase.cpp uibase.h @@ -64,13 +65,17 @@ obj/sha.o: sha.cpp sha.h obj/irc.o: irc.cpp $(HEADERS) g++ -c $(CFLAGS) -o $@ $< +obj/rpc.o: rpc.cpp $(HEADERS) + g++ -c $(CFLAGS) -o $@ $< + obj/ui_res.o: ui.rc rc/bitcoin.ico rc/check.ico rc/send16.bmp rc/send16mask.bmp rc/send16masknoshadow.bmp rc/send20.bmp rc/send20mask.bmp rc/addressbook16.bmp rc/addressbook16mask.bmp rc/addressbook20.bmp rc/addressbook20mask.bmp windres $(WXDEFS) $(INCLUDEPATHS) -o $@ -i $< OBJS=obj/util.o obj/script.o obj/db.o obj/net.o obj/main.o obj/market.o \ - obj/ui.o obj/uibase.o obj/sha.o obj/irc.o obj/ui_res.o + obj/ui.o obj/uibase.o obj/sha.o obj/irc.o obj/rpc.o \ + obj/ui_res.o bitcoin.exe: headers.h.gch $(OBJS) -kill /f bitcoin.exe diff --git a/makefile.unix.wx2.8 b/makefile.unix.wx2.8 index b9826d6ccb..d3358ab2df 100644 --- a/makefile.unix.wx2.8 +++ b/makefile.unix.wx2.8 @@ -1,4 +1,4 @@ -# Copyright (c) 2009 Satoshi Nakamoto +# 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. @@ -35,14 +35,14 @@ LIBS= \ WXDEFS=-D__WXGTK__ -DNOPCH CFLAGS=-O0 -Wno-invalid-offsetof -Wformat $(DEBUGFLAGS) $(WXDEFS) $(INCLUDEPATHS) -HEADERS=headers.h util.h main.h serialize.h uint256.h key.h bignum.h script.h db.h base58.h +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 market.h rpc.h uibase.h ui.h all: bitcoin -headers.h.gch: headers.h $(HEADERS) net.h irc.h market.h uibase.h ui.h +headers.h.gch: headers.h $(HEADERS) g++ -c $(CFLAGS) -o $@ $< obj/util.o: util.cpp $(HEADERS) @@ -51,19 +51,19 @@ obj/util.o: util.cpp $(HEADERS) obj/script.o: script.cpp $(HEADERS) g++ -c $(CFLAGS) -o $@ $< -obj/db.o: db.cpp $(HEADERS) market.h +obj/db.o: db.cpp $(HEADERS) g++ -c $(CFLAGS) -o $@ $< -obj/net.o: net.cpp $(HEADERS) net.h +obj/net.o: net.cpp $(HEADERS) g++ -c $(CFLAGS) -o $@ $< -obj/main.o: main.cpp $(HEADERS) net.h market.h sha.h +obj/main.o: main.cpp $(HEADERS) sha.h g++ -c $(CFLAGS) -o $@ $< -obj/market.o: market.cpp $(HEADERS) market.h +obj/market.o: market.cpp $(HEADERS) g++ -c $(CFLAGS) -o $@ $< -obj/ui.o: ui.cpp $(HEADERS) net.h uibase.h ui.h market.h +obj/ui.o: ui.cpp $(HEADERS) g++ -c $(CFLAGS) -o $@ $< obj/uibase.o: uibase.cpp uibase.h @@ -75,11 +75,13 @@ obj/sha.o: sha.cpp sha.h obj/irc.o: irc.cpp $(HEADERS) g++ -c $(CFLAGS) -o $@ $< +obj/rpc.o: rpc.cpp $(HEADERS) + g++ -c $(CFLAGS) -o $@ $< OBJS=obj/util.o obj/script.o obj/db.o obj/net.o obj/main.o obj/market.o \ - obj/ui.o obj/uibase.o obj/sha.o obj/irc.o + obj/ui.o obj/uibase.o obj/sha.o obj/irc.o obj/rpc.o bitcoin: headers.h.gch $(OBJS) g++ $(CFLAGS) -o $@ $(LIBPATHS) $(OBJS) $(LIBS) diff --git a/makefile.unix.wx2.9 b/makefile.unix.wx2.9 index 81dcbd70e9..8defcbb6fc 100644 --- a/makefile.unix.wx2.9 +++ b/makefile.unix.wx2.9 @@ -1,4 +1,4 @@ -# Copyright (c) 2009 Satoshi Nakamoto +# 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. @@ -35,14 +35,14 @@ LIBS= \ WXDEFS=-D__WXGTK__ -DNOPCH CFLAGS=-O0 -Wno-invalid-offsetof -Wformat $(DEBUGFLAGS) $(WXDEFS) $(INCLUDEPATHS) -HEADERS=headers.h util.h main.h serialize.h uint256.h key.h bignum.h script.h db.h base58.h +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 market.h rpc.h uibase.h ui.h all: bitcoin -headers.h.gch: headers.h $(HEADERS) net.h irc.h market.h uibase.h ui.h +headers.h.gch: headers.h $(HEADERS) g++ -c $(CFLAGS) -o $@ $< obj/util.o: util.cpp $(HEADERS) @@ -51,19 +51,19 @@ obj/util.o: util.cpp $(HEADERS) obj/script.o: script.cpp $(HEADERS) g++ -c $(CFLAGS) -o $@ $< -obj/db.o: db.cpp $(HEADERS) market.h +obj/db.o: db.cpp $(HEADERS) g++ -c $(CFLAGS) -o $@ $< -obj/net.o: net.cpp $(HEADERS) net.h +obj/net.o: net.cpp $(HEADERS) g++ -c $(CFLAGS) -o $@ $< -obj/main.o: main.cpp $(HEADERS) net.h market.h sha.h +obj/main.o: main.cpp $(HEADERS) sha.h g++ -c $(CFLAGS) -o $@ $< -obj/market.o: market.cpp $(HEADERS) market.h +obj/market.o: market.cpp $(HEADERS) g++ -c $(CFLAGS) -o $@ $< -obj/ui.o: ui.cpp $(HEADERS) net.h uibase.h ui.h market.h +obj/ui.o: ui.cpp $(HEADERS) g++ -c $(CFLAGS) -o $@ $< obj/uibase.o: uibase.cpp uibase.h @@ -75,11 +75,13 @@ obj/sha.o: sha.cpp sha.h obj/irc.o: irc.cpp $(HEADERS) g++ -c $(CFLAGS) -o $@ $< +obj/rpc.o: rpc.cpp $(HEADERS) + g++ -c $(CFLAGS) -o $@ $< OBJS=obj/util.o obj/script.o obj/db.o obj/net.o obj/main.o obj/market.o \ - obj/ui.o obj/uibase.o obj/sha.o obj/irc.o + obj/ui.o obj/uibase.o obj/sha.o obj/irc.o obj/rpc.o bitcoin: headers.h.gch $(OBJS) g++ $(CFLAGS) -o $@ $(LIBPATHS) $(OBJS) $(LIBS) diff --git a/makefile.vc b/makefile.vc index fb7f3086e3..73fd1cfd9a 100644 --- a/makefile.vc +++ b/makefile.vc @@ -1,4 +1,4 @@ -# Copyright (c) 2009 Satoshi Nakamoto +# 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. @@ -14,15 +14,16 @@ DEBUGFLAGS=/Zi /Od /D__WXDEBUG__ INCLUDEPATHS=/I"/boost" /I"/db/build_windows" /I"/openssl/include" /I"/wxwidgets/lib/vc_lib/mswd" /I"/wxwidgets/include" -LIBPATHS=/LIBPATH:"/db/build_windows/$(BUILD)" /LIBPATH:"/openssl/out" /LIBPATH:"/wxwidgets/lib/vc_lib" +LIBPATHS=/LIBPATH:"/boost/stage/lib" /LIBPATH:"/db/build_windows/$(BUILD)" /LIBPATH:"/openssl/out" /LIBPATH:"/wxwidgets/lib/vc_lib" LIBS= \ + libboost_system-vc80-mt-gd.lib libboost_filesystem-vc80-mt-gd.lib \ libdb47s$(D).lib \ libeay32.lib \ wxmsw28$(D)_richtext.lib wxmsw28$(D)_html.lib wxmsw28$(D)_core.lib wxmsw28$(D)_adv.lib wxbase28$(D).lib wxtiff$(D).lib wxjpeg$(D).lib wxpng$(D).lib wxzlib$(D).lib wxregex$(D).lib wxexpat$(D).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 WXDEFS=/DWIN32 /D__WXMSW__ /D_WINDOWS /DNOPCH CFLAGS=/c /nologo /Ob0 /MD$(D) /EHsc /GR /Zm300 /YX /Fpobj/headers.pch $(DEBUGFLAGS) $(WXDEFS) $(INCLUDEPATHS) -HEADERS=headers.h util.h main.h serialize.h uint256.h key.h bignum.h script.h db.h base58.h +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 market.h rpc.h uibase.h ui.h @@ -35,37 +36,41 @@ obj\util.obj: util.cpp $(HEADERS) obj\script.obj: script.cpp $(HEADERS) cl $(CFLAGS) /Fo$@ %s -obj\db.obj: db.cpp $(HEADERS) market.h +obj\db.obj: db.cpp $(HEADERS) cl $(CFLAGS) /Fo$@ %s -obj\net.obj: net.cpp $(HEADERS) net.h +obj\net.obj: net.cpp $(HEADERS) cl $(CFLAGS) /Fo$@ %s -obj\main.obj: main.cpp $(HEADERS) net.h market.h +obj\main.obj: main.cpp $(HEADERS) sha.h cl $(CFLAGS) /Fo$@ %s -obj\market.obj: market.cpp $(HEADERS) market.h +obj\market.obj: market.cpp $(HEADERS) cl $(CFLAGS) /Fo$@ %s -obj\ui.obj: ui.cpp $(HEADERS) net.h uibase.h ui.h market.h +obj\ui.obj: ui.cpp $(HEADERS) cl $(CFLAGS) /Fo$@ %s obj\uibase.obj: uibase.cpp uibase.h cl $(CFLAGS) /Fo$@ %s -obj\sha.obj: sha.cpp sha.h +obj\sha.obj: sha.cpp sha.h cl $(CFLAGS) /O2 /Fo$@ %s obj\irc.obj: irc.cpp $(HEADERS) cl $(CFLAGS) /Fo$@ %s +obj\rpc.obj: rpc.cpp $(HEADERS) + cl $(CFLAGS) /Fo$@ %s + obj\ui.res: ui.rc rc/bitcoin.ico rc/check.ico rc/send16.bmp rc/send16mask.bmp rc/send16masknoshadow.bmp rc/send20.bmp rc/send20mask.bmp rc/addressbook16.bmp rc/addressbook16mask.bmp rc/addressbook20.bmp rc/addressbook20mask.bmp rc $(INCLUDEPATHS) $(WXDEFS) /Fo$@ %s OBJS=obj\util.obj obj\script.obj obj\db.obj obj\net.obj obj\main.obj obj\market.obj \ - obj\ui.obj obj\uibase.obj obj\sha.obj obj\irc.obj obj\ui.res + obj\ui.obj obj\uibase.obj obj\sha.obj obj\irc.obj obj\rpc.obj \ + obj\ui.res bitcoin.exe: $(OBJS) -kill /f bitcoin.exe & sleep 1 diff --git a/net.cpp b/net.cpp index 38d05de1ab..ada78eb366 100644 --- a/net.cpp +++ b/net.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2009 Satoshi Nakamoto +// 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. @@ -522,7 +522,6 @@ void CNode::Cleanup() void ThreadSocketHandler(void* parg) { IMPLEMENT_RANDOMIZE_STACK(ThreadSocketHandler(parg)); - try { vnThreadsRunning[0]++; @@ -536,7 +535,6 @@ void ThreadSocketHandler(void* parg) vnThreadsRunning[0]--; throw; // support pthread_cancel() } - printf("ThreadSocketHandler exiting\n"); } @@ -816,7 +814,6 @@ void ThreadSocketHandler2(void* parg) void ThreadOpenConnections(void* parg) { IMPLEMENT_RANDOMIZE_STACK(ThreadOpenConnections(parg)); - try { vnThreadsRunning[1]++; @@ -830,7 +827,6 @@ void ThreadOpenConnections(void* parg) vnThreadsRunning[1]--; PrintException(NULL, "ThreadOpenConnections()"); } - printf("ThreadOpenConnections exiting\n"); } @@ -928,7 +924,7 @@ void ThreadOpenConnections2(void* parg) // 30 days 27 hours // 90 days 46 hours // 365 days 93 hours - int64 nDelay = (int64)(3600.0 * sqrt(fabs(nSinceLastSeen) / 3600.0) + nRandomizer); + int64 nDelay = (int64)(3600.0 * sqrt(fabs((double)nSinceLastSeen) / 3600.0) + nRandomizer); // Fast reconnect for one hour after last seen if (nSinceLastSeen < 60 * 60) @@ -1016,7 +1012,6 @@ bool OpenNetworkConnection(const CAddress& addrConnect) void ThreadMessageHandler(void* parg) { IMPLEMENT_RANDOMIZE_STACK(ThreadMessageHandler(parg)); - try { vnThreadsRunning[2]++; @@ -1030,7 +1025,6 @@ void ThreadMessageHandler(void* parg) vnThreadsRunning[2]--; PrintException(NULL, "ThreadMessageHandler()"); } - printf("ThreadMessageHandler exiting\n"); } @@ -1329,7 +1323,7 @@ bool StopNode() fShutdown = true; nTransactionsUpdated++; int64 nStart = GetTime(); - while (vnThreadsRunning[0] > 0 || vnThreadsRunning[2] > 0 || vnThreadsRunning[3] > 0) + while (vnThreadsRunning[0] > 0 || vnThreadsRunning[2] > 0 || vnThreadsRunning[3] > 0 || vnThreadsRunning[4] > 0) { if (GetTime() - nStart > 20) break; @@ -1339,7 +1333,8 @@ bool StopNode() if (vnThreadsRunning[1] > 0) printf("ThreadOpenConnections still running\n"); if (vnThreadsRunning[2] > 0) printf("ThreadMessageHandler still running\n"); if (vnThreadsRunning[3] > 0) printf("ThreadBitcoinMiner still running\n"); - while (vnThreadsRunning[2] > 0) + if (vnThreadsRunning[4] > 0) printf("ThreadRPCServer still running\n"); + while (vnThreadsRunning[2] > 0 || vnThreadsRunning[4] > 0) Sleep(20); Sleep(50); diff --git a/net.h b/net.h index ba4607a558..ce6f772f49 100644 --- a/net.h +++ b/net.h @@ -1,4 +1,4 @@ -// Copyright (c) 2009 Satoshi Nakamoto +// 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. @@ -518,6 +518,7 @@ public: vector vInventoryToSend; CCriticalSection cs_inventory; multimap mapAskFor; + int64 nLastSentTxInv; // publish and subscription vector vfSubscribe; diff --git a/rpc.cpp b/rpc.cpp new file mode 100644 index 0000000000..9f28e7ec74 --- /dev/null +++ b/rpc.cpp @@ -0,0 +1,641 @@ +// 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. + +#include "headers.h" +#undef printf +#include +#include "json/json_spirit_reader_template.h" +#include "json/json_spirit_writer_template.h" +#include "json/json_spirit_utils.h" +#define printf OutputDebugStringF +// MinGW 3.4.5 gets "fatal error: had to relocate PCH" if the json headers are +// precompiled in headers.h. The problem might be when the pch file goes over +// a certain size around 145MB. If we need access to json_spirit outside this +// file, we could use the compiled json_spirit option. + +using boost::asio::ip::tcp; +using namespace json_spirit; + +void ThreadRPCServer2(void* parg); + + + + + + + +/// +/// Note: I'm not finished designing this interface, it's still subject to change. +/// + + + +Value stop(const Array& params) +{ + if (params.size() != 0) + throw runtime_error( + "stop (no parameters)\n" + "Stop bitcoin server."); + + // Shutdown will take long enough that the response should get back + CreateThread(Shutdown, NULL); + return "bitcoin server stopping"; +} + + +Value getblockcount(const Array& params) +{ + if (params.size() != 0) + throw runtime_error( + "getblockcount (no parameters)\n" + "Returns the number of blocks in the longest block chain."); + + return nBestHeight + 1; +} + + +Value getblocknumber(const Array& params) +{ + if (params.size() != 0) + throw runtime_error( + "getblocknumber (no parameters)\n" + "Returns the block number of the latest block in the longest block chain."); + + return nBestHeight; +} + + +Value getdifficulty(const Array& params) +{ + if (params.size() != 0) + throw runtime_error( + "getdifficulty (no parameters)\n" + "Returns the proof-of-work difficulty as a multiple of the minimum difficulty."); + + if (pindexBest == NULL) + throw runtime_error("block chain not loaded"); + + // Floating point number that is a multiple of the minimum difficulty, + // minimum difficulty = 1.0. + int nShift = 256 - 32 - 31; // to fit in a uint + double dMinimum = (CBigNum().SetCompact(bnProofOfWorkLimit.GetCompact()) >> nShift).getuint(); + double dCurrently = (CBigNum().SetCompact(pindexBest->nBits) >> nShift).getuint(); + return dMinimum / dCurrently; +} + + +Value getnewaddress(const Array& params) +{ + if (params.size() > 1) + throw runtime_error( + "getnewaddress [label]\n" + "Returns a new bitcoin address for receiving payments. " + "If [label] is specified (recommended), it is added to the address book " + "so payments received with the address will be labeled."); + + // Parse the label first so we don't generate a key if there's an error + string strLabel; + if (params.size() > 0) + strLabel = params[0].get_str(); + + // Generate a new key that is added to wallet + string strAddress = PubKeyToAddress(GenerateNewKey()); + + if (params.size() > 0) + SetAddressBookName(strAddress, strLabel); + return strAddress; +} + + +Value sendtoaddress(const Array& params) +{ + if (params.size() < 2 || params.size() > 4) + throw runtime_error( + "sendtoaddress [comment] [comment-to]\n" + " is a real and is rounded to the nearest 0.01"); + + string strAddress = params[0].get_str(); + + // Amount + if (params[1].get_real() <= 0.0 || params[1].get_real() > 21000000.0) + throw runtime_error("Invalid amount"); + int64 nAmount = roundint64(params[1].get_real() * 100.00) * CENT; + + // Wallet comments + CWalletTx wtx; + if (params.size() > 2 && params[2].type() != null_type && !params[2].get_str().empty()) + wtx.mapValue["message"] = params[2].get_str(); + if (params.size() > 3 && params[3].type() != null_type && !params[3].get_str().empty()) + wtx.mapValue["to"] = params[3].get_str(); + + string strError = SendMoneyToBitcoinAddress(strAddress, nAmount, wtx); + if (strError != "") + throw runtime_error(strError); + return "sent"; +} + + +Value listtransactions(const Array& params) +{ + if (params.size() > 2) + throw runtime_error( + "listtransactions [count=10] [includegenerated=false]\n" + "Returns up to [count] most recent transactions."); + + int64 nCount = 10; + if (params.size() > 0) + nCount = params[0].get_int64(); + bool fGenerated = false; + if (params.size() > 1) + fGenerated = params[1].get_bool(); + + Array ret; + //// not finished + ret.push_back("not implemented yet"); + return ret; +} + + +Value getamountpaid(const Array& params) +{ + if (params.size() < 1 || params.size() > 2) + throw runtime_error( + "getamountpaid [minconf=1]\n" + "Returns the total amount paid to in transactions with at least [minconf] confirmations."); + + // Bitcoin address + string strAddress = params[0].get_str(); + CScript scriptPubKey; + if (!scriptPubKey.SetBitcoinAddress(strAddress)) + throw runtime_error("Invalid bitcoin address"); + + // Minimum confirmations + int nMinDepth = 1; + if (params.size() > 1) + nMinDepth = params[1].get_int(); + + // Tally + int64 nAmount = 0; + CRITICAL_BLOCK(cs_mapWallet) + { + for (map::iterator it = mapWallet.begin(); it != mapWallet.end(); ++it) + { + const CWalletTx& wtx = (*it).second; + if (wtx.IsCoinBase() || !wtx.IsFinal()) + continue; + + foreach(const CTxOut& txout, wtx.vout) + if (txout.scriptPubKey == scriptPubKey) + if (wtx.GetDepthInMainChain() >= nMinDepth) + nAmount += txout.nValue; + } + } + + return (double)nAmount / (double)COIN; +} + + +struct tallyitem +{ + int64 nAmount; + int nConf; + tallyitem() + { + nAmount = 0; + nConf = INT_MAX; + } +}; + +Value getallpayments(const Array& params) +{ + if (params.size() > 1) + throw runtime_error( + "getallpayments [minconf=1]\n" + "[minconf] is the minimum number of confirmations before payments are included.\n" + "Returns an array of objects containing:\n" + " \"address\" : bitcoin address\n" + " \"amount\" : total amount paid to the address\n" + " \"conf\" : number of confirmations\n" + " \"label\" : the label set for this address when it was created by getnewaddress"); + + // Minimum confirmations + int nMinDepth = 1; + if (params.size() > 0) + nMinDepth = params[0].get_int(); + + // Tally + map mapTally; + CRITICAL_BLOCK(cs_mapWallet) + { + for (map::iterator it = mapWallet.begin(); it != mapWallet.end(); ++it) + { + const CWalletTx& wtx = (*it).second; + if (wtx.IsCoinBase() || !wtx.IsFinal()) + continue; + + int nDepth = wtx.GetDepthInMainChain(); + if (nDepth >= nMinDepth) + { + foreach(const CTxOut& txout, wtx.vout) + { + uint160 hash160 = txout.scriptPubKey.GetBitcoinAddressHash160(); + if (hash160 == 0 || !mapPubKeys.count(hash160)) + continue; + + tallyitem& item = mapTally[hash160]; + item.nAmount += txout.nValue; + item.nConf = min(item.nConf, nDepth); + } + } + } + } + + // Reply + Array ret; + CRITICAL_BLOCK(cs_mapAddressBook) + { + for (map::iterator it = mapTally.begin(); it != mapTally.end(); ++it) + { + string strAddress = Hash160ToAddress((*it).first); + string strLabel; + map::iterator mi = mapAddressBook.find(strAddress); + if (mi != mapAddressBook.end()) + strLabel = (*mi).second; + + Object obj; + obj.push_back(Pair("address", strAddress)); + obj.push_back(Pair("amount", (double)(*it).second.nAmount / (double)COIN)); + obj.push_back(Pair("conf", (*it).second.nConf)); + obj.push_back(Pair("label", strLabel)); + ret.push_back(obj); + } + } + return ret; +} + + + + + + + +// +// Call Table +// + +typedef Value(*rpcfn_type)(const Array& params); +pair pCallTable[] = +{ + make_pair("stop", &stop), + make_pair("getblockcount", &getblockcount), + make_pair("getblocknumber", &getblocknumber), + make_pair("getdifficulty", &getdifficulty), + make_pair("getnewaddress", &getnewaddress), + make_pair("sendtoaddress", &sendtoaddress), + make_pair("listtransactions", &listtransactions), + make_pair("getamountpaid", &getamountpaid), + make_pair("getallpayments", &getallpayments), +}; +map mapCallTable(pCallTable, pCallTable + sizeof(pCallTable)/sizeof(pCallTable[0])); + + + + +// +// HTTP protocol +// +// This ain't Apache. We're just using HTTP header for the length field +// and to be compatible with other JSON-RPC implementations. +// + +string HTTPPost(const string& strMsg) +{ + return strprintf( + "POST / HTTP/1.1\r\n" + "User-Agent: json-rpc/1.0\r\n" + "Host: 127.0.0.1\r\n" + "Content-Type: application/json\r\n" + "Content-Length: %d\r\n" + "Accept: application/json\r\n" + "\r\n" + "%s", + strMsg.size(), + strMsg.c_str()); +} + +string HTTPReply(const string& strMsg, int nStatus=200) +{ + string strStatus; + if (nStatus == 200) strStatus = "OK"; + if (nStatus == 500) strStatus = "Internal Server Error"; + return strprintf( + "HTTP/1.1 %d %s\r\n" + "Connection: close\r\n" + "Content-Length: %d\r\n" + "Content-Type: application/json\r\n" + "Date: Sat, 08 Jul 2006 12:04:08 GMT\r\n" + "Server: json-rpc/1.0\r\n" + "\r\n" + "%s", + nStatus, + strStatus.c_str(), + strMsg.size(), + strMsg.c_str()); +} + +int ReadHTTPHeader(tcp::iostream& stream) +{ + int nLen = 0; + loop + { + string str; + std::getline(stream, str); + if (str.empty() || str == "\r") + break; + if (str.substr(0,15) == "Content-Length:") + nLen = atoi(str.substr(15)); + } + return nLen; +} + +inline string ReadHTTP(tcp::iostream& stream) +{ + // Read header + int nLen = ReadHTTPHeader(stream); + if (nLen <= 0) + return string(); + + // Read message + vector vch(nLen); + stream.read(&vch[0], nLen); + return string(vch.begin(), vch.end()); +} + + + +// +// JSON-RPC protocol +// +// http://json-rpc.org/wiki/specification +// http://www.codeproject.com/KB/recipes/JSON_Spirit.aspx +// + +string JSONRPCRequest(const string& strMethod, const Array& params, const Value& id) +{ + Object request; + request.push_back(Pair("method", strMethod)); + request.push_back(Pair("params", params)); + request.push_back(Pair("id", id)); + return write_string(Value(request), false) + "\n"; +} + +string JSONRPCReply(const Value& result, const Value& error, const Value& id) +{ + Object reply; + if (error.type() != null_type) + reply.push_back(Pair("result", Value::null)); + else + reply.push_back(Pair("result", result)); + reply.push_back(Pair("error", error)); + reply.push_back(Pair("id", id)); + return write_string(Value(reply), false) + "\n"; +} + + + + +void ThreadRPCServer(void* parg) +{ + IMPLEMENT_RANDOMIZE_STACK(ThreadRPCServer(parg)); + try + { + vnThreadsRunning[4]++; + ThreadRPCServer2(parg); + vnThreadsRunning[4]--; + } + catch (std::exception& e) { + vnThreadsRunning[4]--; + PrintException(&e, "ThreadRPCServer()"); + } catch (...) { + vnThreadsRunning[4]--; + PrintException(NULL, "ThreadRPCServer()"); + } + printf("ThreadRPCServer exiting\n"); +} + +void ThreadRPCServer2(void* parg) +{ + printf("ThreadRPCServer started\n"); + + // Bind to loopback 127.0.0.1 so the socket can only be accessed locally + boost::asio::io_service io_service; + tcp::endpoint endpoint(boost::asio::ip::address_v4::loopback(), 8332); + tcp::acceptor acceptor(io_service, endpoint); + + loop + { + // Accept connection + tcp::iostream stream; + tcp::endpoint peer; + vnThreadsRunning[4]--; + acceptor.accept(*stream.rdbuf(), peer); + vnThreadsRunning[4]++; + if (fShutdown) + return; + + // Shouldn't be possible for anyone else to connect, but just in case + if (peer.address().to_string() != "127.0.0.1") + continue; + + // Receive request + string strRequest = ReadHTTP(stream); + printf("ThreadRPCServer request=%s", strRequest.c_str()); + + // Handle multiple invocations per request + string::iterator begin = strRequest.begin(); + while (skipspaces(begin), begin != strRequest.end()) + { + string::iterator prev = begin; + Value id; + try + { + // Parse request + Value valRequest; + if (!read_range(begin, strRequest.end(), valRequest)) + throw runtime_error("Parse error."); + const Object& request = valRequest.get_obj(); + if (find_value(request, "method").type() != str_type || + find_value(request, "params").type() != array_type) + throw runtime_error("Invalid request."); + + string strMethod = find_value(request, "method").get_str(); + const Array& params = find_value(request, "params").get_array(); + id = find_value(request, "id"); + + // Execute + map::iterator mi = mapCallTable.find(strMethod); + if (mi == mapCallTable.end()) + throw runtime_error("Method not found."); + Value result = (*(*mi).second)(params); + + // Send reply + string strReply = JSONRPCReply(result, Value::null, id); + stream << HTTPReply(strReply, 200) << std::flush; + } + catch (std::exception& e) + { + // Send error reply + string strReply = JSONRPCReply(Value::null, e.what(), id); + stream << HTTPReply(strReply, 500) << std::flush; + } + if (begin == prev) + break; + } + } +} + + + + +Value CallRPC(const string& strMethod, const Array& params) +{ + // Connect to localhost + tcp::iostream stream("127.0.0.1", "8332"); + if (stream.fail()) + throw runtime_error("unable to connect to server"); + + // Send request + string strRequest = JSONRPCRequest(strMethod, params, 1); + stream << HTTPPost(strRequest) << std::flush; + + // Receive reply + string strReply = ReadHTTP(stream); + if (strReply.empty()) + throw runtime_error("no response from server"); + + // Parse reply + Value valReply; + if (!read_string(strReply, valReply)) + throw runtime_error("couldn't parse reply from server"); + const Object& reply = valReply.get_obj(); + if (reply.empty()) + throw runtime_error("expected reply to have result, error and id properties"); + + const Value& result = find_value(reply, "result"); + const Value& error = find_value(reply, "error"); + const Value& id = find_value(reply, "id"); + + if (error.type() == str_type) + throw runtime_error(error.get_str()); + else if (error.type() != null_type) + throw runtime_error(write_string(error, false)); + return result; +} + + + + +template +void ConvertTo(Value& value) +{ + if (value.type() == str_type) + { + // reinterpret string as unquoted json value + Value value2; + if (!read_string(value.get_str(), value2)) + throw runtime_error("type mismatch"); + value = value2.get_value(); + } + else + { + value = value.get_value(); + } +} + +int CommandLineRPC(int argc, char *argv[]) +{ + try + { + // Check that method exists + if (argc < 2) + throw runtime_error("too few parameters"); + string strMethod = argv[1]; + if (!mapCallTable.count(strMethod)) + throw runtime_error(strprintf("unknown command: %s", strMethod.c_str())); + + // Parameters default to strings + Array params; + for (int i = 2; i < argc; i++) + params.push_back(argv[i]); + + // Special case other types + int n = params.size(); + if (strMethod == "sendtoaddress" && n > 1) ConvertTo(params[1]); + if (strMethod == "listtransactions" && n > 0) ConvertTo(params[0]); + if (strMethod == "listtransactions" && n > 1) ConvertTo(params[1]); + if (strMethod == "getamountpaid" && n > 1) ConvertTo(params[1]); + if (strMethod == "getallpayments" && n > 0) ConvertTo(params[0]); + + // Execute + Value result = CallRPC(strMethod, params); + + // Print result + string strResult = (result.type() == str_type ? result.get_str() : write_string(result, true)); + if (result.type() != null_type) + { + if (fWindows) + // Windows GUI apps can't print to command line, + // so for now settle for a message box yuck + wxMessageBox(strResult.c_str(), "Bitcoin", wxOK); + else + fprintf(stdout, "%s\n", strResult.c_str()); + } + return 0; + } + catch (std::exception& e) { + if (fWindows) + wxMessageBox(strprintf("error: %s\n", e.what()).c_str(), "Bitcoin", wxOK); + else + fprintf(stderr, "error: %s\n", e.what()); + } catch (...) { + PrintException(NULL, "CommandLineRPC()"); + } + return 1; +} + + + + +#ifdef TEST +int main(int argc, char *argv[]) +{ +#ifdef _MSC_VER + // Turn off microsoft heap dump noise + _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE); + _CrtSetReportFile(_CRT_WARN, CreateFile("NUL", GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0)); +#endif + setbuf(stdin, NULL); + setbuf(stdout, NULL); + setbuf(stderr, NULL); + + try + { + if (argc >= 2 && string(argv[1]) == "-server") + { + printf("server ready\n"); + ThreadRPCServer(NULL); + } + else + { + return CommandLineRPC(argc, argv); + } + } + catch (std::exception& e) { + PrintException(&e, "main()"); + } catch (...) { + PrintException(NULL, "main()"); + } + return 0; +} +#endif diff --git a/rpc.h b/rpc.h new file mode 100644 index 0000000000..81ad840c4a --- /dev/null +++ b/rpc.h @@ -0,0 +1,6 @@ +// 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. + +void ThreadRPCServer(void* parg); +int CommandLineRPC(int argc, char *argv[]); diff --git a/script.cpp b/script.cpp index a41de2aa76..98f5afd5a7 100644 --- a/script.cpp +++ b/script.cpp @@ -660,7 +660,7 @@ bool EvalScript(const CScript& script, const CTransaction& txTo, unsigned int nI if (stack.size() < 1) return false; valtype& vch = stacktop(-1); - valtype vchHash(opcode == OP_RIPEMD160 || opcode == OP_SHA1 || opcode == OP_HASH160 ? 20 : 32); + valtype vchHash((opcode == OP_RIPEMD160 || opcode == OP_SHA1 || opcode == OP_HASH160) ? 20 : 32); if (opcode == OP_RIPEMD160) RIPEMD160(&vch[0], vch.size(), &vchHash[0]); else if (opcode == OP_SHA1) @@ -753,9 +753,9 @@ bool EvalScript(const CScript& script, const CTransaction& txTo, unsigned int nI CScript scriptCode(pbegincodehash, pend); // Drop the signatures, since there's no way for a signature to sign itself - for (int i = 0; i < nSigsCount; i++) + for (int k = 0; k < nSigsCount; k++) { - valtype& vchSig = stacktop(-isig-i); + valtype& vchSig = stacktop(-isig-k); scriptCode.FindAndDelete(CScript(vchSig)); } @@ -909,7 +909,6 @@ bool CheckSig(vector vchSig, vector vchPubKey, CSc - bool Solver(const CScript& scriptPubKey, vector >& vSolutionRet) { // Templates @@ -919,7 +918,7 @@ bool Solver(const CScript& scriptPubKey, vector >& vSo // Standard tx, sender provides pubkey, receiver adds signature vTemplates.push_back(CScript() << OP_PUBKEY << OP_CHECKSIG); - // Short account number tx, sender provides hash of pubkey, receiver provides signature and pubkey + // Bitcoin address tx, sender provides hash of pubkey, receiver provides signature and pubkey vTemplates.push_back(CScript() << OP_DUP << OP_HASH160 << OP_PUBKEYHASH << OP_EQUALVERIFY << OP_CHECKSIG); } diff --git a/script.h b/script.h index 0d977734b9..9e41889150 100644 --- a/script.h +++ b/script.h @@ -1,4 +1,4 @@ -// Copyright (c) 2009 Satoshi Nakamoto +// 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. @@ -472,7 +472,7 @@ public: bool GetOp(iterator& pc, opcodetype& opcodeRet, vector& vchRet) { - // This is why people hate C++ + // Wrapper so it can be called with either iterator or const_iterator const_iterator pc2 = pc; bool fRet = GetOp(pc2, opcodeRet, vchRet); pc = begin() + (pc2 - begin()); @@ -551,6 +551,46 @@ public: } + uint160 GetBitcoinAddressHash160() const + { + opcodetype opcode; + vector vch; + CScript::const_iterator pc = begin(); + if (!GetOp(pc, opcode, vch) || opcode != OP_DUP) return 0; + if (!GetOp(pc, opcode, vch) || opcode != OP_HASH160) return 0; + if (!GetOp(pc, opcode, vch) || vch.size() != sizeof(uint160)) return 0; + uint160 hash160 = uint160(vch); + 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; + } + + string GetBitcoinAddress() const + { + uint160 hash160 = GetBitcoinAddressHash160(); + if (hash160 == 0) + return ""; + return Hash160ToAddress(hash160); + } + + void SetBitcoinAddress(const uint160& hash160) + { + this->clear(); + *this << OP_DUP << OP_HASH160 << hash160 << OP_EQUALVERIFY << OP_CHECKSIG; + } + + bool SetBitcoinAddress(const string& strAddress) + { + this->clear(); + uint160 hash160; + if (!AddressToHash160(strAddress, hash160)) + return false; + SetBitcoinAddress(hash160); + return true; + } + + void PrintHex() const { printf("CScript(%s)\n", HexStr(begin(), end()).c_str()); diff --git a/serialize.h b/serialize.h index 439ef64125..eb090ae2e6 100644 --- a/serialize.h +++ b/serialize.h @@ -19,8 +19,8 @@ class CScript; class CDataStream; class CAutoFile; -static const int VERSION = 200; -static const char* pszSubVer = " test2"; +static const int VERSION = 201; +static const char* pszSubVer = ".0"; diff --git a/ui.cpp b/ui.cpp index 5d93ad227f..586200d6ef 100644 --- a/ui.cpp +++ b/ui.cpp @@ -21,7 +21,6 @@ DEFINE_EVENT_TYPE(wxEVT_REPLY3) CMainFrame* pframeMain = NULL; CMyTaskBarIcon* ptaskbaricon = NULL; -map mapAddressBook; bool fRandSendTest = false; void RandSend(); extern int g_isPainting; @@ -177,8 +176,11 @@ void CalledMessageBox(const string& message, const string& caption, int style, w int ThreadSafeMessageBox(const string& message, const string& caption, int style, wxWindow* parent, int x, int y) { - if (mapArgs.count("-noui")) + if (fDaemon) + { + printf("wxMessageBox %s: %s\n", caption.c_str(), message.c_str()); return wxOK; + } #ifdef __WXMSW__ return wxMessageBox(message, caption, style, parent, x, y); @@ -413,7 +415,7 @@ void Shutdown(void* parg) StopNode(); DBFlush(true); CreateThread(ExitTimeout, NULL); - Sleep(10); + Sleep(50); printf("Bitcoin exiting\n\n"); fExit = true; exit(0); @@ -697,19 +699,22 @@ bool CMainFrame::InsertTransaction(const CWalletTx& wtx, bool fNew, int nIndex) vector vchPubKey; if (ExtractPubKey(txout.scriptPubKey, true, vchPubKey)) { - string strAddress = PubKeyToAddress(vchPubKey); - if (mapAddressBook.count(strAddress)) + CRITICAL_BLOCK(cs_mapAddressBook) { - //strDescription += "Received payment to "; - //strDescription += "Received with address "; - strDescription += "From: unknown, To: "; - strDescription += strAddress; - /// The labeling feature is just too confusing, so I hid it - /// by putting it at the end where it runs off the screen. - /// It can still be seen by widening the column, or in the - /// details dialog. - if (!mapAddressBook[strAddress].empty()) - strDescription += " (" + mapAddressBook[strAddress] + ")"; + string strAddress = PubKeyToAddress(vchPubKey); + if (mapAddressBook.count(strAddress)) + { + //strDescription += "Received payment to "; + //strDescription += "Received with address "; + strDescription += "From: unknown, To: "; + strDescription += strAddress; + /// The labeling feature is just too confusing, so I hid it + /// by putting it at the end where it runs off the screen. + /// It can still be seen by widening the column, or in the + /// details dialog. + if (!mapAddressBook[strAddress].empty()) + strDescription += " (" + mapAddressBook[strAddress] + ")"; + } } } break; @@ -776,8 +781,9 @@ bool CMainFrame::InsertTransaction(const CWalletTx& wtx, bool fNew, int nIndex) } string strDescription = "To: "; - if (mapAddressBook.count(strAddress) && !mapAddressBook[strAddress].empty()) - strDescription += mapAddressBook[strAddress] + " "; + CRITICAL_BLOCK(cs_mapAddressBook) + if (mapAddressBook.count(strAddress) && !mapAddressBook[strAddress].empty()) + strDescription += mapAddressBook[strAddress] + " "; strDescription += strAddress; if (!mapValue["message"].empty()) { @@ -1273,238 +1279,241 @@ void CMainFrame::OnListItemActivatedOrdersReceived(wxListEvent& event) CTxDetailsDialog::CTxDetailsDialog(wxWindow* parent, CWalletTx wtx) : CTxDetailsDialogBase(parent) { - string strHTML; - strHTML.reserve(4000); - strHTML += ""; + CRITICAL_BLOCK(cs_mapAddressBook) + { + string strHTML; + strHTML.reserve(4000); + strHTML += ""; - int64 nTime = wtx.GetTxTime(); - int64 nCredit = wtx.GetCredit(); - int64 nDebit = wtx.GetDebit(); - int64 nNet = nCredit - nDebit; + int64 nTime = wtx.GetTxTime(); + int64 nCredit = wtx.GetCredit(); + int64 nDebit = wtx.GetDebit(); + int64 nNet = nCredit - nDebit; - strHTML += "Status: " + 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 += "
"; + strHTML += "Status: " + 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 += "
"; - strHTML += "Date: " + (nTime ? DateTimeStr(nTime) : "") + "
"; + strHTML += "Date: " + (nTime ? DateTimeStr(nTime) : "") + "
"; - // - // From - // - if (wtx.IsCoinBase()) - { - strHTML += "Source: Generated
"; - } - else if (!wtx.mapValue["from"].empty()) - { - // Online transaction - if (!wtx.mapValue["from"].empty()) - strHTML += "From: " + HtmlEscape(wtx.mapValue["from"]) + "
"; - } - else - { - // Offline transaction - if (nNet > 0) + // + // From + // + if (wtx.IsCoinBase()) { - // Credit - foreach(const CTxOut& txout, wtx.vout) + strHTML += "Source: Generated
"; + } + else if (!wtx.mapValue["from"].empty()) + { + // Online transaction + if (!wtx.mapValue["from"].empty()) + strHTML += "From: " + HtmlEscape(wtx.mapValue["from"]) + "
"; + } + else + { + // Offline transaction + if (nNet > 0) { - if (txout.IsMine()) + // Credit + foreach(const CTxOut& txout, wtx.vout) { - vector vchPubKey; - if (ExtractPubKey(txout.scriptPubKey, true, vchPubKey)) + if (txout.IsMine()) { - string strAddress = PubKeyToAddress(vchPubKey); - if (mapAddressBook.count(strAddress)) + vector vchPubKey; + if (ExtractPubKey(txout.scriptPubKey, true, vchPubKey)) { - strHTML += "From: unknown
"; - strHTML += "To: "; - strHTML += HtmlEscape(strAddress); - if (!mapAddressBook[strAddress].empty()) - strHTML += " (yours, label: " + mapAddressBook[strAddress] + ")"; - else - strHTML += " (yours)"; - strHTML += "
"; + string strAddress = PubKeyToAddress(vchPubKey); + if (mapAddressBook.count(strAddress)) + { + strHTML += "From: unknown
"; + strHTML += "To: "; + strHTML += HtmlEscape(strAddress); + if (!mapAddressBook[strAddress].empty()) + strHTML += " (yours, label: " + mapAddressBook[strAddress] + ")"; + else + strHTML += " (yours)"; + strHTML += "
"; + } } + break; } - break; } } } - } - // - // To - // - string strAddress; - if (!wtx.mapValue["to"].empty()) - { - // Online transaction - strAddress = wtx.mapValue["to"]; - strHTML += "To: "; - if (mapAddressBook.count(strAddress) && !mapAddressBook[strAddress].empty()) - strHTML += mapAddressBook[strAddress] + " "; - strHTML += HtmlEscape(strAddress) + "
"; - } - - - // - // Amount - // - if (wtx.IsCoinBase() && nCredit == 0) - { - // - // Coinbase - // - int64 nUnmatured = 0; - foreach(const CTxOut& txout, wtx.vout) - nUnmatured += txout.GetCredit(); - if (wtx.IsInMainChain()) - strHTML += strprintf("Credit: (%s matures in %d more blocks)
", FormatMoney(nUnmatured).c_str(), wtx.GetBlocksToMaturity()); - else - strHTML += "Credit: (not accepted)
"; - } - else if (nNet > 0) - { // - // Credit + // To // - strHTML += "Credit: " + FormatMoney(nNet) + "
"; - } - else - { - bool fAllFromMe = true; - foreach(const CTxIn& txin, wtx.vin) - fAllFromMe = fAllFromMe && txin.IsMine(); + string strAddress; + if (!wtx.mapValue["to"].empty()) + { + // Online transaction + strAddress = wtx.mapValue["to"]; + strHTML += "To: "; + if (mapAddressBook.count(strAddress) && !mapAddressBook[strAddress].empty()) + strHTML += mapAddressBook[strAddress] + " "; + strHTML += HtmlEscape(strAddress) + "
"; + } - bool fAllToMe = true; - foreach(const CTxOut& txout, wtx.vout) - fAllToMe = fAllToMe && txout.IsMine(); - if (fAllFromMe) + // + // Amount + // + if (wtx.IsCoinBase() && nCredit == 0) { // - // Debit + // Coinbase // + int64 nUnmatured = 0; foreach(const CTxOut& txout, wtx.vout) - { - if (txout.IsMine()) - continue; + nUnmatured += txout.GetCredit(); + if (wtx.IsInMainChain()) + strHTML += strprintf("Credit: (%s matures in %d more blocks)
", FormatMoney(nUnmatured).c_str(), wtx.GetBlocksToMaturity()); + else + strHTML += "Credit: (not accepted)
"; + } + else if (nNet > 0) + { + // + // Credit + // + strHTML += "Credit: " + FormatMoney(nNet) + "
"; + } + else + { + bool fAllFromMe = true; + foreach(const CTxIn& txin, wtx.vin) + fAllFromMe = fAllFromMe && txin.IsMine(); + + bool fAllToMe = true; + foreach(const CTxOut& txout, wtx.vout) + fAllToMe = fAllToMe && txout.IsMine(); - if (wtx.mapValue["to"].empty()) + if (fAllFromMe) + { + // + // Debit + // + foreach(const CTxOut& txout, wtx.vout) { - // Offline transaction - uint160 hash160; - if (ExtractHash160(txout.scriptPubKey, hash160)) + if (txout.IsMine()) + continue; + + if (wtx.mapValue["to"].empty()) { - string strAddress = Hash160ToAddress(hash160); - strHTML += "To: "; - if (mapAddressBook.count(strAddress) && !mapAddressBook[strAddress].empty()) - strHTML += mapAddressBook[strAddress] + " "; - strHTML += strAddress; - strHTML += "
"; + // Offline transaction + uint160 hash160; + if (ExtractHash160(txout.scriptPubKey, hash160)) + { + string strAddress = Hash160ToAddress(hash160); + strHTML += "To: "; + if (mapAddressBook.count(strAddress) && !mapAddressBook[strAddress].empty()) + strHTML += mapAddressBook[strAddress] + " "; + strHTML += strAddress; + strHTML += "
"; + } } + + strHTML += "Debit: " + FormatMoney(-txout.nValue) + "
"; } - strHTML += "Debit: " + FormatMoney(-txout.nValue) + "
"; - } + if (fAllToMe) + { + // Payment to self + /// issue: can't tell which is the payment and which is the change anymore + //int64 nValue = wtx.vout[0].nValue; + //strHTML += "Debit: " + FormatMoney(-nValue) + "
"; + //strHTML += "Credit: " + FormatMoney(nValue) + "
"; + } - if (fAllToMe) + int64 nTxFee = nDebit - wtx.GetValueOut(); + if (nTxFee > 0) + strHTML += "Transaction fee: " + FormatMoney(-nTxFee) + "
"; + } + else { - // Payment to self - /// issue: can't tell which is the payment and which is the change anymore - //int64 nValue = wtx.vout[0].nValue; - //strHTML += "Debit: " + FormatMoney(-nValue) + "
"; - //strHTML += "Credit: " + FormatMoney(nValue) + "
"; + // + // Mixed debit transaction + // + foreach(const CTxIn& txin, wtx.vin) + if (txin.IsMine()) + strHTML += "Debit: " + FormatMoney(-txin.GetDebit()) + "
"; + foreach(const CTxOut& txout, wtx.vout) + if (txout.IsMine()) + strHTML += "Credit: " + FormatMoney(txout.GetCredit()) + "
"; } - - int64 nTxFee = nDebit - wtx.GetValueOut(); - if (nTxFee > 0) - strHTML += "Transaction fee: " + FormatMoney(-nTxFee) + "
"; } - else - { - // - // Mixed debit transaction - // - foreach(const CTxIn& txin, wtx.vin) - if (txin.IsMine()) - strHTML += "Debit: " + FormatMoney(-txin.GetDebit()) + "
"; - foreach(const CTxOut& txout, wtx.vout) - if (txout.IsMine()) - strHTML += "Credit: " + FormatMoney(txout.GetCredit()) + "
"; - } - } - strHTML += "Net amount: " + FormatMoney(nNet, true) + "
"; + strHTML += "Net amount: " + FormatMoney(nNet, true) + "
"; - // - // Message - // - if (!wtx.mapValue["message"].empty()) - strHTML += "
Message:
" + HtmlEscape(wtx.mapValue["message"], true) + "
"; - - if (wtx.IsCoinBase()) - strHTML += "
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.
"; + // + // Message + // + if (!wtx.mapValue["message"].empty()) + strHTML += "
Message:
" + HtmlEscape(wtx.mapValue["message"], true) + "
"; + if (wtx.IsCoinBase()) + strHTML += "
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.
"; - // - // Debug view - // - if (fDebug) - { - strHTML += "

debug print

"; - foreach(const CTxIn& txin, wtx.vin) - if (txin.IsMine()) - strHTML += "Debit: " + FormatMoney(-txin.GetDebit()) + "
"; - foreach(const CTxOut& txout, wtx.vout) - if (txout.IsMine()) - strHTML += "Credit: " + FormatMoney(txout.GetCredit()) + "
"; - strHTML += "Inputs:
"; - CRITICAL_BLOCK(cs_mapWallet) + // + // Debug view + // + if (fDebug) { + strHTML += "

debug print

"; foreach(const CTxIn& txin, wtx.vin) + if (txin.IsMine()) + strHTML += "Debit: " + FormatMoney(-txin.GetDebit()) + "
"; + foreach(const CTxOut& txout, wtx.vout) + if (txout.IsMine()) + strHTML += "Credit: " + FormatMoney(txout.GetCredit()) + "
"; + + strHTML += "Inputs:
"; + CRITICAL_BLOCK(cs_mapWallet) { - COutPoint prevout = txin.prevout; - map::iterator mi = mapWallet.find(prevout.hash); - if (mi != mapWallet.end()) + foreach(const CTxIn& txin, wtx.vin) { - const CWalletTx& prev = (*mi).second; - if (prevout.n < prev.vout.size()) + COutPoint prevout = txin.prevout; + map::iterator mi = mapWallet.find(prevout.hash); + if (mi != mapWallet.end()) { - strHTML += HtmlEscape(prev.ToString(), true); - strHTML += "    " + FormatTxStatus(prev) + ", "; - strHTML = strHTML + "IsMine=" + (prev.vout[prevout.n].IsMine() ? "true" : "false") + "
"; + const CWalletTx& prev = (*mi).second; + if (prevout.n < prev.vout.size()) + { + strHTML += HtmlEscape(prev.ToString(), true); + strHTML += "    " + FormatTxStatus(prev) + ", "; + strHTML = strHTML + "IsMine=" + (prev.vout[prevout.n].IsMine() ? "true" : "false") + "
"; + } } } } - } - strHTML += "


Transaction:
"; - strHTML += HtmlEscape(wtx.ToString(), true); - } + strHTML += "


Transaction:
"; + strHTML += HtmlEscape(wtx.ToString(), true); + } - strHTML += "
"; - string(strHTML.begin(), strHTML.end()).swap(strHTML); - m_htmlWin->SetPage(strHTML); - m_buttonOK->SetFocus(); + strHTML += "
"; + string(strHTML.begin(), strHTML.end()).swap(strHTML); + m_htmlWin->SetPage(strHTML); + m_buttonOK->SetFocus(); + } } void CTxDetailsDialog::OnButtonOK(wxCommandEvent& event) @@ -1686,9 +1695,10 @@ CAboutDialog::CAboutDialog(wxWindow* parent) : CAboutDialogBase(parent) #if !wxUSE_UNICODE // Workaround until upgrade to wxWidgets supporting UTF-8 + // Hack to change the (c) character from UTF-8 back to ANSI wxString str = m_staticTextMain->GetLabel(); - if (str.Find('Â') != wxNOT_FOUND) - str.Remove(str.Find('Â'), 1); + if (str.Find('\xC2') != wxNOT_FOUND) + str.Remove(str.Find('\xC2'), 1); m_staticTextMain->SetLabel(str); #endif #ifndef __WXMSW__ @@ -1843,10 +1853,11 @@ void CSendDialog::OnButtonSend(wxCommandEvent& event) CScript scriptPubKey; scriptPubKey << OP_DUP << OP_HASH160 << hash160 << OP_EQUALVERIFY << OP_CHECKSIG; - if (!SendMoney(scriptPubKey, nValue, wtx)) - return; - - wxMessageBox("Payment sent ", "Sending..."); + string strError = SendMoney(scriptPubKey, nValue, wtx); + if (strError != "") + wxMessageBox(strError + " ", "Sending..."); + else + wxMessageBox("Payment sent ", "Sending..."); } else { @@ -1869,8 +1880,9 @@ void CSendDialog::OnButtonSend(wxCommandEvent& event) return; } - if (!mapAddressBook.count(strAddress)) - SetAddressBookName(strAddress, ""); + CRITICAL_BLOCK(cs_mapAddressBook) + if (!mapAddressBook.count(strAddress)) + SetAddressBookName(strAddress, ""); EndModal(true); } @@ -2227,6 +2239,7 @@ CYourAddressDialog::CYourAddressDialog(wxWindow* parent, const string& strInitSe // Fill listctrl with address book data CRITICAL_BLOCK(cs_mapKeys) + CRITICAL_BLOCK(cs_mapAddressBook) { foreach(const PAIRTYPE(string, string)& item, mapAddressBook) { @@ -2366,6 +2379,7 @@ CAddressBookDialog::CAddressBookDialog(wxWindow* parent, const wxString& strInit // Fill listctrl with address book data CRITICAL_BLOCK(cs_mapKeys) + CRITICAL_BLOCK(cs_mapAddressBook) { foreach(const PAIRTYPE(string, string)& item, mapAddressBook) { @@ -3515,6 +3529,12 @@ bool CMyApp::OnInit2() // // Parameters // + if (argc > 1 && argv[1][0] != '-' && argv[1][0] != '/') + { + int ret = CommandLineRPC(argc, argv); + exit(ret); + } + ParseParameters(argc, argv); if (mapArgs.count("-?") || mapArgs.count("--help")) { @@ -3557,6 +3577,13 @@ bool CMyApp::OnInit2() if (mapArgs.count("-printtodebugger")) fPrintToDebugger = true; + if (mapArgs.count("-daemon") || mapArgs.count("-d")) + { + fDaemon = true; + /// todo: need to fork + /// should it fork after the bind/single instance stuff? + } + if (!fDebug && !pszSetDataDir[0]) ShrinkDebugFile(); printf("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"); @@ -3730,7 +3757,7 @@ bool CMyApp::OnInit2() // // Create the main frame window // - if (!mapArgs.count("-noui")) + if (!fDaemon) { pframeMain = new CMainFrame(NULL); if (mapArgs.count("-min")) @@ -3752,6 +3779,9 @@ bool CMyApp::OnInit2() if (!CreateThread(StartNode, NULL)) wxMessageBox("Error: CreateThread(StartNode) failed", "Bitcoin"); + if (mapArgs.count("-server") || fDaemon) + CreateThread(ThreadRPCServer, NULL); + if (fFirstRun) SetStartOnSystemStartup(true); diff --git a/util.cpp b/util.cpp index 4292246762..2f5be2227f 100644 --- a/util.cpp +++ b/util.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2009 Satoshi Nakamoto +// 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. @@ -12,6 +12,7 @@ bool fPrintToConsole = false; bool fPrintToDebugger = false; char pszSetDataDir[MAX_PATH] = ""; bool fShutdown = false; +bool fDaemon = false; diff --git a/util.h b/util.h index d20648bcd3..6a7fabc5e9 100644 --- a/util.h +++ b/util.h @@ -1,4 +1,4 @@ -// Copyright (c) 2009 Satoshi Nakamoto +// 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. @@ -55,6 +55,7 @@ inline T& REF(const T& val) } #ifdef __WXMSW__ +static const bool fWindows = true; #define MSG_NOSIGNAL 0 #define MSG_DONTWAIT 0 #ifndef UINT64_MAX @@ -66,7 +67,9 @@ inline T& REF(const T& val) #define S_IRUSR 0400 #define S_IWUSR 0200 #endif +#define unlink _unlink #else +static const bool fWindows = false; #define WSAGetLastError() errno #define WSAEWOULDBLOCK EWOULDBLOCK #define WSAEMSGSIZE EMSGSIZE @@ -116,6 +119,7 @@ extern bool fPrintToConsole; extern bool fPrintToDebugger; extern char pszSetDataDir[MAX_PATH]; extern bool fShutdown; +extern bool fDaemon; void RandAddSeed(); void RandAddSeedPerfmon(); @@ -258,6 +262,11 @@ inline int roundint(double d) return (int)(d > 0 ? d + 0.5 : d - 0.5); } +inline int64 roundint64(double d) +{ + return (int64)(d > 0 ? d + 0.5 : d - 0.5); +} + template string HexStr(const T itbegin, const T itend, bool fSpaces=true) { @@ -323,7 +332,12 @@ inline string DateTimeStrFormat(const char* pszFormat, int64 nTime) return pszTime; } - +template +void skipspaces(T& it) +{ + while (isspace(*it)) + ++it; +} -- cgit v1.2.3 From 19765903dc39a641af614443f5876190fe56931d Mon Sep 17 00:00:00 2001 From: s_nakamoto Date: Sat, 13 Feb 2010 02:09:07 +0000 Subject: updated build-unix.txt --- build-unix.txt | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/build-unix.txt b/build-unix.txt index 5467bbea17..f1a72eaacc 100644 --- a/build-unix.txt +++ b/build-unix.txt @@ -20,11 +20,15 @@ sudo apt-get install libdb4.7-dev sudo apt-get install libdb4.7++-dev sudo apt-get install libboost-dev +The release was built with wxWidgets 2.8.9 ansi on 32-bit. The current +sourcecode can be built on 64-bit with wxWidgets 2.9.0. + There is currently no libwxgtk2.8-ansi-dev debian package for Karmic. libwxgtk2.8-dev is the "unicode" build, but for wxWidgets 2.8 "unicode" means wchar, not UTF-8. wchar wxString doesn't convert to std::string. +We haven't been able to compile the 2.8 versions on 64-bit. -In wxWidgets 2.9, unicode is UTF-8 and that's the only version. +wxWidgets 2.9 is UTF-8 and compiles on 64-bit. You need to download wxWidgets from http://www.wxwidgets.org/downloads/ and build it yourself. See the build instructions and configure parameters @@ -60,7 +64,7 @@ mkdir buildgtk cd buildgtk ../configure --with-gtk --enable-debug --disable-shared --enable-monolithic make -su +sudo su make install ldconfig -- cgit v1.2.3 From c85dfb148a1e3d75773bc5f6b7cad14363fd666b Mon Sep 17 00:00:00 2001 From: s_nakamoto Date: Sat, 13 Feb 2010 02:09:07 +0000 Subject: updated build-unix.txt git-svn-id: https://bitcoin.svn.sourceforge.net/svnroot/bitcoin/trunk@61 1a98c847-1fd6-4fd8-948a-caf3550aa51b --- build-unix.txt | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/build-unix.txt b/build-unix.txt index 5467bbea17..f1a72eaacc 100644 --- a/build-unix.txt +++ b/build-unix.txt @@ -20,11 +20,15 @@ sudo apt-get install libdb4.7-dev sudo apt-get install libdb4.7++-dev sudo apt-get install libboost-dev +The release was built with wxWidgets 2.8.9 ansi on 32-bit. The current +sourcecode can be built on 64-bit with wxWidgets 2.9.0. + There is currently no libwxgtk2.8-ansi-dev debian package for Karmic. libwxgtk2.8-dev is the "unicode" build, but for wxWidgets 2.8 "unicode" means wchar, not UTF-8. wchar wxString doesn't convert to std::string. +We haven't been able to compile the 2.8 versions on 64-bit. -In wxWidgets 2.9, unicode is UTF-8 and that's the only version. +wxWidgets 2.9 is UTF-8 and compiles on 64-bit. You need to download wxWidgets from http://www.wxwidgets.org/downloads/ and build it yourself. See the build instructions and configure parameters @@ -60,7 +64,7 @@ mkdir buildgtk cd buildgtk ../configure --with-gtk --enable-debug --disable-shared --enable-monolithic make -su +sudo su make install ldconfig -- cgit v1.2.3 From 7271c7ff35b74b7fa0bb9dd2db95b99fb9f9db01 Mon Sep 17 00:00:00 2001 From: s_nakamoto Date: Sun, 14 Feb 2010 00:08:27 +0000 Subject: Workaround for bug on wxWidgets 2.9.0 Ubuntu 9.10 64-bit where first character of the hidden columns were displayed so status column had three numbers overprinted. Fixed by adding a leading space to the hidden columns. 64-bit compile with wxWidgets 2.9.0 seems to be fully working normally now. --- bignum.h | 8 ++------ main.cpp | 11 +++++------ net.cpp | 2 +- rpc.cpp | 2 +- ui.cpp | 40 ++++++++++++---------------------------- uint256.h | 14 +++++++++----- 6 files changed, 30 insertions(+), 47 deletions(-) diff --git a/bignum.h b/bignum.h index e1ab165b2c..61ba3fa03b 100644 --- a/bignum.h +++ b/bignum.h @@ -64,12 +64,6 @@ public: } } - explicit CBigNum(const std::string& str) - { - BN_init(this); - SetHex(str); - } - CBigNum& operator=(const CBigNum& b) { if (!BN_copy(this, &b)) @@ -407,6 +401,7 @@ public: CBigNum& operator>>=(unsigned int shift) { + // Note: BN_rshift segfaults on 64-bit ubuntu 9.10 if 2^shift is greater than the number if (!BN_rshift(this, this, shift)) throw bignum_error("CBigNum:operator>>= : BN_rshift failed"); return *this; @@ -516,6 +511,7 @@ inline const CBigNum operator<<(const CBigNum& a, unsigned int shift) inline const CBigNum operator>>(const CBigNum& a, unsigned int shift) { CBigNum r; + // Note: BN_rshift segfaults on 64-bit ubuntu 9.10 if 2^shift is greater than the number if (!BN_rshift(&r, &a, shift)) throw bignum_error("CBigNum:operator>> : BN_rshift failed"); return r; diff --git a/main.cpp b/main.cpp index 90d239fa0f..0c7aff842b 100644 --- a/main.cpp +++ b/main.cpp @@ -1570,7 +1570,9 @@ bool LoadBlockIndex(bool fAllowNew) txNew.vout.resize(1); txNew.vin[0].scriptSig = CScript() << 486604799 << CBigNum(4) << vector((const unsigned char*)pszTimestamp, (const unsigned char*)pszTimestamp + strlen(pszTimestamp)); txNew.vout[0].nValue = 50 * COIN; - txNew.vout[0].scriptPubKey = CScript() << CBigNum("0x5F1DF16B2B704C8A578D0BBAF74D385CDE12C11EE50455F3C438EF4C3FBCF649B6DE611FEAE06279A60939E028A8D65C10B73071A6F16719274855FEB0FD8A6704") << OP_CHECKSIG; + CBigNum bnPubKey; + bnPubKey.SetHex("0x5F1DF16B2B704C8A578D0BBAF74D385CDE12C11EE50455F3C438EF4C3FBCF649B6DE611FEAE06279A60939E028A8D65C10B73071A6F16719274855FEB0FD8A6704"); + txNew.vout[0].scriptPubKey = CScript() << bnPubKey << OP_CHECKSIG; CBlock block; block.vtx.push_back(txNew); block.hashPrevBlock = 0; @@ -3022,12 +3024,9 @@ string SendMoneyToBitcoinAddress(string strAddress, int64 nValue, CWalletTx& wtx return "You don't have enough money"; // Parse bitcoin address - uint160 hash160; - if (!AddressToHash160(strAddress, hash160)) + CScript scriptPubKey; + if (!scriptPubKey.SetBitcoinAddress(strAddress)) return "Invalid bitcoin address"; - // Send to bitcoin address - CScript scriptPubKey; - scriptPubKey.SetBitcoinAddress(hash160); return SendMoney(scriptPubKey, nValue, wtxNew); } diff --git a/net.cpp b/net.cpp index ada78eb366..d669b8c5e5 100644 --- a/net.cpp +++ b/net.cpp @@ -1032,7 +1032,7 @@ void ThreadMessageHandler2(void* parg) { printf("ThreadMessageHandler started\n"); SetThreadPriority(THREAD_PRIORITY_BELOW_NORMAL); - loop + while (!fShutdown) { // Poll the connected nodes for messages vector vNodesCopy; diff --git a/rpc.cpp b/rpc.cpp index 9f28e7ec74..b176b1580c 100644 --- a/rpc.cpp +++ b/rpc.cpp @@ -503,7 +503,7 @@ Value CallRPC(const string& strMethod, const Array& params) // Connect to localhost tcp::iostream stream("127.0.0.1", "8332"); if (stream.fail()) - throw runtime_error("unable to connect to server"); + throw runtime_error("couldn't connect to server"); // Send request string strRequest = JSONRPCRequest(strMethod, params, 1); diff --git a/ui.cpp b/ui.cpp index 586200d6ef..aad599c77c 100644 --- a/ui.cpp +++ b/ui.cpp @@ -328,7 +328,7 @@ CMainFrame::CMainFrame(wxWindow* parent) : CMainFrameBase(parent) m_toolBar->Realize(); // resize to fit ubuntu's huge default font dResize = 1.20; - SetSize(dResize * GetSize().GetWidth(), 1.1 * GetSize().GetHeight()); + SetSize((dResize + 0.02) * GetSize().GetWidth(), 1.09 * GetSize().GetHeight()); #endif m_staticTextBalance->SetLabel(FormatMoney(GetBalance()) + " "); m_listCtrl->SetFocus(); @@ -346,24 +346,6 @@ CMainFrame::CMainFrame(wxWindow* parent) : CMainFrameBase(parent) m_listCtrl->InsertColumn(5, "Debit", wxLIST_FORMAT_RIGHT, dResize * 79); m_listCtrl->InsertColumn(6, "Credit", wxLIST_FORMAT_RIGHT, dResize * 79); - //m_listCtrlProductsSent->InsertColumn(0, "Category", wxLIST_FORMAT_LEFT, 100); - //m_listCtrlProductsSent->InsertColumn(1, "Title", wxLIST_FORMAT_LEFT, 100); - //m_listCtrlProductsSent->InsertColumn(2, "Description", wxLIST_FORMAT_LEFT, 100); - //m_listCtrlProductsSent->InsertColumn(3, "Price", wxLIST_FORMAT_LEFT, 100); - //m_listCtrlProductsSent->InsertColumn(4, "", wxLIST_FORMAT_LEFT, 100); - - //m_listCtrlOrdersSent->InsertColumn(0, "Time", wxLIST_FORMAT_LEFT, 100); - //m_listCtrlOrdersSent->InsertColumn(1, "Price", wxLIST_FORMAT_LEFT, 100); - //m_listCtrlOrdersSent->InsertColumn(2, "", wxLIST_FORMAT_LEFT, 100); - //m_listCtrlOrdersSent->InsertColumn(3, "", wxLIST_FORMAT_LEFT, 100); - //m_listCtrlOrdersSent->InsertColumn(4, "", wxLIST_FORMAT_LEFT, 100); - - //m_listCtrlOrdersReceived->InsertColumn(0, "Time", wxLIST_FORMAT_LEFT, 100); - //m_listCtrlOrdersReceived->InsertColumn(1, "Price", wxLIST_FORMAT_LEFT, 100); - //m_listCtrlOrdersReceived->InsertColumn(2, "Payment Status", wxLIST_FORMAT_LEFT, 100); - //m_listCtrlOrdersReceived->InsertColumn(3, "", wxLIST_FORMAT_LEFT, 100); - //m_listCtrlOrdersReceived->InsertColumn(4, "", wxLIST_FORMAT_LEFT, 100); - // Init status bar int pnWidths[3] = { -100, 88, 290 }; #ifndef __WXMSW__ @@ -503,33 +485,34 @@ int CMainFrame::GetSortIndex(const string& strSort) void CMainFrame::InsertLine(bool fNew, int nIndex, uint256 hashKey, string strSort, const wxString& str2, const wxString& str3, const wxString& str4, const wxString& str5, const wxString& str6) { - string str0 = strSort; - long nData = *(long*)&hashKey; + 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) == hashKey.ToString()) + 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), str0); + 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) != str0) + if (GetItemText(m_listCtrl, nIndex, 0) != strSort) { m_listCtrl->DeleteItem(nIndex); - nIndex = m_listCtrl->InsertItem(GetSortIndex(strSort), str0); + nIndex = m_listCtrl->InsertItem(GetSortIndex(strSort), strSort); } } - m_listCtrl->SetItem(nIndex, 1, hashKey.ToString()); + 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); @@ -544,8 +527,9 @@ bool CMainFrame::DeleteLine(uint256 hashKey) // Find item int nIndex = -1; + string strHash = " " + hashKey.ToString(); while ((nIndex = m_listCtrl->FindItem(nIndex, nData)) != -1) - if (GetItemText(m_listCtrl, nIndex, 1) == hashKey.ToString()) + if (GetItemText(m_listCtrl, nIndex, 1) == strHash) break; if (nIndex != -1) @@ -1916,7 +1900,7 @@ CSendingDialog::CSendingDialog(wxWindow* parent, const CAddress& addrIn, int64 n fUIDone = false; fWorkDone = false; #ifndef __WXMSW__ - SetSize(1.2 * GetSize().GetWidth(), 1.05 * GetSize().GetHeight()); + SetSize(1.2 * GetSize().GetWidth(), 1.08 * GetSize().GetHeight()); #endif SetTitle(strprintf("Sending %s to %s", FormatMoney(nPrice).c_str(), wtx.mapValue["to"].c_str())); diff --git a/uint256.h b/uint256.h index 9a0c770497..6976d9dc00 100644 --- a/uint256.h +++ b/uint256.h @@ -299,19 +299,18 @@ public: return string(psz, psz + sizeof(pn)*2); } - void SetHex(const std::string& str) + void SetHex(const char* psz) { for (int i = 0; i < WIDTH; i++) pn[i] = 0; - // skip 0x - const char* psz = str.c_str(); + // skip leading spaces while (isspace(*psz)) psz++; + + // skip 0x if (psz[0] == '0' && tolower(psz[1]) == 'x') psz += 2; - while (isspace(*psz)) - psz++; // hex string to uint static char phexdigit[256] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,1,2,3,4,5,6,7,8,9,0,0,0,0,0,0, 0,0xa,0xb,0xc,0xd,0xe,0xf,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0xa,0xb,0xc,0xd,0xe,0xf,0,0,0,0,0,0,0,0,0 }; @@ -332,6 +331,11 @@ public: } } + void SetHex(const std::string& str) + { + SetHex(str.c_str()); + } + std::string ToString() const { return (GetHex()); -- cgit v1.2.3 From c4319e678f693d5fbc49bd357ded1c8f951476e9 Mon Sep 17 00:00:00 2001 From: s_nakamoto Date: Sun, 14 Feb 2010 00:08:27 +0000 Subject: Workaround for bug on wxWidgets 2.9.0 Ubuntu 9.10 64-bit where first character of the hidden columns were displayed so status column had three numbers overprinted. Fixed by adding a leading space to the hidden columns. 64-bit compile with wxWidgets 2.9.0 seems to be fully working normally now. git-svn-id: https://bitcoin.svn.sourceforge.net/svnroot/bitcoin/trunk@62 1a98c847-1fd6-4fd8-948a-caf3550aa51b --- bignum.h | 8 ++------ main.cpp | 11 +++++------ net.cpp | 2 +- rpc.cpp | 2 +- ui.cpp | 40 ++++++++++++---------------------------- uint256.h | 14 +++++++++----- 6 files changed, 30 insertions(+), 47 deletions(-) diff --git a/bignum.h b/bignum.h index e1ab165b2c..61ba3fa03b 100644 --- a/bignum.h +++ b/bignum.h @@ -64,12 +64,6 @@ public: } } - explicit CBigNum(const std::string& str) - { - BN_init(this); - SetHex(str); - } - CBigNum& operator=(const CBigNum& b) { if (!BN_copy(this, &b)) @@ -407,6 +401,7 @@ public: CBigNum& operator>>=(unsigned int shift) { + // Note: BN_rshift segfaults on 64-bit ubuntu 9.10 if 2^shift is greater than the number if (!BN_rshift(this, this, shift)) throw bignum_error("CBigNum:operator>>= : BN_rshift failed"); return *this; @@ -516,6 +511,7 @@ inline const CBigNum operator<<(const CBigNum& a, unsigned int shift) inline const CBigNum operator>>(const CBigNum& a, unsigned int shift) { CBigNum r; + // Note: BN_rshift segfaults on 64-bit ubuntu 9.10 if 2^shift is greater than the number if (!BN_rshift(&r, &a, shift)) throw bignum_error("CBigNum:operator>> : BN_rshift failed"); return r; diff --git a/main.cpp b/main.cpp index 90d239fa0f..0c7aff842b 100644 --- a/main.cpp +++ b/main.cpp @@ -1570,7 +1570,9 @@ bool LoadBlockIndex(bool fAllowNew) txNew.vout.resize(1); txNew.vin[0].scriptSig = CScript() << 486604799 << CBigNum(4) << vector((const unsigned char*)pszTimestamp, (const unsigned char*)pszTimestamp + strlen(pszTimestamp)); txNew.vout[0].nValue = 50 * COIN; - txNew.vout[0].scriptPubKey = CScript() << CBigNum("0x5F1DF16B2B704C8A578D0BBAF74D385CDE12C11EE50455F3C438EF4C3FBCF649B6DE611FEAE06279A60939E028A8D65C10B73071A6F16719274855FEB0FD8A6704") << OP_CHECKSIG; + CBigNum bnPubKey; + bnPubKey.SetHex("0x5F1DF16B2B704C8A578D0BBAF74D385CDE12C11EE50455F3C438EF4C3FBCF649B6DE611FEAE06279A60939E028A8D65C10B73071A6F16719274855FEB0FD8A6704"); + txNew.vout[0].scriptPubKey = CScript() << bnPubKey << OP_CHECKSIG; CBlock block; block.vtx.push_back(txNew); block.hashPrevBlock = 0; @@ -3022,12 +3024,9 @@ string SendMoneyToBitcoinAddress(string strAddress, int64 nValue, CWalletTx& wtx return "You don't have enough money"; // Parse bitcoin address - uint160 hash160; - if (!AddressToHash160(strAddress, hash160)) + CScript scriptPubKey; + if (!scriptPubKey.SetBitcoinAddress(strAddress)) return "Invalid bitcoin address"; - // Send to bitcoin address - CScript scriptPubKey; - scriptPubKey.SetBitcoinAddress(hash160); return SendMoney(scriptPubKey, nValue, wtxNew); } diff --git a/net.cpp b/net.cpp index ada78eb366..d669b8c5e5 100644 --- a/net.cpp +++ b/net.cpp @@ -1032,7 +1032,7 @@ void ThreadMessageHandler2(void* parg) { printf("ThreadMessageHandler started\n"); SetThreadPriority(THREAD_PRIORITY_BELOW_NORMAL); - loop + while (!fShutdown) { // Poll the connected nodes for messages vector vNodesCopy; diff --git a/rpc.cpp b/rpc.cpp index 9f28e7ec74..b176b1580c 100644 --- a/rpc.cpp +++ b/rpc.cpp @@ -503,7 +503,7 @@ Value CallRPC(const string& strMethod, const Array& params) // Connect to localhost tcp::iostream stream("127.0.0.1", "8332"); if (stream.fail()) - throw runtime_error("unable to connect to server"); + throw runtime_error("couldn't connect to server"); // Send request string strRequest = JSONRPCRequest(strMethod, params, 1); diff --git a/ui.cpp b/ui.cpp index 586200d6ef..aad599c77c 100644 --- a/ui.cpp +++ b/ui.cpp @@ -328,7 +328,7 @@ CMainFrame::CMainFrame(wxWindow* parent) : CMainFrameBase(parent) m_toolBar->Realize(); // resize to fit ubuntu's huge default font dResize = 1.20; - SetSize(dResize * GetSize().GetWidth(), 1.1 * GetSize().GetHeight()); + SetSize((dResize + 0.02) * GetSize().GetWidth(), 1.09 * GetSize().GetHeight()); #endif m_staticTextBalance->SetLabel(FormatMoney(GetBalance()) + " "); m_listCtrl->SetFocus(); @@ -346,24 +346,6 @@ CMainFrame::CMainFrame(wxWindow* parent) : CMainFrameBase(parent) m_listCtrl->InsertColumn(5, "Debit", wxLIST_FORMAT_RIGHT, dResize * 79); m_listCtrl->InsertColumn(6, "Credit", wxLIST_FORMAT_RIGHT, dResize * 79); - //m_listCtrlProductsSent->InsertColumn(0, "Category", wxLIST_FORMAT_LEFT, 100); - //m_listCtrlProductsSent->InsertColumn(1, "Title", wxLIST_FORMAT_LEFT, 100); - //m_listCtrlProductsSent->InsertColumn(2, "Description", wxLIST_FORMAT_LEFT, 100); - //m_listCtrlProductsSent->InsertColumn(3, "Price", wxLIST_FORMAT_LEFT, 100); - //m_listCtrlProductsSent->InsertColumn(4, "", wxLIST_FORMAT_LEFT, 100); - - //m_listCtrlOrdersSent->InsertColumn(0, "Time", wxLIST_FORMAT_LEFT, 100); - //m_listCtrlOrdersSent->InsertColumn(1, "Price", wxLIST_FORMAT_LEFT, 100); - //m_listCtrlOrdersSent->InsertColumn(2, "", wxLIST_FORMAT_LEFT, 100); - //m_listCtrlOrdersSent->InsertColumn(3, "", wxLIST_FORMAT_LEFT, 100); - //m_listCtrlOrdersSent->InsertColumn(4, "", wxLIST_FORMAT_LEFT, 100); - - //m_listCtrlOrdersReceived->InsertColumn(0, "Time", wxLIST_FORMAT_LEFT, 100); - //m_listCtrlOrdersReceived->InsertColumn(1, "Price", wxLIST_FORMAT_LEFT, 100); - //m_listCtrlOrdersReceived->InsertColumn(2, "Payment Status", wxLIST_FORMAT_LEFT, 100); - //m_listCtrlOrdersReceived->InsertColumn(3, "", wxLIST_FORMAT_LEFT, 100); - //m_listCtrlOrdersReceived->InsertColumn(4, "", wxLIST_FORMAT_LEFT, 100); - // Init status bar int pnWidths[3] = { -100, 88, 290 }; #ifndef __WXMSW__ @@ -503,33 +485,34 @@ int CMainFrame::GetSortIndex(const string& strSort) void CMainFrame::InsertLine(bool fNew, int nIndex, uint256 hashKey, string strSort, const wxString& str2, const wxString& str3, const wxString& str4, const wxString& str5, const wxString& str6) { - string str0 = strSort; - long nData = *(long*)&hashKey; + 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) == hashKey.ToString()) + 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), str0); + 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) != str0) + if (GetItemText(m_listCtrl, nIndex, 0) != strSort) { m_listCtrl->DeleteItem(nIndex); - nIndex = m_listCtrl->InsertItem(GetSortIndex(strSort), str0); + nIndex = m_listCtrl->InsertItem(GetSortIndex(strSort), strSort); } } - m_listCtrl->SetItem(nIndex, 1, hashKey.ToString()); + 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); @@ -544,8 +527,9 @@ bool CMainFrame::DeleteLine(uint256 hashKey) // Find item int nIndex = -1; + string strHash = " " + hashKey.ToString(); while ((nIndex = m_listCtrl->FindItem(nIndex, nData)) != -1) - if (GetItemText(m_listCtrl, nIndex, 1) == hashKey.ToString()) + if (GetItemText(m_listCtrl, nIndex, 1) == strHash) break; if (nIndex != -1) @@ -1916,7 +1900,7 @@ CSendingDialog::CSendingDialog(wxWindow* parent, const CAddress& addrIn, int64 n fUIDone = false; fWorkDone = false; #ifndef __WXMSW__ - SetSize(1.2 * GetSize().GetWidth(), 1.05 * GetSize().GetHeight()); + SetSize(1.2 * GetSize().GetWidth(), 1.08 * GetSize().GetHeight()); #endif SetTitle(strprintf("Sending %s to %s", FormatMoney(nPrice).c_str(), wtx.mapValue["to"].c_str())); diff --git a/uint256.h b/uint256.h index 9a0c770497..6976d9dc00 100644 --- a/uint256.h +++ b/uint256.h @@ -299,19 +299,18 @@ public: return string(psz, psz + sizeof(pn)*2); } - void SetHex(const std::string& str) + void SetHex(const char* psz) { for (int i = 0; i < WIDTH; i++) pn[i] = 0; - // skip 0x - const char* psz = str.c_str(); + // skip leading spaces while (isspace(*psz)) psz++; + + // skip 0x if (psz[0] == '0' && tolower(psz[1]) == 'x') psz += 2; - while (isspace(*psz)) - psz++; // hex string to uint static char phexdigit[256] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,1,2,3,4,5,6,7,8,9,0,0,0,0,0,0, 0,0xa,0xb,0xc,0xd,0xe,0xf,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0xa,0xb,0xc,0xd,0xe,0xf,0,0,0,0,0,0,0,0,0 }; @@ -332,6 +331,11 @@ public: } } + void SetHex(const std::string& str) + { + SetHex(str.c_str()); + } + std::string ToString() const { return (GetHex()); -- cgit v1.2.3 From 297a50a06350e2094213a0930e896c10744256b9 Mon Sep 17 00:00:00 2001 From: s_nakamoto Date: Sun, 14 Feb 2010 22:27:13 +0000 Subject: renamed a few rpc methods --- makefile.vc | 2 +- net.cpp | 4 ---- rpc.cpp | 26 +++++++++++++------------- serialize.h | 2 +- util.h | 1 + 5 files changed, 16 insertions(+), 19 deletions(-) diff --git a/makefile.vc b/makefile.vc index 73fd1cfd9a..527f246769 100644 --- a/makefile.vc +++ b/makefile.vc @@ -22,7 +22,7 @@ LIBS= \ wxmsw28$(D)_richtext.lib wxmsw28$(D)_html.lib wxmsw28$(D)_core.lib wxmsw28$(D)_adv.lib wxbase28$(D).lib wxtiff$(D).lib wxjpeg$(D).lib wxpng$(D).lib wxzlib$(D).lib wxregex$(D).lib wxexpat$(D).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 WXDEFS=/DWIN32 /D__WXMSW__ /D_WINDOWS /DNOPCH -CFLAGS=/c /nologo /Ob0 /MD$(D) /EHsc /GR /Zm300 /YX /Fpobj/headers.pch $(DEBUGFLAGS) $(WXDEFS) $(INCLUDEPATHS) +CFLAGS=/c /nologo /Ob0 /MD$(D) /EHsc /GR /Zm300 $(DEBUGFLAGS) $(WXDEFS) $(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 market.h rpc.h uibase.h ui.h diff --git a/net.cpp b/net.cpp index d669b8c5e5..061f000a73 100644 --- a/net.cpp +++ b/net.cpp @@ -655,11 +655,7 @@ void ThreadSocketHandler2(void* parg) if (FD_ISSET(hListenSocket, &fdsetRecv)) { struct sockaddr_in sockaddr; -#ifdef __WXMSW__ - int len = sizeof(sockaddr); -#else socklen_t len = sizeof(sockaddr); -#endif SOCKET hSocket = accept(hListenSocket, (struct sockaddr*)&sockaddr, &len); CAddress addr(sockaddr); if (hSocket == INVALID_SOCKET) diff --git a/rpc.cpp b/rpc.cpp index b176b1580c..f4eef37f0c 100644 --- a/rpc.cpp +++ b/rpc.cpp @@ -157,12 +157,12 @@ Value listtransactions(const Array& params) } -Value getamountpaid(const Array& params) +Value getamountreceived(const Array& params) { if (params.size() < 1 || params.size() > 2) throw runtime_error( - "getamountpaid [minconf=1]\n" - "Returns the total amount paid to in transactions with at least [minconf] confirmations."); + "getamountreceived [minconf=1]\n" + "Returns the total amount received by in transactions with at least [minconf] confirmations."); // Bitcoin address string strAddress = params[0].get_str(); @@ -207,15 +207,15 @@ struct tallyitem } }; -Value getallpayments(const Array& params) +Value getallreceived(const Array& params) { if (params.size() > 1) throw runtime_error( - "getallpayments [minconf=1]\n" + "getallreceived [minconf=1]\n" "[minconf] is the minimum number of confirmations before payments are included.\n" "Returns an array of objects containing:\n" " \"address\" : bitcoin address\n" - " \"amount\" : total amount paid to the address\n" + " \"amount\" : total amount received by the address\n" " \"conf\" : number of confirmations\n" " \"label\" : the label set for this address when it was created by getnewaddress"); @@ -294,8 +294,8 @@ pair pCallTable[] = make_pair("getnewaddress", &getnewaddress), make_pair("sendtoaddress", &sendtoaddress), make_pair("listtransactions", &listtransactions), - make_pair("getamountpaid", &getamountpaid), - make_pair("getallpayments", &getallpayments), + make_pair("getamountreceived", &getamountreceived), + make_pair("getallreceived", &getallreceived), }; map mapCallTable(pCallTable, pCallTable + sizeof(pCallTable)/sizeof(pCallTable[0])); @@ -571,11 +571,11 @@ int CommandLineRPC(int argc, char *argv[]) // Special case other types int n = params.size(); - if (strMethod == "sendtoaddress" && n > 1) ConvertTo(params[1]); - if (strMethod == "listtransactions" && n > 0) ConvertTo(params[0]); - if (strMethod == "listtransactions" && n > 1) ConvertTo(params[1]); - if (strMethod == "getamountpaid" && n > 1) ConvertTo(params[1]); - if (strMethod == "getallpayments" && n > 0) ConvertTo(params[0]); + if (strMethod == "sendtoaddress" && n > 1) ConvertTo(params[1]); + if (strMethod == "listtransactions" && n > 0) ConvertTo(params[0]); + if (strMethod == "listtransactions" && n > 1) ConvertTo(params[1]); + if (strMethod == "getamountreceived" && n > 1) ConvertTo(params[1]); + if (strMethod == "getallreceived" && n > 0) ConvertTo(params[0]); // Execute Value result = CallRPC(strMethod, params); diff --git a/serialize.h b/serialize.h index eb090ae2e6..f73773147d 100644 --- a/serialize.h +++ b/serialize.h @@ -20,7 +20,7 @@ class CDataStream; class CAutoFile; static const int VERSION = 201; -static const char* pszSubVer = ".0"; +static const char* pszSubVer = ".1"; diff --git a/util.h b/util.h index 6a7fabc5e9..933c71be0b 100644 --- a/util.h +++ b/util.h @@ -68,6 +68,7 @@ static const bool fWindows = true; #define S_IWUSR 0200 #endif #define unlink _unlink +typedef int socklen_t; #else static const bool fWindows = false; #define WSAGetLastError() errno -- cgit v1.2.3 From 64a474a49b20a66453fbcd2382e4b042427b0a0f Mon Sep 17 00:00:00 2001 From: s_nakamoto Date: Sun, 14 Feb 2010 22:27:13 +0000 Subject: renamed a few rpc methods git-svn-id: https://bitcoin.svn.sourceforge.net/svnroot/bitcoin/trunk@63 1a98c847-1fd6-4fd8-948a-caf3550aa51b --- makefile.vc | 2 +- net.cpp | 4 ---- rpc.cpp | 26 +++++++++++++------------- serialize.h | 2 +- util.h | 1 + 5 files changed, 16 insertions(+), 19 deletions(-) diff --git a/makefile.vc b/makefile.vc index 73fd1cfd9a..527f246769 100644 --- a/makefile.vc +++ b/makefile.vc @@ -22,7 +22,7 @@ LIBS= \ wxmsw28$(D)_richtext.lib wxmsw28$(D)_html.lib wxmsw28$(D)_core.lib wxmsw28$(D)_adv.lib wxbase28$(D).lib wxtiff$(D).lib wxjpeg$(D).lib wxpng$(D).lib wxzlib$(D).lib wxregex$(D).lib wxexpat$(D).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 WXDEFS=/DWIN32 /D__WXMSW__ /D_WINDOWS /DNOPCH -CFLAGS=/c /nologo /Ob0 /MD$(D) /EHsc /GR /Zm300 /YX /Fpobj/headers.pch $(DEBUGFLAGS) $(WXDEFS) $(INCLUDEPATHS) +CFLAGS=/c /nologo /Ob0 /MD$(D) /EHsc /GR /Zm300 $(DEBUGFLAGS) $(WXDEFS) $(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 market.h rpc.h uibase.h ui.h diff --git a/net.cpp b/net.cpp index d669b8c5e5..061f000a73 100644 --- a/net.cpp +++ b/net.cpp @@ -655,11 +655,7 @@ void ThreadSocketHandler2(void* parg) if (FD_ISSET(hListenSocket, &fdsetRecv)) { struct sockaddr_in sockaddr; -#ifdef __WXMSW__ - int len = sizeof(sockaddr); -#else socklen_t len = sizeof(sockaddr); -#endif SOCKET hSocket = accept(hListenSocket, (struct sockaddr*)&sockaddr, &len); CAddress addr(sockaddr); if (hSocket == INVALID_SOCKET) diff --git a/rpc.cpp b/rpc.cpp index b176b1580c..f4eef37f0c 100644 --- a/rpc.cpp +++ b/rpc.cpp @@ -157,12 +157,12 @@ Value listtransactions(const Array& params) } -Value getamountpaid(const Array& params) +Value getamountreceived(const Array& params) { if (params.size() < 1 || params.size() > 2) throw runtime_error( - "getamountpaid [minconf=1]\n" - "Returns the total amount paid to in transactions with at least [minconf] confirmations."); + "getamountreceived [minconf=1]\n" + "Returns the total amount received by in transactions with at least [minconf] confirmations."); // Bitcoin address string strAddress = params[0].get_str(); @@ -207,15 +207,15 @@ struct tallyitem } }; -Value getallpayments(const Array& params) +Value getallreceived(const Array& params) { if (params.size() > 1) throw runtime_error( - "getallpayments [minconf=1]\n" + "getallreceived [minconf=1]\n" "[minconf] is the minimum number of confirmations before payments are included.\n" "Returns an array of objects containing:\n" " \"address\" : bitcoin address\n" - " \"amount\" : total amount paid to the address\n" + " \"amount\" : total amount received by the address\n" " \"conf\" : number of confirmations\n" " \"label\" : the label set for this address when it was created by getnewaddress"); @@ -294,8 +294,8 @@ pair pCallTable[] = make_pair("getnewaddress", &getnewaddress), make_pair("sendtoaddress", &sendtoaddress), make_pair("listtransactions", &listtransactions), - make_pair("getamountpaid", &getamountpaid), - make_pair("getallpayments", &getallpayments), + make_pair("getamountreceived", &getamountreceived), + make_pair("getallreceived", &getallreceived), }; map mapCallTable(pCallTable, pCallTable + sizeof(pCallTable)/sizeof(pCallTable[0])); @@ -571,11 +571,11 @@ int CommandLineRPC(int argc, char *argv[]) // Special case other types int n = params.size(); - if (strMethod == "sendtoaddress" && n > 1) ConvertTo(params[1]); - if (strMethod == "listtransactions" && n > 0) ConvertTo(params[0]); - if (strMethod == "listtransactions" && n > 1) ConvertTo(params[1]); - if (strMethod == "getamountpaid" && n > 1) ConvertTo(params[1]); - if (strMethod == "getallpayments" && n > 0) ConvertTo(params[0]); + if (strMethod == "sendtoaddress" && n > 1) ConvertTo(params[1]); + if (strMethod == "listtransactions" && n > 0) ConvertTo(params[0]); + if (strMethod == "listtransactions" && n > 1) ConvertTo(params[1]); + if (strMethod == "getamountreceived" && n > 1) ConvertTo(params[1]); + if (strMethod == "getallreceived" && n > 0) ConvertTo(params[0]); // Execute Value result = CallRPC(strMethod, params); diff --git a/serialize.h b/serialize.h index eb090ae2e6..f73773147d 100644 --- a/serialize.h +++ b/serialize.h @@ -20,7 +20,7 @@ class CDataStream; class CAutoFile; static const int VERSION = 201; -static const char* pszSubVer = ".0"; +static const char* pszSubVer = ".1"; diff --git a/util.h b/util.h index 6a7fabc5e9..933c71be0b 100644 --- a/util.h +++ b/util.h @@ -68,6 +68,7 @@ static const bool fWindows = true; #define S_IWUSR 0200 #endif #define unlink _unlink +typedef int socklen_t; #else static const bool fWindows = false; #define WSAGetLastError() errno -- cgit v1.2.3 From cc4b78d59f566ff43881f57797a16ce45eb1b80e Mon Sep 17 00:00:00 2001 From: s_nakamoto Date: Mon, 15 Feb 2010 04:03:07 +0000 Subject: strip out unfinished product, review and market stuff, enable _() instead of wxT() in uiproject.fbp so it uses wxGetTranslation for the wxFormBuilder generated part of the UI --- db.cpp | 21 - db.h | 39 - headers.h | 1 - main.cpp | 24 +- makefile | 7 +- makefile.unix.wx2.8 | 7 +- makefile.unix.wx2.9 | 7 +- makefile.vc | 7 +- market.cpp | 264 --- market.h | 182 -- net.cpp | 9 - net.h | 6 - serialize.h | 2 +- ui.cpp | 930 +-------- ui.h | 142 +- uibase.cpp | 851 +------- uibase.h | 287 +-- uiproject.fbp | 5805 +-------------------------------------------------- 18 files changed, 127 insertions(+), 8464 deletions(-) delete mode 100644 market.cpp delete mode 100644 market.h diff --git a/db.cpp b/db.cpp index ff9ece52b1..bbf24a0e70 100644 --- a/db.cpp +++ b/db.cpp @@ -507,27 +507,6 @@ bool LoadAddresses() -// -// CReviewDB -// - -bool CReviewDB::ReadReviews(uint256 hash, vector& vReviews) -{ - vReviews.size(); // msvc workaround, just need to do anything with vReviews - return Read(make_pair(string("reviews"), hash), vReviews); -} - -bool CReviewDB::WriteReviews(uint256 hash, const vector& vReviews) -{ - return Write(make_pair(string("reviews"), hash), vReviews); -} - - - - - - - // // CWalletDB // diff --git a/db.h b/db.h index 538076b5aa..fb4e9268c8 100644 --- a/db.h +++ b/db.h @@ -285,45 +285,6 @@ public: -class CReviewDB : public CDB -{ -public: - CReviewDB(const char* pszMode="r+") : CDB("reviews.dat", pszMode) { } -private: - CReviewDB(const CReviewDB&); - void operator=(const CReviewDB&); -public: - bool ReadUser(uint256 hash, CUser& user) - { - return Read(make_pair(string("user"), hash), user); - } - - bool WriteUser(uint256 hash, const CUser& user) - { - return Write(make_pair(string("user"), hash), user); - } - - bool ReadReviews(uint256 hash, vector& vReviews); - bool WriteReviews(uint256 hash, const vector& vReviews); -}; - - - - - -class CMarketDB : public CDB -{ -public: - CMarketDB(const char* pszMode="r+") : CDB("market.dat", pszMode) { } -private: - CMarketDB(const CMarketDB&); - void operator=(const CMarketDB&); -}; - - - - - class CAddrDB : public CDB { public: diff --git a/headers.h b/headers.h index dda4f9caf2..7fb227ec42 100644 --- a/headers.h +++ b/headers.h @@ -99,7 +99,6 @@ using namespace boost; #include "net.h" #include "irc.h" #include "main.h" -#include "market.h" #include "rpc.h" #include "uibase.h" #include "ui.h" diff --git a/main.cpp b/main.cpp index 0c7aff842b..3391a2994a 100644 --- a/main.cpp +++ b/main.cpp @@ -1706,10 +1706,8 @@ bool AlreadyHave(CTxDB& txdb, const CInv& inv) { switch (inv.type) { - case MSG_TX: return mapTransactions.count(inv.hash) || txdb.ContainsTx(inv.hash); - case MSG_BLOCK: return mapBlockIndex.count(inv.hash) || mapOrphanBlocks.count(inv.hash); - case MSG_REVIEW: return true; - case MSG_PRODUCT: return mapProducts.count(inv.hash); + case MSG_TX: return mapTransactions.count(inv.hash) || txdb.ContainsTx(inv.hash); + case MSG_BLOCK: return mapBlockIndex.count(inv.hash) || mapOrphanBlocks.count(inv.hash); } // Don't know what it is, just say we already got one return true; @@ -2108,24 +2106,6 @@ bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) } - else if (strCommand == "review") - { - CDataStream vMsg(vRecv); - CReview review; - vRecv >> review; - - CInv inv(MSG_REVIEW, review.GetHash()); - pfrom->AddInventoryKnown(inv); - - if (review.AcceptReview()) - { - // Relay the original message as-is in case it's a higher version than we know how to parse - RelayMessage(inv, vMsg); - mapAlreadyAskedFor.erase(inv); - } - } - - else if (strCommand == "block") { auto_ptr pblock(new CBlock); diff --git a/makefile b/makefile index affbe517c7..fb8dd2746b 100644 --- a/makefile +++ b/makefile @@ -25,7 +25,7 @@ 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 WXDEFS=-DWIN32 -D__WXMSW__ -D_WINDOWS -DNOPCH CFLAGS=-mthreads -O0 -w -Wno-invalid-offsetof -Wformat $(DEBUGFLAGS) $(WXDEFS) $(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 market.h rpc.h uibase.h ui.h +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 @@ -50,9 +50,6 @@ obj/net.o: net.cpp $(HEADERS) obj/main.o: main.cpp $(HEADERS) sha.h g++ -c $(CFLAGS) -o $@ $< -obj/market.o: market.cpp $(HEADERS) - g++ -c $(CFLAGS) -o $@ $< - obj/ui.o: ui.cpp $(HEADERS) g++ -c $(CFLAGS) -o $@ $< @@ -73,7 +70,7 @@ obj/ui_res.o: ui.rc rc/bitcoin.ico rc/check.ico rc/send16.bmp rc/send16mask.bmp -OBJS=obj/util.o obj/script.o obj/db.o obj/net.o obj/main.o obj/market.o \ +OBJS=obj/util.o obj/script.o obj/db.o obj/net.o obj/main.o \ obj/ui.o obj/uibase.o obj/sha.o obj/irc.o obj/rpc.o \ obj/ui_res.o diff --git a/makefile.unix.wx2.8 b/makefile.unix.wx2.8 index d3358ab2df..38d9bc0e90 100644 --- a/makefile.unix.wx2.8 +++ b/makefile.unix.wx2.8 @@ -35,7 +35,7 @@ LIBS= \ WXDEFS=-D__WXGTK__ -DNOPCH CFLAGS=-O0 -Wno-invalid-offsetof -Wformat $(DEBUGFLAGS) $(WXDEFS) $(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 market.h rpc.h uibase.h ui.h +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 @@ -60,9 +60,6 @@ obj/net.o: net.cpp $(HEADERS) obj/main.o: main.cpp $(HEADERS) sha.h g++ -c $(CFLAGS) -o $@ $< -obj/market.o: market.cpp $(HEADERS) - g++ -c $(CFLAGS) -o $@ $< - obj/ui.o: ui.cpp $(HEADERS) g++ -c $(CFLAGS) -o $@ $< @@ -80,7 +77,7 @@ obj/rpc.o: rpc.cpp $(HEADERS) -OBJS=obj/util.o obj/script.o obj/db.o obj/net.o obj/main.o obj/market.o \ +OBJS=obj/util.o obj/script.o obj/db.o obj/net.o obj/main.o \ obj/ui.o obj/uibase.o obj/sha.o obj/irc.o obj/rpc.o bitcoin: headers.h.gch $(OBJS) diff --git a/makefile.unix.wx2.9 b/makefile.unix.wx2.9 index 8defcbb6fc..0b3b09b577 100644 --- a/makefile.unix.wx2.9 +++ b/makefile.unix.wx2.9 @@ -35,7 +35,7 @@ LIBS= \ WXDEFS=-D__WXGTK__ -DNOPCH CFLAGS=-O0 -Wno-invalid-offsetof -Wformat $(DEBUGFLAGS) $(WXDEFS) $(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 market.h rpc.h uibase.h ui.h +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 @@ -60,9 +60,6 @@ obj/net.o: net.cpp $(HEADERS) obj/main.o: main.cpp $(HEADERS) sha.h g++ -c $(CFLAGS) -o $@ $< -obj/market.o: market.cpp $(HEADERS) - g++ -c $(CFLAGS) -o $@ $< - obj/ui.o: ui.cpp $(HEADERS) g++ -c $(CFLAGS) -o $@ $< @@ -80,7 +77,7 @@ obj/rpc.o: rpc.cpp $(HEADERS) -OBJS=obj/util.o obj/script.o obj/db.o obj/net.o obj/main.o obj/market.o \ +OBJS=obj/util.o obj/script.o obj/db.o obj/net.o obj/main.o \ obj/ui.o obj/uibase.o obj/sha.o obj/irc.o obj/rpc.o bitcoin: headers.h.gch $(OBJS) diff --git a/makefile.vc b/makefile.vc index 527f246769..5ca8de464c 100644 --- a/makefile.vc +++ b/makefile.vc @@ -23,7 +23,7 @@ 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 WXDEFS=/DWIN32 /D__WXMSW__ /D_WINDOWS /DNOPCH CFLAGS=/c /nologo /Ob0 /MD$(D) /EHsc /GR /Zm300 $(DEBUGFLAGS) $(WXDEFS) $(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 market.h rpc.h uibase.h ui.h +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 @@ -45,9 +45,6 @@ obj\net.obj: net.cpp $(HEADERS) obj\main.obj: main.cpp $(HEADERS) sha.h cl $(CFLAGS) /Fo$@ %s -obj\market.obj: market.cpp $(HEADERS) - cl $(CFLAGS) /Fo$@ %s - obj\ui.obj: ui.cpp $(HEADERS) cl $(CFLAGS) /Fo$@ %s @@ -68,7 +65,7 @@ obj\ui.res: ui.rc rc/bitcoin.ico rc/check.ico rc/send16.bmp rc/send16mask.bmp r -OBJS=obj\util.obj obj\script.obj obj\db.obj obj\net.obj obj\main.obj obj\market.obj \ +OBJS=obj\util.obj obj\script.obj obj\db.obj obj\net.obj obj\main.obj \ obj\ui.obj obj\uibase.obj obj\sha.obj obj\irc.obj obj\rpc.obj \ obj\ui.res diff --git a/market.cpp b/market.cpp deleted file mode 100644 index 22b5365fa4..0000000000 --- a/market.cpp +++ /dev/null @@ -1,264 +0,0 @@ -// Copyright (c) 2009 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" - - - - - - - - - - -// -// Global state variables -// - -//// later figure out how these are persisted -map mapMyProducts; - - - - -map mapProducts; -CCriticalSection cs_mapProducts; - -bool AdvertInsert(const CProduct& product) -{ - uint256 hash = product.GetHash(); - bool fNew = false; - bool fUpdated = false; - - CRITICAL_BLOCK(cs_mapProducts) - { - // Insert or find existing product - pair::iterator, bool> item = mapProducts.insert(make_pair(hash, product)); - CProduct* pproduct = &(*(item.first)).second; - fNew = item.second; - - // Update if newer - if (product.nSequence > pproduct->nSequence) - { - *pproduct = product; - fUpdated = true; - } - } - - //if (fNew) - // NotifyProductAdded(hash); - //else if (fUpdated) - // NotifyProductUpdated(hash); - - return (fNew || fUpdated); -} - -void AdvertErase(const CProduct& product) -{ - uint256 hash = product.GetHash(); - CRITICAL_BLOCK(cs_mapProducts) - mapProducts.erase(hash); - //NotifyProductDeleted(hash); -} - - - - - - - - - - - - - - - - - - - -template -unsigned int Union(T& v1, T& v2) -{ - // v1 = v1 union v2 - // v1 and v2 must be sorted - // returns the number of elements added to v1 - - ///// need to check that this is equivalent, then delete this comment - //vector vUnion(v1.size() + v2.size()); - //vUnion.erase(set_union(v1.begin(), v1.end(), - // v2.begin(), v2.end(), - // vUnion.begin()), - // vUnion.end()); - - T vUnion; - vUnion.reserve(v1.size() + v2.size()); - set_union(v1.begin(), v1.end(), - v2.begin(), v2.end(), - back_inserter(vUnion)); - unsigned int nAdded = vUnion.size() - v1.size(); - if (nAdded > 0) - v1 = vUnion; - return nAdded; -} - -void CUser::AddAtom(unsigned short nAtom, bool fOrigin) -{ - // Ignore duplicates - if (binary_search(vAtomsIn.begin(), vAtomsIn.end(), nAtom) || - find(vAtomsNew.begin(), vAtomsNew.end(), nAtom) != vAtomsNew.end()) - return; - - //// instead of zero atom, should change to free atom that propagates, - //// limited to lower than a certain value like 5 so conflicts quickly - // The zero atom never propagates, - // new atoms always propagate through the user that created them - if (nAtom == 0 || fOrigin) - { - vector vTmp(1, nAtom); - Union(vAtomsIn, vTmp); - if (fOrigin) - vAtomsOut.push_back(nAtom); - return; - } - - vAtomsNew.push_back(nAtom); - - if (vAtomsNew.size() >= nFlowthroughRate || vAtomsOut.empty()) - { - // Select atom to flow through to vAtomsOut - vAtomsOut.push_back(vAtomsNew[GetRand(vAtomsNew.size())]); - - // Merge vAtomsNew into vAtomsIn - sort(vAtomsNew.begin(), vAtomsNew.end()); - Union(vAtomsIn, vAtomsNew); - vAtomsNew.clear(); - } -} - -bool AddAtomsAndPropagate(uint256 hashUserStart, const vector& vAtoms, bool fOrigin) -{ - CReviewDB reviewdb; - map > pmapPropagate[2]; - pmapPropagate[0][hashUserStart] = vAtoms; - - for (int side = 0; !pmapPropagate[side].empty(); side = 1 - side) - { - map >& mapFrom = pmapPropagate[side]; - map >& mapTo = pmapPropagate[1 - side]; - - for (map >::iterator mi = mapFrom.begin(); mi != mapFrom.end(); ++mi) - { - const uint256& hashUser = (*mi).first; - const vector& vReceived = (*mi).second; - - ///// this would be a lot easier on the database if it put the new atom at the beginning of the list, - ///// so the change would be right next to the vector size. - - // Read user - CUser user; - reviewdb.ReadUser(hashUser, user); - unsigned int nIn = user.vAtomsIn.size(); - unsigned int nNew = user.vAtomsNew.size(); - unsigned int nOut = user.vAtomsOut.size(); - - // Add atoms received - foreach(unsigned short nAtom, vReceived) - user.AddAtom(nAtom, fOrigin); - fOrigin = false; - - // Don't bother writing to disk if no changes - if (user.vAtomsIn.size() == nIn && user.vAtomsNew.size() == nNew) - continue; - - // Propagate - if (user.vAtomsOut.size() > nOut) - foreach(const uint256& hash, user.vLinksOut) - mapTo[hash].insert(mapTo[hash].end(), user.vAtomsOut.begin() + nOut, user.vAtomsOut.end()); - - // Write back - if (!reviewdb.WriteUser(hashUser, user)) - return false; - } - mapFrom.clear(); - } - return true; -} - - - - - - -bool CReview::AcceptReview() -{ - // Timestamp - nTime = GetTime(); - - // Check signature - if (!CKey::Verify(vchPubKeyFrom, GetSigHash(), vchSig)) - return false; - - CReviewDB reviewdb; - - // Add review text to recipient - vector vReviews; - reviewdb.ReadReviews(hashTo, vReviews); - vReviews.push_back(*this); - if (!reviewdb.WriteReviews(hashTo, vReviews)) - return false; - - // Add link from sender - CUser user; - uint256 hashFrom = Hash(vchPubKeyFrom.begin(), vchPubKeyFrom.end()); - reviewdb.ReadUser(hashFrom, user); - user.vLinksOut.push_back(hashTo); - if (!reviewdb.WriteUser(hashFrom, user)) - return false; - - reviewdb.Close(); - - // Propagate atoms to recipient - vector vZeroAtom(1, 0); - if (!AddAtomsAndPropagate(hashTo, user.vAtomsOut.size() ? user.vAtomsOut : vZeroAtom, false)) - return false; - - return true; -} - - - - - -bool CProduct::CheckSignature() -{ - return (CKey::Verify(vchPubKeyFrom, GetSigHash(), vchSig)); -} - -bool CProduct::CheckProduct() -{ - if (!CheckSignature()) - return false; - - // Make sure it's a summary product - if (!mapDetails.empty() || !vOrderForm.empty()) - return false; - - // Look up seller's atom count - CReviewDB reviewdb("r"); - CUser user; - reviewdb.ReadUser(GetUserHash(), user); - nAtoms = user.GetAtomCount(); - reviewdb.Close(); - - ////// delme, this is now done by AdvertInsert - //// Store to memory - //CRITICAL_BLOCK(cs_mapProducts) - // mapProducts[GetHash()] = *this; - - return true; -} diff --git a/market.h b/market.h deleted file mode 100644 index 2714787307..0000000000 --- a/market.h +++ /dev/null @@ -1,182 +0,0 @@ -// Copyright (c) 2009 Satoshi Nakamoto -// Distributed under the MIT/X11 software license, see the accompanying -// file license.txt or http://www.opensource.org/licenses/mit-license.php. - -class CUser; -class CReview; -class CProduct; - -static const unsigned int nFlowthroughRate = 2; - - - - -bool AdvertInsert(const CProduct& product); -void AdvertErase(const CProduct& product); -bool AddAtomsAndPropagate(uint256 hashUserStart, const vector& vAtoms, bool fOrigin); - - - - - - - - -class CUser -{ -public: - vector vAtomsIn; - vector vAtomsNew; - vector vAtomsOut; - vector vLinksOut; - - CUser() - { - } - - IMPLEMENT_SERIALIZE - ( - if (!(nType & SER_GETHASH)) - READWRITE(nVersion); - READWRITE(vAtomsIn); - READWRITE(vAtomsNew); - READWRITE(vAtomsOut); - READWRITE(vLinksOut); - ) - - void SetNull() - { - vAtomsIn.clear(); - vAtomsNew.clear(); - vAtomsOut.clear(); - vLinksOut.clear(); - } - - uint256 GetHash() const { return SerializeHash(*this); } - - - int GetAtomCount() const - { - return (vAtomsIn.size() + vAtomsNew.size()); - } - - void AddAtom(unsigned short nAtom, bool fOrigin); -}; - - - - - - - -class CReview -{ -public: - int nVersion; - uint256 hashTo; - map mapValue; - vector vchPubKeyFrom; - vector vchSig; - - // memory only - unsigned int nTime; - int nAtoms; - - - CReview() - { - nVersion = 1; - hashTo = 0; - nTime = 0; - nAtoms = 0; - } - - IMPLEMENT_SERIALIZE - ( - READWRITE(this->nVersion); - nVersion = this->nVersion; - if (!(nType & SER_DISK)) - READWRITE(hashTo); - READWRITE(mapValue); - READWRITE(vchPubKeyFrom); - if (!(nType & SER_GETHASH)) - READWRITE(vchSig); - ) - - uint256 GetHash() const { return SerializeHash(*this); } - uint256 GetSigHash() const { return SerializeHash(*this, SER_GETHASH|SER_SKIPSIG); } - uint256 GetUserHash() const { return Hash(vchPubKeyFrom.begin(), vchPubKeyFrom.end()); } - - - bool AcceptReview(); -}; - - - - - - - -class CProduct -{ -public: - int nVersion; - CAddress addr; - map mapValue; - map mapDetails; - vector > vOrderForm; - unsigned int nSequence; - vector vchPubKeyFrom; - vector vchSig; - - // disk only - int nAtoms; - - // memory only - set setSources; - - CProduct() - { - nVersion = 1; - nAtoms = 0; - nSequence = 0; - } - - IMPLEMENT_SERIALIZE - ( - READWRITE(this->nVersion); - nVersion = this->nVersion; - READWRITE(addr); - READWRITE(mapValue); - if (!(nType & SER_GETHASH)) - { - READWRITE(mapDetails); - READWRITE(vOrderForm); - READWRITE(nSequence); - } - READWRITE(vchPubKeyFrom); - if (!(nType & SER_GETHASH)) - READWRITE(vchSig); - if (nType & SER_DISK) - READWRITE(nAtoms); - ) - - uint256 GetHash() const { return SerializeHash(*this); } - uint256 GetSigHash() const { return SerializeHash(*this, SER_GETHASH|SER_SKIPSIG); } - uint256 GetUserHash() const { return Hash(vchPubKeyFrom.begin(), vchPubKeyFrom.end()); } - - - bool CheckSignature(); - bool CheckProduct(); -}; - - - - - - - - -extern map mapProducts; -extern CCriticalSection cs_mapProducts; -extern map mapMyProducts; diff --git a/net.cpp b/net.cpp index 061f000a73..8e8127d73b 100644 --- a/net.cpp +++ b/net.cpp @@ -381,11 +381,6 @@ void CNode::CancelSubscribe(unsigned int nChannel) foreach(CNode* pnode, vNodes) if (pnode != this) pnode->PushMessage("sub-cancel", nChannel); - - // Clear memory, no longer subscribed - if (nChannel == MSG_PRODUCT) - CRITICAL_BLOCK(cs_mapProducts) - mapProducts.clear(); } } @@ -497,10 +492,6 @@ void CNode::Cleanup() // All of a nodes broadcasts and subscriptions are automatically torn down // when it goes down, so a node has to stay up to keep its broadcast going. - CRITICAL_BLOCK(cs_mapProducts) - for (map::iterator mi = mapProducts.begin(); mi != mapProducts.end();) - AdvertRemoveSource(this, MSG_PRODUCT, 0, (*(mi++)).second); - // Cancel subscriptions for (unsigned int nChannel = 0; nChannel < vfSubscribe.size(); nChannel++) if (vfSubscribe[nChannel]) diff --git a/net.h b/net.h index ce6f772f49..c7d15460a4 100644 --- a/net.h +++ b/net.h @@ -341,9 +341,6 @@ enum { MSG_TX = 1, MSG_BLOCK, - MSG_REVIEW, - MSG_PRODUCT, - MSG_TABLE, }; static const char* ppszTypeName[] = @@ -351,9 +348,6 @@ static const char* ppszTypeName[] = "ERROR", "tx", "block", - "review", - "product", - "table", }; class CInv diff --git a/serialize.h b/serialize.h index f73773147d..12b58ad1ca 100644 --- a/serialize.h +++ b/serialize.h @@ -20,7 +20,7 @@ class CDataStream; class CAutoFile; static const int VERSION = 201; -static const char* pszSubVer = ".1"; +static const char* pszSubVer = ".2"; diff --git a/ui.cpp b/ui.cpp index aad599c77c..f506fcf3e7 100644 --- a/ui.cpp +++ b/ui.cpp @@ -7,22 +7,15 @@ #include #endif -void ThreadRequestProductDetails(void* parg); -void ThreadRandSendTest(void* parg); bool GetStartOnSystemStartup(); void SetStartOnSystemStartup(bool fAutoStart); DEFINE_EVENT_TYPE(wxEVT_UITHREADCALL) -DEFINE_EVENT_TYPE(wxEVT_REPLY1) -DEFINE_EVENT_TYPE(wxEVT_REPLY2) -DEFINE_EVENT_TYPE(wxEVT_REPLY3) CMainFrame* pframeMain = NULL; CMyTaskBarIcon* ptaskbaricon = NULL; -bool fRandSendTest = false; -void RandSend(); extern int g_isPainting; bool fClosedToTray = false; @@ -210,93 +203,6 @@ int ThreadSafeMessageBox(const string& message, const string& caption, int style -////////////////////////////////////////////////////////////////////////////// -// -// Custom events -// -// If this code gets used again, it should be replaced with something like UIThreadCall - -set setCallbackAvailable; -CCriticalSection cs_setCallbackAvailable; - -void AddCallbackAvailable(void* p) -{ - CRITICAL_BLOCK(cs_setCallbackAvailable) - setCallbackAvailable.insert(p); -} - -void RemoveCallbackAvailable(void* p) -{ - CRITICAL_BLOCK(cs_setCallbackAvailable) - setCallbackAvailable.erase(p); -} - -bool IsCallbackAvailable(void* p) -{ - CRITICAL_BLOCK(cs_setCallbackAvailable) - return setCallbackAvailable.count(p); - return false; -} - -template -void AddPendingCustomEvent(wxEvtHandler* pevthandler, int nEventID, const T pbeginIn, const T pendIn) -{ - // Need to rewrite with something like UIThreadCall - // I'm tired of maintaining this hack that's only called by unfinished unused code. - assert(("Unimplemented", 0)); - //if (!pevthandler) - // return; - // - //const char* pbegin = (pendIn != pbeginIn) ? &pbeginIn[0] : NULL; - //const char* pend = pbegin + (pendIn - pbeginIn) * sizeof(pbeginIn[0]); - //wxCommandEvent event(nEventID); - //wxString strData(wxChar(0), (pend - pbegin) / sizeof(wxChar) + 1); - //memcpy(&strData[0], pbegin, pend - pbegin); - //event.SetString(strData); - //event.SetInt(pend - pbegin); - // - //pevthandler->AddPendingEvent(event); -} - -template -void AddPendingCustomEvent(wxEvtHandler* pevthandler, int nEventID, const T& obj) -{ - CDataStream ss; - ss << obj; - AddPendingCustomEvent(pevthandler, nEventID, ss.begin(), ss.end()); -} - -void AddPendingReplyEvent1(void* pevthandler, CDataStream& vRecv) -{ - if (IsCallbackAvailable(pevthandler)) - AddPendingCustomEvent((wxEvtHandler*)pevthandler, wxEVT_REPLY1, vRecv.begin(), vRecv.end()); -} - -void AddPendingReplyEvent2(void* pevthandler, CDataStream& vRecv) -{ - if (IsCallbackAvailable(pevthandler)) - AddPendingCustomEvent((wxEvtHandler*)pevthandler, wxEVT_REPLY2, vRecv.begin(), vRecv.end()); -} - -void AddPendingReplyEvent3(void* pevthandler, CDataStream& vRecv) -{ - if (IsCallbackAvailable(pevthandler)) - AddPendingCustomEvent((wxEvtHandler*)pevthandler, wxEVT_REPLY3, vRecv.begin(), vRecv.end()); -} - -CDataStream GetStreamFromEvent(const wxCommandEvent& event) -{ - wxString strData = event.GetString(); - const char* pszBegin = strData.c_str(); - return CDataStream(pszBegin, pszBegin + event.GetInt(), SER_NETWORK); -} - - - - - - - ////////////////////////////////////////////////////////////////////////////// // // CMainFrame @@ -1180,16 +1086,6 @@ void CMainFrame::OnMouseEventsAddress(wxMouseEvent& event) event.Skip(); } -void CMainFrame::OnButtonCopy(wxCommandEvent& event) -{ - // Copy address box to clipboard - if (wxTheClipboard->Open()) - { - wxTheClipboard->SetData(new wxTextDataObject(m_textCtrlAddress->GetValue())); - wxTheClipboard->Close(); - } -} - void CMainFrame::OnButtonChange(wxCommandEvent& event) { CYourAddressDialog dialog(this, string(m_textCtrlAddress->GetValue())); @@ -1208,6 +1104,16 @@ void CMainFrame::OnButtonChange(wxCommandEvent& event) } } +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)); @@ -1228,28 +1134,6 @@ void CMainFrame::OnListItemActivated(wxListEvent& event) //pdialog->Show(); } -void CMainFrame::OnListItemActivatedProductsSent(wxListEvent& event) -{ - CProduct& product = *(CProduct*)event.GetItem().GetData(); - CEditProductDialog* pdialog = new CEditProductDialog(this); - pdialog->SetProduct(product); - pdialog->Show(); -} - -void CMainFrame::OnListItemActivatedOrdersSent(wxListEvent& event) -{ - CWalletTx& order = *(CWalletTx*)event.GetItem().GetData(); - CViewOrderDialog* pdialog = new CViewOrderDialog(this, order, false); - pdialog->Show(); -} - -void CMainFrame::OnListItemActivatedOrdersReceived(wxListEvent& event) -{ - CWalletTx& order = *(CWalletTx*)event.GetItem().GetData(); - CViewOrderDialog* pdialog = new CViewOrderDialog(this, order, true); - pdialog->Show(); -} - @@ -2525,800 +2409,6 @@ void CAddressBookDialog::OnClose(wxCloseEvent& event) -////////////////////////////////////////////////////////////////////////////// -// -// CProductsDialog -// - -bool CompareIntStringPairBestFirst(const pair& item1, const pair& item2) -{ - return (item1.first > item2.first); -} - -CProductsDialog::CProductsDialog(wxWindow* parent) : CProductsDialogBase(parent) -{ - // Init column headers - m_listCtrl->InsertColumn(0, "Title", wxLIST_FORMAT_LEFT, 200); - m_listCtrl->InsertColumn(1, "Price", wxLIST_FORMAT_LEFT, 80); - m_listCtrl->InsertColumn(2, "Seller", wxLIST_FORMAT_LEFT, 80); - m_listCtrl->InsertColumn(3, "Stars", wxLIST_FORMAT_LEFT, 50); - m_listCtrl->InsertColumn(4, "Power", wxLIST_FORMAT_LEFT, 50); - - // Tally top categories - map mapTopCategories; - CRITICAL_BLOCK(cs_mapProducts) - for (map::iterator mi = mapProducts.begin(); mi != mapProducts.end(); ++mi) - mapTopCategories[(*mi).second.mapValue["category"]]++; - - // Sort top categories - vector > vTopCategories; - for (map::iterator mi = mapTopCategories.begin(); mi != mapTopCategories.end(); ++mi) - vTopCategories.push_back(make_pair((*mi).second, (*mi).first)); - sort(vTopCategories.begin(), vTopCategories.end(), CompareIntStringPairBestFirst); - - // Fill categories combo box - int nLimit = 250; - for (vector >::iterator it = vTopCategories.begin(); it != vTopCategories.end() && nLimit-- > 0; ++it) - m_comboBoxCategory->Append((*it).second); - - // Fill window with initial search - //wxCommandEvent event; - //OnButtonSearch(event); -} - -void CProductsDialog::OnCombobox(wxCommandEvent& event) -{ - OnButtonSearch(event); -} - -bool CompareProductsBestFirst(const CProduct* p1, const CProduct* p2) -{ - return (p1->nAtoms > p2->nAtoms); -} - -void CProductsDialog::OnButtonSearch(wxCommandEvent& event) -{ - string strCategory = (string)m_comboBoxCategory->GetValue(); - string strSearch = (string)m_textCtrlSearch->GetValue(); - - // Search products - vector vProductsFound; - CRITICAL_BLOCK(cs_mapProducts) - { - for (map::iterator mi = mapProducts.begin(); mi != mapProducts.end(); ++mi) - { - CProduct& product = (*mi).second; - if (product.mapValue["category"].find(strCategory) != -1) - { - if (product.mapValue["title"].find(strSearch) != -1 || - product.mapValue["description"].find(strSearch) != -1 || - product.mapValue["seller"].find(strSearch) != -1) - { - vProductsFound.push_back(&product); - } - } - } - } - - // Sort - sort(vProductsFound.begin(), vProductsFound.end(), CompareProductsBestFirst); - - // Display - foreach(CProduct* pproduct, vProductsFound) - { - InsertLine(m_listCtrl, - pproduct->mapValue["title"], - pproduct->mapValue["price"], - pproduct->mapValue["seller"], - pproduct->mapValue["stars"], - itostr(pproduct->nAtoms)); - } -} - -void CProductsDialog::OnListItemActivated(wxListEvent& event) -{ - // Doubleclick opens product - CViewProductDialog* pdialog = new CViewProductDialog(this, m_vProduct[event.GetIndex()]); - pdialog->Show(); -} - - - - - - - -////////////////////////////////////////////////////////////////////////////// -// -// CEditProductDialog -// - -CEditProductDialog::CEditProductDialog(wxWindow* parent) : CEditProductDialogBase(parent) -{ - m_textCtrlLabel[0 ] = m_textCtrlLabel0; - m_textCtrlLabel[1 ] = m_textCtrlLabel1; - m_textCtrlLabel[2 ] = m_textCtrlLabel2; - m_textCtrlLabel[3 ] = m_textCtrlLabel3; - m_textCtrlLabel[4 ] = m_textCtrlLabel4; - m_textCtrlLabel[5 ] = m_textCtrlLabel5; - m_textCtrlLabel[6 ] = m_textCtrlLabel6; - m_textCtrlLabel[7 ] = m_textCtrlLabel7; - m_textCtrlLabel[8 ] = m_textCtrlLabel8; - m_textCtrlLabel[9 ] = m_textCtrlLabel9; - m_textCtrlLabel[10] = m_textCtrlLabel10; - m_textCtrlLabel[11] = m_textCtrlLabel11; - m_textCtrlLabel[12] = m_textCtrlLabel12; - m_textCtrlLabel[13] = m_textCtrlLabel13; - m_textCtrlLabel[14] = m_textCtrlLabel14; - m_textCtrlLabel[15] = m_textCtrlLabel15; - m_textCtrlLabel[16] = m_textCtrlLabel16; - m_textCtrlLabel[17] = m_textCtrlLabel17; - m_textCtrlLabel[18] = m_textCtrlLabel18; - m_textCtrlLabel[19] = m_textCtrlLabel19; - - m_textCtrlField[0 ] = m_textCtrlField0; - m_textCtrlField[1 ] = m_textCtrlField1; - m_textCtrlField[2 ] = m_textCtrlField2; - m_textCtrlField[3 ] = m_textCtrlField3; - m_textCtrlField[4 ] = m_textCtrlField4; - m_textCtrlField[5 ] = m_textCtrlField5; - m_textCtrlField[6 ] = m_textCtrlField6; - m_textCtrlField[7 ] = m_textCtrlField7; - m_textCtrlField[8 ] = m_textCtrlField8; - m_textCtrlField[9 ] = m_textCtrlField9; - m_textCtrlField[10] = m_textCtrlField10; - m_textCtrlField[11] = m_textCtrlField11; - m_textCtrlField[12] = m_textCtrlField12; - m_textCtrlField[13] = m_textCtrlField13; - m_textCtrlField[14] = m_textCtrlField14; - m_textCtrlField[15] = m_textCtrlField15; - m_textCtrlField[16] = m_textCtrlField16; - m_textCtrlField[17] = m_textCtrlField17; - m_textCtrlField[18] = m_textCtrlField18; - m_textCtrlField[19] = m_textCtrlField19; - - m_buttonDel[0 ] = m_buttonDel0; - m_buttonDel[1 ] = m_buttonDel1; - m_buttonDel[2 ] = m_buttonDel2; - m_buttonDel[3 ] = m_buttonDel3; - m_buttonDel[4 ] = m_buttonDel4; - m_buttonDel[5 ] = m_buttonDel5; - m_buttonDel[6 ] = m_buttonDel6; - m_buttonDel[7 ] = m_buttonDel7; - m_buttonDel[8 ] = m_buttonDel8; - m_buttonDel[9 ] = m_buttonDel9; - m_buttonDel[10] = m_buttonDel10; - m_buttonDel[11] = m_buttonDel11; - m_buttonDel[12] = m_buttonDel12; - m_buttonDel[13] = m_buttonDel13; - m_buttonDel[14] = m_buttonDel14; - m_buttonDel[15] = m_buttonDel15; - m_buttonDel[16] = m_buttonDel16; - m_buttonDel[17] = m_buttonDel17; - m_buttonDel[18] = m_buttonDel18; - m_buttonDel[19] = m_buttonDel19; - - for (int i = 1; i < FIELDS_MAX; i++) - ShowLine(i, false); - - LayoutAll(); -} - -void CEditProductDialog::LayoutAll() -{ - m_scrolledWindow->Layout(); - m_scrolledWindow->GetSizer()->Fit(m_scrolledWindow); - this->Layout(); -} - -void CEditProductDialog::ShowLine(int i, bool fShow) -{ - m_textCtrlLabel[i]->Show(fShow); - m_textCtrlField[i]->Show(fShow); - m_buttonDel[i]->Show(fShow); -} - -void CEditProductDialog::OnButtonDel0(wxCommandEvent& event) { OnButtonDel(event, 0); } -void CEditProductDialog::OnButtonDel1(wxCommandEvent& event) { OnButtonDel(event, 1); } -void CEditProductDialog::OnButtonDel2(wxCommandEvent& event) { OnButtonDel(event, 2); } -void CEditProductDialog::OnButtonDel3(wxCommandEvent& event) { OnButtonDel(event, 3); } -void CEditProductDialog::OnButtonDel4(wxCommandEvent& event) { OnButtonDel(event, 4); } -void CEditProductDialog::OnButtonDel5(wxCommandEvent& event) { OnButtonDel(event, 5); } -void CEditProductDialog::OnButtonDel6(wxCommandEvent& event) { OnButtonDel(event, 6); } -void CEditProductDialog::OnButtonDel7(wxCommandEvent& event) { OnButtonDel(event, 7); } -void CEditProductDialog::OnButtonDel8(wxCommandEvent& event) { OnButtonDel(event, 8); } -void CEditProductDialog::OnButtonDel9(wxCommandEvent& event) { OnButtonDel(event, 9); } -void CEditProductDialog::OnButtonDel10(wxCommandEvent& event) { OnButtonDel(event, 10); } -void CEditProductDialog::OnButtonDel11(wxCommandEvent& event) { OnButtonDel(event, 11); } -void CEditProductDialog::OnButtonDel12(wxCommandEvent& event) { OnButtonDel(event, 12); } -void CEditProductDialog::OnButtonDel13(wxCommandEvent& event) { OnButtonDel(event, 13); } -void CEditProductDialog::OnButtonDel14(wxCommandEvent& event) { OnButtonDel(event, 14); } -void CEditProductDialog::OnButtonDel15(wxCommandEvent& event) { OnButtonDel(event, 15); } -void CEditProductDialog::OnButtonDel16(wxCommandEvent& event) { OnButtonDel(event, 16); } -void CEditProductDialog::OnButtonDel17(wxCommandEvent& event) { OnButtonDel(event, 17); } -void CEditProductDialog::OnButtonDel18(wxCommandEvent& event) { OnButtonDel(event, 18); } -void CEditProductDialog::OnButtonDel19(wxCommandEvent& event) { OnButtonDel(event, 19); } - -void CEditProductDialog::OnButtonDel(wxCommandEvent& event, int n) -{ - Freeze(); - int x, y; - m_scrolledWindow->GetViewStart(&x, &y); - int i; - for (i = n; i < FIELDS_MAX-1; i++) - { - m_textCtrlLabel[i]->SetValue(m_textCtrlLabel[i+1]->GetValue()); - m_textCtrlField[i]->SetValue(m_textCtrlField[i+1]->GetValue()); - if (!m_buttonDel[i+1]->IsShown()) - break; - } - m_textCtrlLabel[i]->SetValue(""); - m_textCtrlField[i]->SetValue(""); - ShowLine(i, false); - m_buttonAddField->Enable(true); - LayoutAll(); - m_scrolledWindow->Scroll(0, y); - Thaw(); -} - -void CEditProductDialog::OnButtonAddField(wxCommandEvent& event) -{ - for (int i = 0; i < FIELDS_MAX; i++) - { - if (!m_buttonDel[i]->IsShown()) - { - Freeze(); - ShowLine(i, true); - if (i == FIELDS_MAX-1) - m_buttonAddField->Enable(false); - LayoutAll(); - m_scrolledWindow->Scroll(0, 99999); - Thaw(); - break; - } - } -} - -void AddToMyProducts(CProduct product) -{ - CProduct& productInsert = mapMyProducts[product.GetHash()]; - productInsert = product; - //InsertLine(pframeMain->m_listCtrlProductsSent, &productInsert, - // product.mapValue["category"], - // product.mapValue["title"].substr(0, 100), - // product.mapValue["description"].substr(0, 100), - // product.mapValue["price"], - // ""); -} - -void CEditProductDialog::OnButtonSend(wxCommandEvent& event) -{ - CProduct product; - GetProduct(product); - - // Sign the detailed product - product.vchPubKeyFrom = keyUser.GetPubKey(); - if (!keyUser.Sign(product.GetSigHash(), product.vchSig)) - { - wxMessageBox("Error digitally signing the product "); - return; - } - - // Save detailed product - AddToMyProducts(product); - - // Strip down to summary product - product.mapDetails.clear(); - product.vOrderForm.clear(); - - // Sign the summary product - if (!keyUser.Sign(product.GetSigHash(), product.vchSig)) - { - wxMessageBox("Error digitally signing the product "); - return; - } - - // Verify - if (!product.CheckProduct()) - { - wxMessageBox("Errors found in product "); - return; - } - - // Broadcast - AdvertStartPublish(pnodeLocalHost, MSG_PRODUCT, 0, product); - - Destroy(); -} - -void CEditProductDialog::OnButtonPreview(wxCommandEvent& event) -{ - CProduct product; - GetProduct(product); - CViewProductDialog* pdialog = new CViewProductDialog(this, product); - pdialog->Show(); -} - -void CEditProductDialog::OnButtonCancel(wxCommandEvent& event) -{ - Destroy(); -} - -void CEditProductDialog::SetProduct(const CProduct& productIn) -{ - CProduct product = productIn; - - m_comboBoxCategory->SetValue(product.mapValue["category"]); - m_textCtrlTitle->SetValue(product.mapValue["title"]); - m_textCtrlPrice->SetValue(product.mapValue["price"]); - m_textCtrlDescription->SetValue(product.mapValue["description"]); - m_textCtrlInstructions->SetValue(product.mapValue["instructions"]); - - for (int i = 0; i < FIELDS_MAX; i++) - { - bool fUsed = i < product.vOrderForm.size(); - m_buttonDel[i]->Show(fUsed); - m_textCtrlLabel[i]->Show(fUsed); - m_textCtrlField[i]->Show(fUsed); - if (!fUsed) - continue; - - m_textCtrlLabel[i]->SetValue(product.vOrderForm[i].first); - string strControl = product.vOrderForm[i].second; - if (strControl.substr(0, 5) == "text=") - m_textCtrlField[i]->SetValue(""); - else if (strControl.substr(0, 7) == "choice=") - m_textCtrlField[i]->SetValue(strControl.substr(7)); - else - m_textCtrlField[i]->SetValue(strControl); - } -} - -void CEditProductDialog::GetProduct(CProduct& product) -{ - // map mapValue; - // vector > vOrderForm; - - product.mapValue["category"] = m_comboBoxCategory->GetValue().Trim(); - product.mapValue["title"] = m_textCtrlTitle->GetValue().Trim(); - product.mapValue["price"] = m_textCtrlPrice->GetValue().Trim(); - product.mapValue["description"] = m_textCtrlDescription->GetValue().Trim(); - product.mapValue["instructions"] = m_textCtrlInstructions->GetValue().Trim(); - - for (int i = 0; i < FIELDS_MAX; i++) - { - if (m_buttonDel[i]->IsShown()) - { - string strLabel = (string)m_textCtrlLabel[i]->GetValue().Trim(); - string strControl = (string)m_textCtrlField[i]->GetValue(); - if (strControl.empty()) - strControl = "text="; - else - strControl = "choice=" + strControl; - product.vOrderForm.push_back(make_pair(strLabel, strControl)); - } - } -} - - - - - - - -////////////////////////////////////////////////////////////////////////////// -// -// CViewProductDialog -// - -CViewProductDialog::CViewProductDialog(wxWindow* parent, const CProduct& productIn) : CViewProductDialogBase(parent) -{ - Connect(wxEVT_REPLY1, wxCommandEventHandler(CViewProductDialog::OnReply1), NULL, this); - AddCallbackAvailable(GetEventHandler()); - - // Fill display with product summary while waiting for details - product = productIn; - UpdateProductDisplay(false); - - m_buttonBack->Enable(false); - m_buttonNext->Enable(!product.vOrderForm.empty()); - m_htmlWinReviews->Show(true); - m_scrolledWindow->Show(false); - this->Layout(); - - // Request details from seller - CreateThread(ThreadRequestProductDetails, new pair(product, GetEventHandler())); -} - -CViewProductDialog::~CViewProductDialog() -{ - RemoveCallbackAvailable(GetEventHandler()); -} - -void ThreadRequestProductDetails(void* parg) -{ - // Extract parameters - pair* pitem = (pair*)parg; - CProduct product = pitem->first; - wxEvtHandler* pevthandler = pitem->second; - delete pitem; - - // Connect to seller - CNode* pnode = ConnectNode(product.addr, 5 * 60); - if (!pnode) - { - CDataStream ssEmpty; - AddPendingReplyEvent1(pevthandler, ssEmpty); - return; - } - - // Request detailed product, with response going to OnReply1 via dialog's event handler - pnode->PushRequest("getdetails", product.GetHash(), AddPendingReplyEvent1, (void*)pevthandler); -} - -void CViewProductDialog::OnReply1(wxCommandEvent& event) -{ - CDataStream ss = GetStreamFromEvent(event); - if (ss.empty()) - { - product.mapValue["description"] = "-- CAN'T CONNECT TO SELLER --\n"; - UpdateProductDisplay(true); - return; - } - - int nRet; - CProduct product2; - try - { - ss >> nRet; - if (nRet > 0) - throw false; - ss >> product2; - if (product2.GetHash() != product.GetHash()) - throw false; - if (!product2.CheckSignature()) - throw false; - } - catch (...) - { - product.mapValue["description"] = "-- INVALID RESPONSE --\n"; - UpdateProductDisplay(true); - return; - } - - product = product2; - UpdateProductDisplay(true); -} - -bool CompareReviewsBestFirst(const CReview* p1, const CReview* p2) -{ - return (p1->nAtoms > p2->nAtoms); -} - -void CViewProductDialog::UpdateProductDisplay(bool fDetails) -{ - // Product and reviews - string strHTML; - strHTML.reserve(4000); - strHTML += "\n" - "\n" - "\n" - "\n" - "\n"; - strHTML += "Category: " + HtmlEscape(product.mapValue["category"]) + "
\n"; - strHTML += "Title: " + HtmlEscape(product.mapValue["title"]) + "
\n"; - strHTML += "Price: " + HtmlEscape(product.mapValue["price"]) + "
\n"; - - if (!fDetails) - strHTML += "Loading details...
\n
\n"; - else - strHTML += HtmlEscape(product.mapValue["description"], true) + "
\n
\n"; - - strHTML += "Reviews:
\n
\n"; - - if (!product.vchPubKeyFrom.empty()) - { - CReviewDB reviewdb("r"); - - // Get reviews - vector vReviews; - reviewdb.ReadReviews(product.GetUserHash(), vReviews); - - // Get reviewer's number of atoms - vector vSortedReviews; - vSortedReviews.reserve(vReviews.size()); - for (vector::reverse_iterator it = vReviews.rbegin(); it != vReviews.rend(); ++it) - { - CReview& review = *it; - CUser user; - reviewdb.ReadUser(review.GetUserHash(), user); - review.nAtoms = user.GetAtomCount(); - vSortedReviews.push_back(&review); - } - - reviewdb.Close(); - - // Sort - stable_sort(vSortedReviews.begin(), vSortedReviews.end(), CompareReviewsBestFirst); - - // Format reviews - foreach(CReview* preview, vSortedReviews) - { - CReview& review = *preview; - int nStars = atoi(review.mapValue["stars"].c_str()); - if (nStars < 1 || nStars > 5) - continue; - - strHTML += "" + itostr(nStars) + (nStars == 1 ? " star" : " stars") + ""; - strHTML += "     "; - strHTML += DateStr(atoi64(review.mapValue["date"])) + "
\n"; - strHTML += HtmlEscape(review.mapValue["review"], true); - strHTML += "
\n
\n"; - } - } - - strHTML += "\n\n"; - - // Shrink capacity to fit - string(strHTML.begin(), strHTML.end()).swap(strHTML); - - m_htmlWinReviews->SetPage(strHTML); - - ///// need to find some other indicator to use so can allow empty order form - if (product.vOrderForm.empty()) - return; - - // Order form - m_staticTextInstructions->SetLabel(product.mapValue["instructions"]); - for (int i = 0; i < FIELDS_MAX; i++) - { - m_staticTextLabel[i] = NULL; - m_textCtrlField[i] = NULL; - m_choiceField[i] = NULL; - } - - // Construct flexgridsizer - wxBoxSizer* bSizer21 = (wxBoxSizer*)m_scrolledWindow->GetSizer(); - wxFlexGridSizer* fgSizer; - fgSizer = new wxFlexGridSizer(0, 2, 0, 0); - fgSizer->AddGrowableCol(1); - fgSizer->SetFlexibleDirection(wxBOTH); - fgSizer->SetNonFlexibleGrowMode(wxFLEX_GROWMODE_SPECIFIED); - - // Construct order form fields - wxWindow* windowLast = NULL; - for (int i = 0; i < product.vOrderForm.size(); i++) - { - string strLabel = product.vOrderForm[i].first; - string strControl = product.vOrderForm[i].second; - - if (strLabel.size() < 20) - strLabel.insert(strLabel.begin(), 20 - strLabel.size(), ' '); - - m_staticTextLabel[i] = new wxStaticText(m_scrolledWindow, wxID_ANY, strLabel, wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT); - m_staticTextLabel[i]->Wrap(-1); - fgSizer->Add(m_staticTextLabel[i], 0, wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxALL, 5); - - if (strControl.substr(0, 5) == "text=") - { - m_textCtrlField[i] = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0); - fgSizer->Add(m_textCtrlField[i], 1, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5); - windowLast = m_textCtrlField[i]; - } - else if (strControl.substr(0, 7) == "choice=") - { - vector vChoices; - ParseString(strControl.substr(7), ',', vChoices); - - wxArrayString arraystring; - foreach(const string& str, vChoices) - arraystring.Add(str); - - m_choiceField[i] = new wxChoice(m_scrolledWindow, wxID_ANY, wxDefaultPosition, wxDefaultSize, arraystring, 0); - fgSizer->Add(m_choiceField[i], 0, wxALL|wxALIGN_CENTER_VERTICAL, 5); - windowLast = m_choiceField[i]; - } - else - { - m_textCtrlField[i] = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0); - fgSizer->Add(m_textCtrlField[i], 1, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5); - m_staticTextLabel[i]->Show(false); - m_textCtrlField[i]->Show(false); - } - } - - // Insert after instructions and before submit/cancel buttons - bSizer21->Insert(2, fgSizer, 0, wxEXPAND|wxRIGHT|wxLEFT, 5); - m_scrolledWindow->Layout(); - bSizer21->Fit(m_scrolledWindow); - this->Layout(); - - // Fixup the tab order - m_buttonSubmitForm->MoveAfterInTabOrder(windowLast); - m_buttonCancelForm->MoveAfterInTabOrder(m_buttonSubmitForm); - //m_buttonBack->MoveAfterInTabOrder(m_buttonCancelForm); - //m_buttonNext->MoveAfterInTabOrder(m_buttonBack); - //m_buttonCancel->MoveAfterInTabOrder(m_buttonNext); - this->Layout(); -} - -void CViewProductDialog::GetOrder(CWalletTx& wtx) -{ - wtx.SetNull(); - for (int i = 0; i < product.vOrderForm.size(); i++) - { - string strValue; - if (m_textCtrlField[i]) - strValue = m_textCtrlField[i]->GetValue().Trim(); - else - strValue = m_choiceField[i]->GetStringSelection(); - wtx.vOrderForm.push_back(make_pair(m_staticTextLabel[i]->GetLabel(), strValue)); - } -} - -void CViewProductDialog::OnButtonSubmitForm(wxCommandEvent& event) -{ - m_buttonSubmitForm->Enable(false); - m_buttonCancelForm->Enable(false); - - CWalletTx wtx; - GetOrder(wtx); - - CSendingDialog* pdialog = new CSendingDialog(this, product.addr, atoi64(product.mapValue["price"]), wtx); - if (!pdialog->ShowModal()) - { - m_buttonSubmitForm->Enable(true); - m_buttonCancelForm->Enable(true); - return; - } -} - -void CViewProductDialog::OnButtonCancelForm(wxCommandEvent& event) -{ - Destroy(); -} - -void CViewProductDialog::OnButtonBack(wxCommandEvent& event) -{ - Freeze(); - m_htmlWinReviews->Show(true); - m_scrolledWindow->Show(false); - m_buttonBack->Enable(false); - m_buttonNext->Enable(!product.vOrderForm.empty()); - this->Layout(); - Thaw(); -} - -void CViewProductDialog::OnButtonNext(wxCommandEvent& event) -{ - if (!product.vOrderForm.empty()) - { - Freeze(); - m_htmlWinReviews->Show(false); - m_scrolledWindow->Show(true); - m_buttonBack->Enable(true); - m_buttonNext->Enable(false); - this->Layout(); - Thaw(); - } -} - -void CViewProductDialog::OnButtonCancel(wxCommandEvent& event) -{ - Destroy(); -} - - - - - - - -////////////////////////////////////////////////////////////////////////////// -// -// CViewOrderDialog -// - -CViewOrderDialog::CViewOrderDialog(wxWindow* parent, CWalletTx order, bool fReceived) : CViewOrderDialogBase(parent) -{ - int64 nPrice = (fReceived ? order.GetCredit() : order.GetDebit()); - - string strHTML; - strHTML.reserve(4000); - strHTML += "\n" - "\n" - "\n" - "\n" - "\n"; - strHTML += "Time: " + HtmlEscape(DateTimeStr(order.nTimeReceived)) + "
\n"; - strHTML += "Price: " + HtmlEscape(FormatMoney(nPrice)) + "
\n"; - strHTML += "Status: " + HtmlEscape(FormatTxStatus(order)) + "
\n"; - - strHTML += "\n"; - for (int i = 0; i < order.vOrderForm.size(); i++) - { - strHTML += " "; - strHTML += "\n"; - } - strHTML += "
" + HtmlEscape(order.vOrderForm[i].first) + ":" + HtmlEscape(order.vOrderForm[i].second) + "
\n"; - - strHTML += "\n\n"; - - // Shrink capacity to fit - // (strings are ref counted, so it may live on in SetPage) - string(strHTML.begin(), strHTML.end()).swap(strHTML); - - m_htmlWin->SetPage(strHTML); -} - -void CViewOrderDialog::OnButtonOK(wxCommandEvent& event) -{ - Destroy(); -} - - - - - - - -////////////////////////////////////////////////////////////////////////////// -// -// CEditReviewDialog -// - -CEditReviewDialog::CEditReviewDialog(wxWindow* parent) : CEditReviewDialogBase(parent) -{ -} - -void CEditReviewDialog::OnButtonSubmit(wxCommandEvent& event) -{ - if (m_choiceStars->GetSelection() == -1) - { - wxMessageBox("Please select a rating "); - return; - } - - CReview review; - GetReview(review); - - // Sign the review - review.vchPubKeyFrom = keyUser.GetPubKey(); - if (!keyUser.Sign(review.GetSigHash(), review.vchSig)) - { - wxMessageBox("Unable to digitally sign the review "); - return; - } - - // Broadcast - if (!review.AcceptReview()) - { - wxMessageBox("Save failed "); - return; - } - RelayMessage(CInv(MSG_REVIEW, review.GetHash()), review); - - Destroy(); -} - -void CEditReviewDialog::OnButtonCancel(wxCommandEvent& event) -{ - Destroy(); -} - -void CEditReviewDialog::GetReview(CReview& review) -{ - review.mapValue["time"] = i64tostr(GetAdjustedTime()); - review.mapValue["stars"] = itostr(m_choiceStars->GetSelection()+1); - review.mapValue["review"] = m_textCtrlReview->GetValue(); -} - - - - - - - ////////////////////////////////////////////////////////////////////////////// // // CMyTaskBarIcon diff --git a/ui.h b/ui.h index 43e056596a..da1ada7def 100644 --- a/ui.h +++ b/ui.h @@ -6,12 +6,6 @@ DECLARE_EVENT_TYPE(wxEVT_UITHREADCALL, -1) -DECLARE_EVENT_TYPE(wxEVT_REPLY1, -1) -DECLARE_EVENT_TYPE(wxEVT_REPLY2, -1) -DECLARE_EVENT_TYPE(wxEVT_REPLY3, -1) - - - extern map mapArgs; @@ -57,8 +51,8 @@ protected: void OnButtonAddressBook(wxCommandEvent& event); void OnSetFocusAddress(wxFocusEvent& event); void OnMouseEventsAddress(wxMouseEvent& event); - void OnButtonCopy(wxCommandEvent& event); void OnButtonChange(wxCommandEvent& event); + void OnButtonCopy(wxCommandEvent& event); void OnListColBeginDrag(wxListEvent& event); void OnListItemActivated(wxListEvent& event); void OnListItemActivatedProductsSent(wxListEvent& event); @@ -263,138 +257,6 @@ public: -class CProductsDialog : public CProductsDialogBase -{ -protected: - // Event handlers - void OnKeyDown(wxKeyEvent& event) { HandleCtrlA(event); } - void OnCombobox(wxCommandEvent& event); - void OnButtonSearch(wxCommandEvent& event); - void OnListItemActivated(wxListEvent& event); - -public: - /** Constructor */ - CProductsDialog(wxWindow* parent); - - // Custom - vector m_vProduct; -}; - - - -class CEditProductDialog : public CEditProductDialogBase -{ -protected: - // Event handlers - void OnKeyDown(wxKeyEvent& event) { HandleCtrlA(event); } - void OnButtonDel0(wxCommandEvent& event); - void OnButtonDel1(wxCommandEvent& event); - void OnButtonDel2(wxCommandEvent& event); - void OnButtonDel3(wxCommandEvent& event); - void OnButtonDel4(wxCommandEvent& event); - void OnButtonDel5(wxCommandEvent& event); - void OnButtonDel6(wxCommandEvent& event); - void OnButtonDel7(wxCommandEvent& event); - void OnButtonDel8(wxCommandEvent& event); - void OnButtonDel9(wxCommandEvent& event); - void OnButtonDel10(wxCommandEvent& event); - void OnButtonDel11(wxCommandEvent& event); - void OnButtonDel12(wxCommandEvent& event); - void OnButtonDel13(wxCommandEvent& event); - void OnButtonDel14(wxCommandEvent& event); - void OnButtonDel15(wxCommandEvent& event); - void OnButtonDel16(wxCommandEvent& event); - void OnButtonDel17(wxCommandEvent& event); - void OnButtonDel18(wxCommandEvent& event); - void OnButtonDel19(wxCommandEvent& event); - void OnButtonAddField(wxCommandEvent& event); - void OnButtonSend(wxCommandEvent& event); - void OnButtonPreview(wxCommandEvent& event); - void OnButtonCancel(wxCommandEvent& event); - -public: - /** Constructor */ - CEditProductDialog(wxWindow* parent); - - // Custom - enum { FIELDS_MAX = 20 }; - wxTextCtrl* m_textCtrlLabel[FIELDS_MAX]; - wxTextCtrl* m_textCtrlField[FIELDS_MAX]; - wxButton* m_buttonDel[FIELDS_MAX]; - - void LayoutAll(); - void ShowLine(int i, bool fShow=true); - void OnButtonDel(wxCommandEvent& event, int n); - void SetProduct(const CProduct& productIn); - void GetProduct(CProduct& product); - -}; - - - -class CViewProductDialog : public CViewProductDialogBase -{ -protected: - // Event handlers - void OnButtonSubmitForm(wxCommandEvent& event); - void OnButtonCancelForm(wxCommandEvent& event); - void OnButtonBack(wxCommandEvent& event); - void OnButtonNext(wxCommandEvent& event); - void OnButtonCancel(wxCommandEvent& event); - -public: - /** Constructor */ - CViewProductDialog(wxWindow* parent, const CProduct& productIn); - ~CViewProductDialog(); - - // Custom - CProduct product; - enum { FIELDS_MAX = 20 }; - wxStaticText* m_staticTextLabel[FIELDS_MAX]; - wxTextCtrl* m_textCtrlField[FIELDS_MAX]; - wxChoice* m_choiceField[FIELDS_MAX]; - - void GetOrder(CWalletTx& order); - void UpdateProductDisplay(bool fDetails); - void OnReply1(wxCommandEvent& event); -}; - - - -class CViewOrderDialog : public CViewOrderDialogBase -{ -protected: - // Event handlers - void OnButtonOK(wxCommandEvent& event); - -public: - /** Constructor */ - CViewOrderDialog(wxWindow* parent, CWalletTx order, bool fReceived); - - // Custom - bool fReceived; -}; - - - -class CEditReviewDialog : public CEditReviewDialogBase -{ -protected: - // Event handlers - void OnKeyDown(wxKeyEvent& event) { HandleCtrlA(event); } - void OnButtonSubmit(wxCommandEvent& event); - void OnButtonCancel(wxCommandEvent& event); - -public: - /** Constructor */ - CEditReviewDialog(wxWindow* parent); - - // Custom - void GetReview(CReview& review); -}; - - - class CGetTextFromUserDialog : public CGetTextFromUserDialogBase { protected: @@ -430,6 +292,8 @@ public: m_textCtrl2->SetValue(strValue2); SetSize(wxDefaultCoord, 180); } + if (!fWindows) + SetSize(1.14 * GetSize().GetWidth(), 1.14 * GetSize().GetHeight()); } // Custom diff --git a/uibase.cpp b/uibase.cpp index 08c025facb..03bd791226 100644 --- a/uibase.cpp +++ b/uibase.cpp @@ -27,39 +27,39 @@ CMainFrameBase::CMainFrameBase( wxWindow* parent, wxWindowID id, const wxString& m_menuFile = new wxMenu(); wxMenuItem* m_menuFileExit; - m_menuFileExit = new wxMenuItem( m_menuFile, wxID_ANY, wxString( wxT("E&xit") ) , wxEmptyString, wxITEM_NORMAL ); + m_menuFileExit = new wxMenuItem( m_menuFile, wxID_ANY, wxString( _("E&xit") ) , wxEmptyString, wxITEM_NORMAL ); m_menuFile->Append( m_menuFileExit ); - m_menubar->Append( m_menuFile, wxT("&File") ); + m_menubar->Append( m_menuFile, _("&File") ); m_menuView = new wxMenu(); wxMenuItem* m_menuViewShowGenerated; - m_menuViewShowGenerated = new wxMenuItem( m_menuView, wxID_VIEWSHOWGENERATED, wxString( wxT("&Show Generated Coins") ) , wxEmptyString, wxITEM_CHECK ); + m_menuViewShowGenerated = new wxMenuItem( m_menuView, wxID_VIEWSHOWGENERATED, wxString( _("&Show Generated Coins") ) , wxEmptyString, wxITEM_CHECK ); m_menuView->Append( m_menuViewShowGenerated ); - m_menubar->Append( m_menuView, wxT("&View") ); + m_menubar->Append( m_menuView, _("&View") ); m_menuOptions = new wxMenu(); wxMenuItem* m_menuOptionsGenerateBitcoins; - m_menuOptionsGenerateBitcoins = new wxMenuItem( m_menuOptions, wxID_OPTIONSGENERATEBITCOINS, wxString( wxT("&Generate Coins") ) , wxEmptyString, wxITEM_CHECK ); + m_menuOptionsGenerateBitcoins = new wxMenuItem( m_menuOptions, wxID_OPTIONSGENERATEBITCOINS, wxString( _("&Generate Coins") ) , wxEmptyString, wxITEM_CHECK ); m_menuOptions->Append( m_menuOptionsGenerateBitcoins ); wxMenuItem* m_menuOptionsChangeYourAddress; - m_menuOptionsChangeYourAddress = new wxMenuItem( m_menuOptions, wxID_ANY, wxString( wxT("&Change Your Address...") ) , wxEmptyString, wxITEM_NORMAL ); + m_menuOptionsChangeYourAddress = new wxMenuItem( m_menuOptions, wxID_ANY, wxString( _("&Change Your Address...") ) , wxEmptyString, wxITEM_NORMAL ); m_menuOptions->Append( m_menuOptionsChangeYourAddress ); wxMenuItem* m_menuOptionsOptions; - m_menuOptionsOptions = new wxMenuItem( m_menuOptions, wxID_MENUOPTIONSOPTIONS, wxString( wxT("&Options...") ) , wxEmptyString, wxITEM_NORMAL ); + m_menuOptionsOptions = new wxMenuItem( m_menuOptions, wxID_MENUOPTIONSOPTIONS, wxString( _("&Options...") ) , wxEmptyString, wxITEM_NORMAL ); m_menuOptions->Append( m_menuOptionsOptions ); - m_menubar->Append( m_menuOptions, wxT("&Options") ); + m_menubar->Append( m_menuOptions, _("&Options") ); m_menuHelp = new wxMenu(); wxMenuItem* m_menuHelpAbout; - m_menuHelpAbout = new wxMenuItem( m_menuHelp, wxID_ANY, wxString( wxT("&About...") ) , wxEmptyString, wxITEM_NORMAL ); + m_menuHelpAbout = new wxMenuItem( m_menuHelp, wxID_ANY, wxString( _("&About...") ) , wxEmptyString, wxITEM_NORMAL ); m_menuHelp->Append( m_menuHelpAbout ); - m_menubar->Append( m_menuHelp, wxT("&Help") ); + m_menubar->Append( m_menuHelp, _("&Help") ); this->SetMenuBar( m_menubar ); @@ -68,8 +68,8 @@ CMainFrameBase::CMainFrameBase( wxWindow* parent, wxWindowID id, const wxString& m_toolBar->SetToolSeparation( 1 ); m_toolBar->SetFont( wxFont( wxNORMAL_FONT->GetPointSize(), 70, 90, 90, false, wxEmptyString ) ); - m_toolBar->AddTool( wxID_BUTTONSEND, wxT("&Send Coins"), wxBitmap( send20_xpm ), wxNullBitmap, wxITEM_NORMAL, wxEmptyString, wxEmptyString ); - m_toolBar->AddTool( wxID_BUTTONRECEIVE, wxT("&Address Book"), wxBitmap( addressbook20_xpm ), wxNullBitmap, wxITEM_NORMAL, wxEmptyString, 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 ); @@ -84,7 +84,7 @@ CMainFrameBase::CMainFrameBase( wxWindow* parent, wxWindowID id, const wxString& wxBoxSizer* bSizer85; bSizer85 = new wxBoxSizer( wxHORIZONTAL ); - m_staticText32 = new wxStaticText( this, wxID_ANY, wxT("Your Bitcoin Address:"), wxDefaultPosition, wxDefaultSize, 0 ); + 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 ); @@ -93,13 +93,13 @@ CMainFrameBase::CMainFrameBase( wxWindow* parent, wxWindowID id, const wxString& bSizer85->Add( m_textCtrlAddress, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 ); - m_buttonCopy = new wxButton( this, wxID_BUTTONCOPY, wxT(" &Copy to Clipboard "), wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT ); - bSizer85->Add( m_buttonCopy, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 5 ); + m_buttonNew = new wxButton( this, wxID_BUTTONCHANGE, _("&New..."), wxDefaultPosition, wxDefaultSize, 0 ); + m_buttonNew->Hide(); - m_button91 = new wxButton( this, wxID_BUTTONCHANGE, wxT("C&hange..."), wxDefaultPosition, wxDefaultSize, 0 ); - m_button91->Hide(); + bSizer85->Add( m_buttonNew, 0, wxRIGHT, 5 ); - bSizer85->Add( m_button91, 0, wxRIGHT, 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 ); @@ -113,7 +113,7 @@ CMainFrameBase::CMainFrameBase( wxWindow* parent, wxWindowID id, const wxString& wxBoxSizer* bSizer66; bSizer66 = new wxBoxSizer( wxHORIZONTAL ); - m_staticText41 = new wxStaticText( m_panel14, wxID_ANY, wxT("Balance:"), wxDefaultPosition, wxSize( -1,15 ), 0 ); + m_staticText41 = new wxStaticText( m_panel14, wxID_ANY, _("Balance:"), wxDefaultPosition, wxSize( -1,15 ), 0 ); m_staticText41->Wrap( -1 ); bSizer66->Add( m_staticText41, 0, wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxLEFT, 5 ); @@ -132,7 +132,7 @@ CMainFrameBase::CMainFrameBase( wxWindow* parent, wxWindowID id, const wxString& bSizer3->Add( 0, 0, 0, wxEXPAND, 5 ); - wxString m_choiceFilterChoices[] = { wxT(" All"), wxT(" Sent"), wxT(" Received"), wxT(" In Progress") }; + 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 ); @@ -191,8 +191,8 @@ CMainFrameBase::CMainFrameBase( wxWindow* parent, wxWindowID id, const wxString& 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::OnButtonChange ), NULL, this ); m_buttonCopy->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CMainFrameBase::OnButtonCopy ), NULL, this ); - m_button91->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CMainFrameBase::OnButtonChange ), NULL, this ); m_listCtrl->Connect( wxEVT_COMMAND_LIST_COL_BEGIN_DRAG, wxListEventHandler( CMainFrameBase::OnListColBeginDrag ), NULL, this ); m_listCtrl->Connect( wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler( CMainFrameBase::OnListItemActivated ), NULL, this ); m_listCtrl->Connect( wxEVT_PAINT, wxPaintEventHandler( CMainFrameBase::OnPaintListCtrl ), NULL, this ); @@ -243,8 +243,8 @@ CMainFrameBase::~CMainFrameBase() 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::OnButtonChange ), NULL, this ); m_buttonCopy->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CMainFrameBase::OnButtonCopy ), NULL, this ); - m_button91->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CMainFrameBase::OnButtonChange ), NULL, this ); m_listCtrl->Disconnect( wxEVT_COMMAND_LIST_COL_BEGIN_DRAG, wxListEventHandler( CMainFrameBase::OnListColBeginDrag ), NULL, this ); m_listCtrl->Disconnect( wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler( CMainFrameBase::OnListItemActivated ), NULL, this ); m_listCtrl->Disconnect( wxEVT_PAINT, wxPaintEventHandler( CMainFrameBase::OnPaintListCtrl ), NULL, this ); @@ -268,7 +268,7 @@ CTxDetailsDialogBase::CTxDetailsDialogBase( wxWindow* parent, wxWindowID id, con wxBoxSizer* bSizer65; bSizer65 = new wxBoxSizer( wxHORIZONTAL ); - m_buttonOK = new wxButton( this, wxID_OK, wxT("OK"), wxDefaultPosition, wxSize( -1,-1 ), 0 ); + 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 ); @@ -311,7 +311,7 @@ COptionsDialogBase::COptionsDialogBase( wxWindow* parent, wxWindowID id, const w bSizer69->Add( 0, 16, 0, wxEXPAND, 5 ); - m_staticText32 = new wxStaticText( m_panelMain, wxID_ANY, wxT("Optional transaction fee you give to the nodes that process your transactions."), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticText32 = new wxStaticText( m_panelMain, wxID_ANY, _("Optional transaction fee you give to the nodes that process your transactions."), wxDefaultPosition, wxDefaultSize, 0 ); m_staticText32->Wrap( -1 ); m_staticText32->Hide(); @@ -320,7 +320,7 @@ COptionsDialogBase::COptionsDialogBase( wxWindow* parent, wxWindowID id, const w wxBoxSizer* bSizer56; bSizer56 = new wxBoxSizer( wxHORIZONTAL ); - m_staticText31 = new wxStaticText( m_panelMain, wxID_ANY, wxT("Transaction fee:"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticText31 = new wxStaticText( m_panelMain, wxID_ANY, _("Transaction fee:"), wxDefaultPosition, wxDefaultSize, 0 ); m_staticText31->Wrap( -1 ); m_staticText31->Hide(); @@ -336,35 +336,35 @@ COptionsDialogBase::COptionsDialogBase( wxWindow* parent, wxWindowID id, const w wxBoxSizer* bSizer71; bSizer71 = new wxBoxSizer( wxHORIZONTAL ); - m_checkBoxLimitProcessors = new wxCheckBox( m_panelMain, wxID_ANY, wxT("&Limit coin generation to"), wxDefaultPosition, wxDefaultSize, 0 ); + m_checkBoxLimitProcessors = new wxCheckBox( m_panelMain, wxID_ANY, _("&Limit coin generation to"), wxDefaultPosition, wxDefaultSize, 0 ); bSizer71->Add( m_checkBoxLimitProcessors, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 ); m_spinCtrlLimitProcessors = new wxSpinCtrl( m_panelMain, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize( 48,-1 ), wxSP_ARROW_KEYS, 1, 999, 1 ); bSizer71->Add( m_spinCtrlLimitProcessors, 0, wxALIGN_CENTER_VERTICAL, 5 ); - m_staticText35 = new wxStaticText( m_panelMain, wxID_ANY, wxT("processors"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticText35 = new wxStaticText( m_panelMain, wxID_ANY, _("processors"), wxDefaultPosition, wxDefaultSize, 0 ); m_staticText35->Wrap( -1 ); bSizer71->Add( m_staticText35, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 ); bSizer69->Add( bSizer71, 0, 0, 5 ); - m_checkBoxStartOnSystemStartup = new wxCheckBox( m_panelMain, wxID_ANY, wxT("&Start Bitcoin on system startup"), wxDefaultPosition, wxDefaultSize, 0 ); + 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, wxT("&Minimize to the tray instead of the taskbar"), wxDefaultPosition, wxDefaultSize, 0 ); + 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_checkBoxMinimizeOnClose = new wxCheckBox( m_panelMain, wxID_ANY, wxT("M&inimize to the tray on close"), wxDefaultPosition, wxDefaultSize, 0 ); + 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, wxT("&Connect through socks4 proxy: "), wxDefaultPosition, wxDefaultSize, 0 ); + 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 ); @@ -376,7 +376,7 @@ COptionsDialogBase::COptionsDialogBase( wxWindow* parent, wxWindowID id, const w bSizer103->Add( 18, 0, 0, 0, 5 ); - m_staticTextProxyIP = new wxStaticText( m_panelMain, wxID_ANY, wxT("Proxy &IP:"), wxDefaultPosition, wxDefaultSize, 0 ); + 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 ); @@ -384,7 +384,7 @@ COptionsDialogBase::COptionsDialogBase( wxWindow* parent, wxWindowID id, const w m_textCtrlProxyIP->SetMaxLength( 15 ); bSizer103->Add( m_textCtrlProxyIP, 0, wxALIGN_CENTER_VERTICAL, 5 ); - m_staticTextProxyPort = new wxStaticText( m_panelMain, wxID_ANY, wxT(" &Port:"), wxDefaultPosition, wxDefaultSize, 0 ); + 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 ); @@ -406,19 +406,19 @@ COptionsDialogBase::COptionsDialogBase( wxWindow* parent, wxWindowID id, const w bSizer64->Add( 0, 16, 0, wxEXPAND, 5 ); - m_staticText321 = new wxStaticText( m_panelTest2, wxID_ANY, wxT("Test panel 2 for future expansion"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticText321 = new wxStaticText( m_panelTest2, wxID_ANY, _("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, wxT("Let's not start multiple pages until the first page is filled up"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticText69 = new wxStaticText( m_panelTest2, wxID_ANY, _("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_staticText70 = new wxStaticText( m_panelTest2, wxID_ANY, wxT("MyLabel"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticText70 = new wxStaticText( m_panelTest2, wxID_ANY, _("MyLabel"), wxDefaultPosition, wxDefaultSize, 0 ); m_staticText70->Wrap( -1 ); bSizer64->Add( m_staticText70, 0, wxALL, 5 ); - m_staticText71 = new wxStaticText( m_panelTest2, wxID_ANY, wxT("MyLabel"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticText71 = new wxStaticText( m_panelTest2, wxID_ANY, _("MyLabel"), wxDefaultPosition, wxDefaultSize, 0 ); m_staticText71->Wrap( -1 ); bSizer64->Add( m_staticText71, 0, wxALL, 5 ); @@ -437,13 +437,13 @@ COptionsDialogBase::COptionsDialogBase( wxWindow* parent, wxWindowID id, const w wxBoxSizer* bSizer58; bSizer58 = new wxBoxSizer( wxHORIZONTAL ); - m_buttonOK = new wxButton( this, wxID_OK, wxT("OK"), wxDefaultPosition, wxSize( -1,-1 ), 0 ); + 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, wxT("Cancel"), wxDefaultPosition, wxSize( -1,-1 ), 0 ); + 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, wxT("&Apply"), wxDefaultPosition, wxSize( -1,-1 ), 0 ); + 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 ); @@ -504,13 +504,13 @@ CAboutDialogBase::CAboutDialogBase( wxWindow* parent, wxWindowID id, const wxStr wxBoxSizer* bSizer64; bSizer64 = new wxBoxSizer( wxHORIZONTAL ); - m_staticText40 = new wxStaticText( this, wxID_ANY, wxT("Bitcoin "), wxDefaultPosition, wxDefaultSize, 0 ); + 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, wxT("version"), wxDefaultPosition, wxDefaultSize, 0 ); + 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") ) ); @@ -521,7 +521,7 @@ CAboutDialogBase::CAboutDialogBase( wxWindow* parent, wxWindowID id, const wxStr bSizer631->Add( 0, 4, 0, wxEXPAND, 5 ); - m_staticTextMain = new wxStaticText( this, wxID_ANY, wxT("Copyright © 2009-2010 Satoshi Nakamoto.\n\nThis is experimental software. Do not rely on it for actual financial transactions.\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)."), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticTextMain = new wxStaticText( this, wxID_ANY, _("Copyright © 2009-2010 Satoshi Nakamoto.\n\nThis is experimental software. Do not rely on it for actual financial transactions.\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)."), wxDefaultPosition, wxDefaultSize, 0 ); m_staticTextMain->Wrap( -1 ); bSizer631->Add( m_staticTextMain, 0, wxALL, 5 ); @@ -538,7 +538,7 @@ CAboutDialogBase::CAboutDialogBase( wxWindow* parent, wxWindowID id, const wxStr bSizer61->Add( 0, 0, 1, wxEXPAND, 5 ); - m_buttonOK = new wxButton( this, wxID_OK, wxT("OK"), wxDefaultPosition, wxSize( -1,-1 ), 0 ); + m_buttonOK = new wxButton( this, wxID_OK, _("OK"), wxDefaultPosition, wxSize( -1,-1 ), 0 ); bSizer61->Add( m_buttonOK, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); bSizer60->Add( bSizer61, 0, wxALIGN_RIGHT|wxEXPAND|wxRIGHT, 5 ); @@ -577,7 +577,7 @@ CSendDialogBase::CSendDialogBase( wxWindow* parent, wxWindowID id, const wxStrin fgSizer1->Add( 0, 0, 0, wxEXPAND, 5 ); - m_staticTextInstructions = new wxStaticText( this, wxID_ANY, wxT("Enter the recipient's IP address (e.g. 123.45.6.7) for online transfer with comments and confirmation, \nor Bitcoin address (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJED9L) if recipient is not online."), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticTextInstructions = new wxStaticText( this, wxID_ANY, _("Enter the recipient's IP address (e.g. 123.45.6.7) for online transfer with comments and confirmation, \nor Bitcoin address (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJED9L) if recipient is not online."), wxDefaultPosition, wxDefaultSize, 0 ); m_staticTextInstructions->Wrap( -1 ); fgSizer1->Add( m_staticTextInstructions, 0, wxTOP|wxRIGHT|wxLEFT, 5 ); @@ -591,7 +591,7 @@ CSendDialogBase::CSendDialogBase( wxWindow* parent, wxWindowID id, const wxStrin 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, wxT("Pay &To:"), wxDefaultPosition, wxSize( -1,-1 ), wxALIGN_RIGHT ); + 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 ); @@ -606,17 +606,17 @@ CSendDialogBase::CSendDialogBase( wxWindow* parent, wxWindowID id, const wxStrin wxBoxSizer* bSizer66; bSizer66 = new wxBoxSizer( wxHORIZONTAL ); - m_buttonPaste = new wxButton( this, wxID_BUTTONPASTE, wxT("&Paste"), wxDefaultPosition, wxSize( -1,-1 ), wxBU_EXACTFIT ); + 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, wxT(" Address &Book..."), wxDefaultPosition, wxDefaultSize, 0 ); + 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, wxT("&Amount:"), wxDefaultPosition, wxSize( -1,-1 ), wxALIGN_RIGHT ); + 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 ); @@ -626,13 +626,13 @@ CSendDialogBase::CSendDialogBase( wxWindow* parent, wxWindowID id, const wxStrin fgSizer1->Add( m_textCtrlAmount, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 ); - m_staticText20 = new wxStaticText( this, wxID_ANY, wxT("T&ransfer:"), wxDefaultPosition, wxSize( -1,-1 ), wxALIGN_RIGHT ); + 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[] = { wxT(" Standard") }; + 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 ); @@ -654,7 +654,7 @@ CSendDialogBase::CSendDialogBase( wxWindow* parent, wxWindowID id, const wxStrin wxBoxSizer* bSizer681; bSizer681 = new wxBoxSizer( wxVERTICAL ); - m_staticTextFrom = new wxStaticText( this, wxID_ANY, wxT("&From:"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticTextFrom = new wxStaticText( this, wxID_ANY, _("&From:"), wxDefaultPosition, wxDefaultSize, 0 ); m_staticTextFrom->Wrap( -1 ); bSizer681->Add( m_staticTextFrom, 0, wxBOTTOM|wxLEFT, 5 ); @@ -671,7 +671,7 @@ CSendDialogBase::CSendDialogBase( wxWindow* parent, wxWindowID id, const wxStrin wxBoxSizer* bSizer68; bSizer68 = new wxBoxSizer( wxVERTICAL ); - m_staticTextMessage = new wxStaticText( this, wxID_ANY, wxT("&Message:"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticTextMessage = new wxStaticText( this, wxID_ANY, _("&Message:"), wxDefaultPosition, wxDefaultSize, 0 ); m_staticTextMessage->Wrap( -1 ); bSizer68->Add( m_staticTextMessage, 0, wxTOP|wxBOTTOM|wxLEFT, 5 ); @@ -688,12 +688,12 @@ CSendDialogBase::CSendDialogBase( wxWindow* parent, wxWindowID id, const wxStrin bSizer23->Add( 0, 0, 1, wxEXPAND, 5 ); - m_buttonSend = new wxButton( this, wxID_BUTTONSEND, wxT("&Send"), wxDefaultPosition, wxSize( -1,-1 ), 0 ); + 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, wxT("Cancel"), wxDefaultPosition, wxSize( -1,-1 ), 0 ); + 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 ); @@ -740,7 +740,7 @@ CSendingDialogBase::CSendingDialogBase( wxWindow* parent, wxWindowID id, const w m_staticTextSending->Wrap( -1 ); bSizer68->Add( m_staticTextSending, 0, wxALIGN_CENTER_VERTICAL|wxEXPAND|wxTOP|wxRIGHT|wxLEFT, 8 ); - m_textCtrlStatus = new wxTextCtrl( this, wxID_ANY, wxT("\n\nConnecting..."), wxDefaultPosition, wxDefaultSize, wxTE_CENTRE|wxTE_MULTILINE|wxTE_NO_VSCROLL|wxTE_READONLY|wxNO_BORDER ); + 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 ); @@ -751,12 +751,12 @@ CSendingDialogBase::CSendingDialogBase( wxWindow* parent, wxWindowID id, const w bSizer69->Add( 0, 0, 1, wxEXPAND, 5 ); - m_buttonOK = new wxButton( this, wxID_ANY, wxT("OK"), wxDefaultPosition, wxDefaultSize, 0 ); + 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, wxT("Cancel"), wxDefaultPosition, wxSize( -1,-1 ), 0 ); + 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 ); @@ -790,7 +790,7 @@ CYourAddressDialogBase::CYourAddressDialogBase( wxWindow* parent, wxWindowID id, bSizer68->Add( 0, 5, 0, wxEXPAND, 5 ); - m_staticText45 = new wxStaticText( this, wxID_ANY, wxT("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 = 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 ); @@ -803,19 +803,19 @@ CYourAddressDialogBase::CYourAddressDialogBase( wxWindow* parent, wxWindowID id, bSizer69->Add( 0, 0, 1, wxEXPAND, 5 ); - m_buttonRename = new wxButton( this, wxID_BUTTONRENAME, wxT("&Edit..."), wxDefaultPosition, wxDefaultSize, 0 ); + 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, wxT(" &New Address... "), wxDefaultPosition, wxSize( -1,-1 ), 0 ); + 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, wxT(" &Copy to Clipboard "), wxDefaultPosition, wxSize( -1,-1 ), 0 ); + 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, wxT("OK"), wxDefaultPosition, wxDefaultSize, 0 ); + 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, wxT("Cancel"), wxDefaultPosition, wxSize( -1,-1 ), 0 ); + 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 ); @@ -861,7 +861,7 @@ CAddressBookDialogBase::CAddressBookDialogBase( wxWindow* parent, wxWindowID id, bSizer68->Add( 0, 5, 0, wxEXPAND, 5 ); - m_staticText55 = new wxStaticText( this, wxID_ANY, wxT("Bitcoin Address"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticText55 = new wxStaticText( this, wxID_ANY, _("Bitcoin Address"), wxDefaultPosition, wxDefaultSize, 0 ); m_staticText55->Wrap( -1 ); m_staticText55->Hide(); @@ -876,19 +876,19 @@ CAddressBookDialogBase::CAddressBookDialogBase( wxWindow* parent, wxWindowID id, bSizer69->Add( 0, 0, 1, wxEXPAND, 5 ); - m_buttonEdit = new wxButton( this, wxID_BUTTONEDIT, wxT("&Edit..."), wxDefaultPosition, wxDefaultSize, 0 ); + 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, wxT(" &New Address... "), wxDefaultPosition, wxDefaultSize, 0 ); + m_buttonNew = new wxButton( this, wxID_BUTTONNEW, _(" &New Address... "), wxDefaultPosition, wxDefaultSize, 0 ); bSizer69->Add( m_buttonNew, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); - m_buttonDelete = new wxButton( this, wxID_BUTTONDELETE, wxT("&Delete"), wxDefaultPosition, wxDefaultSize, 0 ); + m_buttonDelete = new wxButton( this, wxID_BUTTONDELETE, _("&Delete"), wxDefaultPosition, wxDefaultSize, 0 ); bSizer69->Add( m_buttonDelete, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); - m_buttonOK = new wxButton( this, wxID_OK, wxT("OK"), wxDefaultPosition, wxSize( -1,-1 ), 0 ); + 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, wxT("Cancel"), wxDefaultPosition, wxSize( -1,-1 ), 0 ); + 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 ); @@ -922,713 +922,6 @@ CAddressBookDialogBase::~CAddressBookDialogBase() m_buttonCancel->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CAddressBookDialogBase::OnButtonCancel ), NULL, this ); } -CProductsDialogBase::CProductsDialogBase( 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* bSizer22; - bSizer22 = new wxBoxSizer( wxVERTICAL ); - - wxBoxSizer* bSizer23; - bSizer23 = new wxBoxSizer( wxHORIZONTAL ); - - m_comboBoxCategory = new wxComboBox( this, wxID_ANY, wxT("(Any Category)"), wxDefaultPosition, wxSize( 150,-1 ), 0, NULL, 0 ); - m_comboBoxCategory->Append( wxT("(Any Category)") ); - bSizer23->Add( m_comboBoxCategory, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); - - m_textCtrlSearch = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); - bSizer23->Add( m_textCtrlSearch, 1, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); - - m_buttonSearch = new wxButton( this, wxID_ANY, wxT("&Search"), wxDefaultPosition, wxDefaultSize, 0 ); - bSizer23->Add( m_buttonSearch, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); - - bSizer22->Add( bSizer23, 0, wxEXPAND|wxTOP|wxBOTTOM|wxRIGHT, 5 ); - - m_listCtrl = new wxListCtrl( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_NO_SORT_HEADER|wxLC_REPORT ); - bSizer22->Add( m_listCtrl, 1, wxALL|wxEXPAND, 5 ); - - this->SetSizer( bSizer22 ); - this->Layout(); - - // Connect Events - m_comboBoxCategory->Connect( wxEVT_COMMAND_COMBOBOX_SELECTED, wxCommandEventHandler( CProductsDialogBase::OnCombobox ), NULL, this ); - m_textCtrlSearch->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CProductsDialogBase::OnKeyDown ), NULL, this ); - m_buttonSearch->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CProductsDialogBase::OnButtonSearch ), NULL, this ); - m_listCtrl->Connect( wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler( CProductsDialogBase::OnListItemActivated ), NULL, this ); -} - -CProductsDialogBase::~CProductsDialogBase() -{ - // Disconnect Events - m_comboBoxCategory->Disconnect( wxEVT_COMMAND_COMBOBOX_SELECTED, wxCommandEventHandler( CProductsDialogBase::OnCombobox ), NULL, this ); - m_textCtrlSearch->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CProductsDialogBase::OnKeyDown ), NULL, this ); - m_buttonSearch->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CProductsDialogBase::OnButtonSearch ), NULL, this ); - m_listCtrl->Disconnect( wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler( CProductsDialogBase::OnListItemActivated ), NULL, this ); -} - -CEditProductDialogBase::CEditProductDialogBase( 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_MENU ) ); - - wxBoxSizer* bSizer20; - bSizer20 = new wxBoxSizer( wxVERTICAL ); - - m_scrolledWindow = new wxScrolledWindow( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxHSCROLL|wxTAB_TRAVERSAL|wxVSCROLL ); - m_scrolledWindow->SetScrollRate( 5, 5 ); - m_scrolledWindow->SetBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_WINDOW ) ); - - wxBoxSizer* bSizer21; - bSizer21 = new wxBoxSizer( wxVERTICAL ); - - wxFlexGridSizer* fgSizer8; - fgSizer8 = new wxFlexGridSizer( 0, 2, 0, 0 ); - fgSizer8->AddGrowableCol( 1 ); - fgSizer8->SetFlexibleDirection( wxBOTH ); - fgSizer8->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED ); - - m_staticText106 = new wxStaticText( m_scrolledWindow, wxID_ANY, wxT("Category"), wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT ); - m_staticText106->Wrap( -1 ); - fgSizer8->Add( m_staticText106, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxTOP|wxBOTTOM|wxLEFT, 5 ); - - m_comboBoxCategory = new wxComboBox( m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0, NULL, 0 ); - m_comboBoxCategory->SetMinSize( wxSize( 180,-1 ) ); - - fgSizer8->Add( m_comboBoxCategory, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); - - m_staticText108 = new wxStaticText( m_scrolledWindow, wxID_ANY, wxT("Title"), wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT ); - m_staticText108->Wrap( -1 ); - fgSizer8->Add( m_staticText108, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxTOP|wxBOTTOM|wxLEFT, 5 ); - - m_textCtrlTitle = new wxTextCtrl( m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); - fgSizer8->Add( m_textCtrlTitle, 1, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); - - m_staticText107 = new wxStaticText( m_scrolledWindow, wxID_ANY, wxT("Price"), wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT ); - m_staticText107->Wrap( -1 ); - fgSizer8->Add( m_staticText107, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxTOP|wxBOTTOM|wxLEFT, 5 ); - - m_textCtrlPrice = new wxTextCtrl( m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); - m_textCtrlPrice->SetMinSize( wxSize( 105,-1 ) ); - - fgSizer8->Add( m_textCtrlPrice, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); - - bSizer21->Add( fgSizer8, 0, wxEXPAND|wxTOP|wxRIGHT|wxLEFT, 5 ); - - m_staticText22 = new wxStaticText( m_scrolledWindow, wxID_ANY, wxT("Page 1: Description"), wxDefaultPosition, wxDefaultSize, 0 ); - m_staticText22->Wrap( -1 ); - bSizer21->Add( m_staticText22, 0, wxTOP|wxRIGHT|wxLEFT, 5 ); - - m_textCtrlDescription = new wxTextCtrl( m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE ); - m_textCtrlDescription->SetMinSize( wxSize( -1,170 ) ); - - bSizer21->Add( m_textCtrlDescription, 0, wxALL|wxEXPAND, 5 ); - - m_staticText23 = new wxStaticText( m_scrolledWindow, wxID_ANY, wxT("Page 2: Order Form"), wxDefaultPosition, wxDefaultSize, 0 ); - m_staticText23->Wrap( -1 ); - bSizer21->Add( m_staticText23, 0, wxTOP|wxRIGHT|wxLEFT, 5 ); - - m_textCtrlInstructions = new wxTextCtrl( m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE ); - m_textCtrlInstructions->SetMinSize( wxSize( -1,120 ) ); - - bSizer21->Add( m_textCtrlInstructions, 0, wxEXPAND|wxALL, 5 ); - - fgSizer5 = new wxFlexGridSizer( 0, 3, 0, 0 ); - fgSizer5->AddGrowableCol( 1 ); - fgSizer5->SetFlexibleDirection( wxBOTH ); - fgSizer5->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED ); - - m_staticText24 = new wxStaticText( m_scrolledWindow, wxID_ANY, wxT("Label"), wxDefaultPosition, wxDefaultSize, 0 ); - m_staticText24->Wrap( -1 ); - fgSizer5->Add( m_staticText24, 0, wxALIGN_CENTER_VERTICAL|wxTOP|wxRIGHT|wxLEFT, 5 ); - - m_staticText25 = new wxStaticText( m_scrolledWindow, wxID_ANY, wxT("Comma separated list of choices, or leave blank for text field"), wxDefaultPosition, wxDefaultSize, 0 ); - m_staticText25->Wrap( -1 ); - fgSizer5->Add( m_staticText25, 0, wxALIGN_CENTER_VERTICAL|wxTOP|wxRIGHT|wxLEFT, 5 ); - - - fgSizer5->Add( 0, 0, 1, wxEXPAND, 5 ); - - m_textCtrlLabel0 = new wxTextCtrl( m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); - m_textCtrlLabel0->SetMinSize( wxSize( 150,-1 ) ); - - fgSizer5->Add( m_textCtrlLabel0, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); - - m_textCtrlField0 = new wxTextCtrl( m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize( -1,-1 ), 0 ); - fgSizer5->Add( m_textCtrlField0, 0, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5 ); - - m_buttonDel0 = new wxButton( m_scrolledWindow, wxID_DEL0, wxT("Delete"), wxDefaultPosition, wxSize( 60,20 ), 0 ); - fgSizer5->Add( m_buttonDel0, 0, wxRIGHT|wxLEFT|wxALIGN_CENTER_VERTICAL, 5 ); - - m_textCtrlLabel1 = new wxTextCtrl( m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); - m_textCtrlLabel1->SetMinSize( wxSize( 150,-1 ) ); - - fgSizer5->Add( m_textCtrlLabel1, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); - - m_textCtrlField1 = new wxTextCtrl( m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize( -1,-1 ), 0 ); - fgSizer5->Add( m_textCtrlField1, 0, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5 ); - - m_buttonDel1 = new wxButton( m_scrolledWindow, wxID_DEL1, wxT("Delete"), wxDefaultPosition, wxSize( 60,20 ), 0 ); - fgSizer5->Add( m_buttonDel1, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 ); - - m_textCtrlLabel2 = new wxTextCtrl( m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); - m_textCtrlLabel2->SetMinSize( wxSize( 150,-1 ) ); - - fgSizer5->Add( m_textCtrlLabel2, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); - - m_textCtrlField2 = new wxTextCtrl( m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize( -1,-1 ), 0 ); - fgSizer5->Add( m_textCtrlField2, 0, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5 ); - - m_buttonDel2 = new wxButton( m_scrolledWindow, wxID_DEL2, wxT("Delete"), wxDefaultPosition, wxSize( 60,20 ), 0 ); - fgSizer5->Add( m_buttonDel2, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 ); - - m_textCtrlLabel3 = new wxTextCtrl( m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); - m_textCtrlLabel3->SetMinSize( wxSize( 150,-1 ) ); - - fgSizer5->Add( m_textCtrlLabel3, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); - - m_textCtrlField3 = new wxTextCtrl( m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize( -1,-1 ), 0 ); - fgSizer5->Add( m_textCtrlField3, 0, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5 ); - - m_buttonDel3 = new wxButton( m_scrolledWindow, wxID_DEL3, wxT("Delete"), wxDefaultPosition, wxSize( 60,20 ), 0 ); - fgSizer5->Add( m_buttonDel3, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 ); - - m_textCtrlLabel4 = new wxTextCtrl( m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); - m_textCtrlLabel4->SetMinSize( wxSize( 150,-1 ) ); - - fgSizer5->Add( m_textCtrlLabel4, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); - - m_textCtrlField4 = new wxTextCtrl( m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize( -1,-1 ), 0 ); - fgSizer5->Add( m_textCtrlField4, 0, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5 ); - - m_buttonDel4 = new wxButton( m_scrolledWindow, wxID_DEL4, wxT("Delete"), wxDefaultPosition, wxSize( 60,20 ), 0 ); - fgSizer5->Add( m_buttonDel4, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 ); - - m_textCtrlLabel5 = new wxTextCtrl( m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); - m_textCtrlLabel5->SetMinSize( wxSize( 150,-1 ) ); - - fgSizer5->Add( m_textCtrlLabel5, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); - - m_textCtrlField5 = new wxTextCtrl( m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize( -1,-1 ), 0 ); - fgSizer5->Add( m_textCtrlField5, 0, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5 ); - - m_buttonDel5 = new wxButton( m_scrolledWindow, wxID_DEL5, wxT("Delete"), wxDefaultPosition, wxSize( 60,20 ), 0 ); - fgSizer5->Add( m_buttonDel5, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 ); - - m_textCtrlLabel6 = new wxTextCtrl( m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); - m_textCtrlLabel6->SetMinSize( wxSize( 150,-1 ) ); - - fgSizer5->Add( m_textCtrlLabel6, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); - - m_textCtrlField6 = new wxTextCtrl( m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize( -1,-1 ), 0 ); - fgSizer5->Add( m_textCtrlField6, 0, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5 ); - - m_buttonDel6 = new wxButton( m_scrolledWindow, wxID_DEL6, wxT("Delete"), wxDefaultPosition, wxSize( 60,20 ), 0 ); - fgSizer5->Add( m_buttonDel6, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 ); - - m_textCtrlLabel7 = new wxTextCtrl( m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); - m_textCtrlLabel7->SetMinSize( wxSize( 150,-1 ) ); - - fgSizer5->Add( m_textCtrlLabel7, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); - - m_textCtrlField7 = new wxTextCtrl( m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize( -1,-1 ), 0 ); - fgSizer5->Add( m_textCtrlField7, 0, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5 ); - - m_buttonDel7 = new wxButton( m_scrolledWindow, wxID_DEL7, wxT("Delete"), wxDefaultPosition, wxSize( 60,20 ), 0 ); - fgSizer5->Add( m_buttonDel7, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 ); - - m_textCtrlLabel8 = new wxTextCtrl( m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); - m_textCtrlLabel8->SetMinSize( wxSize( 150,-1 ) ); - - fgSizer5->Add( m_textCtrlLabel8, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); - - m_textCtrlField8 = new wxTextCtrl( m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize( -1,-1 ), 0 ); - fgSizer5->Add( m_textCtrlField8, 0, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5 ); - - m_buttonDel8 = new wxButton( m_scrolledWindow, wxID_DEL8, wxT("Delete"), wxDefaultPosition, wxSize( 60,20 ), 0 ); - fgSizer5->Add( m_buttonDel8, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 ); - - m_textCtrlLabel9 = new wxTextCtrl( m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); - m_textCtrlLabel9->SetMinSize( wxSize( 150,-1 ) ); - - fgSizer5->Add( m_textCtrlLabel9, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); - - m_textCtrlField9 = new wxTextCtrl( m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize( -1,-1 ), 0 ); - fgSizer5->Add( m_textCtrlField9, 0, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5 ); - - m_buttonDel9 = new wxButton( m_scrolledWindow, wxID_DEL9, wxT("Delete"), wxDefaultPosition, wxSize( 60,20 ), 0 ); - fgSizer5->Add( m_buttonDel9, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 ); - - m_textCtrlLabel10 = new wxTextCtrl( m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); - m_textCtrlLabel10->SetMinSize( wxSize( 150,-1 ) ); - - fgSizer5->Add( m_textCtrlLabel10, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); - - m_textCtrlField10 = new wxTextCtrl( m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize( -1,-1 ), 0 ); - fgSizer5->Add( m_textCtrlField10, 0, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5 ); - - m_buttonDel10 = new wxButton( m_scrolledWindow, wxID_DEL10, wxT("Delete"), wxDefaultPosition, wxSize( 60,20 ), 0 ); - fgSizer5->Add( m_buttonDel10, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 ); - - m_textCtrlLabel11 = new wxTextCtrl( m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); - m_textCtrlLabel11->SetMinSize( wxSize( 150,-1 ) ); - - fgSizer5->Add( m_textCtrlLabel11, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); - - m_textCtrlField11 = new wxTextCtrl( m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize( -1,-1 ), 0 ); - fgSizer5->Add( m_textCtrlField11, 0, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5 ); - - m_buttonDel11 = new wxButton( m_scrolledWindow, wxID_DEL11, wxT("Delete"), wxDefaultPosition, wxSize( 60,20 ), 0 ); - fgSizer5->Add( m_buttonDel11, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 ); - - m_textCtrlLabel12 = new wxTextCtrl( m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); - m_textCtrlLabel12->SetMinSize( wxSize( 150,-1 ) ); - - fgSizer5->Add( m_textCtrlLabel12, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); - - m_textCtrlField12 = new wxTextCtrl( m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize( -1,-1 ), 0 ); - fgSizer5->Add( m_textCtrlField12, 0, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5 ); - - m_buttonDel12 = new wxButton( m_scrolledWindow, wxID_DEL12, wxT("Delete"), wxDefaultPosition, wxSize( 60,20 ), 0 ); - fgSizer5->Add( m_buttonDel12, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 ); - - m_textCtrlLabel13 = new wxTextCtrl( m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); - m_textCtrlLabel13->SetMinSize( wxSize( 150,-1 ) ); - - fgSizer5->Add( m_textCtrlLabel13, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); - - m_textCtrlField13 = new wxTextCtrl( m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize( -1,-1 ), 0 ); - fgSizer5->Add( m_textCtrlField13, 0, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5 ); - - m_buttonDel13 = new wxButton( m_scrolledWindow, wxID_DEL13, wxT("Delete"), wxDefaultPosition, wxSize( 60,20 ), 0 ); - fgSizer5->Add( m_buttonDel13, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 ); - - m_textCtrlLabel14 = new wxTextCtrl( m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); - m_textCtrlLabel14->SetMinSize( wxSize( 150,-1 ) ); - - fgSizer5->Add( m_textCtrlLabel14, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); - - m_textCtrlField14 = new wxTextCtrl( m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize( -1,-1 ), 0 ); - fgSizer5->Add( m_textCtrlField14, 0, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5 ); - - m_buttonDel14 = new wxButton( m_scrolledWindow, wxID_DEL14, wxT("Delete"), wxDefaultPosition, wxSize( 60,20 ), 0 ); - fgSizer5->Add( m_buttonDel14, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 ); - - m_textCtrlLabel15 = new wxTextCtrl( m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); - m_textCtrlLabel15->SetMinSize( wxSize( 150,-1 ) ); - - fgSizer5->Add( m_textCtrlLabel15, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); - - m_textCtrlField15 = new wxTextCtrl( m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize( -1,-1 ), 0 ); - fgSizer5->Add( m_textCtrlField15, 0, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5 ); - - m_buttonDel15 = new wxButton( m_scrolledWindow, wxID_DEL15, wxT("Delete"), wxDefaultPosition, wxSize( 60,20 ), 0 ); - fgSizer5->Add( m_buttonDel15, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 ); - - m_textCtrlLabel16 = new wxTextCtrl( m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); - m_textCtrlLabel16->SetMinSize( wxSize( 150,-1 ) ); - - fgSizer5->Add( m_textCtrlLabel16, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); - - m_textCtrlField16 = new wxTextCtrl( m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize( -1,-1 ), 0 ); - fgSizer5->Add( m_textCtrlField16, 0, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5 ); - - m_buttonDel16 = new wxButton( m_scrolledWindow, wxID_DEL16, wxT("Delete"), wxDefaultPosition, wxSize( 60,20 ), 0 ); - fgSizer5->Add( m_buttonDel16, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 ); - - m_textCtrlLabel17 = new wxTextCtrl( m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); - m_textCtrlLabel17->SetMinSize( wxSize( 150,-1 ) ); - - fgSizer5->Add( m_textCtrlLabel17, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); - - m_textCtrlField17 = new wxTextCtrl( m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize( -1,-1 ), 0 ); - fgSizer5->Add( m_textCtrlField17, 0, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5 ); - - m_buttonDel17 = new wxButton( m_scrolledWindow, wxID_DEL17, wxT("Delete"), wxDefaultPosition, wxSize( 60,20 ), 0 ); - fgSizer5->Add( m_buttonDel17, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 ); - - m_textCtrlLabel18 = new wxTextCtrl( m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); - m_textCtrlLabel18->SetMinSize( wxSize( 150,-1 ) ); - - fgSizer5->Add( m_textCtrlLabel18, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); - - m_textCtrlField18 = new wxTextCtrl( m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize( -1,-1 ), 0 ); - fgSizer5->Add( m_textCtrlField18, 0, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5 ); - - m_buttonDel18 = new wxButton( m_scrolledWindow, wxID_DEL18, wxT("Delete"), wxDefaultPosition, wxSize( 60,20 ), 0 ); - fgSizer5->Add( m_buttonDel18, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 ); - - m_textCtrlLabel19 = new wxTextCtrl( m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); - m_textCtrlLabel19->SetMinSize( wxSize( 150,-1 ) ); - - fgSizer5->Add( m_textCtrlLabel19, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); - - m_textCtrlField19 = new wxTextCtrl( m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize( -1,-1 ), 0 ); - fgSizer5->Add( m_textCtrlField19, 0, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5 ); - - m_buttonDel19 = new wxButton( m_scrolledWindow, wxID_DEL19, wxT("Delete"), wxDefaultPosition, wxSize( 60,20 ), 0 ); - fgSizer5->Add( m_buttonDel19, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 ); - - bSizer21->Add( fgSizer5, 0, wxEXPAND, 5 ); - - wxBoxSizer* bSizer25; - bSizer25 = new wxBoxSizer( wxHORIZONTAL ); - - m_buttonAddField = new wxButton( m_scrolledWindow, wxID_ANY, wxT("&Add Field"), wxDefaultPosition, wxDefaultSize, 0 ); - bSizer25->Add( m_buttonAddField, 0, wxALL, 5 ); - - bSizer21->Add( bSizer25, 0, wxALIGN_CENTER_HORIZONTAL, 5 ); - - m_scrolledWindow->SetSizer( bSizer21 ); - m_scrolledWindow->Layout(); - bSizer21->Fit( m_scrolledWindow ); - bSizer20->Add( m_scrolledWindow, 1, wxEXPAND|wxALL, 5 ); - - wxBoxSizer* bSizer26; - bSizer26 = new wxBoxSizer( wxHORIZONTAL ); - - m_buttonOK = new wxButton( this, wxID_BUTTONSEND, wxT("&Send"), wxDefaultPosition, wxDefaultSize, 0 ); - bSizer26->Add( m_buttonOK, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); - - m_buttonPreview = new wxButton( this, wxID_BUTTONPREVIEW, wxT("&Preview"), wxDefaultPosition, wxDefaultSize, 0 ); - bSizer26->Add( m_buttonPreview, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); - - m_buttonCancel = new wxButton( this, wxID_CANCEL, wxT("Cancel"), wxDefaultPosition, wxDefaultSize, 0 ); - bSizer26->Add( m_buttonCancel, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); - - bSizer20->Add( bSizer26, 0, wxALIGN_RIGHT, 5 ); - - this->SetSizer( bSizer20 ); - this->Layout(); - - // Connect Events - m_textCtrlTitle->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); - m_textCtrlPrice->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); - m_textCtrlDescription->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); - m_textCtrlInstructions->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); - m_textCtrlLabel0->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); - m_textCtrlField0->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); - m_buttonDel0->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditProductDialogBase::OnButtonDel0 ), NULL, this ); - m_textCtrlLabel1->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); - m_textCtrlField1->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); - m_buttonDel1->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditProductDialogBase::OnButtonDel1 ), NULL, this ); - m_textCtrlLabel2->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); - m_textCtrlField2->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); - m_buttonDel2->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditProductDialogBase::OnButtonDel2 ), NULL, this ); - m_textCtrlLabel3->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); - m_textCtrlField3->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); - m_buttonDel3->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditProductDialogBase::OnButtonDel3 ), NULL, this ); - m_textCtrlLabel4->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); - m_textCtrlField4->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); - m_buttonDel4->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditProductDialogBase::OnButtonDel4 ), NULL, this ); - m_textCtrlLabel5->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); - m_textCtrlField5->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); - m_buttonDel5->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditProductDialogBase::OnButtonDel5 ), NULL, this ); - m_textCtrlLabel6->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); - m_textCtrlField6->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); - m_buttonDel6->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditProductDialogBase::OnButtonDel6 ), NULL, this ); - m_textCtrlLabel7->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); - m_textCtrlField7->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); - m_buttonDel7->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditProductDialogBase::OnButtonDel7 ), NULL, this ); - m_textCtrlLabel8->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); - m_textCtrlField8->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); - m_buttonDel8->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditProductDialogBase::OnButtonDel8 ), NULL, this ); - m_textCtrlLabel9->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); - m_textCtrlField9->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); - m_buttonDel9->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditProductDialogBase::OnButtonDel9 ), NULL, this ); - m_textCtrlLabel10->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); - m_textCtrlField10->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); - m_buttonDel10->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditProductDialogBase::OnButtonDel10 ), NULL, this ); - m_textCtrlLabel11->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); - m_textCtrlField11->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); - m_buttonDel11->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditProductDialogBase::OnButtonDel11 ), NULL, this ); - m_textCtrlLabel12->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); - m_textCtrlField12->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); - m_buttonDel12->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditProductDialogBase::OnButtonDel12 ), NULL, this ); - m_textCtrlLabel13->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); - m_textCtrlField13->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); - m_buttonDel13->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditProductDialogBase::OnButtonDel13 ), NULL, this ); - m_textCtrlLabel14->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); - m_textCtrlField14->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); - m_buttonDel14->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditProductDialogBase::OnButtonDel14 ), NULL, this ); - m_textCtrlLabel15->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); - m_textCtrlField15->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); - m_buttonDel15->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditProductDialogBase::OnButtonDel15 ), NULL, this ); - m_textCtrlLabel16->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); - m_textCtrlField16->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); - m_buttonDel16->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditProductDialogBase::OnButtonDel16 ), NULL, this ); - m_textCtrlLabel17->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); - m_textCtrlField17->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); - m_buttonDel17->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditProductDialogBase::OnButtonDel17 ), NULL, this ); - m_textCtrlLabel18->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); - m_textCtrlField18->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); - m_buttonDel18->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditProductDialogBase::OnButtonDel18 ), NULL, this ); - m_textCtrlLabel19->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); - m_textCtrlField19->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); - m_buttonDel19->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditProductDialogBase::OnButtonDel19 ), NULL, this ); - m_buttonAddField->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditProductDialogBase::OnButtonAddField ), NULL, this ); - m_buttonOK->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditProductDialogBase::OnButtonSend ), NULL, this ); - m_buttonPreview->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditProductDialogBase::OnButtonPreview ), NULL, this ); - m_buttonCancel->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditProductDialogBase::OnButtonCancel ), NULL, this ); -} - -CEditProductDialogBase::~CEditProductDialogBase() -{ - // Disconnect Events - m_textCtrlTitle->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); - m_textCtrlPrice->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); - m_textCtrlDescription->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); - m_textCtrlInstructions->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); - m_textCtrlLabel0->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); - m_textCtrlField0->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); - m_buttonDel0->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditProductDialogBase::OnButtonDel0 ), NULL, this ); - m_textCtrlLabel1->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); - m_textCtrlField1->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); - m_buttonDel1->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditProductDialogBase::OnButtonDel1 ), NULL, this ); - m_textCtrlLabel2->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); - m_textCtrlField2->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); - m_buttonDel2->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditProductDialogBase::OnButtonDel2 ), NULL, this ); - m_textCtrlLabel3->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); - m_textCtrlField3->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); - m_buttonDel3->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditProductDialogBase::OnButtonDel3 ), NULL, this ); - m_textCtrlLabel4->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); - m_textCtrlField4->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); - m_buttonDel4->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditProductDialogBase::OnButtonDel4 ), NULL, this ); - m_textCtrlLabel5->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); - m_textCtrlField5->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); - m_buttonDel5->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditProductDialogBase::OnButtonDel5 ), NULL, this ); - m_textCtrlLabel6->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); - m_textCtrlField6->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); - m_buttonDel6->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditProductDialogBase::OnButtonDel6 ), NULL, this ); - m_textCtrlLabel7->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); - m_textCtrlField7->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); - m_buttonDel7->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditProductDialogBase::OnButtonDel7 ), NULL, this ); - m_textCtrlLabel8->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); - m_textCtrlField8->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); - m_buttonDel8->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditProductDialogBase::OnButtonDel8 ), NULL, this ); - m_textCtrlLabel9->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); - m_textCtrlField9->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); - m_buttonDel9->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditProductDialogBase::OnButtonDel9 ), NULL, this ); - m_textCtrlLabel10->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); - m_textCtrlField10->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); - m_buttonDel10->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditProductDialogBase::OnButtonDel10 ), NULL, this ); - m_textCtrlLabel11->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); - m_textCtrlField11->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); - m_buttonDel11->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditProductDialogBase::OnButtonDel11 ), NULL, this ); - m_textCtrlLabel12->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); - m_textCtrlField12->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); - m_buttonDel12->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditProductDialogBase::OnButtonDel12 ), NULL, this ); - m_textCtrlLabel13->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); - m_textCtrlField13->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); - m_buttonDel13->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditProductDialogBase::OnButtonDel13 ), NULL, this ); - m_textCtrlLabel14->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); - m_textCtrlField14->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); - m_buttonDel14->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditProductDialogBase::OnButtonDel14 ), NULL, this ); - m_textCtrlLabel15->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); - m_textCtrlField15->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); - m_buttonDel15->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditProductDialogBase::OnButtonDel15 ), NULL, this ); - m_textCtrlLabel16->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); - m_textCtrlField16->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); - m_buttonDel16->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditProductDialogBase::OnButtonDel16 ), NULL, this ); - m_textCtrlLabel17->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); - m_textCtrlField17->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); - m_buttonDel17->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditProductDialogBase::OnButtonDel17 ), NULL, this ); - m_textCtrlLabel18->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); - m_textCtrlField18->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); - m_buttonDel18->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditProductDialogBase::OnButtonDel18 ), NULL, this ); - m_textCtrlLabel19->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); - m_textCtrlField19->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); - m_buttonDel19->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditProductDialogBase::OnButtonDel19 ), NULL, this ); - m_buttonAddField->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditProductDialogBase::OnButtonAddField ), NULL, this ); - m_buttonOK->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditProductDialogBase::OnButtonSend ), NULL, this ); - m_buttonPreview->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditProductDialogBase::OnButtonPreview ), NULL, this ); - m_buttonCancel->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditProductDialogBase::OnButtonCancel ), NULL, this ); -} - -CViewProductDialogBase::CViewProductDialogBase( 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_MENU ) ); - - wxBoxSizer* bSizer20; - bSizer20 = new wxBoxSizer( wxVERTICAL ); - - wxBoxSizer* bSizer116; - bSizer116 = new wxBoxSizer( wxHORIZONTAL ); - - m_htmlWinReviews = new wxHtmlWindow( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxHW_SCROLLBAR_AUTO ); - m_htmlWinReviews->Hide(); - - bSizer116->Add( m_htmlWinReviews, 1, wxALL|wxEXPAND, 5 ); - - m_scrolledWindow = new wxScrolledWindow( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxHSCROLL|wxTAB_TRAVERSAL|wxVSCROLL ); - m_scrolledWindow->SetScrollRate( 5, 5 ); - m_scrolledWindow->SetBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_WINDOW ) ); - - wxBoxSizer* bSizer21; - bSizer21 = new wxBoxSizer( wxVERTICAL ); - - m_richTextHeading = new wxRichTextCtrl( m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize( -1,50 ), wxTE_READONLY|wxNO_BORDER ); - bSizer21->Add( m_richTextHeading, 0, wxEXPAND, 5 ); - - m_staticTextInstructions = new wxStaticText( m_scrolledWindow, wxID_ANY, wxT("Order Form instructions here\nmultiple lines\n1\n2\n3\n4\n5\n6"), wxDefaultPosition, wxDefaultSize, 0 ); - m_staticTextInstructions->Wrap( -1 ); - bSizer21->Add( m_staticTextInstructions, 0, wxALL|wxEXPAND, 5 ); - - wxBoxSizer* bSizer25; - bSizer25 = new wxBoxSizer( wxHORIZONTAL ); - - m_buttonSubmitForm = new wxButton( m_scrolledWindow, wxID_BUTTONSAMPLE, wxT("&Submit"), wxDefaultPosition, wxDefaultSize, 0 ); - bSizer25->Add( m_buttonSubmitForm, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); - - m_buttonCancelForm = new wxButton( m_scrolledWindow, wxID_CANCEL2, wxT("Cancel"), wxDefaultPosition, wxDefaultSize, 0 ); - bSizer25->Add( m_buttonCancelForm, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); - - bSizer21->Add( bSizer25, 0, wxALIGN_CENTER_HORIZONTAL, 5 ); - - m_scrolledWindow->SetSizer( bSizer21 ); - m_scrolledWindow->Layout(); - bSizer21->Fit( m_scrolledWindow ); - bSizer116->Add( m_scrolledWindow, 1, wxEXPAND|wxALL, 5 ); - - bSizer20->Add( bSizer116, 1, wxEXPAND, 5 ); - - wxBoxSizer* bSizer26; - bSizer26 = new wxBoxSizer( wxHORIZONTAL ); - - m_buttonBack = new wxButton( this, wxID_BUTTONBACK, wxT("< &Back "), wxDefaultPosition, wxDefaultSize, 0 ); - m_buttonBack->Enable( false ); - - bSizer26->Add( m_buttonBack, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); - - m_buttonNext = new wxButton( this, wxID_BUTTONNEXT, wxT(" &Next >"), wxDefaultPosition, wxDefaultSize, 0 ); - bSizer26->Add( m_buttonNext, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); - - m_buttonCancel = new wxButton( this, wxID_CANCEL, wxT("Cancel"), wxDefaultPosition, wxDefaultSize, 0 ); - bSizer26->Add( m_buttonCancel, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); - - bSizer20->Add( bSizer26, 0, wxALIGN_RIGHT, 5 ); - - this->SetSizer( bSizer20 ); - this->Layout(); - - // Connect Events - m_buttonSubmitForm->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CViewProductDialogBase::OnButtonSubmitForm ), NULL, this ); - m_buttonCancelForm->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CViewProductDialogBase::OnButtonCancelForm ), NULL, this ); - m_buttonBack->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CViewProductDialogBase::OnButtonBack ), NULL, this ); - m_buttonNext->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CViewProductDialogBase::OnButtonNext ), NULL, this ); - m_buttonCancel->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CViewProductDialogBase::OnButtonCancel ), NULL, this ); -} - -CViewProductDialogBase::~CViewProductDialogBase() -{ - // Disconnect Events - m_buttonSubmitForm->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CViewProductDialogBase::OnButtonSubmitForm ), NULL, this ); - m_buttonCancelForm->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CViewProductDialogBase::OnButtonCancelForm ), NULL, this ); - m_buttonBack->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CViewProductDialogBase::OnButtonBack ), NULL, this ); - m_buttonNext->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CViewProductDialogBase::OnButtonNext ), NULL, this ); - m_buttonCancel->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CViewProductDialogBase::OnButtonCancel ), NULL, this ); -} - -CViewOrderDialogBase::CViewOrderDialogBase( 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_MENU ) ); - - wxBoxSizer* bSizer20; - bSizer20 = new wxBoxSizer( wxVERTICAL ); - - wxBoxSizer* bSizer116; - bSizer116 = new wxBoxSizer( wxHORIZONTAL ); - - m_htmlWin = new wxHtmlWindow( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxHW_SCROLLBAR_AUTO ); - bSizer116->Add( m_htmlWin, 1, wxALL|wxEXPAND, 5 ); - - bSizer20->Add( bSizer116, 1, wxEXPAND, 5 ); - - wxBoxSizer* bSizer26; - bSizer26 = new wxBoxSizer( wxHORIZONTAL ); - - m_buttonOK = new wxButton( this, wxID_OK, wxT("OK"), wxDefaultPosition, wxDefaultSize, 0 ); - bSizer26->Add( m_buttonOK, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); - - bSizer20->Add( bSizer26, 0, wxALIGN_RIGHT, 5 ); - - this->SetSizer( bSizer20 ); - this->Layout(); - - // Connect Events - m_buttonOK->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CViewOrderDialogBase::OnButtonOK ), NULL, this ); -} - -CViewOrderDialogBase::~CViewOrderDialogBase() -{ - // Disconnect Events - m_buttonOK->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CViewOrderDialogBase::OnButtonOK ), NULL, this ); -} - -CEditReviewDialogBase::CEditReviewDialogBase( 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_MENU ) ); - - wxBoxSizer* bSizer112; - bSizer112 = new wxBoxSizer( wxVERTICAL ); - - - bSizer112->Add( 0, 3, 0, 0, 5 ); - - m_staticTextSeller = new wxStaticText( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); - m_staticTextSeller->Wrap( -1 ); - bSizer112->Add( m_staticTextSeller, 0, wxALL|wxEXPAND, 5 ); - - - bSizer112->Add( 0, 3, 0, 0, 5 ); - - m_staticText110 = new wxStaticText( this, wxID_ANY, wxT("Rating"), wxDefaultPosition, wxDefaultSize, 0 ); - m_staticText110->Wrap( -1 ); - bSizer112->Add( m_staticText110, 0, wxTOP|wxRIGHT|wxLEFT, 5 ); - - wxString m_choiceStarsChoices[] = { wxT(" 1 star"), wxT(" 2 stars"), wxT(" 3 stars"), wxT(" 4 stars"), wxT(" 5 stars") }; - int m_choiceStarsNChoices = sizeof( m_choiceStarsChoices ) / sizeof( wxString ); - m_choiceStars = new wxChoice( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, m_choiceStarsNChoices, m_choiceStarsChoices, 0 ); - m_choiceStars->SetSelection( 0 ); - bSizer112->Add( m_choiceStars, 0, wxALL, 5 ); - - m_staticText43 = new wxStaticText( this, wxID_ANY, wxT("Review"), wxDefaultPosition, wxDefaultSize, 0 ); - m_staticText43->Wrap( -1 ); - bSizer112->Add( m_staticText43, 0, wxTOP|wxRIGHT|wxLEFT, 5 ); - - m_textCtrlReview = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE ); - bSizer112->Add( m_textCtrlReview, 1, wxALL|wxEXPAND, 5 ); - - wxBoxSizer* bSizer113; - bSizer113 = new wxBoxSizer( wxHORIZONTAL ); - - m_buttonSubmit = new wxButton( this, wxID_SUBMIT, wxT("&Submit"), wxDefaultPosition, wxDefaultSize, 0 ); - bSizer113->Add( m_buttonSubmit, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); - - m_buttonCancel = new wxButton( this, wxID_CANCEL, wxT("Cancel"), wxDefaultPosition, wxDefaultSize, 0 ); - bSizer113->Add( m_buttonCancel, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); - - bSizer112->Add( bSizer113, 0, wxALIGN_RIGHT, 5 ); - - this->SetSizer( bSizer112 ); - this->Layout(); - - // Connect Events - m_textCtrlReview->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditReviewDialogBase::OnKeyDown ), NULL, this ); - m_buttonSubmit->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditReviewDialogBase::OnButtonSubmit ), NULL, this ); - m_buttonCancel->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditReviewDialogBase::OnButtonCancel ), NULL, this ); -} - -CEditReviewDialogBase::~CEditReviewDialogBase() -{ - // Disconnect Events - m_textCtrlReview->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditReviewDialogBase::OnKeyDown ), NULL, this ); - m_buttonSubmit->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditReviewDialogBase::OnButtonSubmit ), NULL, this ); - m_buttonCancel->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditReviewDialogBase::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 ); @@ -1671,10 +964,10 @@ CGetTextFromUserDialogBase::CGetTextFromUserDialogBase( wxWindow* parent, wxWind bSizer80->Add( 0, 0, 1, wxEXPAND, 5 ); - m_buttonOK = new wxButton( this, wxID_OK, wxT("OK"), wxDefaultPosition, wxSize( -1,-1 ), 0 ); + 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, wxT("Cancel"), wxDefaultPosition, wxDefaultSize, 0 ); + 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 ); diff --git a/uibase.h b/uibase.h index faef982989..2dfc2af14d 100644 --- a/uibase.h +++ b/uibase.h @@ -11,6 +11,8 @@ #ifndef __uibase__ #define __uibase__ +#include + #include #include #include @@ -37,8 +39,6 @@ #include #include #include -#include -#include /////////////////////////////////////////////////////////////////////////// @@ -49,8 +49,8 @@ #define wxID_BUTTONSEND 1004 #define wxID_BUTTONRECEIVE 1005 #define wxID_TEXTCTRLADDRESS 1006 -#define wxID_BUTTONCOPY 1007 -#define wxID_BUTTONCHANGE 1008 +#define wxID_BUTTONCHANGE 1007 +#define wxID_BUTTONCOPY 1008 #define wxID_TRANSACTIONFEE 1009 #define wxID_PROXYIP 1010 #define wxID_PROXYPORT 1011 @@ -64,33 +64,7 @@ #define wxID_BUTTONNEW 1019 #define wxID_BUTTONEDIT 1020 #define wxID_BUTTONDELETE 1021 -#define wxID_DEL0 1022 -#define wxID_DEL1 1023 -#define wxID_DEL2 1024 -#define wxID_DEL3 1025 -#define wxID_DEL4 1026 -#define wxID_DEL5 1027 -#define wxID_DEL6 1028 -#define wxID_DEL7 1029 -#define wxID_DEL8 1030 -#define wxID_DEL9 1031 -#define wxID_DEL10 1032 -#define wxID_DEL11 1033 -#define wxID_DEL12 1034 -#define wxID_DEL13 1035 -#define wxID_DEL14 1036 -#define wxID_DEL15 1037 -#define wxID_DEL16 1038 -#define wxID_DEL17 1039 -#define wxID_DEL18 1040 -#define wxID_DEL19 1041 -#define wxID_BUTTONPREVIEW 1042 -#define wxID_BUTTONSAMPLE 1043 -#define wxID_CANCEL2 1044 -#define wxID_BUTTONBACK 1045 -#define wxID_BUTTONNEXT 1046 -#define wxID_SUBMIT 1047 -#define wxID_TEXTCTRL 1048 +#define wxID_TEXTCTRL 1022 /////////////////////////////////////////////////////////////////////////////// /// Class CMainFrameBase @@ -109,8 +83,8 @@ class CMainFrameBase : public wxFrame wxStaticText* m_staticText32; wxTextCtrl* m_textCtrlAddress; + wxButton* m_buttonNew; wxButton* m_buttonCopy; - wxButton* m_button91; wxPanel* m_panel14; wxStaticText* m_staticText41; @@ -137,8 +111,8 @@ class CMainFrameBase : public wxFrame virtual void OnKeyDown( wxKeyEvent& event ){ event.Skip(); } virtual void OnMouseEventsAddress( wxMouseEvent& event ){ event.Skip(); } virtual void OnSetFocusAddress( wxFocusEvent& event ){ event.Skip(); } - virtual void OnButtonCopy( wxCommandEvent& event ){ event.Skip(); } virtual void OnButtonChange( wxCommandEvent& event ){ event.Skip(); } + virtual void OnButtonCopy( wxCommandEvent& event ){ event.Skip(); } virtual void OnListColBeginDrag( wxListEvent& event ){ event.Skip(); } virtual void OnListItemActivated( wxListEvent& event ){ event.Skip(); } virtual void OnPaintListCtrl( wxPaintEvent& event ){ event.Skip(); } @@ -147,7 +121,7 @@ class CMainFrameBase : public wxFrame public: wxMenu* m_menuOptions; wxListCtrl* m_listCtrl; - CMainFrameBase( wxWindow* parent, wxWindowID id = wxID_MAINFRAME, const wxString& title = wxT("Bitcoin"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 712,484 ), long style = wxDEFAULT_FRAME_STYLE|wxRESIZE_BORDER|wxTAB_TRAVERSAL ); + CMainFrameBase( wxWindow* parent, wxWindowID id = wxID_MAINFRAME, const wxString& title = _("Bitcoin"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 712,484 ), long style = wxDEFAULT_FRAME_STYLE|wxRESIZE_BORDER|wxTAB_TRAVERSAL ); ~CMainFrameBase(); }; @@ -168,7 +142,7 @@ class CTxDetailsDialogBase : public wxDialog public: - CTxDetailsDialogBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxT("Transaction Details"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 620,450 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER ); + 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(); }; @@ -223,7 +197,7 @@ class COptionsDialogBase : public wxDialog public: - COptionsDialogBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxT("Options"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 540,360 ), long style = wxDEFAULT_DIALOG_STYLE ); + 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(); }; @@ -251,7 +225,7 @@ class CAboutDialogBase : public wxDialog public: wxStaticText* m_staticTextVersion; - CAboutDialogBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxT("About Bitcoin"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 532,329 ), long style = wxDEFAULT_DIALOG_STYLE ); + CAboutDialogBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("About Bitcoin"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 532,329 ), long style = wxDEFAULT_DIALOG_STYLE ); ~CAboutDialogBase(); }; @@ -298,7 +272,7 @@ class CSendDialogBase : public wxDialog public: - CSendDialogBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxT("Send Coins"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 675,312 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER ); + CSendDialogBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Send Coins"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 675,312 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER ); ~CSendDialogBase(); }; @@ -325,7 +299,7 @@ class CSendingDialogBase : public wxDialog public: - CSendingDialogBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxT("Sending..."), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 442,151 ), long style = wxDEFAULT_DIALOG_STYLE ); + 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(); }; @@ -361,7 +335,7 @@ class CYourAddressDialogBase : public wxDialog public: - CYourAddressDialogBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxT("Your Bitcoin Addresses"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 610,390 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER ); + 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(); }; @@ -397,242 +371,11 @@ class CAddressBookDialogBase : public wxDialog public: wxButton* m_buttonCancel; - CAddressBookDialogBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxT("Address Book"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 610,390 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER ); + 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 CProductsDialogBase -/////////////////////////////////////////////////////////////////////////////// -class CProductsDialogBase : public wxDialog -{ - private: - - protected: - wxComboBox* m_comboBoxCategory; - wxTextCtrl* m_textCtrlSearch; - wxButton* m_buttonSearch; - wxListCtrl* m_listCtrl; - - // Virtual event handlers, overide them in your derived class - virtual void OnCombobox( wxCommandEvent& event ){ event.Skip(); } - virtual void OnKeyDown( wxKeyEvent& event ){ event.Skip(); } - virtual void OnButtonSearch( wxCommandEvent& event ){ event.Skip(); } - virtual void OnListItemActivated( wxListEvent& event ){ event.Skip(); } - - - public: - CProductsDialogBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxT("Marketplace"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 708,535 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER ); - ~CProductsDialogBase(); - -}; - -/////////////////////////////////////////////////////////////////////////////// -/// Class CEditProductDialogBase -/////////////////////////////////////////////////////////////////////////////// -class CEditProductDialogBase : public wxFrame -{ - private: - - protected: - wxScrolledWindow* m_scrolledWindow; - wxStaticText* m_staticText106; - wxComboBox* m_comboBoxCategory; - wxStaticText* m_staticText108; - wxTextCtrl* m_textCtrlTitle; - wxStaticText* m_staticText107; - wxTextCtrl* m_textCtrlPrice; - wxStaticText* m_staticText22; - wxTextCtrl* m_textCtrlDescription; - wxStaticText* m_staticText23; - wxTextCtrl* m_textCtrlInstructions; - wxStaticText* m_staticText24; - wxStaticText* m_staticText25; - - wxTextCtrl* m_textCtrlLabel0; - wxTextCtrl* m_textCtrlField0; - wxButton* m_buttonDel0; - wxTextCtrl* m_textCtrlLabel1; - wxTextCtrl* m_textCtrlField1; - wxButton* m_buttonDel1; - wxTextCtrl* m_textCtrlLabel2; - wxTextCtrl* m_textCtrlField2; - wxButton* m_buttonDel2; - wxTextCtrl* m_textCtrlLabel3; - wxTextCtrl* m_textCtrlField3; - wxButton* m_buttonDel3; - wxTextCtrl* m_textCtrlLabel4; - wxTextCtrl* m_textCtrlField4; - wxButton* m_buttonDel4; - wxTextCtrl* m_textCtrlLabel5; - wxTextCtrl* m_textCtrlField5; - wxButton* m_buttonDel5; - wxTextCtrl* m_textCtrlLabel6; - wxTextCtrl* m_textCtrlField6; - wxButton* m_buttonDel6; - wxTextCtrl* m_textCtrlLabel7; - wxTextCtrl* m_textCtrlField7; - wxButton* m_buttonDel7; - wxTextCtrl* m_textCtrlLabel8; - wxTextCtrl* m_textCtrlField8; - wxButton* m_buttonDel8; - wxTextCtrl* m_textCtrlLabel9; - wxTextCtrl* m_textCtrlField9; - wxButton* m_buttonDel9; - wxTextCtrl* m_textCtrlLabel10; - wxTextCtrl* m_textCtrlField10; - wxButton* m_buttonDel10; - wxTextCtrl* m_textCtrlLabel11; - wxTextCtrl* m_textCtrlField11; - wxButton* m_buttonDel11; - wxTextCtrl* m_textCtrlLabel12; - wxTextCtrl* m_textCtrlField12; - wxButton* m_buttonDel12; - wxTextCtrl* m_textCtrlLabel13; - wxTextCtrl* m_textCtrlField13; - wxButton* m_buttonDel13; - wxTextCtrl* m_textCtrlLabel14; - wxTextCtrl* m_textCtrlField14; - wxButton* m_buttonDel14; - wxTextCtrl* m_textCtrlLabel15; - wxTextCtrl* m_textCtrlField15; - wxButton* m_buttonDel15; - wxTextCtrl* m_textCtrlLabel16; - wxTextCtrl* m_textCtrlField16; - wxButton* m_buttonDel16; - wxTextCtrl* m_textCtrlLabel17; - wxTextCtrl* m_textCtrlField17; - wxButton* m_buttonDel17; - wxTextCtrl* m_textCtrlLabel18; - wxTextCtrl* m_textCtrlField18; - wxButton* m_buttonDel18; - wxTextCtrl* m_textCtrlLabel19; - wxTextCtrl* m_textCtrlField19; - wxButton* m_buttonDel19; - wxButton* m_buttonAddField; - wxButton* m_buttonOK; - wxButton* m_buttonPreview; - wxButton* m_buttonCancel; - - // Virtual event handlers, overide them in your derived class - virtual void OnKeyDown( wxKeyEvent& event ){ event.Skip(); } - virtual void OnButtonDel0( wxCommandEvent& event ){ event.Skip(); } - virtual void OnButtonDel1( wxCommandEvent& event ){ event.Skip(); } - virtual void OnButtonDel2( wxCommandEvent& event ){ event.Skip(); } - virtual void OnButtonDel3( wxCommandEvent& event ){ event.Skip(); } - virtual void OnButtonDel4( wxCommandEvent& event ){ event.Skip(); } - virtual void OnButtonDel5( wxCommandEvent& event ){ event.Skip(); } - virtual void OnButtonDel6( wxCommandEvent& event ){ event.Skip(); } - virtual void OnButtonDel7( wxCommandEvent& event ){ event.Skip(); } - virtual void OnButtonDel8( wxCommandEvent& event ){ event.Skip(); } - virtual void OnButtonDel9( wxCommandEvent& event ){ event.Skip(); } - virtual void OnButtonDel10( wxCommandEvent& event ){ event.Skip(); } - virtual void OnButtonDel11( wxCommandEvent& event ){ event.Skip(); } - virtual void OnButtonDel12( wxCommandEvent& event ){ event.Skip(); } - virtual void OnButtonDel13( wxCommandEvent& event ){ event.Skip(); } - virtual void OnButtonDel14( wxCommandEvent& event ){ event.Skip(); } - virtual void OnButtonDel15( wxCommandEvent& event ){ event.Skip(); } - virtual void OnButtonDel16( wxCommandEvent& event ){ event.Skip(); } - virtual void OnButtonDel17( wxCommandEvent& event ){ event.Skip(); } - virtual void OnButtonDel18( wxCommandEvent& event ){ event.Skip(); } - virtual void OnButtonDel19( wxCommandEvent& event ){ event.Skip(); } - virtual void OnButtonAddField( wxCommandEvent& event ){ event.Skip(); } - virtual void OnButtonSend( wxCommandEvent& event ){ event.Skip(); } - virtual void OnButtonPreview( wxCommandEvent& event ){ event.Skip(); } - virtual void OnButtonCancel( wxCommandEvent& event ){ event.Skip(); } - - - public: - wxFlexGridSizer* fgSizer5; - CEditProductDialogBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxT("Edit Product"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 660,640 ), long style = wxDEFAULT_FRAME_STYLE|wxRESIZE_BORDER|wxTAB_TRAVERSAL ); - ~CEditProductDialogBase(); - -}; - -/////////////////////////////////////////////////////////////////////////////// -/// Class CViewProductDialogBase -/////////////////////////////////////////////////////////////////////////////// -class CViewProductDialogBase : public wxFrame -{ - private: - - protected: - wxHtmlWindow* m_htmlWinReviews; - wxScrolledWindow* m_scrolledWindow; - wxRichTextCtrl* m_richTextHeading; - wxStaticText* m_staticTextInstructions; - wxButton* m_buttonSubmitForm; - wxButton* m_buttonCancelForm; - wxButton* m_buttonBack; - wxButton* m_buttonNext; - wxButton* m_buttonCancel; - - // Virtual event handlers, overide them in your derived class - virtual void OnButtonSubmitForm( wxCommandEvent& event ){ event.Skip(); } - virtual void OnButtonCancelForm( wxCommandEvent& event ){ event.Skip(); } - virtual void OnButtonBack( wxCommandEvent& event ){ event.Skip(); } - virtual void OnButtonNext( wxCommandEvent& event ){ event.Skip(); } - virtual void OnButtonCancel( wxCommandEvent& event ){ event.Skip(); } - - - public: - CViewProductDialogBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxT("Order Form"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 630,520 ), long style = wxDEFAULT_FRAME_STYLE|wxRESIZE_BORDER|wxTAB_TRAVERSAL ); - ~CViewProductDialogBase(); - -}; - -/////////////////////////////////////////////////////////////////////////////// -/// Class CViewOrderDialogBase -/////////////////////////////////////////////////////////////////////////////// -class CViewOrderDialogBase : public wxFrame -{ - 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: - CViewOrderDialogBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxT("View Order"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 630,520 ), long style = wxDEFAULT_FRAME_STYLE|wxRESIZE_BORDER|wxTAB_TRAVERSAL ); - ~CViewOrderDialogBase(); - -}; - -/////////////////////////////////////////////////////////////////////////////// -/// Class CEditReviewDialogBase -/////////////////////////////////////////////////////////////////////////////// -class CEditReviewDialogBase : public wxFrame -{ - private: - - protected: - - wxStaticText* m_staticTextSeller; - - wxStaticText* m_staticText110; - wxChoice* m_choiceStars; - wxStaticText* m_staticText43; - wxTextCtrl* m_textCtrlReview; - wxButton* m_buttonSubmit; - wxButton* m_buttonCancel; - - // Virtual event handlers, overide them in your derived class - virtual void OnKeyDown( wxKeyEvent& event ){ event.Skip(); } - virtual void OnButtonSubmit( wxCommandEvent& event ){ event.Skip(); } - virtual void OnButtonCancel( wxCommandEvent& event ){ event.Skip(); } - - - public: - CEditReviewDialogBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxT("Enter Review"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 630,440 ), long style = wxDEFAULT_FRAME_STYLE|wxRESIZE_BORDER|wxTAB_TRAVERSAL ); - ~CEditReviewDialogBase(); - -}; - /////////////////////////////////////////////////////////////////////////////// /// Class CGetTextFromUserDialogBase /////////////////////////////////////////////////////////////////////////////// diff --git a/uiproject.fbp b/uiproject.fbp index c24f6962b9..5c6eaa55a5 100644 --- a/uiproject.fbp +++ b/uiproject.fbp @@ -10,7 +10,7 @@ uibase 1000 none - 0 + 1 . @@ -18,7 +18,7 @@ 1 0 0 - + wxSYS_COLOUR_BTNFACE @@ -478,7 +478,7 @@ 5 - wxALIGN_CENTER_VERTICAL|wxRIGHT + wxRIGHT 0 @@ -487,22 +487,22 @@ 1 - 0 - wxID_BUTTONCOPY - &Copy to Clipboard + 1 + wxID_BUTTONCHANGE + &New... - m_buttonCopy + m_buttonNew protected - wxBU_EXACTFIT + - OnButtonCopy + OnButtonChange @@ -530,7 +530,7 @@ 5 - wxRIGHT + wxALIGN_CENTER_VERTICAL|wxRIGHT 0 @@ -539,22 +539,22 @@ 1 - 1 - wxID_BUTTONCHANGE - C&hange... + 0 + wxID_BUTTONCOPY + &Copy to Clipboard - m_button91 + m_buttonCopy protected - + wxBU_EXACTFIT - OnButtonChange + OnButtonCopy @@ -5239,5779 +5239,6 @@ - - - - - 1 - - - - 0 - wxID_ANY - - - CProductsDialogBase - - 708,535 - wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER - - Marketplace - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - bSizer22 - wxVERTICAL - none - - 5 - wxEXPAND|wxTOP|wxBOTTOM|wxRIGHT - 0 - - - bSizer23 - wxHORIZONTAL - none - - 5 - wxALL|wxALIGN_CENTER_VERTICAL - 0 - - - "(Any Category)" - - 1 - - - 0 - wxID_ANY - - - m_comboBoxCategory - protected - - 150,-1 - - - - (Any Category) - - - - - OnCombobox - - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALL|wxALIGN_CENTER_VERTICAL - 1 - - - - 1 - - - 0 - wxID_ANY - - 0 - - m_textCtrlSearch - protected - - - - - - - - - - - - - OnKeyDown - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALL|wxALIGN_CENTER_VERTICAL - 0 - - - - 0 - 1 - - - 0 - wxID_ANY - &Search - - - m_buttonSearch - protected - - - - - - - - - OnButtonSearch - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALL|wxEXPAND - 1 - - - - 1 - - - 0 - wxID_ANY - - - m_listCtrl - protected - - - wxLC_NO_SORT_HEADER|wxLC_REPORT - - - - - - - - - - - - - - - - - - - - - - - - - - - - - OnListItemActivated - - - - - - - - - - - - - - - - - - - - - - - - - wxSYS_COLOUR_MENU - - - 1 - - - - 0 - wxID_ANY - - - CEditProductDialogBase - - 660,640 - wxDEFAULT_FRAME_STYLE|wxRESIZE_BORDER - - Edit Product - - - - wxTAB_TRAVERSAL - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - bSizer20 - wxVERTICAL - none - - 5 - wxEXPAND|wxALL - 1 - - wxSYS_COLOUR_WINDOW - - 1 - - - 0 - wxID_ANY - - - m_scrolledWindow - protected - - 5 - 5 - - - - - - wxHSCROLL|wxTAB_TRAVERSAL|wxVSCROLL - - - - - - - - - - - - - - - - - - - - - - - - - - bSizer21 - wxVERTICAL - none - - 5 - wxEXPAND|wxTOP|wxRIGHT|wxLEFT - 0 - - 2 - wxBOTH - 1 - - 0 - - fgSizer8 - wxFLEX_GROWMODE_SPECIFIED - none - 0 - 0 - - 5 - wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxTOP|wxBOTTOM|wxLEFT - 0 - - - - 1 - - - 0 - wxID_ANY - Category - - - m_staticText106 - protected - - - wxALIGN_RIGHT - - - - - - -1 - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALL|wxALIGN_CENTER_VERTICAL - 0 - - - - - 1 - - - 0 - wxID_ANY - - 180,-1 - m_comboBoxCategory - protected - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxTOP|wxBOTTOM|wxLEFT - 0 - - - - 1 - - - 0 - wxID_ANY - Title - - - m_staticText108 - protected - - - wxALIGN_RIGHT - - - - - - -1 - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND - 1 - - - - 1 - - - 0 - wxID_ANY - - 0 - - m_textCtrlTitle - protected - - - - - - - - - - - - - OnKeyDown - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxTOP|wxBOTTOM|wxLEFT - 0 - - - - 1 - - - 0 - wxID_ANY - Price - - - m_staticText107 - protected - - - wxALIGN_RIGHT - - - - - - -1 - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALL|wxALIGN_CENTER_VERTICAL - 0 - - - - 1 - - - 0 - wxID_ANY - - 0 - 105,-1 - m_textCtrlPrice - protected - - - - - - - - - - - - - OnKeyDown - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxTOP|wxRIGHT|wxLEFT - 0 - - - - 1 - - - 0 - wxID_ANY - Page 1: Description - - - m_staticText22 - protected - - - - - - - - - -1 - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALL|wxEXPAND - 0 - - - - 1 - - - 0 - wxID_ANY - - 0 - -1,170 - m_textCtrlDescription - protected - - - wxTE_MULTILINE - - - - - - - - - - OnKeyDown - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxTOP|wxRIGHT|wxLEFT - 0 - - - - 1 - - - 0 - wxID_ANY - Page 2: Order Form - - - m_staticText23 - protected - - - - - - - - - -1 - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxEXPAND|wxALL - 0 - - - - 1 - - - 0 - wxID_ANY - - 0 - -1,120 - m_textCtrlInstructions - protected - - - wxTE_MULTILINE - - - - - - - - - - OnKeyDown - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxEXPAND - 0 - - 3 - wxBOTH - 1 - - 0 - - fgSizer5 - wxFLEX_GROWMODE_SPECIFIED - public - 0 - 0 - - 5 - wxALIGN_CENTER_VERTICAL|wxTOP|wxRIGHT|wxLEFT - 0 - - - - 1 - - - 0 - wxID_ANY - Label - - - m_staticText24 - protected - - - - - - - - - -1 - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALIGN_CENTER_VERTICAL|wxTOP|wxRIGHT|wxLEFT - 0 - - - - 1 - - - 0 - wxID_ANY - Comma separated list of choices, or leave blank for text field - - - m_staticText25 - protected - - - - - - - - - -1 - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxEXPAND - 1 - - 0 - protected - 0 - - - - 5 - wxALL|wxALIGN_CENTER_VERTICAL - 0 - - - - 1 - - - 0 - wxID_ANY - - 0 - 150,-1 - m_textCtrlLabel0 - protected - - - - - - - - - - - - - OnKeyDown - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL - 0 - - - - 1 - - - 0 - wxID_ANY - -1,-1 - 0 - -1,-1 - m_textCtrlField0 - protected - - -1,-1 - - - - - - - - - - - OnKeyDown - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxRIGHT|wxLEFT|wxALIGN_CENTER_VERTICAL - 0 - - - - 0 - 1 - - - 0 - wxID_DEL0 - Delete - - -1,-1 - m_buttonDel0 - protected - - 60,20 - - - - - - - OnButtonDel0 - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALL|wxALIGN_CENTER_VERTICAL - 0 - - - - 1 - - - 0 - wxID_ANY - - 0 - 150,-1 - m_textCtrlLabel1 - protected - - - - - - - - - - - - - OnKeyDown - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL - 0 - - - - 1 - - - 0 - wxID_ANY - -1,-1 - 0 - -1,-1 - m_textCtrlField1 - protected - - -1,-1 - - - - - - - - - - - OnKeyDown - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT - 0 - - - - 0 - 1 - - - 0 - wxID_DEL1 - Delete - - -1,-1 - m_buttonDel1 - protected - - 60,20 - - - - - - - OnButtonDel1 - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALL|wxALIGN_CENTER_VERTICAL - 0 - - - - 1 - - - 0 - wxID_ANY - - 0 - 150,-1 - m_textCtrlLabel2 - protected - - - - - - - - - - - - - OnKeyDown - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL - 0 - - - - 1 - - - 0 - wxID_ANY - -1,-1 - 0 - -1,-1 - m_textCtrlField2 - protected - - -1,-1 - - - - - - - - - - - OnKeyDown - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT - 0 - - - - 0 - 1 - - - 0 - wxID_DEL2 - Delete - - -1,-1 - m_buttonDel2 - protected - - 60,20 - - - - - - - OnButtonDel2 - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALL|wxALIGN_CENTER_VERTICAL - 0 - - - - 1 - - - 0 - wxID_ANY - - 0 - 150,-1 - m_textCtrlLabel3 - protected - - - - - - - - - - - - - OnKeyDown - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL - 0 - - - - 1 - - - 0 - wxID_ANY - -1,-1 - 0 - -1,-1 - m_textCtrlField3 - protected - - -1,-1 - - - - - - - - - - - OnKeyDown - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT - 0 - - - - 0 - 1 - - - 0 - wxID_DEL3 - Delete - - -1,-1 - m_buttonDel3 - protected - - 60,20 - - - - - - - OnButtonDel3 - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALL|wxALIGN_CENTER_VERTICAL - 0 - - - - 1 - - - 0 - wxID_ANY - - 0 - 150,-1 - m_textCtrlLabel4 - protected - - - - - - - - - - - - - OnKeyDown - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL - 0 - - - - 1 - - - 0 - wxID_ANY - -1,-1 - 0 - -1,-1 - m_textCtrlField4 - protected - - -1,-1 - - - - - - - - - - - OnKeyDown - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT - 0 - - - - 0 - 1 - - - 0 - wxID_DEL4 - Delete - - -1,-1 - m_buttonDel4 - protected - - 60,20 - - - - - - - OnButtonDel4 - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALL|wxALIGN_CENTER_VERTICAL - 0 - - - - 1 - - - 0 - wxID_ANY - - 0 - 150,-1 - m_textCtrlLabel5 - protected - - - - - - - - - - - - - OnKeyDown - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL - 0 - - - - 1 - - - 0 - wxID_ANY - -1,-1 - 0 - -1,-1 - m_textCtrlField5 - protected - - -1,-1 - - - - - - - - - - - OnKeyDown - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT - 0 - - - - 0 - 1 - - - 0 - wxID_DEL5 - Delete - - -1,-1 - m_buttonDel5 - protected - - 60,20 - - - - - - - OnButtonDel5 - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALL|wxALIGN_CENTER_VERTICAL - 0 - - - - 1 - - - 0 - wxID_ANY - - 0 - 150,-1 - m_textCtrlLabel6 - protected - - - - - - - - - - - - - OnKeyDown - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL - 0 - - - - 1 - - - 0 - wxID_ANY - -1,-1 - 0 - -1,-1 - m_textCtrlField6 - protected - - -1,-1 - - - - - - - - - - - OnKeyDown - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT - 0 - - - - 0 - 1 - - - 0 - wxID_DEL6 - Delete - - -1,-1 - m_buttonDel6 - protected - - 60,20 - - - - - - - OnButtonDel6 - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALL|wxALIGN_CENTER_VERTICAL - 0 - - - - 1 - - - 0 - wxID_ANY - - 0 - 150,-1 - m_textCtrlLabel7 - protected - - - - - - - - - - - - - OnKeyDown - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL - 0 - - - - 1 - - - 0 - wxID_ANY - -1,-1 - 0 - -1,-1 - m_textCtrlField7 - protected - - -1,-1 - - - - - - - - - - - OnKeyDown - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT - 0 - - - - 0 - 1 - - - 0 - wxID_DEL7 - Delete - - -1,-1 - m_buttonDel7 - protected - - 60,20 - - - - - - - OnButtonDel7 - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALL|wxALIGN_CENTER_VERTICAL - 0 - - - - 1 - - - 0 - wxID_ANY - - 0 - 150,-1 - m_textCtrlLabel8 - protected - - - - - - - - - - - - - OnKeyDown - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL - 0 - - - - 1 - - - 0 - wxID_ANY - -1,-1 - 0 - -1,-1 - m_textCtrlField8 - protected - - -1,-1 - - - - - - - - - - - OnKeyDown - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT - 0 - - - - 0 - 1 - - - 0 - wxID_DEL8 - Delete - - -1,-1 - m_buttonDel8 - protected - - 60,20 - - - - - - - OnButtonDel8 - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALL|wxALIGN_CENTER_VERTICAL - 0 - - - - 1 - - - 0 - wxID_ANY - - 0 - 150,-1 - m_textCtrlLabel9 - protected - - - - - - - - - - - - - OnKeyDown - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL - 0 - - - - 1 - - - 0 - wxID_ANY - -1,-1 - 0 - -1,-1 - m_textCtrlField9 - protected - - -1,-1 - - - - - - - - - - - OnKeyDown - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT - 0 - - - - 0 - 1 - - - 0 - wxID_DEL9 - Delete - - -1,-1 - m_buttonDel9 - protected - - 60,20 - - - - - - - OnButtonDel9 - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALL|wxALIGN_CENTER_VERTICAL - 0 - - - - 1 - - - 0 - wxID_ANY - - 0 - 150,-1 - m_textCtrlLabel10 - protected - - - - - - - - - - - - - OnKeyDown - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL - 0 - - - - 1 - - - 0 - wxID_ANY - -1,-1 - 0 - -1,-1 - m_textCtrlField10 - protected - - -1,-1 - - - - - - - - - - - OnKeyDown - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT - 0 - - - - 0 - 1 - - - 0 - wxID_DEL10 - Delete - - -1,-1 - m_buttonDel10 - protected - - 60,20 - - - - - - - OnButtonDel10 - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALL|wxALIGN_CENTER_VERTICAL - 0 - - - - 1 - - - 0 - wxID_ANY - - 0 - 150,-1 - m_textCtrlLabel11 - protected - - - - - - - - - - - - - OnKeyDown - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL - 0 - - - - 1 - - - 0 - wxID_ANY - -1,-1 - 0 - -1,-1 - m_textCtrlField11 - protected - - -1,-1 - - - - - - - - - - - OnKeyDown - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT - 0 - - - - 0 - 1 - - - 0 - wxID_DEL11 - Delete - - -1,-1 - m_buttonDel11 - protected - - 60,20 - - - - - - - OnButtonDel11 - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALL|wxALIGN_CENTER_VERTICAL - 0 - - - - 1 - - - 0 - wxID_ANY - - 0 - 150,-1 - m_textCtrlLabel12 - protected - - - - - - - - - - - - - OnKeyDown - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL - 0 - - - - 1 - - - 0 - wxID_ANY - -1,-1 - 0 - -1,-1 - m_textCtrlField12 - protected - - -1,-1 - - - - - - - - - - - OnKeyDown - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT - 0 - - - - 0 - 1 - - - 0 - wxID_DEL12 - Delete - - -1,-1 - m_buttonDel12 - protected - - 60,20 - - - - - - - OnButtonDel12 - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALL|wxALIGN_CENTER_VERTICAL - 0 - - - - 1 - - - 0 - wxID_ANY - - 0 - 150,-1 - m_textCtrlLabel13 - protected - - - - - - - - - - - - - OnKeyDown - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL - 0 - - - - 1 - - - 0 - wxID_ANY - -1,-1 - 0 - -1,-1 - m_textCtrlField13 - protected - - -1,-1 - - - - - - - - - - - OnKeyDown - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT - 0 - - - - 0 - 1 - - - 0 - wxID_DEL13 - Delete - - -1,-1 - m_buttonDel13 - protected - - 60,20 - - - - - - - OnButtonDel13 - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALL|wxALIGN_CENTER_VERTICAL - 0 - - - - 1 - - - 0 - wxID_ANY - - 0 - 150,-1 - m_textCtrlLabel14 - protected - - - - - - - - - - - - - OnKeyDown - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL - 0 - - - - 1 - - - 0 - wxID_ANY - -1,-1 - 0 - -1,-1 - m_textCtrlField14 - protected - - -1,-1 - - - - - - - - - - - OnKeyDown - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT - 0 - - - - 0 - 1 - - - 0 - wxID_DEL14 - Delete - - -1,-1 - m_buttonDel14 - protected - - 60,20 - - - - - - - OnButtonDel14 - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALL|wxALIGN_CENTER_VERTICAL - 0 - - - - 1 - - - 0 - wxID_ANY - - 0 - 150,-1 - m_textCtrlLabel15 - protected - - - - - - - - - - - - - OnKeyDown - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL - 0 - - - - 1 - - - 0 - wxID_ANY - -1,-1 - 0 - -1,-1 - m_textCtrlField15 - protected - - -1,-1 - - - - - - - - - - - OnKeyDown - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT - 0 - - - - 0 - 1 - - - 0 - wxID_DEL15 - Delete - - -1,-1 - m_buttonDel15 - protected - - 60,20 - - - - - - - OnButtonDel15 - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALL|wxALIGN_CENTER_VERTICAL - 0 - - - - 1 - - - 0 - wxID_ANY - - 0 - 150,-1 - m_textCtrlLabel16 - protected - - - - - - - - - - - - - OnKeyDown - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL - 0 - - - - 1 - - - 0 - wxID_ANY - -1,-1 - 0 - -1,-1 - m_textCtrlField16 - protected - - -1,-1 - - - - - - - - - - - OnKeyDown - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT - 0 - - - - 0 - 1 - - - 0 - wxID_DEL16 - Delete - - -1,-1 - m_buttonDel16 - protected - - 60,20 - - - - - - - OnButtonDel16 - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALL|wxALIGN_CENTER_VERTICAL - 0 - - - - 1 - - - 0 - wxID_ANY - - 0 - 150,-1 - m_textCtrlLabel17 - protected - - - - - - - - - - - - - OnKeyDown - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL - 0 - - - - 1 - - - 0 - wxID_ANY - -1,-1 - 0 - -1,-1 - m_textCtrlField17 - protected - - -1,-1 - - - - - - - - - - - OnKeyDown - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT - 0 - - - - 0 - 1 - - - 0 - wxID_DEL17 - Delete - - -1,-1 - m_buttonDel17 - protected - - 60,20 - - - - - - - OnButtonDel17 - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALL|wxALIGN_CENTER_VERTICAL - 0 - - - - 1 - - - 0 - wxID_ANY - - 0 - 150,-1 - m_textCtrlLabel18 - protected - - - - - - - - - - - - - OnKeyDown - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL - 0 - - - - 1 - - - 0 - wxID_ANY - -1,-1 - 0 - -1,-1 - m_textCtrlField18 - protected - - -1,-1 - - - - - - - - - - - OnKeyDown - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT - 0 - - - - 0 - 1 - - - 0 - wxID_DEL18 - Delete - - -1,-1 - m_buttonDel18 - protected - - 60,20 - - - - - - - OnButtonDel18 - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALL|wxALIGN_CENTER_VERTICAL - 0 - - - - 1 - - - 0 - wxID_ANY - - 0 - 150,-1 - m_textCtrlLabel19 - protected - - - - - - - - - - - - - OnKeyDown - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL - 0 - - - - 1 - - - 0 - wxID_ANY - -1,-1 - 0 - -1,-1 - m_textCtrlField19 - protected - - -1,-1 - - - - - - - - - - - OnKeyDown - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT - 0 - - - - 0 - 1 - - - 0 - wxID_DEL19 - Delete - - -1,-1 - m_buttonDel19 - protected - - 60,20 - - - - - - - OnButtonDel19 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALIGN_CENTER_HORIZONTAL - 0 - - - bSizer25 - wxHORIZONTAL - none - - 5 - wxALL - 0 - - - - 0 - 1 - - - 0 - wxID_ANY - &Add Field - - - m_buttonAddField - protected - - - - - - - - - OnButtonAddField - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALIGN_RIGHT - 0 - - - bSizer26 - wxHORIZONTAL - none - - 5 - wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND - 0 - - - - 0 - 1 - - - 0 - wxID_BUTTONSEND - &Send - - -1,-1 - m_buttonOK - protected - - - - - - - - - OnButtonSend - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND - 0 - - - - 0 - 1 - - - 0 - wxID_BUTTONPREVIEW - &Preview - - -1,-1 - m_buttonPreview - protected - - - - - - - - - OnButtonPreview - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND - 0 - - - - 0 - 1 - - - 0 - wxID_CANCEL - Cancel - - -1,-1 - m_buttonCancel - protected - - - - - - - - - OnButtonCancel - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - wxSYS_COLOUR_MENU - - - 1 - - - - 0 - wxID_ANY - - - CViewProductDialogBase - - 630,520 - wxDEFAULT_FRAME_STYLE|wxRESIZE_BORDER - - Order Form - - - - wxTAB_TRAVERSAL - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - bSizer20 - wxVERTICAL - none - - 5 - wxEXPAND - 1 - - - bSizer116 - wxHORIZONTAL - none - - 5 - wxALL|wxEXPAND - 1 - - - - 1 - - - 1 - wxID_ANY - - - m_htmlWinReviews - protected - - - wxHW_SCROLLBAR_AUTO - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxEXPAND|wxALL - 1 - - wxSYS_COLOUR_WINDOW - - 1 - - - 0 - wxID_ANY - - - m_scrolledWindow - protected - - 5 - 5 - - - - - - wxHSCROLL|wxTAB_TRAVERSAL|wxVSCROLL - - - - - - - - - - - - - - - - - - - - - - - - - - bSizer21 - wxVERTICAL - none - - 5 - wxEXPAND - 0 - - - - 1 - - - 0 - wxID_ANY - - -1,-1 - m_richTextHeading - protected - - -1,50 - wxTE_READONLY - - - - - wxNO_BORDER - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALL|wxEXPAND - 0 - - - - 1 - - - 0 - wxID_ANY - Order Form instructions here multiple lines 1 2 3 4 5 6 - - - m_staticTextInstructions - protected - - - - - - - - - -1 - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALIGN_CENTER_HORIZONTAL - 0 - - - bSizer25 - wxHORIZONTAL - none - - 5 - wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND - 0 - - - - 0 - 1 - - - 0 - wxID_BUTTONSAMPLE - &Submit - - -1,-1 - m_buttonSubmitForm - protected - - - - - - - - - OnButtonSubmitForm - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND - 0 - - - - 0 - 1 - - - 0 - wxID_CANCEL2 - Cancel - - - m_buttonCancelForm - protected - - - - - - - - - OnButtonCancelForm - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALIGN_RIGHT - 0 - - - bSizer26 - wxHORIZONTAL - none - - 5 - wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND - 0 - - - - 0 - 0 - - - 0 - wxID_BUTTONBACK - < &Back - - -1,-1 - m_buttonBack - protected - - - - - - - - - OnButtonBack - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND - 0 - - - - 0 - 1 - - - 0 - wxID_BUTTONNEXT - &Next > - - -1,-1 - m_buttonNext - protected - - - - - - - - - OnButtonNext - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND - 0 - - - - 0 - 1 - - - 0 - wxID_CANCEL - Cancel - - -1,-1 - m_buttonCancel - protected - - - - - - - - - OnButtonCancel - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - wxSYS_COLOUR_MENU - - - 1 - - - - 0 - wxID_ANY - - - CViewOrderDialogBase - - 630,520 - wxDEFAULT_FRAME_STYLE|wxRESIZE_BORDER - - View Order - - - - wxTAB_TRAVERSAL - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - bSizer20 - wxVERTICAL - none - - 5 - wxEXPAND - 1 - - - bSizer116 - wxHORIZONTAL - none - - 5 - wxALL|wxEXPAND - 1 - - - - 1 - - - 0 - wxID_ANY - - - m_htmlWin - protected - - - wxHW_SCROLLBAR_AUTO - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALIGN_RIGHT - 0 - - - bSizer26 - wxHORIZONTAL - none - - 5 - wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND - 0 - - - - 0 - 1 - - - 0 - wxID_OK - OK - - -1,-1 - m_buttonOK - protected - - - - - - - - - OnButtonOK - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - wxSYS_COLOUR_MENU - - - 1 - - - - 0 - wxID_ANY - - - CEditReviewDialogBase - - 630,440 - wxDEFAULT_FRAME_STYLE|wxRESIZE_BORDER - - Enter Review - - - - wxTAB_TRAVERSAL - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - bSizer112 - wxVERTICAL - none - - 5 - - 0 - - 3 - protected - 0 - - - - 5 - wxALL|wxEXPAND - 0 - - - - 1 - - - 0 - wxID_ANY - - - - m_staticTextSeller - protected - - - - - - - - - -1 - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - - 0 - - 3 - protected - 0 - - - - 5 - wxTOP|wxRIGHT|wxLEFT - 0 - - - - 1 - - - 0 - wxID_ANY - Rating - - - m_staticText110 - protected - - - - - - - - - -1 - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALL - 0 - - - " 1 star" " 2 stars" " 3 stars" " 4 stars" " 5 stars" - - 1 - - - 0 - wxID_ANY - - - m_choiceStars - protected - - 0 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxTOP|wxRIGHT|wxLEFT - 0 - - - - 1 - - - 0 - wxID_ANY - Review - - - m_staticText43 - protected - - - - - - - - - -1 - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALL|wxEXPAND - 1 - - - - 1 - - - 0 - wxID_ANY - - 0 - - m_textCtrlReview - protected - - - wxTE_MULTILINE - - - - - - - - - - OnKeyDown - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALIGN_RIGHT - 0 - - - bSizer113 - wxHORIZONTAL - none - - 5 - wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND - 0 - - - - 0 - 1 - - - 0 - wxID_SUBMIT - &Submit - - -1,-1 - m_buttonSubmit - protected - - - - - - - - - OnButtonSubmit - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND - 0 - - - - 0 - 1 - - - 0 - wxID_CANCEL - Cancel - - -1,-1 - m_buttonCancel - protected - - - - - - - - - OnButtonCancel - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- cgit v1.2.3 From 5253d1ab77fab1995ede03fb934edd67f1359ba8 Mon Sep 17 00:00:00 2001 From: s_nakamoto Date: Mon, 15 Feb 2010 04:03:07 +0000 Subject: strip out unfinished product, review and market stuff, enable _() instead of wxT() in uiproject.fbp so it uses wxGetTranslation for the wxFormBuilder generated part of the UI git-svn-id: https://bitcoin.svn.sourceforge.net/svnroot/bitcoin/trunk@64 1a98c847-1fd6-4fd8-948a-caf3550aa51b --- db.cpp | 21 - db.h | 39 - headers.h | 1 - main.cpp | 24 +- makefile | 7 +- makefile.unix.wx2.8 | 7 +- makefile.unix.wx2.9 | 7 +- makefile.vc | 7 +- market.cpp | 264 --- market.h | 182 -- net.cpp | 9 - net.h | 6 - serialize.h | 2 +- ui.cpp | 930 +-------- ui.h | 142 +- uibase.cpp | 851 +------- uibase.h | 287 +-- uiproject.fbp | 5805 +-------------------------------------------------- 18 files changed, 127 insertions(+), 8464 deletions(-) delete mode 100644 market.cpp delete mode 100644 market.h diff --git a/db.cpp b/db.cpp index ff9ece52b1..bbf24a0e70 100644 --- a/db.cpp +++ b/db.cpp @@ -507,27 +507,6 @@ bool LoadAddresses() -// -// CReviewDB -// - -bool CReviewDB::ReadReviews(uint256 hash, vector& vReviews) -{ - vReviews.size(); // msvc workaround, just need to do anything with vReviews - return Read(make_pair(string("reviews"), hash), vReviews); -} - -bool CReviewDB::WriteReviews(uint256 hash, const vector& vReviews) -{ - return Write(make_pair(string("reviews"), hash), vReviews); -} - - - - - - - // // CWalletDB // diff --git a/db.h b/db.h index 538076b5aa..fb4e9268c8 100644 --- a/db.h +++ b/db.h @@ -285,45 +285,6 @@ public: -class CReviewDB : public CDB -{ -public: - CReviewDB(const char* pszMode="r+") : CDB("reviews.dat", pszMode) { } -private: - CReviewDB(const CReviewDB&); - void operator=(const CReviewDB&); -public: - bool ReadUser(uint256 hash, CUser& user) - { - return Read(make_pair(string("user"), hash), user); - } - - bool WriteUser(uint256 hash, const CUser& user) - { - return Write(make_pair(string("user"), hash), user); - } - - bool ReadReviews(uint256 hash, vector& vReviews); - bool WriteReviews(uint256 hash, const vector& vReviews); -}; - - - - - -class CMarketDB : public CDB -{ -public: - CMarketDB(const char* pszMode="r+") : CDB("market.dat", pszMode) { } -private: - CMarketDB(const CMarketDB&); - void operator=(const CMarketDB&); -}; - - - - - class CAddrDB : public CDB { public: diff --git a/headers.h b/headers.h index dda4f9caf2..7fb227ec42 100644 --- a/headers.h +++ b/headers.h @@ -99,7 +99,6 @@ using namespace boost; #include "net.h" #include "irc.h" #include "main.h" -#include "market.h" #include "rpc.h" #include "uibase.h" #include "ui.h" diff --git a/main.cpp b/main.cpp index 0c7aff842b..3391a2994a 100644 --- a/main.cpp +++ b/main.cpp @@ -1706,10 +1706,8 @@ bool AlreadyHave(CTxDB& txdb, const CInv& inv) { switch (inv.type) { - case MSG_TX: return mapTransactions.count(inv.hash) || txdb.ContainsTx(inv.hash); - case MSG_BLOCK: return mapBlockIndex.count(inv.hash) || mapOrphanBlocks.count(inv.hash); - case MSG_REVIEW: return true; - case MSG_PRODUCT: return mapProducts.count(inv.hash); + case MSG_TX: return mapTransactions.count(inv.hash) || txdb.ContainsTx(inv.hash); + case MSG_BLOCK: return mapBlockIndex.count(inv.hash) || mapOrphanBlocks.count(inv.hash); } // Don't know what it is, just say we already got one return true; @@ -2108,24 +2106,6 @@ bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) } - else if (strCommand == "review") - { - CDataStream vMsg(vRecv); - CReview review; - vRecv >> review; - - CInv inv(MSG_REVIEW, review.GetHash()); - pfrom->AddInventoryKnown(inv); - - if (review.AcceptReview()) - { - // Relay the original message as-is in case it's a higher version than we know how to parse - RelayMessage(inv, vMsg); - mapAlreadyAskedFor.erase(inv); - } - } - - else if (strCommand == "block") { auto_ptr pblock(new CBlock); diff --git a/makefile b/makefile index affbe517c7..fb8dd2746b 100644 --- a/makefile +++ b/makefile @@ -25,7 +25,7 @@ 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 WXDEFS=-DWIN32 -D__WXMSW__ -D_WINDOWS -DNOPCH CFLAGS=-mthreads -O0 -w -Wno-invalid-offsetof -Wformat $(DEBUGFLAGS) $(WXDEFS) $(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 market.h rpc.h uibase.h ui.h +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 @@ -50,9 +50,6 @@ obj/net.o: net.cpp $(HEADERS) obj/main.o: main.cpp $(HEADERS) sha.h g++ -c $(CFLAGS) -o $@ $< -obj/market.o: market.cpp $(HEADERS) - g++ -c $(CFLAGS) -o $@ $< - obj/ui.o: ui.cpp $(HEADERS) g++ -c $(CFLAGS) -o $@ $< @@ -73,7 +70,7 @@ obj/ui_res.o: ui.rc rc/bitcoin.ico rc/check.ico rc/send16.bmp rc/send16mask.bmp -OBJS=obj/util.o obj/script.o obj/db.o obj/net.o obj/main.o obj/market.o \ +OBJS=obj/util.o obj/script.o obj/db.o obj/net.o obj/main.o \ obj/ui.o obj/uibase.o obj/sha.o obj/irc.o obj/rpc.o \ obj/ui_res.o diff --git a/makefile.unix.wx2.8 b/makefile.unix.wx2.8 index d3358ab2df..38d9bc0e90 100644 --- a/makefile.unix.wx2.8 +++ b/makefile.unix.wx2.8 @@ -35,7 +35,7 @@ LIBS= \ WXDEFS=-D__WXGTK__ -DNOPCH CFLAGS=-O0 -Wno-invalid-offsetof -Wformat $(DEBUGFLAGS) $(WXDEFS) $(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 market.h rpc.h uibase.h ui.h +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 @@ -60,9 +60,6 @@ obj/net.o: net.cpp $(HEADERS) obj/main.o: main.cpp $(HEADERS) sha.h g++ -c $(CFLAGS) -o $@ $< -obj/market.o: market.cpp $(HEADERS) - g++ -c $(CFLAGS) -o $@ $< - obj/ui.o: ui.cpp $(HEADERS) g++ -c $(CFLAGS) -o $@ $< @@ -80,7 +77,7 @@ obj/rpc.o: rpc.cpp $(HEADERS) -OBJS=obj/util.o obj/script.o obj/db.o obj/net.o obj/main.o obj/market.o \ +OBJS=obj/util.o obj/script.o obj/db.o obj/net.o obj/main.o \ obj/ui.o obj/uibase.o obj/sha.o obj/irc.o obj/rpc.o bitcoin: headers.h.gch $(OBJS) diff --git a/makefile.unix.wx2.9 b/makefile.unix.wx2.9 index 8defcbb6fc..0b3b09b577 100644 --- a/makefile.unix.wx2.9 +++ b/makefile.unix.wx2.9 @@ -35,7 +35,7 @@ LIBS= \ WXDEFS=-D__WXGTK__ -DNOPCH CFLAGS=-O0 -Wno-invalid-offsetof -Wformat $(DEBUGFLAGS) $(WXDEFS) $(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 market.h rpc.h uibase.h ui.h +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 @@ -60,9 +60,6 @@ obj/net.o: net.cpp $(HEADERS) obj/main.o: main.cpp $(HEADERS) sha.h g++ -c $(CFLAGS) -o $@ $< -obj/market.o: market.cpp $(HEADERS) - g++ -c $(CFLAGS) -o $@ $< - obj/ui.o: ui.cpp $(HEADERS) g++ -c $(CFLAGS) -o $@ $< @@ -80,7 +77,7 @@ obj/rpc.o: rpc.cpp $(HEADERS) -OBJS=obj/util.o obj/script.o obj/db.o obj/net.o obj/main.o obj/market.o \ +OBJS=obj/util.o obj/script.o obj/db.o obj/net.o obj/main.o \ obj/ui.o obj/uibase.o obj/sha.o obj/irc.o obj/rpc.o bitcoin: headers.h.gch $(OBJS) diff --git a/makefile.vc b/makefile.vc index 527f246769..5ca8de464c 100644 --- a/makefile.vc +++ b/makefile.vc @@ -23,7 +23,7 @@ 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 WXDEFS=/DWIN32 /D__WXMSW__ /D_WINDOWS /DNOPCH CFLAGS=/c /nologo /Ob0 /MD$(D) /EHsc /GR /Zm300 $(DEBUGFLAGS) $(WXDEFS) $(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 market.h rpc.h uibase.h ui.h +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 @@ -45,9 +45,6 @@ obj\net.obj: net.cpp $(HEADERS) obj\main.obj: main.cpp $(HEADERS) sha.h cl $(CFLAGS) /Fo$@ %s -obj\market.obj: market.cpp $(HEADERS) - cl $(CFLAGS) /Fo$@ %s - obj\ui.obj: ui.cpp $(HEADERS) cl $(CFLAGS) /Fo$@ %s @@ -68,7 +65,7 @@ obj\ui.res: ui.rc rc/bitcoin.ico rc/check.ico rc/send16.bmp rc/send16mask.bmp r -OBJS=obj\util.obj obj\script.obj obj\db.obj obj\net.obj obj\main.obj obj\market.obj \ +OBJS=obj\util.obj obj\script.obj obj\db.obj obj\net.obj obj\main.obj \ obj\ui.obj obj\uibase.obj obj\sha.obj obj\irc.obj obj\rpc.obj \ obj\ui.res diff --git a/market.cpp b/market.cpp deleted file mode 100644 index 22b5365fa4..0000000000 --- a/market.cpp +++ /dev/null @@ -1,264 +0,0 @@ -// Copyright (c) 2009 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" - - - - - - - - - - -// -// Global state variables -// - -//// later figure out how these are persisted -map mapMyProducts; - - - - -map mapProducts; -CCriticalSection cs_mapProducts; - -bool AdvertInsert(const CProduct& product) -{ - uint256 hash = product.GetHash(); - bool fNew = false; - bool fUpdated = false; - - CRITICAL_BLOCK(cs_mapProducts) - { - // Insert or find existing product - pair::iterator, bool> item = mapProducts.insert(make_pair(hash, product)); - CProduct* pproduct = &(*(item.first)).second; - fNew = item.second; - - // Update if newer - if (product.nSequence > pproduct->nSequence) - { - *pproduct = product; - fUpdated = true; - } - } - - //if (fNew) - // NotifyProductAdded(hash); - //else if (fUpdated) - // NotifyProductUpdated(hash); - - return (fNew || fUpdated); -} - -void AdvertErase(const CProduct& product) -{ - uint256 hash = product.GetHash(); - CRITICAL_BLOCK(cs_mapProducts) - mapProducts.erase(hash); - //NotifyProductDeleted(hash); -} - - - - - - - - - - - - - - - - - - - -template -unsigned int Union(T& v1, T& v2) -{ - // v1 = v1 union v2 - // v1 and v2 must be sorted - // returns the number of elements added to v1 - - ///// need to check that this is equivalent, then delete this comment - //vector vUnion(v1.size() + v2.size()); - //vUnion.erase(set_union(v1.begin(), v1.end(), - // v2.begin(), v2.end(), - // vUnion.begin()), - // vUnion.end()); - - T vUnion; - vUnion.reserve(v1.size() + v2.size()); - set_union(v1.begin(), v1.end(), - v2.begin(), v2.end(), - back_inserter(vUnion)); - unsigned int nAdded = vUnion.size() - v1.size(); - if (nAdded > 0) - v1 = vUnion; - return nAdded; -} - -void CUser::AddAtom(unsigned short nAtom, bool fOrigin) -{ - // Ignore duplicates - if (binary_search(vAtomsIn.begin(), vAtomsIn.end(), nAtom) || - find(vAtomsNew.begin(), vAtomsNew.end(), nAtom) != vAtomsNew.end()) - return; - - //// instead of zero atom, should change to free atom that propagates, - //// limited to lower than a certain value like 5 so conflicts quickly - // The zero atom never propagates, - // new atoms always propagate through the user that created them - if (nAtom == 0 || fOrigin) - { - vector vTmp(1, nAtom); - Union(vAtomsIn, vTmp); - if (fOrigin) - vAtomsOut.push_back(nAtom); - return; - } - - vAtomsNew.push_back(nAtom); - - if (vAtomsNew.size() >= nFlowthroughRate || vAtomsOut.empty()) - { - // Select atom to flow through to vAtomsOut - vAtomsOut.push_back(vAtomsNew[GetRand(vAtomsNew.size())]); - - // Merge vAtomsNew into vAtomsIn - sort(vAtomsNew.begin(), vAtomsNew.end()); - Union(vAtomsIn, vAtomsNew); - vAtomsNew.clear(); - } -} - -bool AddAtomsAndPropagate(uint256 hashUserStart, const vector& vAtoms, bool fOrigin) -{ - CReviewDB reviewdb; - map > pmapPropagate[2]; - pmapPropagate[0][hashUserStart] = vAtoms; - - for (int side = 0; !pmapPropagate[side].empty(); side = 1 - side) - { - map >& mapFrom = pmapPropagate[side]; - map >& mapTo = pmapPropagate[1 - side]; - - for (map >::iterator mi = mapFrom.begin(); mi != mapFrom.end(); ++mi) - { - const uint256& hashUser = (*mi).first; - const vector& vReceived = (*mi).second; - - ///// this would be a lot easier on the database if it put the new atom at the beginning of the list, - ///// so the change would be right next to the vector size. - - // Read user - CUser user; - reviewdb.ReadUser(hashUser, user); - unsigned int nIn = user.vAtomsIn.size(); - unsigned int nNew = user.vAtomsNew.size(); - unsigned int nOut = user.vAtomsOut.size(); - - // Add atoms received - foreach(unsigned short nAtom, vReceived) - user.AddAtom(nAtom, fOrigin); - fOrigin = false; - - // Don't bother writing to disk if no changes - if (user.vAtomsIn.size() == nIn && user.vAtomsNew.size() == nNew) - continue; - - // Propagate - if (user.vAtomsOut.size() > nOut) - foreach(const uint256& hash, user.vLinksOut) - mapTo[hash].insert(mapTo[hash].end(), user.vAtomsOut.begin() + nOut, user.vAtomsOut.end()); - - // Write back - if (!reviewdb.WriteUser(hashUser, user)) - return false; - } - mapFrom.clear(); - } - return true; -} - - - - - - -bool CReview::AcceptReview() -{ - // Timestamp - nTime = GetTime(); - - // Check signature - if (!CKey::Verify(vchPubKeyFrom, GetSigHash(), vchSig)) - return false; - - CReviewDB reviewdb; - - // Add review text to recipient - vector vReviews; - reviewdb.ReadReviews(hashTo, vReviews); - vReviews.push_back(*this); - if (!reviewdb.WriteReviews(hashTo, vReviews)) - return false; - - // Add link from sender - CUser user; - uint256 hashFrom = Hash(vchPubKeyFrom.begin(), vchPubKeyFrom.end()); - reviewdb.ReadUser(hashFrom, user); - user.vLinksOut.push_back(hashTo); - if (!reviewdb.WriteUser(hashFrom, user)) - return false; - - reviewdb.Close(); - - // Propagate atoms to recipient - vector vZeroAtom(1, 0); - if (!AddAtomsAndPropagate(hashTo, user.vAtomsOut.size() ? user.vAtomsOut : vZeroAtom, false)) - return false; - - return true; -} - - - - - -bool CProduct::CheckSignature() -{ - return (CKey::Verify(vchPubKeyFrom, GetSigHash(), vchSig)); -} - -bool CProduct::CheckProduct() -{ - if (!CheckSignature()) - return false; - - // Make sure it's a summary product - if (!mapDetails.empty() || !vOrderForm.empty()) - return false; - - // Look up seller's atom count - CReviewDB reviewdb("r"); - CUser user; - reviewdb.ReadUser(GetUserHash(), user); - nAtoms = user.GetAtomCount(); - reviewdb.Close(); - - ////// delme, this is now done by AdvertInsert - //// Store to memory - //CRITICAL_BLOCK(cs_mapProducts) - // mapProducts[GetHash()] = *this; - - return true; -} diff --git a/market.h b/market.h deleted file mode 100644 index 2714787307..0000000000 --- a/market.h +++ /dev/null @@ -1,182 +0,0 @@ -// Copyright (c) 2009 Satoshi Nakamoto -// Distributed under the MIT/X11 software license, see the accompanying -// file license.txt or http://www.opensource.org/licenses/mit-license.php. - -class CUser; -class CReview; -class CProduct; - -static const unsigned int nFlowthroughRate = 2; - - - - -bool AdvertInsert(const CProduct& product); -void AdvertErase(const CProduct& product); -bool AddAtomsAndPropagate(uint256 hashUserStart, const vector& vAtoms, bool fOrigin); - - - - - - - - -class CUser -{ -public: - vector vAtomsIn; - vector vAtomsNew; - vector vAtomsOut; - vector vLinksOut; - - CUser() - { - } - - IMPLEMENT_SERIALIZE - ( - if (!(nType & SER_GETHASH)) - READWRITE(nVersion); - READWRITE(vAtomsIn); - READWRITE(vAtomsNew); - READWRITE(vAtomsOut); - READWRITE(vLinksOut); - ) - - void SetNull() - { - vAtomsIn.clear(); - vAtomsNew.clear(); - vAtomsOut.clear(); - vLinksOut.clear(); - } - - uint256 GetHash() const { return SerializeHash(*this); } - - - int GetAtomCount() const - { - return (vAtomsIn.size() + vAtomsNew.size()); - } - - void AddAtom(unsigned short nAtom, bool fOrigin); -}; - - - - - - - -class CReview -{ -public: - int nVersion; - uint256 hashTo; - map mapValue; - vector vchPubKeyFrom; - vector vchSig; - - // memory only - unsigned int nTime; - int nAtoms; - - - CReview() - { - nVersion = 1; - hashTo = 0; - nTime = 0; - nAtoms = 0; - } - - IMPLEMENT_SERIALIZE - ( - READWRITE(this->nVersion); - nVersion = this->nVersion; - if (!(nType & SER_DISK)) - READWRITE(hashTo); - READWRITE(mapValue); - READWRITE(vchPubKeyFrom); - if (!(nType & SER_GETHASH)) - READWRITE(vchSig); - ) - - uint256 GetHash() const { return SerializeHash(*this); } - uint256 GetSigHash() const { return SerializeHash(*this, SER_GETHASH|SER_SKIPSIG); } - uint256 GetUserHash() const { return Hash(vchPubKeyFrom.begin(), vchPubKeyFrom.end()); } - - - bool AcceptReview(); -}; - - - - - - - -class CProduct -{ -public: - int nVersion; - CAddress addr; - map mapValue; - map mapDetails; - vector > vOrderForm; - unsigned int nSequence; - vector vchPubKeyFrom; - vector vchSig; - - // disk only - int nAtoms; - - // memory only - set setSources; - - CProduct() - { - nVersion = 1; - nAtoms = 0; - nSequence = 0; - } - - IMPLEMENT_SERIALIZE - ( - READWRITE(this->nVersion); - nVersion = this->nVersion; - READWRITE(addr); - READWRITE(mapValue); - if (!(nType & SER_GETHASH)) - { - READWRITE(mapDetails); - READWRITE(vOrderForm); - READWRITE(nSequence); - } - READWRITE(vchPubKeyFrom); - if (!(nType & SER_GETHASH)) - READWRITE(vchSig); - if (nType & SER_DISK) - READWRITE(nAtoms); - ) - - uint256 GetHash() const { return SerializeHash(*this); } - uint256 GetSigHash() const { return SerializeHash(*this, SER_GETHASH|SER_SKIPSIG); } - uint256 GetUserHash() const { return Hash(vchPubKeyFrom.begin(), vchPubKeyFrom.end()); } - - - bool CheckSignature(); - bool CheckProduct(); -}; - - - - - - - - -extern map mapProducts; -extern CCriticalSection cs_mapProducts; -extern map mapMyProducts; diff --git a/net.cpp b/net.cpp index 061f000a73..8e8127d73b 100644 --- a/net.cpp +++ b/net.cpp @@ -381,11 +381,6 @@ void CNode::CancelSubscribe(unsigned int nChannel) foreach(CNode* pnode, vNodes) if (pnode != this) pnode->PushMessage("sub-cancel", nChannel); - - // Clear memory, no longer subscribed - if (nChannel == MSG_PRODUCT) - CRITICAL_BLOCK(cs_mapProducts) - mapProducts.clear(); } } @@ -497,10 +492,6 @@ void CNode::Cleanup() // All of a nodes broadcasts and subscriptions are automatically torn down // when it goes down, so a node has to stay up to keep its broadcast going. - CRITICAL_BLOCK(cs_mapProducts) - for (map::iterator mi = mapProducts.begin(); mi != mapProducts.end();) - AdvertRemoveSource(this, MSG_PRODUCT, 0, (*(mi++)).second); - // Cancel subscriptions for (unsigned int nChannel = 0; nChannel < vfSubscribe.size(); nChannel++) if (vfSubscribe[nChannel]) diff --git a/net.h b/net.h index ce6f772f49..c7d15460a4 100644 --- a/net.h +++ b/net.h @@ -341,9 +341,6 @@ enum { MSG_TX = 1, MSG_BLOCK, - MSG_REVIEW, - MSG_PRODUCT, - MSG_TABLE, }; static const char* ppszTypeName[] = @@ -351,9 +348,6 @@ static const char* ppszTypeName[] = "ERROR", "tx", "block", - "review", - "product", - "table", }; class CInv diff --git a/serialize.h b/serialize.h index f73773147d..12b58ad1ca 100644 --- a/serialize.h +++ b/serialize.h @@ -20,7 +20,7 @@ class CDataStream; class CAutoFile; static const int VERSION = 201; -static const char* pszSubVer = ".1"; +static const char* pszSubVer = ".2"; diff --git a/ui.cpp b/ui.cpp index aad599c77c..f506fcf3e7 100644 --- a/ui.cpp +++ b/ui.cpp @@ -7,22 +7,15 @@ #include #endif -void ThreadRequestProductDetails(void* parg); -void ThreadRandSendTest(void* parg); bool GetStartOnSystemStartup(); void SetStartOnSystemStartup(bool fAutoStart); DEFINE_EVENT_TYPE(wxEVT_UITHREADCALL) -DEFINE_EVENT_TYPE(wxEVT_REPLY1) -DEFINE_EVENT_TYPE(wxEVT_REPLY2) -DEFINE_EVENT_TYPE(wxEVT_REPLY3) CMainFrame* pframeMain = NULL; CMyTaskBarIcon* ptaskbaricon = NULL; -bool fRandSendTest = false; -void RandSend(); extern int g_isPainting; bool fClosedToTray = false; @@ -210,93 +203,6 @@ int ThreadSafeMessageBox(const string& message, const string& caption, int style -////////////////////////////////////////////////////////////////////////////// -// -// Custom events -// -// If this code gets used again, it should be replaced with something like UIThreadCall - -set setCallbackAvailable; -CCriticalSection cs_setCallbackAvailable; - -void AddCallbackAvailable(void* p) -{ - CRITICAL_BLOCK(cs_setCallbackAvailable) - setCallbackAvailable.insert(p); -} - -void RemoveCallbackAvailable(void* p) -{ - CRITICAL_BLOCK(cs_setCallbackAvailable) - setCallbackAvailable.erase(p); -} - -bool IsCallbackAvailable(void* p) -{ - CRITICAL_BLOCK(cs_setCallbackAvailable) - return setCallbackAvailable.count(p); - return false; -} - -template -void AddPendingCustomEvent(wxEvtHandler* pevthandler, int nEventID, const T pbeginIn, const T pendIn) -{ - // Need to rewrite with something like UIThreadCall - // I'm tired of maintaining this hack that's only called by unfinished unused code. - assert(("Unimplemented", 0)); - //if (!pevthandler) - // return; - // - //const char* pbegin = (pendIn != pbeginIn) ? &pbeginIn[0] : NULL; - //const char* pend = pbegin + (pendIn - pbeginIn) * sizeof(pbeginIn[0]); - //wxCommandEvent event(nEventID); - //wxString strData(wxChar(0), (pend - pbegin) / sizeof(wxChar) + 1); - //memcpy(&strData[0], pbegin, pend - pbegin); - //event.SetString(strData); - //event.SetInt(pend - pbegin); - // - //pevthandler->AddPendingEvent(event); -} - -template -void AddPendingCustomEvent(wxEvtHandler* pevthandler, int nEventID, const T& obj) -{ - CDataStream ss; - ss << obj; - AddPendingCustomEvent(pevthandler, nEventID, ss.begin(), ss.end()); -} - -void AddPendingReplyEvent1(void* pevthandler, CDataStream& vRecv) -{ - if (IsCallbackAvailable(pevthandler)) - AddPendingCustomEvent((wxEvtHandler*)pevthandler, wxEVT_REPLY1, vRecv.begin(), vRecv.end()); -} - -void AddPendingReplyEvent2(void* pevthandler, CDataStream& vRecv) -{ - if (IsCallbackAvailable(pevthandler)) - AddPendingCustomEvent((wxEvtHandler*)pevthandler, wxEVT_REPLY2, vRecv.begin(), vRecv.end()); -} - -void AddPendingReplyEvent3(void* pevthandler, CDataStream& vRecv) -{ - if (IsCallbackAvailable(pevthandler)) - AddPendingCustomEvent((wxEvtHandler*)pevthandler, wxEVT_REPLY3, vRecv.begin(), vRecv.end()); -} - -CDataStream GetStreamFromEvent(const wxCommandEvent& event) -{ - wxString strData = event.GetString(); - const char* pszBegin = strData.c_str(); - return CDataStream(pszBegin, pszBegin + event.GetInt(), SER_NETWORK); -} - - - - - - - ////////////////////////////////////////////////////////////////////////////// // // CMainFrame @@ -1180,16 +1086,6 @@ void CMainFrame::OnMouseEventsAddress(wxMouseEvent& event) event.Skip(); } -void CMainFrame::OnButtonCopy(wxCommandEvent& event) -{ - // Copy address box to clipboard - if (wxTheClipboard->Open()) - { - wxTheClipboard->SetData(new wxTextDataObject(m_textCtrlAddress->GetValue())); - wxTheClipboard->Close(); - } -} - void CMainFrame::OnButtonChange(wxCommandEvent& event) { CYourAddressDialog dialog(this, string(m_textCtrlAddress->GetValue())); @@ -1208,6 +1104,16 @@ void CMainFrame::OnButtonChange(wxCommandEvent& event) } } +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)); @@ -1228,28 +1134,6 @@ void CMainFrame::OnListItemActivated(wxListEvent& event) //pdialog->Show(); } -void CMainFrame::OnListItemActivatedProductsSent(wxListEvent& event) -{ - CProduct& product = *(CProduct*)event.GetItem().GetData(); - CEditProductDialog* pdialog = new CEditProductDialog(this); - pdialog->SetProduct(product); - pdialog->Show(); -} - -void CMainFrame::OnListItemActivatedOrdersSent(wxListEvent& event) -{ - CWalletTx& order = *(CWalletTx*)event.GetItem().GetData(); - CViewOrderDialog* pdialog = new CViewOrderDialog(this, order, false); - pdialog->Show(); -} - -void CMainFrame::OnListItemActivatedOrdersReceived(wxListEvent& event) -{ - CWalletTx& order = *(CWalletTx*)event.GetItem().GetData(); - CViewOrderDialog* pdialog = new CViewOrderDialog(this, order, true); - pdialog->Show(); -} - @@ -2525,800 +2409,6 @@ void CAddressBookDialog::OnClose(wxCloseEvent& event) -////////////////////////////////////////////////////////////////////////////// -// -// CProductsDialog -// - -bool CompareIntStringPairBestFirst(const pair& item1, const pair& item2) -{ - return (item1.first > item2.first); -} - -CProductsDialog::CProductsDialog(wxWindow* parent) : CProductsDialogBase(parent) -{ - // Init column headers - m_listCtrl->InsertColumn(0, "Title", wxLIST_FORMAT_LEFT, 200); - m_listCtrl->InsertColumn(1, "Price", wxLIST_FORMAT_LEFT, 80); - m_listCtrl->InsertColumn(2, "Seller", wxLIST_FORMAT_LEFT, 80); - m_listCtrl->InsertColumn(3, "Stars", wxLIST_FORMAT_LEFT, 50); - m_listCtrl->InsertColumn(4, "Power", wxLIST_FORMAT_LEFT, 50); - - // Tally top categories - map mapTopCategories; - CRITICAL_BLOCK(cs_mapProducts) - for (map::iterator mi = mapProducts.begin(); mi != mapProducts.end(); ++mi) - mapTopCategories[(*mi).second.mapValue["category"]]++; - - // Sort top categories - vector > vTopCategories; - for (map::iterator mi = mapTopCategories.begin(); mi != mapTopCategories.end(); ++mi) - vTopCategories.push_back(make_pair((*mi).second, (*mi).first)); - sort(vTopCategories.begin(), vTopCategories.end(), CompareIntStringPairBestFirst); - - // Fill categories combo box - int nLimit = 250; - for (vector >::iterator it = vTopCategories.begin(); it != vTopCategories.end() && nLimit-- > 0; ++it) - m_comboBoxCategory->Append((*it).second); - - // Fill window with initial search - //wxCommandEvent event; - //OnButtonSearch(event); -} - -void CProductsDialog::OnCombobox(wxCommandEvent& event) -{ - OnButtonSearch(event); -} - -bool CompareProductsBestFirst(const CProduct* p1, const CProduct* p2) -{ - return (p1->nAtoms > p2->nAtoms); -} - -void CProductsDialog::OnButtonSearch(wxCommandEvent& event) -{ - string strCategory = (string)m_comboBoxCategory->GetValue(); - string strSearch = (string)m_textCtrlSearch->GetValue(); - - // Search products - vector vProductsFound; - CRITICAL_BLOCK(cs_mapProducts) - { - for (map::iterator mi = mapProducts.begin(); mi != mapProducts.end(); ++mi) - { - CProduct& product = (*mi).second; - if (product.mapValue["category"].find(strCategory) != -1) - { - if (product.mapValue["title"].find(strSearch) != -1 || - product.mapValue["description"].find(strSearch) != -1 || - product.mapValue["seller"].find(strSearch) != -1) - { - vProductsFound.push_back(&product); - } - } - } - } - - // Sort - sort(vProductsFound.begin(), vProductsFound.end(), CompareProductsBestFirst); - - // Display - foreach(CProduct* pproduct, vProductsFound) - { - InsertLine(m_listCtrl, - pproduct->mapValue["title"], - pproduct->mapValue["price"], - pproduct->mapValue["seller"], - pproduct->mapValue["stars"], - itostr(pproduct->nAtoms)); - } -} - -void CProductsDialog::OnListItemActivated(wxListEvent& event) -{ - // Doubleclick opens product - CViewProductDialog* pdialog = new CViewProductDialog(this, m_vProduct[event.GetIndex()]); - pdialog->Show(); -} - - - - - - - -////////////////////////////////////////////////////////////////////////////// -// -// CEditProductDialog -// - -CEditProductDialog::CEditProductDialog(wxWindow* parent) : CEditProductDialogBase(parent) -{ - m_textCtrlLabel[0 ] = m_textCtrlLabel0; - m_textCtrlLabel[1 ] = m_textCtrlLabel1; - m_textCtrlLabel[2 ] = m_textCtrlLabel2; - m_textCtrlLabel[3 ] = m_textCtrlLabel3; - m_textCtrlLabel[4 ] = m_textCtrlLabel4; - m_textCtrlLabel[5 ] = m_textCtrlLabel5; - m_textCtrlLabel[6 ] = m_textCtrlLabel6; - m_textCtrlLabel[7 ] = m_textCtrlLabel7; - m_textCtrlLabel[8 ] = m_textCtrlLabel8; - m_textCtrlLabel[9 ] = m_textCtrlLabel9; - m_textCtrlLabel[10] = m_textCtrlLabel10; - m_textCtrlLabel[11] = m_textCtrlLabel11; - m_textCtrlLabel[12] = m_textCtrlLabel12; - m_textCtrlLabel[13] = m_textCtrlLabel13; - m_textCtrlLabel[14] = m_textCtrlLabel14; - m_textCtrlLabel[15] = m_textCtrlLabel15; - m_textCtrlLabel[16] = m_textCtrlLabel16; - m_textCtrlLabel[17] = m_textCtrlLabel17; - m_textCtrlLabel[18] = m_textCtrlLabel18; - m_textCtrlLabel[19] = m_textCtrlLabel19; - - m_textCtrlField[0 ] = m_textCtrlField0; - m_textCtrlField[1 ] = m_textCtrlField1; - m_textCtrlField[2 ] = m_textCtrlField2; - m_textCtrlField[3 ] = m_textCtrlField3; - m_textCtrlField[4 ] = m_textCtrlField4; - m_textCtrlField[5 ] = m_textCtrlField5; - m_textCtrlField[6 ] = m_textCtrlField6; - m_textCtrlField[7 ] = m_textCtrlField7; - m_textCtrlField[8 ] = m_textCtrlField8; - m_textCtrlField[9 ] = m_textCtrlField9; - m_textCtrlField[10] = m_textCtrlField10; - m_textCtrlField[11] = m_textCtrlField11; - m_textCtrlField[12] = m_textCtrlField12; - m_textCtrlField[13] = m_textCtrlField13; - m_textCtrlField[14] = m_textCtrlField14; - m_textCtrlField[15] = m_textCtrlField15; - m_textCtrlField[16] = m_textCtrlField16; - m_textCtrlField[17] = m_textCtrlField17; - m_textCtrlField[18] = m_textCtrlField18; - m_textCtrlField[19] = m_textCtrlField19; - - m_buttonDel[0 ] = m_buttonDel0; - m_buttonDel[1 ] = m_buttonDel1; - m_buttonDel[2 ] = m_buttonDel2; - m_buttonDel[3 ] = m_buttonDel3; - m_buttonDel[4 ] = m_buttonDel4; - m_buttonDel[5 ] = m_buttonDel5; - m_buttonDel[6 ] = m_buttonDel6; - m_buttonDel[7 ] = m_buttonDel7; - m_buttonDel[8 ] = m_buttonDel8; - m_buttonDel[9 ] = m_buttonDel9; - m_buttonDel[10] = m_buttonDel10; - m_buttonDel[11] = m_buttonDel11; - m_buttonDel[12] = m_buttonDel12; - m_buttonDel[13] = m_buttonDel13; - m_buttonDel[14] = m_buttonDel14; - m_buttonDel[15] = m_buttonDel15; - m_buttonDel[16] = m_buttonDel16; - m_buttonDel[17] = m_buttonDel17; - m_buttonDel[18] = m_buttonDel18; - m_buttonDel[19] = m_buttonDel19; - - for (int i = 1; i < FIELDS_MAX; i++) - ShowLine(i, false); - - LayoutAll(); -} - -void CEditProductDialog::LayoutAll() -{ - m_scrolledWindow->Layout(); - m_scrolledWindow->GetSizer()->Fit(m_scrolledWindow); - this->Layout(); -} - -void CEditProductDialog::ShowLine(int i, bool fShow) -{ - m_textCtrlLabel[i]->Show(fShow); - m_textCtrlField[i]->Show(fShow); - m_buttonDel[i]->Show(fShow); -} - -void CEditProductDialog::OnButtonDel0(wxCommandEvent& event) { OnButtonDel(event, 0); } -void CEditProductDialog::OnButtonDel1(wxCommandEvent& event) { OnButtonDel(event, 1); } -void CEditProductDialog::OnButtonDel2(wxCommandEvent& event) { OnButtonDel(event, 2); } -void CEditProductDialog::OnButtonDel3(wxCommandEvent& event) { OnButtonDel(event, 3); } -void CEditProductDialog::OnButtonDel4(wxCommandEvent& event) { OnButtonDel(event, 4); } -void CEditProductDialog::OnButtonDel5(wxCommandEvent& event) { OnButtonDel(event, 5); } -void CEditProductDialog::OnButtonDel6(wxCommandEvent& event) { OnButtonDel(event, 6); } -void CEditProductDialog::OnButtonDel7(wxCommandEvent& event) { OnButtonDel(event, 7); } -void CEditProductDialog::OnButtonDel8(wxCommandEvent& event) { OnButtonDel(event, 8); } -void CEditProductDialog::OnButtonDel9(wxCommandEvent& event) { OnButtonDel(event, 9); } -void CEditProductDialog::OnButtonDel10(wxCommandEvent& event) { OnButtonDel(event, 10); } -void CEditProductDialog::OnButtonDel11(wxCommandEvent& event) { OnButtonDel(event, 11); } -void CEditProductDialog::OnButtonDel12(wxCommandEvent& event) { OnButtonDel(event, 12); } -void CEditProductDialog::OnButtonDel13(wxCommandEvent& event) { OnButtonDel(event, 13); } -void CEditProductDialog::OnButtonDel14(wxCommandEvent& event) { OnButtonDel(event, 14); } -void CEditProductDialog::OnButtonDel15(wxCommandEvent& event) { OnButtonDel(event, 15); } -void CEditProductDialog::OnButtonDel16(wxCommandEvent& event) { OnButtonDel(event, 16); } -void CEditProductDialog::OnButtonDel17(wxCommandEvent& event) { OnButtonDel(event, 17); } -void CEditProductDialog::OnButtonDel18(wxCommandEvent& event) { OnButtonDel(event, 18); } -void CEditProductDialog::OnButtonDel19(wxCommandEvent& event) { OnButtonDel(event, 19); } - -void CEditProductDialog::OnButtonDel(wxCommandEvent& event, int n) -{ - Freeze(); - int x, y; - m_scrolledWindow->GetViewStart(&x, &y); - int i; - for (i = n; i < FIELDS_MAX-1; i++) - { - m_textCtrlLabel[i]->SetValue(m_textCtrlLabel[i+1]->GetValue()); - m_textCtrlField[i]->SetValue(m_textCtrlField[i+1]->GetValue()); - if (!m_buttonDel[i+1]->IsShown()) - break; - } - m_textCtrlLabel[i]->SetValue(""); - m_textCtrlField[i]->SetValue(""); - ShowLine(i, false); - m_buttonAddField->Enable(true); - LayoutAll(); - m_scrolledWindow->Scroll(0, y); - Thaw(); -} - -void CEditProductDialog::OnButtonAddField(wxCommandEvent& event) -{ - for (int i = 0; i < FIELDS_MAX; i++) - { - if (!m_buttonDel[i]->IsShown()) - { - Freeze(); - ShowLine(i, true); - if (i == FIELDS_MAX-1) - m_buttonAddField->Enable(false); - LayoutAll(); - m_scrolledWindow->Scroll(0, 99999); - Thaw(); - break; - } - } -} - -void AddToMyProducts(CProduct product) -{ - CProduct& productInsert = mapMyProducts[product.GetHash()]; - productInsert = product; - //InsertLine(pframeMain->m_listCtrlProductsSent, &productInsert, - // product.mapValue["category"], - // product.mapValue["title"].substr(0, 100), - // product.mapValue["description"].substr(0, 100), - // product.mapValue["price"], - // ""); -} - -void CEditProductDialog::OnButtonSend(wxCommandEvent& event) -{ - CProduct product; - GetProduct(product); - - // Sign the detailed product - product.vchPubKeyFrom = keyUser.GetPubKey(); - if (!keyUser.Sign(product.GetSigHash(), product.vchSig)) - { - wxMessageBox("Error digitally signing the product "); - return; - } - - // Save detailed product - AddToMyProducts(product); - - // Strip down to summary product - product.mapDetails.clear(); - product.vOrderForm.clear(); - - // Sign the summary product - if (!keyUser.Sign(product.GetSigHash(), product.vchSig)) - { - wxMessageBox("Error digitally signing the product "); - return; - } - - // Verify - if (!product.CheckProduct()) - { - wxMessageBox("Errors found in product "); - return; - } - - // Broadcast - AdvertStartPublish(pnodeLocalHost, MSG_PRODUCT, 0, product); - - Destroy(); -} - -void CEditProductDialog::OnButtonPreview(wxCommandEvent& event) -{ - CProduct product; - GetProduct(product); - CViewProductDialog* pdialog = new CViewProductDialog(this, product); - pdialog->Show(); -} - -void CEditProductDialog::OnButtonCancel(wxCommandEvent& event) -{ - Destroy(); -} - -void CEditProductDialog::SetProduct(const CProduct& productIn) -{ - CProduct product = productIn; - - m_comboBoxCategory->SetValue(product.mapValue["category"]); - m_textCtrlTitle->SetValue(product.mapValue["title"]); - m_textCtrlPrice->SetValue(product.mapValue["price"]); - m_textCtrlDescription->SetValue(product.mapValue["description"]); - m_textCtrlInstructions->SetValue(product.mapValue["instructions"]); - - for (int i = 0; i < FIELDS_MAX; i++) - { - bool fUsed = i < product.vOrderForm.size(); - m_buttonDel[i]->Show(fUsed); - m_textCtrlLabel[i]->Show(fUsed); - m_textCtrlField[i]->Show(fUsed); - if (!fUsed) - continue; - - m_textCtrlLabel[i]->SetValue(product.vOrderForm[i].first); - string strControl = product.vOrderForm[i].second; - if (strControl.substr(0, 5) == "text=") - m_textCtrlField[i]->SetValue(""); - else if (strControl.substr(0, 7) == "choice=") - m_textCtrlField[i]->SetValue(strControl.substr(7)); - else - m_textCtrlField[i]->SetValue(strControl); - } -} - -void CEditProductDialog::GetProduct(CProduct& product) -{ - // map mapValue; - // vector > vOrderForm; - - product.mapValue["category"] = m_comboBoxCategory->GetValue().Trim(); - product.mapValue["title"] = m_textCtrlTitle->GetValue().Trim(); - product.mapValue["price"] = m_textCtrlPrice->GetValue().Trim(); - product.mapValue["description"] = m_textCtrlDescription->GetValue().Trim(); - product.mapValue["instructions"] = m_textCtrlInstructions->GetValue().Trim(); - - for (int i = 0; i < FIELDS_MAX; i++) - { - if (m_buttonDel[i]->IsShown()) - { - string strLabel = (string)m_textCtrlLabel[i]->GetValue().Trim(); - string strControl = (string)m_textCtrlField[i]->GetValue(); - if (strControl.empty()) - strControl = "text="; - else - strControl = "choice=" + strControl; - product.vOrderForm.push_back(make_pair(strLabel, strControl)); - } - } -} - - - - - - - -////////////////////////////////////////////////////////////////////////////// -// -// CViewProductDialog -// - -CViewProductDialog::CViewProductDialog(wxWindow* parent, const CProduct& productIn) : CViewProductDialogBase(parent) -{ - Connect(wxEVT_REPLY1, wxCommandEventHandler(CViewProductDialog::OnReply1), NULL, this); - AddCallbackAvailable(GetEventHandler()); - - // Fill display with product summary while waiting for details - product = productIn; - UpdateProductDisplay(false); - - m_buttonBack->Enable(false); - m_buttonNext->Enable(!product.vOrderForm.empty()); - m_htmlWinReviews->Show(true); - m_scrolledWindow->Show(false); - this->Layout(); - - // Request details from seller - CreateThread(ThreadRequestProductDetails, new pair(product, GetEventHandler())); -} - -CViewProductDialog::~CViewProductDialog() -{ - RemoveCallbackAvailable(GetEventHandler()); -} - -void ThreadRequestProductDetails(void* parg) -{ - // Extract parameters - pair* pitem = (pair*)parg; - CProduct product = pitem->first; - wxEvtHandler* pevthandler = pitem->second; - delete pitem; - - // Connect to seller - CNode* pnode = ConnectNode(product.addr, 5 * 60); - if (!pnode) - { - CDataStream ssEmpty; - AddPendingReplyEvent1(pevthandler, ssEmpty); - return; - } - - // Request detailed product, with response going to OnReply1 via dialog's event handler - pnode->PushRequest("getdetails", product.GetHash(), AddPendingReplyEvent1, (void*)pevthandler); -} - -void CViewProductDialog::OnReply1(wxCommandEvent& event) -{ - CDataStream ss = GetStreamFromEvent(event); - if (ss.empty()) - { - product.mapValue["description"] = "-- CAN'T CONNECT TO SELLER --\n"; - UpdateProductDisplay(true); - return; - } - - int nRet; - CProduct product2; - try - { - ss >> nRet; - if (nRet > 0) - throw false; - ss >> product2; - if (product2.GetHash() != product.GetHash()) - throw false; - if (!product2.CheckSignature()) - throw false; - } - catch (...) - { - product.mapValue["description"] = "-- INVALID RESPONSE --\n"; - UpdateProductDisplay(true); - return; - } - - product = product2; - UpdateProductDisplay(true); -} - -bool CompareReviewsBestFirst(const CReview* p1, const CReview* p2) -{ - return (p1->nAtoms > p2->nAtoms); -} - -void CViewProductDialog::UpdateProductDisplay(bool fDetails) -{ - // Product and reviews - string strHTML; - strHTML.reserve(4000); - strHTML += "\n" - "\n" - "\n" - "\n" - "\n"; - strHTML += "Category: " + HtmlEscape(product.mapValue["category"]) + "
\n"; - strHTML += "Title: " + HtmlEscape(product.mapValue["title"]) + "
\n"; - strHTML += "Price: " + HtmlEscape(product.mapValue["price"]) + "
\n"; - - if (!fDetails) - strHTML += "Loading details...
\n
\n"; - else - strHTML += HtmlEscape(product.mapValue["description"], true) + "
\n
\n"; - - strHTML += "Reviews:
\n
\n"; - - if (!product.vchPubKeyFrom.empty()) - { - CReviewDB reviewdb("r"); - - // Get reviews - vector vReviews; - reviewdb.ReadReviews(product.GetUserHash(), vReviews); - - // Get reviewer's number of atoms - vector vSortedReviews; - vSortedReviews.reserve(vReviews.size()); - for (vector::reverse_iterator it = vReviews.rbegin(); it != vReviews.rend(); ++it) - { - CReview& review = *it; - CUser user; - reviewdb.ReadUser(review.GetUserHash(), user); - review.nAtoms = user.GetAtomCount(); - vSortedReviews.push_back(&review); - } - - reviewdb.Close(); - - // Sort - stable_sort(vSortedReviews.begin(), vSortedReviews.end(), CompareReviewsBestFirst); - - // Format reviews - foreach(CReview* preview, vSortedReviews) - { - CReview& review = *preview; - int nStars = atoi(review.mapValue["stars"].c_str()); - if (nStars < 1 || nStars > 5) - continue; - - strHTML += "" + itostr(nStars) + (nStars == 1 ? " star" : " stars") + ""; - strHTML += "     "; - strHTML += DateStr(atoi64(review.mapValue["date"])) + "
\n"; - strHTML += HtmlEscape(review.mapValue["review"], true); - strHTML += "
\n
\n"; - } - } - - strHTML += "\n\n"; - - // Shrink capacity to fit - string(strHTML.begin(), strHTML.end()).swap(strHTML); - - m_htmlWinReviews->SetPage(strHTML); - - ///// need to find some other indicator to use so can allow empty order form - if (product.vOrderForm.empty()) - return; - - // Order form - m_staticTextInstructions->SetLabel(product.mapValue["instructions"]); - for (int i = 0; i < FIELDS_MAX; i++) - { - m_staticTextLabel[i] = NULL; - m_textCtrlField[i] = NULL; - m_choiceField[i] = NULL; - } - - // Construct flexgridsizer - wxBoxSizer* bSizer21 = (wxBoxSizer*)m_scrolledWindow->GetSizer(); - wxFlexGridSizer* fgSizer; - fgSizer = new wxFlexGridSizer(0, 2, 0, 0); - fgSizer->AddGrowableCol(1); - fgSizer->SetFlexibleDirection(wxBOTH); - fgSizer->SetNonFlexibleGrowMode(wxFLEX_GROWMODE_SPECIFIED); - - // Construct order form fields - wxWindow* windowLast = NULL; - for (int i = 0; i < product.vOrderForm.size(); i++) - { - string strLabel = product.vOrderForm[i].first; - string strControl = product.vOrderForm[i].second; - - if (strLabel.size() < 20) - strLabel.insert(strLabel.begin(), 20 - strLabel.size(), ' '); - - m_staticTextLabel[i] = new wxStaticText(m_scrolledWindow, wxID_ANY, strLabel, wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT); - m_staticTextLabel[i]->Wrap(-1); - fgSizer->Add(m_staticTextLabel[i], 0, wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxALL, 5); - - if (strControl.substr(0, 5) == "text=") - { - m_textCtrlField[i] = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0); - fgSizer->Add(m_textCtrlField[i], 1, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5); - windowLast = m_textCtrlField[i]; - } - else if (strControl.substr(0, 7) == "choice=") - { - vector vChoices; - ParseString(strControl.substr(7), ',', vChoices); - - wxArrayString arraystring; - foreach(const string& str, vChoices) - arraystring.Add(str); - - m_choiceField[i] = new wxChoice(m_scrolledWindow, wxID_ANY, wxDefaultPosition, wxDefaultSize, arraystring, 0); - fgSizer->Add(m_choiceField[i], 0, wxALL|wxALIGN_CENTER_VERTICAL, 5); - windowLast = m_choiceField[i]; - } - else - { - m_textCtrlField[i] = new wxTextCtrl(m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0); - fgSizer->Add(m_textCtrlField[i], 1, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5); - m_staticTextLabel[i]->Show(false); - m_textCtrlField[i]->Show(false); - } - } - - // Insert after instructions and before submit/cancel buttons - bSizer21->Insert(2, fgSizer, 0, wxEXPAND|wxRIGHT|wxLEFT, 5); - m_scrolledWindow->Layout(); - bSizer21->Fit(m_scrolledWindow); - this->Layout(); - - // Fixup the tab order - m_buttonSubmitForm->MoveAfterInTabOrder(windowLast); - m_buttonCancelForm->MoveAfterInTabOrder(m_buttonSubmitForm); - //m_buttonBack->MoveAfterInTabOrder(m_buttonCancelForm); - //m_buttonNext->MoveAfterInTabOrder(m_buttonBack); - //m_buttonCancel->MoveAfterInTabOrder(m_buttonNext); - this->Layout(); -} - -void CViewProductDialog::GetOrder(CWalletTx& wtx) -{ - wtx.SetNull(); - for (int i = 0; i < product.vOrderForm.size(); i++) - { - string strValue; - if (m_textCtrlField[i]) - strValue = m_textCtrlField[i]->GetValue().Trim(); - else - strValue = m_choiceField[i]->GetStringSelection(); - wtx.vOrderForm.push_back(make_pair(m_staticTextLabel[i]->GetLabel(), strValue)); - } -} - -void CViewProductDialog::OnButtonSubmitForm(wxCommandEvent& event) -{ - m_buttonSubmitForm->Enable(false); - m_buttonCancelForm->Enable(false); - - CWalletTx wtx; - GetOrder(wtx); - - CSendingDialog* pdialog = new CSendingDialog(this, product.addr, atoi64(product.mapValue["price"]), wtx); - if (!pdialog->ShowModal()) - { - m_buttonSubmitForm->Enable(true); - m_buttonCancelForm->Enable(true); - return; - } -} - -void CViewProductDialog::OnButtonCancelForm(wxCommandEvent& event) -{ - Destroy(); -} - -void CViewProductDialog::OnButtonBack(wxCommandEvent& event) -{ - Freeze(); - m_htmlWinReviews->Show(true); - m_scrolledWindow->Show(false); - m_buttonBack->Enable(false); - m_buttonNext->Enable(!product.vOrderForm.empty()); - this->Layout(); - Thaw(); -} - -void CViewProductDialog::OnButtonNext(wxCommandEvent& event) -{ - if (!product.vOrderForm.empty()) - { - Freeze(); - m_htmlWinReviews->Show(false); - m_scrolledWindow->Show(true); - m_buttonBack->Enable(true); - m_buttonNext->Enable(false); - this->Layout(); - Thaw(); - } -} - -void CViewProductDialog::OnButtonCancel(wxCommandEvent& event) -{ - Destroy(); -} - - - - - - - -////////////////////////////////////////////////////////////////////////////// -// -// CViewOrderDialog -// - -CViewOrderDialog::CViewOrderDialog(wxWindow* parent, CWalletTx order, bool fReceived) : CViewOrderDialogBase(parent) -{ - int64 nPrice = (fReceived ? order.GetCredit() : order.GetDebit()); - - string strHTML; - strHTML.reserve(4000); - strHTML += "\n" - "\n" - "\n" - "\n" - "\n"; - strHTML += "Time: " + HtmlEscape(DateTimeStr(order.nTimeReceived)) + "
\n"; - strHTML += "Price: " + HtmlEscape(FormatMoney(nPrice)) + "
\n"; - strHTML += "Status: " + HtmlEscape(FormatTxStatus(order)) + "
\n"; - - strHTML += "\n"; - for (int i = 0; i < order.vOrderForm.size(); i++) - { - strHTML += " "; - strHTML += "\n"; - } - strHTML += "
" + HtmlEscape(order.vOrderForm[i].first) + ":" + HtmlEscape(order.vOrderForm[i].second) + "
\n"; - - strHTML += "\n\n"; - - // Shrink capacity to fit - // (strings are ref counted, so it may live on in SetPage) - string(strHTML.begin(), strHTML.end()).swap(strHTML); - - m_htmlWin->SetPage(strHTML); -} - -void CViewOrderDialog::OnButtonOK(wxCommandEvent& event) -{ - Destroy(); -} - - - - - - - -////////////////////////////////////////////////////////////////////////////// -// -// CEditReviewDialog -// - -CEditReviewDialog::CEditReviewDialog(wxWindow* parent) : CEditReviewDialogBase(parent) -{ -} - -void CEditReviewDialog::OnButtonSubmit(wxCommandEvent& event) -{ - if (m_choiceStars->GetSelection() == -1) - { - wxMessageBox("Please select a rating "); - return; - } - - CReview review; - GetReview(review); - - // Sign the review - review.vchPubKeyFrom = keyUser.GetPubKey(); - if (!keyUser.Sign(review.GetSigHash(), review.vchSig)) - { - wxMessageBox("Unable to digitally sign the review "); - return; - } - - // Broadcast - if (!review.AcceptReview()) - { - wxMessageBox("Save failed "); - return; - } - RelayMessage(CInv(MSG_REVIEW, review.GetHash()), review); - - Destroy(); -} - -void CEditReviewDialog::OnButtonCancel(wxCommandEvent& event) -{ - Destroy(); -} - -void CEditReviewDialog::GetReview(CReview& review) -{ - review.mapValue["time"] = i64tostr(GetAdjustedTime()); - review.mapValue["stars"] = itostr(m_choiceStars->GetSelection()+1); - review.mapValue["review"] = m_textCtrlReview->GetValue(); -} - - - - - - - ////////////////////////////////////////////////////////////////////////////// // // CMyTaskBarIcon diff --git a/ui.h b/ui.h index 43e056596a..da1ada7def 100644 --- a/ui.h +++ b/ui.h @@ -6,12 +6,6 @@ DECLARE_EVENT_TYPE(wxEVT_UITHREADCALL, -1) -DECLARE_EVENT_TYPE(wxEVT_REPLY1, -1) -DECLARE_EVENT_TYPE(wxEVT_REPLY2, -1) -DECLARE_EVENT_TYPE(wxEVT_REPLY3, -1) - - - extern map mapArgs; @@ -57,8 +51,8 @@ protected: void OnButtonAddressBook(wxCommandEvent& event); void OnSetFocusAddress(wxFocusEvent& event); void OnMouseEventsAddress(wxMouseEvent& event); - void OnButtonCopy(wxCommandEvent& event); void OnButtonChange(wxCommandEvent& event); + void OnButtonCopy(wxCommandEvent& event); void OnListColBeginDrag(wxListEvent& event); void OnListItemActivated(wxListEvent& event); void OnListItemActivatedProductsSent(wxListEvent& event); @@ -263,138 +257,6 @@ public: -class CProductsDialog : public CProductsDialogBase -{ -protected: - // Event handlers - void OnKeyDown(wxKeyEvent& event) { HandleCtrlA(event); } - void OnCombobox(wxCommandEvent& event); - void OnButtonSearch(wxCommandEvent& event); - void OnListItemActivated(wxListEvent& event); - -public: - /** Constructor */ - CProductsDialog(wxWindow* parent); - - // Custom - vector m_vProduct; -}; - - - -class CEditProductDialog : public CEditProductDialogBase -{ -protected: - // Event handlers - void OnKeyDown(wxKeyEvent& event) { HandleCtrlA(event); } - void OnButtonDel0(wxCommandEvent& event); - void OnButtonDel1(wxCommandEvent& event); - void OnButtonDel2(wxCommandEvent& event); - void OnButtonDel3(wxCommandEvent& event); - void OnButtonDel4(wxCommandEvent& event); - void OnButtonDel5(wxCommandEvent& event); - void OnButtonDel6(wxCommandEvent& event); - void OnButtonDel7(wxCommandEvent& event); - void OnButtonDel8(wxCommandEvent& event); - void OnButtonDel9(wxCommandEvent& event); - void OnButtonDel10(wxCommandEvent& event); - void OnButtonDel11(wxCommandEvent& event); - void OnButtonDel12(wxCommandEvent& event); - void OnButtonDel13(wxCommandEvent& event); - void OnButtonDel14(wxCommandEvent& event); - void OnButtonDel15(wxCommandEvent& event); - void OnButtonDel16(wxCommandEvent& event); - void OnButtonDel17(wxCommandEvent& event); - void OnButtonDel18(wxCommandEvent& event); - void OnButtonDel19(wxCommandEvent& event); - void OnButtonAddField(wxCommandEvent& event); - void OnButtonSend(wxCommandEvent& event); - void OnButtonPreview(wxCommandEvent& event); - void OnButtonCancel(wxCommandEvent& event); - -public: - /** Constructor */ - CEditProductDialog(wxWindow* parent); - - // Custom - enum { FIELDS_MAX = 20 }; - wxTextCtrl* m_textCtrlLabel[FIELDS_MAX]; - wxTextCtrl* m_textCtrlField[FIELDS_MAX]; - wxButton* m_buttonDel[FIELDS_MAX]; - - void LayoutAll(); - void ShowLine(int i, bool fShow=true); - void OnButtonDel(wxCommandEvent& event, int n); - void SetProduct(const CProduct& productIn); - void GetProduct(CProduct& product); - -}; - - - -class CViewProductDialog : public CViewProductDialogBase -{ -protected: - // Event handlers - void OnButtonSubmitForm(wxCommandEvent& event); - void OnButtonCancelForm(wxCommandEvent& event); - void OnButtonBack(wxCommandEvent& event); - void OnButtonNext(wxCommandEvent& event); - void OnButtonCancel(wxCommandEvent& event); - -public: - /** Constructor */ - CViewProductDialog(wxWindow* parent, const CProduct& productIn); - ~CViewProductDialog(); - - // Custom - CProduct product; - enum { FIELDS_MAX = 20 }; - wxStaticText* m_staticTextLabel[FIELDS_MAX]; - wxTextCtrl* m_textCtrlField[FIELDS_MAX]; - wxChoice* m_choiceField[FIELDS_MAX]; - - void GetOrder(CWalletTx& order); - void UpdateProductDisplay(bool fDetails); - void OnReply1(wxCommandEvent& event); -}; - - - -class CViewOrderDialog : public CViewOrderDialogBase -{ -protected: - // Event handlers - void OnButtonOK(wxCommandEvent& event); - -public: - /** Constructor */ - CViewOrderDialog(wxWindow* parent, CWalletTx order, bool fReceived); - - // Custom - bool fReceived; -}; - - - -class CEditReviewDialog : public CEditReviewDialogBase -{ -protected: - // Event handlers - void OnKeyDown(wxKeyEvent& event) { HandleCtrlA(event); } - void OnButtonSubmit(wxCommandEvent& event); - void OnButtonCancel(wxCommandEvent& event); - -public: - /** Constructor */ - CEditReviewDialog(wxWindow* parent); - - // Custom - void GetReview(CReview& review); -}; - - - class CGetTextFromUserDialog : public CGetTextFromUserDialogBase { protected: @@ -430,6 +292,8 @@ public: m_textCtrl2->SetValue(strValue2); SetSize(wxDefaultCoord, 180); } + if (!fWindows) + SetSize(1.14 * GetSize().GetWidth(), 1.14 * GetSize().GetHeight()); } // Custom diff --git a/uibase.cpp b/uibase.cpp index 08c025facb..03bd791226 100644 --- a/uibase.cpp +++ b/uibase.cpp @@ -27,39 +27,39 @@ CMainFrameBase::CMainFrameBase( wxWindow* parent, wxWindowID id, const wxString& m_menuFile = new wxMenu(); wxMenuItem* m_menuFileExit; - m_menuFileExit = new wxMenuItem( m_menuFile, wxID_ANY, wxString( wxT("E&xit") ) , wxEmptyString, wxITEM_NORMAL ); + m_menuFileExit = new wxMenuItem( m_menuFile, wxID_ANY, wxString( _("E&xit") ) , wxEmptyString, wxITEM_NORMAL ); m_menuFile->Append( m_menuFileExit ); - m_menubar->Append( m_menuFile, wxT("&File") ); + m_menubar->Append( m_menuFile, _("&File") ); m_menuView = new wxMenu(); wxMenuItem* m_menuViewShowGenerated; - m_menuViewShowGenerated = new wxMenuItem( m_menuView, wxID_VIEWSHOWGENERATED, wxString( wxT("&Show Generated Coins") ) , wxEmptyString, wxITEM_CHECK ); + m_menuViewShowGenerated = new wxMenuItem( m_menuView, wxID_VIEWSHOWGENERATED, wxString( _("&Show Generated Coins") ) , wxEmptyString, wxITEM_CHECK ); m_menuView->Append( m_menuViewShowGenerated ); - m_menubar->Append( m_menuView, wxT("&View") ); + m_menubar->Append( m_menuView, _("&View") ); m_menuOptions = new wxMenu(); wxMenuItem* m_menuOptionsGenerateBitcoins; - m_menuOptionsGenerateBitcoins = new wxMenuItem( m_menuOptions, wxID_OPTIONSGENERATEBITCOINS, wxString( wxT("&Generate Coins") ) , wxEmptyString, wxITEM_CHECK ); + m_menuOptionsGenerateBitcoins = new wxMenuItem( m_menuOptions, wxID_OPTIONSGENERATEBITCOINS, wxString( _("&Generate Coins") ) , wxEmptyString, wxITEM_CHECK ); m_menuOptions->Append( m_menuOptionsGenerateBitcoins ); wxMenuItem* m_menuOptionsChangeYourAddress; - m_menuOptionsChangeYourAddress = new wxMenuItem( m_menuOptions, wxID_ANY, wxString( wxT("&Change Your Address...") ) , wxEmptyString, wxITEM_NORMAL ); + m_menuOptionsChangeYourAddress = new wxMenuItem( m_menuOptions, wxID_ANY, wxString( _("&Change Your Address...") ) , wxEmptyString, wxITEM_NORMAL ); m_menuOptions->Append( m_menuOptionsChangeYourAddress ); wxMenuItem* m_menuOptionsOptions; - m_menuOptionsOptions = new wxMenuItem( m_menuOptions, wxID_MENUOPTIONSOPTIONS, wxString( wxT("&Options...") ) , wxEmptyString, wxITEM_NORMAL ); + m_menuOptionsOptions = new wxMenuItem( m_menuOptions, wxID_MENUOPTIONSOPTIONS, wxString( _("&Options...") ) , wxEmptyString, wxITEM_NORMAL ); m_menuOptions->Append( m_menuOptionsOptions ); - m_menubar->Append( m_menuOptions, wxT("&Options") ); + m_menubar->Append( m_menuOptions, _("&Options") ); m_menuHelp = new wxMenu(); wxMenuItem* m_menuHelpAbout; - m_menuHelpAbout = new wxMenuItem( m_menuHelp, wxID_ANY, wxString( wxT("&About...") ) , wxEmptyString, wxITEM_NORMAL ); + m_menuHelpAbout = new wxMenuItem( m_menuHelp, wxID_ANY, wxString( _("&About...") ) , wxEmptyString, wxITEM_NORMAL ); m_menuHelp->Append( m_menuHelpAbout ); - m_menubar->Append( m_menuHelp, wxT("&Help") ); + m_menubar->Append( m_menuHelp, _("&Help") ); this->SetMenuBar( m_menubar ); @@ -68,8 +68,8 @@ CMainFrameBase::CMainFrameBase( wxWindow* parent, wxWindowID id, const wxString& m_toolBar->SetToolSeparation( 1 ); m_toolBar->SetFont( wxFont( wxNORMAL_FONT->GetPointSize(), 70, 90, 90, false, wxEmptyString ) ); - m_toolBar->AddTool( wxID_BUTTONSEND, wxT("&Send Coins"), wxBitmap( send20_xpm ), wxNullBitmap, wxITEM_NORMAL, wxEmptyString, wxEmptyString ); - m_toolBar->AddTool( wxID_BUTTONRECEIVE, wxT("&Address Book"), wxBitmap( addressbook20_xpm ), wxNullBitmap, wxITEM_NORMAL, wxEmptyString, 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 ); @@ -84,7 +84,7 @@ CMainFrameBase::CMainFrameBase( wxWindow* parent, wxWindowID id, const wxString& wxBoxSizer* bSizer85; bSizer85 = new wxBoxSizer( wxHORIZONTAL ); - m_staticText32 = new wxStaticText( this, wxID_ANY, wxT("Your Bitcoin Address:"), wxDefaultPosition, wxDefaultSize, 0 ); + 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 ); @@ -93,13 +93,13 @@ CMainFrameBase::CMainFrameBase( wxWindow* parent, wxWindowID id, const wxString& bSizer85->Add( m_textCtrlAddress, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 ); - m_buttonCopy = new wxButton( this, wxID_BUTTONCOPY, wxT(" &Copy to Clipboard "), wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT ); - bSizer85->Add( m_buttonCopy, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 5 ); + m_buttonNew = new wxButton( this, wxID_BUTTONCHANGE, _("&New..."), wxDefaultPosition, wxDefaultSize, 0 ); + m_buttonNew->Hide(); - m_button91 = new wxButton( this, wxID_BUTTONCHANGE, wxT("C&hange..."), wxDefaultPosition, wxDefaultSize, 0 ); - m_button91->Hide(); + bSizer85->Add( m_buttonNew, 0, wxRIGHT, 5 ); - bSizer85->Add( m_button91, 0, wxRIGHT, 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 ); @@ -113,7 +113,7 @@ CMainFrameBase::CMainFrameBase( wxWindow* parent, wxWindowID id, const wxString& wxBoxSizer* bSizer66; bSizer66 = new wxBoxSizer( wxHORIZONTAL ); - m_staticText41 = new wxStaticText( m_panel14, wxID_ANY, wxT("Balance:"), wxDefaultPosition, wxSize( -1,15 ), 0 ); + m_staticText41 = new wxStaticText( m_panel14, wxID_ANY, _("Balance:"), wxDefaultPosition, wxSize( -1,15 ), 0 ); m_staticText41->Wrap( -1 ); bSizer66->Add( m_staticText41, 0, wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxLEFT, 5 ); @@ -132,7 +132,7 @@ CMainFrameBase::CMainFrameBase( wxWindow* parent, wxWindowID id, const wxString& bSizer3->Add( 0, 0, 0, wxEXPAND, 5 ); - wxString m_choiceFilterChoices[] = { wxT(" All"), wxT(" Sent"), wxT(" Received"), wxT(" In Progress") }; + 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 ); @@ -191,8 +191,8 @@ CMainFrameBase::CMainFrameBase( wxWindow* parent, wxWindowID id, const wxString& 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::OnButtonChange ), NULL, this ); m_buttonCopy->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CMainFrameBase::OnButtonCopy ), NULL, this ); - m_button91->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CMainFrameBase::OnButtonChange ), NULL, this ); m_listCtrl->Connect( wxEVT_COMMAND_LIST_COL_BEGIN_DRAG, wxListEventHandler( CMainFrameBase::OnListColBeginDrag ), NULL, this ); m_listCtrl->Connect( wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler( CMainFrameBase::OnListItemActivated ), NULL, this ); m_listCtrl->Connect( wxEVT_PAINT, wxPaintEventHandler( CMainFrameBase::OnPaintListCtrl ), NULL, this ); @@ -243,8 +243,8 @@ CMainFrameBase::~CMainFrameBase() 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::OnButtonChange ), NULL, this ); m_buttonCopy->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CMainFrameBase::OnButtonCopy ), NULL, this ); - m_button91->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CMainFrameBase::OnButtonChange ), NULL, this ); m_listCtrl->Disconnect( wxEVT_COMMAND_LIST_COL_BEGIN_DRAG, wxListEventHandler( CMainFrameBase::OnListColBeginDrag ), NULL, this ); m_listCtrl->Disconnect( wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler( CMainFrameBase::OnListItemActivated ), NULL, this ); m_listCtrl->Disconnect( wxEVT_PAINT, wxPaintEventHandler( CMainFrameBase::OnPaintListCtrl ), NULL, this ); @@ -268,7 +268,7 @@ CTxDetailsDialogBase::CTxDetailsDialogBase( wxWindow* parent, wxWindowID id, con wxBoxSizer* bSizer65; bSizer65 = new wxBoxSizer( wxHORIZONTAL ); - m_buttonOK = new wxButton( this, wxID_OK, wxT("OK"), wxDefaultPosition, wxSize( -1,-1 ), 0 ); + 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 ); @@ -311,7 +311,7 @@ COptionsDialogBase::COptionsDialogBase( wxWindow* parent, wxWindowID id, const w bSizer69->Add( 0, 16, 0, wxEXPAND, 5 ); - m_staticText32 = new wxStaticText( m_panelMain, wxID_ANY, wxT("Optional transaction fee you give to the nodes that process your transactions."), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticText32 = new wxStaticText( m_panelMain, wxID_ANY, _("Optional transaction fee you give to the nodes that process your transactions."), wxDefaultPosition, wxDefaultSize, 0 ); m_staticText32->Wrap( -1 ); m_staticText32->Hide(); @@ -320,7 +320,7 @@ COptionsDialogBase::COptionsDialogBase( wxWindow* parent, wxWindowID id, const w wxBoxSizer* bSizer56; bSizer56 = new wxBoxSizer( wxHORIZONTAL ); - m_staticText31 = new wxStaticText( m_panelMain, wxID_ANY, wxT("Transaction fee:"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticText31 = new wxStaticText( m_panelMain, wxID_ANY, _("Transaction fee:"), wxDefaultPosition, wxDefaultSize, 0 ); m_staticText31->Wrap( -1 ); m_staticText31->Hide(); @@ -336,35 +336,35 @@ COptionsDialogBase::COptionsDialogBase( wxWindow* parent, wxWindowID id, const w wxBoxSizer* bSizer71; bSizer71 = new wxBoxSizer( wxHORIZONTAL ); - m_checkBoxLimitProcessors = new wxCheckBox( m_panelMain, wxID_ANY, wxT("&Limit coin generation to"), wxDefaultPosition, wxDefaultSize, 0 ); + m_checkBoxLimitProcessors = new wxCheckBox( m_panelMain, wxID_ANY, _("&Limit coin generation to"), wxDefaultPosition, wxDefaultSize, 0 ); bSizer71->Add( m_checkBoxLimitProcessors, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 ); m_spinCtrlLimitProcessors = new wxSpinCtrl( m_panelMain, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize( 48,-1 ), wxSP_ARROW_KEYS, 1, 999, 1 ); bSizer71->Add( m_spinCtrlLimitProcessors, 0, wxALIGN_CENTER_VERTICAL, 5 ); - m_staticText35 = new wxStaticText( m_panelMain, wxID_ANY, wxT("processors"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticText35 = new wxStaticText( m_panelMain, wxID_ANY, _("processors"), wxDefaultPosition, wxDefaultSize, 0 ); m_staticText35->Wrap( -1 ); bSizer71->Add( m_staticText35, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 ); bSizer69->Add( bSizer71, 0, 0, 5 ); - m_checkBoxStartOnSystemStartup = new wxCheckBox( m_panelMain, wxID_ANY, wxT("&Start Bitcoin on system startup"), wxDefaultPosition, wxDefaultSize, 0 ); + 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, wxT("&Minimize to the tray instead of the taskbar"), wxDefaultPosition, wxDefaultSize, 0 ); + 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_checkBoxMinimizeOnClose = new wxCheckBox( m_panelMain, wxID_ANY, wxT("M&inimize to the tray on close"), wxDefaultPosition, wxDefaultSize, 0 ); + 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, wxT("&Connect through socks4 proxy: "), wxDefaultPosition, wxDefaultSize, 0 ); + 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 ); @@ -376,7 +376,7 @@ COptionsDialogBase::COptionsDialogBase( wxWindow* parent, wxWindowID id, const w bSizer103->Add( 18, 0, 0, 0, 5 ); - m_staticTextProxyIP = new wxStaticText( m_panelMain, wxID_ANY, wxT("Proxy &IP:"), wxDefaultPosition, wxDefaultSize, 0 ); + 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 ); @@ -384,7 +384,7 @@ COptionsDialogBase::COptionsDialogBase( wxWindow* parent, wxWindowID id, const w m_textCtrlProxyIP->SetMaxLength( 15 ); bSizer103->Add( m_textCtrlProxyIP, 0, wxALIGN_CENTER_VERTICAL, 5 ); - m_staticTextProxyPort = new wxStaticText( m_panelMain, wxID_ANY, wxT(" &Port:"), wxDefaultPosition, wxDefaultSize, 0 ); + 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 ); @@ -406,19 +406,19 @@ COptionsDialogBase::COptionsDialogBase( wxWindow* parent, wxWindowID id, const w bSizer64->Add( 0, 16, 0, wxEXPAND, 5 ); - m_staticText321 = new wxStaticText( m_panelTest2, wxID_ANY, wxT("Test panel 2 for future expansion"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticText321 = new wxStaticText( m_panelTest2, wxID_ANY, _("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, wxT("Let's not start multiple pages until the first page is filled up"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticText69 = new wxStaticText( m_panelTest2, wxID_ANY, _("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_staticText70 = new wxStaticText( m_panelTest2, wxID_ANY, wxT("MyLabel"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticText70 = new wxStaticText( m_panelTest2, wxID_ANY, _("MyLabel"), wxDefaultPosition, wxDefaultSize, 0 ); m_staticText70->Wrap( -1 ); bSizer64->Add( m_staticText70, 0, wxALL, 5 ); - m_staticText71 = new wxStaticText( m_panelTest2, wxID_ANY, wxT("MyLabel"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticText71 = new wxStaticText( m_panelTest2, wxID_ANY, _("MyLabel"), wxDefaultPosition, wxDefaultSize, 0 ); m_staticText71->Wrap( -1 ); bSizer64->Add( m_staticText71, 0, wxALL, 5 ); @@ -437,13 +437,13 @@ COptionsDialogBase::COptionsDialogBase( wxWindow* parent, wxWindowID id, const w wxBoxSizer* bSizer58; bSizer58 = new wxBoxSizer( wxHORIZONTAL ); - m_buttonOK = new wxButton( this, wxID_OK, wxT("OK"), wxDefaultPosition, wxSize( -1,-1 ), 0 ); + 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, wxT("Cancel"), wxDefaultPosition, wxSize( -1,-1 ), 0 ); + 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, wxT("&Apply"), wxDefaultPosition, wxSize( -1,-1 ), 0 ); + 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 ); @@ -504,13 +504,13 @@ CAboutDialogBase::CAboutDialogBase( wxWindow* parent, wxWindowID id, const wxStr wxBoxSizer* bSizer64; bSizer64 = new wxBoxSizer( wxHORIZONTAL ); - m_staticText40 = new wxStaticText( this, wxID_ANY, wxT("Bitcoin "), wxDefaultPosition, wxDefaultSize, 0 ); + 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, wxT("version"), wxDefaultPosition, wxDefaultSize, 0 ); + 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") ) ); @@ -521,7 +521,7 @@ CAboutDialogBase::CAboutDialogBase( wxWindow* parent, wxWindowID id, const wxStr bSizer631->Add( 0, 4, 0, wxEXPAND, 5 ); - m_staticTextMain = new wxStaticText( this, wxID_ANY, wxT("Copyright © 2009-2010 Satoshi Nakamoto.\n\nThis is experimental software. Do not rely on it for actual financial transactions.\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)."), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticTextMain = new wxStaticText( this, wxID_ANY, _("Copyright © 2009-2010 Satoshi Nakamoto.\n\nThis is experimental software. Do not rely on it for actual financial transactions.\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)."), wxDefaultPosition, wxDefaultSize, 0 ); m_staticTextMain->Wrap( -1 ); bSizer631->Add( m_staticTextMain, 0, wxALL, 5 ); @@ -538,7 +538,7 @@ CAboutDialogBase::CAboutDialogBase( wxWindow* parent, wxWindowID id, const wxStr bSizer61->Add( 0, 0, 1, wxEXPAND, 5 ); - m_buttonOK = new wxButton( this, wxID_OK, wxT("OK"), wxDefaultPosition, wxSize( -1,-1 ), 0 ); + m_buttonOK = new wxButton( this, wxID_OK, _("OK"), wxDefaultPosition, wxSize( -1,-1 ), 0 ); bSizer61->Add( m_buttonOK, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); bSizer60->Add( bSizer61, 0, wxALIGN_RIGHT|wxEXPAND|wxRIGHT, 5 ); @@ -577,7 +577,7 @@ CSendDialogBase::CSendDialogBase( wxWindow* parent, wxWindowID id, const wxStrin fgSizer1->Add( 0, 0, 0, wxEXPAND, 5 ); - m_staticTextInstructions = new wxStaticText( this, wxID_ANY, wxT("Enter the recipient's IP address (e.g. 123.45.6.7) for online transfer with comments and confirmation, \nor Bitcoin address (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJED9L) if recipient is not online."), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticTextInstructions = new wxStaticText( this, wxID_ANY, _("Enter the recipient's IP address (e.g. 123.45.6.7) for online transfer with comments and confirmation, \nor Bitcoin address (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJED9L) if recipient is not online."), wxDefaultPosition, wxDefaultSize, 0 ); m_staticTextInstructions->Wrap( -1 ); fgSizer1->Add( m_staticTextInstructions, 0, wxTOP|wxRIGHT|wxLEFT, 5 ); @@ -591,7 +591,7 @@ CSendDialogBase::CSendDialogBase( wxWindow* parent, wxWindowID id, const wxStrin 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, wxT("Pay &To:"), wxDefaultPosition, wxSize( -1,-1 ), wxALIGN_RIGHT ); + 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 ); @@ -606,17 +606,17 @@ CSendDialogBase::CSendDialogBase( wxWindow* parent, wxWindowID id, const wxStrin wxBoxSizer* bSizer66; bSizer66 = new wxBoxSizer( wxHORIZONTAL ); - m_buttonPaste = new wxButton( this, wxID_BUTTONPASTE, wxT("&Paste"), wxDefaultPosition, wxSize( -1,-1 ), wxBU_EXACTFIT ); + 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, wxT(" Address &Book..."), wxDefaultPosition, wxDefaultSize, 0 ); + 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, wxT("&Amount:"), wxDefaultPosition, wxSize( -1,-1 ), wxALIGN_RIGHT ); + 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 ); @@ -626,13 +626,13 @@ CSendDialogBase::CSendDialogBase( wxWindow* parent, wxWindowID id, const wxStrin fgSizer1->Add( m_textCtrlAmount, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 ); - m_staticText20 = new wxStaticText( this, wxID_ANY, wxT("T&ransfer:"), wxDefaultPosition, wxSize( -1,-1 ), wxALIGN_RIGHT ); + 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[] = { wxT(" Standard") }; + 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 ); @@ -654,7 +654,7 @@ CSendDialogBase::CSendDialogBase( wxWindow* parent, wxWindowID id, const wxStrin wxBoxSizer* bSizer681; bSizer681 = new wxBoxSizer( wxVERTICAL ); - m_staticTextFrom = new wxStaticText( this, wxID_ANY, wxT("&From:"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticTextFrom = new wxStaticText( this, wxID_ANY, _("&From:"), wxDefaultPosition, wxDefaultSize, 0 ); m_staticTextFrom->Wrap( -1 ); bSizer681->Add( m_staticTextFrom, 0, wxBOTTOM|wxLEFT, 5 ); @@ -671,7 +671,7 @@ CSendDialogBase::CSendDialogBase( wxWindow* parent, wxWindowID id, const wxStrin wxBoxSizer* bSizer68; bSizer68 = new wxBoxSizer( wxVERTICAL ); - m_staticTextMessage = new wxStaticText( this, wxID_ANY, wxT("&Message:"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticTextMessage = new wxStaticText( this, wxID_ANY, _("&Message:"), wxDefaultPosition, wxDefaultSize, 0 ); m_staticTextMessage->Wrap( -1 ); bSizer68->Add( m_staticTextMessage, 0, wxTOP|wxBOTTOM|wxLEFT, 5 ); @@ -688,12 +688,12 @@ CSendDialogBase::CSendDialogBase( wxWindow* parent, wxWindowID id, const wxStrin bSizer23->Add( 0, 0, 1, wxEXPAND, 5 ); - m_buttonSend = new wxButton( this, wxID_BUTTONSEND, wxT("&Send"), wxDefaultPosition, wxSize( -1,-1 ), 0 ); + 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, wxT("Cancel"), wxDefaultPosition, wxSize( -1,-1 ), 0 ); + 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 ); @@ -740,7 +740,7 @@ CSendingDialogBase::CSendingDialogBase( wxWindow* parent, wxWindowID id, const w m_staticTextSending->Wrap( -1 ); bSizer68->Add( m_staticTextSending, 0, wxALIGN_CENTER_VERTICAL|wxEXPAND|wxTOP|wxRIGHT|wxLEFT, 8 ); - m_textCtrlStatus = new wxTextCtrl( this, wxID_ANY, wxT("\n\nConnecting..."), wxDefaultPosition, wxDefaultSize, wxTE_CENTRE|wxTE_MULTILINE|wxTE_NO_VSCROLL|wxTE_READONLY|wxNO_BORDER ); + 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 ); @@ -751,12 +751,12 @@ CSendingDialogBase::CSendingDialogBase( wxWindow* parent, wxWindowID id, const w bSizer69->Add( 0, 0, 1, wxEXPAND, 5 ); - m_buttonOK = new wxButton( this, wxID_ANY, wxT("OK"), wxDefaultPosition, wxDefaultSize, 0 ); + 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, wxT("Cancel"), wxDefaultPosition, wxSize( -1,-1 ), 0 ); + 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 ); @@ -790,7 +790,7 @@ CYourAddressDialogBase::CYourAddressDialogBase( wxWindow* parent, wxWindowID id, bSizer68->Add( 0, 5, 0, wxEXPAND, 5 ); - m_staticText45 = new wxStaticText( this, wxID_ANY, wxT("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 = 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 ); @@ -803,19 +803,19 @@ CYourAddressDialogBase::CYourAddressDialogBase( wxWindow* parent, wxWindowID id, bSizer69->Add( 0, 0, 1, wxEXPAND, 5 ); - m_buttonRename = new wxButton( this, wxID_BUTTONRENAME, wxT("&Edit..."), wxDefaultPosition, wxDefaultSize, 0 ); + 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, wxT(" &New Address... "), wxDefaultPosition, wxSize( -1,-1 ), 0 ); + 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, wxT(" &Copy to Clipboard "), wxDefaultPosition, wxSize( -1,-1 ), 0 ); + 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, wxT("OK"), wxDefaultPosition, wxDefaultSize, 0 ); + 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, wxT("Cancel"), wxDefaultPosition, wxSize( -1,-1 ), 0 ); + 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 ); @@ -861,7 +861,7 @@ CAddressBookDialogBase::CAddressBookDialogBase( wxWindow* parent, wxWindowID id, bSizer68->Add( 0, 5, 0, wxEXPAND, 5 ); - m_staticText55 = new wxStaticText( this, wxID_ANY, wxT("Bitcoin Address"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticText55 = new wxStaticText( this, wxID_ANY, _("Bitcoin Address"), wxDefaultPosition, wxDefaultSize, 0 ); m_staticText55->Wrap( -1 ); m_staticText55->Hide(); @@ -876,19 +876,19 @@ CAddressBookDialogBase::CAddressBookDialogBase( wxWindow* parent, wxWindowID id, bSizer69->Add( 0, 0, 1, wxEXPAND, 5 ); - m_buttonEdit = new wxButton( this, wxID_BUTTONEDIT, wxT("&Edit..."), wxDefaultPosition, wxDefaultSize, 0 ); + 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, wxT(" &New Address... "), wxDefaultPosition, wxDefaultSize, 0 ); + m_buttonNew = new wxButton( this, wxID_BUTTONNEW, _(" &New Address... "), wxDefaultPosition, wxDefaultSize, 0 ); bSizer69->Add( m_buttonNew, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); - m_buttonDelete = new wxButton( this, wxID_BUTTONDELETE, wxT("&Delete"), wxDefaultPosition, wxDefaultSize, 0 ); + m_buttonDelete = new wxButton( this, wxID_BUTTONDELETE, _("&Delete"), wxDefaultPosition, wxDefaultSize, 0 ); bSizer69->Add( m_buttonDelete, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); - m_buttonOK = new wxButton( this, wxID_OK, wxT("OK"), wxDefaultPosition, wxSize( -1,-1 ), 0 ); + 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, wxT("Cancel"), wxDefaultPosition, wxSize( -1,-1 ), 0 ); + 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 ); @@ -922,713 +922,6 @@ CAddressBookDialogBase::~CAddressBookDialogBase() m_buttonCancel->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CAddressBookDialogBase::OnButtonCancel ), NULL, this ); } -CProductsDialogBase::CProductsDialogBase( 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* bSizer22; - bSizer22 = new wxBoxSizer( wxVERTICAL ); - - wxBoxSizer* bSizer23; - bSizer23 = new wxBoxSizer( wxHORIZONTAL ); - - m_comboBoxCategory = new wxComboBox( this, wxID_ANY, wxT("(Any Category)"), wxDefaultPosition, wxSize( 150,-1 ), 0, NULL, 0 ); - m_comboBoxCategory->Append( wxT("(Any Category)") ); - bSizer23->Add( m_comboBoxCategory, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); - - m_textCtrlSearch = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); - bSizer23->Add( m_textCtrlSearch, 1, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); - - m_buttonSearch = new wxButton( this, wxID_ANY, wxT("&Search"), wxDefaultPosition, wxDefaultSize, 0 ); - bSizer23->Add( m_buttonSearch, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); - - bSizer22->Add( bSizer23, 0, wxEXPAND|wxTOP|wxBOTTOM|wxRIGHT, 5 ); - - m_listCtrl = new wxListCtrl( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_NO_SORT_HEADER|wxLC_REPORT ); - bSizer22->Add( m_listCtrl, 1, wxALL|wxEXPAND, 5 ); - - this->SetSizer( bSizer22 ); - this->Layout(); - - // Connect Events - m_comboBoxCategory->Connect( wxEVT_COMMAND_COMBOBOX_SELECTED, wxCommandEventHandler( CProductsDialogBase::OnCombobox ), NULL, this ); - m_textCtrlSearch->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CProductsDialogBase::OnKeyDown ), NULL, this ); - m_buttonSearch->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CProductsDialogBase::OnButtonSearch ), NULL, this ); - m_listCtrl->Connect( wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler( CProductsDialogBase::OnListItemActivated ), NULL, this ); -} - -CProductsDialogBase::~CProductsDialogBase() -{ - // Disconnect Events - m_comboBoxCategory->Disconnect( wxEVT_COMMAND_COMBOBOX_SELECTED, wxCommandEventHandler( CProductsDialogBase::OnCombobox ), NULL, this ); - m_textCtrlSearch->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CProductsDialogBase::OnKeyDown ), NULL, this ); - m_buttonSearch->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CProductsDialogBase::OnButtonSearch ), NULL, this ); - m_listCtrl->Disconnect( wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler( CProductsDialogBase::OnListItemActivated ), NULL, this ); -} - -CEditProductDialogBase::CEditProductDialogBase( 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_MENU ) ); - - wxBoxSizer* bSizer20; - bSizer20 = new wxBoxSizer( wxVERTICAL ); - - m_scrolledWindow = new wxScrolledWindow( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxHSCROLL|wxTAB_TRAVERSAL|wxVSCROLL ); - m_scrolledWindow->SetScrollRate( 5, 5 ); - m_scrolledWindow->SetBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_WINDOW ) ); - - wxBoxSizer* bSizer21; - bSizer21 = new wxBoxSizer( wxVERTICAL ); - - wxFlexGridSizer* fgSizer8; - fgSizer8 = new wxFlexGridSizer( 0, 2, 0, 0 ); - fgSizer8->AddGrowableCol( 1 ); - fgSizer8->SetFlexibleDirection( wxBOTH ); - fgSizer8->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED ); - - m_staticText106 = new wxStaticText( m_scrolledWindow, wxID_ANY, wxT("Category"), wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT ); - m_staticText106->Wrap( -1 ); - fgSizer8->Add( m_staticText106, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxTOP|wxBOTTOM|wxLEFT, 5 ); - - m_comboBoxCategory = new wxComboBox( m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0, NULL, 0 ); - m_comboBoxCategory->SetMinSize( wxSize( 180,-1 ) ); - - fgSizer8->Add( m_comboBoxCategory, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); - - m_staticText108 = new wxStaticText( m_scrolledWindow, wxID_ANY, wxT("Title"), wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT ); - m_staticText108->Wrap( -1 ); - fgSizer8->Add( m_staticText108, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxTOP|wxBOTTOM|wxLEFT, 5 ); - - m_textCtrlTitle = new wxTextCtrl( m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); - fgSizer8->Add( m_textCtrlTitle, 1, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); - - m_staticText107 = new wxStaticText( m_scrolledWindow, wxID_ANY, wxT("Price"), wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT ); - m_staticText107->Wrap( -1 ); - fgSizer8->Add( m_staticText107, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxTOP|wxBOTTOM|wxLEFT, 5 ); - - m_textCtrlPrice = new wxTextCtrl( m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); - m_textCtrlPrice->SetMinSize( wxSize( 105,-1 ) ); - - fgSizer8->Add( m_textCtrlPrice, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); - - bSizer21->Add( fgSizer8, 0, wxEXPAND|wxTOP|wxRIGHT|wxLEFT, 5 ); - - m_staticText22 = new wxStaticText( m_scrolledWindow, wxID_ANY, wxT("Page 1: Description"), wxDefaultPosition, wxDefaultSize, 0 ); - m_staticText22->Wrap( -1 ); - bSizer21->Add( m_staticText22, 0, wxTOP|wxRIGHT|wxLEFT, 5 ); - - m_textCtrlDescription = new wxTextCtrl( m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE ); - m_textCtrlDescription->SetMinSize( wxSize( -1,170 ) ); - - bSizer21->Add( m_textCtrlDescription, 0, wxALL|wxEXPAND, 5 ); - - m_staticText23 = new wxStaticText( m_scrolledWindow, wxID_ANY, wxT("Page 2: Order Form"), wxDefaultPosition, wxDefaultSize, 0 ); - m_staticText23->Wrap( -1 ); - bSizer21->Add( m_staticText23, 0, wxTOP|wxRIGHT|wxLEFT, 5 ); - - m_textCtrlInstructions = new wxTextCtrl( m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE ); - m_textCtrlInstructions->SetMinSize( wxSize( -1,120 ) ); - - bSizer21->Add( m_textCtrlInstructions, 0, wxEXPAND|wxALL, 5 ); - - fgSizer5 = new wxFlexGridSizer( 0, 3, 0, 0 ); - fgSizer5->AddGrowableCol( 1 ); - fgSizer5->SetFlexibleDirection( wxBOTH ); - fgSizer5->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED ); - - m_staticText24 = new wxStaticText( m_scrolledWindow, wxID_ANY, wxT("Label"), wxDefaultPosition, wxDefaultSize, 0 ); - m_staticText24->Wrap( -1 ); - fgSizer5->Add( m_staticText24, 0, wxALIGN_CENTER_VERTICAL|wxTOP|wxRIGHT|wxLEFT, 5 ); - - m_staticText25 = new wxStaticText( m_scrolledWindow, wxID_ANY, wxT("Comma separated list of choices, or leave blank for text field"), wxDefaultPosition, wxDefaultSize, 0 ); - m_staticText25->Wrap( -1 ); - fgSizer5->Add( m_staticText25, 0, wxALIGN_CENTER_VERTICAL|wxTOP|wxRIGHT|wxLEFT, 5 ); - - - fgSizer5->Add( 0, 0, 1, wxEXPAND, 5 ); - - m_textCtrlLabel0 = new wxTextCtrl( m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); - m_textCtrlLabel0->SetMinSize( wxSize( 150,-1 ) ); - - fgSizer5->Add( m_textCtrlLabel0, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); - - m_textCtrlField0 = new wxTextCtrl( m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize( -1,-1 ), 0 ); - fgSizer5->Add( m_textCtrlField0, 0, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5 ); - - m_buttonDel0 = new wxButton( m_scrolledWindow, wxID_DEL0, wxT("Delete"), wxDefaultPosition, wxSize( 60,20 ), 0 ); - fgSizer5->Add( m_buttonDel0, 0, wxRIGHT|wxLEFT|wxALIGN_CENTER_VERTICAL, 5 ); - - m_textCtrlLabel1 = new wxTextCtrl( m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); - m_textCtrlLabel1->SetMinSize( wxSize( 150,-1 ) ); - - fgSizer5->Add( m_textCtrlLabel1, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); - - m_textCtrlField1 = new wxTextCtrl( m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize( -1,-1 ), 0 ); - fgSizer5->Add( m_textCtrlField1, 0, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5 ); - - m_buttonDel1 = new wxButton( m_scrolledWindow, wxID_DEL1, wxT("Delete"), wxDefaultPosition, wxSize( 60,20 ), 0 ); - fgSizer5->Add( m_buttonDel1, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 ); - - m_textCtrlLabel2 = new wxTextCtrl( m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); - m_textCtrlLabel2->SetMinSize( wxSize( 150,-1 ) ); - - fgSizer5->Add( m_textCtrlLabel2, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); - - m_textCtrlField2 = new wxTextCtrl( m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize( -1,-1 ), 0 ); - fgSizer5->Add( m_textCtrlField2, 0, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5 ); - - m_buttonDel2 = new wxButton( m_scrolledWindow, wxID_DEL2, wxT("Delete"), wxDefaultPosition, wxSize( 60,20 ), 0 ); - fgSizer5->Add( m_buttonDel2, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 ); - - m_textCtrlLabel3 = new wxTextCtrl( m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); - m_textCtrlLabel3->SetMinSize( wxSize( 150,-1 ) ); - - fgSizer5->Add( m_textCtrlLabel3, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); - - m_textCtrlField3 = new wxTextCtrl( m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize( -1,-1 ), 0 ); - fgSizer5->Add( m_textCtrlField3, 0, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5 ); - - m_buttonDel3 = new wxButton( m_scrolledWindow, wxID_DEL3, wxT("Delete"), wxDefaultPosition, wxSize( 60,20 ), 0 ); - fgSizer5->Add( m_buttonDel3, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 ); - - m_textCtrlLabel4 = new wxTextCtrl( m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); - m_textCtrlLabel4->SetMinSize( wxSize( 150,-1 ) ); - - fgSizer5->Add( m_textCtrlLabel4, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); - - m_textCtrlField4 = new wxTextCtrl( m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize( -1,-1 ), 0 ); - fgSizer5->Add( m_textCtrlField4, 0, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5 ); - - m_buttonDel4 = new wxButton( m_scrolledWindow, wxID_DEL4, wxT("Delete"), wxDefaultPosition, wxSize( 60,20 ), 0 ); - fgSizer5->Add( m_buttonDel4, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 ); - - m_textCtrlLabel5 = new wxTextCtrl( m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); - m_textCtrlLabel5->SetMinSize( wxSize( 150,-1 ) ); - - fgSizer5->Add( m_textCtrlLabel5, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); - - m_textCtrlField5 = new wxTextCtrl( m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize( -1,-1 ), 0 ); - fgSizer5->Add( m_textCtrlField5, 0, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5 ); - - m_buttonDel5 = new wxButton( m_scrolledWindow, wxID_DEL5, wxT("Delete"), wxDefaultPosition, wxSize( 60,20 ), 0 ); - fgSizer5->Add( m_buttonDel5, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 ); - - m_textCtrlLabel6 = new wxTextCtrl( m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); - m_textCtrlLabel6->SetMinSize( wxSize( 150,-1 ) ); - - fgSizer5->Add( m_textCtrlLabel6, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); - - m_textCtrlField6 = new wxTextCtrl( m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize( -1,-1 ), 0 ); - fgSizer5->Add( m_textCtrlField6, 0, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5 ); - - m_buttonDel6 = new wxButton( m_scrolledWindow, wxID_DEL6, wxT("Delete"), wxDefaultPosition, wxSize( 60,20 ), 0 ); - fgSizer5->Add( m_buttonDel6, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 ); - - m_textCtrlLabel7 = new wxTextCtrl( m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); - m_textCtrlLabel7->SetMinSize( wxSize( 150,-1 ) ); - - fgSizer5->Add( m_textCtrlLabel7, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); - - m_textCtrlField7 = new wxTextCtrl( m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize( -1,-1 ), 0 ); - fgSizer5->Add( m_textCtrlField7, 0, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5 ); - - m_buttonDel7 = new wxButton( m_scrolledWindow, wxID_DEL7, wxT("Delete"), wxDefaultPosition, wxSize( 60,20 ), 0 ); - fgSizer5->Add( m_buttonDel7, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 ); - - m_textCtrlLabel8 = new wxTextCtrl( m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); - m_textCtrlLabel8->SetMinSize( wxSize( 150,-1 ) ); - - fgSizer5->Add( m_textCtrlLabel8, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); - - m_textCtrlField8 = new wxTextCtrl( m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize( -1,-1 ), 0 ); - fgSizer5->Add( m_textCtrlField8, 0, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5 ); - - m_buttonDel8 = new wxButton( m_scrolledWindow, wxID_DEL8, wxT("Delete"), wxDefaultPosition, wxSize( 60,20 ), 0 ); - fgSizer5->Add( m_buttonDel8, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 ); - - m_textCtrlLabel9 = new wxTextCtrl( m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); - m_textCtrlLabel9->SetMinSize( wxSize( 150,-1 ) ); - - fgSizer5->Add( m_textCtrlLabel9, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); - - m_textCtrlField9 = new wxTextCtrl( m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize( -1,-1 ), 0 ); - fgSizer5->Add( m_textCtrlField9, 0, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5 ); - - m_buttonDel9 = new wxButton( m_scrolledWindow, wxID_DEL9, wxT("Delete"), wxDefaultPosition, wxSize( 60,20 ), 0 ); - fgSizer5->Add( m_buttonDel9, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 ); - - m_textCtrlLabel10 = new wxTextCtrl( m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); - m_textCtrlLabel10->SetMinSize( wxSize( 150,-1 ) ); - - fgSizer5->Add( m_textCtrlLabel10, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); - - m_textCtrlField10 = new wxTextCtrl( m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize( -1,-1 ), 0 ); - fgSizer5->Add( m_textCtrlField10, 0, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5 ); - - m_buttonDel10 = new wxButton( m_scrolledWindow, wxID_DEL10, wxT("Delete"), wxDefaultPosition, wxSize( 60,20 ), 0 ); - fgSizer5->Add( m_buttonDel10, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 ); - - m_textCtrlLabel11 = new wxTextCtrl( m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); - m_textCtrlLabel11->SetMinSize( wxSize( 150,-1 ) ); - - fgSizer5->Add( m_textCtrlLabel11, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); - - m_textCtrlField11 = new wxTextCtrl( m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize( -1,-1 ), 0 ); - fgSizer5->Add( m_textCtrlField11, 0, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5 ); - - m_buttonDel11 = new wxButton( m_scrolledWindow, wxID_DEL11, wxT("Delete"), wxDefaultPosition, wxSize( 60,20 ), 0 ); - fgSizer5->Add( m_buttonDel11, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 ); - - m_textCtrlLabel12 = new wxTextCtrl( m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); - m_textCtrlLabel12->SetMinSize( wxSize( 150,-1 ) ); - - fgSizer5->Add( m_textCtrlLabel12, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); - - m_textCtrlField12 = new wxTextCtrl( m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize( -1,-1 ), 0 ); - fgSizer5->Add( m_textCtrlField12, 0, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5 ); - - m_buttonDel12 = new wxButton( m_scrolledWindow, wxID_DEL12, wxT("Delete"), wxDefaultPosition, wxSize( 60,20 ), 0 ); - fgSizer5->Add( m_buttonDel12, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 ); - - m_textCtrlLabel13 = new wxTextCtrl( m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); - m_textCtrlLabel13->SetMinSize( wxSize( 150,-1 ) ); - - fgSizer5->Add( m_textCtrlLabel13, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); - - m_textCtrlField13 = new wxTextCtrl( m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize( -1,-1 ), 0 ); - fgSizer5->Add( m_textCtrlField13, 0, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5 ); - - m_buttonDel13 = new wxButton( m_scrolledWindow, wxID_DEL13, wxT("Delete"), wxDefaultPosition, wxSize( 60,20 ), 0 ); - fgSizer5->Add( m_buttonDel13, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 ); - - m_textCtrlLabel14 = new wxTextCtrl( m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); - m_textCtrlLabel14->SetMinSize( wxSize( 150,-1 ) ); - - fgSizer5->Add( m_textCtrlLabel14, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); - - m_textCtrlField14 = new wxTextCtrl( m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize( -1,-1 ), 0 ); - fgSizer5->Add( m_textCtrlField14, 0, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5 ); - - m_buttonDel14 = new wxButton( m_scrolledWindow, wxID_DEL14, wxT("Delete"), wxDefaultPosition, wxSize( 60,20 ), 0 ); - fgSizer5->Add( m_buttonDel14, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 ); - - m_textCtrlLabel15 = new wxTextCtrl( m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); - m_textCtrlLabel15->SetMinSize( wxSize( 150,-1 ) ); - - fgSizer5->Add( m_textCtrlLabel15, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); - - m_textCtrlField15 = new wxTextCtrl( m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize( -1,-1 ), 0 ); - fgSizer5->Add( m_textCtrlField15, 0, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5 ); - - m_buttonDel15 = new wxButton( m_scrolledWindow, wxID_DEL15, wxT("Delete"), wxDefaultPosition, wxSize( 60,20 ), 0 ); - fgSizer5->Add( m_buttonDel15, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 ); - - m_textCtrlLabel16 = new wxTextCtrl( m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); - m_textCtrlLabel16->SetMinSize( wxSize( 150,-1 ) ); - - fgSizer5->Add( m_textCtrlLabel16, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); - - m_textCtrlField16 = new wxTextCtrl( m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize( -1,-1 ), 0 ); - fgSizer5->Add( m_textCtrlField16, 0, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5 ); - - m_buttonDel16 = new wxButton( m_scrolledWindow, wxID_DEL16, wxT("Delete"), wxDefaultPosition, wxSize( 60,20 ), 0 ); - fgSizer5->Add( m_buttonDel16, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 ); - - m_textCtrlLabel17 = new wxTextCtrl( m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); - m_textCtrlLabel17->SetMinSize( wxSize( 150,-1 ) ); - - fgSizer5->Add( m_textCtrlLabel17, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); - - m_textCtrlField17 = new wxTextCtrl( m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize( -1,-1 ), 0 ); - fgSizer5->Add( m_textCtrlField17, 0, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5 ); - - m_buttonDel17 = new wxButton( m_scrolledWindow, wxID_DEL17, wxT("Delete"), wxDefaultPosition, wxSize( 60,20 ), 0 ); - fgSizer5->Add( m_buttonDel17, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 ); - - m_textCtrlLabel18 = new wxTextCtrl( m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); - m_textCtrlLabel18->SetMinSize( wxSize( 150,-1 ) ); - - fgSizer5->Add( m_textCtrlLabel18, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); - - m_textCtrlField18 = new wxTextCtrl( m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize( -1,-1 ), 0 ); - fgSizer5->Add( m_textCtrlField18, 0, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5 ); - - m_buttonDel18 = new wxButton( m_scrolledWindow, wxID_DEL18, wxT("Delete"), wxDefaultPosition, wxSize( 60,20 ), 0 ); - fgSizer5->Add( m_buttonDel18, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 ); - - m_textCtrlLabel19 = new wxTextCtrl( m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); - m_textCtrlLabel19->SetMinSize( wxSize( 150,-1 ) ); - - fgSizer5->Add( m_textCtrlLabel19, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); - - m_textCtrlField19 = new wxTextCtrl( m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize( -1,-1 ), 0 ); - fgSizer5->Add( m_textCtrlField19, 0, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 5 ); - - m_buttonDel19 = new wxButton( m_scrolledWindow, wxID_DEL19, wxT("Delete"), wxDefaultPosition, wxSize( 60,20 ), 0 ); - fgSizer5->Add( m_buttonDel19, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 ); - - bSizer21->Add( fgSizer5, 0, wxEXPAND, 5 ); - - wxBoxSizer* bSizer25; - bSizer25 = new wxBoxSizer( wxHORIZONTAL ); - - m_buttonAddField = new wxButton( m_scrolledWindow, wxID_ANY, wxT("&Add Field"), wxDefaultPosition, wxDefaultSize, 0 ); - bSizer25->Add( m_buttonAddField, 0, wxALL, 5 ); - - bSizer21->Add( bSizer25, 0, wxALIGN_CENTER_HORIZONTAL, 5 ); - - m_scrolledWindow->SetSizer( bSizer21 ); - m_scrolledWindow->Layout(); - bSizer21->Fit( m_scrolledWindow ); - bSizer20->Add( m_scrolledWindow, 1, wxEXPAND|wxALL, 5 ); - - wxBoxSizer* bSizer26; - bSizer26 = new wxBoxSizer( wxHORIZONTAL ); - - m_buttonOK = new wxButton( this, wxID_BUTTONSEND, wxT("&Send"), wxDefaultPosition, wxDefaultSize, 0 ); - bSizer26->Add( m_buttonOK, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); - - m_buttonPreview = new wxButton( this, wxID_BUTTONPREVIEW, wxT("&Preview"), wxDefaultPosition, wxDefaultSize, 0 ); - bSizer26->Add( m_buttonPreview, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); - - m_buttonCancel = new wxButton( this, wxID_CANCEL, wxT("Cancel"), wxDefaultPosition, wxDefaultSize, 0 ); - bSizer26->Add( m_buttonCancel, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); - - bSizer20->Add( bSizer26, 0, wxALIGN_RIGHT, 5 ); - - this->SetSizer( bSizer20 ); - this->Layout(); - - // Connect Events - m_textCtrlTitle->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); - m_textCtrlPrice->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); - m_textCtrlDescription->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); - m_textCtrlInstructions->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); - m_textCtrlLabel0->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); - m_textCtrlField0->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); - m_buttonDel0->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditProductDialogBase::OnButtonDel0 ), NULL, this ); - m_textCtrlLabel1->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); - m_textCtrlField1->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); - m_buttonDel1->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditProductDialogBase::OnButtonDel1 ), NULL, this ); - m_textCtrlLabel2->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); - m_textCtrlField2->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); - m_buttonDel2->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditProductDialogBase::OnButtonDel2 ), NULL, this ); - m_textCtrlLabel3->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); - m_textCtrlField3->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); - m_buttonDel3->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditProductDialogBase::OnButtonDel3 ), NULL, this ); - m_textCtrlLabel4->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); - m_textCtrlField4->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); - m_buttonDel4->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditProductDialogBase::OnButtonDel4 ), NULL, this ); - m_textCtrlLabel5->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); - m_textCtrlField5->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); - m_buttonDel5->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditProductDialogBase::OnButtonDel5 ), NULL, this ); - m_textCtrlLabel6->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); - m_textCtrlField6->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); - m_buttonDel6->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditProductDialogBase::OnButtonDel6 ), NULL, this ); - m_textCtrlLabel7->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); - m_textCtrlField7->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); - m_buttonDel7->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditProductDialogBase::OnButtonDel7 ), NULL, this ); - m_textCtrlLabel8->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); - m_textCtrlField8->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); - m_buttonDel8->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditProductDialogBase::OnButtonDel8 ), NULL, this ); - m_textCtrlLabel9->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); - m_textCtrlField9->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); - m_buttonDel9->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditProductDialogBase::OnButtonDel9 ), NULL, this ); - m_textCtrlLabel10->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); - m_textCtrlField10->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); - m_buttonDel10->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditProductDialogBase::OnButtonDel10 ), NULL, this ); - m_textCtrlLabel11->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); - m_textCtrlField11->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); - m_buttonDel11->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditProductDialogBase::OnButtonDel11 ), NULL, this ); - m_textCtrlLabel12->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); - m_textCtrlField12->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); - m_buttonDel12->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditProductDialogBase::OnButtonDel12 ), NULL, this ); - m_textCtrlLabel13->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); - m_textCtrlField13->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); - m_buttonDel13->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditProductDialogBase::OnButtonDel13 ), NULL, this ); - m_textCtrlLabel14->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); - m_textCtrlField14->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); - m_buttonDel14->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditProductDialogBase::OnButtonDel14 ), NULL, this ); - m_textCtrlLabel15->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); - m_textCtrlField15->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); - m_buttonDel15->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditProductDialogBase::OnButtonDel15 ), NULL, this ); - m_textCtrlLabel16->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); - m_textCtrlField16->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); - m_buttonDel16->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditProductDialogBase::OnButtonDel16 ), NULL, this ); - m_textCtrlLabel17->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); - m_textCtrlField17->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); - m_buttonDel17->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditProductDialogBase::OnButtonDel17 ), NULL, this ); - m_textCtrlLabel18->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); - m_textCtrlField18->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); - m_buttonDel18->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditProductDialogBase::OnButtonDel18 ), NULL, this ); - m_textCtrlLabel19->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); - m_textCtrlField19->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); - m_buttonDel19->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditProductDialogBase::OnButtonDel19 ), NULL, this ); - m_buttonAddField->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditProductDialogBase::OnButtonAddField ), NULL, this ); - m_buttonOK->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditProductDialogBase::OnButtonSend ), NULL, this ); - m_buttonPreview->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditProductDialogBase::OnButtonPreview ), NULL, this ); - m_buttonCancel->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditProductDialogBase::OnButtonCancel ), NULL, this ); -} - -CEditProductDialogBase::~CEditProductDialogBase() -{ - // Disconnect Events - m_textCtrlTitle->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); - m_textCtrlPrice->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); - m_textCtrlDescription->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); - m_textCtrlInstructions->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); - m_textCtrlLabel0->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); - m_textCtrlField0->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); - m_buttonDel0->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditProductDialogBase::OnButtonDel0 ), NULL, this ); - m_textCtrlLabel1->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); - m_textCtrlField1->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); - m_buttonDel1->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditProductDialogBase::OnButtonDel1 ), NULL, this ); - m_textCtrlLabel2->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); - m_textCtrlField2->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); - m_buttonDel2->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditProductDialogBase::OnButtonDel2 ), NULL, this ); - m_textCtrlLabel3->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); - m_textCtrlField3->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); - m_buttonDel3->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditProductDialogBase::OnButtonDel3 ), NULL, this ); - m_textCtrlLabel4->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); - m_textCtrlField4->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); - m_buttonDel4->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditProductDialogBase::OnButtonDel4 ), NULL, this ); - m_textCtrlLabel5->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); - m_textCtrlField5->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); - m_buttonDel5->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditProductDialogBase::OnButtonDel5 ), NULL, this ); - m_textCtrlLabel6->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); - m_textCtrlField6->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); - m_buttonDel6->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditProductDialogBase::OnButtonDel6 ), NULL, this ); - m_textCtrlLabel7->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); - m_textCtrlField7->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); - m_buttonDel7->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditProductDialogBase::OnButtonDel7 ), NULL, this ); - m_textCtrlLabel8->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); - m_textCtrlField8->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); - m_buttonDel8->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditProductDialogBase::OnButtonDel8 ), NULL, this ); - m_textCtrlLabel9->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); - m_textCtrlField9->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); - m_buttonDel9->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditProductDialogBase::OnButtonDel9 ), NULL, this ); - m_textCtrlLabel10->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); - m_textCtrlField10->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); - m_buttonDel10->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditProductDialogBase::OnButtonDel10 ), NULL, this ); - m_textCtrlLabel11->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); - m_textCtrlField11->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); - m_buttonDel11->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditProductDialogBase::OnButtonDel11 ), NULL, this ); - m_textCtrlLabel12->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); - m_textCtrlField12->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); - m_buttonDel12->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditProductDialogBase::OnButtonDel12 ), NULL, this ); - m_textCtrlLabel13->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); - m_textCtrlField13->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); - m_buttonDel13->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditProductDialogBase::OnButtonDel13 ), NULL, this ); - m_textCtrlLabel14->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); - m_textCtrlField14->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); - m_buttonDel14->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditProductDialogBase::OnButtonDel14 ), NULL, this ); - m_textCtrlLabel15->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); - m_textCtrlField15->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); - m_buttonDel15->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditProductDialogBase::OnButtonDel15 ), NULL, this ); - m_textCtrlLabel16->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); - m_textCtrlField16->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); - m_buttonDel16->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditProductDialogBase::OnButtonDel16 ), NULL, this ); - m_textCtrlLabel17->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); - m_textCtrlField17->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); - m_buttonDel17->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditProductDialogBase::OnButtonDel17 ), NULL, this ); - m_textCtrlLabel18->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); - m_textCtrlField18->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); - m_buttonDel18->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditProductDialogBase::OnButtonDel18 ), NULL, this ); - m_textCtrlLabel19->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); - m_textCtrlField19->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditProductDialogBase::OnKeyDown ), NULL, this ); - m_buttonDel19->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditProductDialogBase::OnButtonDel19 ), NULL, this ); - m_buttonAddField->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditProductDialogBase::OnButtonAddField ), NULL, this ); - m_buttonOK->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditProductDialogBase::OnButtonSend ), NULL, this ); - m_buttonPreview->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditProductDialogBase::OnButtonPreview ), NULL, this ); - m_buttonCancel->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditProductDialogBase::OnButtonCancel ), NULL, this ); -} - -CViewProductDialogBase::CViewProductDialogBase( 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_MENU ) ); - - wxBoxSizer* bSizer20; - bSizer20 = new wxBoxSizer( wxVERTICAL ); - - wxBoxSizer* bSizer116; - bSizer116 = new wxBoxSizer( wxHORIZONTAL ); - - m_htmlWinReviews = new wxHtmlWindow( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxHW_SCROLLBAR_AUTO ); - m_htmlWinReviews->Hide(); - - bSizer116->Add( m_htmlWinReviews, 1, wxALL|wxEXPAND, 5 ); - - m_scrolledWindow = new wxScrolledWindow( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxHSCROLL|wxTAB_TRAVERSAL|wxVSCROLL ); - m_scrolledWindow->SetScrollRate( 5, 5 ); - m_scrolledWindow->SetBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_WINDOW ) ); - - wxBoxSizer* bSizer21; - bSizer21 = new wxBoxSizer( wxVERTICAL ); - - m_richTextHeading = new wxRichTextCtrl( m_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize( -1,50 ), wxTE_READONLY|wxNO_BORDER ); - bSizer21->Add( m_richTextHeading, 0, wxEXPAND, 5 ); - - m_staticTextInstructions = new wxStaticText( m_scrolledWindow, wxID_ANY, wxT("Order Form instructions here\nmultiple lines\n1\n2\n3\n4\n5\n6"), wxDefaultPosition, wxDefaultSize, 0 ); - m_staticTextInstructions->Wrap( -1 ); - bSizer21->Add( m_staticTextInstructions, 0, wxALL|wxEXPAND, 5 ); - - wxBoxSizer* bSizer25; - bSizer25 = new wxBoxSizer( wxHORIZONTAL ); - - m_buttonSubmitForm = new wxButton( m_scrolledWindow, wxID_BUTTONSAMPLE, wxT("&Submit"), wxDefaultPosition, wxDefaultSize, 0 ); - bSizer25->Add( m_buttonSubmitForm, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); - - m_buttonCancelForm = new wxButton( m_scrolledWindow, wxID_CANCEL2, wxT("Cancel"), wxDefaultPosition, wxDefaultSize, 0 ); - bSizer25->Add( m_buttonCancelForm, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); - - bSizer21->Add( bSizer25, 0, wxALIGN_CENTER_HORIZONTAL, 5 ); - - m_scrolledWindow->SetSizer( bSizer21 ); - m_scrolledWindow->Layout(); - bSizer21->Fit( m_scrolledWindow ); - bSizer116->Add( m_scrolledWindow, 1, wxEXPAND|wxALL, 5 ); - - bSizer20->Add( bSizer116, 1, wxEXPAND, 5 ); - - wxBoxSizer* bSizer26; - bSizer26 = new wxBoxSizer( wxHORIZONTAL ); - - m_buttonBack = new wxButton( this, wxID_BUTTONBACK, wxT("< &Back "), wxDefaultPosition, wxDefaultSize, 0 ); - m_buttonBack->Enable( false ); - - bSizer26->Add( m_buttonBack, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); - - m_buttonNext = new wxButton( this, wxID_BUTTONNEXT, wxT(" &Next >"), wxDefaultPosition, wxDefaultSize, 0 ); - bSizer26->Add( m_buttonNext, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); - - m_buttonCancel = new wxButton( this, wxID_CANCEL, wxT("Cancel"), wxDefaultPosition, wxDefaultSize, 0 ); - bSizer26->Add( m_buttonCancel, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); - - bSizer20->Add( bSizer26, 0, wxALIGN_RIGHT, 5 ); - - this->SetSizer( bSizer20 ); - this->Layout(); - - // Connect Events - m_buttonSubmitForm->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CViewProductDialogBase::OnButtonSubmitForm ), NULL, this ); - m_buttonCancelForm->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CViewProductDialogBase::OnButtonCancelForm ), NULL, this ); - m_buttonBack->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CViewProductDialogBase::OnButtonBack ), NULL, this ); - m_buttonNext->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CViewProductDialogBase::OnButtonNext ), NULL, this ); - m_buttonCancel->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CViewProductDialogBase::OnButtonCancel ), NULL, this ); -} - -CViewProductDialogBase::~CViewProductDialogBase() -{ - // Disconnect Events - m_buttonSubmitForm->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CViewProductDialogBase::OnButtonSubmitForm ), NULL, this ); - m_buttonCancelForm->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CViewProductDialogBase::OnButtonCancelForm ), NULL, this ); - m_buttonBack->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CViewProductDialogBase::OnButtonBack ), NULL, this ); - m_buttonNext->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CViewProductDialogBase::OnButtonNext ), NULL, this ); - m_buttonCancel->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CViewProductDialogBase::OnButtonCancel ), NULL, this ); -} - -CViewOrderDialogBase::CViewOrderDialogBase( 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_MENU ) ); - - wxBoxSizer* bSizer20; - bSizer20 = new wxBoxSizer( wxVERTICAL ); - - wxBoxSizer* bSizer116; - bSizer116 = new wxBoxSizer( wxHORIZONTAL ); - - m_htmlWin = new wxHtmlWindow( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxHW_SCROLLBAR_AUTO ); - bSizer116->Add( m_htmlWin, 1, wxALL|wxEXPAND, 5 ); - - bSizer20->Add( bSizer116, 1, wxEXPAND, 5 ); - - wxBoxSizer* bSizer26; - bSizer26 = new wxBoxSizer( wxHORIZONTAL ); - - m_buttonOK = new wxButton( this, wxID_OK, wxT("OK"), wxDefaultPosition, wxDefaultSize, 0 ); - bSizer26->Add( m_buttonOK, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); - - bSizer20->Add( bSizer26, 0, wxALIGN_RIGHT, 5 ); - - this->SetSizer( bSizer20 ); - this->Layout(); - - // Connect Events - m_buttonOK->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CViewOrderDialogBase::OnButtonOK ), NULL, this ); -} - -CViewOrderDialogBase::~CViewOrderDialogBase() -{ - // Disconnect Events - m_buttonOK->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CViewOrderDialogBase::OnButtonOK ), NULL, this ); -} - -CEditReviewDialogBase::CEditReviewDialogBase( 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_MENU ) ); - - wxBoxSizer* bSizer112; - bSizer112 = new wxBoxSizer( wxVERTICAL ); - - - bSizer112->Add( 0, 3, 0, 0, 5 ); - - m_staticTextSeller = new wxStaticText( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); - m_staticTextSeller->Wrap( -1 ); - bSizer112->Add( m_staticTextSeller, 0, wxALL|wxEXPAND, 5 ); - - - bSizer112->Add( 0, 3, 0, 0, 5 ); - - m_staticText110 = new wxStaticText( this, wxID_ANY, wxT("Rating"), wxDefaultPosition, wxDefaultSize, 0 ); - m_staticText110->Wrap( -1 ); - bSizer112->Add( m_staticText110, 0, wxTOP|wxRIGHT|wxLEFT, 5 ); - - wxString m_choiceStarsChoices[] = { wxT(" 1 star"), wxT(" 2 stars"), wxT(" 3 stars"), wxT(" 4 stars"), wxT(" 5 stars") }; - int m_choiceStarsNChoices = sizeof( m_choiceStarsChoices ) / sizeof( wxString ); - m_choiceStars = new wxChoice( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, m_choiceStarsNChoices, m_choiceStarsChoices, 0 ); - m_choiceStars->SetSelection( 0 ); - bSizer112->Add( m_choiceStars, 0, wxALL, 5 ); - - m_staticText43 = new wxStaticText( this, wxID_ANY, wxT("Review"), wxDefaultPosition, wxDefaultSize, 0 ); - m_staticText43->Wrap( -1 ); - bSizer112->Add( m_staticText43, 0, wxTOP|wxRIGHT|wxLEFT, 5 ); - - m_textCtrlReview = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE ); - bSizer112->Add( m_textCtrlReview, 1, wxALL|wxEXPAND, 5 ); - - wxBoxSizer* bSizer113; - bSizer113 = new wxBoxSizer( wxHORIZONTAL ); - - m_buttonSubmit = new wxButton( this, wxID_SUBMIT, wxT("&Submit"), wxDefaultPosition, wxDefaultSize, 0 ); - bSizer113->Add( m_buttonSubmit, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); - - m_buttonCancel = new wxButton( this, wxID_CANCEL, wxT("Cancel"), wxDefaultPosition, wxDefaultSize, 0 ); - bSizer113->Add( m_buttonCancel, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); - - bSizer112->Add( bSizer113, 0, wxALIGN_RIGHT, 5 ); - - this->SetSizer( bSizer112 ); - this->Layout(); - - // Connect Events - m_textCtrlReview->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditReviewDialogBase::OnKeyDown ), NULL, this ); - m_buttonSubmit->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditReviewDialogBase::OnButtonSubmit ), NULL, this ); - m_buttonCancel->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditReviewDialogBase::OnButtonCancel ), NULL, this ); -} - -CEditReviewDialogBase::~CEditReviewDialogBase() -{ - // Disconnect Events - m_textCtrlReview->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( CEditReviewDialogBase::OnKeyDown ), NULL, this ); - m_buttonSubmit->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditReviewDialogBase::OnButtonSubmit ), NULL, this ); - m_buttonCancel->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CEditReviewDialogBase::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 ); @@ -1671,10 +964,10 @@ CGetTextFromUserDialogBase::CGetTextFromUserDialogBase( wxWindow* parent, wxWind bSizer80->Add( 0, 0, 1, wxEXPAND, 5 ); - m_buttonOK = new wxButton( this, wxID_OK, wxT("OK"), wxDefaultPosition, wxSize( -1,-1 ), 0 ); + 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, wxT("Cancel"), wxDefaultPosition, wxDefaultSize, 0 ); + 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 ); diff --git a/uibase.h b/uibase.h index faef982989..2dfc2af14d 100644 --- a/uibase.h +++ b/uibase.h @@ -11,6 +11,8 @@ #ifndef __uibase__ #define __uibase__ +#include + #include #include #include @@ -37,8 +39,6 @@ #include #include #include -#include -#include /////////////////////////////////////////////////////////////////////////// @@ -49,8 +49,8 @@ #define wxID_BUTTONSEND 1004 #define wxID_BUTTONRECEIVE 1005 #define wxID_TEXTCTRLADDRESS 1006 -#define wxID_BUTTONCOPY 1007 -#define wxID_BUTTONCHANGE 1008 +#define wxID_BUTTONCHANGE 1007 +#define wxID_BUTTONCOPY 1008 #define wxID_TRANSACTIONFEE 1009 #define wxID_PROXYIP 1010 #define wxID_PROXYPORT 1011 @@ -64,33 +64,7 @@ #define wxID_BUTTONNEW 1019 #define wxID_BUTTONEDIT 1020 #define wxID_BUTTONDELETE 1021 -#define wxID_DEL0 1022 -#define wxID_DEL1 1023 -#define wxID_DEL2 1024 -#define wxID_DEL3 1025 -#define wxID_DEL4 1026 -#define wxID_DEL5 1027 -#define wxID_DEL6 1028 -#define wxID_DEL7 1029 -#define wxID_DEL8 1030 -#define wxID_DEL9 1031 -#define wxID_DEL10 1032 -#define wxID_DEL11 1033 -#define wxID_DEL12 1034 -#define wxID_DEL13 1035 -#define wxID_DEL14 1036 -#define wxID_DEL15 1037 -#define wxID_DEL16 1038 -#define wxID_DEL17 1039 -#define wxID_DEL18 1040 -#define wxID_DEL19 1041 -#define wxID_BUTTONPREVIEW 1042 -#define wxID_BUTTONSAMPLE 1043 -#define wxID_CANCEL2 1044 -#define wxID_BUTTONBACK 1045 -#define wxID_BUTTONNEXT 1046 -#define wxID_SUBMIT 1047 -#define wxID_TEXTCTRL 1048 +#define wxID_TEXTCTRL 1022 /////////////////////////////////////////////////////////////////////////////// /// Class CMainFrameBase @@ -109,8 +83,8 @@ class CMainFrameBase : public wxFrame wxStaticText* m_staticText32; wxTextCtrl* m_textCtrlAddress; + wxButton* m_buttonNew; wxButton* m_buttonCopy; - wxButton* m_button91; wxPanel* m_panel14; wxStaticText* m_staticText41; @@ -137,8 +111,8 @@ class CMainFrameBase : public wxFrame virtual void OnKeyDown( wxKeyEvent& event ){ event.Skip(); } virtual void OnMouseEventsAddress( wxMouseEvent& event ){ event.Skip(); } virtual void OnSetFocusAddress( wxFocusEvent& event ){ event.Skip(); } - virtual void OnButtonCopy( wxCommandEvent& event ){ event.Skip(); } virtual void OnButtonChange( wxCommandEvent& event ){ event.Skip(); } + virtual void OnButtonCopy( wxCommandEvent& event ){ event.Skip(); } virtual void OnListColBeginDrag( wxListEvent& event ){ event.Skip(); } virtual void OnListItemActivated( wxListEvent& event ){ event.Skip(); } virtual void OnPaintListCtrl( wxPaintEvent& event ){ event.Skip(); } @@ -147,7 +121,7 @@ class CMainFrameBase : public wxFrame public: wxMenu* m_menuOptions; wxListCtrl* m_listCtrl; - CMainFrameBase( wxWindow* parent, wxWindowID id = wxID_MAINFRAME, const wxString& title = wxT("Bitcoin"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 712,484 ), long style = wxDEFAULT_FRAME_STYLE|wxRESIZE_BORDER|wxTAB_TRAVERSAL ); + CMainFrameBase( wxWindow* parent, wxWindowID id = wxID_MAINFRAME, const wxString& title = _("Bitcoin"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 712,484 ), long style = wxDEFAULT_FRAME_STYLE|wxRESIZE_BORDER|wxTAB_TRAVERSAL ); ~CMainFrameBase(); }; @@ -168,7 +142,7 @@ class CTxDetailsDialogBase : public wxDialog public: - CTxDetailsDialogBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxT("Transaction Details"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 620,450 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER ); + 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(); }; @@ -223,7 +197,7 @@ class COptionsDialogBase : public wxDialog public: - COptionsDialogBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxT("Options"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 540,360 ), long style = wxDEFAULT_DIALOG_STYLE ); + 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(); }; @@ -251,7 +225,7 @@ class CAboutDialogBase : public wxDialog public: wxStaticText* m_staticTextVersion; - CAboutDialogBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxT("About Bitcoin"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 532,329 ), long style = wxDEFAULT_DIALOG_STYLE ); + CAboutDialogBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("About Bitcoin"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 532,329 ), long style = wxDEFAULT_DIALOG_STYLE ); ~CAboutDialogBase(); }; @@ -298,7 +272,7 @@ class CSendDialogBase : public wxDialog public: - CSendDialogBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxT("Send Coins"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 675,312 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER ); + CSendDialogBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Send Coins"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 675,312 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER ); ~CSendDialogBase(); }; @@ -325,7 +299,7 @@ class CSendingDialogBase : public wxDialog public: - CSendingDialogBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxT("Sending..."), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 442,151 ), long style = wxDEFAULT_DIALOG_STYLE ); + 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(); }; @@ -361,7 +335,7 @@ class CYourAddressDialogBase : public wxDialog public: - CYourAddressDialogBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxT("Your Bitcoin Addresses"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 610,390 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER ); + 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(); }; @@ -397,242 +371,11 @@ class CAddressBookDialogBase : public wxDialog public: wxButton* m_buttonCancel; - CAddressBookDialogBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxT("Address Book"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 610,390 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER ); + 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 CProductsDialogBase -/////////////////////////////////////////////////////////////////////////////// -class CProductsDialogBase : public wxDialog -{ - private: - - protected: - wxComboBox* m_comboBoxCategory; - wxTextCtrl* m_textCtrlSearch; - wxButton* m_buttonSearch; - wxListCtrl* m_listCtrl; - - // Virtual event handlers, overide them in your derived class - virtual void OnCombobox( wxCommandEvent& event ){ event.Skip(); } - virtual void OnKeyDown( wxKeyEvent& event ){ event.Skip(); } - virtual void OnButtonSearch( wxCommandEvent& event ){ event.Skip(); } - virtual void OnListItemActivated( wxListEvent& event ){ event.Skip(); } - - - public: - CProductsDialogBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxT("Marketplace"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 708,535 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER ); - ~CProductsDialogBase(); - -}; - -/////////////////////////////////////////////////////////////////////////////// -/// Class CEditProductDialogBase -/////////////////////////////////////////////////////////////////////////////// -class CEditProductDialogBase : public wxFrame -{ - private: - - protected: - wxScrolledWindow* m_scrolledWindow; - wxStaticText* m_staticText106; - wxComboBox* m_comboBoxCategory; - wxStaticText* m_staticText108; - wxTextCtrl* m_textCtrlTitle; - wxStaticText* m_staticText107; - wxTextCtrl* m_textCtrlPrice; - wxStaticText* m_staticText22; - wxTextCtrl* m_textCtrlDescription; - wxStaticText* m_staticText23; - wxTextCtrl* m_textCtrlInstructions; - wxStaticText* m_staticText24; - wxStaticText* m_staticText25; - - wxTextCtrl* m_textCtrlLabel0; - wxTextCtrl* m_textCtrlField0; - wxButton* m_buttonDel0; - wxTextCtrl* m_textCtrlLabel1; - wxTextCtrl* m_textCtrlField1; - wxButton* m_buttonDel1; - wxTextCtrl* m_textCtrlLabel2; - wxTextCtrl* m_textCtrlField2; - wxButton* m_buttonDel2; - wxTextCtrl* m_textCtrlLabel3; - wxTextCtrl* m_textCtrlField3; - wxButton* m_buttonDel3; - wxTextCtrl* m_textCtrlLabel4; - wxTextCtrl* m_textCtrlField4; - wxButton* m_buttonDel4; - wxTextCtrl* m_textCtrlLabel5; - wxTextCtrl* m_textCtrlField5; - wxButton* m_buttonDel5; - wxTextCtrl* m_textCtrlLabel6; - wxTextCtrl* m_textCtrlField6; - wxButton* m_buttonDel6; - wxTextCtrl* m_textCtrlLabel7; - wxTextCtrl* m_textCtrlField7; - wxButton* m_buttonDel7; - wxTextCtrl* m_textCtrlLabel8; - wxTextCtrl* m_textCtrlField8; - wxButton* m_buttonDel8; - wxTextCtrl* m_textCtrlLabel9; - wxTextCtrl* m_textCtrlField9; - wxButton* m_buttonDel9; - wxTextCtrl* m_textCtrlLabel10; - wxTextCtrl* m_textCtrlField10; - wxButton* m_buttonDel10; - wxTextCtrl* m_textCtrlLabel11; - wxTextCtrl* m_textCtrlField11; - wxButton* m_buttonDel11; - wxTextCtrl* m_textCtrlLabel12; - wxTextCtrl* m_textCtrlField12; - wxButton* m_buttonDel12; - wxTextCtrl* m_textCtrlLabel13; - wxTextCtrl* m_textCtrlField13; - wxButton* m_buttonDel13; - wxTextCtrl* m_textCtrlLabel14; - wxTextCtrl* m_textCtrlField14; - wxButton* m_buttonDel14; - wxTextCtrl* m_textCtrlLabel15; - wxTextCtrl* m_textCtrlField15; - wxButton* m_buttonDel15; - wxTextCtrl* m_textCtrlLabel16; - wxTextCtrl* m_textCtrlField16; - wxButton* m_buttonDel16; - wxTextCtrl* m_textCtrlLabel17; - wxTextCtrl* m_textCtrlField17; - wxButton* m_buttonDel17; - wxTextCtrl* m_textCtrlLabel18; - wxTextCtrl* m_textCtrlField18; - wxButton* m_buttonDel18; - wxTextCtrl* m_textCtrlLabel19; - wxTextCtrl* m_textCtrlField19; - wxButton* m_buttonDel19; - wxButton* m_buttonAddField; - wxButton* m_buttonOK; - wxButton* m_buttonPreview; - wxButton* m_buttonCancel; - - // Virtual event handlers, overide them in your derived class - virtual void OnKeyDown( wxKeyEvent& event ){ event.Skip(); } - virtual void OnButtonDel0( wxCommandEvent& event ){ event.Skip(); } - virtual void OnButtonDel1( wxCommandEvent& event ){ event.Skip(); } - virtual void OnButtonDel2( wxCommandEvent& event ){ event.Skip(); } - virtual void OnButtonDel3( wxCommandEvent& event ){ event.Skip(); } - virtual void OnButtonDel4( wxCommandEvent& event ){ event.Skip(); } - virtual void OnButtonDel5( wxCommandEvent& event ){ event.Skip(); } - virtual void OnButtonDel6( wxCommandEvent& event ){ event.Skip(); } - virtual void OnButtonDel7( wxCommandEvent& event ){ event.Skip(); } - virtual void OnButtonDel8( wxCommandEvent& event ){ event.Skip(); } - virtual void OnButtonDel9( wxCommandEvent& event ){ event.Skip(); } - virtual void OnButtonDel10( wxCommandEvent& event ){ event.Skip(); } - virtual void OnButtonDel11( wxCommandEvent& event ){ event.Skip(); } - virtual void OnButtonDel12( wxCommandEvent& event ){ event.Skip(); } - virtual void OnButtonDel13( wxCommandEvent& event ){ event.Skip(); } - virtual void OnButtonDel14( wxCommandEvent& event ){ event.Skip(); } - virtual void OnButtonDel15( wxCommandEvent& event ){ event.Skip(); } - virtual void OnButtonDel16( wxCommandEvent& event ){ event.Skip(); } - virtual void OnButtonDel17( wxCommandEvent& event ){ event.Skip(); } - virtual void OnButtonDel18( wxCommandEvent& event ){ event.Skip(); } - virtual void OnButtonDel19( wxCommandEvent& event ){ event.Skip(); } - virtual void OnButtonAddField( wxCommandEvent& event ){ event.Skip(); } - virtual void OnButtonSend( wxCommandEvent& event ){ event.Skip(); } - virtual void OnButtonPreview( wxCommandEvent& event ){ event.Skip(); } - virtual void OnButtonCancel( wxCommandEvent& event ){ event.Skip(); } - - - public: - wxFlexGridSizer* fgSizer5; - CEditProductDialogBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxT("Edit Product"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 660,640 ), long style = wxDEFAULT_FRAME_STYLE|wxRESIZE_BORDER|wxTAB_TRAVERSAL ); - ~CEditProductDialogBase(); - -}; - -/////////////////////////////////////////////////////////////////////////////// -/// Class CViewProductDialogBase -/////////////////////////////////////////////////////////////////////////////// -class CViewProductDialogBase : public wxFrame -{ - private: - - protected: - wxHtmlWindow* m_htmlWinReviews; - wxScrolledWindow* m_scrolledWindow; - wxRichTextCtrl* m_richTextHeading; - wxStaticText* m_staticTextInstructions; - wxButton* m_buttonSubmitForm; - wxButton* m_buttonCancelForm; - wxButton* m_buttonBack; - wxButton* m_buttonNext; - wxButton* m_buttonCancel; - - // Virtual event handlers, overide them in your derived class - virtual void OnButtonSubmitForm( wxCommandEvent& event ){ event.Skip(); } - virtual void OnButtonCancelForm( wxCommandEvent& event ){ event.Skip(); } - virtual void OnButtonBack( wxCommandEvent& event ){ event.Skip(); } - virtual void OnButtonNext( wxCommandEvent& event ){ event.Skip(); } - virtual void OnButtonCancel( wxCommandEvent& event ){ event.Skip(); } - - - public: - CViewProductDialogBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxT("Order Form"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 630,520 ), long style = wxDEFAULT_FRAME_STYLE|wxRESIZE_BORDER|wxTAB_TRAVERSAL ); - ~CViewProductDialogBase(); - -}; - -/////////////////////////////////////////////////////////////////////////////// -/// Class CViewOrderDialogBase -/////////////////////////////////////////////////////////////////////////////// -class CViewOrderDialogBase : public wxFrame -{ - 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: - CViewOrderDialogBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxT("View Order"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 630,520 ), long style = wxDEFAULT_FRAME_STYLE|wxRESIZE_BORDER|wxTAB_TRAVERSAL ); - ~CViewOrderDialogBase(); - -}; - -/////////////////////////////////////////////////////////////////////////////// -/// Class CEditReviewDialogBase -/////////////////////////////////////////////////////////////////////////////// -class CEditReviewDialogBase : public wxFrame -{ - private: - - protected: - - wxStaticText* m_staticTextSeller; - - wxStaticText* m_staticText110; - wxChoice* m_choiceStars; - wxStaticText* m_staticText43; - wxTextCtrl* m_textCtrlReview; - wxButton* m_buttonSubmit; - wxButton* m_buttonCancel; - - // Virtual event handlers, overide them in your derived class - virtual void OnKeyDown( wxKeyEvent& event ){ event.Skip(); } - virtual void OnButtonSubmit( wxCommandEvent& event ){ event.Skip(); } - virtual void OnButtonCancel( wxCommandEvent& event ){ event.Skip(); } - - - public: - CEditReviewDialogBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxT("Enter Review"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 630,440 ), long style = wxDEFAULT_FRAME_STYLE|wxRESIZE_BORDER|wxTAB_TRAVERSAL ); - ~CEditReviewDialogBase(); - -}; - /////////////////////////////////////////////////////////////////////////////// /// Class CGetTextFromUserDialogBase /////////////////////////////////////////////////////////////////////////////// diff --git a/uiproject.fbp b/uiproject.fbp index c24f6962b9..5c6eaa55a5 100644 --- a/uiproject.fbp +++ b/uiproject.fbp @@ -10,7 +10,7 @@ uibase 1000 none - 0 + 1 . @@ -18,7 +18,7 @@ 1 0 0 - + wxSYS_COLOUR_BTNFACE @@ -478,7 +478,7 @@ 5 - wxALIGN_CENTER_VERTICAL|wxRIGHT + wxRIGHT 0 @@ -487,22 +487,22 @@ 1 - 0 - wxID_BUTTONCOPY - &Copy to Clipboard + 1 + wxID_BUTTONCHANGE + &New... - m_buttonCopy + m_buttonNew protected - wxBU_EXACTFIT + - OnButtonCopy + OnButtonChange @@ -530,7 +530,7 @@ 5 - wxRIGHT + wxALIGN_CENTER_VERTICAL|wxRIGHT 0 @@ -539,22 +539,22 @@ 1 - 1 - wxID_BUTTONCHANGE - C&hange... + 0 + wxID_BUTTONCOPY + &Copy to Clipboard - m_button91 + m_buttonCopy protected - + wxBU_EXACTFIT - OnButtonChange + OnButtonCopy @@ -5239,5779 +5239,6 @@ - - - - - 1 - - - - 0 - wxID_ANY - - - CProductsDialogBase - - 708,535 - wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER - - Marketplace - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - bSizer22 - wxVERTICAL - none - - 5 - wxEXPAND|wxTOP|wxBOTTOM|wxRIGHT - 0 - - - bSizer23 - wxHORIZONTAL - none - - 5 - wxALL|wxALIGN_CENTER_VERTICAL - 0 - - - "(Any Category)" - - 1 - - - 0 - wxID_ANY - - - m_comboBoxCategory - protected - - 150,-1 - - - - (Any Category) - - - - - OnCombobox - - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALL|wxALIGN_CENTER_VERTICAL - 1 - - - - 1 - - - 0 - wxID_ANY - - 0 - - m_textCtrlSearch - protected - - - - - - - - - - - - - OnKeyDown - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALL|wxALIGN_CENTER_VERTICAL - 0 - - - - 0 - 1 - - - 0 - wxID_ANY - &Search - - - m_buttonSearch - protected - - - - - - - - - OnButtonSearch - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALL|wxEXPAND - 1 - - - - 1 - - - 0 - wxID_ANY - - - m_listCtrl - protected - - - wxLC_NO_SORT_HEADER|wxLC_REPORT - - - - - - - - - - - - - - - - - - - - - - - - - - - - - OnListItemActivated - - - - - - - - - - - - - - - - - - - - - - - - - wxSYS_COLOUR_MENU - - - 1 - - - - 0 - wxID_ANY - - - CEditProductDialogBase - - 660,640 - wxDEFAULT_FRAME_STYLE|wxRESIZE_BORDER - - Edit Product - - - - wxTAB_TRAVERSAL - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - bSizer20 - wxVERTICAL - none - - 5 - wxEXPAND|wxALL - 1 - - wxSYS_COLOUR_WINDOW - - 1 - - - 0 - wxID_ANY - - - m_scrolledWindow - protected - - 5 - 5 - - - - - - wxHSCROLL|wxTAB_TRAVERSAL|wxVSCROLL - - - - - - - - - - - - - - - - - - - - - - - - - - bSizer21 - wxVERTICAL - none - - 5 - wxEXPAND|wxTOP|wxRIGHT|wxLEFT - 0 - - 2 - wxBOTH - 1 - - 0 - - fgSizer8 - wxFLEX_GROWMODE_SPECIFIED - none - 0 - 0 - - 5 - wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxTOP|wxBOTTOM|wxLEFT - 0 - - - - 1 - - - 0 - wxID_ANY - Category - - - m_staticText106 - protected - - - wxALIGN_RIGHT - - - - - - -1 - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALL|wxALIGN_CENTER_VERTICAL - 0 - - - - - 1 - - - 0 - wxID_ANY - - 180,-1 - m_comboBoxCategory - protected - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxTOP|wxBOTTOM|wxLEFT - 0 - - - - 1 - - - 0 - wxID_ANY - Title - - - m_staticText108 - protected - - - wxALIGN_RIGHT - - - - - - -1 - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND - 1 - - - - 1 - - - 0 - wxID_ANY - - 0 - - m_textCtrlTitle - protected - - - - - - - - - - - - - OnKeyDown - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxTOP|wxBOTTOM|wxLEFT - 0 - - - - 1 - - - 0 - wxID_ANY - Price - - - m_staticText107 - protected - - - wxALIGN_RIGHT - - - - - - -1 - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALL|wxALIGN_CENTER_VERTICAL - 0 - - - - 1 - - - 0 - wxID_ANY - - 0 - 105,-1 - m_textCtrlPrice - protected - - - - - - - - - - - - - OnKeyDown - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxTOP|wxRIGHT|wxLEFT - 0 - - - - 1 - - - 0 - wxID_ANY - Page 1: Description - - - m_staticText22 - protected - - - - - - - - - -1 - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALL|wxEXPAND - 0 - - - - 1 - - - 0 - wxID_ANY - - 0 - -1,170 - m_textCtrlDescription - protected - - - wxTE_MULTILINE - - - - - - - - - - OnKeyDown - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxTOP|wxRIGHT|wxLEFT - 0 - - - - 1 - - - 0 - wxID_ANY - Page 2: Order Form - - - m_staticText23 - protected - - - - - - - - - -1 - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxEXPAND|wxALL - 0 - - - - 1 - - - 0 - wxID_ANY - - 0 - -1,120 - m_textCtrlInstructions - protected - - - wxTE_MULTILINE - - - - - - - - - - OnKeyDown - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxEXPAND - 0 - - 3 - wxBOTH - 1 - - 0 - - fgSizer5 - wxFLEX_GROWMODE_SPECIFIED - public - 0 - 0 - - 5 - wxALIGN_CENTER_VERTICAL|wxTOP|wxRIGHT|wxLEFT - 0 - - - - 1 - - - 0 - wxID_ANY - Label - - - m_staticText24 - protected - - - - - - - - - -1 - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALIGN_CENTER_VERTICAL|wxTOP|wxRIGHT|wxLEFT - 0 - - - - 1 - - - 0 - wxID_ANY - Comma separated list of choices, or leave blank for text field - - - m_staticText25 - protected - - - - - - - - - -1 - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxEXPAND - 1 - - 0 - protected - 0 - - - - 5 - wxALL|wxALIGN_CENTER_VERTICAL - 0 - - - - 1 - - - 0 - wxID_ANY - - 0 - 150,-1 - m_textCtrlLabel0 - protected - - - - - - - - - - - - - OnKeyDown - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL - 0 - - - - 1 - - - 0 - wxID_ANY - -1,-1 - 0 - -1,-1 - m_textCtrlField0 - protected - - -1,-1 - - - - - - - - - - - OnKeyDown - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxRIGHT|wxLEFT|wxALIGN_CENTER_VERTICAL - 0 - - - - 0 - 1 - - - 0 - wxID_DEL0 - Delete - - -1,-1 - m_buttonDel0 - protected - - 60,20 - - - - - - - OnButtonDel0 - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALL|wxALIGN_CENTER_VERTICAL - 0 - - - - 1 - - - 0 - wxID_ANY - - 0 - 150,-1 - m_textCtrlLabel1 - protected - - - - - - - - - - - - - OnKeyDown - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL - 0 - - - - 1 - - - 0 - wxID_ANY - -1,-1 - 0 - -1,-1 - m_textCtrlField1 - protected - - -1,-1 - - - - - - - - - - - OnKeyDown - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT - 0 - - - - 0 - 1 - - - 0 - wxID_DEL1 - Delete - - -1,-1 - m_buttonDel1 - protected - - 60,20 - - - - - - - OnButtonDel1 - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALL|wxALIGN_CENTER_VERTICAL - 0 - - - - 1 - - - 0 - wxID_ANY - - 0 - 150,-1 - m_textCtrlLabel2 - protected - - - - - - - - - - - - - OnKeyDown - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL - 0 - - - - 1 - - - 0 - wxID_ANY - -1,-1 - 0 - -1,-1 - m_textCtrlField2 - protected - - -1,-1 - - - - - - - - - - - OnKeyDown - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT - 0 - - - - 0 - 1 - - - 0 - wxID_DEL2 - Delete - - -1,-1 - m_buttonDel2 - protected - - 60,20 - - - - - - - OnButtonDel2 - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALL|wxALIGN_CENTER_VERTICAL - 0 - - - - 1 - - - 0 - wxID_ANY - - 0 - 150,-1 - m_textCtrlLabel3 - protected - - - - - - - - - - - - - OnKeyDown - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL - 0 - - - - 1 - - - 0 - wxID_ANY - -1,-1 - 0 - -1,-1 - m_textCtrlField3 - protected - - -1,-1 - - - - - - - - - - - OnKeyDown - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT - 0 - - - - 0 - 1 - - - 0 - wxID_DEL3 - Delete - - -1,-1 - m_buttonDel3 - protected - - 60,20 - - - - - - - OnButtonDel3 - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALL|wxALIGN_CENTER_VERTICAL - 0 - - - - 1 - - - 0 - wxID_ANY - - 0 - 150,-1 - m_textCtrlLabel4 - protected - - - - - - - - - - - - - OnKeyDown - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL - 0 - - - - 1 - - - 0 - wxID_ANY - -1,-1 - 0 - -1,-1 - m_textCtrlField4 - protected - - -1,-1 - - - - - - - - - - - OnKeyDown - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT - 0 - - - - 0 - 1 - - - 0 - wxID_DEL4 - Delete - - -1,-1 - m_buttonDel4 - protected - - 60,20 - - - - - - - OnButtonDel4 - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALL|wxALIGN_CENTER_VERTICAL - 0 - - - - 1 - - - 0 - wxID_ANY - - 0 - 150,-1 - m_textCtrlLabel5 - protected - - - - - - - - - - - - - OnKeyDown - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL - 0 - - - - 1 - - - 0 - wxID_ANY - -1,-1 - 0 - -1,-1 - m_textCtrlField5 - protected - - -1,-1 - - - - - - - - - - - OnKeyDown - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT - 0 - - - - 0 - 1 - - - 0 - wxID_DEL5 - Delete - - -1,-1 - m_buttonDel5 - protected - - 60,20 - - - - - - - OnButtonDel5 - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALL|wxALIGN_CENTER_VERTICAL - 0 - - - - 1 - - - 0 - wxID_ANY - - 0 - 150,-1 - m_textCtrlLabel6 - protected - - - - - - - - - - - - - OnKeyDown - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL - 0 - - - - 1 - - - 0 - wxID_ANY - -1,-1 - 0 - -1,-1 - m_textCtrlField6 - protected - - -1,-1 - - - - - - - - - - - OnKeyDown - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT - 0 - - - - 0 - 1 - - - 0 - wxID_DEL6 - Delete - - -1,-1 - m_buttonDel6 - protected - - 60,20 - - - - - - - OnButtonDel6 - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALL|wxALIGN_CENTER_VERTICAL - 0 - - - - 1 - - - 0 - wxID_ANY - - 0 - 150,-1 - m_textCtrlLabel7 - protected - - - - - - - - - - - - - OnKeyDown - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL - 0 - - - - 1 - - - 0 - wxID_ANY - -1,-1 - 0 - -1,-1 - m_textCtrlField7 - protected - - -1,-1 - - - - - - - - - - - OnKeyDown - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT - 0 - - - - 0 - 1 - - - 0 - wxID_DEL7 - Delete - - -1,-1 - m_buttonDel7 - protected - - 60,20 - - - - - - - OnButtonDel7 - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALL|wxALIGN_CENTER_VERTICAL - 0 - - - - 1 - - - 0 - wxID_ANY - - 0 - 150,-1 - m_textCtrlLabel8 - protected - - - - - - - - - - - - - OnKeyDown - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL - 0 - - - - 1 - - - 0 - wxID_ANY - -1,-1 - 0 - -1,-1 - m_textCtrlField8 - protected - - -1,-1 - - - - - - - - - - - OnKeyDown - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT - 0 - - - - 0 - 1 - - - 0 - wxID_DEL8 - Delete - - -1,-1 - m_buttonDel8 - protected - - 60,20 - - - - - - - OnButtonDel8 - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALL|wxALIGN_CENTER_VERTICAL - 0 - - - - 1 - - - 0 - wxID_ANY - - 0 - 150,-1 - m_textCtrlLabel9 - protected - - - - - - - - - - - - - OnKeyDown - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL - 0 - - - - 1 - - - 0 - wxID_ANY - -1,-1 - 0 - -1,-1 - m_textCtrlField9 - protected - - -1,-1 - - - - - - - - - - - OnKeyDown - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT - 0 - - - - 0 - 1 - - - 0 - wxID_DEL9 - Delete - - -1,-1 - m_buttonDel9 - protected - - 60,20 - - - - - - - OnButtonDel9 - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALL|wxALIGN_CENTER_VERTICAL - 0 - - - - 1 - - - 0 - wxID_ANY - - 0 - 150,-1 - m_textCtrlLabel10 - protected - - - - - - - - - - - - - OnKeyDown - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL - 0 - - - - 1 - - - 0 - wxID_ANY - -1,-1 - 0 - -1,-1 - m_textCtrlField10 - protected - - -1,-1 - - - - - - - - - - - OnKeyDown - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT - 0 - - - - 0 - 1 - - - 0 - wxID_DEL10 - Delete - - -1,-1 - m_buttonDel10 - protected - - 60,20 - - - - - - - OnButtonDel10 - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALL|wxALIGN_CENTER_VERTICAL - 0 - - - - 1 - - - 0 - wxID_ANY - - 0 - 150,-1 - m_textCtrlLabel11 - protected - - - - - - - - - - - - - OnKeyDown - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL - 0 - - - - 1 - - - 0 - wxID_ANY - -1,-1 - 0 - -1,-1 - m_textCtrlField11 - protected - - -1,-1 - - - - - - - - - - - OnKeyDown - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT - 0 - - - - 0 - 1 - - - 0 - wxID_DEL11 - Delete - - -1,-1 - m_buttonDel11 - protected - - 60,20 - - - - - - - OnButtonDel11 - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALL|wxALIGN_CENTER_VERTICAL - 0 - - - - 1 - - - 0 - wxID_ANY - - 0 - 150,-1 - m_textCtrlLabel12 - protected - - - - - - - - - - - - - OnKeyDown - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL - 0 - - - - 1 - - - 0 - wxID_ANY - -1,-1 - 0 - -1,-1 - m_textCtrlField12 - protected - - -1,-1 - - - - - - - - - - - OnKeyDown - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT - 0 - - - - 0 - 1 - - - 0 - wxID_DEL12 - Delete - - -1,-1 - m_buttonDel12 - protected - - 60,20 - - - - - - - OnButtonDel12 - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALL|wxALIGN_CENTER_VERTICAL - 0 - - - - 1 - - - 0 - wxID_ANY - - 0 - 150,-1 - m_textCtrlLabel13 - protected - - - - - - - - - - - - - OnKeyDown - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL - 0 - - - - 1 - - - 0 - wxID_ANY - -1,-1 - 0 - -1,-1 - m_textCtrlField13 - protected - - -1,-1 - - - - - - - - - - - OnKeyDown - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT - 0 - - - - 0 - 1 - - - 0 - wxID_DEL13 - Delete - - -1,-1 - m_buttonDel13 - protected - - 60,20 - - - - - - - OnButtonDel13 - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALL|wxALIGN_CENTER_VERTICAL - 0 - - - - 1 - - - 0 - wxID_ANY - - 0 - 150,-1 - m_textCtrlLabel14 - protected - - - - - - - - - - - - - OnKeyDown - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL - 0 - - - - 1 - - - 0 - wxID_ANY - -1,-1 - 0 - -1,-1 - m_textCtrlField14 - protected - - -1,-1 - - - - - - - - - - - OnKeyDown - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT - 0 - - - - 0 - 1 - - - 0 - wxID_DEL14 - Delete - - -1,-1 - m_buttonDel14 - protected - - 60,20 - - - - - - - OnButtonDel14 - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALL|wxALIGN_CENTER_VERTICAL - 0 - - - - 1 - - - 0 - wxID_ANY - - 0 - 150,-1 - m_textCtrlLabel15 - protected - - - - - - - - - - - - - OnKeyDown - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL - 0 - - - - 1 - - - 0 - wxID_ANY - -1,-1 - 0 - -1,-1 - m_textCtrlField15 - protected - - -1,-1 - - - - - - - - - - - OnKeyDown - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT - 0 - - - - 0 - 1 - - - 0 - wxID_DEL15 - Delete - - -1,-1 - m_buttonDel15 - protected - - 60,20 - - - - - - - OnButtonDel15 - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALL|wxALIGN_CENTER_VERTICAL - 0 - - - - 1 - - - 0 - wxID_ANY - - 0 - 150,-1 - m_textCtrlLabel16 - protected - - - - - - - - - - - - - OnKeyDown - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL - 0 - - - - 1 - - - 0 - wxID_ANY - -1,-1 - 0 - -1,-1 - m_textCtrlField16 - protected - - -1,-1 - - - - - - - - - - - OnKeyDown - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT - 0 - - - - 0 - 1 - - - 0 - wxID_DEL16 - Delete - - -1,-1 - m_buttonDel16 - protected - - 60,20 - - - - - - - OnButtonDel16 - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALL|wxALIGN_CENTER_VERTICAL - 0 - - - - 1 - - - 0 - wxID_ANY - - 0 - 150,-1 - m_textCtrlLabel17 - protected - - - - - - - - - - - - - OnKeyDown - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL - 0 - - - - 1 - - - 0 - wxID_ANY - -1,-1 - 0 - -1,-1 - m_textCtrlField17 - protected - - -1,-1 - - - - - - - - - - - OnKeyDown - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT - 0 - - - - 0 - 1 - - - 0 - wxID_DEL17 - Delete - - -1,-1 - m_buttonDel17 - protected - - 60,20 - - - - - - - OnButtonDel17 - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALL|wxALIGN_CENTER_VERTICAL - 0 - - - - 1 - - - 0 - wxID_ANY - - 0 - 150,-1 - m_textCtrlLabel18 - protected - - - - - - - - - - - - - OnKeyDown - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL - 0 - - - - 1 - - - 0 - wxID_ANY - -1,-1 - 0 - -1,-1 - m_textCtrlField18 - protected - - -1,-1 - - - - - - - - - - - OnKeyDown - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT - 0 - - - - 0 - 1 - - - 0 - wxID_DEL18 - Delete - - -1,-1 - m_buttonDel18 - protected - - 60,20 - - - - - - - OnButtonDel18 - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALL|wxALIGN_CENTER_VERTICAL - 0 - - - - 1 - - - 0 - wxID_ANY - - 0 - 150,-1 - m_textCtrlLabel19 - protected - - - - - - - - - - - - - OnKeyDown - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL - 0 - - - - 1 - - - 0 - wxID_ANY - -1,-1 - 0 - -1,-1 - m_textCtrlField19 - protected - - -1,-1 - - - - - - - - - - - OnKeyDown - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT - 0 - - - - 0 - 1 - - - 0 - wxID_DEL19 - Delete - - -1,-1 - m_buttonDel19 - protected - - 60,20 - - - - - - - OnButtonDel19 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALIGN_CENTER_HORIZONTAL - 0 - - - bSizer25 - wxHORIZONTAL - none - - 5 - wxALL - 0 - - - - 0 - 1 - - - 0 - wxID_ANY - &Add Field - - - m_buttonAddField - protected - - - - - - - - - OnButtonAddField - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALIGN_RIGHT - 0 - - - bSizer26 - wxHORIZONTAL - none - - 5 - wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND - 0 - - - - 0 - 1 - - - 0 - wxID_BUTTONSEND - &Send - - -1,-1 - m_buttonOK - protected - - - - - - - - - OnButtonSend - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND - 0 - - - - 0 - 1 - - - 0 - wxID_BUTTONPREVIEW - &Preview - - -1,-1 - m_buttonPreview - protected - - - - - - - - - OnButtonPreview - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND - 0 - - - - 0 - 1 - - - 0 - wxID_CANCEL - Cancel - - -1,-1 - m_buttonCancel - protected - - - - - - - - - OnButtonCancel - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - wxSYS_COLOUR_MENU - - - 1 - - - - 0 - wxID_ANY - - - CViewProductDialogBase - - 630,520 - wxDEFAULT_FRAME_STYLE|wxRESIZE_BORDER - - Order Form - - - - wxTAB_TRAVERSAL - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - bSizer20 - wxVERTICAL - none - - 5 - wxEXPAND - 1 - - - bSizer116 - wxHORIZONTAL - none - - 5 - wxALL|wxEXPAND - 1 - - - - 1 - - - 1 - wxID_ANY - - - m_htmlWinReviews - protected - - - wxHW_SCROLLBAR_AUTO - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxEXPAND|wxALL - 1 - - wxSYS_COLOUR_WINDOW - - 1 - - - 0 - wxID_ANY - - - m_scrolledWindow - protected - - 5 - 5 - - - - - - wxHSCROLL|wxTAB_TRAVERSAL|wxVSCROLL - - - - - - - - - - - - - - - - - - - - - - - - - - bSizer21 - wxVERTICAL - none - - 5 - wxEXPAND - 0 - - - - 1 - - - 0 - wxID_ANY - - -1,-1 - m_richTextHeading - protected - - -1,50 - wxTE_READONLY - - - - - wxNO_BORDER - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALL|wxEXPAND - 0 - - - - 1 - - - 0 - wxID_ANY - Order Form instructions here multiple lines 1 2 3 4 5 6 - - - m_staticTextInstructions - protected - - - - - - - - - -1 - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALIGN_CENTER_HORIZONTAL - 0 - - - bSizer25 - wxHORIZONTAL - none - - 5 - wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND - 0 - - - - 0 - 1 - - - 0 - wxID_BUTTONSAMPLE - &Submit - - -1,-1 - m_buttonSubmitForm - protected - - - - - - - - - OnButtonSubmitForm - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND - 0 - - - - 0 - 1 - - - 0 - wxID_CANCEL2 - Cancel - - - m_buttonCancelForm - protected - - - - - - - - - OnButtonCancelForm - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALIGN_RIGHT - 0 - - - bSizer26 - wxHORIZONTAL - none - - 5 - wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND - 0 - - - - 0 - 0 - - - 0 - wxID_BUTTONBACK - < &Back - - -1,-1 - m_buttonBack - protected - - - - - - - - - OnButtonBack - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND - 0 - - - - 0 - 1 - - - 0 - wxID_BUTTONNEXT - &Next > - - -1,-1 - m_buttonNext - protected - - - - - - - - - OnButtonNext - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND - 0 - - - - 0 - 1 - - - 0 - wxID_CANCEL - Cancel - - -1,-1 - m_buttonCancel - protected - - - - - - - - - OnButtonCancel - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - wxSYS_COLOUR_MENU - - - 1 - - - - 0 - wxID_ANY - - - CViewOrderDialogBase - - 630,520 - wxDEFAULT_FRAME_STYLE|wxRESIZE_BORDER - - View Order - - - - wxTAB_TRAVERSAL - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - bSizer20 - wxVERTICAL - none - - 5 - wxEXPAND - 1 - - - bSizer116 - wxHORIZONTAL - none - - 5 - wxALL|wxEXPAND - 1 - - - - 1 - - - 0 - wxID_ANY - - - m_htmlWin - protected - - - wxHW_SCROLLBAR_AUTO - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALIGN_RIGHT - 0 - - - bSizer26 - wxHORIZONTAL - none - - 5 - wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND - 0 - - - - 0 - 1 - - - 0 - wxID_OK - OK - - -1,-1 - m_buttonOK - protected - - - - - - - - - OnButtonOK - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - wxSYS_COLOUR_MENU - - - 1 - - - - 0 - wxID_ANY - - - CEditReviewDialogBase - - 630,440 - wxDEFAULT_FRAME_STYLE|wxRESIZE_BORDER - - Enter Review - - - - wxTAB_TRAVERSAL - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - bSizer112 - wxVERTICAL - none - - 5 - - 0 - - 3 - protected - 0 - - - - 5 - wxALL|wxEXPAND - 0 - - - - 1 - - - 0 - wxID_ANY - - - - m_staticTextSeller - protected - - - - - - - - - -1 - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - - 0 - - 3 - protected - 0 - - - - 5 - wxTOP|wxRIGHT|wxLEFT - 0 - - - - 1 - - - 0 - wxID_ANY - Rating - - - m_staticText110 - protected - - - - - - - - - -1 - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALL - 0 - - - " 1 star" " 2 stars" " 3 stars" " 4 stars" " 5 stars" - - 1 - - - 0 - wxID_ANY - - - m_choiceStars - protected - - 0 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxTOP|wxRIGHT|wxLEFT - 0 - - - - 1 - - - 0 - wxID_ANY - Review - - - m_staticText43 - protected - - - - - - - - - -1 - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALL|wxEXPAND - 1 - - - - 1 - - - 0 - wxID_ANY - - 0 - - m_textCtrlReview - protected - - - wxTE_MULTILINE - - - - - - - - - - OnKeyDown - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALIGN_RIGHT - 0 - - - bSizer113 - wxHORIZONTAL - none - - 5 - wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND - 0 - - - - 0 - 1 - - - 0 - wxID_SUBMIT - &Submit - - -1,-1 - m_buttonSubmit - protected - - - - - - - - - OnButtonSubmit - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND - 0 - - - - 0 - 1 - - - 0 - wxID_CANCEL - Cancel - - -1,-1 - m_buttonCancel - protected - - - - - - - - - OnButtonCancel - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- cgit v1.2.3 From f3cd4206b8f65048c332ccf2274fb976cfebf08c Mon Sep 17 00:00:00 2001 From: s_nakamoto Date: Mon, 15 Feb 2010 20:36:55 +0000 Subject: fix mingw makefile to use correct wxWidgets include, this is the last version of makefile and makefile.vc for wxWidgets-2.8 --- makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/makefile b/makefile index fb8dd2746b..71f374492a 100644 --- a/makefile +++ b/makefile @@ -15,7 +15,7 @@ endif -INCLUDEPATHS=-I"/boost" -I"/db/build_unix" -I"/openssl/include" -I"/wxwidgets/lib/vc_lib/mswd" -I"/wxwidgets/include" +INCLUDEPATHS=-I"/boost" -I"/db/build_unix" -I"/openssl/include" -I"/wxwidgets/lib/gcc_lib/mswd" -I"/wxwidgets/include" LIBPATHS=-L"/boost/stage/lib" -L"/db/build_unix" -L"/openssl/out" -L"/wxwidgets/lib/gcc_lib" LIBS= \ -l libboost_system-mgw34-mt-d -l libboost_filesystem-mgw34-mt-d \ -- cgit v1.2.3 From 2b63e68bbfebc370aa6f2d542419a6e5680f33c5 Mon Sep 17 00:00:00 2001 From: s_nakamoto Date: Mon, 15 Feb 2010 20:36:55 +0000 Subject: fix mingw makefile to use correct wxWidgets include, this is the last version of makefile and makefile.vc for wxWidgets-2.8 git-svn-id: https://bitcoin.svn.sourceforge.net/svnroot/bitcoin/trunk@65 1a98c847-1fd6-4fd8-948a-caf3550aa51b --- makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/makefile b/makefile index fb8dd2746b..71f374492a 100644 --- a/makefile +++ b/makefile @@ -15,7 +15,7 @@ endif -INCLUDEPATHS=-I"/boost" -I"/db/build_unix" -I"/openssl/include" -I"/wxwidgets/lib/vc_lib/mswd" -I"/wxwidgets/include" +INCLUDEPATHS=-I"/boost" -I"/db/build_unix" -I"/openssl/include" -I"/wxwidgets/lib/gcc_lib/mswd" -I"/wxwidgets/include" LIBPATHS=-L"/boost/stage/lib" -L"/db/build_unix" -L"/openssl/out" -L"/wxwidgets/lib/gcc_lib" LIBS= \ -l libboost_system-mgw34-mt-d -l libboost_filesystem-mgw34-mt-d \ -- cgit v1.2.3 From bcd27140384ec3703f3fd18ec89b0046a0ef17d3 Mon Sep 17 00:00:00 2001 From: s_nakamoto Date: Wed, 17 Feb 2010 17:22:01 +0000 Subject: all builds are now with wxWidgets-2.9.0, we are now using UTF-8, added support for language translation file locale//LC_MESSAGES/bitcoin.mo -- version 0.2.2 --- build-msw.txt | 24 ++-- build-unix.txt | 22 ++-- locale/readme.txt | 5 + main.cpp | 30 ++--- makefile | 83 ------------- makefile.mingw | 86 ++++++++++++++ makefile.unix | 78 ++++++++++++ makefile.unix.wx2.8 | 88 -------------- makefile.unix.wx2.9 | 88 -------------- makefile.vc | 35 +++--- serialize.h | 4 +- ui.cpp | 337 ++++++++++++++++++++++++++++------------------------ ui.h | 12 +- uibase.cpp | 17 +-- uibase.h | 5 - uiproject.fbp | 108 +---------------- util.cpp | 6 +- util.h | 9 +- 18 files changed, 428 insertions(+), 609 deletions(-) create mode 100644 locale/readme.txt delete mode 100644 makefile create mode 100644 makefile.mingw create mode 100644 makefile.unix delete mode 100644 makefile.unix.wx2.8 delete mode 100644 makefile.unix.wx2.9 diff --git a/build-msw.txt b/build-msw.txt index 9786255e1f..adb526a31d 100644 --- a/build-msw.txt +++ b/build-msw.txt @@ -29,11 +29,11 @@ Dependencies ------------ Libraries you need to download separately and build: - default path download -wxWidgets \wxwidgets prebuilt: http://wxpack.sourceforge.net -OpenSSL \openssl http://www.openssl.org/source/ -Berkeley DB \db http://www.oracle.com/technology/software/products/berkeley-db/index.html -Boost \boost http://www.boost.org/users/download/ + default path download +wxWidgets-2.9 \wxwidgets http://www.wxwidgets.org/downloads/ +OpenSSL \openssl http://www.openssl.org/source/ +Berkeley DB \db http://www.oracle.com/technology/software/products/berkeley-db/index.html +Boost \boost http://www.boost.org/users/download/ Their licenses: wxWidgets LGPL 2.1 with very liberal exceptions @@ -43,10 +43,10 @@ Boost MIT-like license Versions used in this release: MinGW GCC 3.4.5 -wxWidgets 2.8.9 +wxWidgets 2.9.0 OpenSSL 0.9.8k Berkeley DB 4.7.25.NC -Boost 1.34.1 +Boost 1.42.1 Notes @@ -59,6 +59,14 @@ The release is built with GCC and then "strip bitcoin.exe" to strip the debug symbols, which reduces the executable size by about 90%. +wxWidgets +--------- +cd \wxwidgets\build\msw +make -f makefile.gcc + or +nmake -f makefile.vc + + OpenSSL ------- Bitcoin does not use any encryption. If you want to do a no-everything @@ -104,5 +112,5 @@ download bjam.exe from http://sourceforge.net/project/showfiles.php?group_id=7586&package_id=72941 cd \boost bjam toolset=gcc --build-type=complete stage -or + or bjam toolset=msvc --build-type=complete stage diff --git a/build-unix.txt b/build-unix.txt index f1a72eaacc..5e3f574afb 100644 --- a/build-unix.txt +++ b/build-unix.txt @@ -20,15 +20,11 @@ sudo apt-get install libdb4.7-dev sudo apt-get install libdb4.7++-dev sudo apt-get install libboost-dev -The release was built with wxWidgets 2.8.9 ansi on 32-bit. The current -sourcecode can be built on 64-bit with wxWidgets 2.9.0. +We're now using wxWidgets 2.9, which uses UTF-8. -There is currently no libwxgtk2.8-ansi-dev debian package for Karmic. -libwxgtk2.8-dev is the "unicode" build, but for wxWidgets 2.8 "unicode" -means wchar, not UTF-8. wchar wxString doesn't convert to std::string. -We haven't been able to compile the 2.8 versions on 64-bit. - -wxWidgets 2.9 is UTF-8 and compiles on 64-bit. +There isn't currently a debian package of wxWidgets we can use. The 2.8 +packages for Karmic are UTF-16 unicode and won't work for us, and we've had +trouble building 2.8 on 64-bit. You need to download wxWidgets from http://www.wxwidgets.org/downloads/ and build it yourself. See the build instructions and configure parameters @@ -42,9 +38,9 @@ Boost MIT-like license Versions used in this release: GCC 4.3.3 OpenSSL 0.9.8k -wxWidgets 2.8.9 +wxWidgets 2.9.0 Berkeley DB 4.7.25.NC -Boost 1.40.0 +Boost 1.38.0 Notes @@ -59,7 +55,9 @@ symbols, which reduces the executable size by about 90%. wxWidgets --------- -cd /usr/local/wxWidgets-2.8.9 or 2.9.0 +cd /usr/local +tar -xzvf wxWidgets-2.9.0.tar.gz +cd /usr/local/wxWidgets-2.9.0 mkdir buildgtk cd buildgtk ../configure --with-gtk --enable-debug --disable-shared --enable-monolithic @@ -72,7 +70,7 @@ ldconfig Boost ----- If you want to build Boost yourself, -cd /usr/local/boost_1_40_0 +cd /usr/local/boost_1_42_0 su ./bootstrap.sh ./bjam install diff --git a/locale/readme.txt b/locale/readme.txt new file mode 100644 index 0000000000..9fca3ce657 --- /dev/null +++ b/locale/readme.txt @@ -0,0 +1,5 @@ +put bitcoin.po and bitcoin.mo files at: +locale//LC_MESSAGES/bitcoin.mo and .po + +.po is the sourcefile +.mo is the compiled translation diff --git a/main.cpp b/main.cpp index 3391a2994a..665a78e207 100644 --- a/main.cpp +++ b/main.cpp @@ -1460,27 +1460,13 @@ bool ScanMessageStart(Stream& s) bool CheckDiskSpace(int64 nAdditionalBytes) { -#ifdef __WXMSW__ - uint64 nFreeBytesAvailable = 0; // bytes available to caller - uint64 nTotalNumberOfBytes = 0; // bytes on disk - uint64 nTotalNumberOfFreeBytes = 0; // free bytes on disk - if (!GetDiskFreeSpaceEx(GetDataDir().c_str(), - (PULARGE_INTEGER)&nFreeBytesAvailable, - (PULARGE_INTEGER)&nTotalNumberOfBytes, - (PULARGE_INTEGER)&nTotalNumberOfFreeBytes)) - { - printf("ERROR: GetDiskFreeSpaceEx() failed\n"); - return true; - } -#else uint64 nFreeBytesAvailable = filesystem::space(GetDataDir()).available; -#endif // Check for 15MB because database could create another 10MB log file at any time if (nFreeBytesAvailable < (int64)15000000 + nAdditionalBytes) { fShutdown = true; - ThreadSafeMessageBox("Warning: Your disk space is low ", "Bitcoin", wxOK | wxICON_EXCLAMATION); + ThreadSafeMessageBox(_("Warning: Disk space is low "), "Bitcoin", wxOK | wxICON_EXCLAMATION); CreateThread(Shutdown, NULL); return false; } @@ -2962,16 +2948,16 @@ string SendMoney(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew) { string strError; if (nValue + nFeeRequired > GetBalance()) - strError = strprintf("Error: This is an oversized transaction that requires a transaction fee of %s ", FormatMoney(nFeeRequired).c_str()); + strError = strprintf(_("Error: This is an oversized transaction that requires a transaction fee of %s "), FormatMoney(nFeeRequired).c_str()); else - strError = "Error: Transaction creation failed "; + strError = _("Error: Transaction creation failed "); printf("SendMoney() : %s", strError.c_str()); return strError; } if (!CommitTransactionSpent(wtxNew, key)) { printf("SendMoney() : Error finalizing transaction"); - return "Error finalizing transaction"; + return _("Error finalizing transaction"); } // Track how many getdata requests our transaction gets @@ -2985,7 +2971,7 @@ string SendMoney(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew) { // This must not fail. The transaction has already been signed and recorded. printf("SendMoney() : Error: Transaction not valid"); - return "Error: The transaction was rejected. This might happen if some of the coins in your wallet were already spent, such as if you used a copy of wallet.dat and coins were spent in the copy but not marked as spent here."; + return _("Error: The transaction was rejected. This might happen if some of the coins in your wallet were already spent, such as if you used a copy of wallet.dat and coins were spent in the copy but not marked as spent here."); } wtxNew.RelayWalletTransaction(); } @@ -2999,14 +2985,14 @@ string SendMoneyToBitcoinAddress(string strAddress, int64 nValue, CWalletTx& wtx { // Check amount if (nValue <= 0) - return "Invalid amount"; + return _("Invalid amount"); if (nValue + nTransactionFee > GetBalance()) - return "You don't have enough money"; + return _("You don't have enough money"); // Parse bitcoin address CScript scriptPubKey; if (!scriptPubKey.SetBitcoinAddress(strAddress)) - return "Invalid bitcoin address"; + return _("Invalid bitcoin address"); return SendMoney(scriptPubKey, nValue, wtxNew); } diff --git a/makefile b/makefile deleted file mode 100644 index 71f374492a..0000000000 --- a/makefile +++ /dev/null @@ -1,83 +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. - - -ifneq "$(BUILD)" "debug" -ifneq "$(BUILD)" "release" -BUILD=debug -endif -endif -ifeq "$(BUILD)" "debug" -D=d -DEBUGFLAGS=-g -D__WXDEBUG__ -endif - - - -INCLUDEPATHS=-I"/boost" -I"/db/build_unix" -I"/openssl/include" -I"/wxwidgets/lib/gcc_lib/mswd" -I"/wxwidgets/include" -LIBPATHS=-L"/boost/stage/lib" -L"/db/build_unix" -L"/openssl/out" -L"/wxwidgets/lib/gcc_lib" -LIBS= \ - -l libboost_system-mgw34-mt-d -l libboost_filesystem-mgw34-mt-d \ - -l db_cxx \ - -l eay32 \ - -l wxmsw28$(D)_richtext -l wxmsw28$(D)_html -l wxmsw28$(D)_core -l wxmsw28$(D)_adv -l wxbase28$(D) -l wxtiff$(D) -l wxjpeg$(D) -l wxpng$(D) -l wxzlib$(D) -l wxregex$(D) -l wxexpat$(D) \ - -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 -WXDEFS=-DWIN32 -D__WXMSW__ -D_WINDOWS -DNOPCH -CFLAGS=-mthreads -O0 -w -Wno-invalid-offsetof -Wformat $(DEBUGFLAGS) $(WXDEFS) $(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 - - - -all: bitcoin.exe - - -headers.h.gch: headers.h $(HEADERS) - g++ -c $(CFLAGS) -o $@ $< - -obj/util.o: util.cpp $(HEADERS) - g++ -c $(CFLAGS) -o $@ $< - -obj/script.o: script.cpp $(HEADERS) - g++ -c $(CFLAGS) -o $@ $< - -obj/db.o: db.cpp $(HEADERS) - g++ -c $(CFLAGS) -o $@ $< - -obj/net.o: net.cpp $(HEADERS) - g++ -c $(CFLAGS) -o $@ $< - -obj/main.o: main.cpp $(HEADERS) sha.h - g++ -c $(CFLAGS) -o $@ $< - -obj/ui.o: ui.cpp $(HEADERS) - g++ -c $(CFLAGS) -o $@ $< - -obj/uibase.o: uibase.cpp uibase.h - g++ -c $(CFLAGS) -o $@ $< - -obj/sha.o: sha.cpp sha.h - g++ -c $(CFLAGS) -O3 -o $@ $< - -obj/irc.o: irc.cpp $(HEADERS) - g++ -c $(CFLAGS) -o $@ $< - -obj/rpc.o: rpc.cpp $(HEADERS) - g++ -c $(CFLAGS) -o $@ $< - -obj/ui_res.o: ui.rc rc/bitcoin.ico rc/check.ico rc/send16.bmp rc/send16mask.bmp rc/send16masknoshadow.bmp rc/send20.bmp rc/send20mask.bmp rc/addressbook16.bmp rc/addressbook16mask.bmp rc/addressbook20.bmp rc/addressbook20mask.bmp - windres $(WXDEFS) $(INCLUDEPATHS) -o $@ -i $< - - - -OBJS=obj/util.o obj/script.o obj/db.o obj/net.o obj/main.o \ - obj/ui.o obj/uibase.o obj/sha.o obj/irc.o obj/rpc.o \ - obj/ui_res.o - -bitcoin.exe: headers.h.gch $(OBJS) - -kill /f bitcoin.exe - g++ $(CFLAGS) -mwindows -Wl,--subsystem,windows -o $@ $(LIBPATHS) $(OBJS) $(LIBS) - -clean: - -del /Q obj\* - -del /Q headers.h.gch diff --git a/makefile.mingw b/makefile.mingw new file mode 100644 index 0000000000..2644cbaad1 --- /dev/null +++ b/makefile.mingw @@ -0,0 +1,86 @@ +# 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. + + +# for wxWidgets-2.8.x, search and replace "mswud"->"mswd" and "29u"->"28" + +INCLUDEPATHS= \ + -I"/boost" \ + -I"/db/build_unix" \ + -I"/openssl/include" \ + -I"/wxwidgets/lib/gcc_lib/mswud" \ + -I"/wxwidgets/include" + +LIBPATHS= \ + -L"/boost/stage/lib" \ + -L"/db/build_unix" \ + -L"/openssl/out" \ + -L"/wxwidgets/lib/gcc_lib" + +LIBS= \ + -l libboost_system-mgw34-mt-d -l libboost_filesystem-mgw34-mt-d \ + -l db_cxx \ + -l eay32 \ + -l wxmsw29ud_html -l wxmsw29ud_core -l wxmsw29ud_adv -l wxbase29ud -l wxtiffd -l wxjpegd -l wxpngd -l wxzlibd \ + -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 + +WXDEFS=-DWIN32 -D__WXMSW__ -D_WINDOWS -DNOPCH +DEBUGFLAGS=-g -D__WXDEBUG__ +CFLAGS=-mthreads -O0 -w -Wno-invalid-offsetof -Wformat $(DEBUGFLAGS) $(WXDEFS) $(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 + + + +all: bitcoin.exe + + +headers.h.gch: headers.h $(HEADERS) + g++ -c $(CFLAGS) -o $@ $< + +obj/util.o: util.cpp $(HEADERS) + g++ -c $(CFLAGS) -o $@ $< + +obj/script.o: script.cpp $(HEADERS) + g++ -c $(CFLAGS) -o $@ $< + +obj/db.o: db.cpp $(HEADERS) + g++ -c $(CFLAGS) -o $@ $< + +obj/net.o: net.cpp $(HEADERS) + g++ -c $(CFLAGS) -o $@ $< + +obj/main.o: main.cpp $(HEADERS) sha.h + g++ -c $(CFLAGS) -o $@ $< + +obj/ui.o: ui.cpp $(HEADERS) + g++ -c $(CFLAGS) -o $@ $< + +obj/uibase.o: uibase.cpp uibase.h + g++ -c $(CFLAGS) -o $@ $< + +obj/sha.o: sha.cpp sha.h + g++ -c $(CFLAGS) -O3 -o $@ $< + +obj/irc.o: irc.cpp $(HEADERS) + g++ -c $(CFLAGS) -o $@ $< + +obj/rpc.o: rpc.cpp $(HEADERS) + g++ -c $(CFLAGS) -o $@ $< + +obj/ui_res.o: ui.rc rc/bitcoin.ico rc/check.ico rc/send16.bmp rc/send16mask.bmp rc/send16masknoshadow.bmp rc/send20.bmp rc/send20mask.bmp rc/addressbook16.bmp rc/addressbook16mask.bmp rc/addressbook20.bmp rc/addressbook20mask.bmp + windres $(WXDEFS) $(INCLUDEPATHS) -o $@ -i $< + + + +OBJS=obj/util.o obj/script.o obj/db.o obj/net.o obj/main.o \ + obj/ui.o obj/uibase.o obj/sha.o obj/irc.o obj/rpc.o \ + obj/ui_res.o + +bitcoin.exe: headers.h.gch $(OBJS) + -kill /f bitcoin.exe + g++ $(CFLAGS) -mwindows -Wl,--subsystem,windows -o $@ $(LIBPATHS) $(OBJS) $(LIBS) + +clean: + -del /Q obj\* + -del /Q headers.h.gch diff --git a/makefile.unix b/makefile.unix new file mode 100644 index 0000000000..a8ec936776 --- /dev/null +++ b/makefile.unix @@ -0,0 +1,78 @@ +# 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. + + + +INCLUDEPATHS= \ + -I"/usr/include" \ + -I"/usr/local/include/wx-2.9" \ + -I"/usr/local/lib/wx/include/gtk2-unicode-debug-static-2.9" + +LIBPATHS= \ + -L"/usr/lib" \ + -L"/usr/local/lib" + +LIBS= \ + -Wl,-Bstatic \ + -l boost_system-mt -l boost_filesystem-mt \ + -l db_cxx \ + -l wx_gtk2ud-2.9 \ + -Wl,-Bdynamic \ + -l crypto \ + -l gtk-x11-2.0 -l gthread-2.0 -l SM + +WXDEFS=-D__WXGTK__ -DNOPCH +DEBUGFLAGS=-g -D__WXDEBUG__ +CFLAGS=-O0 -Wno-invalid-offsetof -Wformat $(DEBUGFLAGS) $(WXDEFS) $(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 + + + +all: bitcoin + + +headers.h.gch: headers.h $(HEADERS) + g++ -c $(CFLAGS) -o $@ $< + +obj/util.o: util.cpp $(HEADERS) + g++ -c $(CFLAGS) -o $@ $< + +obj/script.o: script.cpp $(HEADERS) + g++ -c $(CFLAGS) -o $@ $< + +obj/db.o: db.cpp $(HEADERS) + g++ -c $(CFLAGS) -o $@ $< + +obj/net.o: net.cpp $(HEADERS) + g++ -c $(CFLAGS) -o $@ $< + +obj/main.o: main.cpp $(HEADERS) sha.h + g++ -c $(CFLAGS) -o $@ $< + +obj/ui.o: ui.cpp $(HEADERS) + g++ -c $(CFLAGS) -o $@ $< + +obj/uibase.o: uibase.cpp uibase.h + g++ -c $(CFLAGS) -o $@ $< + +obj/sha.o: sha.cpp sha.h + g++ -c $(CFLAGS) -O3 -o $@ $< + +obj/irc.o: irc.cpp $(HEADERS) + g++ -c $(CFLAGS) -o $@ $< + +obj/rpc.o: rpc.cpp $(HEADERS) + g++ -c $(CFLAGS) -o $@ $< + + + +OBJS=obj/util.o obj/script.o obj/db.o obj/net.o obj/main.o \ + obj/ui.o obj/uibase.o obj/sha.o obj/irc.o obj/rpc.o + +bitcoin: headers.h.gch $(OBJS) + g++ $(CFLAGS) -o $@ $(LIBPATHS) $(OBJS) $(LIBS) + +clean: + -rm obj/* + -rm headers.h.gch diff --git a/makefile.unix.wx2.8 b/makefile.unix.wx2.8 deleted file mode 100644 index 38d9bc0e90..0000000000 --- a/makefile.unix.wx2.8 +++ /dev/null @@ -1,88 +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. - - -ifneq "$(BUILD)" "debug" -ifneq "$(BUILD)" "release" -BUILD=debug -endif -endif -ifeq "$(BUILD)" "debug" -D=d -DEBUGFLAGS=-g -D__WXDEBUG__ -endif - - - -INCLUDEPATHS= \ - -I"/usr/include" \ - -I"/usr/local/include/wx-2.8" \ - -I"/usr/local/lib/wx/include/gtk2-ansi-debug-static-2.8" - -LIBPATHS= \ - -L"/usr/lib" \ - -L"/usr/local/lib" - -LIBS= \ - -Wl,-Bstatic \ - -l boost_system -l boost_filesystem \ - -l db_cxx \ - -l wx_gtk2$(D)-2.8 \ - -Wl,-Bdynamic \ - -l crypto \ - -l gtk-x11-2.0 -l gthread-2.0 -l SM - -WXDEFS=-D__WXGTK__ -DNOPCH -CFLAGS=-O0 -Wno-invalid-offsetof -Wformat $(DEBUGFLAGS) $(WXDEFS) $(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 - - - -all: bitcoin - - -headers.h.gch: headers.h $(HEADERS) - g++ -c $(CFLAGS) -o $@ $< - -obj/util.o: util.cpp $(HEADERS) - g++ -c $(CFLAGS) -o $@ $< - -obj/script.o: script.cpp $(HEADERS) - g++ -c $(CFLAGS) -o $@ $< - -obj/db.o: db.cpp $(HEADERS) - g++ -c $(CFLAGS) -o $@ $< - -obj/net.o: net.cpp $(HEADERS) - g++ -c $(CFLAGS) -o $@ $< - -obj/main.o: main.cpp $(HEADERS) sha.h - g++ -c $(CFLAGS) -o $@ $< - -obj/ui.o: ui.cpp $(HEADERS) - g++ -c $(CFLAGS) -o $@ $< - -obj/uibase.o: uibase.cpp uibase.h - g++ -c $(CFLAGS) -o $@ $< - -obj/sha.o: sha.cpp sha.h - g++ -c $(CFLAGS) -O3 -o $@ $< - -obj/irc.o: irc.cpp $(HEADERS) - g++ -c $(CFLAGS) -o $@ $< - -obj/rpc.o: rpc.cpp $(HEADERS) - g++ -c $(CFLAGS) -o $@ $< - - - -OBJS=obj/util.o obj/script.o obj/db.o obj/net.o obj/main.o \ - obj/ui.o obj/uibase.o obj/sha.o obj/irc.o obj/rpc.o - -bitcoin: headers.h.gch $(OBJS) - g++ $(CFLAGS) -o $@ $(LIBPATHS) $(OBJS) $(LIBS) - -clean: - -rm obj/* - -rm headers.h.gch diff --git a/makefile.unix.wx2.9 b/makefile.unix.wx2.9 deleted file mode 100644 index 0b3b09b577..0000000000 --- a/makefile.unix.wx2.9 +++ /dev/null @@ -1,88 +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. - - -ifneq "$(BUILD)" "debug" -ifneq "$(BUILD)" "release" -BUILD=debug -endif -endif -ifeq "$(BUILD)" "debug" -D=d -DEBUGFLAGS=-g -D__WXDEBUG__ -endif - - - -INCLUDEPATHS= \ - -I"/usr/include" \ - -I"/usr/local/include/wx-2.9" \ - -I"/usr/local/lib/wx/include/gtk2-unicode-debug-static-2.9" - -LIBPATHS= \ - -L"/usr/lib" \ - -L"/usr/local/lib" - -LIBS= \ - -Wl,-Bstatic \ - -l boost_system-mt -l boost_filesystem-mt \ - -l db_cxx \ - -l wx_gtk2u$(D)-2.9 \ - -Wl,-Bdynamic \ - -l crypto \ - -l gtk-x11-2.0 -l gthread-2.0 -l SM - -WXDEFS=-D__WXGTK__ -DNOPCH -CFLAGS=-O0 -Wno-invalid-offsetof -Wformat $(DEBUGFLAGS) $(WXDEFS) $(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 - - - -all: bitcoin - - -headers.h.gch: headers.h $(HEADERS) - g++ -c $(CFLAGS) -o $@ $< - -obj/util.o: util.cpp $(HEADERS) - g++ -c $(CFLAGS) -o $@ $< - -obj/script.o: script.cpp $(HEADERS) - g++ -c $(CFLAGS) -o $@ $< - -obj/db.o: db.cpp $(HEADERS) - g++ -c $(CFLAGS) -o $@ $< - -obj/net.o: net.cpp $(HEADERS) - g++ -c $(CFLAGS) -o $@ $< - -obj/main.o: main.cpp $(HEADERS) sha.h - g++ -c $(CFLAGS) -o $@ $< - -obj/ui.o: ui.cpp $(HEADERS) - g++ -c $(CFLAGS) -o $@ $< - -obj/uibase.o: uibase.cpp uibase.h - g++ -c $(CFLAGS) -o $@ $< - -obj/sha.o: sha.cpp sha.h - g++ -c $(CFLAGS) -O3 -o $@ $< - -obj/irc.o: irc.cpp $(HEADERS) - g++ -c $(CFLAGS) -o $@ $< - -obj/rpc.o: rpc.cpp $(HEADERS) - g++ -c $(CFLAGS) -o $@ $< - - - -OBJS=obj/util.o obj/script.o obj/db.o obj/net.o obj/main.o \ - obj/ui.o obj/uibase.o obj/sha.o obj/irc.o obj/rpc.o - -bitcoin: headers.h.gch $(OBJS) - g++ $(CFLAGS) -o $@ $(LIBPATHS) $(OBJS) $(LIBS) - -clean: - -rm obj/* - -rm headers.h.gch diff --git a/makefile.vc b/makefile.vc index 5ca8de464c..c407be3d2f 100644 --- a/makefile.vc +++ b/makefile.vc @@ -3,26 +3,31 @@ # file license.txt or http://www.opensource.org/licenses/mit-license.php. -!IF "$(BUILD)" != "debug" && "$(BUILD)" != "release" -BUILD=debug -!ENDIF -!IF "$(BUILD)" == "debug" -D=d -DEBUGFLAGS=/Zi /Od /D__WXDEBUG__ -!ENDIF +# for wxWidgets-2.8.x, search and replace "mswud"->"mswd" and "29u"->"28" +INCLUDEPATHS= \ + /I"/boost" \ + /I"/db/build_windows" \ + /I"/openssl/include" \ + /I"/wxwidgets/lib/vc_lib/mswud" \ + /I"/wxwidgets/include" +LIBPATHS= \ + /LIBPATH:"/boost/stage/lib" \ + /LIBPATH:"/db/build_windows/debug" \ + /LIBPATH:"/openssl/out" \ + /LIBPATH:"/wxwidgets/lib/vc_lib" -INCLUDEPATHS=/I"/boost" /I"/db/build_windows" /I"/openssl/include" /I"/wxwidgets/lib/vc_lib/mswd" /I"/wxwidgets/include" -LIBPATHS=/LIBPATH:"/boost/stage/lib" /LIBPATH:"/db/build_windows/$(BUILD)" /LIBPATH:"/openssl/out" /LIBPATH:"/wxwidgets/lib/vc_lib" LIBS= \ - libboost_system-vc80-mt-gd.lib libboost_filesystem-vc80-mt-gd.lib \ - libdb47s$(D).lib \ - libeay32.lib \ - wxmsw28$(D)_richtext.lib wxmsw28$(D)_html.lib wxmsw28$(D)_core.lib wxmsw28$(D)_adv.lib wxbase28$(D).lib wxtiff$(D).lib wxjpeg$(D).lib wxpng$(D).lib wxzlib$(D).lib wxregex$(D).lib wxexpat$(D).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 + libboost_system-vc80-mt-gd.lib libboost_filesystem-vc80-mt-gd.lib \ + libdb47sd.lib \ + libeay32.lib \ + wxmsw29ud_html.lib wxmsw29ud_core.lib wxmsw29ud_adv.lib wxbase29ud.lib wxtiffd.lib wxjpegd.lib wxpngd.lib wxzlibd.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 + WXDEFS=/DWIN32 /D__WXMSW__ /D_WINDOWS /DNOPCH -CFLAGS=/c /nologo /Ob0 /MD$(D) /EHsc /GR /Zm300 $(DEBUGFLAGS) $(WXDEFS) $(INCLUDEPATHS) +DEBUGFLAGS=/Zi /Od /D__WXDEBUG__ +CFLAGS=/c /nologo /Ob0 /MDd /EHsc /GR /Zm300 $(DEBUGFLAGS) $(WXDEFS) $(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 diff --git a/serialize.h b/serialize.h index 12b58ad1ca..f3b99978df 100644 --- a/serialize.h +++ b/serialize.h @@ -19,8 +19,8 @@ class CScript; class CDataStream; class CAutoFile; -static const int VERSION = 201; -static const char* pszSubVer = ".2"; +static const int VERSION = 202; +static const char* pszSubVer = ".0"; diff --git a/ui.cpp b/ui.cpp index f506fcf3e7..87ba19e082 100644 --- a/ui.cpp +++ b/ui.cpp @@ -229,8 +229,8 @@ CMainFrame::CMainFrame(wxWindow* parent) : CMainFrameBase(parent) m_staticTextBalance->SetSize(140, 17); // & underlines don't work on the toolbar buttons on gtk m_toolBar->ClearTools(); - 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->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(); // resize to fit ubuntu's huge default font dResize = 1.20; @@ -244,13 +244,13 @@ CMainFrame::CMainFrame(wxWindow* parent) : CMainFrameBase(parent) int nDateWidth = DateTimeStr(1229413914).size() * 6 + 8; if (!strstr(DateTimeStr(1229413914).c_str(), "2008")) nDateWidth += 12; - m_listCtrl->InsertColumn(0, "", wxLIST_FORMAT_LEFT, dResize * 0); - m_listCtrl->InsertColumn(1, "", wxLIST_FORMAT_LEFT, dResize * 0); - m_listCtrl->InsertColumn(2, "Status", wxLIST_FORMAT_LEFT, dResize * 110); - m_listCtrl->InsertColumn(3, "Date", wxLIST_FORMAT_LEFT, dResize * nDateWidth); - m_listCtrl->InsertColumn(4, "Description", wxLIST_FORMAT_LEFT, dResize * 409 - nDateWidth); - m_listCtrl->InsertColumn(5, "Debit", wxLIST_FORMAT_RIGHT, dResize * 79); - m_listCtrl->InsertColumn(6, "Credit", wxLIST_FORMAT_RIGHT, dResize * 79); + m_listCtrl->InsertColumn(0, "", wxLIST_FORMAT_LEFT, dResize * 0); + m_listCtrl->InsertColumn(1, "", wxLIST_FORMAT_LEFT, dResize * 0); + m_listCtrl->InsertColumn(2, _("Status"), wxLIST_FORMAT_LEFT, dResize * 110); + m_listCtrl->InsertColumn(3, _("Date"), wxLIST_FORMAT_LEFT, dResize * nDateWidth); + m_listCtrl->InsertColumn(4, _("Description"), wxLIST_FORMAT_LEFT, dResize * 409 - nDateWidth); + m_listCtrl->InsertColumn(5, _("Debit"), wxLIST_FORMAT_RIGHT, dResize * 79); + m_listCtrl->InsertColumn(6, _("Credit"), wxLIST_FORMAT_RIGHT, dResize * 79); // Init status bar int pnWidths[3] = { -100, 88, 290 }; @@ -450,19 +450,19 @@ string FormatTxStatus(const CWalletTx& wtx) if (!wtx.IsFinal()) { if (wtx.nLockTime < 500000000) - return strprintf("Open for %d blocks", nBestHeight - wtx.nLockTime); + return strprintf(_("Open for %d blocks"), nBestHeight - wtx.nLockTime); else - return strprintf("Open until %s", DateTimeStr(wtx.nLockTime).c_str()); + 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); + return strprintf(_("%d/offline?"), nDepth); else if (nDepth < 6) - return strprintf("%d/unconfirmed", nDepth); + return strprintf(_("%d/unconfirmed"), nDepth); else - return strprintf("%d confirmations", nDepth); + return strprintf(_("%d confirmations"), nDepth); } } @@ -547,7 +547,7 @@ bool CMainFrame::InsertTransaction(const CWalletTx& wtx, bool fNew, int nIndex) if (wtx.IsCoinBase()) { // Coinbase - strDescription = "Generated"; + strDescription = _("Generated"); if (nCredit == 0) { int64 nUnmatured = 0; @@ -555,15 +555,15 @@ bool CMainFrame::InsertTransaction(const CWalletTx& wtx, bool fNew, int nIndex) nUnmatured += txout.GetCredit(); if (wtx.IsInMainChain()) { - strDescription = strprintf("Generated (%s matures in %d more blocks)", FormatMoney(nUnmatured).c_str(), wtx.GetBlocksToMaturity()); + 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!"; + strDescription = _("Generated - Warning: This block was not received by any other nodes and will probably not be accepted!"); } else { - strDescription = "Generated (not accepted)"; + strDescription = _("Generated (not accepted)"); } } } @@ -571,7 +571,7 @@ bool CMainFrame::InsertTransaction(const CWalletTx& wtx, bool fNew, int nIndex) { // Online transaction if (!mapValue["from"].empty()) - strDescription += "From: " + mapValue["from"]; + strDescription += _("From: ") + mapValue["from"]; if (!mapValue["message"].empty()) { if (!strDescription.empty()) @@ -594,9 +594,9 @@ bool CMainFrame::InsertTransaction(const CWalletTx& wtx, bool fNew, int nIndex) string strAddress = PubKeyToAddress(vchPubKey); if (mapAddressBook.count(strAddress)) { - //strDescription += "Received payment to "; - //strDescription += "Received with address "; - strDescription += "From: unknown, To: "; + //strDescription += _("Received payment to "); + //strDescription += _("Received with address "); + strDescription += _("From: unknown, To: "); strDescription += strAddress; /// The labeling feature is just too confusing, so I hid it /// by putting it at the end where it runs off the screen. @@ -636,7 +636,7 @@ bool CMainFrame::InsertTransaction(const CWalletTx& wtx, bool fNew, int nIndex) InsertLine(fNew, nIndex, hash, strSort, strStatus, nTime ? DateTimeStr(nTime) : "", - "Payment to yourself", + _("Payment to yourself"), "", ""); /// issue: can't tell which is the payment and which is the change anymore @@ -670,7 +670,7 @@ bool CMainFrame::InsertTransaction(const CWalletTx& wtx, bool fNew, int nIndex) strAddress = Hash160ToAddress(hash160); } - string strDescription = "To: "; + string strDescription = _("To: "); CRITICAL_BLOCK(cs_mapAddressBook) if (mapAddressBook.count(strAddress) && !mapAddressBook[strAddress].empty()) strDescription += mapAddressBook[strAddress] + " "; @@ -960,12 +960,12 @@ void CMainFrame::OnPaintListCtrl(wxPaintEvent& event) // Update status bar string strGen = ""; if (fGenerateBitcoins) - strGen = " Generating"; + strGen = _(" Generating"); if (fGenerateBitcoins && vNodes.empty()) - strGen = "(not connected)"; + strGen = _("(not connected)"); m_statusBar->SetStatusText(strGen, 1); - string strStatus = strprintf(" %d connections %d blocks %d transactions", vNodes.size(), nBestHeight + 1, nTransactionCount); + string strStatus = strprintf(_(" %d connections %d blocks %d transactions"), vNodes.size(), nBestHeight + 1, nTransactionCount); m_statusBar->SetStatusText(strStatus, 2); if (fDebug && GetTime() - nThreadSocketHandlerHeartbeat > 60) @@ -1160,20 +1160,20 @@ CTxDetailsDialog::CTxDetailsDialog(wxWindow* parent, CWalletTx wtx) : CTxDetails - strHTML += "Status: " + FormatTxStatus(wtx); + strHTML += _("Status: ") + FormatTxStatus(wtx); int nRequests = wtx.GetRequestCount(); if (nRequests != -1) { if (nRequests == 0) - strHTML += ", has not been successfully broadcast yet"; + strHTML += _(", has not been successfully broadcast yet"); else if (nRequests == 1) - strHTML += strprintf(", broadcast through %d node", nRequests); + strHTML += strprintf(_(", broadcast through %d node"), nRequests); else - strHTML += strprintf(", broadcast through %d nodes", nRequests); + strHTML += strprintf(_(", broadcast through %d nodes"), nRequests); } strHTML += "
"; - strHTML += "Date: " + (nTime ? DateTimeStr(nTime) : "") + "
"; + strHTML += _("Date: ") + (nTime ? DateTimeStr(nTime) : "") + "
"; // @@ -1181,13 +1181,13 @@ CTxDetailsDialog::CTxDetailsDialog(wxWindow* parent, CWalletTx wtx) : CTxDetails // if (wtx.IsCoinBase()) { - strHTML += "Source: Generated
"; + strHTML += _("Source: Generated
"); } else if (!wtx.mapValue["from"].empty()) { // Online transaction if (!wtx.mapValue["from"].empty()) - strHTML += "From: " + HtmlEscape(wtx.mapValue["from"]) + "
"; + strHTML += _("From: ") + HtmlEscape(wtx.mapValue["from"]) + "
"; } else { @@ -1205,13 +1205,13 @@ CTxDetailsDialog::CTxDetailsDialog(wxWindow* parent, CWalletTx wtx) : CTxDetails string strAddress = PubKeyToAddress(vchPubKey); if (mapAddressBook.count(strAddress)) { - strHTML += "From: unknown
"; - strHTML += "To: "; + strHTML += string() + _("From: ") + _("unknown") + "
"; + strHTML += _("To: "); strHTML += HtmlEscape(strAddress); if (!mapAddressBook[strAddress].empty()) - strHTML += " (yours, label: " + mapAddressBook[strAddress] + ")"; + strHTML += _(" (yours, label: ") + mapAddressBook[strAddress] + ")"; else - strHTML += " (yours)"; + strHTML += _(" (yours)"); strHTML += "
"; } } @@ -1230,7 +1230,7 @@ CTxDetailsDialog::CTxDetailsDialog(wxWindow* parent, CWalletTx wtx) : CTxDetails { // Online transaction strAddress = wtx.mapValue["to"]; - strHTML += "To: "; + strHTML += _("To: "); if (mapAddressBook.count(strAddress) && !mapAddressBook[strAddress].empty()) strHTML += mapAddressBook[strAddress] + " "; strHTML += HtmlEscape(strAddress) + "
"; @@ -1248,17 +1248,19 @@ CTxDetailsDialog::CTxDetailsDialog(wxWindow* parent, CWalletTx wtx) : CTxDetails int64 nUnmatured = 0; foreach(const CTxOut& txout, wtx.vout) nUnmatured += txout.GetCredit(); + strHTML += _("Credit: "); if (wtx.IsInMainChain()) - strHTML += strprintf("Credit: (%s matures in %d more blocks)
", FormatMoney(nUnmatured).c_str(), wtx.GetBlocksToMaturity()); + strHTML += strprintf(_("(%s matures in %d more blocks)"), FormatMoney(nUnmatured).c_str(), wtx.GetBlocksToMaturity()); else - strHTML += "Credit: (not accepted)
"; + strHTML += _("(not accepted)"); + strHTML += "
"; } else if (nNet > 0) { // // Credit // - strHTML += "Credit: " + FormatMoney(nNet) + "
"; + strHTML += _("Credit: ") + FormatMoney(nNet) + "
"; } else { @@ -1287,7 +1289,7 @@ CTxDetailsDialog::CTxDetailsDialog(wxWindow* parent, CWalletTx wtx) : CTxDetails if (ExtractHash160(txout.scriptPubKey, hash160)) { string strAddress = Hash160ToAddress(hash160); - strHTML += "To: "; + strHTML += _("To: "); if (mapAddressBook.count(strAddress) && !mapAddressBook[strAddress].empty()) strHTML += mapAddressBook[strAddress] + " "; strHTML += strAddress; @@ -1295,7 +1297,7 @@ CTxDetailsDialog::CTxDetailsDialog(wxWindow* parent, CWalletTx wtx) : CTxDetails } } - strHTML += "Debit: " + FormatMoney(-txout.nValue) + "
"; + strHTML += _("Debit: ") + FormatMoney(-txout.nValue) + "
"; } if (fAllToMe) @@ -1303,13 +1305,13 @@ CTxDetailsDialog::CTxDetailsDialog(wxWindow* parent, CWalletTx wtx) : CTxDetails // Payment to self /// issue: can't tell which is the payment and which is the change anymore //int64 nValue = wtx.vout[0].nValue; - //strHTML += "Debit: " + FormatMoney(-nValue) + "
"; - //strHTML += "Credit: " + FormatMoney(nValue) + "
"; + //strHTML += _("Debit: ") + FormatMoney(-nValue) + "
"; + //strHTML += _("Credit: ") + FormatMoney(nValue) + "
"; } int64 nTxFee = nDebit - wtx.GetValueOut(); if (nTxFee > 0) - strHTML += "Transaction fee: " + FormatMoney(-nTxFee) + "
"; + strHTML += _("Transaction fee: ") + FormatMoney(-nTxFee) + "
"; } else { @@ -1318,24 +1320,24 @@ CTxDetailsDialog::CTxDetailsDialog(wxWindow* parent, CWalletTx wtx) : CTxDetails // foreach(const CTxIn& txin, wtx.vin) if (txin.IsMine()) - strHTML += "Debit: " + FormatMoney(-txin.GetDebit()) + "
"; + strHTML += _("Debit: ") + FormatMoney(-txin.GetDebit()) + "
"; foreach(const CTxOut& txout, wtx.vout) if (txout.IsMine()) - strHTML += "Credit: " + FormatMoney(txout.GetCredit()) + "
"; + strHTML += _("Credit: ") + FormatMoney(txout.GetCredit()) + "
"; } } - strHTML += "Net amount: " + FormatMoney(nNet, true) + "
"; + strHTML += _("Net amount: ") + FormatMoney(nNet, true) + "
"; // // Message // if (!wtx.mapValue["message"].empty()) - strHTML += "
Message:
" + HtmlEscape(wtx.mapValue["message"], true) + "
"; + strHTML += string() + "
" + _("Message:") + "
" + HtmlEscape(wtx.mapValue["message"], true) + "
"; if (wtx.IsCoinBase()) - strHTML += "
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.
"; + strHTML += string() + "
" + _("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.") + "
"; // @@ -1402,12 +1404,12 @@ void CTxDetailsDialog::OnButtonOK(wxCommandEvent& event) COptionsDialog::COptionsDialog(wxWindow* parent) : COptionsDialogBase(parent) { // Set up list box of page choices - m_listBox->Append("Main"); - //m_listBox->Append("Test 2"); + m_listBox->Append(_("Main")); + //m_listBox->Append(_("Test 2")); m_listBox->SetSelection(0); SelectPage(0); #ifndef __WXMSW__ - m_checkBoxMinimizeOnClose->SetLabel("&Minimize on close"); + m_checkBoxMinimizeOnClose->SetLabel(_("&Minimize on close")); m_checkBoxStartOnSystemStartup->Enable(false); // not implemented yet #endif @@ -1559,16 +1561,16 @@ void COptionsDialog::OnButtonApply(wxCommandEvent& event) CAboutDialog::CAboutDialog(wxWindow* parent) : CAboutDialogBase(parent) { - m_staticTextVersion->SetLabel(strprintf("version 0.%d.%d beta", VERSION/100, VERSION%100)); + m_staticTextVersion->SetLabel(strprintf(_("version 0.%d.%d beta"), VERSION/100, VERSION%100)); -#if !wxUSE_UNICODE - // Workaround until upgrade to wxWidgets supporting UTF-8 - // Hack to change the (c) character from UTF-8 back to ANSI + // Change (c) into UTF-8 or ANSI copyright symbol wxString str = m_staticTextMain->GetLabel(); - if (str.Find('\xC2') != wxNOT_FOUND) - str.Remove(str.Find('\xC2'), 1); - m_staticTextMain->SetLabel(str); +#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 @@ -1577,7 +1579,7 @@ CAboutDialog::CAboutDialog(wxWindow* parent) : CAboutDialogBase(parent) if (fontTmp.GetPointSize() > 8); fontTmp.SetPointSize(8); m_staticTextMain->SetFont(fontTmp); - SetSize(GetSize().GetWidth() + 44, GetSize().GetHeight() - 4); + SetSize(GetSize().GetWidth() + 44, GetSize().GetHeight() + 10); #endif } @@ -1644,8 +1646,8 @@ void CSendDialog::OnTextAddress(wxCommandEvent& event) { strFromSave = m_textCtrlFrom->GetValue(); strMessageSave = m_textCtrlMessage->GetValue(); - m_textCtrlFrom->SetValue("Will appear as \"From: Unknown\""); - m_textCtrlMessage->SetValue("Can't include a message when sending to a Bitcoin address"); + m_textCtrlFrom->SetValue(_("Will appear as \"From: Unknown\"")); + m_textCtrlMessage->SetValue(_("Can't include a message when sending to a Bitcoin address")); } else if (fEnable && !fEnabledPrev) { @@ -1697,17 +1699,17 @@ void CSendDialog::OnButtonSend(wxCommandEvent& event) int64 nValue = 0; if (!ParseMoney(m_textCtrlAmount->GetValue(), nValue) || nValue <= 0) { - wxMessageBox("Error in amount ", "Send Coins"); + wxMessageBox(_("Error in amount "), _("Send Coins")); return; } if (nValue > GetBalance()) { - wxMessageBox("Amount exceeds your balance ", "Send Coins"); + wxMessageBox(_("Amount exceeds your balance "), _("Send Coins")); return; } if (nValue + nTransactionFee > GetBalance()) { - wxMessageBox(string("Total exceeds your balance when the ") + FormatMoney(nTransactionFee) + " transaction fee is included ", "Send Coins"); + wxMessageBox(string(_("Total exceeds your balance when the ")) + FormatMoney(nTransactionFee) + _(" transaction fee is included "), _("Send Coins")); return; } @@ -1723,9 +1725,9 @@ void CSendDialog::OnButtonSend(wxCommandEvent& event) string strError = SendMoney(scriptPubKey, nValue, wtx); if (strError != "") - wxMessageBox(strError + " ", "Sending..."); + wxMessageBox(strError + " ", _("Sending...")); else - wxMessageBox("Payment sent ", "Sending..."); + wxMessageBox(_("Payment sent "), _("Sending...")); } else { @@ -1733,7 +1735,7 @@ void CSendDialog::OnButtonSend(wxCommandEvent& event) CAddress addr(strAddress); if (!addr.IsValid()) { - wxMessageBox("Invalid address ", "Send Coins"); + wxMessageBox(_("Invalid address "), _("Send Coins")); return; } @@ -1787,7 +1789,7 @@ CSendingDialog::CSendingDialog(wxWindow* parent, const CAddress& addrIn, int64 n SetSize(1.2 * GetSize().GetWidth(), 1.08 * GetSize().GetHeight()); #endif - SetTitle(strprintf("Sending %s to %s", FormatMoney(nPrice).c_str(), wtx.mapValue["to"].c_str())); + SetTitle(strprintf(_("Sending %s to %s"), FormatMoney(nPrice).c_str(), wtx.mapValue["to"].c_str())); m_textCtrlStatus->SetValue(""); CreateThread(SendingDialogStartTransfer, this); @@ -1859,13 +1861,13 @@ void CSendingDialog::OnPaint(wxPaintEvent& event) } if (fAbort && fCanCancel && IsShown()) { - strcpy(pszStatus, "CANCELLED"); + strcpy(pszStatus, _("CANCELLED")); m_buttonOK->Enable(true); m_buttonOK->SetFocus(); m_buttonCancel->Enable(false); - m_buttonCancel->SetLabel("Cancelled"); + m_buttonCancel->SetLabel(_("Cancelled")); Close(); - wxMessageBox("Transfer cancelled ", "Sending...", wxOK, this); + wxMessageBox(_("Transfer cancelled "), _("Sending..."), wxOK, this); } event.Skip(); } @@ -1893,7 +1895,7 @@ bool CSendingDialog::Status() if (fAbort && fCanCancel) { memset(pszStatus, 0, 10); - strcpy(pszStatus, "CANCELLED"); + strcpy(pszStatus, _("CANCELLED")); Repaint(); fWorkDone = true; return false; @@ -1919,7 +1921,7 @@ bool CSendingDialog::Error(const string& str) { fCanCancel = false; fWorkDone = true; - Status(string("Error: ") + str); + Status(string(_("Error: ")) + str); return false; } @@ -1933,22 +1935,22 @@ void CSendingDialog::StartTransfer() // Make sure we have enough money if (nPrice + nTransactionFee > GetBalance()) { - Error("You don't have enough money"); + Error(_("You don't have enough money")); return; } // We may have connected already for product details - if (!Status("Connecting...")) + if (!Status(_("Connecting..."))) return; CNode* pnode = ConnectNode(addr, 15 * 60); if (!pnode) { - Error("Unable to connect"); + Error(_("Unable to connect")); return; } // Send order to seller, with response going to OnReply2 via event handler - if (!Status("Requesting public key...")) + if (!Status(_("Requesting public key..."))) return; pnode->PushRequest("checkorder", wtx, SendingDialogOnReply2, this); } @@ -1960,7 +1962,7 @@ void SendingDialogOnReply2(void* parg, CDataStream& vRecv) void CSendingDialog::OnReply2(CDataStream& vRecv) { - if (!Status("Received public key...")) + if (!Status(_("Received public key..."))) return; CScript scriptPubKey; @@ -1972,7 +1974,7 @@ void CSendingDialog::OnReply2(CDataStream& vRecv) { string strMessage; vRecv >> strMessage; - Error("Transfer was not accepted"); + Error(_("Transfer was not accepted")); //// todo: enlarge the window and enable a hidden white box to put seller's message return; } @@ -1981,7 +1983,7 @@ void CSendingDialog::OnReply2(CDataStream& vRecv) catch (...) { //// what do we want to do about this? - Error("Invalid response received"); + Error(_("Invalid response received")); return; } @@ -1996,11 +1998,11 @@ void CSendingDialog::OnReply2(CDataStream& vRecv) CRITICAL_BLOCK(cs_main) { // Pay - if (!Status("Creating transaction...")) + if (!Status(_("Creating transaction..."))) return; if (nPrice + nTransactionFee > GetBalance()) { - Error("You don't have enough money"); + Error(_("You don't have enough money")); return; } CKey key; @@ -2008,9 +2010,9 @@ void CSendingDialog::OnReply2(CDataStream& vRecv) if (!CreateTransaction(scriptPubKey, nPrice, wtx, key, nFeeRequired)) { if (nPrice + nFeeRequired > GetBalance()) - Error(strprintf("This is an oversized transaction that requires a transaction fee of %s", FormatMoney(nFeeRequired).c_str())); + Error(strprintf(_("This is an oversized transaction that requires a transaction fee of %s"), FormatMoney(nFeeRequired).c_str())); else - Error("Transaction creation failed"); + Error(_("Transaction creation failed")); return; } @@ -2018,7 +2020,7 @@ void CSendingDialog::OnReply2(CDataStream& vRecv) CNode* pnode = ConnectNode(addr, 2 * 60 * 60); if (!pnode) { - Error("Lost connection, transaction cancelled"); + Error(_("Lost connection, transaction cancelled")); return; } @@ -2034,13 +2036,13 @@ void CSendingDialog::OnReply2(CDataStream& vRecv) return; fCanCancel = false; } - if (!Status("Sending payment...")) + if (!Status(_("Sending payment..."))) return; // Commit if (!CommitTransactionSpent(wtx, key)) { - Error("Error finalizing payment"); + Error(_("Error finalizing payment")); return; } @@ -2052,7 +2054,7 @@ void CSendingDialog::OnReply2(CDataStream& vRecv) printf("ERROR: CSendingDialog : wtxNew.AcceptTransaction() %s failed\n", wtx.GetHash().ToString().c_str()); wtx.RelayWalletTransaction(); - Status("Waiting for confirmation..."); + Status(_("Waiting for confirmation...")); MainFrameRepaint(); } } @@ -2070,22 +2072,22 @@ void CSendingDialog::OnReply3(CDataStream& vRecv) 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."); + 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"); + Error(_("Payment was sent, but an invalid response was received")); return; } fSuccess = true; fWorkDone = true; - Status("Payment completed"); + Status(_("Payment completed")); } @@ -2101,8 +2103,8 @@ void CSendingDialog::OnReply3(CDataStream& vRecv) CYourAddressDialog::CYourAddressDialog(wxWindow* parent, const string& strInitSelected) : CYourAddressDialogBase(parent) { // Init column headers - m_listCtrl->InsertColumn(0, "Label", wxLIST_FORMAT_LEFT, 200); - m_listCtrl->InsertColumn(1, "Bitcoin Address", wxLIST_FORMAT_LEFT, 350); + m_listCtrl->InsertColumn(0, _("Label"), wxLIST_FORMAT_LEFT, 200); + m_listCtrl->InsertColumn(1, _("Bitcoin Address"), wxLIST_FORMAT_LEFT, 350); m_listCtrl->SetFocus(); // Fill listctrl with address book data @@ -2162,7 +2164,7 @@ void CYourAddressDialog::OnButtonRename(wxCommandEvent& event) return; string strName = (string)m_listCtrl->GetItemText(nIndex); string strAddress = (string)GetItemText(m_listCtrl, nIndex, 1); - CGetTextFromUserDialog dialog(this, "Edit Address Label", "New Label", strName); + CGetTextFromUserDialog dialog(this, _("Edit Address Label"), _("New Label"), strName); if (!dialog.ShowModal()) return; strName = dialog.GetValue(); @@ -2176,7 +2178,7 @@ void CYourAddressDialog::OnButtonRename(wxCommandEvent& event) void CYourAddressDialog::OnButtonNew(wxCommandEvent& event) { // Ask name - CGetTextFromUserDialog dialog(this, "New Bitcoin Address", "Label", ""); + CGetTextFromUserDialog dialog(this, _("New Bitcoin Address"), _("Label"), ""); if (!dialog.ShowModal()) return; string strName = dialog.GetValue(); @@ -2236,8 +2238,8 @@ CAddressBookDialog::CAddressBookDialog(wxWindow* parent, const wxString& strInit m_buttonCancel->Show(false); // Init column headers - m_listCtrl->InsertColumn(0, "Name", wxLIST_FORMAT_LEFT, 200); - m_listCtrl->InsertColumn(1, "Address", wxLIST_FORMAT_LEFT, 350); + m_listCtrl->InsertColumn(0, _("Name"), wxLIST_FORMAT_LEFT, 200); + m_listCtrl->InsertColumn(1, _("Address"), wxLIST_FORMAT_LEFT, 350); m_listCtrl->SetFocus(); // Set Icon @@ -2307,7 +2309,7 @@ bool CAddressBookDialog::CheckIfMine(const string& strAddress, const string& str 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); + wxMessageBox(_("This is one of your own addresses for receiving payments and cannot be entered in the address book. "), strTitle); return fMine; } @@ -2322,13 +2324,13 @@ void CAddressBookDialog::OnButtonEdit(wxCommandEvent& event) string strAddressOrg = strAddress; do { - CGetTextFromUserDialog dialog(this, "Edit Address", "Name", strName, "Address", strAddress); + CGetTextFromUserDialog dialog(this, _("Edit Address"), _("Name"), strName, _("Address"), strAddress); if (!dialog.ShowModal()) return; strName = dialog.GetValue1(); strAddress = dialog.GetValue2(); } - while (CheckIfMine(strAddress, "Edit Address")); + while (CheckIfMine(strAddress, _("Edit Address"))); // Change name if (strAddress != strAddressOrg) @@ -2346,13 +2348,13 @@ void CAddressBookDialog::OnButtonNew(wxCommandEvent& event) string strAddress; do { - CGetTextFromUserDialog dialog(this, "New Address", "Name", strName, "Address", strAddress); + CGetTextFromUserDialog dialog(this, _("New Address"), _("Name"), strName, _("Address"), strAddress); if (!dialog.ShowModal()) return; strName = dialog.GetValue1(); strAddress = dialog.GetValue2(); } - while (CheckIfMine(strAddress, "New Address")); + while (CheckIfMine(strAddress, _("New Address"))); // Add to list and select it SetAddressBookName(strAddress, strName); @@ -2436,11 +2438,11 @@ void CMyTaskBarIcon::Show(bool fShow) static char pszPrevTip[200]; if (fShow) { - string strTooltip = "Bitcoin"; + string strTooltip = _("Bitcoin"); if (fGenerateBitcoins) - strTooltip = "Bitcoin - Generating"; + strTooltip = _("Bitcoin - Generating"); if (fGenerateBitcoins && vNodes.empty()) - strTooltip = "Bitcoin - (not connected)"; + 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) @@ -2515,12 +2517,12 @@ void CMyTaskBarIcon::UpdateTooltip() wxMenu* CMyTaskBarIcon::CreatePopupMenu() { wxMenu* pmenu = new wxMenu; - pmenu->Append(ID_TASKBAR_RESTORE, "&Open Bitcoin"); - pmenu->Append(ID_TASKBAR_OPTIONS, "O&ptions..."); - pmenu->AppendCheckItem(ID_TASKBAR_GENERATE, "&Generate Coins")->Check(fGenerateBitcoins); + pmenu->Append(ID_TASKBAR_RESTORE, _("&Open Bitcoin")); + pmenu->Append(ID_TASKBAR_OPTIONS, _("O&ptions...")); + pmenu->AppendCheckItem(ID_TASKBAR_GENERATE, _("&Generate Coins"))->Check(fGenerateBitcoins); #ifndef __WXMAC_OSX__ // Mac has built-in quit menu pmenu->AppendSeparator(); - pmenu->Append(ID_TASKBAR_EXIT, "E&xit"); + pmenu->Append(ID_TASKBAR_EXIT, _("E&xit")); #endif return pmenu; } @@ -2542,7 +2544,9 @@ wxMenu* CMyTaskBarIcon::CreatePopupMenu() // Define a new application class CMyApp: public wxApp { - public: +public: + wxLocale m_locale; + CMyApp(){}; ~CMyApp(){}; bool OnInit(); @@ -2584,9 +2588,9 @@ bool CMyApp::OnInit() bool CMyApp::OnInit2() { #ifdef _MSC_VER - // Turn off microsoft heap dump noise for now + // Turn off microsoft heap dump noise _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE); - _CrtSetReportFile(_CRT_WARN, CreateFile("NUL", GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0)); + _CrtSetReportFile(_CRT_WARN, CreateFileA("NUL", GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0)); #endif #if defined(__WXMSW__) && defined(__WXDEBUG__) // Disable malfunctioning wxWidgets debug assertion @@ -2599,6 +2603,31 @@ bool CMyApp::OnInit2() SetAppName("bitcoin"); umask(077); #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//LC_MESSAGES/bitcoin.mo language file + m_locale.Init(wxLANGUAGE_DEFAULT, 0); + m_locale.AddCatalogLookupPathPrefix("locale"); + if (!fWindows) + { + m_locale.AddCatalogLookupPathPrefix("/usr/share/locale"); + m_locale.AddCatalogLookupPathPrefix("/usr/local/share/locale"); + } + m_locale.AddCatalog("wxstd"); // wxWidgets standard translations, if any + m_locale.AddCatalog("bitcoin"); // // Parameters @@ -2612,33 +2641,31 @@ bool CMyApp::OnInit2() ParseParameters(argc, argv); if (mapArgs.count("-?") || mapArgs.count("--help")) { -#ifdef __WXMSW__ - string strUsage = - "Usage: bitcoin [options]\t\t\t\t\t\t\n" - "Options:\n" - " -gen\t\t Generate coins\n" - " -gen=0\t\t Don't generate coins\n" - " -min\t\t Start minimized\n" - " -datadir=\t Specify data directory\n" - " -proxy=\t Connect through socks4 proxy\n" - " -addnode=\t Add a node to connect to\n" - " -connect=\t Connect only to the specified node\n" - " -?\t\t This help message\n"; - wxMessageBox(strUsage, "Bitcoin", wxOK); -#else - string strUsage = - "Usage: bitcoin [options]\n" - "Options:\n" - " -gen Generate coins\n" - " -gen=0 Don't generate coins\n" - " -min Start minimized\n" - " -datadir= Specify data directory\n" - " -proxy= Connect through socks4 proxy\n" - " -addnode= Add a node to connect to\n" - " -connect= Connect only to the specified node\n" - " -? This help message\n"; - fprintf(stderr, "%s", strUsage.c_str()); -#endif + wxString strUsage = string() + + _("Usage: bitcoin [options]") + "\t\t\t\t\t\t\n" + + _("Options:\n") + + " -gen \t\t " + _("Generate coins\n") + + " -gen=0 \t\t " + _("Don't generate coins\n") + + " -min \t\t " + _("Start minimized\n") + + " -datadir= \t " + _("Specify data directory\n") + + " -proxy=\t " + _("Connect through socks4 proxy\n") + + " -addnode= \t " + _("Add a node to connect to\n") + + " -connect= \t " + _("Connect only to the specified node\n") + + " -? \t\t " + _("This help message\n"); + + if (fWindows) + { + // Remove spaces, the tabs make the columns line up in the message box + for (int i = 0; i < 50; i++) + strUsage.Replace(" \t", "\t"); + wxMessageBox(strUsage, "Bitcoin", wxOK); + } + else + { + // Remove tabs + strUsage.Replace("\t", ""); + fprintf(stderr, "%s", ((string)strUsage).c_str()); + } return false; } @@ -2661,7 +2688,9 @@ bool CMyApp::OnInit2() if (!fDebug && !pszSetDataDir[0]) 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 %d%s, OS version %s\n", VERSION, pszSubVer, ((string)wxGetOsDescription()).c_str()); + printf("Bitcoin version 0.%d.%d%s beta, OS version %s\n", VERSION/100, VERSION%100, pszSubVer, ((string)wxGetOsDescription()).c_str()); + printf("System default language is %d %s\n", m_locale.GetSystemLanguage(), ((string)m_locale.GetSysName()).c_str()); + printf("Language file %s (%s)\n", (string("locale/") + (string)m_locale.GetCanonicalName() + "/LC_MESSAGES/bitcoin.mo").c_str(), ((string)m_locale.GetLocale()).c_str()); if (mapArgs.count("-loadblockindextest")) { @@ -2691,7 +2720,7 @@ bool CMyApp::OnInit2() { // TODO: find out how to do this in Linux, or replace with wxWidgets commands // Show the previous instance and exit - HWND hwndPrev = FindWindow("wxWindowClassNR", "Bitcoin"); + HWND hwndPrev = FindWindowA("wxWindowClassNR", "Bitcoin"); if (hwndPrev) { if (IsIconic(hwndPrev)) @@ -2732,19 +2761,19 @@ bool CMyApp::OnInit2() printf("Loading addresses...\n"); nStart = GetTimeMillis(); if (!LoadAddresses()) - strErrors += "Error loading addr.dat \n"; + strErrors += _("Error loading addr.dat \n"); printf(" addresses %15"PRI64d"ms\n", GetTimeMillis() - nStart); printf("Loading block index...\n"); nStart = GetTimeMillis(); if (!LoadBlockIndex()) - strErrors += "Error loading blkindex.dat \n"; + strErrors += _("Error loading blkindex.dat \n"); printf(" block index %15"PRI64d"ms\n", GetTimeMillis() - nStart); printf("Loading wallet...\n"); nStart = GetTimeMillis(); if (!LoadWallet(fFirstRun)) - strErrors += "Error loading wallet.dat \n"; + strErrors += _("Error loading wallet.dat \n"); printf(" wallet %15"PRI64d"ms\n", GetTimeMillis() - nStart); printf("Done loading\n"); @@ -2812,7 +2841,7 @@ bool CMyApp::OnInit2() addrProxy = CAddress(mapArgs["-proxy"]); if (!addrProxy.IsValid()) { - wxMessageBox("Invalid -proxy address", "Bitcoin"); + wxMessageBox(_("Invalid -proxy address"), "Bitcoin"); return false; } } @@ -2947,7 +2976,7 @@ void CMyApp::OnUnhandledException() void CMyApp::OnFatalException() { - wxMessageBox("Program has crashed and will terminate. ", "Bitcoin", wxOK | wxICON_ERROR); + wxMessageBox(_("Program has crashed and will terminate. "), "Bitcoin", wxOK | wxICON_ERROR); } @@ -2962,7 +2991,7 @@ string MyGetSpecialFolderPath(int nFolder, bool fCreate) char pszPath[MAX_PATH+100] = ""; // SHGetSpecialFolderPath is not usually available on NT 4.0 - HMODULE hShell32 = LoadLibrary("shell32.dll"); + HMODULE hShell32 = LoadLibraryA("shell32.dll"); if (hShell32) { PSHGETSPECIALFOLDERPATHA pSHGetSpecialFolderPath = @@ -3017,7 +3046,7 @@ void SetStartOnSystemStartup(bool fAutoStart) if (SUCCEEDED(hres)) { // Get the current executable path - char pszExePath[MAX_PATH]; + TCHAR pszExePath[MAX_PATH]; GetModuleFileName(NULL, pszExePath, sizeof(pszExePath)); // Set the path to the shortcut target diff --git a/ui.h b/ui.h index da1ada7def..50d39ab7fc 100644 --- a/ui.h +++ b/ui.h @@ -16,12 +16,12 @@ extern int fMinimizeOnClose; -extern void HandleCtrlA(wxKeyEvent& event); -extern string FormatTxStatus(const CWalletTx& wtx); -extern void UIThreadCall(boost::function0); -extern void MainFrameRepaint(); -extern void Shutdown(void* parg); -extern int ThreadSafeMessageBox(const string& message, const string& caption="Message", int style=wxOK, wxWindow* parent=NULL, int x=-1, int y=-1); +void HandleCtrlA(wxKeyEvent& event); +string FormatTxStatus(const CWalletTx& wtx); +void UIThreadCall(boost::function0); +void MainFrameRepaint(); +void Shutdown(void* parg); +int ThreadSafeMessageBox(const string& message, const string& caption="Message", int style=wxOK, wxWindow* parent=NULL, int x=-1, int y=-1); diff --git a/uibase.cpp b/uibase.cpp index 03bd791226..5b3f9abc22 100644 --- a/uibase.cpp +++ b/uibase.cpp @@ -1,6 +1,3 @@ -// 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. /////////////////////////////////////////////////////////////////////////// // C++ code generated with wxFormBuilder (version Apr 16 2008) // http://www.wxformbuilder.org/ @@ -406,22 +403,14 @@ COptionsDialogBase::COptionsDialogBase( wxWindow* parent, wxWindowID id, const w bSizer64->Add( 0, 16, 0, wxEXPAND, 5 ); - m_staticText321 = new wxStaticText( m_panelTest2, wxID_ANY, _("Test panel 2 for future expansion"), wxDefaultPosition, wxDefaultSize, 0 ); + 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, _("Let's not start multiple pages until the first page is filled up"), wxDefaultPosition, wxDefaultSize, 0 ); + 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_staticText70 = new wxStaticText( m_panelTest2, wxID_ANY, _("MyLabel"), wxDefaultPosition, wxDefaultSize, 0 ); - m_staticText70->Wrap( -1 ); - bSizer64->Add( m_staticText70, 0, wxALL, 5 ); - - m_staticText71 = new wxStaticText( m_panelTest2, wxID_ANY, _("MyLabel"), wxDefaultPosition, wxDefaultSize, 0 ); - m_staticText71->Wrap( -1 ); - bSizer64->Add( m_staticText71, 0, wxALL, 5 ); - m_panelTest2->SetSizer( bSizer64 ); m_panelTest2->Layout(); bSizer64->Fit( m_panelTest2 ); @@ -521,7 +510,7 @@ CAboutDialogBase::CAboutDialogBase( wxWindow* parent, wxWindowID id, const wxStr bSizer631->Add( 0, 4, 0, wxEXPAND, 5 ); - m_staticTextMain = new wxStaticText( this, wxID_ANY, _("Copyright © 2009-2010 Satoshi Nakamoto.\n\nThis is experimental software. Do not rely on it for actual financial transactions.\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)."), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticTextMain = new wxStaticText( this, wxID_ANY, _("Copyright (c) 2009-2010 Satoshi Nakamoto.\n\nThis is experimental software. Do not rely on it for actual financial transactions.\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)."), wxDefaultPosition, wxDefaultSize, 0 ); m_staticTextMain->Wrap( -1 ); bSizer631->Add( m_staticTextMain, 0, wxALL, 5 ); diff --git a/uibase.h b/uibase.h index 2dfc2af14d..494ed10f7c 100644 --- a/uibase.h +++ b/uibase.h @@ -1,6 +1,3 @@ -// 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. /////////////////////////////////////////////////////////////////////////// // C++ code generated with wxFormBuilder (version Apr 16 2008) // http://www.wxformbuilder.org/ @@ -178,8 +175,6 @@ class COptionsDialogBase : public wxDialog wxStaticText* m_staticText321; wxStaticText* m_staticText69; - wxStaticText* m_staticText70; - wxStaticText* m_staticText71; wxButton* m_buttonOK; wxButton* m_buttonCancel; wxButton* m_buttonApply; diff --git a/uiproject.fbp b/uiproject.fbp index 5c6eaa55a5..988df2a9b9 100644 --- a/uiproject.fbp +++ b/uiproject.fbp @@ -2173,7 +2173,7 @@ 0 wxID_ANY - Test panel 2 for future expansion + // [don't translate] Test panel 2 for future expansion m_staticText321 @@ -2224,7 +2224,7 @@ 0 wxID_ANY - Let's not start multiple pages until the first page is filled up + // [don't translate] Let's not start multiple pages until the first page is filled up m_staticText69 @@ -2263,108 +2263,6 @@
- - 5 - wxALL - 0 - - - - 1 - - - 0 - wxID_ANY - MyLabel - - - m_staticText70 - protected - - - - - - - - - -1 - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALL - 0 - - - - 1 - - - 0 - wxID_ANY - MyLabel - - - m_staticText71 - protected - - - - - - - - - -1 - - - - - - - - - - - - - - - - - - - - - - - - -
@@ -2820,7 +2718,7 @@ 0 wxID_ANY - Copyright © 2009-2010 Satoshi Nakamoto. This is experimental software. Do not rely on it for actual financial transactions. 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). + Copyright (c) 2009-2010 Satoshi Nakamoto. This is experimental software. Do not rely on it for actual financial transactions. 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). m_staticTextMain diff --git a/util.cpp b/util.cpp index 2f5be2227f..266c1dd7df 100644 --- a/util.cpp +++ b/util.cpp @@ -90,7 +90,7 @@ void RandAddSeedPerfmon() unsigned char pdata[250000]; memset(pdata, 0, sizeof(pdata)); unsigned long nSize = sizeof(pdata); - long ret = RegQueryValueEx(HKEY_PERFORMANCE_DATA, "Global", NULL, NULL, pdata, &nSize); + long ret = RegQueryValueExA(HKEY_PERFORMANCE_DATA, "Global", NULL, NULL, pdata, &nSize); RegCloseKey(HKEY_PERFORMANCE_DATA); if (ret == ERROR_SUCCESS) { @@ -193,7 +193,7 @@ inline int OutputDebugStringF(const char* pszFormat, ...) p2++; char c = *p2; *p2 = '\0'; - OutputDebugString(p1); + OutputDebugStringA(p1); *p2 = c; p1 = p2; } @@ -441,7 +441,7 @@ void FormatException(char* pszMessage, std::exception* pex, const char* pszThrea #ifdef __WXMSW__ char pszModule[MAX_PATH]; pszModule[0] = '\0'; - GetModuleFileName(NULL, pszModule, sizeof(pszModule)); + GetModuleFileNameA(NULL, pszModule, sizeof(pszModule)); #else // might not be thread safe, uses wxString //const char* pszModule = wxStandardPaths::Get().GetExecutablePath().mb_str(); diff --git a/util.h b/util.h index 933c71be0b..188a9ece14 100644 --- a/util.h +++ b/util.h @@ -340,10 +340,11 @@ void skipspaces(T& it) ++it; } - - - - +inline const char* wxGetTranslation(const char* psz) +{ + // Return translated UTF-8 const char* + return wxGetTranslation(wxString(psz, wxConvUTF8)).utf8_str(); +} -- cgit v1.2.3 From e4806597650d8a17f1da7a5b5501eb367ea786fc Mon Sep 17 00:00:00 2001 From: s_nakamoto Date: Wed, 17 Feb 2010 17:22:01 +0000 Subject: all builds are now with wxWidgets-2.9.0, we are now using UTF-8, added support for language translation file locale//LC_MESSAGES/bitcoin.mo -- version 0.2.2 git-svn-id: https://bitcoin.svn.sourceforge.net/svnroot/bitcoin/trunk@66 1a98c847-1fd6-4fd8-948a-caf3550aa51b --- build-msw.txt | 24 ++-- build-unix.txt | 22 ++-- locale/readme.txt | 5 + main.cpp | 30 ++--- makefile | 83 ------------- makefile.mingw | 86 ++++++++++++++ makefile.unix | 78 ++++++++++++ makefile.unix.wx2.8 | 88 -------------- makefile.unix.wx2.9 | 88 -------------- makefile.vc | 35 +++--- serialize.h | 4 +- ui.cpp | 337 ++++++++++++++++++++++++++++------------------------ ui.h | 12 +- uibase.cpp | 17 +-- uibase.h | 5 - uiproject.fbp | 108 +---------------- util.cpp | 6 +- util.h | 9 +- 18 files changed, 428 insertions(+), 609 deletions(-) create mode 100644 locale/readme.txt delete mode 100644 makefile create mode 100644 makefile.mingw create mode 100644 makefile.unix delete mode 100644 makefile.unix.wx2.8 delete mode 100644 makefile.unix.wx2.9 diff --git a/build-msw.txt b/build-msw.txt index 9786255e1f..adb526a31d 100644 --- a/build-msw.txt +++ b/build-msw.txt @@ -29,11 +29,11 @@ Dependencies ------------ Libraries you need to download separately and build: - default path download -wxWidgets \wxwidgets prebuilt: http://wxpack.sourceforge.net -OpenSSL \openssl http://www.openssl.org/source/ -Berkeley DB \db http://www.oracle.com/technology/software/products/berkeley-db/index.html -Boost \boost http://www.boost.org/users/download/ + default path download +wxWidgets-2.9 \wxwidgets http://www.wxwidgets.org/downloads/ +OpenSSL \openssl http://www.openssl.org/source/ +Berkeley DB \db http://www.oracle.com/technology/software/products/berkeley-db/index.html +Boost \boost http://www.boost.org/users/download/ Their licenses: wxWidgets LGPL 2.1 with very liberal exceptions @@ -43,10 +43,10 @@ Boost MIT-like license Versions used in this release: MinGW GCC 3.4.5 -wxWidgets 2.8.9 +wxWidgets 2.9.0 OpenSSL 0.9.8k Berkeley DB 4.7.25.NC -Boost 1.34.1 +Boost 1.42.1 Notes @@ -59,6 +59,14 @@ The release is built with GCC and then "strip bitcoin.exe" to strip the debug symbols, which reduces the executable size by about 90%. +wxWidgets +--------- +cd \wxwidgets\build\msw +make -f makefile.gcc + or +nmake -f makefile.vc + + OpenSSL ------- Bitcoin does not use any encryption. If you want to do a no-everything @@ -104,5 +112,5 @@ download bjam.exe from http://sourceforge.net/project/showfiles.php?group_id=7586&package_id=72941 cd \boost bjam toolset=gcc --build-type=complete stage -or + or bjam toolset=msvc --build-type=complete stage diff --git a/build-unix.txt b/build-unix.txt index f1a72eaacc..5e3f574afb 100644 --- a/build-unix.txt +++ b/build-unix.txt @@ -20,15 +20,11 @@ sudo apt-get install libdb4.7-dev sudo apt-get install libdb4.7++-dev sudo apt-get install libboost-dev -The release was built with wxWidgets 2.8.9 ansi on 32-bit. The current -sourcecode can be built on 64-bit with wxWidgets 2.9.0. +We're now using wxWidgets 2.9, which uses UTF-8. -There is currently no libwxgtk2.8-ansi-dev debian package for Karmic. -libwxgtk2.8-dev is the "unicode" build, but for wxWidgets 2.8 "unicode" -means wchar, not UTF-8. wchar wxString doesn't convert to std::string. -We haven't been able to compile the 2.8 versions on 64-bit. - -wxWidgets 2.9 is UTF-8 and compiles on 64-bit. +There isn't currently a debian package of wxWidgets we can use. The 2.8 +packages for Karmic are UTF-16 unicode and won't work for us, and we've had +trouble building 2.8 on 64-bit. You need to download wxWidgets from http://www.wxwidgets.org/downloads/ and build it yourself. See the build instructions and configure parameters @@ -42,9 +38,9 @@ Boost MIT-like license Versions used in this release: GCC 4.3.3 OpenSSL 0.9.8k -wxWidgets 2.8.9 +wxWidgets 2.9.0 Berkeley DB 4.7.25.NC -Boost 1.40.0 +Boost 1.38.0 Notes @@ -59,7 +55,9 @@ symbols, which reduces the executable size by about 90%. wxWidgets --------- -cd /usr/local/wxWidgets-2.8.9 or 2.9.0 +cd /usr/local +tar -xzvf wxWidgets-2.9.0.tar.gz +cd /usr/local/wxWidgets-2.9.0 mkdir buildgtk cd buildgtk ../configure --with-gtk --enable-debug --disable-shared --enable-monolithic @@ -72,7 +70,7 @@ ldconfig Boost ----- If you want to build Boost yourself, -cd /usr/local/boost_1_40_0 +cd /usr/local/boost_1_42_0 su ./bootstrap.sh ./bjam install diff --git a/locale/readme.txt b/locale/readme.txt new file mode 100644 index 0000000000..9fca3ce657 --- /dev/null +++ b/locale/readme.txt @@ -0,0 +1,5 @@ +put bitcoin.po and bitcoin.mo files at: +locale//LC_MESSAGES/bitcoin.mo and .po + +.po is the sourcefile +.mo is the compiled translation diff --git a/main.cpp b/main.cpp index 3391a2994a..665a78e207 100644 --- a/main.cpp +++ b/main.cpp @@ -1460,27 +1460,13 @@ bool ScanMessageStart(Stream& s) bool CheckDiskSpace(int64 nAdditionalBytes) { -#ifdef __WXMSW__ - uint64 nFreeBytesAvailable = 0; // bytes available to caller - uint64 nTotalNumberOfBytes = 0; // bytes on disk - uint64 nTotalNumberOfFreeBytes = 0; // free bytes on disk - if (!GetDiskFreeSpaceEx(GetDataDir().c_str(), - (PULARGE_INTEGER)&nFreeBytesAvailable, - (PULARGE_INTEGER)&nTotalNumberOfBytes, - (PULARGE_INTEGER)&nTotalNumberOfFreeBytes)) - { - printf("ERROR: GetDiskFreeSpaceEx() failed\n"); - return true; - } -#else uint64 nFreeBytesAvailable = filesystem::space(GetDataDir()).available; -#endif // Check for 15MB because database could create another 10MB log file at any time if (nFreeBytesAvailable < (int64)15000000 + nAdditionalBytes) { fShutdown = true; - ThreadSafeMessageBox("Warning: Your disk space is low ", "Bitcoin", wxOK | wxICON_EXCLAMATION); + ThreadSafeMessageBox(_("Warning: Disk space is low "), "Bitcoin", wxOK | wxICON_EXCLAMATION); CreateThread(Shutdown, NULL); return false; } @@ -2962,16 +2948,16 @@ string SendMoney(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew) { string strError; if (nValue + nFeeRequired > GetBalance()) - strError = strprintf("Error: This is an oversized transaction that requires a transaction fee of %s ", FormatMoney(nFeeRequired).c_str()); + strError = strprintf(_("Error: This is an oversized transaction that requires a transaction fee of %s "), FormatMoney(nFeeRequired).c_str()); else - strError = "Error: Transaction creation failed "; + strError = _("Error: Transaction creation failed "); printf("SendMoney() : %s", strError.c_str()); return strError; } if (!CommitTransactionSpent(wtxNew, key)) { printf("SendMoney() : Error finalizing transaction"); - return "Error finalizing transaction"; + return _("Error finalizing transaction"); } // Track how many getdata requests our transaction gets @@ -2985,7 +2971,7 @@ string SendMoney(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew) { // This must not fail. The transaction has already been signed and recorded. printf("SendMoney() : Error: Transaction not valid"); - return "Error: The transaction was rejected. This might happen if some of the coins in your wallet were already spent, such as if you used a copy of wallet.dat and coins were spent in the copy but not marked as spent here."; + return _("Error: The transaction was rejected. This might happen if some of the coins in your wallet were already spent, such as if you used a copy of wallet.dat and coins were spent in the copy but not marked as spent here."); } wtxNew.RelayWalletTransaction(); } @@ -2999,14 +2985,14 @@ string SendMoneyToBitcoinAddress(string strAddress, int64 nValue, CWalletTx& wtx { // Check amount if (nValue <= 0) - return "Invalid amount"; + return _("Invalid amount"); if (nValue + nTransactionFee > GetBalance()) - return "You don't have enough money"; + return _("You don't have enough money"); // Parse bitcoin address CScript scriptPubKey; if (!scriptPubKey.SetBitcoinAddress(strAddress)) - return "Invalid bitcoin address"; + return _("Invalid bitcoin address"); return SendMoney(scriptPubKey, nValue, wtxNew); } diff --git a/makefile b/makefile deleted file mode 100644 index 71f374492a..0000000000 --- a/makefile +++ /dev/null @@ -1,83 +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. - - -ifneq "$(BUILD)" "debug" -ifneq "$(BUILD)" "release" -BUILD=debug -endif -endif -ifeq "$(BUILD)" "debug" -D=d -DEBUGFLAGS=-g -D__WXDEBUG__ -endif - - - -INCLUDEPATHS=-I"/boost" -I"/db/build_unix" -I"/openssl/include" -I"/wxwidgets/lib/gcc_lib/mswd" -I"/wxwidgets/include" -LIBPATHS=-L"/boost/stage/lib" -L"/db/build_unix" -L"/openssl/out" -L"/wxwidgets/lib/gcc_lib" -LIBS= \ - -l libboost_system-mgw34-mt-d -l libboost_filesystem-mgw34-mt-d \ - -l db_cxx \ - -l eay32 \ - -l wxmsw28$(D)_richtext -l wxmsw28$(D)_html -l wxmsw28$(D)_core -l wxmsw28$(D)_adv -l wxbase28$(D) -l wxtiff$(D) -l wxjpeg$(D) -l wxpng$(D) -l wxzlib$(D) -l wxregex$(D) -l wxexpat$(D) \ - -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 -WXDEFS=-DWIN32 -D__WXMSW__ -D_WINDOWS -DNOPCH -CFLAGS=-mthreads -O0 -w -Wno-invalid-offsetof -Wformat $(DEBUGFLAGS) $(WXDEFS) $(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 - - - -all: bitcoin.exe - - -headers.h.gch: headers.h $(HEADERS) - g++ -c $(CFLAGS) -o $@ $< - -obj/util.o: util.cpp $(HEADERS) - g++ -c $(CFLAGS) -o $@ $< - -obj/script.o: script.cpp $(HEADERS) - g++ -c $(CFLAGS) -o $@ $< - -obj/db.o: db.cpp $(HEADERS) - g++ -c $(CFLAGS) -o $@ $< - -obj/net.o: net.cpp $(HEADERS) - g++ -c $(CFLAGS) -o $@ $< - -obj/main.o: main.cpp $(HEADERS) sha.h - g++ -c $(CFLAGS) -o $@ $< - -obj/ui.o: ui.cpp $(HEADERS) - g++ -c $(CFLAGS) -o $@ $< - -obj/uibase.o: uibase.cpp uibase.h - g++ -c $(CFLAGS) -o $@ $< - -obj/sha.o: sha.cpp sha.h - g++ -c $(CFLAGS) -O3 -o $@ $< - -obj/irc.o: irc.cpp $(HEADERS) - g++ -c $(CFLAGS) -o $@ $< - -obj/rpc.o: rpc.cpp $(HEADERS) - g++ -c $(CFLAGS) -o $@ $< - -obj/ui_res.o: ui.rc rc/bitcoin.ico rc/check.ico rc/send16.bmp rc/send16mask.bmp rc/send16masknoshadow.bmp rc/send20.bmp rc/send20mask.bmp rc/addressbook16.bmp rc/addressbook16mask.bmp rc/addressbook20.bmp rc/addressbook20mask.bmp - windres $(WXDEFS) $(INCLUDEPATHS) -o $@ -i $< - - - -OBJS=obj/util.o obj/script.o obj/db.o obj/net.o obj/main.o \ - obj/ui.o obj/uibase.o obj/sha.o obj/irc.o obj/rpc.o \ - obj/ui_res.o - -bitcoin.exe: headers.h.gch $(OBJS) - -kill /f bitcoin.exe - g++ $(CFLAGS) -mwindows -Wl,--subsystem,windows -o $@ $(LIBPATHS) $(OBJS) $(LIBS) - -clean: - -del /Q obj\* - -del /Q headers.h.gch diff --git a/makefile.mingw b/makefile.mingw new file mode 100644 index 0000000000..2644cbaad1 --- /dev/null +++ b/makefile.mingw @@ -0,0 +1,86 @@ +# 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. + + +# for wxWidgets-2.8.x, search and replace "mswud"->"mswd" and "29u"->"28" + +INCLUDEPATHS= \ + -I"/boost" \ + -I"/db/build_unix" \ + -I"/openssl/include" \ + -I"/wxwidgets/lib/gcc_lib/mswud" \ + -I"/wxwidgets/include" + +LIBPATHS= \ + -L"/boost/stage/lib" \ + -L"/db/build_unix" \ + -L"/openssl/out" \ + -L"/wxwidgets/lib/gcc_lib" + +LIBS= \ + -l libboost_system-mgw34-mt-d -l libboost_filesystem-mgw34-mt-d \ + -l db_cxx \ + -l eay32 \ + -l wxmsw29ud_html -l wxmsw29ud_core -l wxmsw29ud_adv -l wxbase29ud -l wxtiffd -l wxjpegd -l wxpngd -l wxzlibd \ + -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 + +WXDEFS=-DWIN32 -D__WXMSW__ -D_WINDOWS -DNOPCH +DEBUGFLAGS=-g -D__WXDEBUG__ +CFLAGS=-mthreads -O0 -w -Wno-invalid-offsetof -Wformat $(DEBUGFLAGS) $(WXDEFS) $(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 + + + +all: bitcoin.exe + + +headers.h.gch: headers.h $(HEADERS) + g++ -c $(CFLAGS) -o $@ $< + +obj/util.o: util.cpp $(HEADERS) + g++ -c $(CFLAGS) -o $@ $< + +obj/script.o: script.cpp $(HEADERS) + g++ -c $(CFLAGS) -o $@ $< + +obj/db.o: db.cpp $(HEADERS) + g++ -c $(CFLAGS) -o $@ $< + +obj/net.o: net.cpp $(HEADERS) + g++ -c $(CFLAGS) -o $@ $< + +obj/main.o: main.cpp $(HEADERS) sha.h + g++ -c $(CFLAGS) -o $@ $< + +obj/ui.o: ui.cpp $(HEADERS) + g++ -c $(CFLAGS) -o $@ $< + +obj/uibase.o: uibase.cpp uibase.h + g++ -c $(CFLAGS) -o $@ $< + +obj/sha.o: sha.cpp sha.h + g++ -c $(CFLAGS) -O3 -o $@ $< + +obj/irc.o: irc.cpp $(HEADERS) + g++ -c $(CFLAGS) -o $@ $< + +obj/rpc.o: rpc.cpp $(HEADERS) + g++ -c $(CFLAGS) -o $@ $< + +obj/ui_res.o: ui.rc rc/bitcoin.ico rc/check.ico rc/send16.bmp rc/send16mask.bmp rc/send16masknoshadow.bmp rc/send20.bmp rc/send20mask.bmp rc/addressbook16.bmp rc/addressbook16mask.bmp rc/addressbook20.bmp rc/addressbook20mask.bmp + windres $(WXDEFS) $(INCLUDEPATHS) -o $@ -i $< + + + +OBJS=obj/util.o obj/script.o obj/db.o obj/net.o obj/main.o \ + obj/ui.o obj/uibase.o obj/sha.o obj/irc.o obj/rpc.o \ + obj/ui_res.o + +bitcoin.exe: headers.h.gch $(OBJS) + -kill /f bitcoin.exe + g++ $(CFLAGS) -mwindows -Wl,--subsystem,windows -o $@ $(LIBPATHS) $(OBJS) $(LIBS) + +clean: + -del /Q obj\* + -del /Q headers.h.gch diff --git a/makefile.unix b/makefile.unix new file mode 100644 index 0000000000..a8ec936776 --- /dev/null +++ b/makefile.unix @@ -0,0 +1,78 @@ +# 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. + + + +INCLUDEPATHS= \ + -I"/usr/include" \ + -I"/usr/local/include/wx-2.9" \ + -I"/usr/local/lib/wx/include/gtk2-unicode-debug-static-2.9" + +LIBPATHS= \ + -L"/usr/lib" \ + -L"/usr/local/lib" + +LIBS= \ + -Wl,-Bstatic \ + -l boost_system-mt -l boost_filesystem-mt \ + -l db_cxx \ + -l wx_gtk2ud-2.9 \ + -Wl,-Bdynamic \ + -l crypto \ + -l gtk-x11-2.0 -l gthread-2.0 -l SM + +WXDEFS=-D__WXGTK__ -DNOPCH +DEBUGFLAGS=-g -D__WXDEBUG__ +CFLAGS=-O0 -Wno-invalid-offsetof -Wformat $(DEBUGFLAGS) $(WXDEFS) $(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 + + + +all: bitcoin + + +headers.h.gch: headers.h $(HEADERS) + g++ -c $(CFLAGS) -o $@ $< + +obj/util.o: util.cpp $(HEADERS) + g++ -c $(CFLAGS) -o $@ $< + +obj/script.o: script.cpp $(HEADERS) + g++ -c $(CFLAGS) -o $@ $< + +obj/db.o: db.cpp $(HEADERS) + g++ -c $(CFLAGS) -o $@ $< + +obj/net.o: net.cpp $(HEADERS) + g++ -c $(CFLAGS) -o $@ $< + +obj/main.o: main.cpp $(HEADERS) sha.h + g++ -c $(CFLAGS) -o $@ $< + +obj/ui.o: ui.cpp $(HEADERS) + g++ -c $(CFLAGS) -o $@ $< + +obj/uibase.o: uibase.cpp uibase.h + g++ -c $(CFLAGS) -o $@ $< + +obj/sha.o: sha.cpp sha.h + g++ -c $(CFLAGS) -O3 -o $@ $< + +obj/irc.o: irc.cpp $(HEADERS) + g++ -c $(CFLAGS) -o $@ $< + +obj/rpc.o: rpc.cpp $(HEADERS) + g++ -c $(CFLAGS) -o $@ $< + + + +OBJS=obj/util.o obj/script.o obj/db.o obj/net.o obj/main.o \ + obj/ui.o obj/uibase.o obj/sha.o obj/irc.o obj/rpc.o + +bitcoin: headers.h.gch $(OBJS) + g++ $(CFLAGS) -o $@ $(LIBPATHS) $(OBJS) $(LIBS) + +clean: + -rm obj/* + -rm headers.h.gch diff --git a/makefile.unix.wx2.8 b/makefile.unix.wx2.8 deleted file mode 100644 index 38d9bc0e90..0000000000 --- a/makefile.unix.wx2.8 +++ /dev/null @@ -1,88 +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. - - -ifneq "$(BUILD)" "debug" -ifneq "$(BUILD)" "release" -BUILD=debug -endif -endif -ifeq "$(BUILD)" "debug" -D=d -DEBUGFLAGS=-g -D__WXDEBUG__ -endif - - - -INCLUDEPATHS= \ - -I"/usr/include" \ - -I"/usr/local/include/wx-2.8" \ - -I"/usr/local/lib/wx/include/gtk2-ansi-debug-static-2.8" - -LIBPATHS= \ - -L"/usr/lib" \ - -L"/usr/local/lib" - -LIBS= \ - -Wl,-Bstatic \ - -l boost_system -l boost_filesystem \ - -l db_cxx \ - -l wx_gtk2$(D)-2.8 \ - -Wl,-Bdynamic \ - -l crypto \ - -l gtk-x11-2.0 -l gthread-2.0 -l SM - -WXDEFS=-D__WXGTK__ -DNOPCH -CFLAGS=-O0 -Wno-invalid-offsetof -Wformat $(DEBUGFLAGS) $(WXDEFS) $(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 - - - -all: bitcoin - - -headers.h.gch: headers.h $(HEADERS) - g++ -c $(CFLAGS) -o $@ $< - -obj/util.o: util.cpp $(HEADERS) - g++ -c $(CFLAGS) -o $@ $< - -obj/script.o: script.cpp $(HEADERS) - g++ -c $(CFLAGS) -o $@ $< - -obj/db.o: db.cpp $(HEADERS) - g++ -c $(CFLAGS) -o $@ $< - -obj/net.o: net.cpp $(HEADERS) - g++ -c $(CFLAGS) -o $@ $< - -obj/main.o: main.cpp $(HEADERS) sha.h - g++ -c $(CFLAGS) -o $@ $< - -obj/ui.o: ui.cpp $(HEADERS) - g++ -c $(CFLAGS) -o $@ $< - -obj/uibase.o: uibase.cpp uibase.h - g++ -c $(CFLAGS) -o $@ $< - -obj/sha.o: sha.cpp sha.h - g++ -c $(CFLAGS) -O3 -o $@ $< - -obj/irc.o: irc.cpp $(HEADERS) - g++ -c $(CFLAGS) -o $@ $< - -obj/rpc.o: rpc.cpp $(HEADERS) - g++ -c $(CFLAGS) -o $@ $< - - - -OBJS=obj/util.o obj/script.o obj/db.o obj/net.o obj/main.o \ - obj/ui.o obj/uibase.o obj/sha.o obj/irc.o obj/rpc.o - -bitcoin: headers.h.gch $(OBJS) - g++ $(CFLAGS) -o $@ $(LIBPATHS) $(OBJS) $(LIBS) - -clean: - -rm obj/* - -rm headers.h.gch diff --git a/makefile.unix.wx2.9 b/makefile.unix.wx2.9 deleted file mode 100644 index 0b3b09b577..0000000000 --- a/makefile.unix.wx2.9 +++ /dev/null @@ -1,88 +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. - - -ifneq "$(BUILD)" "debug" -ifneq "$(BUILD)" "release" -BUILD=debug -endif -endif -ifeq "$(BUILD)" "debug" -D=d -DEBUGFLAGS=-g -D__WXDEBUG__ -endif - - - -INCLUDEPATHS= \ - -I"/usr/include" \ - -I"/usr/local/include/wx-2.9" \ - -I"/usr/local/lib/wx/include/gtk2-unicode-debug-static-2.9" - -LIBPATHS= \ - -L"/usr/lib" \ - -L"/usr/local/lib" - -LIBS= \ - -Wl,-Bstatic \ - -l boost_system-mt -l boost_filesystem-mt \ - -l db_cxx \ - -l wx_gtk2u$(D)-2.9 \ - -Wl,-Bdynamic \ - -l crypto \ - -l gtk-x11-2.0 -l gthread-2.0 -l SM - -WXDEFS=-D__WXGTK__ -DNOPCH -CFLAGS=-O0 -Wno-invalid-offsetof -Wformat $(DEBUGFLAGS) $(WXDEFS) $(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 - - - -all: bitcoin - - -headers.h.gch: headers.h $(HEADERS) - g++ -c $(CFLAGS) -o $@ $< - -obj/util.o: util.cpp $(HEADERS) - g++ -c $(CFLAGS) -o $@ $< - -obj/script.o: script.cpp $(HEADERS) - g++ -c $(CFLAGS) -o $@ $< - -obj/db.o: db.cpp $(HEADERS) - g++ -c $(CFLAGS) -o $@ $< - -obj/net.o: net.cpp $(HEADERS) - g++ -c $(CFLAGS) -o $@ $< - -obj/main.o: main.cpp $(HEADERS) sha.h - g++ -c $(CFLAGS) -o $@ $< - -obj/ui.o: ui.cpp $(HEADERS) - g++ -c $(CFLAGS) -o $@ $< - -obj/uibase.o: uibase.cpp uibase.h - g++ -c $(CFLAGS) -o $@ $< - -obj/sha.o: sha.cpp sha.h - g++ -c $(CFLAGS) -O3 -o $@ $< - -obj/irc.o: irc.cpp $(HEADERS) - g++ -c $(CFLAGS) -o $@ $< - -obj/rpc.o: rpc.cpp $(HEADERS) - g++ -c $(CFLAGS) -o $@ $< - - - -OBJS=obj/util.o obj/script.o obj/db.o obj/net.o obj/main.o \ - obj/ui.o obj/uibase.o obj/sha.o obj/irc.o obj/rpc.o - -bitcoin: headers.h.gch $(OBJS) - g++ $(CFLAGS) -o $@ $(LIBPATHS) $(OBJS) $(LIBS) - -clean: - -rm obj/* - -rm headers.h.gch diff --git a/makefile.vc b/makefile.vc index 5ca8de464c..c407be3d2f 100644 --- a/makefile.vc +++ b/makefile.vc @@ -3,26 +3,31 @@ # file license.txt or http://www.opensource.org/licenses/mit-license.php. -!IF "$(BUILD)" != "debug" && "$(BUILD)" != "release" -BUILD=debug -!ENDIF -!IF "$(BUILD)" == "debug" -D=d -DEBUGFLAGS=/Zi /Od /D__WXDEBUG__ -!ENDIF +# for wxWidgets-2.8.x, search and replace "mswud"->"mswd" and "29u"->"28" +INCLUDEPATHS= \ + /I"/boost" \ + /I"/db/build_windows" \ + /I"/openssl/include" \ + /I"/wxwidgets/lib/vc_lib/mswud" \ + /I"/wxwidgets/include" +LIBPATHS= \ + /LIBPATH:"/boost/stage/lib" \ + /LIBPATH:"/db/build_windows/debug" \ + /LIBPATH:"/openssl/out" \ + /LIBPATH:"/wxwidgets/lib/vc_lib" -INCLUDEPATHS=/I"/boost" /I"/db/build_windows" /I"/openssl/include" /I"/wxwidgets/lib/vc_lib/mswd" /I"/wxwidgets/include" -LIBPATHS=/LIBPATH:"/boost/stage/lib" /LIBPATH:"/db/build_windows/$(BUILD)" /LIBPATH:"/openssl/out" /LIBPATH:"/wxwidgets/lib/vc_lib" LIBS= \ - libboost_system-vc80-mt-gd.lib libboost_filesystem-vc80-mt-gd.lib \ - libdb47s$(D).lib \ - libeay32.lib \ - wxmsw28$(D)_richtext.lib wxmsw28$(D)_html.lib wxmsw28$(D)_core.lib wxmsw28$(D)_adv.lib wxbase28$(D).lib wxtiff$(D).lib wxjpeg$(D).lib wxpng$(D).lib wxzlib$(D).lib wxregex$(D).lib wxexpat$(D).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 + libboost_system-vc80-mt-gd.lib libboost_filesystem-vc80-mt-gd.lib \ + libdb47sd.lib \ + libeay32.lib \ + wxmsw29ud_html.lib wxmsw29ud_core.lib wxmsw29ud_adv.lib wxbase29ud.lib wxtiffd.lib wxjpegd.lib wxpngd.lib wxzlibd.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 + WXDEFS=/DWIN32 /D__WXMSW__ /D_WINDOWS /DNOPCH -CFLAGS=/c /nologo /Ob0 /MD$(D) /EHsc /GR /Zm300 $(DEBUGFLAGS) $(WXDEFS) $(INCLUDEPATHS) +DEBUGFLAGS=/Zi /Od /D__WXDEBUG__ +CFLAGS=/c /nologo /Ob0 /MDd /EHsc /GR /Zm300 $(DEBUGFLAGS) $(WXDEFS) $(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 diff --git a/serialize.h b/serialize.h index 12b58ad1ca..f3b99978df 100644 --- a/serialize.h +++ b/serialize.h @@ -19,8 +19,8 @@ class CScript; class CDataStream; class CAutoFile; -static const int VERSION = 201; -static const char* pszSubVer = ".2"; +static const int VERSION = 202; +static const char* pszSubVer = ".0"; diff --git a/ui.cpp b/ui.cpp index f506fcf3e7..87ba19e082 100644 --- a/ui.cpp +++ b/ui.cpp @@ -229,8 +229,8 @@ CMainFrame::CMainFrame(wxWindow* parent) : CMainFrameBase(parent) m_staticTextBalance->SetSize(140, 17); // & underlines don't work on the toolbar buttons on gtk m_toolBar->ClearTools(); - 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->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(); // resize to fit ubuntu's huge default font dResize = 1.20; @@ -244,13 +244,13 @@ CMainFrame::CMainFrame(wxWindow* parent) : CMainFrameBase(parent) int nDateWidth = DateTimeStr(1229413914).size() * 6 + 8; if (!strstr(DateTimeStr(1229413914).c_str(), "2008")) nDateWidth += 12; - m_listCtrl->InsertColumn(0, "", wxLIST_FORMAT_LEFT, dResize * 0); - m_listCtrl->InsertColumn(1, "", wxLIST_FORMAT_LEFT, dResize * 0); - m_listCtrl->InsertColumn(2, "Status", wxLIST_FORMAT_LEFT, dResize * 110); - m_listCtrl->InsertColumn(3, "Date", wxLIST_FORMAT_LEFT, dResize * nDateWidth); - m_listCtrl->InsertColumn(4, "Description", wxLIST_FORMAT_LEFT, dResize * 409 - nDateWidth); - m_listCtrl->InsertColumn(5, "Debit", wxLIST_FORMAT_RIGHT, dResize * 79); - m_listCtrl->InsertColumn(6, "Credit", wxLIST_FORMAT_RIGHT, dResize * 79); + m_listCtrl->InsertColumn(0, "", wxLIST_FORMAT_LEFT, dResize * 0); + m_listCtrl->InsertColumn(1, "", wxLIST_FORMAT_LEFT, dResize * 0); + m_listCtrl->InsertColumn(2, _("Status"), wxLIST_FORMAT_LEFT, dResize * 110); + m_listCtrl->InsertColumn(3, _("Date"), wxLIST_FORMAT_LEFT, dResize * nDateWidth); + m_listCtrl->InsertColumn(4, _("Description"), wxLIST_FORMAT_LEFT, dResize * 409 - nDateWidth); + m_listCtrl->InsertColumn(5, _("Debit"), wxLIST_FORMAT_RIGHT, dResize * 79); + m_listCtrl->InsertColumn(6, _("Credit"), wxLIST_FORMAT_RIGHT, dResize * 79); // Init status bar int pnWidths[3] = { -100, 88, 290 }; @@ -450,19 +450,19 @@ string FormatTxStatus(const CWalletTx& wtx) if (!wtx.IsFinal()) { if (wtx.nLockTime < 500000000) - return strprintf("Open for %d blocks", nBestHeight - wtx.nLockTime); + return strprintf(_("Open for %d blocks"), nBestHeight - wtx.nLockTime); else - return strprintf("Open until %s", DateTimeStr(wtx.nLockTime).c_str()); + 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); + return strprintf(_("%d/offline?"), nDepth); else if (nDepth < 6) - return strprintf("%d/unconfirmed", nDepth); + return strprintf(_("%d/unconfirmed"), nDepth); else - return strprintf("%d confirmations", nDepth); + return strprintf(_("%d confirmations"), nDepth); } } @@ -547,7 +547,7 @@ bool CMainFrame::InsertTransaction(const CWalletTx& wtx, bool fNew, int nIndex) if (wtx.IsCoinBase()) { // Coinbase - strDescription = "Generated"; + strDescription = _("Generated"); if (nCredit == 0) { int64 nUnmatured = 0; @@ -555,15 +555,15 @@ bool CMainFrame::InsertTransaction(const CWalletTx& wtx, bool fNew, int nIndex) nUnmatured += txout.GetCredit(); if (wtx.IsInMainChain()) { - strDescription = strprintf("Generated (%s matures in %d more blocks)", FormatMoney(nUnmatured).c_str(), wtx.GetBlocksToMaturity()); + 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!"; + strDescription = _("Generated - Warning: This block was not received by any other nodes and will probably not be accepted!"); } else { - strDescription = "Generated (not accepted)"; + strDescription = _("Generated (not accepted)"); } } } @@ -571,7 +571,7 @@ bool CMainFrame::InsertTransaction(const CWalletTx& wtx, bool fNew, int nIndex) { // Online transaction if (!mapValue["from"].empty()) - strDescription += "From: " + mapValue["from"]; + strDescription += _("From: ") + mapValue["from"]; if (!mapValue["message"].empty()) { if (!strDescription.empty()) @@ -594,9 +594,9 @@ bool CMainFrame::InsertTransaction(const CWalletTx& wtx, bool fNew, int nIndex) string strAddress = PubKeyToAddress(vchPubKey); if (mapAddressBook.count(strAddress)) { - //strDescription += "Received payment to "; - //strDescription += "Received with address "; - strDescription += "From: unknown, To: "; + //strDescription += _("Received payment to "); + //strDescription += _("Received with address "); + strDescription += _("From: unknown, To: "); strDescription += strAddress; /// The labeling feature is just too confusing, so I hid it /// by putting it at the end where it runs off the screen. @@ -636,7 +636,7 @@ bool CMainFrame::InsertTransaction(const CWalletTx& wtx, bool fNew, int nIndex) InsertLine(fNew, nIndex, hash, strSort, strStatus, nTime ? DateTimeStr(nTime) : "", - "Payment to yourself", + _("Payment to yourself"), "", ""); /// issue: can't tell which is the payment and which is the change anymore @@ -670,7 +670,7 @@ bool CMainFrame::InsertTransaction(const CWalletTx& wtx, bool fNew, int nIndex) strAddress = Hash160ToAddress(hash160); } - string strDescription = "To: "; + string strDescription = _("To: "); CRITICAL_BLOCK(cs_mapAddressBook) if (mapAddressBook.count(strAddress) && !mapAddressBook[strAddress].empty()) strDescription += mapAddressBook[strAddress] + " "; @@ -960,12 +960,12 @@ void CMainFrame::OnPaintListCtrl(wxPaintEvent& event) // Update status bar string strGen = ""; if (fGenerateBitcoins) - strGen = " Generating"; + strGen = _(" Generating"); if (fGenerateBitcoins && vNodes.empty()) - strGen = "(not connected)"; + strGen = _("(not connected)"); m_statusBar->SetStatusText(strGen, 1); - string strStatus = strprintf(" %d connections %d blocks %d transactions", vNodes.size(), nBestHeight + 1, nTransactionCount); + string strStatus = strprintf(_(" %d connections %d blocks %d transactions"), vNodes.size(), nBestHeight + 1, nTransactionCount); m_statusBar->SetStatusText(strStatus, 2); if (fDebug && GetTime() - nThreadSocketHandlerHeartbeat > 60) @@ -1160,20 +1160,20 @@ CTxDetailsDialog::CTxDetailsDialog(wxWindow* parent, CWalletTx wtx) : CTxDetails - strHTML += "Status: " + FormatTxStatus(wtx); + strHTML += _("Status: ") + FormatTxStatus(wtx); int nRequests = wtx.GetRequestCount(); if (nRequests != -1) { if (nRequests == 0) - strHTML += ", has not been successfully broadcast yet"; + strHTML += _(", has not been successfully broadcast yet"); else if (nRequests == 1) - strHTML += strprintf(", broadcast through %d node", nRequests); + strHTML += strprintf(_(", broadcast through %d node"), nRequests); else - strHTML += strprintf(", broadcast through %d nodes", nRequests); + strHTML += strprintf(_(", broadcast through %d nodes"), nRequests); } strHTML += "
"; - strHTML += "Date: " + (nTime ? DateTimeStr(nTime) : "") + "
"; + strHTML += _("Date: ") + (nTime ? DateTimeStr(nTime) : "") + "
"; // @@ -1181,13 +1181,13 @@ CTxDetailsDialog::CTxDetailsDialog(wxWindow* parent, CWalletTx wtx) : CTxDetails // if (wtx.IsCoinBase()) { - strHTML += "Source: Generated
"; + strHTML += _("Source: Generated
"); } else if (!wtx.mapValue["from"].empty()) { // Online transaction if (!wtx.mapValue["from"].empty()) - strHTML += "From: " + HtmlEscape(wtx.mapValue["from"]) + "
"; + strHTML += _("From: ") + HtmlEscape(wtx.mapValue["from"]) + "
"; } else { @@ -1205,13 +1205,13 @@ CTxDetailsDialog::CTxDetailsDialog(wxWindow* parent, CWalletTx wtx) : CTxDetails string strAddress = PubKeyToAddress(vchPubKey); if (mapAddressBook.count(strAddress)) { - strHTML += "From: unknown
"; - strHTML += "To: "; + strHTML += string() + _("From: ") + _("unknown") + "
"; + strHTML += _("To: "); strHTML += HtmlEscape(strAddress); if (!mapAddressBook[strAddress].empty()) - strHTML += " (yours, label: " + mapAddressBook[strAddress] + ")"; + strHTML += _(" (yours, label: ") + mapAddressBook[strAddress] + ")"; else - strHTML += " (yours)"; + strHTML += _(" (yours)"); strHTML += "
"; } } @@ -1230,7 +1230,7 @@ CTxDetailsDialog::CTxDetailsDialog(wxWindow* parent, CWalletTx wtx) : CTxDetails { // Online transaction strAddress = wtx.mapValue["to"]; - strHTML += "To: "; + strHTML += _("To: "); if (mapAddressBook.count(strAddress) && !mapAddressBook[strAddress].empty()) strHTML += mapAddressBook[strAddress] + " "; strHTML += HtmlEscape(strAddress) + "
"; @@ -1248,17 +1248,19 @@ CTxDetailsDialog::CTxDetailsDialog(wxWindow* parent, CWalletTx wtx) : CTxDetails int64 nUnmatured = 0; foreach(const CTxOut& txout, wtx.vout) nUnmatured += txout.GetCredit(); + strHTML += _("Credit: "); if (wtx.IsInMainChain()) - strHTML += strprintf("Credit: (%s matures in %d more blocks)
", FormatMoney(nUnmatured).c_str(), wtx.GetBlocksToMaturity()); + strHTML += strprintf(_("(%s matures in %d more blocks)"), FormatMoney(nUnmatured).c_str(), wtx.GetBlocksToMaturity()); else - strHTML += "Credit: (not accepted)
"; + strHTML += _("(not accepted)"); + strHTML += "
"; } else if (nNet > 0) { // // Credit // - strHTML += "Credit: " + FormatMoney(nNet) + "
"; + strHTML += _("Credit: ") + FormatMoney(nNet) + "
"; } else { @@ -1287,7 +1289,7 @@ CTxDetailsDialog::CTxDetailsDialog(wxWindow* parent, CWalletTx wtx) : CTxDetails if (ExtractHash160(txout.scriptPubKey, hash160)) { string strAddress = Hash160ToAddress(hash160); - strHTML += "To: "; + strHTML += _("To: "); if (mapAddressBook.count(strAddress) && !mapAddressBook[strAddress].empty()) strHTML += mapAddressBook[strAddress] + " "; strHTML += strAddress; @@ -1295,7 +1297,7 @@ CTxDetailsDialog::CTxDetailsDialog(wxWindow* parent, CWalletTx wtx) : CTxDetails } } - strHTML += "Debit: " + FormatMoney(-txout.nValue) + "
"; + strHTML += _("Debit: ") + FormatMoney(-txout.nValue) + "
"; } if (fAllToMe) @@ -1303,13 +1305,13 @@ CTxDetailsDialog::CTxDetailsDialog(wxWindow* parent, CWalletTx wtx) : CTxDetails // Payment to self /// issue: can't tell which is the payment and which is the change anymore //int64 nValue = wtx.vout[0].nValue; - //strHTML += "Debit: " + FormatMoney(-nValue) + "
"; - //strHTML += "Credit: " + FormatMoney(nValue) + "
"; + //strHTML += _("Debit: ") + FormatMoney(-nValue) + "
"; + //strHTML += _("Credit: ") + FormatMoney(nValue) + "
"; } int64 nTxFee = nDebit - wtx.GetValueOut(); if (nTxFee > 0) - strHTML += "Transaction fee: " + FormatMoney(-nTxFee) + "
"; + strHTML += _("Transaction fee: ") + FormatMoney(-nTxFee) + "
"; } else { @@ -1318,24 +1320,24 @@ CTxDetailsDialog::CTxDetailsDialog(wxWindow* parent, CWalletTx wtx) : CTxDetails // foreach(const CTxIn& txin, wtx.vin) if (txin.IsMine()) - strHTML += "Debit: " + FormatMoney(-txin.GetDebit()) + "
"; + strHTML += _("Debit: ") + FormatMoney(-txin.GetDebit()) + "
"; foreach(const CTxOut& txout, wtx.vout) if (txout.IsMine()) - strHTML += "Credit: " + FormatMoney(txout.GetCredit()) + "
"; + strHTML += _("Credit: ") + FormatMoney(txout.GetCredit()) + "
"; } } - strHTML += "Net amount: " + FormatMoney(nNet, true) + "
"; + strHTML += _("Net amount: ") + FormatMoney(nNet, true) + "
"; // // Message // if (!wtx.mapValue["message"].empty()) - strHTML += "
Message:
" + HtmlEscape(wtx.mapValue["message"], true) + "
"; + strHTML += string() + "
" + _("Message:") + "
" + HtmlEscape(wtx.mapValue["message"], true) + "
"; if (wtx.IsCoinBase()) - strHTML += "
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.
"; + strHTML += string() + "
" + _("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.") + "
"; // @@ -1402,12 +1404,12 @@ void CTxDetailsDialog::OnButtonOK(wxCommandEvent& event) COptionsDialog::COptionsDialog(wxWindow* parent) : COptionsDialogBase(parent) { // Set up list box of page choices - m_listBox->Append("Main"); - //m_listBox->Append("Test 2"); + m_listBox->Append(_("Main")); + //m_listBox->Append(_("Test 2")); m_listBox->SetSelection(0); SelectPage(0); #ifndef __WXMSW__ - m_checkBoxMinimizeOnClose->SetLabel("&Minimize on close"); + m_checkBoxMinimizeOnClose->SetLabel(_("&Minimize on close")); m_checkBoxStartOnSystemStartup->Enable(false); // not implemented yet #endif @@ -1559,16 +1561,16 @@ void COptionsDialog::OnButtonApply(wxCommandEvent& event) CAboutDialog::CAboutDialog(wxWindow* parent) : CAboutDialogBase(parent) { - m_staticTextVersion->SetLabel(strprintf("version 0.%d.%d beta", VERSION/100, VERSION%100)); + m_staticTextVersion->SetLabel(strprintf(_("version 0.%d.%d beta"), VERSION/100, VERSION%100)); -#if !wxUSE_UNICODE - // Workaround until upgrade to wxWidgets supporting UTF-8 - // Hack to change the (c) character from UTF-8 back to ANSI + // Change (c) into UTF-8 or ANSI copyright symbol wxString str = m_staticTextMain->GetLabel(); - if (str.Find('\xC2') != wxNOT_FOUND) - str.Remove(str.Find('\xC2'), 1); - m_staticTextMain->SetLabel(str); +#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 @@ -1577,7 +1579,7 @@ CAboutDialog::CAboutDialog(wxWindow* parent) : CAboutDialogBase(parent) if (fontTmp.GetPointSize() > 8); fontTmp.SetPointSize(8); m_staticTextMain->SetFont(fontTmp); - SetSize(GetSize().GetWidth() + 44, GetSize().GetHeight() - 4); + SetSize(GetSize().GetWidth() + 44, GetSize().GetHeight() + 10); #endif } @@ -1644,8 +1646,8 @@ void CSendDialog::OnTextAddress(wxCommandEvent& event) { strFromSave = m_textCtrlFrom->GetValue(); strMessageSave = m_textCtrlMessage->GetValue(); - m_textCtrlFrom->SetValue("Will appear as \"From: Unknown\""); - m_textCtrlMessage->SetValue("Can't include a message when sending to a Bitcoin address"); + m_textCtrlFrom->SetValue(_("Will appear as \"From: Unknown\"")); + m_textCtrlMessage->SetValue(_("Can't include a message when sending to a Bitcoin address")); } else if (fEnable && !fEnabledPrev) { @@ -1697,17 +1699,17 @@ void CSendDialog::OnButtonSend(wxCommandEvent& event) int64 nValue = 0; if (!ParseMoney(m_textCtrlAmount->GetValue(), nValue) || nValue <= 0) { - wxMessageBox("Error in amount ", "Send Coins"); + wxMessageBox(_("Error in amount "), _("Send Coins")); return; } if (nValue > GetBalance()) { - wxMessageBox("Amount exceeds your balance ", "Send Coins"); + wxMessageBox(_("Amount exceeds your balance "), _("Send Coins")); return; } if (nValue + nTransactionFee > GetBalance()) { - wxMessageBox(string("Total exceeds your balance when the ") + FormatMoney(nTransactionFee) + " transaction fee is included ", "Send Coins"); + wxMessageBox(string(_("Total exceeds your balance when the ")) + FormatMoney(nTransactionFee) + _(" transaction fee is included "), _("Send Coins")); return; } @@ -1723,9 +1725,9 @@ void CSendDialog::OnButtonSend(wxCommandEvent& event) string strError = SendMoney(scriptPubKey, nValue, wtx); if (strError != "") - wxMessageBox(strError + " ", "Sending..."); + wxMessageBox(strError + " ", _("Sending...")); else - wxMessageBox("Payment sent ", "Sending..."); + wxMessageBox(_("Payment sent "), _("Sending...")); } else { @@ -1733,7 +1735,7 @@ void CSendDialog::OnButtonSend(wxCommandEvent& event) CAddress addr(strAddress); if (!addr.IsValid()) { - wxMessageBox("Invalid address ", "Send Coins"); + wxMessageBox(_("Invalid address "), _("Send Coins")); return; } @@ -1787,7 +1789,7 @@ CSendingDialog::CSendingDialog(wxWindow* parent, const CAddress& addrIn, int64 n SetSize(1.2 * GetSize().GetWidth(), 1.08 * GetSize().GetHeight()); #endif - SetTitle(strprintf("Sending %s to %s", FormatMoney(nPrice).c_str(), wtx.mapValue["to"].c_str())); + SetTitle(strprintf(_("Sending %s to %s"), FormatMoney(nPrice).c_str(), wtx.mapValue["to"].c_str())); m_textCtrlStatus->SetValue(""); CreateThread(SendingDialogStartTransfer, this); @@ -1859,13 +1861,13 @@ void CSendingDialog::OnPaint(wxPaintEvent& event) } if (fAbort && fCanCancel && IsShown()) { - strcpy(pszStatus, "CANCELLED"); + strcpy(pszStatus, _("CANCELLED")); m_buttonOK->Enable(true); m_buttonOK->SetFocus(); m_buttonCancel->Enable(false); - m_buttonCancel->SetLabel("Cancelled"); + m_buttonCancel->SetLabel(_("Cancelled")); Close(); - wxMessageBox("Transfer cancelled ", "Sending...", wxOK, this); + wxMessageBox(_("Transfer cancelled "), _("Sending..."), wxOK, this); } event.Skip(); } @@ -1893,7 +1895,7 @@ bool CSendingDialog::Status() if (fAbort && fCanCancel) { memset(pszStatus, 0, 10); - strcpy(pszStatus, "CANCELLED"); + strcpy(pszStatus, _("CANCELLED")); Repaint(); fWorkDone = true; return false; @@ -1919,7 +1921,7 @@ bool CSendingDialog::Error(const string& str) { fCanCancel = false; fWorkDone = true; - Status(string("Error: ") + str); + Status(string(_("Error: ")) + str); return false; } @@ -1933,22 +1935,22 @@ void CSendingDialog::StartTransfer() // Make sure we have enough money if (nPrice + nTransactionFee > GetBalance()) { - Error("You don't have enough money"); + Error(_("You don't have enough money")); return; } // We may have connected already for product details - if (!Status("Connecting...")) + if (!Status(_("Connecting..."))) return; CNode* pnode = ConnectNode(addr, 15 * 60); if (!pnode) { - Error("Unable to connect"); + Error(_("Unable to connect")); return; } // Send order to seller, with response going to OnReply2 via event handler - if (!Status("Requesting public key...")) + if (!Status(_("Requesting public key..."))) return; pnode->PushRequest("checkorder", wtx, SendingDialogOnReply2, this); } @@ -1960,7 +1962,7 @@ void SendingDialogOnReply2(void* parg, CDataStream& vRecv) void CSendingDialog::OnReply2(CDataStream& vRecv) { - if (!Status("Received public key...")) + if (!Status(_("Received public key..."))) return; CScript scriptPubKey; @@ -1972,7 +1974,7 @@ void CSendingDialog::OnReply2(CDataStream& vRecv) { string strMessage; vRecv >> strMessage; - Error("Transfer was not accepted"); + Error(_("Transfer was not accepted")); //// todo: enlarge the window and enable a hidden white box to put seller's message return; } @@ -1981,7 +1983,7 @@ void CSendingDialog::OnReply2(CDataStream& vRecv) catch (...) { //// what do we want to do about this? - Error("Invalid response received"); + Error(_("Invalid response received")); return; } @@ -1996,11 +1998,11 @@ void CSendingDialog::OnReply2(CDataStream& vRecv) CRITICAL_BLOCK(cs_main) { // Pay - if (!Status("Creating transaction...")) + if (!Status(_("Creating transaction..."))) return; if (nPrice + nTransactionFee > GetBalance()) { - Error("You don't have enough money"); + Error(_("You don't have enough money")); return; } CKey key; @@ -2008,9 +2010,9 @@ void CSendingDialog::OnReply2(CDataStream& vRecv) if (!CreateTransaction(scriptPubKey, nPrice, wtx, key, nFeeRequired)) { if (nPrice + nFeeRequired > GetBalance()) - Error(strprintf("This is an oversized transaction that requires a transaction fee of %s", FormatMoney(nFeeRequired).c_str())); + Error(strprintf(_("This is an oversized transaction that requires a transaction fee of %s"), FormatMoney(nFeeRequired).c_str())); else - Error("Transaction creation failed"); + Error(_("Transaction creation failed")); return; } @@ -2018,7 +2020,7 @@ void CSendingDialog::OnReply2(CDataStream& vRecv) CNode* pnode = ConnectNode(addr, 2 * 60 * 60); if (!pnode) { - Error("Lost connection, transaction cancelled"); + Error(_("Lost connection, transaction cancelled")); return; } @@ -2034,13 +2036,13 @@ void CSendingDialog::OnReply2(CDataStream& vRecv) return; fCanCancel = false; } - if (!Status("Sending payment...")) + if (!Status(_("Sending payment..."))) return; // Commit if (!CommitTransactionSpent(wtx, key)) { - Error("Error finalizing payment"); + Error(_("Error finalizing payment")); return; } @@ -2052,7 +2054,7 @@ void CSendingDialog::OnReply2(CDataStream& vRecv) printf("ERROR: CSendingDialog : wtxNew.AcceptTransaction() %s failed\n", wtx.GetHash().ToString().c_str()); wtx.RelayWalletTransaction(); - Status("Waiting for confirmation..."); + Status(_("Waiting for confirmation...")); MainFrameRepaint(); } } @@ -2070,22 +2072,22 @@ void CSendingDialog::OnReply3(CDataStream& vRecv) 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."); + 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"); + Error(_("Payment was sent, but an invalid response was received")); return; } fSuccess = true; fWorkDone = true; - Status("Payment completed"); + Status(_("Payment completed")); } @@ -2101,8 +2103,8 @@ void CSendingDialog::OnReply3(CDataStream& vRecv) CYourAddressDialog::CYourAddressDialog(wxWindow* parent, const string& strInitSelected) : CYourAddressDialogBase(parent) { // Init column headers - m_listCtrl->InsertColumn(0, "Label", wxLIST_FORMAT_LEFT, 200); - m_listCtrl->InsertColumn(1, "Bitcoin Address", wxLIST_FORMAT_LEFT, 350); + m_listCtrl->InsertColumn(0, _("Label"), wxLIST_FORMAT_LEFT, 200); + m_listCtrl->InsertColumn(1, _("Bitcoin Address"), wxLIST_FORMAT_LEFT, 350); m_listCtrl->SetFocus(); // Fill listctrl with address book data @@ -2162,7 +2164,7 @@ void CYourAddressDialog::OnButtonRename(wxCommandEvent& event) return; string strName = (string)m_listCtrl->GetItemText(nIndex); string strAddress = (string)GetItemText(m_listCtrl, nIndex, 1); - CGetTextFromUserDialog dialog(this, "Edit Address Label", "New Label", strName); + CGetTextFromUserDialog dialog(this, _("Edit Address Label"), _("New Label"), strName); if (!dialog.ShowModal()) return; strName = dialog.GetValue(); @@ -2176,7 +2178,7 @@ void CYourAddressDialog::OnButtonRename(wxCommandEvent& event) void CYourAddressDialog::OnButtonNew(wxCommandEvent& event) { // Ask name - CGetTextFromUserDialog dialog(this, "New Bitcoin Address", "Label", ""); + CGetTextFromUserDialog dialog(this, _("New Bitcoin Address"), _("Label"), ""); if (!dialog.ShowModal()) return; string strName = dialog.GetValue(); @@ -2236,8 +2238,8 @@ CAddressBookDialog::CAddressBookDialog(wxWindow* parent, const wxString& strInit m_buttonCancel->Show(false); // Init column headers - m_listCtrl->InsertColumn(0, "Name", wxLIST_FORMAT_LEFT, 200); - m_listCtrl->InsertColumn(1, "Address", wxLIST_FORMAT_LEFT, 350); + m_listCtrl->InsertColumn(0, _("Name"), wxLIST_FORMAT_LEFT, 200); + m_listCtrl->InsertColumn(1, _("Address"), wxLIST_FORMAT_LEFT, 350); m_listCtrl->SetFocus(); // Set Icon @@ -2307,7 +2309,7 @@ bool CAddressBookDialog::CheckIfMine(const string& strAddress, const string& str 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); + wxMessageBox(_("This is one of your own addresses for receiving payments and cannot be entered in the address book. "), strTitle); return fMine; } @@ -2322,13 +2324,13 @@ void CAddressBookDialog::OnButtonEdit(wxCommandEvent& event) string strAddressOrg = strAddress; do { - CGetTextFromUserDialog dialog(this, "Edit Address", "Name", strName, "Address", strAddress); + CGetTextFromUserDialog dialog(this, _("Edit Address"), _("Name"), strName, _("Address"), strAddress); if (!dialog.ShowModal()) return; strName = dialog.GetValue1(); strAddress = dialog.GetValue2(); } - while (CheckIfMine(strAddress, "Edit Address")); + while (CheckIfMine(strAddress, _("Edit Address"))); // Change name if (strAddress != strAddressOrg) @@ -2346,13 +2348,13 @@ void CAddressBookDialog::OnButtonNew(wxCommandEvent& event) string strAddress; do { - CGetTextFromUserDialog dialog(this, "New Address", "Name", strName, "Address", strAddress); + CGetTextFromUserDialog dialog(this, _("New Address"), _("Name"), strName, _("Address"), strAddress); if (!dialog.ShowModal()) return; strName = dialog.GetValue1(); strAddress = dialog.GetValue2(); } - while (CheckIfMine(strAddress, "New Address")); + while (CheckIfMine(strAddress, _("New Address"))); // Add to list and select it SetAddressBookName(strAddress, strName); @@ -2436,11 +2438,11 @@ void CMyTaskBarIcon::Show(bool fShow) static char pszPrevTip[200]; if (fShow) { - string strTooltip = "Bitcoin"; + string strTooltip = _("Bitcoin"); if (fGenerateBitcoins) - strTooltip = "Bitcoin - Generating"; + strTooltip = _("Bitcoin - Generating"); if (fGenerateBitcoins && vNodes.empty()) - strTooltip = "Bitcoin - (not connected)"; + 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) @@ -2515,12 +2517,12 @@ void CMyTaskBarIcon::UpdateTooltip() wxMenu* CMyTaskBarIcon::CreatePopupMenu() { wxMenu* pmenu = new wxMenu; - pmenu->Append(ID_TASKBAR_RESTORE, "&Open Bitcoin"); - pmenu->Append(ID_TASKBAR_OPTIONS, "O&ptions..."); - pmenu->AppendCheckItem(ID_TASKBAR_GENERATE, "&Generate Coins")->Check(fGenerateBitcoins); + pmenu->Append(ID_TASKBAR_RESTORE, _("&Open Bitcoin")); + pmenu->Append(ID_TASKBAR_OPTIONS, _("O&ptions...")); + pmenu->AppendCheckItem(ID_TASKBAR_GENERATE, _("&Generate Coins"))->Check(fGenerateBitcoins); #ifndef __WXMAC_OSX__ // Mac has built-in quit menu pmenu->AppendSeparator(); - pmenu->Append(ID_TASKBAR_EXIT, "E&xit"); + pmenu->Append(ID_TASKBAR_EXIT, _("E&xit")); #endif return pmenu; } @@ -2542,7 +2544,9 @@ wxMenu* CMyTaskBarIcon::CreatePopupMenu() // Define a new application class CMyApp: public wxApp { - public: +public: + wxLocale m_locale; + CMyApp(){}; ~CMyApp(){}; bool OnInit(); @@ -2584,9 +2588,9 @@ bool CMyApp::OnInit() bool CMyApp::OnInit2() { #ifdef _MSC_VER - // Turn off microsoft heap dump noise for now + // Turn off microsoft heap dump noise _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE); - _CrtSetReportFile(_CRT_WARN, CreateFile("NUL", GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0)); + _CrtSetReportFile(_CRT_WARN, CreateFileA("NUL", GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0)); #endif #if defined(__WXMSW__) && defined(__WXDEBUG__) // Disable malfunctioning wxWidgets debug assertion @@ -2599,6 +2603,31 @@ bool CMyApp::OnInit2() SetAppName("bitcoin"); umask(077); #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//LC_MESSAGES/bitcoin.mo language file + m_locale.Init(wxLANGUAGE_DEFAULT, 0); + m_locale.AddCatalogLookupPathPrefix("locale"); + if (!fWindows) + { + m_locale.AddCatalogLookupPathPrefix("/usr/share/locale"); + m_locale.AddCatalogLookupPathPrefix("/usr/local/share/locale"); + } + m_locale.AddCatalog("wxstd"); // wxWidgets standard translations, if any + m_locale.AddCatalog("bitcoin"); // // Parameters @@ -2612,33 +2641,31 @@ bool CMyApp::OnInit2() ParseParameters(argc, argv); if (mapArgs.count("-?") || mapArgs.count("--help")) { -#ifdef __WXMSW__ - string strUsage = - "Usage: bitcoin [options]\t\t\t\t\t\t\n" - "Options:\n" - " -gen\t\t Generate coins\n" - " -gen=0\t\t Don't generate coins\n" - " -min\t\t Start minimized\n" - " -datadir=\t Specify data directory\n" - " -proxy=\t Connect through socks4 proxy\n" - " -addnode=\t Add a node to connect to\n" - " -connect=\t Connect only to the specified node\n" - " -?\t\t This help message\n"; - wxMessageBox(strUsage, "Bitcoin", wxOK); -#else - string strUsage = - "Usage: bitcoin [options]\n" - "Options:\n" - " -gen Generate coins\n" - " -gen=0 Don't generate coins\n" - " -min Start minimized\n" - " -datadir= Specify data directory\n" - " -proxy= Connect through socks4 proxy\n" - " -addnode= Add a node to connect to\n" - " -connect= Connect only to the specified node\n" - " -? This help message\n"; - fprintf(stderr, "%s", strUsage.c_str()); -#endif + wxString strUsage = string() + + _("Usage: bitcoin [options]") + "\t\t\t\t\t\t\n" + + _("Options:\n") + + " -gen \t\t " + _("Generate coins\n") + + " -gen=0 \t\t " + _("Don't generate coins\n") + + " -min \t\t " + _("Start minimized\n") + + " -datadir= \t " + _("Specify data directory\n") + + " -proxy=\t " + _("Connect through socks4 proxy\n") + + " -addnode= \t " + _("Add a node to connect to\n") + + " -connect= \t " + _("Connect only to the specified node\n") + + " -? \t\t " + _("This help message\n"); + + if (fWindows) + { + // Remove spaces, the tabs make the columns line up in the message box + for (int i = 0; i < 50; i++) + strUsage.Replace(" \t", "\t"); + wxMessageBox(strUsage, "Bitcoin", wxOK); + } + else + { + // Remove tabs + strUsage.Replace("\t", ""); + fprintf(stderr, "%s", ((string)strUsage).c_str()); + } return false; } @@ -2661,7 +2688,9 @@ bool CMyApp::OnInit2() if (!fDebug && !pszSetDataDir[0]) 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 %d%s, OS version %s\n", VERSION, pszSubVer, ((string)wxGetOsDescription()).c_str()); + printf("Bitcoin version 0.%d.%d%s beta, OS version %s\n", VERSION/100, VERSION%100, pszSubVer, ((string)wxGetOsDescription()).c_str()); + printf("System default language is %d %s\n", m_locale.GetSystemLanguage(), ((string)m_locale.GetSysName()).c_str()); + printf("Language file %s (%s)\n", (string("locale/") + (string)m_locale.GetCanonicalName() + "/LC_MESSAGES/bitcoin.mo").c_str(), ((string)m_locale.GetLocale()).c_str()); if (mapArgs.count("-loadblockindextest")) { @@ -2691,7 +2720,7 @@ bool CMyApp::OnInit2() { // TODO: find out how to do this in Linux, or replace with wxWidgets commands // Show the previous instance and exit - HWND hwndPrev = FindWindow("wxWindowClassNR", "Bitcoin"); + HWND hwndPrev = FindWindowA("wxWindowClassNR", "Bitcoin"); if (hwndPrev) { if (IsIconic(hwndPrev)) @@ -2732,19 +2761,19 @@ bool CMyApp::OnInit2() printf("Loading addresses...\n"); nStart = GetTimeMillis(); if (!LoadAddresses()) - strErrors += "Error loading addr.dat \n"; + strErrors += _("Error loading addr.dat \n"); printf(" addresses %15"PRI64d"ms\n", GetTimeMillis() - nStart); printf("Loading block index...\n"); nStart = GetTimeMillis(); if (!LoadBlockIndex()) - strErrors += "Error loading blkindex.dat \n"; + strErrors += _("Error loading blkindex.dat \n"); printf(" block index %15"PRI64d"ms\n", GetTimeMillis() - nStart); printf("Loading wallet...\n"); nStart = GetTimeMillis(); if (!LoadWallet(fFirstRun)) - strErrors += "Error loading wallet.dat \n"; + strErrors += _("Error loading wallet.dat \n"); printf(" wallet %15"PRI64d"ms\n", GetTimeMillis() - nStart); printf("Done loading\n"); @@ -2812,7 +2841,7 @@ bool CMyApp::OnInit2() addrProxy = CAddress(mapArgs["-proxy"]); if (!addrProxy.IsValid()) { - wxMessageBox("Invalid -proxy address", "Bitcoin"); + wxMessageBox(_("Invalid -proxy address"), "Bitcoin"); return false; } } @@ -2947,7 +2976,7 @@ void CMyApp::OnUnhandledException() void CMyApp::OnFatalException() { - wxMessageBox("Program has crashed and will terminate. ", "Bitcoin", wxOK | wxICON_ERROR); + wxMessageBox(_("Program has crashed and will terminate. "), "Bitcoin", wxOK | wxICON_ERROR); } @@ -2962,7 +2991,7 @@ string MyGetSpecialFolderPath(int nFolder, bool fCreate) char pszPath[MAX_PATH+100] = ""; // SHGetSpecialFolderPath is not usually available on NT 4.0 - HMODULE hShell32 = LoadLibrary("shell32.dll"); + HMODULE hShell32 = LoadLibraryA("shell32.dll"); if (hShell32) { PSHGETSPECIALFOLDERPATHA pSHGetSpecialFolderPath = @@ -3017,7 +3046,7 @@ void SetStartOnSystemStartup(bool fAutoStart) if (SUCCEEDED(hres)) { // Get the current executable path - char pszExePath[MAX_PATH]; + TCHAR pszExePath[MAX_PATH]; GetModuleFileName(NULL, pszExePath, sizeof(pszExePath)); // Set the path to the shortcut target diff --git a/ui.h b/ui.h index da1ada7def..50d39ab7fc 100644 --- a/ui.h +++ b/ui.h @@ -16,12 +16,12 @@ extern int fMinimizeOnClose; -extern void HandleCtrlA(wxKeyEvent& event); -extern string FormatTxStatus(const CWalletTx& wtx); -extern void UIThreadCall(boost::function0); -extern void MainFrameRepaint(); -extern void Shutdown(void* parg); -extern int ThreadSafeMessageBox(const string& message, const string& caption="Message", int style=wxOK, wxWindow* parent=NULL, int x=-1, int y=-1); +void HandleCtrlA(wxKeyEvent& event); +string FormatTxStatus(const CWalletTx& wtx); +void UIThreadCall(boost::function0); +void MainFrameRepaint(); +void Shutdown(void* parg); +int ThreadSafeMessageBox(const string& message, const string& caption="Message", int style=wxOK, wxWindow* parent=NULL, int x=-1, int y=-1); diff --git a/uibase.cpp b/uibase.cpp index 03bd791226..5b3f9abc22 100644 --- a/uibase.cpp +++ b/uibase.cpp @@ -1,6 +1,3 @@ -// 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. /////////////////////////////////////////////////////////////////////////// // C++ code generated with wxFormBuilder (version Apr 16 2008) // http://www.wxformbuilder.org/ @@ -406,22 +403,14 @@ COptionsDialogBase::COptionsDialogBase( wxWindow* parent, wxWindowID id, const w bSizer64->Add( 0, 16, 0, wxEXPAND, 5 ); - m_staticText321 = new wxStaticText( m_panelTest2, wxID_ANY, _("Test panel 2 for future expansion"), wxDefaultPosition, wxDefaultSize, 0 ); + 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, _("Let's not start multiple pages until the first page is filled up"), wxDefaultPosition, wxDefaultSize, 0 ); + 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_staticText70 = new wxStaticText( m_panelTest2, wxID_ANY, _("MyLabel"), wxDefaultPosition, wxDefaultSize, 0 ); - m_staticText70->Wrap( -1 ); - bSizer64->Add( m_staticText70, 0, wxALL, 5 ); - - m_staticText71 = new wxStaticText( m_panelTest2, wxID_ANY, _("MyLabel"), wxDefaultPosition, wxDefaultSize, 0 ); - m_staticText71->Wrap( -1 ); - bSizer64->Add( m_staticText71, 0, wxALL, 5 ); - m_panelTest2->SetSizer( bSizer64 ); m_panelTest2->Layout(); bSizer64->Fit( m_panelTest2 ); @@ -521,7 +510,7 @@ CAboutDialogBase::CAboutDialogBase( wxWindow* parent, wxWindowID id, const wxStr bSizer631->Add( 0, 4, 0, wxEXPAND, 5 ); - m_staticTextMain = new wxStaticText( this, wxID_ANY, _("Copyright © 2009-2010 Satoshi Nakamoto.\n\nThis is experimental software. Do not rely on it for actual financial transactions.\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)."), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticTextMain = new wxStaticText( this, wxID_ANY, _("Copyright (c) 2009-2010 Satoshi Nakamoto.\n\nThis is experimental software. Do not rely on it for actual financial transactions.\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)."), wxDefaultPosition, wxDefaultSize, 0 ); m_staticTextMain->Wrap( -1 ); bSizer631->Add( m_staticTextMain, 0, wxALL, 5 ); diff --git a/uibase.h b/uibase.h index 2dfc2af14d..494ed10f7c 100644 --- a/uibase.h +++ b/uibase.h @@ -1,6 +1,3 @@ -// 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. /////////////////////////////////////////////////////////////////////////// // C++ code generated with wxFormBuilder (version Apr 16 2008) // http://www.wxformbuilder.org/ @@ -178,8 +175,6 @@ class COptionsDialogBase : public wxDialog wxStaticText* m_staticText321; wxStaticText* m_staticText69; - wxStaticText* m_staticText70; - wxStaticText* m_staticText71; wxButton* m_buttonOK; wxButton* m_buttonCancel; wxButton* m_buttonApply; diff --git a/uiproject.fbp b/uiproject.fbp index 5c6eaa55a5..988df2a9b9 100644 --- a/uiproject.fbp +++ b/uiproject.fbp @@ -2173,7 +2173,7 @@ 0 wxID_ANY - Test panel 2 for future expansion + // [don't translate] Test panel 2 for future expansion m_staticText321 @@ -2224,7 +2224,7 @@ 0 wxID_ANY - Let's not start multiple pages until the first page is filled up + // [don't translate] Let's not start multiple pages until the first page is filled up m_staticText69 @@ -2263,108 +2263,6 @@
- - 5 - wxALL - 0 - - - - 1 - - - 0 - wxID_ANY - MyLabel - - - m_staticText70 - protected - - - - - - - - - -1 - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALL - 0 - - - - 1 - - - 0 - wxID_ANY - MyLabel - - - m_staticText71 - protected - - - - - - - - - -1 - - - - - - - - - - - - - - - - - - - - - - - - -
@@ -2820,7 +2718,7 @@ 0 wxID_ANY - Copyright © 2009-2010 Satoshi Nakamoto. This is experimental software. Do not rely on it for actual financial transactions. 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). + Copyright (c) 2009-2010 Satoshi Nakamoto. This is experimental software. Do not rely on it for actual financial transactions. 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). m_staticTextMain diff --git a/util.cpp b/util.cpp index 2f5be2227f..266c1dd7df 100644 --- a/util.cpp +++ b/util.cpp @@ -90,7 +90,7 @@ void RandAddSeedPerfmon() unsigned char pdata[250000]; memset(pdata, 0, sizeof(pdata)); unsigned long nSize = sizeof(pdata); - long ret = RegQueryValueEx(HKEY_PERFORMANCE_DATA, "Global", NULL, NULL, pdata, &nSize); + long ret = RegQueryValueExA(HKEY_PERFORMANCE_DATA, "Global", NULL, NULL, pdata, &nSize); RegCloseKey(HKEY_PERFORMANCE_DATA); if (ret == ERROR_SUCCESS) { @@ -193,7 +193,7 @@ inline int OutputDebugStringF(const char* pszFormat, ...) p2++; char c = *p2; *p2 = '\0'; - OutputDebugString(p1); + OutputDebugStringA(p1); *p2 = c; p1 = p2; } @@ -441,7 +441,7 @@ void FormatException(char* pszMessage, std::exception* pex, const char* pszThrea #ifdef __WXMSW__ char pszModule[MAX_PATH]; pszModule[0] = '\0'; - GetModuleFileName(NULL, pszModule, sizeof(pszModule)); + GetModuleFileNameA(NULL, pszModule, sizeof(pszModule)); #else // might not be thread safe, uses wxString //const char* pszModule = wxStandardPaths::Get().GetExecutablePath().mb_str(); diff --git a/util.h b/util.h index 933c71be0b..188a9ece14 100644 --- a/util.h +++ b/util.h @@ -340,10 +340,11 @@ void skipspaces(T& it) ++it; } - - - - +inline const char* wxGetTranslation(const char* psz) +{ + // Return translated UTF-8 const char* + return wxGetTranslation(wxString(psz, wxConvUTF8)).utf8_str(); +} -- cgit v1.2.3 From 794298063de40a6837736f9d928d28c2d6712a73 Mon Sep 17 00:00:00 2001 From: s_nakamoto Date: Wed, 17 Feb 2010 23:55:43 +0000 Subject: safer wxGetTranslation wrapper --- serialize.h | 2 +- util.cpp | 29 +++++++++++++++++++++++++++++ util.h | 9 ++++----- 3 files changed, 34 insertions(+), 6 deletions(-) diff --git a/serialize.h b/serialize.h index f3b99978df..aaf3f99051 100644 --- a/serialize.h +++ b/serialize.h @@ -19,7 +19,7 @@ class CScript; class CDataStream; class CAutoFile; -static const int VERSION = 202; +static const int VERSION = 203; static const char* pszSubVer = ".0"; diff --git a/util.cpp b/util.cpp index 266c1dd7df..f4ce556643 100644 --- a/util.cpp +++ b/util.cpp @@ -431,6 +431,35 @@ void ParseParameters(int argc, char* argv[]) } +const char* wxGetTranslation(const char* pszEnglish) +{ + // Wrapper of wxGetTranslation returning the same const char* type as was passed in + static CCriticalSection cs; + CRITICAL_BLOCK(cs) + { + // Look in cache + static map mapCache; + map::iterator mi = mapCache.find(pszEnglish); + if (mi != mapCache.end()) + return (*mi).second; + + // wxWidgets translation + const char* pszTranslated = wxGetTranslation(wxString(pszEnglish, wxConvUTF8)).utf8_str(); + if (strcmp(pszEnglish, pszTranslated) == 0) + return pszEnglish; + + // Add to cache, memory doesn't need to be freed + char* pszCached = new char[strlen(pszTranslated)+1]; + strcpy(pszCached, pszTranslated); + mapCache[pszEnglish] = pszCached; + return pszCached; + } +} + + + + + diff --git a/util.h b/util.h index 188a9ece14..8aed902f3f 100644 --- a/util.h +++ b/util.h @@ -136,6 +136,7 @@ bool ParseMoney(const char* pszIn, int64& nRet); vector ParseHex(const char* psz); vector ParseHex(const std::string& str); void ParseParameters(int argc, char* argv[]); +const char* wxGetTranslation(const char* psz); int GetFilesize(FILE* file); void GetDataDir(char* pszDirRet); string GetDataDir(); @@ -340,11 +341,9 @@ void skipspaces(T& it) ++it; } -inline const char* wxGetTranslation(const char* psz) -{ - // Return translated UTF-8 const char* - return wxGetTranslation(wxString(psz, wxConvUTF8)).utf8_str(); -} + + + -- cgit v1.2.3 From c6ab3cf6d9cf5f5ade3b8fc48590e1bc4794cb43 Mon Sep 17 00:00:00 2001 From: s_nakamoto Date: Wed, 17 Feb 2010 23:55:43 +0000 Subject: safer wxGetTranslation wrapper git-svn-id: https://bitcoin.svn.sourceforge.net/svnroot/bitcoin/trunk@67 1a98c847-1fd6-4fd8-948a-caf3550aa51b --- serialize.h | 2 +- util.cpp | 29 +++++++++++++++++++++++++++++ util.h | 9 ++++----- 3 files changed, 34 insertions(+), 6 deletions(-) diff --git a/serialize.h b/serialize.h index f3b99978df..aaf3f99051 100644 --- a/serialize.h +++ b/serialize.h @@ -19,7 +19,7 @@ class CScript; class CDataStream; class CAutoFile; -static const int VERSION = 202; +static const int VERSION = 203; static const char* pszSubVer = ".0"; diff --git a/util.cpp b/util.cpp index 266c1dd7df..f4ce556643 100644 --- a/util.cpp +++ b/util.cpp @@ -431,6 +431,35 @@ void ParseParameters(int argc, char* argv[]) } +const char* wxGetTranslation(const char* pszEnglish) +{ + // Wrapper of wxGetTranslation returning the same const char* type as was passed in + static CCriticalSection cs; + CRITICAL_BLOCK(cs) + { + // Look in cache + static map mapCache; + map::iterator mi = mapCache.find(pszEnglish); + if (mi != mapCache.end()) + return (*mi).second; + + // wxWidgets translation + const char* pszTranslated = wxGetTranslation(wxString(pszEnglish, wxConvUTF8)).utf8_str(); + if (strcmp(pszEnglish, pszTranslated) == 0) + return pszEnglish; + + // Add to cache, memory doesn't need to be freed + char* pszCached = new char[strlen(pszTranslated)+1]; + strcpy(pszCached, pszTranslated); + mapCache[pszEnglish] = pszCached; + return pszCached; + } +} + + + + + diff --git a/util.h b/util.h index 188a9ece14..8aed902f3f 100644 --- a/util.h +++ b/util.h @@ -136,6 +136,7 @@ bool ParseMoney(const char* pszIn, int64& nRet); vector ParseHex(const char* psz); vector ParseHex(const std::string& str); void ParseParameters(int argc, char* argv[]); +const char* wxGetTranslation(const char* psz); int GetFilesize(FILE* file); void GetDataDir(char* pszDirRet); string GetDataDir(); @@ -340,11 +341,9 @@ void skipspaces(T& it) ++it; } -inline const char* wxGetTranslation(const char* psz) -{ - // Return translated UTF-8 const char* - return wxGetTranslation(wxString(psz, wxConvUTF8)).utf8_str(); -} + + + -- cgit v1.2.3 From 6ff4388ffa56fcf2fb398bd893a79f008af7efdc Mon Sep 17 00:00:00 2001 From: s_nakamoto Date: Sat, 20 Feb 2010 21:59:59 +0000 Subject: Address Book with tabs instead of separate Your Address book, with live update of default address in main window, New... button on main window for creating new receiving address, made receiving address labels more visible, ask user before paying transaction fee, when sending to bitcoin address also use a bitcoin address for the change, added some event.Skip() to fix UI glitches -- version 0.2.4 --- main.cpp | 112 ++++++------ main.h | 7 +- script.h | 5 + serialize.h | 2 +- ui.cpp | 580 ++++++++++++++++++++++++++++------------------------------ ui.h | 62 +++---- uibase.cpp | 100 +++++++--- uibase.h | 36 ++-- uiproject.fbp | 580 ++++++++++++++++++++++++++++++++++++++++++++++------------ util.cpp | 6 +- 10 files changed, 941 insertions(+), 549 deletions(-) diff --git a/main.cpp b/main.cpp index 665a78e207..e5cc881bb2 100644 --- a/main.cpp +++ b/main.cpp @@ -2645,7 +2645,12 @@ void BitcoinMiner() do { pindexTmp = pindexBest; - Sleep(10000); + for (int i = 0; i < 10; i++) + { + Sleep(1000); + if (fShutdown) + return; + } } while (pindexTmp != pindexBest); } @@ -2852,10 +2857,13 @@ bool CreateTransaction(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew, CK if (keyRet.IsNull()) keyRet.MakeNewKey(); - // Fill a vout to ourself - CScript scriptPubKey; - scriptPubKey << keyRet.GetPubKey() << OP_CHECKSIG; - wtxNew.vout.push_back(CTxOut(nValueIn - nTotalValue, scriptPubKey)); + // Fill a vout to ourself, using same address type as the payment + CScript scriptChange; + if (scriptPubKey.GetBitcoinAddressHash160() != 0) + scriptChange.SetBitcoinAddress(keyRet.GetPubKey()); + else + scriptChange << keyRet.GetPubKey() << OP_CHECKSIG; + wtxNew.vout.push_back(CTxOut(nValueIn - nTotalValue, scriptChange)); } // Fill a vout to the payee @@ -2894,42 +2902,50 @@ bool CreateTransaction(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew, CK } // Call after CreateTransaction unless you want to abort -bool CommitTransactionSpent(const CWalletTx& wtxNew, const CKey& key) +bool CommitTransaction(CWalletTx& wtxNew, const CKey& key) { CRITICAL_BLOCK(cs_main) - CRITICAL_BLOCK(cs_mapWallet) { - //// old: eventually should make this transactional, never want to add a - //// transaction without marking spent transactions, although the risk of - //// interruption during this step is remote. - //// update: This matters even less now that fSpent can get corrected - //// when transactions are seen in VerifySignature. The remote chance of - //// unmarked fSpent will be handled by that. Don't need to make this - //// transactional. Pls delete this comment block later. - - // 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 - // maybe makes sense; please don't do it anywhere else. - CWalletDB walletdb("r"); - - // Add the change's private key to wallet - if (!key.IsNull() && !AddKey(key)) - throw runtime_error("CommitTransactionSpent() : AddKey failed\n"); - - // Add tx to wallet, because if it has change it's also ours, - // otherwise just for transaction history. - AddToWallet(wtxNew); + 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 + // maybe makes sense; please don't do it anywhere else. + CWalletDB walletdb("r"); + + // Add the change's private key to wallet + if (!key.IsNull() && !AddKey(key)) + throw runtime_error("CommitTransaction() : AddKey failed\n"); + + // Add tx to wallet, because if it has change it's also ours, + // otherwise just for transaction history. + AddToWallet(wtxNew); + + // Mark old coins as spent + set setCoins; + foreach(const CTxIn& txin, wtxNew.vin) + setCoins.insert(&mapWallet[txin.prevout.hash]); + foreach(CWalletTx* pcoin, setCoins) + { + pcoin->fSpent = true; + pcoin->WriteToDisk(); + vWalletUpdated.push_back(pcoin->GetHash()); + } + } + + // Track how many getdata requests our transaction gets + CRITICAL_BLOCK(cs_mapRequestCount) + mapRequestCount[wtxNew.GetHash()] = 0; - // Mark old coins as spent - set setCoins; - foreach(const CTxIn& txin, wtxNew.vin) - setCoins.insert(&mapWallet[txin.prevout.hash]); - foreach(CWalletTx* pcoin, setCoins) + // Broadcast + if (!wtxNew.AcceptTransaction()) { - pcoin->fSpent = true; - pcoin->WriteToDisk(); - vWalletUpdated.push_back(pcoin->GetHash()); + // This must not fail. The transaction has already been signed and recorded. + printf("CommitTransaction() : Error: Transaction not valid"); + return false; } + wtxNew.RelayWalletTransaction(); } MainFrameRepaint(); return true; @@ -2938,7 +2954,7 @@ bool CommitTransactionSpent(const CWalletTx& wtxNew, const CKey& key) -string SendMoney(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew) +string SendMoney(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew, bool fAskFee) { CRITICAL_BLOCK(cs_main) { @@ -2954,26 +2970,12 @@ string SendMoney(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew) printf("SendMoney() : %s", strError.c_str()); return strError; } - if (!CommitTransactionSpent(wtxNew, key)) - { - printf("SendMoney() : Error finalizing transaction"); - return _("Error finalizing transaction"); - } - - // Track how many getdata requests our transaction gets - CRITICAL_BLOCK(cs_mapRequestCount) - mapRequestCount[wtxNew.GetHash()] = 0; - printf("SendMoney: %s\n", wtxNew.GetHash().ToString().substr(0,6).c_str()); + if (fAskFee && !ThreadSafeAskFee(nFeeRequired, _("Sending..."), NULL)) + return "ABORTED"; - // Broadcast - if (!wtxNew.AcceptTransaction()) - { - // This must not fail. The transaction has already been signed and recorded. - printf("SendMoney() : Error: Transaction not valid"); + if (!CommitTransaction(wtxNew, key)) return _("Error: The transaction was rejected. This might happen if some of the coins in your wallet were already spent, such as if you used a copy of wallet.dat and coins were spent in the copy but not marked as spent here."); - } - wtxNew.RelayWalletTransaction(); } MainFrameRepaint(); return ""; @@ -2981,7 +2983,7 @@ string SendMoney(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew) -string SendMoneyToBitcoinAddress(string strAddress, int64 nValue, CWalletTx& wtxNew) +string SendMoneyToBitcoinAddress(string strAddress, int64 nValue, CWalletTx& wtxNew, bool fAskFee) { // Check amount if (nValue <= 0) @@ -2994,5 +2996,5 @@ string SendMoneyToBitcoinAddress(string strAddress, int64 nValue, CWalletTx& wtx if (!scriptPubKey.SetBitcoinAddress(strAddress)) return _("Invalid bitcoin address"); - return SendMoney(scriptPubKey, nValue, wtxNew); + return SendMoney(scriptPubKey, nValue, wtxNew, fAskFee); } diff --git a/main.h b/main.h index bcb6ec7dcc..4027f87eb4 100644 --- a/main.h +++ b/main.h @@ -67,9 +67,10 @@ bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv); bool SendMessages(CNode* pto); int64 GetBalance(); bool CreateTransaction(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew, CKey& keyRet, int64& nFeeRequiredRet); -bool CommitTransactionSpent(const CWalletTx& wtxNew, const CKey& key); -string SendMoney(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew); -string SendMoneyToBitcoinAddress(string strAddress, int64 nValue, CWalletTx& wtxNew); +bool CommitTransaction(CWalletTx& wtxNew, const CKey& key); +bool BroadcastTransaction(CWalletTx& wtxNew); +string SendMoney(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew, bool fAskFee=false); +string SendMoneyToBitcoinAddress(string strAddress, int64 nValue, CWalletTx& wtxNew, bool fAskFee=false); void GenerateBitcoins(bool fGenerate); void ThreadBitcoinMiner(void* parg); void BitcoinMiner(); diff --git a/script.h b/script.h index 9e41889150..dc47e1d836 100644 --- a/script.h +++ b/script.h @@ -580,6 +580,11 @@ public: *this << OP_DUP << OP_HASH160 << hash160 << OP_EQUALVERIFY << OP_CHECKSIG; } + void SetBitcoinAddress(const vector& vchPubKey) + { + SetBitcoinAddress(Hash160(vchPubKey)); + } + bool SetBitcoinAddress(const string& strAddress) { this->clear(); diff --git a/serialize.h b/serialize.h index aaf3f99051..23d61fe977 100644 --- a/serialize.h +++ b/serialize.h @@ -19,7 +19,7 @@ class CScript; class CDataStream; class CAutoFile; -static const int VERSION = 203; +static const int VERSION = 204; static const char* pszSubVer = ".0"; diff --git a/ui.cpp b/ui.cpp index 87ba19e082..9bd34e0952 100644 --- a/ui.cpp +++ b/ui.cpp @@ -35,13 +35,54 @@ int fMinimizeOnClose = true; // Util // +void ExitTimeout(void* parg) +{ +#ifdef __WXMSW__ + Sleep(5000); + ExitProcess(0); +#endif +} + +void Shutdown(void* parg) +{ + static CCriticalSection cs_Shutdown; + static bool fTaken; + bool fFirstThread; + CRITICAL_BLOCK(cs_Shutdown) + { + fFirstThread = !fTaken; + fTaken = true; + } + static bool fExit; + if (fFirstThread) + { + fShutdown = true; + nTransactionsUpdated++; + DBFlush(false); + StopNode(); + DBFlush(true); + CreateThread(ExitTimeout, NULL); + Sleep(50); + printf("Bitcoin exiting\n\n"); + fExit = true; + exit(0); + } + else + { + while (!fExit) + Sleep(500); + Sleep(100); + ExitThread(0); + } +} + 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); - event.Skip(); } bool Is24HourTime() @@ -194,6 +235,35 @@ int ThreadSafeMessageBox(const string& message, const string& caption, int style #endif } +bool ThreadSafeAskFee(int64 nFeeRequired, const string& strCaption, wxWindow* parent) +{ + if (nFeeRequired == 0 || 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 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; + CWalletDB().WriteDefaultKey(mapPubKeys[hash160]); + pframeMain->m_textCtrlAddress->SetValue(strAddress); + } +} + @@ -227,11 +297,6 @@ CMainFrame::CMainFrame(wxWindow* parent) : CMainFrameBase(parent) fontTmp.SetFamily(wxFONTFAMILY_TELETYPE); m_staticTextBalance->SetFont(fontTmp); m_staticTextBalance->SetSize(140, 17); - // & underlines don't work on the toolbar buttons on gtk - m_toolBar->ClearTools(); - 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(); // resize to fit ubuntu's huge default font dResize = 1.20; SetSize((dResize + 0.02) * GetSize().GetWidth(), 1.09 * GetSize().GetHeight()); @@ -276,47 +341,6 @@ CMainFrame::~CMainFrame() ptaskbaricon = NULL; } -void ExitTimeout(void* parg) -{ -#ifdef __WXMSW__ - Sleep(5000); - ExitProcess(0); -#endif -} - -void Shutdown(void* parg) -{ - static CCriticalSection cs_Shutdown; - static bool fTaken; - bool fFirstThread; - CRITICAL_BLOCK(cs_Shutdown) - { - fFirstThread = !fTaken; - fTaken = true; - } - static bool fExit; - if (fFirstThread) - { - fShutdown = true; - nTransactionsUpdated++; - DBFlush(false); - StopNode(); - DBFlush(true); - CreateThread(ExitTimeout, NULL); - Sleep(50); - printf("Bitcoin exiting\n\n"); - fExit = true; - exit(0); - } - else - { - while (!fExit) - Sleep(500); - Sleep(100); - ExitThread(0); - } -} - void CMainFrame::OnClose(wxCloseEvent& event) { if (fMinimizeOnClose && event.CanVeto() && !IsIconized()) @@ -335,6 +359,7 @@ void CMainFrame::OnClose(wxCloseEvent& event) 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 @@ -342,7 +367,7 @@ void CMainFrame::OnIconize(wxIconizeEvent& event) if (!event.Iconized()) fClosedToTray = false; #ifndef __WXMSW__ - // Tray is not reliable on Linux gnome + // Tray is not reliable on ubuntu 9.10 gnome fClosedToTray = false; #endif if (fMinimizeToTray && event.Iconized()) @@ -353,6 +378,7 @@ void CMainFrame::OnIconize(wxIconizeEvent& event) 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); @@ -360,9 +386,11 @@ void CMainFrame::OnMouseEvents(wxMouseEvent& event) void CMainFrame::OnListColBeginDrag(wxListEvent& event) { - // Hidden columns not resizeable - if (event.GetColumn() <= 1 && !fDebug) + // Hidden columns not resizeable + if (event.GetColumn() <= 1 && !fDebug) event.Veto(); + else + event.Skip(); } int CMainFrame::GetSortIndex(const string& strSort) @@ -546,7 +574,7 @@ bool CMainFrame::InsertTransaction(const CWalletTx& wtx, bool fNew, int nIndex) if (wtx.IsCoinBase()) { - // Coinbase + // Generated strDescription = _("Generated"); if (nCredit == 0) { @@ -569,7 +597,7 @@ bool CMainFrame::InsertTransaction(const CWalletTx& wtx, bool fNew, int nIndex) } else if (!mapValue["from"].empty() || !mapValue["message"].empty()) { - // Online transaction + // Received by IP connection if (!mapValue["from"].empty()) strDescription += _("From: ") + mapValue["from"]; if (!mapValue["message"].empty()) @@ -581,7 +609,7 @@ bool CMainFrame::InsertTransaction(const CWalletTx& wtx, bool fNew, int nIndex) } else { - // Offline transaction + // Received by Bitcoin Address foreach(const CTxOut& txout, wtx.vout) { if (txout.IsMine()) @@ -591,20 +619,19 @@ bool CMainFrame::InsertTransaction(const CWalletTx& wtx, bool fNew, int nIndex) { CRITICAL_BLOCK(cs_mapAddressBook) { + //strDescription += _("Received payment to "); + //strDescription += _("Received with address "); + strDescription += _("From: unknown, Received with: "); string strAddress = PubKeyToAddress(vchPubKey); - if (mapAddressBook.count(strAddress)) + map::iterator mi = mapAddressBook.find(strAddress); + if (mi != mapAddressBook.end() && !(*mi).second.empty()) { - //strDescription += _("Received payment to "); - //strDescription += _("Received with address "); - strDescription += _("From: unknown, To: "); - strDescription += strAddress; - /// The labeling feature is just too confusing, so I hid it - /// by putting it at the end where it runs off the screen. - /// It can still be seen by widening the column, or in the - /// details dialog. - if (!mapAddressBook[strAddress].empty()) - strDescription += " (" + mapAddressBook[strAddress] + ")"; + string strLabel = (*mi).second; + strDescription += strAddress.substr(0,12) + "... "; + strDescription += "(" + strLabel + ")"; } + else + strDescription += strAddress; } } break; @@ -659,12 +686,12 @@ bool CMainFrame::InsertTransaction(const CWalletTx& wtx, bool fNew, int nIndex) string strAddress; if (!mapValue["to"].empty()) { - // Online transaction + // Sent to IP strAddress = mapValue["to"]; } else { - // Offline transaction + // Sent to Bitcoin Address uint160 hash160; if (ExtractHash160(txout.scriptPubKey, hash160)) strAddress = Hash160ToAddress(hash160); @@ -683,8 +710,11 @@ bool CMainFrame::InsertTransaction(const CWalletTx& wtx, bool fNew, int nIndex) } int64 nValue = txout.nValue; - if (nOut == 0 && nTxFee > 0) + if (nTxFee > 0) + { nValue += nTxFee; + nTxFee = 0; + } InsertLine(fNew, nIndex, hash, strprintf("%s-%d", strSort.c_str(), nOut), strStatus, @@ -846,12 +876,12 @@ void CMainFrame::RefreshStatusColumn() void CMainFrame::OnPaint(wxPaintEvent& event) { + event.Skip(); if (fRefresh) { fRefresh = false; Refresh(); } - event.Skip(); } @@ -903,6 +933,9 @@ void MainFrameRepaint() void CMainFrame::OnPaintListCtrl(wxPaintEvent& event) { + // Skip lets the listctrl do the paint, we're just hooking the message + event.Skip(); + if (ptaskbaricon) ptaskbaricon->UpdateTooltip(); @@ -970,11 +1003,6 @@ void CMainFrame::OnPaintListCtrl(wxPaintEvent& event) if (fDebug && GetTime() - nThreadSocketHandlerHeartbeat > 60) m_statusBar->SetStatusText(" ERROR: ThreadSocketHandler has stopped", 0); - - // Pass through to listctrl to actually do the paint, we're just hooking the message - m_listCtrl->Disconnect(wxEVT_PAINT, (wxObjectEventFunction)NULL, NULL, this); - m_listCtrl->GetEventHandler()->ProcessEvent(event); - m_listCtrl->Connect(wxEVT_PAINT, wxPaintEventHandler(CMainFrame::OnPaintListCtrl), NULL, this); } @@ -1033,8 +1061,10 @@ void CMainFrame::OnUpdateUIOptionsGenerate(wxUpdateUIEvent& event) void CMainFrame::OnMenuOptionsChangeYourAddress(wxCommandEvent& event) { - // Options->Change Your Address - OnButtonChange(event); + // Options->Your Receiving Addresses + CAddressBookDialog dialog(this, "", CAddressBookDialog::RECEIVING, false); + if (!dialog.ShowModal()) + return; } void CMainFrame::OnMenuOptionsOptions(wxCommandEvent& event) @@ -1061,11 +1091,11 @@ void CMainFrame::OnButtonSend(wxCommandEvent& event) void CMainFrame::OnButtonAddressBook(wxCommandEvent& event) { // Toolbar: Address Book - CAddressBookDialog dialogAddr(this, "", false); + CAddressBookDialog dialogAddr(this, "", CAddressBookDialog::SENDING, false); if (dialogAddr.ShowModal() == 2) { // Send - CSendDialog dialogSend(this, dialogAddr.GetAddress()); + CSendDialog dialogSend(this, dialogAddr.GetSelectedAddress()); dialogSend.ShowModal(); } } @@ -1073,35 +1103,36 @@ void CMainFrame::OnButtonAddressBook(wxCommandEvent& event) void CMainFrame::OnSetFocusAddress(wxFocusEvent& event) { // Automatically select-all when entering window + event.Skip(); m_textCtrlAddress->SetSelection(-1, -1); fOnSetFocusAddress = true; - event.Skip(); } void CMainFrame::OnMouseEventsAddress(wxMouseEvent& event) { + event.Skip(); if (fOnSetFocusAddress) m_textCtrlAddress->SetSelection(-1, -1); fOnSetFocusAddress = false; - event.Skip(); } -void CMainFrame::OnButtonChange(wxCommandEvent& event) +void CMainFrame::OnButtonNew(wxCommandEvent& event) { - CYourAddressDialog dialog(this, string(m_textCtrlAddress->GetValue())); + // Ask name + CGetTextFromUserDialog dialog(this, + _("New Receiving Address"), + _("It's good policy to use a new address for each payment you receive.\n\nLabel"), + ""); if (!dialog.ShowModal()) return; - string strAddress = (string)dialog.GetAddress(); - if (strAddress != m_textCtrlAddress->GetValue()) - { - uint160 hash160; - if (!AddressToHash160(strAddress, hash160)) - return; - if (!mapPubKeys.count(hash160)) - return; - CWalletDB().WriteDefaultKey(mapPubKeys[hash160]); - m_textCtrlAddress->SetValue(strAddress); - } + string strName = dialog.GetValue(); + + // Generate new key + string strAddress = PubKeyToAddress(GenerateNewKey()); + + // Save + SetAddressBookName(strAddress, strName); + SetDefaultReceivingAddress(strAddress); } void CMainFrame::OnButtonCopy(wxCommandEvent& event) @@ -1139,7 +1170,6 @@ void CMainFrame::OnListItemActivated(wxListEvent& event) - ////////////////////////////////////////////////////////////////////////////// // // CTxDetailsDialog @@ -1452,6 +1482,7 @@ void COptionsDialog::OnListBox(wxCommandEvent& event) void COptionsDialog::OnKillFocusTransactionFee(wxFocusEvent& event) { + event.Skip(); int64 nTmp = nTransactionFee; ParseMoney(m_textCtrlTransactionFee->GetValue(), nTmp); m_textCtrlTransactionFee->SetValue(FormatMoney(nTmp)); @@ -1485,6 +1516,7 @@ CAddress COptionsDialog::GetProxyAddr() void COptionsDialog::OnKillFocusProxy(wxFocusEvent& event) { + event.Skip(); m_textCtrlProxyIP->SetValue(GetProxyAddr().ToStringIP()); m_textCtrlProxyPort->SetValue(GetProxyAddr().ToStringPort()); } @@ -1632,6 +1664,7 @@ CSendDialog::CSendDialog(wxWindow* parent, const wxString& strAddress) : CSendDi void CSendDialog::OnTextAddress(wxCommandEvent& event) { // Check mark + event.Skip(); bool fBitcoinAddress = IsValidBitcoinAddress(m_textCtrlAddress->GetValue()); m_bitmapCheckMark->Show(fBitcoinAddress); @@ -1660,6 +1693,7 @@ void CSendDialog::OnTextAddress(wxCommandEvent& event) void CSendDialog::OnKillFocusAmount(wxFocusEvent& event) { // Reformat the amount + event.Skip(); if (m_textCtrlAmount->GetValue().Trim().empty()) return; int64 nTmp; @@ -1670,9 +1704,9 @@ void CSendDialog::OnKillFocusAmount(wxFocusEvent& event) void CSendDialog::OnButtonAddressBook(wxCommandEvent& event) { // Open address book - CAddressBookDialog dialog(this, m_textCtrlAddress->GetValue(), true); + CAddressBookDialog dialog(this, m_textCtrlAddress->GetValue(), CAddressBookDialog::SENDING, true); if (dialog.ShowModal()) - m_textCtrlAddress->SetValue(dialog.GetAddress()); + m_textCtrlAddress->SetValue(dialog.GetSelectedAddress()); } void CSendDialog::OnButtonPaste(wxCommandEvent& event) @@ -1723,11 +1757,11 @@ void CSendDialog::OnButtonSend(wxCommandEvent& event) CScript scriptPubKey; scriptPubKey << OP_DUP << OP_HASH160 << hash160 << OP_EQUALVERIFY << OP_CHECKSIG; - string strError = SendMoney(scriptPubKey, nValue, wtx); - if (strError != "") - wxMessageBox(strError + " ", _("Sending...")); - else + string strError = SendMoney(scriptPubKey, nValue, wtx, true); + if (strError == "") wxMessageBox(_("Payment sent "), _("Sending...")); + else if (strError != "ABORTED") + wxMessageBox(strError + " ", _("Sending...")); } else { @@ -1846,6 +1880,7 @@ void CSendingDialog::OnButtonCancel(wxCommandEvent& event) void CSendingDialog::OnPaint(wxPaintEvent& event) { + event.Skip(); if (strlen(pszStatus) > 130) m_textCtrlStatus->SetValue(string("\n") + pszStatus); else @@ -1869,7 +1904,6 @@ void CSendingDialog::OnPaint(wxPaintEvent& event) Close(); wxMessageBox(_("Transfer cancelled "), _("Sending..."), wxOK, this); } - event.Skip(); } @@ -2016,6 +2050,13 @@ void CSendingDialog::OnReply2(CDataStream& vRecv) 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) @@ -2040,20 +2081,15 @@ void CSendingDialog::OnReply2(CDataStream& vRecv) return; // Commit - if (!CommitTransactionSpent(wtx, key)) + if (!CommitTransaction(wtx, key)) { - Error(_("Error finalizing payment")); + 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 pnode->PushRequest("submitorder", wtx, SendingDialogOnReply3, this); - // Accept and broadcast transaction - if (!wtx.AcceptTransaction()) - printf("ERROR: CSendingDialog : wtxNew.AcceptTransaction() %s failed\n", wtx.GetHash().ToString().c_str()); - wtx.RelayWalletTransaction(); - Status(_("Waiting for confirmation...")); MainFrameRepaint(); } @@ -2097,37 +2133,54 @@ void CSendingDialog::OnReply3(CDataStream& vRecv) ////////////////////////////////////////////////////////////////////////////// // -// CYourAddressDialog +// CAddressBookDialog // -CYourAddressDialog::CYourAddressDialog(wxWindow* parent, const string& strInitSelected) : CYourAddressDialogBase(parent) +CAddressBookDialog::CAddressBookDialog(wxWindow* parent, const wxString& strInitSelected, int nPageIn, bool fDuringSendIn) : CAddressBookDialogBase(parent) { + // 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 + wxIcon iconAddressBook; + iconAddressBook.CopyFromBitmap(wxBitmap(addressbook16_xpm)); + SetIcon(iconAddressBook); + // Init column headers - m_listCtrl->InsertColumn(0, _("Label"), wxLIST_FORMAT_LEFT, 200); - m_listCtrl->InsertColumn(1, _("Bitcoin Address"), wxLIST_FORMAT_LEFT, 350); - m_listCtrl->SetFocus(); + 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(cs_mapKeys) CRITICAL_BLOCK(cs_mapAddressBook) { + string strDefaultReceiving = (string)pframeMain->m_textCtrlAddress->GetValue(); foreach(const PAIRTYPE(string, string)& item, mapAddressBook) { string strAddress = item.first; string strName = item.second; uint160 hash160; bool fMine = (AddressToHash160(strAddress, hash160) && mapPubKeys.count(hash160)); - if (fMine) - { - int nIndex = InsertLine(m_listCtrl, strName, strAddress); - if (strAddress == strInitSelected) - m_listCtrl->SetItemState(nIndex, wxLIST_STATE_SELECTED|wxLIST_STATE_FOCUSED, wxLIST_STATE_SELECTED|wxLIST_STATE_FOCUSED); - } + wxListCtrl* plistCtrl = fMine ? m_listCtrlReceiving : m_listCtrlSending; + int nIndex = InsertLine(plistCtrl, strName, strAddress); + if (strAddress == (fMine ? strDefaultReceiving : strInitSelected)) + plistCtrl->SetItemState(nIndex, wxLIST_STATE_SELECTED|wxLIST_STATE_FOCUSED, wxLIST_STATE_SELECTED|wxLIST_STATE_FOCUSED); } } } -wxString CYourAddressDialog::GetAddress() +wxString CAddressBookDialog::GetSelectedAddress() { int nIndex = GetSelection(m_listCtrl); if (nIndex == -1) @@ -2135,172 +2188,92 @@ wxString CYourAddressDialog::GetAddress() return GetItemText(m_listCtrl, nIndex, 1); } -void CYourAddressDialog::OnListEndLabelEdit(wxListEvent& event) +wxString CAddressBookDialog::GetSelectedSendingAddress() { - // Update address book with edited name - if (event.IsEditCancelled()) - return; - string strAddress = (string)GetItemText(m_listCtrl, event.GetIndex(), 1); - SetAddressBookName(strAddress, string(event.GetText())); - pframeMain->RefreshListCtrl(); + int nIndex = GetSelection(m_listCtrlSending); + if (nIndex == -1) + return ""; + return GetItemText(m_listCtrlSending, nIndex, 1); } -void CYourAddressDialog::OnListItemSelected(wxListEvent& event) +wxString CAddressBookDialog::GetSelectedReceivingAddress() { + int nIndex = GetSelection(m_listCtrlReceiving); + if (nIndex == -1) + return ""; + return GetItemText(m_listCtrlReceiving, nIndex, 1); } -void CYourAddressDialog::OnListItemActivated(wxListEvent& event) +void CAddressBookDialog::OnNotebookPageChanged(wxNotebookEvent& event) { - // Doubleclick edits item - wxCommandEvent event2; - OnButtonRename(event2); + 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 CYourAddressDialog::OnButtonRename(wxCommandEvent& event) +void CAddressBookDialog::OnListEndLabelEdit(wxListEvent& event) { - // Ask new name - int nIndex = GetSelection(m_listCtrl); - if (nIndex == -1) - return; - string strName = (string)m_listCtrl->GetItemText(nIndex); - string strAddress = (string)GetItemText(m_listCtrl, nIndex, 1); - CGetTextFromUserDialog dialog(this, _("Edit Address Label"), _("New Label"), strName); - if (!dialog.ShowModal()) + // Update address book with edited name + event.Skip(); + if (event.IsEditCancelled()) return; - strName = dialog.GetValue(); - - // Change name - SetAddressBookName(strAddress, strName); - m_listCtrl->SetItemText(nIndex, strName); + string strAddress = (string)GetItemText(m_listCtrl, event.GetIndex(), 1); + SetAddressBookName(strAddress, string(event.GetText())); pframeMain->RefreshListCtrl(); } -void CYourAddressDialog::OnButtonNew(wxCommandEvent& event) +void CAddressBookDialog::OnListItemSelected(wxListEvent& event) { - // Ask name - CGetTextFromUserDialog dialog(this, _("New Bitcoin Address"), _("Label"), ""); - if (!dialog.ShowModal()) - return; - string strName = dialog.GetValue(); - - // Generate new key - string strAddress = PubKeyToAddress(GenerateNewKey()); - SetAddressBookName(strAddress, strName); - - // Add to list and select it - int nIndex = InsertLine(m_listCtrl, strName, strAddress); - SetSelection(m_listCtrl, nIndex); - m_listCtrl->SetFocus(); + event.Skip(); + if (nPage == RECEIVING) + SetDefaultReceivingAddress((string)GetSelectedReceivingAddress()); } -void CYourAddressDialog::OnButtonCopy(wxCommandEvent& event) +void CAddressBookDialog::OnListItemActivated(wxListEvent& event) { - // Copy address box to clipboard - if (wxTheClipboard->Open()) + event.Skip(); + if (fDuringSend) { - wxTheClipboard->SetData(new wxTextDataObject(GetAddress())); - wxTheClipboard->Close(); + // Doubleclick returns selection + EndModal(GetSelectedAddress() != "" ? 2 : 0); + return; } -} -void CYourAddressDialog::OnButtonOK(wxCommandEvent& event) -{ - // OK - EndModal(true); -} - -void CYourAddressDialog::OnButtonCancel(wxCommandEvent& event) -{ - // Cancel - EndModal(false); -} - -void CYourAddressDialog::OnClose(wxCloseEvent& event) -{ - // Close - EndModal(false); + // Doubleclick edits item + wxCommandEvent event2; + OnButtonEdit(event2); } - - - - - -////////////////////////////////////////////////////////////////////////////// -// -// CAddressBookDialog -// - -CAddressBookDialog::CAddressBookDialog(wxWindow* parent, const wxString& strInitSelected, bool fSendingIn) : CAddressBookDialogBase(parent) +void CAddressBookDialog::OnButtonDelete(wxCommandEvent& event) { - fSending = fSendingIn; - if (!fSending) - m_buttonCancel->Show(false); - - // Init column headers - m_listCtrl->InsertColumn(0, _("Name"), wxLIST_FORMAT_LEFT, 200); - m_listCtrl->InsertColumn(1, _("Address"), wxLIST_FORMAT_LEFT, 350); - m_listCtrl->SetFocus(); - - // Set Icon - wxIcon iconAddressBook; - iconAddressBook.CopyFromBitmap(wxBitmap(addressbook16_xpm)); - SetIcon(iconAddressBook); - - // Fill listctrl with address book data - CRITICAL_BLOCK(cs_mapKeys) - CRITICAL_BLOCK(cs_mapAddressBook) + if (nPage != SENDING) + return; + for (int nIndex = m_listCtrl->GetItemCount()-1; nIndex >= 0; nIndex--) { - foreach(const PAIRTYPE(string, string)& item, mapAddressBook) + if (m_listCtrl->GetItemState(nIndex, wxLIST_STATE_SELECTED)) { - string strAddress = item.first; - string strName = item.second; - uint160 hash160; - bool fMine = (AddressToHash160(strAddress, hash160) && mapPubKeys.count(hash160)); - if (!fMine) - { - int nIndex = InsertLine(m_listCtrl, strName, strAddress); - if (strAddress == strInitSelected) - m_listCtrl->SetItemState(nIndex, wxLIST_STATE_SELECTED|wxLIST_STATE_FOCUSED, wxLIST_STATE_SELECTED|wxLIST_STATE_FOCUSED); - } + string strAddress = (string)GetItemText(m_listCtrl, nIndex, 1); + CWalletDB().EraseName(strAddress); + m_listCtrl->DeleteItem(nIndex); } } -} - -wxString CAddressBookDialog::GetAddress() -{ - int nIndex = GetSelection(m_listCtrl); - if (nIndex == -1) - return ""; - return GetItemText(m_listCtrl, nIndex, 1); -} - -void CAddressBookDialog::OnListEndLabelEdit(wxListEvent& event) -{ - // Update address book with edited name - if (event.IsEditCancelled()) - return; - string strAddress = (string)GetItemText(m_listCtrl, event.GetIndex(), 1); - SetAddressBookName(strAddress, string(event.GetText())); pframeMain->RefreshListCtrl(); } -void CAddressBookDialog::OnListItemSelected(wxListEvent& event) -{ -} - -void CAddressBookDialog::OnListItemActivated(wxListEvent& event) +void CAddressBookDialog::OnButtonCopy(wxCommandEvent& event) { - if (fSending) - { - // Doubleclick returns selection - EndModal(GetAddress() != "" ? 2 : 0); - } - else + // Copy address box to clipboard + if (wxTheClipboard->Open()) { - // Doubleclick edits item - wxCommandEvent event2; - OnButtonEdit(event2); + wxTheClipboard->SetData(new wxTextDataObject(GetSelectedAddress())); + wxTheClipboard->Close(); } } @@ -2315,24 +2288,37 @@ bool CAddressBookDialog::CheckIfMine(const string& strAddress, const string& str void CAddressBookDialog::OnButtonEdit(wxCommandEvent& event) { - // Ask new name 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; - do + + if (nPage == SENDING) { - CGetTextFromUserDialog dialog(this, _("Edit Address"), _("Name"), strName, _("Address"), strAddress); + // 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.GetValue1(); - strAddress = dialog.GetValue2(); + strName = dialog.GetValue(); } - while (CheckIfMine(strAddress, _("Edit Address"))); - // Change name + // Write back if (strAddress != strAddressOrg) CWalletDB().EraseName(strAddressOrg); SetAddressBookName(strAddress, strName); @@ -2343,55 +2329,50 @@ void CAddressBookDialog::OnButtonEdit(wxCommandEvent& event) void CAddressBookDialog::OnButtonNew(wxCommandEvent& event) { - // Ask name string strName; string strAddress; - do + + if (nPage == SENDING) { - CGetTextFromUserDialog dialog(this, _("New Address"), _("Name"), strName, _("Address"), strAddress); + // 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"), + _("It's good policy to use a new address for each payment you receive.\n\nLabel"), + ""); if (!dialog.ShowModal()) return; - strName = dialog.GetValue1(); - strAddress = dialog.GetValue2(); + strName = dialog.GetValue(); + + // Generate new key + strAddress = PubKeyToAddress(GenerateNewKey()); } - while (CheckIfMine(strAddress, _("New Address"))); // Add to list and select it SetAddressBookName(strAddress, strName); int nIndex = InsertLine(m_listCtrl, strName, strAddress); SetSelection(m_listCtrl, nIndex); m_listCtrl->SetFocus(); - pframeMain->RefreshListCtrl(); -} - -void CAddressBookDialog::OnButtonDelete(wxCommandEvent& event) -{ - 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); - CWalletDB().EraseName(strAddress); - m_listCtrl->DeleteItem(nIndex); - } - } - pframeMain->RefreshListCtrl(); -} - -void CAddressBookDialog::OnButtonCopy(wxCommandEvent& event) -{ - // Copy address box to clipboard - if (wxTheClipboard->Open()) - { - wxTheClipboard->SetData(new wxTextDataObject(GetAddress())); - wxTheClipboard->Close(); - } + if (nPage == SENDING) + pframeMain->RefreshListCtrl(); } void CAddressBookDialog::OnButtonOK(wxCommandEvent& event) { // OK - EndModal(GetAddress() != "" ? 1 : 0); + EndModal(GetSelectedAddress() != "" ? 1 : 0); } void CAddressBookDialog::OnButtonCancel(wxCommandEvent& event) @@ -2644,14 +2625,14 @@ bool CMyApp::OnInit2() wxString strUsage = string() + _("Usage: bitcoin [options]") + "\t\t\t\t\t\t\n" + _("Options:\n") + - " -gen \t\t " + _("Generate coins\n") + - " -gen=0 \t\t " + _("Don't generate coins\n") + - " -min \t\t " + _("Start minimized\n") + - " -datadir= \t " + _("Specify data directory\n") + - " -proxy=\t " + _("Connect through socks4 proxy\n") + - " -addnode= \t " + _("Add a node to connect to\n") + - " -connect= \t " + _("Connect only to the specified node\n") + - " -? \t\t " + _("This help message\n"); + " -gen \t\t " + _("Generate coins\n") + + " -gen=0 \t\t " + _("Don't generate coins\n") + + " -min \t\t " + _("Start minimized\n") + + " -datadir= \t " + _("Specify data directory\n") + + " -proxy=\t " + _("Connect through socks4 proxy\n") + + " -addnode= \t " + _("Add a node to connect to\n") + + " -connect= \t " + _("Connect only to the specified node\n") + + " -? \t\t " + _("This help message\n"); if (fWindows) { @@ -2947,7 +2928,6 @@ bool CMyApp::OnExceptionInMainLoop() Sleep(1000); throw; } - return true; } diff --git a/ui.h b/ui.h index 50d39ab7fc..317b87e987 100644 --- a/ui.h +++ b/ui.h @@ -2,11 +2,9 @@ // Distributed under the MIT/X11 software license, see the accompanying // file license.txt or http://www.opensource.org/licenses/mit-license.php. - - - DECLARE_EVENT_TYPE(wxEVT_UITHREADCALL, -1) + extern map mapArgs; // Settings @@ -22,6 +20,7 @@ void UIThreadCall(boost::function0); void MainFrameRepaint(); void Shutdown(void* parg); int ThreadSafeMessageBox(const string& message, const string& caption="Message", int style=wxOK, wxWindow* parent=NULL, int x=-1, int y=-1); +bool ThreadSafeAskFee(int64 nFeeRequired, const string& strCaption, wxWindow* parent); @@ -51,7 +50,7 @@ protected: void OnButtonAddressBook(wxCommandEvent& event); void OnSetFocusAddress(wxFocusEvent& event); void OnMouseEventsAddress(wxMouseEvent& event); - void OnButtonChange(wxCommandEvent& event); + void OnButtonNew(wxCommandEvent& event); void OnButtonCopy(wxCommandEvent& event); void OnListColBeginDrag(wxListEvent& event); void OnListItemActivated(wxListEvent& event); @@ -205,53 +204,39 @@ void SendingDialogOnReply3(void* parg, CDataStream& vRecv); -class CYourAddressDialog : public CYourAddressDialogBase -{ -protected: - // Event handlers - void OnListEndLabelEdit(wxListEvent& event); - void OnListItemSelected(wxListEvent& event); - void OnListItemActivated(wxListEvent& event); - void OnButtonRename(wxCommandEvent& event); - void OnButtonNew(wxCommandEvent& event); - void OnButtonCopy(wxCommandEvent& event); - void OnButtonOK(wxCommandEvent& event); - void OnButtonCancel(wxCommandEvent& event); - void OnClose(wxCloseEvent& event); - -public: - /** Constructor */ - CYourAddressDialog(wxWindow* parent); - CYourAddressDialog(wxWindow* parent, const string& strInitSelected); - - // Custom - wxString GetAddress(); -}; - - - class CAddressBookDialog : public CAddressBookDialogBase { protected: // Event handlers + void OnNotebookPageChanged(wxNotebookEvent& event); void OnListEndLabelEdit(wxListEvent& event); void OnListItemSelected(wxListEvent& event); void OnListItemActivated(wxListEvent& event); - void OnButtonEdit(wxCommandEvent& event); void OnButtonDelete(wxCommandEvent& event); - void OnButtonNew(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, bool fSendingIn); + CAddressBookDialog(wxWindow* parent, const wxString& strInitSelected, int nPageIn, bool fDuringSendIn); // Custom - bool fSending; + enum + { + SENDING = 0, + RECEIVING = 1, + }; + int nPage; + wxListCtrl* m_listCtrl; + bool fDuringSend; wxString GetAddress(); + wxString GetSelectedAddress(); + wxString GetSelectedSendingAddress(); + wxString GetSelectedReceivingAddress(); bool CheckIfMine(const string& strAddress, const string& strTitle); }; @@ -282,18 +267,25 @@ public: const string& strMessage2="", const 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); - SetSize(wxDefaultCoord, 180); + y += 46 + wxString(strMessage2).Freq('\n') * 14; } if (!fWindows) - SetSize(1.14 * GetSize().GetWidth(), 1.14 * GetSize().GetHeight()); + { + x *= 1.14; + y *= 1.14; + } + SetSize(x, y); } // Custom diff --git a/uibase.cpp b/uibase.cpp index 5b3f9abc22..340c7abcd4 100644 --- a/uibase.cpp +++ b/uibase.cpp @@ -42,14 +42,14 @@ CMainFrameBase::CMainFrameBase( wxWindow* parent, wxWindowID id, const wxString& m_menuOptions->Append( m_menuOptionsGenerateBitcoins ); wxMenuItem* m_menuOptionsChangeYourAddress; - m_menuOptionsChangeYourAddress = new wxMenuItem( m_menuOptions, wxID_ANY, wxString( _("&Change Your Address...") ) , wxEmptyString, wxITEM_NORMAL ); + 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_MENUOPTIONSOPTIONS, wxString( _("&Options...") ) , wxEmptyString, wxITEM_NORMAL ); m_menuOptions->Append( m_menuOptionsOptions ); - m_menubar->Append( m_menuOptions, _("&Options") ); + m_menubar->Append( m_menuOptions, _("&Settings") ); m_menuHelp = new wxMenu(); wxMenuItem* m_menuHelpAbout; @@ -65,8 +65,8 @@ CMainFrameBase::CMainFrameBase( wxWindow* parent, wxWindowID id, const wxString& 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->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 ); @@ -86,14 +86,10 @@ CMainFrameBase::CMainFrameBase( wxWindow* parent, wxWindowID id, const wxString& bSizer85->Add( m_staticText32, 0, wxALIGN_CENTER_VERTICAL|wxLEFT, 5 ); m_textCtrlAddress = new wxTextCtrl( this, wxID_TEXTCTRLADDRESS, wxEmptyString, wxDefaultPosition, wxSize( 340,-1 ), wxTE_READONLY ); - m_textCtrlAddress->SetBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_MENU ) ); - bSizer85->Add( m_textCtrlAddress, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 ); - m_buttonNew = new wxButton( this, wxID_BUTTONCHANGE, _("&New..."), wxDefaultPosition, wxDefaultSize, 0 ); - m_buttonNew->Hide(); - - bSizer85->Add( m_buttonNew, 0, wxRIGHT, 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 ); @@ -188,7 +184,7 @@ CMainFrameBase::CMainFrameBase( wxWindow* parent, wxWindowID id, const wxString& 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::OnButtonChange ), 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_listCtrl->Connect( wxEVT_COMMAND_LIST_COL_BEGIN_DRAG, wxListEventHandler( CMainFrameBase::OnListColBeginDrag ), NULL, this ); m_listCtrl->Connect( wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler( CMainFrameBase::OnListItemActivated ), NULL, this ); @@ -240,7 +236,7 @@ CMainFrameBase::~CMainFrameBase() 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::OnButtonChange ), 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_listCtrl->Disconnect( wxEVT_COMMAND_LIST_COL_BEGIN_DRAG, wxListEventHandler( CMainFrameBase::OnListColBeginDrag ), NULL, this ); m_listCtrl->Disconnect( wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler( CMainFrameBase::OnListItemActivated ), NULL, this ); @@ -844,20 +840,53 @@ CAddressBookDialogBase::CAddressBookDialogBase( wxWindow* parent, wxWindowID id, { 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, 5, 0, wxEXPAND, 5 ); + bSizer68->Add( 0, 0, 0, wxEXPAND, 5 ); - m_staticText55 = new wxStaticText( this, wxID_ANY, _("Bitcoin Address"), wxDefaultPosition, wxDefaultSize, 0 ); + 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_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 ); + 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 ); @@ -865,34 +894,42 @@ CAddressBookDialogBase::CAddressBookDialogBase( wxWindow* parent, wxWindowID id, 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_buttonDelete = new wxButton( this, wxID_BUTTONDELETE, _("&Delete"), wxDefaultPosition, wxDefaultSize, 0 ); - bSizer69->Add( m_buttonDelete, 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 ); - bSizer68->Add( bSizer69, 0, wxEXPAND, 5 ); + bSizer58->Add( bSizer69, 0, wxEXPAND, 5 ); - this->SetSizer( bSizer68 ); + this->SetSizer( bSizer58 ); this->Layout(); // Connect Events this->Connect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( CAddressBookDialogBase::OnClose ) ); - m_listCtrl->Connect( wxEVT_COMMAND_LIST_END_LABEL_EDIT, wxListEventHandler( CAddressBookDialogBase::OnListEndLabelEdit ), NULL, this ); - m_listCtrl->Connect( wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler( CAddressBookDialogBase::OnListItemActivated ), NULL, this ); - m_listCtrl->Connect( wxEVT_COMMAND_LIST_ITEM_SELECTED, wxListEventHandler( CAddressBookDialogBase::OnListItemSelected ), NULL, this ); + 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_buttonDelete->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CAddressBookDialogBase::OnButtonDelete ), 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 ); } @@ -901,12 +938,17 @@ CAddressBookDialogBase::~CAddressBookDialogBase() { // Disconnect Events this->Disconnect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( CAddressBookDialogBase::OnClose ) ); - m_listCtrl->Disconnect( wxEVT_COMMAND_LIST_END_LABEL_EDIT, wxListEventHandler( CAddressBookDialogBase::OnListEndLabelEdit ), NULL, this ); - m_listCtrl->Disconnect( wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler( CAddressBookDialogBase::OnListItemActivated ), NULL, this ); - m_listCtrl->Disconnect( wxEVT_COMMAND_LIST_ITEM_SELECTED, wxListEventHandler( CAddressBookDialogBase::OnListItemSelected ), NULL, this ); + 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_buttonDelete->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CAddressBookDialogBase::OnButtonDelete ), 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 ); } diff --git a/uibase.h b/uibase.h index 494ed10f7c..90abd00f1d 100644 --- a/uibase.h +++ b/uibase.h @@ -36,6 +36,7 @@ #include #include #include +#include /////////////////////////////////////////////////////////////////////////// @@ -46,7 +47,7 @@ #define wxID_BUTTONSEND 1004 #define wxID_BUTTONRECEIVE 1005 #define wxID_TEXTCTRLADDRESS 1006 -#define wxID_BUTTONCHANGE 1007 +#define wxID_BUTTONNEW 1007 #define wxID_BUTTONCOPY 1008 #define wxID_TRANSACTIONFEE 1009 #define wxID_PROXYIP 1010 @@ -58,10 +59,13 @@ #define wxID_CHOICETRANSFERTYPE 1016 #define wxID_LISTCTRL 1017 #define wxID_BUTTONRENAME 1018 -#define wxID_BUTTONNEW 1019 -#define wxID_BUTTONEDIT 1020 -#define wxID_BUTTONDELETE 1021 -#define wxID_TEXTCTRL 1022 +#define wxID_PANELSENDING 1019 +#define wxID_LISTCTRLSENDING 1020 +#define wxID_PANELRECEIVING 1021 +#define wxID_LISTCTRLRECEIVING 1022 +#define wxID_BUTTONDELETE 1023 +#define wxID_BUTTONEDIT 1024 +#define wxID_TEXTCTRL 1025 /////////////////////////////////////////////////////////////////////////////// /// Class CMainFrameBase @@ -79,7 +83,6 @@ class CMainFrameBase : public wxFrame wxStatusBar* m_statusBar; wxStaticText* m_staticText32; - wxTextCtrl* m_textCtrlAddress; wxButton* m_buttonNew; wxButton* m_buttonCopy; @@ -108,7 +111,7 @@ class CMainFrameBase : public wxFrame virtual void OnKeyDown( wxKeyEvent& event ){ event.Skip(); } virtual void OnMouseEventsAddress( wxMouseEvent& event ){ event.Skip(); } virtual void OnSetFocusAddress( wxFocusEvent& event ){ event.Skip(); } - virtual void OnButtonChange( wxCommandEvent& event ){ event.Skip(); } + virtual void OnButtonNew( wxCommandEvent& event ){ event.Skip(); } virtual void OnButtonCopy( wxCommandEvent& event ){ event.Skip(); } virtual void OnListColBeginDrag( wxListEvent& event ){ event.Skip(); } virtual void OnListItemActivated( wxListEvent& event ){ event.Skip(); } @@ -117,6 +120,7 @@ class CMainFrameBase : public wxFrame public: wxMenu* m_menuOptions; + wxTextCtrl* m_textCtrlAddress; wxListCtrl* m_listCtrl; CMainFrameBase( wxWindow* parent, wxWindowID id = wxID_MAINFRAME, const wxString& title = _("Bitcoin"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 712,484 ), long style = wxDEFAULT_FRAME_STYLE|wxRESIZE_BORDER|wxTAB_TRAVERSAL ); ~CMainFrameBase(); @@ -343,23 +347,33 @@ class CAddressBookDialogBase : public wxDialog private: protected: + wxNotebook* m_notebook; + wxPanel* m_panelSending; wxStaticText* m_staticText55; - wxListCtrl* m_listCtrl; + 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_buttonDelete; 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 OnButtonDelete( wxCommandEvent& event ){ event.Skip(); } virtual void OnButtonOK( wxCommandEvent& event ){ event.Skip(); } virtual void OnButtonCancel( wxCommandEvent& event ){ event.Skip(); } @@ -397,7 +411,7 @@ class CGetTextFromUserDialogBase : public wxDialog public: - CGetTextFromUserDialogBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxEmptyString, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 403,138 ), long style = wxDEFAULT_DIALOG_STYLE ); + 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(); }; diff --git a/uiproject.fbp b/uiproject.fbp index 988df2a9b9..113a15796a 100644 --- a/uiproject.fbp +++ b/uiproject.fbp @@ -155,7 +155,7 @@
- &Options + &Settings m_menuOptions public @@ -180,7 +180,7 @@ wxID_ANY wxITEM_NORMAL - &Change Your Address... + &Your Receiving Addresses... m_menuOptionsChangeYourAddress none @@ -276,7 +276,7 @@ xpm/send20.xpm; Load From File wxID_BUTTONSEND wxITEM_NORMAL - &Send Coins + Send Coins m_tool1 @@ -290,7 +290,7 @@ xpm/addressbook20.xpm; Load From File wxID_BUTTONRECEIVE wxITEM_NORMAL - &Address Book + Address Book m_tool2 @@ -426,7 +426,7 @@ wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT 0 - wxSYS_COLOUR_MENU + 1 @@ -437,7 +437,7 @@ 0 -1,-1 m_textCtrlAddress - protected + public 340,-1 wxTE_READONLY @@ -478,7 +478,7 @@ 5 - wxRIGHT + wxRIGHT|wxALIGN_CENTER_VERTICAL 0 @@ -487,22 +487,22 @@ 1 - 1 - wxID_BUTTONCHANGE - &New... + 0 + wxID_BUTTONNEW + &New... m_buttonNew protected - - + -1,-1 + wxBU_EXACTFIT - OnButtonChange + OnButtonNew @@ -4388,7 +4388,7 @@ 5 wxEXPAND 0 - + bSizer69 wxHORIZONTAL @@ -4721,89 +4721,29 @@ - bSizer68 + bSizer58 wxVERTICAL none 5 - wxEXPAND - 0 - - 5 - protected - 0 - - - - 5 - wxTOP|wxRIGHT|wxLEFT - 0 - - - - 1 - - - 1 - wxID_ANY - Bitcoin Address - - - m_staticText55 - protected - - - - - - - - - -1 - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALL|wxEXPAND + wxEXPAND|wxTOP|wxRIGHT|wxLEFT 1 - + + 1 0 - wxID_LISTCTRL + wxID_ANY - m_listCtrl + m_notebook protected - wxLC_NO_SORT_HEADER|wxLC_REPORT|wxLC_SORT_ASCENDING + @@ -4819,32 +4759,14 @@ - - - - - - - - - - - - OnListEndLabelEdit - - OnListItemActivated - - - - - OnListItemSelected - + OnNotebookPageChanged + @@ -4852,6 +4774,384 @@ + + + Sending + 0 + + + + 1 + + + 0 + wxID_PANELSENDING + + + m_panelSending + protected + + + + + + + wxTAB_TRAVERSAL + + + + + + + + + + + + + + + + + + + + + + + + + + bSizer68 + wxVERTICAL + none + + 5 + wxEXPAND + 0 + + 0 + protected + 0 + + + + 5 + wxTOP|wxRIGHT|wxLEFT + 0 + + + + 1 + + + 1 + wxID_ANY + Bitcoin Address + + + m_staticText55 + protected + + + + + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL|wxEXPAND + 1 + + + + 1 + + + 0 + wxID_LISTCTRLSENDING + + + m_listCtrlSending + protected + + + wxLC_NO_SORT_HEADER|wxLC_REPORT|wxLC_SORT_ASCENDING + + + + + + + + + + + + + + + + + + + + + + + + + + + OnListEndLabelEdit + + OnListItemActivated + + + + + OnListItemSelected + + + + + + + + + + + + + + + + + + + + + + Receiving + 1 + + + + 1 + + + 0 + wxID_PANELRECEIVING + + + m_panelReceiving + protected + + + + + + + wxTAB_TRAVERSAL + + + + + + + + + + + + + + + + + + + + + + + + + + bSizer681 + wxVERTICAL + none + + 5 + wxEXPAND + 0 + + 0 + protected + 0 + + + + 6 + wxTOP|wxRIGHT|wxLEFT + 0 + + + + 1 + + + 0 + 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. + + + m_staticText45 + protected + + + + + + + + + 570 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND + 0 + + 2 + protected + 0 + + + + 5 + wxALL|wxEXPAND + 1 + + + + 1 + + + 0 + wxID_LISTCTRLRECEIVING + + + m_listCtrlReceiving + protected + + + wxLC_NO_SORT_HEADER|wxLC_REPORT|wxLC_SORT_ASCENDING + + + + + + + + + + + + + + + + + + + + + + + + + + + OnListEndLabelEdit + + OnListItemActivated + + + + + OnListItemSelected + + + + + + + + + + + + + + + + + + + @@ -4885,11 +5185,11 @@ 0 - wxID_BUTTONEDIT - &Edit... + wxID_BUTTONDELETE + &Delete -1,-1 - m_buttonEdit + m_buttonDelete protected @@ -4899,7 +5199,7 @@ - OnButtonEdit + OnButtonDelete @@ -4937,11 +5237,63 @@ 0 - wxID_BUTTONNEW - &New Address... + wxID_BUTTONCOPY + &Copy to Clipboard -1,-1 - m_buttonNew + m_buttonCopy + protected + + -1,-1 + + + + + + + OnButtonCopy + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND + 0 + + + + 0 + 1 + + + 0 + wxID_BUTTONEDIT + &Edit... + + -1,-1 + m_buttonEdit protected @@ -4951,7 +5303,7 @@ - OnButtonNew + OnButtonEdit @@ -4989,11 +5341,11 @@ 0 - wxID_BUTTONDELETE - &Delete + wxID_BUTTONNEW + &New Address... -1,-1 - m_buttonDelete + m_buttonNew protected @@ -5003,7 +5355,7 @@ - OnButtonDelete + OnButtonNew @@ -5151,7 +5503,7 @@ CGetTextFromUserDialogBase - 403,138 + 440,138 wxDEFAULT_DIALOG_STYLE diff --git a/util.cpp b/util.cpp index f4ce556643..40f7af343b 100644 --- a/util.cpp +++ b/util.cpp @@ -445,10 +445,14 @@ const char* wxGetTranslation(const char* pszEnglish) // wxWidgets translation const char* pszTranslated = wxGetTranslation(wxString(pszEnglish, wxConvUTF8)).utf8_str(); + + // 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, pszTranslated) == 0) return pszEnglish; - // Add to cache, memory doesn't need to be freed + // 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(pszTranslated)+1]; strcpy(pszCached, pszTranslated); mapCache[pszEnglish] = pszCached; -- cgit v1.2.3 From 75199de534a590329a3b636d63fade2e4544ce97 Mon Sep 17 00:00:00 2001 From: s_nakamoto Date: Sat, 20 Feb 2010 21:59:59 +0000 Subject: Address Book with tabs instead of separate Your Address book, with live update of default address in main window, New... button on main window for creating new receiving address, made receiving address labels more visible, ask user before paying transaction fee, when sending to bitcoin address also use a bitcoin address for the change, added some event.Skip() to fix UI glitches -- version 0.2.4 git-svn-id: https://bitcoin.svn.sourceforge.net/svnroot/bitcoin/trunk@68 1a98c847-1fd6-4fd8-948a-caf3550aa51b --- main.cpp | 112 ++++++------ main.h | 7 +- script.h | 5 + serialize.h | 2 +- ui.cpp | 580 ++++++++++++++++++++++++++++------------------------------ ui.h | 62 +++---- uibase.cpp | 100 +++++++--- uibase.h | 36 ++-- uiproject.fbp | 580 ++++++++++++++++++++++++++++++++++++++++++++++------------ util.cpp | 6 +- 10 files changed, 941 insertions(+), 549 deletions(-) diff --git a/main.cpp b/main.cpp index 665a78e207..e5cc881bb2 100644 --- a/main.cpp +++ b/main.cpp @@ -2645,7 +2645,12 @@ void BitcoinMiner() do { pindexTmp = pindexBest; - Sleep(10000); + for (int i = 0; i < 10; i++) + { + Sleep(1000); + if (fShutdown) + return; + } } while (pindexTmp != pindexBest); } @@ -2852,10 +2857,13 @@ bool CreateTransaction(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew, CK if (keyRet.IsNull()) keyRet.MakeNewKey(); - // Fill a vout to ourself - CScript scriptPubKey; - scriptPubKey << keyRet.GetPubKey() << OP_CHECKSIG; - wtxNew.vout.push_back(CTxOut(nValueIn - nTotalValue, scriptPubKey)); + // Fill a vout to ourself, using same address type as the payment + CScript scriptChange; + if (scriptPubKey.GetBitcoinAddressHash160() != 0) + scriptChange.SetBitcoinAddress(keyRet.GetPubKey()); + else + scriptChange << keyRet.GetPubKey() << OP_CHECKSIG; + wtxNew.vout.push_back(CTxOut(nValueIn - nTotalValue, scriptChange)); } // Fill a vout to the payee @@ -2894,42 +2902,50 @@ bool CreateTransaction(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew, CK } // Call after CreateTransaction unless you want to abort -bool CommitTransactionSpent(const CWalletTx& wtxNew, const CKey& key) +bool CommitTransaction(CWalletTx& wtxNew, const CKey& key) { CRITICAL_BLOCK(cs_main) - CRITICAL_BLOCK(cs_mapWallet) { - //// old: eventually should make this transactional, never want to add a - //// transaction without marking spent transactions, although the risk of - //// interruption during this step is remote. - //// update: This matters even less now that fSpent can get corrected - //// when transactions are seen in VerifySignature. The remote chance of - //// unmarked fSpent will be handled by that. Don't need to make this - //// transactional. Pls delete this comment block later. - - // 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 - // maybe makes sense; please don't do it anywhere else. - CWalletDB walletdb("r"); - - // Add the change's private key to wallet - if (!key.IsNull() && !AddKey(key)) - throw runtime_error("CommitTransactionSpent() : AddKey failed\n"); - - // Add tx to wallet, because if it has change it's also ours, - // otherwise just for transaction history. - AddToWallet(wtxNew); + 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 + // maybe makes sense; please don't do it anywhere else. + CWalletDB walletdb("r"); + + // Add the change's private key to wallet + if (!key.IsNull() && !AddKey(key)) + throw runtime_error("CommitTransaction() : AddKey failed\n"); + + // Add tx to wallet, because if it has change it's also ours, + // otherwise just for transaction history. + AddToWallet(wtxNew); + + // Mark old coins as spent + set setCoins; + foreach(const CTxIn& txin, wtxNew.vin) + setCoins.insert(&mapWallet[txin.prevout.hash]); + foreach(CWalletTx* pcoin, setCoins) + { + pcoin->fSpent = true; + pcoin->WriteToDisk(); + vWalletUpdated.push_back(pcoin->GetHash()); + } + } + + // Track how many getdata requests our transaction gets + CRITICAL_BLOCK(cs_mapRequestCount) + mapRequestCount[wtxNew.GetHash()] = 0; - // Mark old coins as spent - set setCoins; - foreach(const CTxIn& txin, wtxNew.vin) - setCoins.insert(&mapWallet[txin.prevout.hash]); - foreach(CWalletTx* pcoin, setCoins) + // Broadcast + if (!wtxNew.AcceptTransaction()) { - pcoin->fSpent = true; - pcoin->WriteToDisk(); - vWalletUpdated.push_back(pcoin->GetHash()); + // This must not fail. The transaction has already been signed and recorded. + printf("CommitTransaction() : Error: Transaction not valid"); + return false; } + wtxNew.RelayWalletTransaction(); } MainFrameRepaint(); return true; @@ -2938,7 +2954,7 @@ bool CommitTransactionSpent(const CWalletTx& wtxNew, const CKey& key) -string SendMoney(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew) +string SendMoney(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew, bool fAskFee) { CRITICAL_BLOCK(cs_main) { @@ -2954,26 +2970,12 @@ string SendMoney(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew) printf("SendMoney() : %s", strError.c_str()); return strError; } - if (!CommitTransactionSpent(wtxNew, key)) - { - printf("SendMoney() : Error finalizing transaction"); - return _("Error finalizing transaction"); - } - - // Track how many getdata requests our transaction gets - CRITICAL_BLOCK(cs_mapRequestCount) - mapRequestCount[wtxNew.GetHash()] = 0; - printf("SendMoney: %s\n", wtxNew.GetHash().ToString().substr(0,6).c_str()); + if (fAskFee && !ThreadSafeAskFee(nFeeRequired, _("Sending..."), NULL)) + return "ABORTED"; - // Broadcast - if (!wtxNew.AcceptTransaction()) - { - // This must not fail. The transaction has already been signed and recorded. - printf("SendMoney() : Error: Transaction not valid"); + if (!CommitTransaction(wtxNew, key)) return _("Error: The transaction was rejected. This might happen if some of the coins in your wallet were already spent, such as if you used a copy of wallet.dat and coins were spent in the copy but not marked as spent here."); - } - wtxNew.RelayWalletTransaction(); } MainFrameRepaint(); return ""; @@ -2981,7 +2983,7 @@ string SendMoney(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew) -string SendMoneyToBitcoinAddress(string strAddress, int64 nValue, CWalletTx& wtxNew) +string SendMoneyToBitcoinAddress(string strAddress, int64 nValue, CWalletTx& wtxNew, bool fAskFee) { // Check amount if (nValue <= 0) @@ -2994,5 +2996,5 @@ string SendMoneyToBitcoinAddress(string strAddress, int64 nValue, CWalletTx& wtx if (!scriptPubKey.SetBitcoinAddress(strAddress)) return _("Invalid bitcoin address"); - return SendMoney(scriptPubKey, nValue, wtxNew); + return SendMoney(scriptPubKey, nValue, wtxNew, fAskFee); } diff --git a/main.h b/main.h index bcb6ec7dcc..4027f87eb4 100644 --- a/main.h +++ b/main.h @@ -67,9 +67,10 @@ bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv); bool SendMessages(CNode* pto); int64 GetBalance(); bool CreateTransaction(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew, CKey& keyRet, int64& nFeeRequiredRet); -bool CommitTransactionSpent(const CWalletTx& wtxNew, const CKey& key); -string SendMoney(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew); -string SendMoneyToBitcoinAddress(string strAddress, int64 nValue, CWalletTx& wtxNew); +bool CommitTransaction(CWalletTx& wtxNew, const CKey& key); +bool BroadcastTransaction(CWalletTx& wtxNew); +string SendMoney(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew, bool fAskFee=false); +string SendMoneyToBitcoinAddress(string strAddress, int64 nValue, CWalletTx& wtxNew, bool fAskFee=false); void GenerateBitcoins(bool fGenerate); void ThreadBitcoinMiner(void* parg); void BitcoinMiner(); diff --git a/script.h b/script.h index 9e41889150..dc47e1d836 100644 --- a/script.h +++ b/script.h @@ -580,6 +580,11 @@ public: *this << OP_DUP << OP_HASH160 << hash160 << OP_EQUALVERIFY << OP_CHECKSIG; } + void SetBitcoinAddress(const vector& vchPubKey) + { + SetBitcoinAddress(Hash160(vchPubKey)); + } + bool SetBitcoinAddress(const string& strAddress) { this->clear(); diff --git a/serialize.h b/serialize.h index aaf3f99051..23d61fe977 100644 --- a/serialize.h +++ b/serialize.h @@ -19,7 +19,7 @@ class CScript; class CDataStream; class CAutoFile; -static const int VERSION = 203; +static const int VERSION = 204; static const char* pszSubVer = ".0"; diff --git a/ui.cpp b/ui.cpp index 87ba19e082..9bd34e0952 100644 --- a/ui.cpp +++ b/ui.cpp @@ -35,13 +35,54 @@ int fMinimizeOnClose = true; // Util // +void ExitTimeout(void* parg) +{ +#ifdef __WXMSW__ + Sleep(5000); + ExitProcess(0); +#endif +} + +void Shutdown(void* parg) +{ + static CCriticalSection cs_Shutdown; + static bool fTaken; + bool fFirstThread; + CRITICAL_BLOCK(cs_Shutdown) + { + fFirstThread = !fTaken; + fTaken = true; + } + static bool fExit; + if (fFirstThread) + { + fShutdown = true; + nTransactionsUpdated++; + DBFlush(false); + StopNode(); + DBFlush(true); + CreateThread(ExitTimeout, NULL); + Sleep(50); + printf("Bitcoin exiting\n\n"); + fExit = true; + exit(0); + } + else + { + while (!fExit) + Sleep(500); + Sleep(100); + ExitThread(0); + } +} + 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); - event.Skip(); } bool Is24HourTime() @@ -194,6 +235,35 @@ int ThreadSafeMessageBox(const string& message, const string& caption, int style #endif } +bool ThreadSafeAskFee(int64 nFeeRequired, const string& strCaption, wxWindow* parent) +{ + if (nFeeRequired == 0 || 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 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; + CWalletDB().WriteDefaultKey(mapPubKeys[hash160]); + pframeMain->m_textCtrlAddress->SetValue(strAddress); + } +} + @@ -227,11 +297,6 @@ CMainFrame::CMainFrame(wxWindow* parent) : CMainFrameBase(parent) fontTmp.SetFamily(wxFONTFAMILY_TELETYPE); m_staticTextBalance->SetFont(fontTmp); m_staticTextBalance->SetSize(140, 17); - // & underlines don't work on the toolbar buttons on gtk - m_toolBar->ClearTools(); - 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(); // resize to fit ubuntu's huge default font dResize = 1.20; SetSize((dResize + 0.02) * GetSize().GetWidth(), 1.09 * GetSize().GetHeight()); @@ -276,47 +341,6 @@ CMainFrame::~CMainFrame() ptaskbaricon = NULL; } -void ExitTimeout(void* parg) -{ -#ifdef __WXMSW__ - Sleep(5000); - ExitProcess(0); -#endif -} - -void Shutdown(void* parg) -{ - static CCriticalSection cs_Shutdown; - static bool fTaken; - bool fFirstThread; - CRITICAL_BLOCK(cs_Shutdown) - { - fFirstThread = !fTaken; - fTaken = true; - } - static bool fExit; - if (fFirstThread) - { - fShutdown = true; - nTransactionsUpdated++; - DBFlush(false); - StopNode(); - DBFlush(true); - CreateThread(ExitTimeout, NULL); - Sleep(50); - printf("Bitcoin exiting\n\n"); - fExit = true; - exit(0); - } - else - { - while (!fExit) - Sleep(500); - Sleep(100); - ExitThread(0); - } -} - void CMainFrame::OnClose(wxCloseEvent& event) { if (fMinimizeOnClose && event.CanVeto() && !IsIconized()) @@ -335,6 +359,7 @@ void CMainFrame::OnClose(wxCloseEvent& event) 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 @@ -342,7 +367,7 @@ void CMainFrame::OnIconize(wxIconizeEvent& event) if (!event.Iconized()) fClosedToTray = false; #ifndef __WXMSW__ - // Tray is not reliable on Linux gnome + // Tray is not reliable on ubuntu 9.10 gnome fClosedToTray = false; #endif if (fMinimizeToTray && event.Iconized()) @@ -353,6 +378,7 @@ void CMainFrame::OnIconize(wxIconizeEvent& event) 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); @@ -360,9 +386,11 @@ void CMainFrame::OnMouseEvents(wxMouseEvent& event) void CMainFrame::OnListColBeginDrag(wxListEvent& event) { - // Hidden columns not resizeable - if (event.GetColumn() <= 1 && !fDebug) + // Hidden columns not resizeable + if (event.GetColumn() <= 1 && !fDebug) event.Veto(); + else + event.Skip(); } int CMainFrame::GetSortIndex(const string& strSort) @@ -546,7 +574,7 @@ bool CMainFrame::InsertTransaction(const CWalletTx& wtx, bool fNew, int nIndex) if (wtx.IsCoinBase()) { - // Coinbase + // Generated strDescription = _("Generated"); if (nCredit == 0) { @@ -569,7 +597,7 @@ bool CMainFrame::InsertTransaction(const CWalletTx& wtx, bool fNew, int nIndex) } else if (!mapValue["from"].empty() || !mapValue["message"].empty()) { - // Online transaction + // Received by IP connection if (!mapValue["from"].empty()) strDescription += _("From: ") + mapValue["from"]; if (!mapValue["message"].empty()) @@ -581,7 +609,7 @@ bool CMainFrame::InsertTransaction(const CWalletTx& wtx, bool fNew, int nIndex) } else { - // Offline transaction + // Received by Bitcoin Address foreach(const CTxOut& txout, wtx.vout) { if (txout.IsMine()) @@ -591,20 +619,19 @@ bool CMainFrame::InsertTransaction(const CWalletTx& wtx, bool fNew, int nIndex) { CRITICAL_BLOCK(cs_mapAddressBook) { + //strDescription += _("Received payment to "); + //strDescription += _("Received with address "); + strDescription += _("From: unknown, Received with: "); string strAddress = PubKeyToAddress(vchPubKey); - if (mapAddressBook.count(strAddress)) + map::iterator mi = mapAddressBook.find(strAddress); + if (mi != mapAddressBook.end() && !(*mi).second.empty()) { - //strDescription += _("Received payment to "); - //strDescription += _("Received with address "); - strDescription += _("From: unknown, To: "); - strDescription += strAddress; - /// The labeling feature is just too confusing, so I hid it - /// by putting it at the end where it runs off the screen. - /// It can still be seen by widening the column, or in the - /// details dialog. - if (!mapAddressBook[strAddress].empty()) - strDescription += " (" + mapAddressBook[strAddress] + ")"; + string strLabel = (*mi).second; + strDescription += strAddress.substr(0,12) + "... "; + strDescription += "(" + strLabel + ")"; } + else + strDescription += strAddress; } } break; @@ -659,12 +686,12 @@ bool CMainFrame::InsertTransaction(const CWalletTx& wtx, bool fNew, int nIndex) string strAddress; if (!mapValue["to"].empty()) { - // Online transaction + // Sent to IP strAddress = mapValue["to"]; } else { - // Offline transaction + // Sent to Bitcoin Address uint160 hash160; if (ExtractHash160(txout.scriptPubKey, hash160)) strAddress = Hash160ToAddress(hash160); @@ -683,8 +710,11 @@ bool CMainFrame::InsertTransaction(const CWalletTx& wtx, bool fNew, int nIndex) } int64 nValue = txout.nValue; - if (nOut == 0 && nTxFee > 0) + if (nTxFee > 0) + { nValue += nTxFee; + nTxFee = 0; + } InsertLine(fNew, nIndex, hash, strprintf("%s-%d", strSort.c_str(), nOut), strStatus, @@ -846,12 +876,12 @@ void CMainFrame::RefreshStatusColumn() void CMainFrame::OnPaint(wxPaintEvent& event) { + event.Skip(); if (fRefresh) { fRefresh = false; Refresh(); } - event.Skip(); } @@ -903,6 +933,9 @@ void MainFrameRepaint() void CMainFrame::OnPaintListCtrl(wxPaintEvent& event) { + // Skip lets the listctrl do the paint, we're just hooking the message + event.Skip(); + if (ptaskbaricon) ptaskbaricon->UpdateTooltip(); @@ -970,11 +1003,6 @@ void CMainFrame::OnPaintListCtrl(wxPaintEvent& event) if (fDebug && GetTime() - nThreadSocketHandlerHeartbeat > 60) m_statusBar->SetStatusText(" ERROR: ThreadSocketHandler has stopped", 0); - - // Pass through to listctrl to actually do the paint, we're just hooking the message - m_listCtrl->Disconnect(wxEVT_PAINT, (wxObjectEventFunction)NULL, NULL, this); - m_listCtrl->GetEventHandler()->ProcessEvent(event); - m_listCtrl->Connect(wxEVT_PAINT, wxPaintEventHandler(CMainFrame::OnPaintListCtrl), NULL, this); } @@ -1033,8 +1061,10 @@ void CMainFrame::OnUpdateUIOptionsGenerate(wxUpdateUIEvent& event) void CMainFrame::OnMenuOptionsChangeYourAddress(wxCommandEvent& event) { - // Options->Change Your Address - OnButtonChange(event); + // Options->Your Receiving Addresses + CAddressBookDialog dialog(this, "", CAddressBookDialog::RECEIVING, false); + if (!dialog.ShowModal()) + return; } void CMainFrame::OnMenuOptionsOptions(wxCommandEvent& event) @@ -1061,11 +1091,11 @@ void CMainFrame::OnButtonSend(wxCommandEvent& event) void CMainFrame::OnButtonAddressBook(wxCommandEvent& event) { // Toolbar: Address Book - CAddressBookDialog dialogAddr(this, "", false); + CAddressBookDialog dialogAddr(this, "", CAddressBookDialog::SENDING, false); if (dialogAddr.ShowModal() == 2) { // Send - CSendDialog dialogSend(this, dialogAddr.GetAddress()); + CSendDialog dialogSend(this, dialogAddr.GetSelectedAddress()); dialogSend.ShowModal(); } } @@ -1073,35 +1103,36 @@ void CMainFrame::OnButtonAddressBook(wxCommandEvent& event) void CMainFrame::OnSetFocusAddress(wxFocusEvent& event) { // Automatically select-all when entering window + event.Skip(); m_textCtrlAddress->SetSelection(-1, -1); fOnSetFocusAddress = true; - event.Skip(); } void CMainFrame::OnMouseEventsAddress(wxMouseEvent& event) { + event.Skip(); if (fOnSetFocusAddress) m_textCtrlAddress->SetSelection(-1, -1); fOnSetFocusAddress = false; - event.Skip(); } -void CMainFrame::OnButtonChange(wxCommandEvent& event) +void CMainFrame::OnButtonNew(wxCommandEvent& event) { - CYourAddressDialog dialog(this, string(m_textCtrlAddress->GetValue())); + // Ask name + CGetTextFromUserDialog dialog(this, + _("New Receiving Address"), + _("It's good policy to use a new address for each payment you receive.\n\nLabel"), + ""); if (!dialog.ShowModal()) return; - string strAddress = (string)dialog.GetAddress(); - if (strAddress != m_textCtrlAddress->GetValue()) - { - uint160 hash160; - if (!AddressToHash160(strAddress, hash160)) - return; - if (!mapPubKeys.count(hash160)) - return; - CWalletDB().WriteDefaultKey(mapPubKeys[hash160]); - m_textCtrlAddress->SetValue(strAddress); - } + string strName = dialog.GetValue(); + + // Generate new key + string strAddress = PubKeyToAddress(GenerateNewKey()); + + // Save + SetAddressBookName(strAddress, strName); + SetDefaultReceivingAddress(strAddress); } void CMainFrame::OnButtonCopy(wxCommandEvent& event) @@ -1139,7 +1170,6 @@ void CMainFrame::OnListItemActivated(wxListEvent& event) - ////////////////////////////////////////////////////////////////////////////// // // CTxDetailsDialog @@ -1452,6 +1482,7 @@ void COptionsDialog::OnListBox(wxCommandEvent& event) void COptionsDialog::OnKillFocusTransactionFee(wxFocusEvent& event) { + event.Skip(); int64 nTmp = nTransactionFee; ParseMoney(m_textCtrlTransactionFee->GetValue(), nTmp); m_textCtrlTransactionFee->SetValue(FormatMoney(nTmp)); @@ -1485,6 +1516,7 @@ CAddress COptionsDialog::GetProxyAddr() void COptionsDialog::OnKillFocusProxy(wxFocusEvent& event) { + event.Skip(); m_textCtrlProxyIP->SetValue(GetProxyAddr().ToStringIP()); m_textCtrlProxyPort->SetValue(GetProxyAddr().ToStringPort()); } @@ -1632,6 +1664,7 @@ CSendDialog::CSendDialog(wxWindow* parent, const wxString& strAddress) : CSendDi void CSendDialog::OnTextAddress(wxCommandEvent& event) { // Check mark + event.Skip(); bool fBitcoinAddress = IsValidBitcoinAddress(m_textCtrlAddress->GetValue()); m_bitmapCheckMark->Show(fBitcoinAddress); @@ -1660,6 +1693,7 @@ void CSendDialog::OnTextAddress(wxCommandEvent& event) void CSendDialog::OnKillFocusAmount(wxFocusEvent& event) { // Reformat the amount + event.Skip(); if (m_textCtrlAmount->GetValue().Trim().empty()) return; int64 nTmp; @@ -1670,9 +1704,9 @@ void CSendDialog::OnKillFocusAmount(wxFocusEvent& event) void CSendDialog::OnButtonAddressBook(wxCommandEvent& event) { // Open address book - CAddressBookDialog dialog(this, m_textCtrlAddress->GetValue(), true); + CAddressBookDialog dialog(this, m_textCtrlAddress->GetValue(), CAddressBookDialog::SENDING, true); if (dialog.ShowModal()) - m_textCtrlAddress->SetValue(dialog.GetAddress()); + m_textCtrlAddress->SetValue(dialog.GetSelectedAddress()); } void CSendDialog::OnButtonPaste(wxCommandEvent& event) @@ -1723,11 +1757,11 @@ void CSendDialog::OnButtonSend(wxCommandEvent& event) CScript scriptPubKey; scriptPubKey << OP_DUP << OP_HASH160 << hash160 << OP_EQUALVERIFY << OP_CHECKSIG; - string strError = SendMoney(scriptPubKey, nValue, wtx); - if (strError != "") - wxMessageBox(strError + " ", _("Sending...")); - else + string strError = SendMoney(scriptPubKey, nValue, wtx, true); + if (strError == "") wxMessageBox(_("Payment sent "), _("Sending...")); + else if (strError != "ABORTED") + wxMessageBox(strError + " ", _("Sending...")); } else { @@ -1846,6 +1880,7 @@ void CSendingDialog::OnButtonCancel(wxCommandEvent& event) void CSendingDialog::OnPaint(wxPaintEvent& event) { + event.Skip(); if (strlen(pszStatus) > 130) m_textCtrlStatus->SetValue(string("\n") + pszStatus); else @@ -1869,7 +1904,6 @@ void CSendingDialog::OnPaint(wxPaintEvent& event) Close(); wxMessageBox(_("Transfer cancelled "), _("Sending..."), wxOK, this); } - event.Skip(); } @@ -2016,6 +2050,13 @@ void CSendingDialog::OnReply2(CDataStream& vRecv) 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) @@ -2040,20 +2081,15 @@ void CSendingDialog::OnReply2(CDataStream& vRecv) return; // Commit - if (!CommitTransactionSpent(wtx, key)) + if (!CommitTransaction(wtx, key)) { - Error(_("Error finalizing payment")); + 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 pnode->PushRequest("submitorder", wtx, SendingDialogOnReply3, this); - // Accept and broadcast transaction - if (!wtx.AcceptTransaction()) - printf("ERROR: CSendingDialog : wtxNew.AcceptTransaction() %s failed\n", wtx.GetHash().ToString().c_str()); - wtx.RelayWalletTransaction(); - Status(_("Waiting for confirmation...")); MainFrameRepaint(); } @@ -2097,37 +2133,54 @@ void CSendingDialog::OnReply3(CDataStream& vRecv) ////////////////////////////////////////////////////////////////////////////// // -// CYourAddressDialog +// CAddressBookDialog // -CYourAddressDialog::CYourAddressDialog(wxWindow* parent, const string& strInitSelected) : CYourAddressDialogBase(parent) +CAddressBookDialog::CAddressBookDialog(wxWindow* parent, const wxString& strInitSelected, int nPageIn, bool fDuringSendIn) : CAddressBookDialogBase(parent) { + // 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 + wxIcon iconAddressBook; + iconAddressBook.CopyFromBitmap(wxBitmap(addressbook16_xpm)); + SetIcon(iconAddressBook); + // Init column headers - m_listCtrl->InsertColumn(0, _("Label"), wxLIST_FORMAT_LEFT, 200); - m_listCtrl->InsertColumn(1, _("Bitcoin Address"), wxLIST_FORMAT_LEFT, 350); - m_listCtrl->SetFocus(); + 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(cs_mapKeys) CRITICAL_BLOCK(cs_mapAddressBook) { + string strDefaultReceiving = (string)pframeMain->m_textCtrlAddress->GetValue(); foreach(const PAIRTYPE(string, string)& item, mapAddressBook) { string strAddress = item.first; string strName = item.second; uint160 hash160; bool fMine = (AddressToHash160(strAddress, hash160) && mapPubKeys.count(hash160)); - if (fMine) - { - int nIndex = InsertLine(m_listCtrl, strName, strAddress); - if (strAddress == strInitSelected) - m_listCtrl->SetItemState(nIndex, wxLIST_STATE_SELECTED|wxLIST_STATE_FOCUSED, wxLIST_STATE_SELECTED|wxLIST_STATE_FOCUSED); - } + wxListCtrl* plistCtrl = fMine ? m_listCtrlReceiving : m_listCtrlSending; + int nIndex = InsertLine(plistCtrl, strName, strAddress); + if (strAddress == (fMine ? strDefaultReceiving : strInitSelected)) + plistCtrl->SetItemState(nIndex, wxLIST_STATE_SELECTED|wxLIST_STATE_FOCUSED, wxLIST_STATE_SELECTED|wxLIST_STATE_FOCUSED); } } } -wxString CYourAddressDialog::GetAddress() +wxString CAddressBookDialog::GetSelectedAddress() { int nIndex = GetSelection(m_listCtrl); if (nIndex == -1) @@ -2135,172 +2188,92 @@ wxString CYourAddressDialog::GetAddress() return GetItemText(m_listCtrl, nIndex, 1); } -void CYourAddressDialog::OnListEndLabelEdit(wxListEvent& event) +wxString CAddressBookDialog::GetSelectedSendingAddress() { - // Update address book with edited name - if (event.IsEditCancelled()) - return; - string strAddress = (string)GetItemText(m_listCtrl, event.GetIndex(), 1); - SetAddressBookName(strAddress, string(event.GetText())); - pframeMain->RefreshListCtrl(); + int nIndex = GetSelection(m_listCtrlSending); + if (nIndex == -1) + return ""; + return GetItemText(m_listCtrlSending, nIndex, 1); } -void CYourAddressDialog::OnListItemSelected(wxListEvent& event) +wxString CAddressBookDialog::GetSelectedReceivingAddress() { + int nIndex = GetSelection(m_listCtrlReceiving); + if (nIndex == -1) + return ""; + return GetItemText(m_listCtrlReceiving, nIndex, 1); } -void CYourAddressDialog::OnListItemActivated(wxListEvent& event) +void CAddressBookDialog::OnNotebookPageChanged(wxNotebookEvent& event) { - // Doubleclick edits item - wxCommandEvent event2; - OnButtonRename(event2); + 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 CYourAddressDialog::OnButtonRename(wxCommandEvent& event) +void CAddressBookDialog::OnListEndLabelEdit(wxListEvent& event) { - // Ask new name - int nIndex = GetSelection(m_listCtrl); - if (nIndex == -1) - return; - string strName = (string)m_listCtrl->GetItemText(nIndex); - string strAddress = (string)GetItemText(m_listCtrl, nIndex, 1); - CGetTextFromUserDialog dialog(this, _("Edit Address Label"), _("New Label"), strName); - if (!dialog.ShowModal()) + // Update address book with edited name + event.Skip(); + if (event.IsEditCancelled()) return; - strName = dialog.GetValue(); - - // Change name - SetAddressBookName(strAddress, strName); - m_listCtrl->SetItemText(nIndex, strName); + string strAddress = (string)GetItemText(m_listCtrl, event.GetIndex(), 1); + SetAddressBookName(strAddress, string(event.GetText())); pframeMain->RefreshListCtrl(); } -void CYourAddressDialog::OnButtonNew(wxCommandEvent& event) +void CAddressBookDialog::OnListItemSelected(wxListEvent& event) { - // Ask name - CGetTextFromUserDialog dialog(this, _("New Bitcoin Address"), _("Label"), ""); - if (!dialog.ShowModal()) - return; - string strName = dialog.GetValue(); - - // Generate new key - string strAddress = PubKeyToAddress(GenerateNewKey()); - SetAddressBookName(strAddress, strName); - - // Add to list and select it - int nIndex = InsertLine(m_listCtrl, strName, strAddress); - SetSelection(m_listCtrl, nIndex); - m_listCtrl->SetFocus(); + event.Skip(); + if (nPage == RECEIVING) + SetDefaultReceivingAddress((string)GetSelectedReceivingAddress()); } -void CYourAddressDialog::OnButtonCopy(wxCommandEvent& event) +void CAddressBookDialog::OnListItemActivated(wxListEvent& event) { - // Copy address box to clipboard - if (wxTheClipboard->Open()) + event.Skip(); + if (fDuringSend) { - wxTheClipboard->SetData(new wxTextDataObject(GetAddress())); - wxTheClipboard->Close(); + // Doubleclick returns selection + EndModal(GetSelectedAddress() != "" ? 2 : 0); + return; } -} -void CYourAddressDialog::OnButtonOK(wxCommandEvent& event) -{ - // OK - EndModal(true); -} - -void CYourAddressDialog::OnButtonCancel(wxCommandEvent& event) -{ - // Cancel - EndModal(false); -} - -void CYourAddressDialog::OnClose(wxCloseEvent& event) -{ - // Close - EndModal(false); + // Doubleclick edits item + wxCommandEvent event2; + OnButtonEdit(event2); } - - - - - -////////////////////////////////////////////////////////////////////////////// -// -// CAddressBookDialog -// - -CAddressBookDialog::CAddressBookDialog(wxWindow* parent, const wxString& strInitSelected, bool fSendingIn) : CAddressBookDialogBase(parent) +void CAddressBookDialog::OnButtonDelete(wxCommandEvent& event) { - fSending = fSendingIn; - if (!fSending) - m_buttonCancel->Show(false); - - // Init column headers - m_listCtrl->InsertColumn(0, _("Name"), wxLIST_FORMAT_LEFT, 200); - m_listCtrl->InsertColumn(1, _("Address"), wxLIST_FORMAT_LEFT, 350); - m_listCtrl->SetFocus(); - - // Set Icon - wxIcon iconAddressBook; - iconAddressBook.CopyFromBitmap(wxBitmap(addressbook16_xpm)); - SetIcon(iconAddressBook); - - // Fill listctrl with address book data - CRITICAL_BLOCK(cs_mapKeys) - CRITICAL_BLOCK(cs_mapAddressBook) + if (nPage != SENDING) + return; + for (int nIndex = m_listCtrl->GetItemCount()-1; nIndex >= 0; nIndex--) { - foreach(const PAIRTYPE(string, string)& item, mapAddressBook) + if (m_listCtrl->GetItemState(nIndex, wxLIST_STATE_SELECTED)) { - string strAddress = item.first; - string strName = item.second; - uint160 hash160; - bool fMine = (AddressToHash160(strAddress, hash160) && mapPubKeys.count(hash160)); - if (!fMine) - { - int nIndex = InsertLine(m_listCtrl, strName, strAddress); - if (strAddress == strInitSelected) - m_listCtrl->SetItemState(nIndex, wxLIST_STATE_SELECTED|wxLIST_STATE_FOCUSED, wxLIST_STATE_SELECTED|wxLIST_STATE_FOCUSED); - } + string strAddress = (string)GetItemText(m_listCtrl, nIndex, 1); + CWalletDB().EraseName(strAddress); + m_listCtrl->DeleteItem(nIndex); } } -} - -wxString CAddressBookDialog::GetAddress() -{ - int nIndex = GetSelection(m_listCtrl); - if (nIndex == -1) - return ""; - return GetItemText(m_listCtrl, nIndex, 1); -} - -void CAddressBookDialog::OnListEndLabelEdit(wxListEvent& event) -{ - // Update address book with edited name - if (event.IsEditCancelled()) - return; - string strAddress = (string)GetItemText(m_listCtrl, event.GetIndex(), 1); - SetAddressBookName(strAddress, string(event.GetText())); pframeMain->RefreshListCtrl(); } -void CAddressBookDialog::OnListItemSelected(wxListEvent& event) -{ -} - -void CAddressBookDialog::OnListItemActivated(wxListEvent& event) +void CAddressBookDialog::OnButtonCopy(wxCommandEvent& event) { - if (fSending) - { - // Doubleclick returns selection - EndModal(GetAddress() != "" ? 2 : 0); - } - else + // Copy address box to clipboard + if (wxTheClipboard->Open()) { - // Doubleclick edits item - wxCommandEvent event2; - OnButtonEdit(event2); + wxTheClipboard->SetData(new wxTextDataObject(GetSelectedAddress())); + wxTheClipboard->Close(); } } @@ -2315,24 +2288,37 @@ bool CAddressBookDialog::CheckIfMine(const string& strAddress, const string& str void CAddressBookDialog::OnButtonEdit(wxCommandEvent& event) { - // Ask new name 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; - do + + if (nPage == SENDING) { - CGetTextFromUserDialog dialog(this, _("Edit Address"), _("Name"), strName, _("Address"), strAddress); + // 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.GetValue1(); - strAddress = dialog.GetValue2(); + strName = dialog.GetValue(); } - while (CheckIfMine(strAddress, _("Edit Address"))); - // Change name + // Write back if (strAddress != strAddressOrg) CWalletDB().EraseName(strAddressOrg); SetAddressBookName(strAddress, strName); @@ -2343,55 +2329,50 @@ void CAddressBookDialog::OnButtonEdit(wxCommandEvent& event) void CAddressBookDialog::OnButtonNew(wxCommandEvent& event) { - // Ask name string strName; string strAddress; - do + + if (nPage == SENDING) { - CGetTextFromUserDialog dialog(this, _("New Address"), _("Name"), strName, _("Address"), strAddress); + // 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"), + _("It's good policy to use a new address for each payment you receive.\n\nLabel"), + ""); if (!dialog.ShowModal()) return; - strName = dialog.GetValue1(); - strAddress = dialog.GetValue2(); + strName = dialog.GetValue(); + + // Generate new key + strAddress = PubKeyToAddress(GenerateNewKey()); } - while (CheckIfMine(strAddress, _("New Address"))); // Add to list and select it SetAddressBookName(strAddress, strName); int nIndex = InsertLine(m_listCtrl, strName, strAddress); SetSelection(m_listCtrl, nIndex); m_listCtrl->SetFocus(); - pframeMain->RefreshListCtrl(); -} - -void CAddressBookDialog::OnButtonDelete(wxCommandEvent& event) -{ - 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); - CWalletDB().EraseName(strAddress); - m_listCtrl->DeleteItem(nIndex); - } - } - pframeMain->RefreshListCtrl(); -} - -void CAddressBookDialog::OnButtonCopy(wxCommandEvent& event) -{ - // Copy address box to clipboard - if (wxTheClipboard->Open()) - { - wxTheClipboard->SetData(new wxTextDataObject(GetAddress())); - wxTheClipboard->Close(); - } + if (nPage == SENDING) + pframeMain->RefreshListCtrl(); } void CAddressBookDialog::OnButtonOK(wxCommandEvent& event) { // OK - EndModal(GetAddress() != "" ? 1 : 0); + EndModal(GetSelectedAddress() != "" ? 1 : 0); } void CAddressBookDialog::OnButtonCancel(wxCommandEvent& event) @@ -2644,14 +2625,14 @@ bool CMyApp::OnInit2() wxString strUsage = string() + _("Usage: bitcoin [options]") + "\t\t\t\t\t\t\n" + _("Options:\n") + - " -gen \t\t " + _("Generate coins\n") + - " -gen=0 \t\t " + _("Don't generate coins\n") + - " -min \t\t " + _("Start minimized\n") + - " -datadir= \t " + _("Specify data directory\n") + - " -proxy=\t " + _("Connect through socks4 proxy\n") + - " -addnode= \t " + _("Add a node to connect to\n") + - " -connect= \t " + _("Connect only to the specified node\n") + - " -? \t\t " + _("This help message\n"); + " -gen \t\t " + _("Generate coins\n") + + " -gen=0 \t\t " + _("Don't generate coins\n") + + " -min \t\t " + _("Start minimized\n") + + " -datadir= \t " + _("Specify data directory\n") + + " -proxy=\t " + _("Connect through socks4 proxy\n") + + " -addnode= \t " + _("Add a node to connect to\n") + + " -connect= \t " + _("Connect only to the specified node\n") + + " -? \t\t " + _("This help message\n"); if (fWindows) { @@ -2947,7 +2928,6 @@ bool CMyApp::OnExceptionInMainLoop() Sleep(1000); throw; } - return true; } diff --git a/ui.h b/ui.h index 50d39ab7fc..317b87e987 100644 --- a/ui.h +++ b/ui.h @@ -2,11 +2,9 @@ // Distributed under the MIT/X11 software license, see the accompanying // file license.txt or http://www.opensource.org/licenses/mit-license.php. - - - DECLARE_EVENT_TYPE(wxEVT_UITHREADCALL, -1) + extern map mapArgs; // Settings @@ -22,6 +20,7 @@ void UIThreadCall(boost::function0); void MainFrameRepaint(); void Shutdown(void* parg); int ThreadSafeMessageBox(const string& message, const string& caption="Message", int style=wxOK, wxWindow* parent=NULL, int x=-1, int y=-1); +bool ThreadSafeAskFee(int64 nFeeRequired, const string& strCaption, wxWindow* parent); @@ -51,7 +50,7 @@ protected: void OnButtonAddressBook(wxCommandEvent& event); void OnSetFocusAddress(wxFocusEvent& event); void OnMouseEventsAddress(wxMouseEvent& event); - void OnButtonChange(wxCommandEvent& event); + void OnButtonNew(wxCommandEvent& event); void OnButtonCopy(wxCommandEvent& event); void OnListColBeginDrag(wxListEvent& event); void OnListItemActivated(wxListEvent& event); @@ -205,53 +204,39 @@ void SendingDialogOnReply3(void* parg, CDataStream& vRecv); -class CYourAddressDialog : public CYourAddressDialogBase -{ -protected: - // Event handlers - void OnListEndLabelEdit(wxListEvent& event); - void OnListItemSelected(wxListEvent& event); - void OnListItemActivated(wxListEvent& event); - void OnButtonRename(wxCommandEvent& event); - void OnButtonNew(wxCommandEvent& event); - void OnButtonCopy(wxCommandEvent& event); - void OnButtonOK(wxCommandEvent& event); - void OnButtonCancel(wxCommandEvent& event); - void OnClose(wxCloseEvent& event); - -public: - /** Constructor */ - CYourAddressDialog(wxWindow* parent); - CYourAddressDialog(wxWindow* parent, const string& strInitSelected); - - // Custom - wxString GetAddress(); -}; - - - class CAddressBookDialog : public CAddressBookDialogBase { protected: // Event handlers + void OnNotebookPageChanged(wxNotebookEvent& event); void OnListEndLabelEdit(wxListEvent& event); void OnListItemSelected(wxListEvent& event); void OnListItemActivated(wxListEvent& event); - void OnButtonEdit(wxCommandEvent& event); void OnButtonDelete(wxCommandEvent& event); - void OnButtonNew(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, bool fSendingIn); + CAddressBookDialog(wxWindow* parent, const wxString& strInitSelected, int nPageIn, bool fDuringSendIn); // Custom - bool fSending; + enum + { + SENDING = 0, + RECEIVING = 1, + }; + int nPage; + wxListCtrl* m_listCtrl; + bool fDuringSend; wxString GetAddress(); + wxString GetSelectedAddress(); + wxString GetSelectedSendingAddress(); + wxString GetSelectedReceivingAddress(); bool CheckIfMine(const string& strAddress, const string& strTitle); }; @@ -282,18 +267,25 @@ public: const string& strMessage2="", const 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); - SetSize(wxDefaultCoord, 180); + y += 46 + wxString(strMessage2).Freq('\n') * 14; } if (!fWindows) - SetSize(1.14 * GetSize().GetWidth(), 1.14 * GetSize().GetHeight()); + { + x *= 1.14; + y *= 1.14; + } + SetSize(x, y); } // Custom diff --git a/uibase.cpp b/uibase.cpp index 5b3f9abc22..340c7abcd4 100644 --- a/uibase.cpp +++ b/uibase.cpp @@ -42,14 +42,14 @@ CMainFrameBase::CMainFrameBase( wxWindow* parent, wxWindowID id, const wxString& m_menuOptions->Append( m_menuOptionsGenerateBitcoins ); wxMenuItem* m_menuOptionsChangeYourAddress; - m_menuOptionsChangeYourAddress = new wxMenuItem( m_menuOptions, wxID_ANY, wxString( _("&Change Your Address...") ) , wxEmptyString, wxITEM_NORMAL ); + 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_MENUOPTIONSOPTIONS, wxString( _("&Options...") ) , wxEmptyString, wxITEM_NORMAL ); m_menuOptions->Append( m_menuOptionsOptions ); - m_menubar->Append( m_menuOptions, _("&Options") ); + m_menubar->Append( m_menuOptions, _("&Settings") ); m_menuHelp = new wxMenu(); wxMenuItem* m_menuHelpAbout; @@ -65,8 +65,8 @@ CMainFrameBase::CMainFrameBase( wxWindow* parent, wxWindowID id, const wxString& 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->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 ); @@ -86,14 +86,10 @@ CMainFrameBase::CMainFrameBase( wxWindow* parent, wxWindowID id, const wxString& bSizer85->Add( m_staticText32, 0, wxALIGN_CENTER_VERTICAL|wxLEFT, 5 ); m_textCtrlAddress = new wxTextCtrl( this, wxID_TEXTCTRLADDRESS, wxEmptyString, wxDefaultPosition, wxSize( 340,-1 ), wxTE_READONLY ); - m_textCtrlAddress->SetBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_MENU ) ); - bSizer85->Add( m_textCtrlAddress, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 ); - m_buttonNew = new wxButton( this, wxID_BUTTONCHANGE, _("&New..."), wxDefaultPosition, wxDefaultSize, 0 ); - m_buttonNew->Hide(); - - bSizer85->Add( m_buttonNew, 0, wxRIGHT, 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 ); @@ -188,7 +184,7 @@ CMainFrameBase::CMainFrameBase( wxWindow* parent, wxWindowID id, const wxString& 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::OnButtonChange ), 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_listCtrl->Connect( wxEVT_COMMAND_LIST_COL_BEGIN_DRAG, wxListEventHandler( CMainFrameBase::OnListColBeginDrag ), NULL, this ); m_listCtrl->Connect( wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler( CMainFrameBase::OnListItemActivated ), NULL, this ); @@ -240,7 +236,7 @@ CMainFrameBase::~CMainFrameBase() 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::OnButtonChange ), 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_listCtrl->Disconnect( wxEVT_COMMAND_LIST_COL_BEGIN_DRAG, wxListEventHandler( CMainFrameBase::OnListColBeginDrag ), NULL, this ); m_listCtrl->Disconnect( wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler( CMainFrameBase::OnListItemActivated ), NULL, this ); @@ -844,20 +840,53 @@ CAddressBookDialogBase::CAddressBookDialogBase( wxWindow* parent, wxWindowID id, { 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, 5, 0, wxEXPAND, 5 ); + bSizer68->Add( 0, 0, 0, wxEXPAND, 5 ); - m_staticText55 = new wxStaticText( this, wxID_ANY, _("Bitcoin Address"), wxDefaultPosition, wxDefaultSize, 0 ); + 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_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 ); + 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 ); @@ -865,34 +894,42 @@ CAddressBookDialogBase::CAddressBookDialogBase( wxWindow* parent, wxWindowID id, 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_buttonDelete = new wxButton( this, wxID_BUTTONDELETE, _("&Delete"), wxDefaultPosition, wxDefaultSize, 0 ); - bSizer69->Add( m_buttonDelete, 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 ); - bSizer68->Add( bSizer69, 0, wxEXPAND, 5 ); + bSizer58->Add( bSizer69, 0, wxEXPAND, 5 ); - this->SetSizer( bSizer68 ); + this->SetSizer( bSizer58 ); this->Layout(); // Connect Events this->Connect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( CAddressBookDialogBase::OnClose ) ); - m_listCtrl->Connect( wxEVT_COMMAND_LIST_END_LABEL_EDIT, wxListEventHandler( CAddressBookDialogBase::OnListEndLabelEdit ), NULL, this ); - m_listCtrl->Connect( wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler( CAddressBookDialogBase::OnListItemActivated ), NULL, this ); - m_listCtrl->Connect( wxEVT_COMMAND_LIST_ITEM_SELECTED, wxListEventHandler( CAddressBookDialogBase::OnListItemSelected ), NULL, this ); + 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_buttonDelete->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CAddressBookDialogBase::OnButtonDelete ), 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 ); } @@ -901,12 +938,17 @@ CAddressBookDialogBase::~CAddressBookDialogBase() { // Disconnect Events this->Disconnect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( CAddressBookDialogBase::OnClose ) ); - m_listCtrl->Disconnect( wxEVT_COMMAND_LIST_END_LABEL_EDIT, wxListEventHandler( CAddressBookDialogBase::OnListEndLabelEdit ), NULL, this ); - m_listCtrl->Disconnect( wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler( CAddressBookDialogBase::OnListItemActivated ), NULL, this ); - m_listCtrl->Disconnect( wxEVT_COMMAND_LIST_ITEM_SELECTED, wxListEventHandler( CAddressBookDialogBase::OnListItemSelected ), NULL, this ); + 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_buttonDelete->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CAddressBookDialogBase::OnButtonDelete ), 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 ); } diff --git a/uibase.h b/uibase.h index 494ed10f7c..90abd00f1d 100644 --- a/uibase.h +++ b/uibase.h @@ -36,6 +36,7 @@ #include #include #include +#include /////////////////////////////////////////////////////////////////////////// @@ -46,7 +47,7 @@ #define wxID_BUTTONSEND 1004 #define wxID_BUTTONRECEIVE 1005 #define wxID_TEXTCTRLADDRESS 1006 -#define wxID_BUTTONCHANGE 1007 +#define wxID_BUTTONNEW 1007 #define wxID_BUTTONCOPY 1008 #define wxID_TRANSACTIONFEE 1009 #define wxID_PROXYIP 1010 @@ -58,10 +59,13 @@ #define wxID_CHOICETRANSFERTYPE 1016 #define wxID_LISTCTRL 1017 #define wxID_BUTTONRENAME 1018 -#define wxID_BUTTONNEW 1019 -#define wxID_BUTTONEDIT 1020 -#define wxID_BUTTONDELETE 1021 -#define wxID_TEXTCTRL 1022 +#define wxID_PANELSENDING 1019 +#define wxID_LISTCTRLSENDING 1020 +#define wxID_PANELRECEIVING 1021 +#define wxID_LISTCTRLRECEIVING 1022 +#define wxID_BUTTONDELETE 1023 +#define wxID_BUTTONEDIT 1024 +#define wxID_TEXTCTRL 1025 /////////////////////////////////////////////////////////////////////////////// /// Class CMainFrameBase @@ -79,7 +83,6 @@ class CMainFrameBase : public wxFrame wxStatusBar* m_statusBar; wxStaticText* m_staticText32; - wxTextCtrl* m_textCtrlAddress; wxButton* m_buttonNew; wxButton* m_buttonCopy; @@ -108,7 +111,7 @@ class CMainFrameBase : public wxFrame virtual void OnKeyDown( wxKeyEvent& event ){ event.Skip(); } virtual void OnMouseEventsAddress( wxMouseEvent& event ){ event.Skip(); } virtual void OnSetFocusAddress( wxFocusEvent& event ){ event.Skip(); } - virtual void OnButtonChange( wxCommandEvent& event ){ event.Skip(); } + virtual void OnButtonNew( wxCommandEvent& event ){ event.Skip(); } virtual void OnButtonCopy( wxCommandEvent& event ){ event.Skip(); } virtual void OnListColBeginDrag( wxListEvent& event ){ event.Skip(); } virtual void OnListItemActivated( wxListEvent& event ){ event.Skip(); } @@ -117,6 +120,7 @@ class CMainFrameBase : public wxFrame public: wxMenu* m_menuOptions; + wxTextCtrl* m_textCtrlAddress; wxListCtrl* m_listCtrl; CMainFrameBase( wxWindow* parent, wxWindowID id = wxID_MAINFRAME, const wxString& title = _("Bitcoin"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 712,484 ), long style = wxDEFAULT_FRAME_STYLE|wxRESIZE_BORDER|wxTAB_TRAVERSAL ); ~CMainFrameBase(); @@ -343,23 +347,33 @@ class CAddressBookDialogBase : public wxDialog private: protected: + wxNotebook* m_notebook; + wxPanel* m_panelSending; wxStaticText* m_staticText55; - wxListCtrl* m_listCtrl; + 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_buttonDelete; 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 OnButtonDelete( wxCommandEvent& event ){ event.Skip(); } virtual void OnButtonOK( wxCommandEvent& event ){ event.Skip(); } virtual void OnButtonCancel( wxCommandEvent& event ){ event.Skip(); } @@ -397,7 +411,7 @@ class CGetTextFromUserDialogBase : public wxDialog public: - CGetTextFromUserDialogBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxEmptyString, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 403,138 ), long style = wxDEFAULT_DIALOG_STYLE ); + 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(); }; diff --git a/uiproject.fbp b/uiproject.fbp index 988df2a9b9..113a15796a 100644 --- a/uiproject.fbp +++ b/uiproject.fbp @@ -155,7 +155,7 @@ - &Options + &Settings m_menuOptions public @@ -180,7 +180,7 @@ wxID_ANY wxITEM_NORMAL - &Change Your Address... + &Your Receiving Addresses... m_menuOptionsChangeYourAddress none @@ -276,7 +276,7 @@ xpm/send20.xpm; Load From File wxID_BUTTONSEND wxITEM_NORMAL - &Send Coins + Send Coins m_tool1 @@ -290,7 +290,7 @@ xpm/addressbook20.xpm; Load From File wxID_BUTTONRECEIVE wxITEM_NORMAL - &Address Book + Address Book m_tool2 @@ -426,7 +426,7 @@ wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT 0 - wxSYS_COLOUR_MENU + 1 @@ -437,7 +437,7 @@ 0 -1,-1 m_textCtrlAddress - protected + public 340,-1 wxTE_READONLY @@ -478,7 +478,7 @@ 5 - wxRIGHT + wxRIGHT|wxALIGN_CENTER_VERTICAL 0 @@ -487,22 +487,22 @@ 1 - 1 - wxID_BUTTONCHANGE - &New... + 0 + wxID_BUTTONNEW + &New... m_buttonNew protected - - + -1,-1 + wxBU_EXACTFIT - OnButtonChange + OnButtonNew @@ -4388,7 +4388,7 @@ 5 wxEXPAND 0 - + bSizer69 wxHORIZONTAL @@ -4721,89 +4721,29 @@ - bSizer68 + bSizer58 wxVERTICAL none 5 - wxEXPAND - 0 - - 5 - protected - 0 - - - - 5 - wxTOP|wxRIGHT|wxLEFT - 0 - - - - 1 - - - 1 - wxID_ANY - Bitcoin Address - - - m_staticText55 - protected - - - - - - - - - -1 - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALL|wxEXPAND + wxEXPAND|wxTOP|wxRIGHT|wxLEFT 1 - + + 1 0 - wxID_LISTCTRL + wxID_ANY - m_listCtrl + m_notebook protected - wxLC_NO_SORT_HEADER|wxLC_REPORT|wxLC_SORT_ASCENDING + @@ -4819,32 +4759,14 @@ - - - - - - - - - - - - OnListEndLabelEdit - - OnListItemActivated - - - - - OnListItemSelected - + OnNotebookPageChanged + @@ -4852,6 +4774,384 @@ + + + Sending + 0 + + + + 1 + + + 0 + wxID_PANELSENDING + + + m_panelSending + protected + + + + + + + wxTAB_TRAVERSAL + + + + + + + + + + + + + + + + + + + + + + + + + + bSizer68 + wxVERTICAL + none + + 5 + wxEXPAND + 0 + + 0 + protected + 0 + + + + 5 + wxTOP|wxRIGHT|wxLEFT + 0 + + + + 1 + + + 1 + wxID_ANY + Bitcoin Address + + + m_staticText55 + protected + + + + + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL|wxEXPAND + 1 + + + + 1 + + + 0 + wxID_LISTCTRLSENDING + + + m_listCtrlSending + protected + + + wxLC_NO_SORT_HEADER|wxLC_REPORT|wxLC_SORT_ASCENDING + + + + + + + + + + + + + + + + + + + + + + + + + + + OnListEndLabelEdit + + OnListItemActivated + + + + + OnListItemSelected + + + + + + + + + + + + + + + + + + + + + + Receiving + 1 + + + + 1 + + + 0 + wxID_PANELRECEIVING + + + m_panelReceiving + protected + + + + + + + wxTAB_TRAVERSAL + + + + + + + + + + + + + + + + + + + + + + + + + + bSizer681 + wxVERTICAL + none + + 5 + wxEXPAND + 0 + + 0 + protected + 0 + + + + 6 + wxTOP|wxRIGHT|wxLEFT + 0 + + + + 1 + + + 0 + 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. + + + m_staticText45 + protected + + + + + + + + + 570 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND + 0 + + 2 + protected + 0 + + + + 5 + wxALL|wxEXPAND + 1 + + + + 1 + + + 0 + wxID_LISTCTRLRECEIVING + + + m_listCtrlReceiving + protected + + + wxLC_NO_SORT_HEADER|wxLC_REPORT|wxLC_SORT_ASCENDING + + + + + + + + + + + + + + + + + + + + + + + + + + + OnListEndLabelEdit + + OnListItemActivated + + + + + OnListItemSelected + + + + + + + + + + + + + + + + + + + @@ -4885,11 +5185,11 @@ 0 - wxID_BUTTONEDIT - &Edit... + wxID_BUTTONDELETE + &Delete -1,-1 - m_buttonEdit + m_buttonDelete protected @@ -4899,7 +5199,7 @@ - OnButtonEdit + OnButtonDelete @@ -4937,11 +5237,63 @@ 0 - wxID_BUTTONNEW - &New Address... + wxID_BUTTONCOPY + &Copy to Clipboard -1,-1 - m_buttonNew + m_buttonCopy + protected + + -1,-1 + + + + + + + OnButtonCopy + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND + 0 + + + + 0 + 1 + + + 0 + wxID_BUTTONEDIT + &Edit... + + -1,-1 + m_buttonEdit protected @@ -4951,7 +5303,7 @@ - OnButtonNew + OnButtonEdit @@ -4989,11 +5341,11 @@ 0 - wxID_BUTTONDELETE - &Delete + wxID_BUTTONNEW + &New Address... -1,-1 - m_buttonDelete + m_buttonNew protected @@ -5003,7 +5355,7 @@ - OnButtonDelete + OnButtonNew @@ -5151,7 +5503,7 @@ CGetTextFromUserDialogBase - 403,138 + 440,138 wxDEFAULT_DIALOG_STYLE diff --git a/util.cpp b/util.cpp index f4ce556643..40f7af343b 100644 --- a/util.cpp +++ b/util.cpp @@ -445,10 +445,14 @@ const char* wxGetTranslation(const char* pszEnglish) // wxWidgets translation const char* pszTranslated = wxGetTranslation(wxString(pszEnglish, wxConvUTF8)).utf8_str(); + + // 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, pszTranslated) == 0) return pszEnglish; - // Add to cache, memory doesn't need to be freed + // 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(pszTranslated)+1]; strcpy(pszCached, pszTranslated); mapCache[pszEnglish] = pszCached; -- cgit v1.2.3 From ee618d7540107aef543a0b252509b3005a15409c Mon Sep 17 00:00:00 2001 From: s_nakamoto Date: Sun, 21 Feb 2010 21:42:01 +0000 Subject: transaction filter tabs instead of view->show generated -- version 0.2.5 --- build-unix.txt | 2 +- db.cpp | 2 - main.cpp | 4 +- serialize.h | 2 +- ui.cpp | 87 ++++++--- ui.h | 16 +- uibase.cpp | 92 ++++++++-- uibase.h | 67 +++---- uiproject.fbp | 553 ++++++++++++++++++++++++++++++++++++++++++++++++++++----- 9 files changed, 693 insertions(+), 132 deletions(-) diff --git a/build-unix.txt b/build-unix.txt index 5e3f574afb..395ac973a6 100644 --- a/build-unix.txt +++ b/build-unix.txt @@ -70,7 +70,7 @@ ldconfig Boost ----- If you want to build Boost yourself, -cd /usr/local/boost_1_42_0 +cd /usr/local/boost_1_38_0 su ./bootstrap.sh ./bjam install diff --git a/db.cpp b/db.cpp index bbf24a0e70..51cbb309b4 100644 --- a/db.cpp +++ b/db.cpp @@ -599,7 +599,6 @@ bool CWalletDB::LoadWallet(vector& vchDefaultKeyRet) ssKey >> strKey; // Menu state - if (strKey == "fShowGenerated") ssValue >> fShowGenerated; if (strKey == "fGenerateBitcoins") ssValue >> fGenerateBitcoins; // Options @@ -618,7 +617,6 @@ bool CWalletDB::LoadWallet(vector& vchDefaultKeyRet) } printf("nFileVersion = %d\n", nFileVersion); - printf("fShowGenerated = %d\n", fShowGenerated); printf("fGenerateBitcoins = %d\n", fGenerateBitcoins); printf("nTransactionFee = %"PRI64d"\n", nTransactionFee); printf("addrIncoming = %s\n", addrIncoming.ToString().c_str()); diff --git a/main.cpp b/main.cpp index e5cc881bb2..56020a13ce 100644 --- a/main.cpp +++ b/main.cpp @@ -1335,7 +1335,9 @@ bool CBlock::AcceptBlock() if (!AddToBlockIndex(nFile, nBlockPos)) return error("AcceptBlock() : AddToBlockIndex failed"); - if (hashBestChain == hash && nBestHeight > 28000) + // Don't relay old inventory during initial block download. + // Please keep this constant updated to a few thousand below current block count. + if (hashBestChain == hash && nBestHeight > 40000) RelayInventory(CInv(MSG_BLOCK, hash)); // // Add atoms to user reviews for coins created diff --git a/serialize.h b/serialize.h index 23d61fe977..fb06f881ca 100644 --- a/serialize.h +++ b/serialize.h @@ -19,7 +19,7 @@ class CScript; class CDataStream; class CAutoFile; -static const int VERSION = 204; +static const int VERSION = 205; static const char* pszSubVer = ".0"; diff --git a/ui.cpp b/ui.cpp index 9bd34e0952..68d57b6c44 100644 --- a/ui.cpp +++ b/ui.cpp @@ -20,7 +20,6 @@ extern int g_isPainting; bool fClosedToTray = false; // Settings -int fShowGenerated = true; int fMinimizeToTray = true; int fMinimizeOnClose = true; @@ -282,6 +281,12 @@ 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; @@ -298,8 +303,8 @@ CMainFrame::CMainFrame(wxWindow* parent) : CMainFrameBase(parent) m_staticTextBalance->SetFont(fontTmp); m_staticTextBalance->SetSize(140, 17); // resize to fit ubuntu's huge default font - dResize = 1.20; - SetSize((dResize + 0.02) * GetSize().GetWidth(), 1.09 * GetSize().GetHeight()); + dResize = 1.22; + SetSize(dResize * GetSize().GetWidth(), 1.09 * GetSize().GetHeight()); #endif m_staticTextBalance->SetLabel(FormatMoney(GetBalance()) + " "); m_listCtrl->SetFocus(); @@ -309,13 +314,17 @@ CMainFrame::CMainFrame(wxWindow* parent) : CMainFrameBase(parent) int nDateWidth = DateTimeStr(1229413914).size() * 6 + 8; if (!strstr(DateTimeStr(1229413914).c_str(), "2008")) nDateWidth += 12; - m_listCtrl->InsertColumn(0, "", wxLIST_FORMAT_LEFT, dResize * 0); - m_listCtrl->InsertColumn(1, "", wxLIST_FORMAT_LEFT, dResize * 0); - m_listCtrl->InsertColumn(2, _("Status"), wxLIST_FORMAT_LEFT, dResize * 110); - m_listCtrl->InsertColumn(3, _("Date"), wxLIST_FORMAT_LEFT, dResize * nDateWidth); - m_listCtrl->InsertColumn(4, _("Description"), wxLIST_FORMAT_LEFT, dResize * 409 - nDateWidth); - m_listCtrl->InsertColumn(5, _("Debit"), wxLIST_FORMAT_RIGHT, dResize * 79); - m_listCtrl->InsertColumn(6, _("Credit"), wxLIST_FORMAT_RIGHT, dResize * 79); + wxListCtrl* pplistCtrl[] = {m_listCtrlAll, m_listCtrlSentReceived, m_listCtrlSent, m_listCtrlReceived}; + 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, 290 }; @@ -341,6 +350,42 @@ CMainFrame::~CMainFrame() 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()) @@ -547,7 +592,6 @@ bool CMainFrame::InsertTransaction(const CWalletTx& wtx, bool fNew, int nIndex) return false; } - // View->Show Generated if (!fShowGenerated) return false; } @@ -571,7 +615,6 @@ bool CMainFrame::InsertTransaction(const CWalletTx& wtx, bool fNew, int nIndex) // Credit // string strDescription; - if (wtx.IsCoinBase()) { // Generated @@ -598,6 +641,8 @@ bool CMainFrame::InsertTransaction(const CWalletTx& wtx, bool fNew, int nIndex) 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()) @@ -610,6 +655,8 @@ bool CMainFrame::InsertTransaction(const CWalletTx& wtx, bool fNew, int nIndex) else { // Received by Bitcoin Address + if (!fShowReceived) + return false; foreach(const CTxOut& txout, wtx.vout) { if (txout.IsMine()) @@ -675,6 +722,9 @@ bool CMainFrame::InsertTransaction(const CWalletTx& wtx, bool fNew, int nIndex) // // Debit // + if (!fShowSent) + return false; + int64 nTxFee = nDebit - wtx.GetValueOut(); wtx.nLinesDisplayed = 0; for (int nOut = 0; nOut < wtx.vout.size(); nOut++) @@ -1035,19 +1085,6 @@ void CMainFrame::OnMenuFileExit(wxCommandEvent& event) Close(true); } -void CMainFrame::OnMenuViewShowGenerated(wxCommandEvent& event) -{ - // View->Show Generated - fShowGenerated = event.IsChecked(); - CWalletDB().WriteSetting("fShowGenerated", fShowGenerated); - RefreshListCtrl(); -} - -void CMainFrame::OnUpdateUIViewShowGenerated(wxUpdateUIEvent& event) -{ - event.Check(fShowGenerated); -} - void CMainFrame::OnMenuOptionsGenerate(wxCommandEvent& event) { // Options->Generate Coins diff --git a/ui.h b/ui.h index 317b87e987..acabd5514a 100644 --- a/ui.h +++ b/ui.h @@ -8,7 +8,6 @@ DECLARE_EVENT_TYPE(wxEVT_UITHREADCALL, -1) extern map mapArgs; // Settings -extern int fShowGenerated; extern int fMinimizeToTray; extern int fMinimizeOnClose; @@ -31,6 +30,7 @@ class CMainFrame : public CMainFrameBase { protected: // Event handlers + void OnNotebookPageChanged(wxNotebookEvent& event); void OnClose(wxCloseEvent& event); void OnIconize(wxIconizeEvent& event); void OnMouseEvents(wxMouseEvent& event); @@ -39,8 +39,6 @@ protected: void OnPaint(wxPaintEvent& event); void OnPaintListCtrl(wxPaintEvent& event); void OnMenuFileExit(wxCommandEvent& event); - void OnMenuViewShowGenerated(wxCommandEvent& event); - void OnUpdateUIViewShowGenerated(wxUpdateUIEvent& event); void OnMenuOptionsGenerate(wxCommandEvent& event); void OnUpdateUIOptionsGenerate(wxUpdateUIEvent& event); void OnMenuOptionsChangeYourAddress(wxCommandEvent& event); @@ -64,6 +62,18 @@ public: ~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; diff --git a/uibase.cpp b/uibase.cpp index 340c7abcd4..03ca13db92 100644 --- a/uibase.cpp +++ b/uibase.cpp @@ -29,13 +29,6 @@ CMainFrameBase::CMainFrameBase( wxWindow* parent, wxWindowID id, const wxString& m_menubar->Append( m_menuFile, _("&File") ); - m_menuView = new wxMenu(); - wxMenuItem* m_menuViewShowGenerated; - m_menuViewShowGenerated = new wxMenuItem( m_menuView, wxID_VIEWSHOWGENERATED, wxString( _("&Show Generated Coins") ) , wxEmptyString, wxITEM_CHECK ); - m_menuView->Append( m_menuViewShowGenerated ); - - m_menubar->Append( m_menuView, _("&View") ); - m_menuOptions = new wxMenu(); wxMenuItem* m_menuOptionsGenerateBitcoins; m_menuOptionsGenerateBitcoins = new wxMenuItem( m_menuOptions, wxID_OPTIONSGENERATEBITCOINS, wxString( _("&Generate Coins") ) , wxEmptyString, wxITEM_CHECK ); @@ -135,8 +128,53 @@ CMainFrameBase::CMainFrameBase( wxWindow* parent, wxWindowID id, const wxString& bSizer2->Add( bSizer3, 0, wxEXPAND, 5 ); - m_listCtrl = new wxListCtrl( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_NO_SORT_HEADER|wxLC_REPORT|wxLC_SORT_DESCENDING|wxVSCROLL ); - bSizer2->Add( m_listCtrl, 1, 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|wxVSCROLL ); + 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|wxVSCROLL ); + 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|wxVSCROLL ); + 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|wxVSCROLL ); + 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(); @@ -160,8 +198,6 @@ CMainFrameBase::CMainFrameBase( wxWindow* parent, wxWindowID id, const wxString& 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_menuViewShowGenerated->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( CMainFrameBase::OnMenuViewShowGenerated ) ); - this->Connect( m_menuViewShowGenerated->GetId(), wxEVT_UPDATE_UI, wxUpdateUIEventHandler( CMainFrameBase::OnUpdateUIViewShowGenerated ) ); this->Connect( m_menuOptionsGenerateBitcoins->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( CMainFrameBase::OnMenuOptionsGenerate ) ); this->Connect( m_menuOptionsGenerateBitcoins->GetId(), wxEVT_UPDATE_UI, wxUpdateUIEventHandler( CMainFrameBase::OnUpdateUIOptionsGenerate ) ); this->Connect( m_menuOptionsChangeYourAddress->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( CMainFrameBase::OnMenuOptionsChangeYourAddress ) ); @@ -186,9 +222,19 @@ CMainFrameBase::CMainFrameBase( wxWindow* parent, wxWindowID id, const wxString& 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_listCtrl->Connect( wxEVT_COMMAND_LIST_COL_BEGIN_DRAG, wxListEventHandler( CMainFrameBase::OnListColBeginDrag ), NULL, this ); - m_listCtrl->Connect( wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler( CMainFrameBase::OnListItemActivated ), NULL, this ); - m_listCtrl->Connect( wxEVT_PAINT, wxPaintEventHandler( CMainFrameBase::OnPaintListCtrl ), 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() @@ -212,8 +258,6 @@ CMainFrameBase::~CMainFrameBase() 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::OnMenuViewShowGenerated ) ); - this->Disconnect( wxID_ANY, wxEVT_UPDATE_UI, wxUpdateUIEventHandler( CMainFrameBase::OnUpdateUIViewShowGenerated ) ); this->Disconnect( wxID_ANY, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( CMainFrameBase::OnMenuOptionsGenerate ) ); this->Disconnect( wxID_ANY, wxEVT_UPDATE_UI, wxUpdateUIEventHandler( CMainFrameBase::OnUpdateUIOptionsGenerate ) ); this->Disconnect( wxID_ANY, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( CMainFrameBase::OnMenuOptionsChangeYourAddress ) ); @@ -238,9 +282,19 @@ CMainFrameBase::~CMainFrameBase() 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_listCtrl->Disconnect( wxEVT_COMMAND_LIST_COL_BEGIN_DRAG, wxListEventHandler( CMainFrameBase::OnListColBeginDrag ), NULL, this ); - m_listCtrl->Disconnect( wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler( CMainFrameBase::OnListItemActivated ), NULL, this ); - m_listCtrl->Disconnect( wxEVT_PAINT, wxPaintEventHandler( CMainFrameBase::OnPaintListCtrl ), 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 ) diff --git a/uibase.h b/uibase.h index 90abd00f1d..1686cbfa8b 100644 --- a/uibase.h +++ b/uibase.h @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include @@ -36,36 +37,34 @@ #include #include #include -#include /////////////////////////////////////////////////////////////////////////// #define wxID_MAINFRAME 1000 -#define wxID_VIEWSHOWGENERATED 1001 -#define wxID_OPTIONSGENERATEBITCOINS 1002 -#define wxID_MENUOPTIONSOPTIONS 1003 -#define wxID_BUTTONSEND 1004 -#define wxID_BUTTONRECEIVE 1005 -#define wxID_TEXTCTRLADDRESS 1006 -#define wxID_BUTTONNEW 1007 -#define wxID_BUTTONCOPY 1008 -#define wxID_TRANSACTIONFEE 1009 -#define wxID_PROXYIP 1010 -#define wxID_PROXYPORT 1011 -#define wxID_TEXTCTRLPAYTO 1012 -#define wxID_BUTTONPASTE 1013 -#define wxID_BUTTONADDRESSBOOK 1014 -#define wxID_TEXTCTRLAMOUNT 1015 -#define wxID_CHOICETRANSFERTYPE 1016 -#define wxID_LISTCTRL 1017 -#define wxID_BUTTONRENAME 1018 -#define wxID_PANELSENDING 1019 -#define wxID_LISTCTRLSENDING 1020 -#define wxID_PANELRECEIVING 1021 -#define wxID_LISTCTRLRECEIVING 1022 -#define wxID_BUTTONDELETE 1023 -#define wxID_BUTTONEDIT 1024 -#define wxID_TEXTCTRL 1025 +#define wxID_OPTIONSGENERATEBITCOINS 1001 +#define wxID_MENUOPTIONSOPTIONS 1002 +#define wxID_BUTTONSEND 1003 +#define wxID_BUTTONRECEIVE 1004 +#define wxID_TEXTCTRLADDRESS 1005 +#define wxID_BUTTONNEW 1006 +#define wxID_BUTTONCOPY 1007 +#define wxID_TRANSACTIONFEE 1008 +#define wxID_PROXYIP 1009 +#define wxID_PROXYPORT 1010 +#define wxID_TEXTCTRLPAYTO 1011 +#define wxID_BUTTONPASTE 1012 +#define wxID_BUTTONADDRESSBOOK 1013 +#define wxID_TEXTCTRLAMOUNT 1014 +#define wxID_CHOICETRANSFERTYPE 1015 +#define wxID_LISTCTRL 1016 +#define wxID_BUTTONRENAME 1017 +#define wxID_PANELSENDING 1018 +#define wxID_LISTCTRLSENDING 1019 +#define wxID_PANELRECEIVING 1020 +#define wxID_LISTCTRLRECEIVING 1021 +#define wxID_BUTTONDELETE 1022 +#define wxID_BUTTONEDIT 1023 +#define wxID_TEXTCTRL 1024 /////////////////////////////////////////////////////////////////////////////// /// Class CMainFrameBase @@ -77,7 +76,6 @@ class CMainFrameBase : public wxFrame protected: wxMenuBar* m_menubar; wxMenu* m_menuFile; - wxMenu* m_menuView; wxMenu* m_menuHelp; wxToolBar* m_toolBar; wxStatusBar* m_statusBar; @@ -91,6 +89,11 @@ class CMainFrameBase : public wxFrame 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(); } @@ -99,8 +102,6 @@ class CMainFrameBase : public wxFrame virtual void OnMouseEvents( wxMouseEvent& event ){ event.Skip(); } virtual void OnPaint( wxPaintEvent& event ){ event.Skip(); } virtual void OnMenuFileExit( wxCommandEvent& event ){ event.Skip(); } - virtual void OnMenuViewShowGenerated( wxCommandEvent& event ){ event.Skip(); } - virtual void OnUpdateUIViewShowGenerated( wxUpdateUIEvent& event ){ event.Skip(); } virtual void OnMenuOptionsGenerate( wxCommandEvent& event ){ event.Skip(); } virtual void OnUpdateUIOptionsGenerate( wxUpdateUIEvent& event ){ event.Skip(); } virtual void OnMenuOptionsChangeYourAddress( wxCommandEvent& event ){ event.Skip(); } @@ -113,6 +114,7 @@ class CMainFrameBase : public wxFrame 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(); } @@ -121,8 +123,11 @@ class CMainFrameBase : public wxFrame public: wxMenu* m_menuOptions; wxTextCtrl* m_textCtrlAddress; - wxListCtrl* m_listCtrl; - CMainFrameBase( wxWindow* parent, wxWindowID id = wxID_MAINFRAME, const wxString& title = _("Bitcoin"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 712,484 ), long style = wxDEFAULT_FRAME_STYLE|wxRESIZE_BORDER|wxTAB_TRAVERSAL ); + 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(); }; diff --git a/uiproject.fbp b/uiproject.fbp index 113a15796a..8643fbab49 100644 --- a/uiproject.fbp +++ b/uiproject.fbp @@ -18,7 +18,7 @@ 1 0 0 - + wxSYS_COLOUR_BTNFACE @@ -32,7 +32,7 @@ CMainFrameBase - 712,484 + 723,484 wxDEFAULT_FRAME_STYLE|wxRESIZE_BORDER Bitcoin @@ -134,26 +134,6 @@ - - &View - m_menuView - protected - - - 0 - 1 - - wxID_VIEWSHOWGENERATED - wxITEM_CHECK - &Show Generated Coins - m_menuViewShowGenerated - none - - - OnMenuViewShowGenerated - OnUpdateUIViewShowGenerated - - &Settings m_menuOptions @@ -346,7 +326,7 @@ - + bSizer2 wxVERTICAL @@ -824,8 +804,9 @@ 5 wxEXPAND 1 - + + 1 @@ -834,16 +815,16 @@ wxID_ANY - m_listCtrl - public + m_notebook + protected - wxLC_NO_SORT_HEADER|wxLC_REPORT|wxLC_SORT_DESCENDING + - wxVSCROLL + @@ -854,39 +835,513 @@ - - - - - OnListColBeginDrag - - - - - - - - - OnListItemActivated - - - - - - - OnPaintListCtrl + OnNotebookPageChanged + + + + + All Transactions + 1 + + + + 1 + + + 0 + wxID_ANY + + + m_panel9 + protected + + + + + + + wxTAB_TRAVERSAL + + + + + + + + + + + + + + + + + + + + + + + + + + bSizer11 + wxVERTICAL + none + + 5 + wxEXPAND + 1 + + + + 1 + + + 0 + wxID_ANY + + + m_listCtrlAll + public + + + wxLC_NO_SORT_HEADER|wxLC_REPORT|wxLC_SORT_DESCENDING + + + + + wxVSCROLL + + + + + + + + + + + + + + + OnListColBeginDrag + + + + + + + + + OnListItemActivated + + + + + + + + + + + + + OnPaintListCtrl + + + + + + + + + + + + + + Sent/Received + 0 + + + + 1 + + + 0 + wxID_ANY + + + m_panel91 + protected + + + + + + + wxTAB_TRAVERSAL + + + + + + + + + + + + + + + + + + + + + + + + + + bSizer111 + wxVERTICAL + none + + 5 + wxEXPAND + 1 + + + + 1 + + + 0 + wxID_ANY + + + m_listCtrlSentReceived + public + + + wxLC_NO_SORT_HEADER|wxLC_REPORT|wxLC_SORT_DESCENDING + + + + + wxVSCROLL + + + + + + + + + + + + + + + OnListColBeginDrag + + + + + + + + + OnListItemActivated + + + + + + + + + + + + + OnPaintListCtrl + + + + + + + + + + + + + + Sent + 0 + + + + 1 + + + 0 + wxID_ANY + + + m_panel92 + protected + + + + + + + wxTAB_TRAVERSAL + + + + + + + + + + + + + + + + + + + + + + + + + + bSizer112 + wxVERTICAL + none + + 5 + wxEXPAND + 1 + + + + 1 + + + 0 + wxID_ANY + + + m_listCtrlSent + public + + + wxLC_NO_SORT_HEADER|wxLC_REPORT|wxLC_SORT_DESCENDING + + + + + wxVSCROLL + + + + + + + + + + + + + + + OnListColBeginDrag + + + + + + + + + OnListItemActivated + + + + + + + + + + + + + OnPaintListCtrl + + + + + + + + + + + + + + Received + 0 + + + + 1 + + + 0 + wxID_ANY + + + m_panel93 + protected + + + + + + + wxTAB_TRAVERSAL + + + + + + + + + + + + + + + + + + + + + + + + + + bSizer113 + wxVERTICAL + none + + 5 + wxEXPAND + 1 + + + + 1 + + + 0 + wxID_ANY + + + m_listCtrlReceived + public + + + wxLC_NO_SORT_HEADER|wxLC_REPORT|wxLC_SORT_DESCENDING + + + + + wxVSCROLL + + + + + + + + + + + + + + + OnListColBeginDrag + + + + + + + + + OnListItemActivated + + + + + + + + + + + + + OnPaintListCtrl + + + + + + + + + + + -- cgit v1.2.3 From 0184604aaf21f8279df9ecbee7be4fbf0bbf99c1 Mon Sep 17 00:00:00 2001 From: s_nakamoto Date: Sun, 21 Feb 2010 21:42:01 +0000 Subject: transaction filter tabs instead of view->show generated -- version 0.2.5 git-svn-id: https://bitcoin.svn.sourceforge.net/svnroot/bitcoin/trunk@69 1a98c847-1fd6-4fd8-948a-caf3550aa51b --- build-unix.txt | 2 +- db.cpp | 2 - main.cpp | 4 +- serialize.h | 2 +- ui.cpp | 87 ++++++--- ui.h | 16 +- uibase.cpp | 92 ++++++++-- uibase.h | 67 +++---- uiproject.fbp | 553 ++++++++++++++++++++++++++++++++++++++++++++++++++++----- 9 files changed, 693 insertions(+), 132 deletions(-) diff --git a/build-unix.txt b/build-unix.txt index 5e3f574afb..395ac973a6 100644 --- a/build-unix.txt +++ b/build-unix.txt @@ -70,7 +70,7 @@ ldconfig Boost ----- If you want to build Boost yourself, -cd /usr/local/boost_1_42_0 +cd /usr/local/boost_1_38_0 su ./bootstrap.sh ./bjam install diff --git a/db.cpp b/db.cpp index bbf24a0e70..51cbb309b4 100644 --- a/db.cpp +++ b/db.cpp @@ -599,7 +599,6 @@ bool CWalletDB::LoadWallet(vector& vchDefaultKeyRet) ssKey >> strKey; // Menu state - if (strKey == "fShowGenerated") ssValue >> fShowGenerated; if (strKey == "fGenerateBitcoins") ssValue >> fGenerateBitcoins; // Options @@ -618,7 +617,6 @@ bool CWalletDB::LoadWallet(vector& vchDefaultKeyRet) } printf("nFileVersion = %d\n", nFileVersion); - printf("fShowGenerated = %d\n", fShowGenerated); printf("fGenerateBitcoins = %d\n", fGenerateBitcoins); printf("nTransactionFee = %"PRI64d"\n", nTransactionFee); printf("addrIncoming = %s\n", addrIncoming.ToString().c_str()); diff --git a/main.cpp b/main.cpp index e5cc881bb2..56020a13ce 100644 --- a/main.cpp +++ b/main.cpp @@ -1335,7 +1335,9 @@ bool CBlock::AcceptBlock() if (!AddToBlockIndex(nFile, nBlockPos)) return error("AcceptBlock() : AddToBlockIndex failed"); - if (hashBestChain == hash && nBestHeight > 28000) + // Don't relay old inventory during initial block download. + // Please keep this constant updated to a few thousand below current block count. + if (hashBestChain == hash && nBestHeight > 40000) RelayInventory(CInv(MSG_BLOCK, hash)); // // Add atoms to user reviews for coins created diff --git a/serialize.h b/serialize.h index 23d61fe977..fb06f881ca 100644 --- a/serialize.h +++ b/serialize.h @@ -19,7 +19,7 @@ class CScript; class CDataStream; class CAutoFile; -static const int VERSION = 204; +static const int VERSION = 205; static const char* pszSubVer = ".0"; diff --git a/ui.cpp b/ui.cpp index 9bd34e0952..68d57b6c44 100644 --- a/ui.cpp +++ b/ui.cpp @@ -20,7 +20,6 @@ extern int g_isPainting; bool fClosedToTray = false; // Settings -int fShowGenerated = true; int fMinimizeToTray = true; int fMinimizeOnClose = true; @@ -282,6 +281,12 @@ 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; @@ -298,8 +303,8 @@ CMainFrame::CMainFrame(wxWindow* parent) : CMainFrameBase(parent) m_staticTextBalance->SetFont(fontTmp); m_staticTextBalance->SetSize(140, 17); // resize to fit ubuntu's huge default font - dResize = 1.20; - SetSize((dResize + 0.02) * GetSize().GetWidth(), 1.09 * GetSize().GetHeight()); + dResize = 1.22; + SetSize(dResize * GetSize().GetWidth(), 1.09 * GetSize().GetHeight()); #endif m_staticTextBalance->SetLabel(FormatMoney(GetBalance()) + " "); m_listCtrl->SetFocus(); @@ -309,13 +314,17 @@ CMainFrame::CMainFrame(wxWindow* parent) : CMainFrameBase(parent) int nDateWidth = DateTimeStr(1229413914).size() * 6 + 8; if (!strstr(DateTimeStr(1229413914).c_str(), "2008")) nDateWidth += 12; - m_listCtrl->InsertColumn(0, "", wxLIST_FORMAT_LEFT, dResize * 0); - m_listCtrl->InsertColumn(1, "", wxLIST_FORMAT_LEFT, dResize * 0); - m_listCtrl->InsertColumn(2, _("Status"), wxLIST_FORMAT_LEFT, dResize * 110); - m_listCtrl->InsertColumn(3, _("Date"), wxLIST_FORMAT_LEFT, dResize * nDateWidth); - m_listCtrl->InsertColumn(4, _("Description"), wxLIST_FORMAT_LEFT, dResize * 409 - nDateWidth); - m_listCtrl->InsertColumn(5, _("Debit"), wxLIST_FORMAT_RIGHT, dResize * 79); - m_listCtrl->InsertColumn(6, _("Credit"), wxLIST_FORMAT_RIGHT, dResize * 79); + wxListCtrl* pplistCtrl[] = {m_listCtrlAll, m_listCtrlSentReceived, m_listCtrlSent, m_listCtrlReceived}; + 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, 290 }; @@ -341,6 +350,42 @@ CMainFrame::~CMainFrame() 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()) @@ -547,7 +592,6 @@ bool CMainFrame::InsertTransaction(const CWalletTx& wtx, bool fNew, int nIndex) return false; } - // View->Show Generated if (!fShowGenerated) return false; } @@ -571,7 +615,6 @@ bool CMainFrame::InsertTransaction(const CWalletTx& wtx, bool fNew, int nIndex) // Credit // string strDescription; - if (wtx.IsCoinBase()) { // Generated @@ -598,6 +641,8 @@ bool CMainFrame::InsertTransaction(const CWalletTx& wtx, bool fNew, int nIndex) 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()) @@ -610,6 +655,8 @@ bool CMainFrame::InsertTransaction(const CWalletTx& wtx, bool fNew, int nIndex) else { // Received by Bitcoin Address + if (!fShowReceived) + return false; foreach(const CTxOut& txout, wtx.vout) { if (txout.IsMine()) @@ -675,6 +722,9 @@ bool CMainFrame::InsertTransaction(const CWalletTx& wtx, bool fNew, int nIndex) // // Debit // + if (!fShowSent) + return false; + int64 nTxFee = nDebit - wtx.GetValueOut(); wtx.nLinesDisplayed = 0; for (int nOut = 0; nOut < wtx.vout.size(); nOut++) @@ -1035,19 +1085,6 @@ void CMainFrame::OnMenuFileExit(wxCommandEvent& event) Close(true); } -void CMainFrame::OnMenuViewShowGenerated(wxCommandEvent& event) -{ - // View->Show Generated - fShowGenerated = event.IsChecked(); - CWalletDB().WriteSetting("fShowGenerated", fShowGenerated); - RefreshListCtrl(); -} - -void CMainFrame::OnUpdateUIViewShowGenerated(wxUpdateUIEvent& event) -{ - event.Check(fShowGenerated); -} - void CMainFrame::OnMenuOptionsGenerate(wxCommandEvent& event) { // Options->Generate Coins diff --git a/ui.h b/ui.h index 317b87e987..acabd5514a 100644 --- a/ui.h +++ b/ui.h @@ -8,7 +8,6 @@ DECLARE_EVENT_TYPE(wxEVT_UITHREADCALL, -1) extern map mapArgs; // Settings -extern int fShowGenerated; extern int fMinimizeToTray; extern int fMinimizeOnClose; @@ -31,6 +30,7 @@ class CMainFrame : public CMainFrameBase { protected: // Event handlers + void OnNotebookPageChanged(wxNotebookEvent& event); void OnClose(wxCloseEvent& event); void OnIconize(wxIconizeEvent& event); void OnMouseEvents(wxMouseEvent& event); @@ -39,8 +39,6 @@ protected: void OnPaint(wxPaintEvent& event); void OnPaintListCtrl(wxPaintEvent& event); void OnMenuFileExit(wxCommandEvent& event); - void OnMenuViewShowGenerated(wxCommandEvent& event); - void OnUpdateUIViewShowGenerated(wxUpdateUIEvent& event); void OnMenuOptionsGenerate(wxCommandEvent& event); void OnUpdateUIOptionsGenerate(wxUpdateUIEvent& event); void OnMenuOptionsChangeYourAddress(wxCommandEvent& event); @@ -64,6 +62,18 @@ public: ~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; diff --git a/uibase.cpp b/uibase.cpp index 340c7abcd4..03ca13db92 100644 --- a/uibase.cpp +++ b/uibase.cpp @@ -29,13 +29,6 @@ CMainFrameBase::CMainFrameBase( wxWindow* parent, wxWindowID id, const wxString& m_menubar->Append( m_menuFile, _("&File") ); - m_menuView = new wxMenu(); - wxMenuItem* m_menuViewShowGenerated; - m_menuViewShowGenerated = new wxMenuItem( m_menuView, wxID_VIEWSHOWGENERATED, wxString( _("&Show Generated Coins") ) , wxEmptyString, wxITEM_CHECK ); - m_menuView->Append( m_menuViewShowGenerated ); - - m_menubar->Append( m_menuView, _("&View") ); - m_menuOptions = new wxMenu(); wxMenuItem* m_menuOptionsGenerateBitcoins; m_menuOptionsGenerateBitcoins = new wxMenuItem( m_menuOptions, wxID_OPTIONSGENERATEBITCOINS, wxString( _("&Generate Coins") ) , wxEmptyString, wxITEM_CHECK ); @@ -135,8 +128,53 @@ CMainFrameBase::CMainFrameBase( wxWindow* parent, wxWindowID id, const wxString& bSizer2->Add( bSizer3, 0, wxEXPAND, 5 ); - m_listCtrl = new wxListCtrl( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_NO_SORT_HEADER|wxLC_REPORT|wxLC_SORT_DESCENDING|wxVSCROLL ); - bSizer2->Add( m_listCtrl, 1, 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|wxVSCROLL ); + 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|wxVSCROLL ); + 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|wxVSCROLL ); + 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|wxVSCROLL ); + 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(); @@ -160,8 +198,6 @@ CMainFrameBase::CMainFrameBase( wxWindow* parent, wxWindowID id, const wxString& 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_menuViewShowGenerated->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( CMainFrameBase::OnMenuViewShowGenerated ) ); - this->Connect( m_menuViewShowGenerated->GetId(), wxEVT_UPDATE_UI, wxUpdateUIEventHandler( CMainFrameBase::OnUpdateUIViewShowGenerated ) ); this->Connect( m_menuOptionsGenerateBitcoins->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( CMainFrameBase::OnMenuOptionsGenerate ) ); this->Connect( m_menuOptionsGenerateBitcoins->GetId(), wxEVT_UPDATE_UI, wxUpdateUIEventHandler( CMainFrameBase::OnUpdateUIOptionsGenerate ) ); this->Connect( m_menuOptionsChangeYourAddress->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( CMainFrameBase::OnMenuOptionsChangeYourAddress ) ); @@ -186,9 +222,19 @@ CMainFrameBase::CMainFrameBase( wxWindow* parent, wxWindowID id, const wxString& 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_listCtrl->Connect( wxEVT_COMMAND_LIST_COL_BEGIN_DRAG, wxListEventHandler( CMainFrameBase::OnListColBeginDrag ), NULL, this ); - m_listCtrl->Connect( wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler( CMainFrameBase::OnListItemActivated ), NULL, this ); - m_listCtrl->Connect( wxEVT_PAINT, wxPaintEventHandler( CMainFrameBase::OnPaintListCtrl ), 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() @@ -212,8 +258,6 @@ CMainFrameBase::~CMainFrameBase() 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::OnMenuViewShowGenerated ) ); - this->Disconnect( wxID_ANY, wxEVT_UPDATE_UI, wxUpdateUIEventHandler( CMainFrameBase::OnUpdateUIViewShowGenerated ) ); this->Disconnect( wxID_ANY, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( CMainFrameBase::OnMenuOptionsGenerate ) ); this->Disconnect( wxID_ANY, wxEVT_UPDATE_UI, wxUpdateUIEventHandler( CMainFrameBase::OnUpdateUIOptionsGenerate ) ); this->Disconnect( wxID_ANY, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( CMainFrameBase::OnMenuOptionsChangeYourAddress ) ); @@ -238,9 +282,19 @@ CMainFrameBase::~CMainFrameBase() 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_listCtrl->Disconnect( wxEVT_COMMAND_LIST_COL_BEGIN_DRAG, wxListEventHandler( CMainFrameBase::OnListColBeginDrag ), NULL, this ); - m_listCtrl->Disconnect( wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler( CMainFrameBase::OnListItemActivated ), NULL, this ); - m_listCtrl->Disconnect( wxEVT_PAINT, wxPaintEventHandler( CMainFrameBase::OnPaintListCtrl ), 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 ) diff --git a/uibase.h b/uibase.h index 90abd00f1d..1686cbfa8b 100644 --- a/uibase.h +++ b/uibase.h @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include @@ -36,36 +37,34 @@ #include #include #include -#include /////////////////////////////////////////////////////////////////////////// #define wxID_MAINFRAME 1000 -#define wxID_VIEWSHOWGENERATED 1001 -#define wxID_OPTIONSGENERATEBITCOINS 1002 -#define wxID_MENUOPTIONSOPTIONS 1003 -#define wxID_BUTTONSEND 1004 -#define wxID_BUTTONRECEIVE 1005 -#define wxID_TEXTCTRLADDRESS 1006 -#define wxID_BUTTONNEW 1007 -#define wxID_BUTTONCOPY 1008 -#define wxID_TRANSACTIONFEE 1009 -#define wxID_PROXYIP 1010 -#define wxID_PROXYPORT 1011 -#define wxID_TEXTCTRLPAYTO 1012 -#define wxID_BUTTONPASTE 1013 -#define wxID_BUTTONADDRESSBOOK 1014 -#define wxID_TEXTCTRLAMOUNT 1015 -#define wxID_CHOICETRANSFERTYPE 1016 -#define wxID_LISTCTRL 1017 -#define wxID_BUTTONRENAME 1018 -#define wxID_PANELSENDING 1019 -#define wxID_LISTCTRLSENDING 1020 -#define wxID_PANELRECEIVING 1021 -#define wxID_LISTCTRLRECEIVING 1022 -#define wxID_BUTTONDELETE 1023 -#define wxID_BUTTONEDIT 1024 -#define wxID_TEXTCTRL 1025 +#define wxID_OPTIONSGENERATEBITCOINS 1001 +#define wxID_MENUOPTIONSOPTIONS 1002 +#define wxID_BUTTONSEND 1003 +#define wxID_BUTTONRECEIVE 1004 +#define wxID_TEXTCTRLADDRESS 1005 +#define wxID_BUTTONNEW 1006 +#define wxID_BUTTONCOPY 1007 +#define wxID_TRANSACTIONFEE 1008 +#define wxID_PROXYIP 1009 +#define wxID_PROXYPORT 1010 +#define wxID_TEXTCTRLPAYTO 1011 +#define wxID_BUTTONPASTE 1012 +#define wxID_BUTTONADDRESSBOOK 1013 +#define wxID_TEXTCTRLAMOUNT 1014 +#define wxID_CHOICETRANSFERTYPE 1015 +#define wxID_LISTCTRL 1016 +#define wxID_BUTTONRENAME 1017 +#define wxID_PANELSENDING 1018 +#define wxID_LISTCTRLSENDING 1019 +#define wxID_PANELRECEIVING 1020 +#define wxID_LISTCTRLRECEIVING 1021 +#define wxID_BUTTONDELETE 1022 +#define wxID_BUTTONEDIT 1023 +#define wxID_TEXTCTRL 1024 /////////////////////////////////////////////////////////////////////////////// /// Class CMainFrameBase @@ -77,7 +76,6 @@ class CMainFrameBase : public wxFrame protected: wxMenuBar* m_menubar; wxMenu* m_menuFile; - wxMenu* m_menuView; wxMenu* m_menuHelp; wxToolBar* m_toolBar; wxStatusBar* m_statusBar; @@ -91,6 +89,11 @@ class CMainFrameBase : public wxFrame 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(); } @@ -99,8 +102,6 @@ class CMainFrameBase : public wxFrame virtual void OnMouseEvents( wxMouseEvent& event ){ event.Skip(); } virtual void OnPaint( wxPaintEvent& event ){ event.Skip(); } virtual void OnMenuFileExit( wxCommandEvent& event ){ event.Skip(); } - virtual void OnMenuViewShowGenerated( wxCommandEvent& event ){ event.Skip(); } - virtual void OnUpdateUIViewShowGenerated( wxUpdateUIEvent& event ){ event.Skip(); } virtual void OnMenuOptionsGenerate( wxCommandEvent& event ){ event.Skip(); } virtual void OnUpdateUIOptionsGenerate( wxUpdateUIEvent& event ){ event.Skip(); } virtual void OnMenuOptionsChangeYourAddress( wxCommandEvent& event ){ event.Skip(); } @@ -113,6 +114,7 @@ class CMainFrameBase : public wxFrame 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(); } @@ -121,8 +123,11 @@ class CMainFrameBase : public wxFrame public: wxMenu* m_menuOptions; wxTextCtrl* m_textCtrlAddress; - wxListCtrl* m_listCtrl; - CMainFrameBase( wxWindow* parent, wxWindowID id = wxID_MAINFRAME, const wxString& title = _("Bitcoin"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 712,484 ), long style = wxDEFAULT_FRAME_STYLE|wxRESIZE_BORDER|wxTAB_TRAVERSAL ); + 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(); }; diff --git a/uiproject.fbp b/uiproject.fbp index 113a15796a..8643fbab49 100644 --- a/uiproject.fbp +++ b/uiproject.fbp @@ -18,7 +18,7 @@ 1 0 0 - + wxSYS_COLOUR_BTNFACE @@ -32,7 +32,7 @@ CMainFrameBase - 712,484 + 723,484 wxDEFAULT_FRAME_STYLE|wxRESIZE_BORDER Bitcoin @@ -134,26 +134,6 @@ - - &View - m_menuView - protected - - - 0 - 1 - - wxID_VIEWSHOWGENERATED - wxITEM_CHECK - &Show Generated Coins - m_menuViewShowGenerated - none - - - OnMenuViewShowGenerated - OnUpdateUIViewShowGenerated - - &Settings m_menuOptions @@ -346,7 +326,7 @@ - + bSizer2 wxVERTICAL @@ -824,8 +804,9 @@ 5 wxEXPAND 1 - + + 1 @@ -834,16 +815,16 @@ wxID_ANY - m_listCtrl - public + m_notebook + protected - wxLC_NO_SORT_HEADER|wxLC_REPORT|wxLC_SORT_DESCENDING + - wxVSCROLL + @@ -854,39 +835,513 @@ - - - - - OnListColBeginDrag - - - - - - - - - OnListItemActivated - - - - - - - OnPaintListCtrl + OnNotebookPageChanged + + + + + All Transactions + 1 + + + + 1 + + + 0 + wxID_ANY + + + m_panel9 + protected + + + + + + + wxTAB_TRAVERSAL + + + + + + + + + + + + + + + + + + + + + + + + + + bSizer11 + wxVERTICAL + none + + 5 + wxEXPAND + 1 + + + + 1 + + + 0 + wxID_ANY + + + m_listCtrlAll + public + + + wxLC_NO_SORT_HEADER|wxLC_REPORT|wxLC_SORT_DESCENDING + + + + + wxVSCROLL + + + + + + + + + + + + + + + OnListColBeginDrag + + + + + + + + + OnListItemActivated + + + + + + + + + + + + + OnPaintListCtrl + + + + + + + + + + + + + + Sent/Received + 0 + + + + 1 + + + 0 + wxID_ANY + + + m_panel91 + protected + + + + + + + wxTAB_TRAVERSAL + + + + + + + + + + + + + + + + + + + + + + + + + + bSizer111 + wxVERTICAL + none + + 5 + wxEXPAND + 1 + + + + 1 + + + 0 + wxID_ANY + + + m_listCtrlSentReceived + public + + + wxLC_NO_SORT_HEADER|wxLC_REPORT|wxLC_SORT_DESCENDING + + + + + wxVSCROLL + + + + + + + + + + + + + + + OnListColBeginDrag + + + + + + + + + OnListItemActivated + + + + + + + + + + + + + OnPaintListCtrl + + + + + + + + + + + + + + Sent + 0 + + + + 1 + + + 0 + wxID_ANY + + + m_panel92 + protected + + + + + + + wxTAB_TRAVERSAL + + + + + + + + + + + + + + + + + + + + + + + + + + bSizer112 + wxVERTICAL + none + + 5 + wxEXPAND + 1 + + + + 1 + + + 0 + wxID_ANY + + + m_listCtrlSent + public + + + wxLC_NO_SORT_HEADER|wxLC_REPORT|wxLC_SORT_DESCENDING + + + + + wxVSCROLL + + + + + + + + + + + + + + + OnListColBeginDrag + + + + + + + + + OnListItemActivated + + + + + + + + + + + + + OnPaintListCtrl + + + + + + + + + + + + + + Received + 0 + + + + 1 + + + 0 + wxID_ANY + + + m_panel93 + protected + + + + + + + wxTAB_TRAVERSAL + + + + + + + + + + + + + + + + + + + + + + + + + + bSizer113 + wxVERTICAL + none + + 5 + wxEXPAND + 1 + + + + 1 + + + 0 + wxID_ANY + + + m_listCtrlReceived + public + + + wxLC_NO_SORT_HEADER|wxLC_REPORT|wxLC_SORT_DESCENDING + + + + + wxVSCROLL + + + + + + + + + + + + + + + OnListColBeginDrag + + + + + + + + + OnListItemActivated + + + + + + + + + + + + + OnPaintListCtrl + + + + + + + + + + + -- cgit v1.2.3 From 30158c77e99a099cbdd556bacbac18b431c3870c Mon Sep 17 00:00:00 2001 From: s_nakamoto Date: Tue, 23 Feb 2010 22:01:39 +0000 Subject: run as daemon without GUI, hooked wxApp::Initialize to ignore gtk-init-check failure if no GUI, fork to daemonize, rpc getinfo, getconnectioncount, getbalance, getgenerate, setgenerate, -- version 0.2.6 --- main.cpp | 15 ++++--- main.h | 4 ++ rpc.cpp | 134 ++++++++++++++++++++++++++++++++++++++++++++++++++---------- serialize.h | 2 +- ui.cpp | 94 ++++++++++++++++++++++++++++++++++-------- util.cpp | 4 +- util.h | 1 + 7 files changed, 207 insertions(+), 47 deletions(-) diff --git a/main.cpp b/main.cpp index 56020a13ce..bd69de92a4 100644 --- a/main.cpp +++ b/main.cpp @@ -1315,11 +1315,10 @@ bool CBlock::AcceptBlock() if (nTime <= pindexPrev->GetMedianTimePast()) return error("AcceptBlock() : block's timestamp is too early"); - // Check that all transactions are finalized (starting around Mar 2010) - if (nBestHeight > 36000) - foreach(const CTransaction& tx, vtx) - if (!tx.IsFinal(nTime)) - return error("AcceptBlock() : contains a non-final transaction"); + // Check that all transactions are finalized + foreach(const CTransaction& tx, vtx) + if (!tx.IsFinal(nTime)) + return error("AcceptBlock() : contains a non-final transaction"); // Check proof of work if (nBits != GetNextWorkRequired(pindexPrev)) @@ -1336,7 +1335,7 @@ bool CBlock::AcceptBlock() return error("AcceptBlock() : AddToBlockIndex failed"); // Don't relay old inventory during initial block download. - // Please keep this constant updated to a few thousand below current block count. + // Please keep this number updated to a few thousand below current block count. if (hashBestChain == hash && nBestHeight > 40000) RelayInventory(CInv(MSG_BLOCK, hash)); @@ -1556,8 +1555,8 @@ bool LoadBlockIndex(bool fAllowNew) CTransaction txNew; txNew.vin.resize(1); txNew.vout.resize(1); - txNew.vin[0].scriptSig = CScript() << 486604799 << CBigNum(4) << vector((const unsigned char*)pszTimestamp, (const unsigned char*)pszTimestamp + strlen(pszTimestamp)); - txNew.vout[0].nValue = 50 * COIN; + txNew.vin[0].scriptSig = CScript() << 486604799 << CBigNum(4) << vector((const unsigned char*)pszTimestamp, (const unsigned char*)pszTimestamp + strlen(pszTimestamp)); + txNew.vout[0].nValue = 50 * COIN; CBigNum bnPubKey; bnPubKey.SetHex("0x5F1DF16B2B704C8A578D0BBAF74D385CDE12C11EE50455F3C438EF4C3FBCF649B6DE611FEAE06279A60939E028A8D65C10B73071A6F16719274855FEB0FD8A6704"); txNew.vout[0].scriptPubKey = CScript() << bnPubKey << OP_CHECKSIG; diff --git a/main.h b/main.h index 4027f87eb4..452ce85b63 100644 --- a/main.h +++ b/main.h @@ -1384,6 +1384,9 @@ public: CPrivKey vchPrivKey; int64 nTimeCreated; int64 nTimeExpires; + string strComment; + //// todo: add something to note what created it (user, getnewaddress, change) + //// maybe should have a map property map CWalletKey(int64 nTimeExpiresIn=0) { @@ -1398,6 +1401,7 @@ public: READWRITE(vchPrivKey); READWRITE(nTimeCreated); READWRITE(nTimeExpires); + READWRITE(strComment); ) }; diff --git a/rpc.cpp b/rpc.cpp index f4eef37f0c..7f3e71dbac 100644 --- a/rpc.cpp +++ b/rpc.cpp @@ -66,6 +66,17 @@ Value getblocknumber(const Array& params) } +Value getconnectioncount(const Array& params) +{ + if (params.size() != 0) + throw runtime_error( + "getconnectioncount (no parameters)\n" + "Returns the number of connections to other nodes."); + + return (int)vNodes.size(); +} + + Value getdifficulty(const Array& params) { if (params.size() != 0) @@ -85,6 +96,71 @@ Value getdifficulty(const Array& params) } +Value getbalance(const Array& params) +{ + if (params.size() != 0) + throw runtime_error( + "getbalance (no parameters)\n" + "Returns the server's available balance."); + + return ((double)GetBalance() / (double)COIN); +} + + +Value getgenerate(const Array& params) +{ + if (params.size() != 0) + throw runtime_error( + "getgenerate (no parameters)\n" + "Returns true or false."); + + return (bool)fGenerateBitcoins; +} + + +Value setgenerate(const Array& params) +{ + if (params.size() < 1 || params.size() > 2) + throw runtime_error( + "setgenerate [genproclimit]\n" + " is true or false to turn generation on or off.\n" + "Generation is limited to [genproclimit] processors, -1 is unlimited."); + + bool fGenerate = true; + if (params.size() > 0) + fGenerate = params[0].get_bool(); + + if (params.size() > 1) + { + int nGenProcLimit = params[1].get_int(); + fLimitProcessors = (nGenProcLimit != -1); + CWalletDB().WriteSetting("fLimitProcessors", fLimitProcessors); + if (nGenProcLimit != -1) + CWalletDB().WriteSetting("nLimitProcessors", nLimitProcessors = nGenProcLimit); + } + + GenerateBitcoins(fGenerate); + return Value::null; +} + + +Value getinfo(const Array& params) +{ + if (params.size() != 0) + throw runtime_error( + "getinfo (no parameters)"); + + Object obj; + obj.push_back(Pair("balance", (double)GetBalance() / (double)COIN)); + obj.push_back(Pair("blocks", (int)nBestHeight + 1)); + obj.push_back(Pair("connections", (int)vNodes.size())); + obj.push_back(Pair("proxy", (fUseProxy ? addrProxy.ToStringIPPort() : string()))); + obj.push_back(Pair("generate", (bool)fGenerateBitcoins)); + obj.push_back(Pair("genproclimit", (int)(fLimitProcessors ? nLimitProcessors : -1))); + return obj; +} + + Value getnewaddress(const Array& params) { if (params.size() > 1) @@ -102,8 +178,7 @@ Value getnewaddress(const Array& params) // Generate a new key that is added to wallet string strAddress = PubKeyToAddress(GenerateNewKey()); - if (params.size() > 0) - SetAddressBookName(strAddress, strLabel); + SetAddressBookName(strAddress, strLabel); return strAddress; } @@ -214,10 +289,10 @@ Value getallreceived(const Array& params) "getallreceived [minconf=1]\n" "[minconf] is the minimum number of confirmations before payments are included.\n" "Returns an array of objects containing:\n" - " \"address\" : bitcoin address\n" + " \"address\" : receiving address\n" " \"amount\" : total amount received by the address\n" - " \"conf\" : number of confirmations\n" - " \"label\" : the label set for this address when it was created by getnewaddress"); + " \"confirmations\" : number of confirmations of the most recent transaction included\n" + " \"label\" : the label of the receiving address"); // Minimum confirmations int nMinDepth = 1; @@ -235,18 +310,26 @@ Value getallreceived(const Array& params) continue; int nDepth = wtx.GetDepthInMainChain(); - if (nDepth >= nMinDepth) + if (nDepth < nMinDepth) + continue; + + // Filter out debits and payments to self, which may have change return + // we don't want to count. + int64 nCredit = wtx.GetCredit(true); + int64 nDebit = wtx.GetDebit(); + int64 nNet = nCredit - nDebit; + if (nNet <= 0) + continue; + + foreach(const CTxOut& txout, wtx.vout) { - foreach(const CTxOut& txout, wtx.vout) - { - uint160 hash160 = txout.scriptPubKey.GetBitcoinAddressHash160(); - if (hash160 == 0 || !mapPubKeys.count(hash160)) - continue; - - tallyitem& item = mapTally[hash160]; - item.nAmount += txout.nValue; - item.nConf = min(item.nConf, nDepth); - } + uint160 hash160 = txout.scriptPubKey.GetBitcoinAddressHash160(); + if (hash160 == 0 || !mapPubKeys.count(hash160)) + continue; + + tallyitem& item = mapTally[hash160]; + item.nAmount += txout.nValue; + item.nConf = min(item.nConf, nDepth); } } } @@ -264,10 +347,10 @@ Value getallreceived(const Array& params) strLabel = (*mi).second; Object obj; - obj.push_back(Pair("address", strAddress)); - obj.push_back(Pair("amount", (double)(*it).second.nAmount / (double)COIN)); - obj.push_back(Pair("conf", (*it).second.nConf)); - obj.push_back(Pair("label", strLabel)); + obj.push_back(Pair("address", strAddress)); + obj.push_back(Pair("amount", (double)(*it).second.nAmount / (double)COIN)); + obj.push_back(Pair("confirmations", (*it).second.nConf)); + obj.push_back(Pair("label", strLabel)); ret.push_back(obj); } } @@ -290,7 +373,12 @@ pair pCallTable[] = make_pair("stop", &stop), make_pair("getblockcount", &getblockcount), make_pair("getblocknumber", &getblocknumber), + make_pair("getconnectioncount", &getconnectioncount), make_pair("getdifficulty", &getdifficulty), + make_pair("getbalance", &getbalance), + make_pair("getgenerate", &getgenerate), + make_pair("setgenerate", &setgenerate), + make_pair("getinfo", &getinfo), make_pair("getnewaddress", &getnewaddress), make_pair("sendtoaddress", &sendtoaddress), make_pair("listtransactions", &listtransactions), @@ -568,9 +656,13 @@ int CommandLineRPC(int argc, char *argv[]) Array params; for (int i = 2; i < argc; i++) params.push_back(argv[i]); + int n = params.size(); + // // Special case other types - int n = params.size(); + // + if (strMethod == "setgenerate" && n > 0) ConvertTo(params[0]); + if (strMethod == "setgenerate" && n > 1) ConvertTo(params[1]); if (strMethod == "sendtoaddress" && n > 1) ConvertTo(params[1]); if (strMethod == "listtransactions" && n > 0) ConvertTo(params[0]); if (strMethod == "listtransactions" && n > 1) ConvertTo(params[1]); diff --git a/serialize.h b/serialize.h index fb06f881ca..8fb72a0aab 100644 --- a/serialize.h +++ b/serialize.h @@ -19,7 +19,7 @@ class CScript; class CDataStream; class CAutoFile; -static const int VERSION = 205; +static const int VERSION = 206; static const char* pszSubVer = ".0"; diff --git a/ui.cpp b/ui.cpp index 68d57b6c44..748b4dad93 100644 --- a/ui.cpp +++ b/ui.cpp @@ -26,6 +26,20 @@ int fMinimizeOnClose = true; +int MyMessageBox(const wxString& message, const wxString& caption="Message", int style=wxOK, wxWindow* parent=NULL, int x=-1, int y=-1) +{ + if (fDaemon) + { + printf("wxMessageBox %s: %s\n", string(caption).c_str(), string(message).c_str()); + fprintf(stderr, "%s: %s\n", string(caption).c_str(), string(message).c_str()); + return wxOK; + } + return wxMessageBox(message, caption, style, parent, x, y); +} +#define wxMessageBox MyMessageBox + + + @@ -209,16 +223,10 @@ void CalledMessageBox(const string& message, const string& caption, int style, w int ThreadSafeMessageBox(const string& message, const string& caption, int style, wxWindow* parent, int x, int y) { - if (fDaemon) - { - printf("wxMessageBox %s: %s\n", caption.c_str(), message.c_str()); - return wxOK; - } - #ifdef __WXMSW__ return wxMessageBox(message, caption, style, parent, x, y); #else - if (wxThread::IsMain()) + if (wxThread::IsMain() || fDaemon) { return wxMessageBox(message, caption, style, parent, x, y); } @@ -563,7 +571,7 @@ string SingleLine(const string& strIn) bool CMainFrame::InsertTransaction(const CWalletTx& wtx, bool fNew, int nIndex) { int64 nTime = wtx.nTimeDisplayed = wtx.GetTxTime(); - int64 nCredit = wtx.GetCredit(); + int64 nCredit = wtx.GetCredit(true); int64 nDebit = wtx.GetDebit(); int64 nNet = nCredit - nDebit; uint256 hash = wtx.GetHash(); @@ -2571,6 +2579,9 @@ public: 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(); @@ -2586,6 +2597,64 @@ public: IMPLEMENT_APP(CMyApp) +bool CMyApp::Initialize(int& argc, wxChar** argv) +{ + if (argc > 1 && argv[1][0] != '-' && (!fWindows || argv[1][0] != '/') && + wxString(argv[1]) != "start") + { + fCommandLine = true; + } + else + { + // 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] = '-'; + str = str.MakeLower(); + #endif + // haven't decided which argument to use for this yet + if (str == "-daemon" || str == "-d" || str == "start") + 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) + { + fprintf(stdout, "bitcoin server starting\n"); + + // 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); + } + + return true; + } +#endif + + return wxApp::Initialize(argc, argv); +} + bool CMyApp::OnInit() { bool fRet = false; @@ -2650,7 +2719,7 @@ bool CMyApp::OnInit2() // // Parameters // - if (argc > 1 && argv[1][0] != '-' && argv[1][0] != '/') + if (fCommandLine) { int ret = CommandLineRPC(argc, argv); exit(ret); @@ -2696,13 +2765,6 @@ bool CMyApp::OnInit2() if (mapArgs.count("-printtodebugger")) fPrintToDebugger = true; - if (mapArgs.count("-daemon") || mapArgs.count("-d")) - { - fDaemon = true; - /// todo: need to fork - /// should it fork after the bind/single instance stuff? - } - if (!fDebug && !pszSetDataDir[0]) ShrinkDebugFile(); printf("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"); diff --git a/util.cpp b/util.cpp index 40f7af343b..6ea735d1e2 100644 --- a/util.cpp +++ b/util.cpp @@ -13,6 +13,7 @@ bool fPrintToDebugger = false; char pszSetDataDir[MAX_PATH] = ""; bool fShutdown = false; bool fDaemon = false; +bool fCommandLine = false; @@ -500,7 +501,8 @@ void PrintException(std::exception* pex, const char* pszThread) char pszMessage[1000]; FormatException(pszMessage, pex, pszThread); printf("\n\n************************\n%s\n", pszMessage); - if (wxTheApp) + fprintf(stderr, "\n\n************************\n%s\n", pszMessage); + if (wxTheApp && !fDaemon) wxMessageBox(pszMessage, "Error", wxOK | wxICON_ERROR); throw; //DebugBreak(); diff --git a/util.h b/util.h index 8aed902f3f..75f0956f2d 100644 --- a/util.h +++ b/util.h @@ -121,6 +121,7 @@ extern bool fPrintToDebugger; extern char pszSetDataDir[MAX_PATH]; extern bool fShutdown; extern bool fDaemon; +extern bool fCommandLine; void RandAddSeed(); void RandAddSeedPerfmon(); -- cgit v1.2.3 From cb420a1dfc23d3c11c5281ed8f7ae003c2f61594 Mon Sep 17 00:00:00 2001 From: s_nakamoto Date: Tue, 23 Feb 2010 22:01:39 +0000 Subject: run as daemon without GUI, hooked wxApp::Initialize to ignore gtk-init-check failure if no GUI, fork to daemonize, rpc getinfo, getconnectioncount, getbalance, getgenerate, setgenerate, -- version 0.2.6 git-svn-id: https://bitcoin.svn.sourceforge.net/svnroot/bitcoin/trunk@70 1a98c847-1fd6-4fd8-948a-caf3550aa51b --- main.cpp | 15 ++++--- main.h | 4 ++ rpc.cpp | 134 ++++++++++++++++++++++++++++++++++++++++++++++++++---------- serialize.h | 2 +- ui.cpp | 94 ++++++++++++++++++++++++++++++++++-------- util.cpp | 4 +- util.h | 1 + 7 files changed, 207 insertions(+), 47 deletions(-) diff --git a/main.cpp b/main.cpp index 56020a13ce..bd69de92a4 100644 --- a/main.cpp +++ b/main.cpp @@ -1315,11 +1315,10 @@ bool CBlock::AcceptBlock() if (nTime <= pindexPrev->GetMedianTimePast()) return error("AcceptBlock() : block's timestamp is too early"); - // Check that all transactions are finalized (starting around Mar 2010) - if (nBestHeight > 36000) - foreach(const CTransaction& tx, vtx) - if (!tx.IsFinal(nTime)) - return error("AcceptBlock() : contains a non-final transaction"); + // Check that all transactions are finalized + foreach(const CTransaction& tx, vtx) + if (!tx.IsFinal(nTime)) + return error("AcceptBlock() : contains a non-final transaction"); // Check proof of work if (nBits != GetNextWorkRequired(pindexPrev)) @@ -1336,7 +1335,7 @@ bool CBlock::AcceptBlock() return error("AcceptBlock() : AddToBlockIndex failed"); // Don't relay old inventory during initial block download. - // Please keep this constant updated to a few thousand below current block count. + // Please keep this number updated to a few thousand below current block count. if (hashBestChain == hash && nBestHeight > 40000) RelayInventory(CInv(MSG_BLOCK, hash)); @@ -1556,8 +1555,8 @@ bool LoadBlockIndex(bool fAllowNew) CTransaction txNew; txNew.vin.resize(1); txNew.vout.resize(1); - txNew.vin[0].scriptSig = CScript() << 486604799 << CBigNum(4) << vector((const unsigned char*)pszTimestamp, (const unsigned char*)pszTimestamp + strlen(pszTimestamp)); - txNew.vout[0].nValue = 50 * COIN; + txNew.vin[0].scriptSig = CScript() << 486604799 << CBigNum(4) << vector((const unsigned char*)pszTimestamp, (const unsigned char*)pszTimestamp + strlen(pszTimestamp)); + txNew.vout[0].nValue = 50 * COIN; CBigNum bnPubKey; bnPubKey.SetHex("0x5F1DF16B2B704C8A578D0BBAF74D385CDE12C11EE50455F3C438EF4C3FBCF649B6DE611FEAE06279A60939E028A8D65C10B73071A6F16719274855FEB0FD8A6704"); txNew.vout[0].scriptPubKey = CScript() << bnPubKey << OP_CHECKSIG; diff --git a/main.h b/main.h index 4027f87eb4..452ce85b63 100644 --- a/main.h +++ b/main.h @@ -1384,6 +1384,9 @@ public: CPrivKey vchPrivKey; int64 nTimeCreated; int64 nTimeExpires; + string strComment; + //// todo: add something to note what created it (user, getnewaddress, change) + //// maybe should have a map property map CWalletKey(int64 nTimeExpiresIn=0) { @@ -1398,6 +1401,7 @@ public: READWRITE(vchPrivKey); READWRITE(nTimeCreated); READWRITE(nTimeExpires); + READWRITE(strComment); ) }; diff --git a/rpc.cpp b/rpc.cpp index f4eef37f0c..7f3e71dbac 100644 --- a/rpc.cpp +++ b/rpc.cpp @@ -66,6 +66,17 @@ Value getblocknumber(const Array& params) } +Value getconnectioncount(const Array& params) +{ + if (params.size() != 0) + throw runtime_error( + "getconnectioncount (no parameters)\n" + "Returns the number of connections to other nodes."); + + return (int)vNodes.size(); +} + + Value getdifficulty(const Array& params) { if (params.size() != 0) @@ -85,6 +96,71 @@ Value getdifficulty(const Array& params) } +Value getbalance(const Array& params) +{ + if (params.size() != 0) + throw runtime_error( + "getbalance (no parameters)\n" + "Returns the server's available balance."); + + return ((double)GetBalance() / (double)COIN); +} + + +Value getgenerate(const Array& params) +{ + if (params.size() != 0) + throw runtime_error( + "getgenerate (no parameters)\n" + "Returns true or false."); + + return (bool)fGenerateBitcoins; +} + + +Value setgenerate(const Array& params) +{ + if (params.size() < 1 || params.size() > 2) + throw runtime_error( + "setgenerate [genproclimit]\n" + " is true or false to turn generation on or off.\n" + "Generation is limited to [genproclimit] processors, -1 is unlimited."); + + bool fGenerate = true; + if (params.size() > 0) + fGenerate = params[0].get_bool(); + + if (params.size() > 1) + { + int nGenProcLimit = params[1].get_int(); + fLimitProcessors = (nGenProcLimit != -1); + CWalletDB().WriteSetting("fLimitProcessors", fLimitProcessors); + if (nGenProcLimit != -1) + CWalletDB().WriteSetting("nLimitProcessors", nLimitProcessors = nGenProcLimit); + } + + GenerateBitcoins(fGenerate); + return Value::null; +} + + +Value getinfo(const Array& params) +{ + if (params.size() != 0) + throw runtime_error( + "getinfo (no parameters)"); + + Object obj; + obj.push_back(Pair("balance", (double)GetBalance() / (double)COIN)); + obj.push_back(Pair("blocks", (int)nBestHeight + 1)); + obj.push_back(Pair("connections", (int)vNodes.size())); + obj.push_back(Pair("proxy", (fUseProxy ? addrProxy.ToStringIPPort() : string()))); + obj.push_back(Pair("generate", (bool)fGenerateBitcoins)); + obj.push_back(Pair("genproclimit", (int)(fLimitProcessors ? nLimitProcessors : -1))); + return obj; +} + + Value getnewaddress(const Array& params) { if (params.size() > 1) @@ -102,8 +178,7 @@ Value getnewaddress(const Array& params) // Generate a new key that is added to wallet string strAddress = PubKeyToAddress(GenerateNewKey()); - if (params.size() > 0) - SetAddressBookName(strAddress, strLabel); + SetAddressBookName(strAddress, strLabel); return strAddress; } @@ -214,10 +289,10 @@ Value getallreceived(const Array& params) "getallreceived [minconf=1]\n" "[minconf] is the minimum number of confirmations before payments are included.\n" "Returns an array of objects containing:\n" - " \"address\" : bitcoin address\n" + " \"address\" : receiving address\n" " \"amount\" : total amount received by the address\n" - " \"conf\" : number of confirmations\n" - " \"label\" : the label set for this address when it was created by getnewaddress"); + " \"confirmations\" : number of confirmations of the most recent transaction included\n" + " \"label\" : the label of the receiving address"); // Minimum confirmations int nMinDepth = 1; @@ -235,18 +310,26 @@ Value getallreceived(const Array& params) continue; int nDepth = wtx.GetDepthInMainChain(); - if (nDepth >= nMinDepth) + if (nDepth < nMinDepth) + continue; + + // Filter out debits and payments to self, which may have change return + // we don't want to count. + int64 nCredit = wtx.GetCredit(true); + int64 nDebit = wtx.GetDebit(); + int64 nNet = nCredit - nDebit; + if (nNet <= 0) + continue; + + foreach(const CTxOut& txout, wtx.vout) { - foreach(const CTxOut& txout, wtx.vout) - { - uint160 hash160 = txout.scriptPubKey.GetBitcoinAddressHash160(); - if (hash160 == 0 || !mapPubKeys.count(hash160)) - continue; - - tallyitem& item = mapTally[hash160]; - item.nAmount += txout.nValue; - item.nConf = min(item.nConf, nDepth); - } + uint160 hash160 = txout.scriptPubKey.GetBitcoinAddressHash160(); + if (hash160 == 0 || !mapPubKeys.count(hash160)) + continue; + + tallyitem& item = mapTally[hash160]; + item.nAmount += txout.nValue; + item.nConf = min(item.nConf, nDepth); } } } @@ -264,10 +347,10 @@ Value getallreceived(const Array& params) strLabel = (*mi).second; Object obj; - obj.push_back(Pair("address", strAddress)); - obj.push_back(Pair("amount", (double)(*it).second.nAmount / (double)COIN)); - obj.push_back(Pair("conf", (*it).second.nConf)); - obj.push_back(Pair("label", strLabel)); + obj.push_back(Pair("address", strAddress)); + obj.push_back(Pair("amount", (double)(*it).second.nAmount / (double)COIN)); + obj.push_back(Pair("confirmations", (*it).second.nConf)); + obj.push_back(Pair("label", strLabel)); ret.push_back(obj); } } @@ -290,7 +373,12 @@ pair pCallTable[] = make_pair("stop", &stop), make_pair("getblockcount", &getblockcount), make_pair("getblocknumber", &getblocknumber), + make_pair("getconnectioncount", &getconnectioncount), make_pair("getdifficulty", &getdifficulty), + make_pair("getbalance", &getbalance), + make_pair("getgenerate", &getgenerate), + make_pair("setgenerate", &setgenerate), + make_pair("getinfo", &getinfo), make_pair("getnewaddress", &getnewaddress), make_pair("sendtoaddress", &sendtoaddress), make_pair("listtransactions", &listtransactions), @@ -568,9 +656,13 @@ int CommandLineRPC(int argc, char *argv[]) Array params; for (int i = 2; i < argc; i++) params.push_back(argv[i]); + int n = params.size(); + // // Special case other types - int n = params.size(); + // + if (strMethod == "setgenerate" && n > 0) ConvertTo(params[0]); + if (strMethod == "setgenerate" && n > 1) ConvertTo(params[1]); if (strMethod == "sendtoaddress" && n > 1) ConvertTo(params[1]); if (strMethod == "listtransactions" && n > 0) ConvertTo(params[0]); if (strMethod == "listtransactions" && n > 1) ConvertTo(params[1]); diff --git a/serialize.h b/serialize.h index fb06f881ca..8fb72a0aab 100644 --- a/serialize.h +++ b/serialize.h @@ -19,7 +19,7 @@ class CScript; class CDataStream; class CAutoFile; -static const int VERSION = 205; +static const int VERSION = 206; static const char* pszSubVer = ".0"; diff --git a/ui.cpp b/ui.cpp index 68d57b6c44..748b4dad93 100644 --- a/ui.cpp +++ b/ui.cpp @@ -26,6 +26,20 @@ int fMinimizeOnClose = true; +int MyMessageBox(const wxString& message, const wxString& caption="Message", int style=wxOK, wxWindow* parent=NULL, int x=-1, int y=-1) +{ + if (fDaemon) + { + printf("wxMessageBox %s: %s\n", string(caption).c_str(), string(message).c_str()); + fprintf(stderr, "%s: %s\n", string(caption).c_str(), string(message).c_str()); + return wxOK; + } + return wxMessageBox(message, caption, style, parent, x, y); +} +#define wxMessageBox MyMessageBox + + + @@ -209,16 +223,10 @@ void CalledMessageBox(const string& message, const string& caption, int style, w int ThreadSafeMessageBox(const string& message, const string& caption, int style, wxWindow* parent, int x, int y) { - if (fDaemon) - { - printf("wxMessageBox %s: %s\n", caption.c_str(), message.c_str()); - return wxOK; - } - #ifdef __WXMSW__ return wxMessageBox(message, caption, style, parent, x, y); #else - if (wxThread::IsMain()) + if (wxThread::IsMain() || fDaemon) { return wxMessageBox(message, caption, style, parent, x, y); } @@ -563,7 +571,7 @@ string SingleLine(const string& strIn) bool CMainFrame::InsertTransaction(const CWalletTx& wtx, bool fNew, int nIndex) { int64 nTime = wtx.nTimeDisplayed = wtx.GetTxTime(); - int64 nCredit = wtx.GetCredit(); + int64 nCredit = wtx.GetCredit(true); int64 nDebit = wtx.GetDebit(); int64 nNet = nCredit - nDebit; uint256 hash = wtx.GetHash(); @@ -2571,6 +2579,9 @@ public: 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(); @@ -2586,6 +2597,64 @@ public: IMPLEMENT_APP(CMyApp) +bool CMyApp::Initialize(int& argc, wxChar** argv) +{ + if (argc > 1 && argv[1][0] != '-' && (!fWindows || argv[1][0] != '/') && + wxString(argv[1]) != "start") + { + fCommandLine = true; + } + else + { + // 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] = '-'; + str = str.MakeLower(); + #endif + // haven't decided which argument to use for this yet + if (str == "-daemon" || str == "-d" || str == "start") + 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) + { + fprintf(stdout, "bitcoin server starting\n"); + + // 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); + } + + return true; + } +#endif + + return wxApp::Initialize(argc, argv); +} + bool CMyApp::OnInit() { bool fRet = false; @@ -2650,7 +2719,7 @@ bool CMyApp::OnInit2() // // Parameters // - if (argc > 1 && argv[1][0] != '-' && argv[1][0] != '/') + if (fCommandLine) { int ret = CommandLineRPC(argc, argv); exit(ret); @@ -2696,13 +2765,6 @@ bool CMyApp::OnInit2() if (mapArgs.count("-printtodebugger")) fPrintToDebugger = true; - if (mapArgs.count("-daemon") || mapArgs.count("-d")) - { - fDaemon = true; - /// todo: need to fork - /// should it fork after the bind/single instance stuff? - } - if (!fDebug && !pszSetDataDir[0]) ShrinkDebugFile(); printf("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"); diff --git a/util.cpp b/util.cpp index 40f7af343b..6ea735d1e2 100644 --- a/util.cpp +++ b/util.cpp @@ -13,6 +13,7 @@ bool fPrintToDebugger = false; char pszSetDataDir[MAX_PATH] = ""; bool fShutdown = false; bool fDaemon = false; +bool fCommandLine = false; @@ -500,7 +501,8 @@ void PrintException(std::exception* pex, const char* pszThread) char pszMessage[1000]; FormatException(pszMessage, pex, pszThread); printf("\n\n************************\n%s\n", pszMessage); - if (wxTheApp) + fprintf(stderr, "\n\n************************\n%s\n", pszMessage); + if (wxTheApp && !fDaemon) wxMessageBox(pszMessage, "Error", wxOK | wxICON_ERROR); throw; //DebugBreak(); diff --git a/util.h b/util.h index 8aed902f3f..75f0956f2d 100644 --- a/util.h +++ b/util.h @@ -121,6 +121,7 @@ extern bool fPrintToDebugger; extern char pszSetDataDir[MAX_PATH]; extern bool fShutdown; extern bool fDaemon; +extern bool fCommandLine; void RandAddSeed(); void RandAddSeedPerfmon(); -- cgit v1.2.3 From 5eede9d4d9932969cd75a47dc0d6fd4c090f0342 Mon Sep 17 00:00:00 2001 From: s_nakamoto Date: Thu, 25 Feb 2010 21:55:27 +0000 Subject: GUI-less build target bitcoind that links to wxBase and shouldn't need GTK, split init and shutdown from ui.cpp into init.cpp, support wxUSE_GUI=0 -- version 0.2.7 --- headers.h | 7 +- init.cpp | 625 +++++++++++++++++++++++++++++++++++++++++++++++++++++ init.h | 7 + main.cpp | 4 +- main.h | 2 + makefile.mingw | 62 +++--- makefile.unix | 61 +++--- makefile.vc | 87 +++++--- rpc.cpp | 10 +- serialize.h | 2 +- ui.cpp | 669 ++------------------------------------------------------- ui.h | 49 ++++- util.cpp | 5 +- 13 files changed, 817 insertions(+), 773 deletions(-) create mode 100644 init.cpp create mode 100644 init.h diff --git a/headers.h b/headers.h index 7fb227ec42..3c8d32cad9 100644 --- a/headers.h +++ b/headers.h @@ -21,9 +21,11 @@ #include #include #include -#include #include #include +#if wxUSE_GUI +#include +#endif #include #include #include @@ -100,8 +102,11 @@ using namespace boost; #include "irc.h" #include "main.h" #include "rpc.h" +#if wxUSE_GUI #include "uibase.h" +#endif #include "ui.h" +#include "init.h" #include "xpm/addressbook16.xpm" #include "xpm/addressbook20.xpm" diff --git a/init.cpp b/init.cpp new file mode 100644 index 0000000000..06d8f4c933 --- /dev/null +++ b/init.cpp @@ -0,0 +1,625 @@ +// 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" + + + + +void ExitTimeout(void* parg) +{ +#ifdef __WXMSW__ + Sleep(5000); + ExitProcess(0); +#endif +} + +void Shutdown(void* parg) +{ + static CCriticalSection cs_Shutdown; + static bool fTaken; + bool fFirstThread; + CRITICAL_BLOCK(cs_Shutdown) + { + fFirstThread = !fTaken; + fTaken = true; + } + static bool fExit; + if (fFirstThread) + { + fShutdown = true; + nTransactionsUpdated++; + DBFlush(false); + StopNode(); + DBFlush(true); + CreateThread(ExitTimeout, NULL); + Sleep(50); + printf("Bitcoin exiting\n\n"); + fExit = true; + exit(0); + } + else + { + while (!fExit) + Sleep(500); + Sleep(100); + ExitThread(0); + } +} + + + + + + +////////////////////////////////////////////////////////////////////////////// +// +// Startup folder +// + +#ifdef __WXMSW__ +typedef WINSHELLAPI BOOL (WINAPI *PSHGETSPECIALFOLDERPATHA)(HWND hwndOwner, LPSTR lpszPath, int nFolder, BOOL fCreate); + +string MyGetSpecialFolderPath(int nFolder, bool fCreate) +{ + char pszPath[MAX_PATH+100] = ""; + + // SHGetSpecialFolderPath is not usually available on NT 4.0 + HMODULE hShell32 = LoadLibraryA("shell32.dll"); + if (hShell32) + { + PSHGETSPECIALFOLDERPATHA pSHGetSpecialFolderPath = + (PSHGETSPECIALFOLDERPATHA)GetProcAddress(hShell32, "SHGetSpecialFolderPathA"); + if (pSHGetSpecialFolderPath) + (*pSHGetSpecialFolderPath)(NULL, pszPath, nFolder, fCreate); + FreeModule(hShell32); + } + + // Backup option + if (pszPath[0] == '\0') + { + if (nFolder == CSIDL_STARTUP) + { + strcpy(pszPath, getenv("USERPROFILE")); + strcat(pszPath, "\\Start Menu\\Programs\\Startup"); + } + else if (nFolder == CSIDL_APPDATA) + { + strcpy(pszPath, getenv("APPDATA")); + } + } + + return pszPath; +} + +string StartupShortcutPath() +{ + return MyGetSpecialFolderPath(CSIDL_STARTUP, true) + "\\Bitcoin.lnk"; +} + +bool GetStartOnSystemStartup() +{ + return wxFileExists(StartupShortcutPath()); +} + +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(&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(&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(); + } +} +#else +bool GetStartOnSystemStartup() { return false; } +void SetStartOnSystemStartup(bool fAutoStart) { } +#endif + + + + + + + +////////////////////////////////////////////////////////////////////////////// +// +// CMyApp +// + +// Define a new application +class CMyApp: public wxApp +{ +public: + wxLocale m_locale; + + 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) +{ + if (argc > 1 && argv[1][0] != '-' && (!fWindows || argv[1][0] != '/') && + wxString(argv[1]) != "start") + { + fCommandLine = true; + } + else if (!fGUI) + { + fDaemon = true; + } + else + { + // 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] = '-'; + str = str.MakeLower(); + #endif + // haven't decided which argument to use for this yet + if (str == "-daemon" || str == "-d" || str == "start") + fDaemon = true; + } + } + + if (fDaemon) + fprintf(stdout, "bitcoin server starting\n"); + +#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); + } + + return true; + } +#endif + + return wxApp::Initialize(argc, argv); +} + +bool CMyApp::OnInit() +{ + bool fRet = false; + try + { + fRet = OnInit2(); + } + catch (std::exception& e) { + PrintException(&e, "OnInit()"); + } catch (...) { + PrintException(NULL, "OnInit()"); + } + if (!fRet) + Shutdown(NULL); + return fRet; +} + +extern int g_isPainting; + +bool CMyApp::OnInit2() +{ +#ifdef _MSC_VER + // Turn off microsoft heap dump noise + _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE); + _CrtSetReportFile(_CRT_WARN, CreateFileA("NUL", GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0)); +#endif +#if defined(__WXMSW__) && defined(__WXDEBUG__) && wxUSE_GUI + // Disable malfunctioning wxWidgets debug assertion + g_isPainting = 10000; +#endif +#if wxUSE_GUI + wxImage::AddHandler(new wxPNGHandler); +#endif +#ifdef __WXMSW__ + SetAppName("Bitcoin"); +#else + SetAppName("bitcoin"); + umask(077); +#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//LC_MESSAGES/bitcoin.mo language file + m_locale.Init(wxLANGUAGE_DEFAULT, 0); + m_locale.AddCatalogLookupPathPrefix("locale"); + if (!fWindows) + { + m_locale.AddCatalogLookupPathPrefix("/usr/share/locale"); + m_locale.AddCatalogLookupPathPrefix("/usr/local/share/locale"); + } + m_locale.AddCatalog("wxstd"); // wxWidgets standard translations, if any + m_locale.AddCatalog("bitcoin"); + + // + // Parameters + // + if (fCommandLine) + { + int ret = CommandLineRPC(argc, argv); + exit(ret); + } + + ParseParameters(argc, argv); + if (mapArgs.count("-?") || mapArgs.count("--help")) + { + wxString strUsage = string() + + _("Usage: bitcoin [options]") + "\t\t\t\t\t\t\n" + + _("Options:\n") + + " -gen \t\t " + _("Generate coins\n") + + " -gen=0 \t\t " + _("Don't generate coins\n") + + " -min \t\t " + _("Start minimized\n") + + " -datadir= \t " + _("Specify data directory\n") + + " -proxy=\t " + _("Connect through socks4 proxy\n") + + " -addnode= \t " + _("Add a node to connect to\n") + + " -connect= \t " + _("Connect only to the specified node\n") + + " -? \t\t " + _("This help message\n"); + + if (fWindows && fGUI) + { + // Remove spaces, the tabs make the columns line up in the message box + for (int i = 0; i < 50; i++) + strUsage.Replace(" \t", "\t"); + wxMessageBox(strUsage, "Bitcoin", wxOK); + } + else + { + // Remove tabs + strUsage.Replace("\t", ""); + fprintf(stderr, "%s", ((string)strUsage).c_str()); + } + return false; + } + + if (mapArgs.count("-datadir")) + strlcpy(pszSetDataDir, mapArgs["-datadir"].c_str(), sizeof(pszSetDataDir)); + + if (mapArgs.count("-debug")) + fDebug = true; + + if (mapArgs.count("-printtodebugger")) + fPrintToDebugger = true; + + if (!fDebug && !pszSetDataDir[0]) + 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 0.%d.%d%s beta, OS version %s\n", VERSION/100, VERSION%100, pszSubVer, ((string)wxGetOsDescription()).c_str()); + printf("System default language is %d %s\n", m_locale.GetSystemLanguage(), ((string)m_locale.GetSysName()).c_str()); + printf("Language file %s (%s)\n", (string("locale/") + (string)m_locale.GetCanonicalName() + "/LC_MESSAGES/bitcoin.mo").c_str(), ((string)m_locale.GetLocale()).c_str()); + + if (mapArgs.count("-loadblockindextest")) + { + CTxDB txdb("r"); + txdb.LoadBlockIndex(); + PrintBlockTree(); + return false; + } + + // + // Limit to single instance per user + // Required to protect the database files if we're going to keep deleting log.* + // +#ifdef __WXMSW__ + // todo: wxSingleInstanceChecker wasn't working on Linux, never deleted its lock file + // maybe should go by whether successfully bind port 8333 instead + 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 + { + // TODO: find out how to do this in Linux, or replace with wxWidgets commands + // 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 + + // Bind to the port early so we can tell if another instance is already running. + // This is a backup to wxSingleInstanceChecker, which doesn't work on Linux. + string strErrors; + if (!BindListenPort(strErrors)) + { + wxMessageBox(strErrors, "Bitcoin"); + return false; + } + + // + // Load data files + // + bool fFirstRun; + strErrors = ""; + int64 nStart; + + printf("Loading addresses...\n"); + nStart = GetTimeMillis(); + if (!LoadAddresses()) + strErrors += _("Error loading addr.dat \n"); + printf(" addresses %15"PRI64d"ms\n", GetTimeMillis() - nStart); + + printf("Loading block index...\n"); + nStart = GetTimeMillis(); + if (!LoadBlockIndex()) + strErrors += _("Error loading blkindex.dat \n"); + printf(" block index %15"PRI64d"ms\n", GetTimeMillis() - nStart); + + printf("Loading wallet...\n"); + nStart = GetTimeMillis(); + if (!LoadWallet(fFirstRun)) + strErrors += _("Error loading wallet.dat \n"); + printf(" wallet %15"PRI64d"ms\n", GetTimeMillis() - nStart); + + printf("Done loading\n"); + + //// debug print + printf("mapBlockIndex.size() = %d\n", mapBlockIndex.size()); + printf("nBestHeight = %d\n", nBestHeight); + printf("mapKeys.size() = %d\n", mapKeys.size()); + printf("mapPubKeys.size() = %d\n", mapPubKeys.size()); + printf("mapWallet.size() = %d\n", mapWallet.size()); + printf("mapAddressBook.size() = %d\n", mapAddressBook.size()); + + if (!strErrors.empty()) + { + wxMessageBox(strErrors, "Bitcoin"); + return false; + } + + // Add wallet transactions that aren't already in a block to mapTransactions + ReacceptWalletTransactions(); + + // + // Parameters + // + if (mapArgs.count("-printblockindex") || mapArgs.count("-printblocktree")) + { + PrintBlockTree(); + return false; + } + + if (mapArgs.count("-printblock")) + { + string strMatch = mapArgs["-printblock"]; + int nFound = 0; + for (map::iterator mi = mapBlockIndex.begin(); mi != mapBlockIndex.end(); ++mi) + { + uint256 hash = (*mi).first; + if (strncmp(hash.ToString().c_str(), strMatch.c_str(), strMatch.size()) == 0) + { + CBlockIndex* pindex = (*mi).second; + CBlock block; + block.ReadFromDisk(pindex); + block.BuildMerkleTree(); + block.print(); + printf("\n"); + nFound++; + } + } + if (nFound == 0) + printf("No blocks matching %s were found\n", strMatch.c_str()); + return false; + } + + if (mapArgs.count("-gen")) + { + if (mapArgs["-gen"].empty()) + fGenerateBitcoins = true; + else + fGenerateBitcoins = (atoi(mapArgs["-gen"].c_str()) != 0); + } + + if (mapArgs.count("-proxy")) + { + fUseProxy = true; + addrProxy = CAddress(mapArgs["-proxy"]); + if (!addrProxy.IsValid()) + { + wxMessageBox(_("Invalid -proxy address"), "Bitcoin"); + return false; + } + } + + if (mapArgs.count("-addnode")) + { + foreach(string strAddr, mapMultiArgs["-addnode"]) + { + CAddress addr(strAddr, NODE_NETWORK); + addr.nTime = 0; // so it won't relay unless successfully connected + if (addr.IsValid()) + AddAddress(addr); + } + } + + // + // Create the main window and start the node + // + if (!fDaemon) + CreateMainWindow(); + + if (!CheckDiskSpace()) + return false; + + RandAddSeedPerfmon(); + + if (!CreateThread(StartNode, NULL)) + wxMessageBox("Error: CreateThread(StartNode) failed", "Bitcoin"); + + if (mapArgs.count("-server") || fDaemon) + CreateThread(ThreadRPCServer, NULL); + + if (fFirstRun) + SetStartOnSystemStartup(true); + + return true; +} + +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/init.h b/init.h new file mode 100644 index 0000000000..bd5e365941 --- /dev/null +++ b/init.h @@ -0,0 +1,7 @@ +// 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. + +void Shutdown(void* parg); +bool GetStartOnSystemStartup(); +void SetStartOnSystemStartup(bool fAutoStart); diff --git a/main.cpp b/main.cpp index bd69de92a4..f7416230f6 100644 --- a/main.cpp +++ b/main.cpp @@ -55,6 +55,8 @@ int64 nTransactionFee = 0; CAddress addrIncoming; int fLimitProcessors = false; int nLimitProcessors = 1; +int fMinimizeToTray = true; +int fMinimizeOnClose = true; @@ -2990,7 +2992,7 @@ string SendMoneyToBitcoinAddress(string strAddress, int64 nValue, CWalletTx& wtx if (nValue <= 0) return _("Invalid amount"); if (nValue + nTransactionFee > GetBalance()) - return _("You don't have enough money"); + return _("Insufficient funds"); // Parse bitcoin address CScript scriptPubKey; diff --git a/main.h b/main.h index 452ce85b63..83b8469937 100644 --- a/main.h +++ b/main.h @@ -45,6 +45,8 @@ extern int64 nTransactionFee; extern CAddress addrIncoming; extern int fLimitProcessors; extern int nLimitProcessors; +extern int fMinimizeToTray; +extern int fMinimizeOnClose; diff --git a/makefile.mingw b/makefile.mingw index 2644cbaad1..449a96072c 100644 --- a/makefile.mingw +++ b/makefile.mingw @@ -18,69 +18,59 @@ LIBPATHS= \ -L"/openssl/out" \ -L"/wxwidgets/lib/gcc_lib" +WXLIBS= \ + -l wxmsw29ud_html -l wxmsw29ud_core -l wxmsw29ud_adv -l wxbase29ud -l wxtiffd -l wxjpegd -l wxpngd -l wxzlibd + LIBS= \ -l libboost_system-mgw34-mt-d -l libboost_filesystem-mgw34-mt-d \ -l db_cxx \ -l eay32 \ - -l wxmsw29ud_html -l wxmsw29ud_core -l wxmsw29ud_adv -l wxbase29ud -l wxtiffd -l wxjpegd -l wxpngd -l wxzlibd \ -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 WXDEFS=-DWIN32 -D__WXMSW__ -D_WINDOWS -DNOPCH DEBUGFLAGS=-g -D__WXDEBUG__ CFLAGS=-mthreads -O0 -w -Wno-invalid-offsetof -Wformat $(DEBUGFLAGS) $(WXDEFS) $(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 - +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 init.h sha.h all: bitcoin.exe -headers.h.gch: headers.h $(HEADERS) - g++ -c $(CFLAGS) -o $@ $< - -obj/util.o: util.cpp $(HEADERS) - g++ -c $(CFLAGS) -o $@ $< - -obj/script.o: script.cpp $(HEADERS) - g++ -c $(CFLAGS) -o $@ $< - -obj/db.o: db.cpp $(HEADERS) - g++ -c $(CFLAGS) -o $@ $< - -obj/net.o: net.cpp $(HEADERS) - g++ -c $(CFLAGS) -o $@ $< - -obj/main.o: main.cpp $(HEADERS) sha.h +headers.h.gch: headers.h $(HEADERS) g++ -c $(CFLAGS) -o $@ $< -obj/ui.o: ui.cpp $(HEADERS) +obj/%.o: %.cpp $(HEADERS) headers.h.gch g++ -c $(CFLAGS) -o $@ $< -obj/uibase.o: uibase.cpp uibase.h - g++ -c $(CFLAGS) -o $@ $< - -obj/sha.o: sha.cpp sha.h +obj/sha.o: sha.cpp sha.h g++ -c $(CFLAGS) -O3 -o $@ $< -obj/irc.o: irc.cpp $(HEADERS) - g++ -c $(CFLAGS) -o $@ $< - -obj/rpc.o: rpc.cpp $(HEADERS) - g++ -c $(CFLAGS) -o $@ $< - obj/ui_res.o: ui.rc rc/bitcoin.ico rc/check.ico rc/send16.bmp rc/send16mask.bmp rc/send16masknoshadow.bmp rc/send20.bmp rc/send20mask.bmp rc/addressbook16.bmp rc/addressbook16mask.bmp rc/addressbook20.bmp rc/addressbook20mask.bmp windres $(WXDEFS) $(INCLUDEPATHS) -o $@ -i $< +OBJS= \ + obj/util.o \ + obj/script.o \ + obj/db.o \ + obj/net.o \ + obj/irc.o \ + obj/main.o \ + obj/rpc.o \ + obj/init.o + +bitcoin.exe: $(OBJS) obj/ui.o obj/uibase.o obj/sha.o obj/ui_res.o + g++ $(CFLAGS) -mwindows -Wl,--subsystem,windows -o $@ $(LIBPATHS) $^ $(WXLIBS) $(LIBS) + +obj/nogui/%.o: %.cpp $(HEADERS) + g++ -c $(CFLAGS) -DwxUSE_GUI=0 -o $@ $< -OBJS=obj/util.o obj/script.o obj/db.o obj/net.o obj/main.o \ - obj/ui.o obj/uibase.o obj/sha.o obj/irc.o obj/rpc.o \ - obj/ui_res.o +bitcoind.exe: $(OBJS:obj/%=obj/nogui/%) obj/sha.o obj/ui_res.o + g++ $(CFLAGS) -o $@ $(LIBPATHS) $^ -l wxbase29ud $(LIBS) -bitcoin.exe: headers.h.gch $(OBJS) - -kill /f bitcoin.exe - g++ $(CFLAGS) -mwindows -Wl,--subsystem,windows -o $@ $(LIBPATHS) $(OBJS) $(LIBS) clean: -del /Q obj\* + -del /Q obj\nogui\* -del /Q headers.h.gch diff --git a/makefile.unix b/makefile.unix index a8ec936776..10c4eece73 100644 --- a/makefile.unix +++ b/makefile.unix @@ -13,66 +13,61 @@ LIBPATHS= \ -L"/usr/lib" \ -L"/usr/local/lib" +WXLIBS= \ + -Wl,-Bstatic \ + -l wx_gtk2ud-2.9 \ + -Wl,-Bdynamic \ + -l gtk-x11-2.0 -l SM + LIBS= \ -Wl,-Bstatic \ -l boost_system-mt -l boost_filesystem-mt \ -l db_cxx \ - -l wx_gtk2ud-2.9 \ -Wl,-Bdynamic \ -l crypto \ - -l gtk-x11-2.0 -l gthread-2.0 -l SM + -l gthread-2.0 WXDEFS=-D__WXGTK__ -DNOPCH DEBUGFLAGS=-g -D__WXDEBUG__ CFLAGS=-O0 -Wno-invalid-offsetof -Wformat $(DEBUGFLAGS) $(WXDEFS) $(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 - +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 init.h sha.h all: bitcoin -headers.h.gch: headers.h $(HEADERS) - g++ -c $(CFLAGS) -o $@ $< - -obj/util.o: util.cpp $(HEADERS) - g++ -c $(CFLAGS) -o $@ $< - -obj/script.o: script.cpp $(HEADERS) - g++ -c $(CFLAGS) -o $@ $< - -obj/db.o: db.cpp $(HEADERS) - g++ -c $(CFLAGS) -o $@ $< - -obj/net.o: net.cpp $(HEADERS) - g++ -c $(CFLAGS) -o $@ $< - -obj/main.o: main.cpp $(HEADERS) sha.h - g++ -c $(CFLAGS) -o $@ $< - -obj/ui.o: ui.cpp $(HEADERS) +headers.h.gch: headers.h $(HEADERS) g++ -c $(CFLAGS) -o $@ $< -obj/uibase.o: uibase.cpp uibase.h +obj/%.o: %.cpp $(HEADERS) headers.h.gch g++ -c $(CFLAGS) -o $@ $< -obj/sha.o: sha.cpp sha.h +obj/sha.o: sha.cpp sha.h g++ -c $(CFLAGS) -O3 -o $@ $< -obj/irc.o: irc.cpp $(HEADERS) - g++ -c $(CFLAGS) -o $@ $< +OBJS= \ + obj/util.o \ + obj/script.o \ + obj/db.o \ + obj/net.o \ + obj/irc.o \ + obj/main.o \ + obj/rpc.o \ + obj/init.o -obj/rpc.o: rpc.cpp $(HEADERS) - g++ -c $(CFLAGS) -o $@ $< +bitcoin: $(OBJS) obj/ui.o obj/uibase.o obj/sha.o + g++ $(CFLAGS) -o $@ $(LIBPATHS) $^ $(WXLIBS) $(LIBS) +obj/nogui/%.o: %.cpp $(HEADERS) + g++ -c $(CFLAGS) -DwxUSE_GUI=0 -o $@ $< -OBJS=obj/util.o obj/script.o obj/db.o obj/net.o obj/main.o \ - obj/ui.o obj/uibase.o obj/sha.o obj/irc.o obj/rpc.o +bitcoind: $(OBJS:obj/%=obj/nogui/%) obj/sha.o + g++ $(CFLAGS) -o $@ $(LIBPATHS) $^ -l wx_baseud-2.9 $(LIBS) -bitcoin: headers.h.gch $(OBJS) - g++ $(CFLAGS) -o $@ $(LIBPATHS) $(OBJS) $(LIBS) clean: -rm obj/* + -rm obj/nogui/* -rm headers.h.gch diff --git a/makefile.vc b/makefile.vc index c407be3d2f..41f13522a0 100644 --- a/makefile.vc +++ b/makefile.vc @@ -28,57 +28,80 @@ LIBS= \ WXDEFS=/DWIN32 /D__WXMSW__ /D_WINDOWS /DNOPCH DEBUGFLAGS=/Zi /Od /D__WXDEBUG__ CFLAGS=/c /nologo /Ob0 /MDd /EHsc /GR /Zm300 $(DEBUGFLAGS) $(WXDEFS) $(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 - +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 init.h sha.h all: bitcoin.exe -obj\util.obj: util.cpp $(HEADERS) - cl $(CFLAGS) /Fo$@ %s +.cpp{obj}.obj: + cl $(CFLAGS) /Fo$@ %s + +obj\util.obj: $(HEADERS) -obj\script.obj: script.cpp $(HEADERS) - cl $(CFLAGS) /Fo$@ %s +obj\script.obj: $(HEADERS) -obj\db.obj: db.cpp $(HEADERS) - cl $(CFLAGS) /Fo$@ %s +obj\db.obj: $(HEADERS) -obj\net.obj: net.cpp $(HEADERS) - cl $(CFLAGS) /Fo$@ %s +obj\net.obj: $(HEADERS) -obj\main.obj: main.cpp $(HEADERS) sha.h - cl $(CFLAGS) /Fo$@ %s +obj\irc.obj: $(HEADERS) -obj\ui.obj: ui.cpp $(HEADERS) - cl $(CFLAGS) /Fo$@ %s +obj\main.obj: $(HEADERS) -obj\uibase.obj: uibase.cpp uibase.h - cl $(CFLAGS) /Fo$@ %s +obj\rpc.obj: $(HEADERS) -obj\sha.obj: sha.cpp sha.h - cl $(CFLAGS) /O2 /Fo$@ %s +obj\init.obj: $(HEADERS) -obj\irc.obj: irc.cpp $(HEADERS) - cl $(CFLAGS) /Fo$@ %s +obj\ui.obj: $(HEADERS) -obj\rpc.obj: rpc.cpp $(HEADERS) - cl $(CFLAGS) /Fo$@ %s +obj\uibase.obj: $(HEADERS) + +obj\sha.obj: sha.cpp sha.h + cl $(CFLAGS) /O2 /Fo$@ %s obj\ui.res: ui.rc rc/bitcoin.ico rc/check.ico rc/send16.bmp rc/send16mask.bmp rc/send16masknoshadow.bmp rc/send20.bmp rc/send20mask.bmp rc/addressbook16.bmp rc/addressbook16mask.bmp rc/addressbook20.bmp rc/addressbook20mask.bmp - rc $(INCLUDEPATHS) $(WXDEFS) /Fo$@ %s + rc $(INCLUDEPATHS) $(WXDEFS) /Fo$@ %s + +OBJS= \ + obj\util.obj \ + obj\script.obj \ + obj\db.obj \ + obj\net.obj \ + obj\irc.obj \ + obj\main.obj \ + obj\rpc.obj \ + obj\init.obj + +bitcoin.exe: $(OBJS) obj\ui.obj obj\uibase.obj obj\sha.obj obj\ui.res + link /nologo /DEBUG /SUBSYSTEM:WINDOWS /OUT:$@ $(LIBPATHS) $** $(LIBS) + + +.cpp{obj\nogui}.obj: + cl $(CFLAGS) /DwxUSE_GUI=0 /Fo$@ %s + +obj\nogui\util.obj: $(HEADERS) + +obj\nogui\script.obj: $(HEADERS) + +obj\nogui\db.obj: $(HEADERS) + +obj\nogui\net.obj: $(HEADERS) + +obj\nogui\irc.obj: $(HEADERS) + +obj\nogui\main.obj: $(HEADERS) +obj\nogui\rpc.obj: $(HEADERS) +obj\nogui\init.obj: $(HEADERS) -OBJS=obj\util.obj obj\script.obj obj\db.obj obj\net.obj obj\main.obj \ - obj\ui.obj obj\uibase.obj obj\sha.obj obj\irc.obj obj\rpc.obj \ - obj\ui.res +bitcoind.exe: $(OBJS:obj\=obj\nogui\) obj\sha.obj obj\ui.res + link /nologo /DEBUG /OUT:$@ $(LIBPATHS) $** $(LIBS) -bitcoin.exe: $(OBJS) - -kill /f bitcoin.exe & sleep 1 - link /nologo /DEBUG /SUBSYSTEM:WINDOWS /OUT:$@ $(LIBPATHS) $** $(LIBS) clean: - -del /Q obj\* - -del *.ilk - -del *.pdb + -del /Q obj\* + -del *.ilk + -del *.pdb diff --git a/rpc.cpp b/rpc.cpp index 7f3e71dbac..f298137aa2 100644 --- a/rpc.cpp +++ b/rpc.cpp @@ -676,18 +676,18 @@ int CommandLineRPC(int argc, char *argv[]) string strResult = (result.type() == str_type ? result.get_str() : write_string(result, true)); if (result.type() != null_type) { - if (fWindows) + if (fWindows && fGUI) // Windows GUI apps can't print to command line, - // so for now settle for a message box yuck - wxMessageBox(strResult.c_str(), "Bitcoin", wxOK); + // so settle for a message box yuck + MyMessageBox(strResult.c_str(), "Bitcoin", wxOK); else fprintf(stdout, "%s\n", strResult.c_str()); } return 0; } catch (std::exception& e) { - if (fWindows) - wxMessageBox(strprintf("error: %s\n", e.what()).c_str(), "Bitcoin", wxOK); + if (fWindows && fGUI) + MyMessageBox(strprintf("error: %s\n", e.what()).c_str(), "Bitcoin", wxOK); else fprintf(stderr, "error: %s\n", e.what()); } catch (...) { diff --git a/serialize.h b/serialize.h index 8fb72a0aab..5399c23d02 100644 --- a/serialize.h +++ b/serialize.h @@ -19,7 +19,7 @@ class CScript; class CDataStream; class CAutoFile; -static const int VERSION = 206; +static const int VERSION = 207; static const char* pszSubVer = ".0"; diff --git a/ui.cpp b/ui.cpp index 748b4dad93..efb05385ec 100644 --- a/ui.cpp +++ b/ui.cpp @@ -7,38 +7,18 @@ #include #endif -bool GetStartOnSystemStartup(); -void SetStartOnSystemStartup(bool fAutoStart); - DEFINE_EVENT_TYPE(wxEVT_UITHREADCALL) CMainFrame* pframeMain = NULL; CMyTaskBarIcon* ptaskbaricon = NULL; -extern int g_isPainting; bool fClosedToTray = false; -// Settings -int fMinimizeToTray = true; -int fMinimizeOnClose = true; -int MyMessageBox(const wxString& message, const wxString& caption="Message", int style=wxOK, wxWindow* parent=NULL, int x=-1, int y=-1) -{ - if (fDaemon) - { - printf("wxMessageBox %s: %s\n", string(caption).c_str(), string(message).c_str()); - fprintf(stderr, "%s: %s\n", string(caption).c_str(), string(message).c_str()); - return wxOK; - } - return wxMessageBox(message, caption, style, parent, x, y); -} -#define wxMessageBox MyMessageBox - - @@ -48,47 +28,6 @@ int MyMessageBox(const wxString& message, const wxString& caption="Message", int // Util // -void ExitTimeout(void* parg) -{ -#ifdef __WXMSW__ - Sleep(5000); - ExitProcess(0); -#endif -} - -void Shutdown(void* parg) -{ - static CCriticalSection cs_Shutdown; - static bool fTaken; - bool fFirstThread; - CRITICAL_BLOCK(cs_Shutdown) - { - fFirstThread = !fTaken; - fTaken = true; - } - static bool fExit; - if (fFirstThread) - { - fShutdown = true; - nTransactionsUpdated++; - DBFlush(false); - StopNode(); - DBFlush(true); - CreateThread(ExitTimeout, NULL); - Sleep(50); - printf("Bitcoin exiting\n\n"); - fExit = true; - exit(0); - } - else - { - while (!fExit) - Sleep(500); - Sleep(100); - ExitThread(0); - } -} - void HandleCtrlA(wxKeyEvent& event) { // Ctrl-a select all @@ -312,7 +251,7 @@ CMainFrame::CMainFrame(wxWindow* parent) : CMainFrameBase(parent) m_staticTextBalance->SetSize(140, 17); // resize to fit ubuntu's huge default font dResize = 1.22; - SetSize(dResize * GetSize().GetWidth(), 1.09 * GetSize().GetHeight()); + SetSize(dResize * GetSize().GetWidth(), 1.15 * GetSize().GetHeight()); #endif m_staticTextBalance->SetLabel(FormatMoney(GetBalance()) + " "); m_listCtrl->SetFocus(); @@ -1630,7 +1569,6 @@ void COptionsDialog::OnButtonApply(wxCommandEvent& event) - ////////////////////////////////////////////////////////////////////////////// // // CAboutDialog @@ -2014,7 +1952,7 @@ void CSendingDialog::StartTransfer() // Make sure we have enough money if (nPrice + nTransactionFee > GetBalance()) { - Error(_("You don't have enough money")); + Error(_("Insufficient funds")); return; } @@ -2081,7 +2019,7 @@ void CSendingDialog::OnReply2(CDataStream& vRecv) return; if (nPrice + nTransactionFee > GetBalance()) { - Error(_("You don't have enough money")); + Error(_("Insufficient funds")); return; } CKey key; @@ -2562,602 +2500,21 @@ wxMenu* CMyTaskBarIcon::CreatePopupMenu() -////////////////////////////////////////////////////////////////////////////// -// -// CMyApp -// - -// Define a new application -class CMyApp: public wxApp -{ -public: - wxLocale m_locale; - - 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) -{ - if (argc > 1 && argv[1][0] != '-' && (!fWindows || argv[1][0] != '/') && - wxString(argv[1]) != "start") - { - fCommandLine = true; - } - else - { - // 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] = '-'; - str = str.MakeLower(); - #endif - // haven't decided which argument to use for this yet - if (str == "-daemon" || str == "-d" || str == "start") - 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) - { - fprintf(stdout, "bitcoin server starting\n"); - - // 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); - } - - return true; - } -#endif - - return wxApp::Initialize(argc, argv); -} - -bool CMyApp::OnInit() -{ - bool fRet = false; - try - { - fRet = OnInit2(); - } - catch (std::exception& e) { - PrintException(&e, "OnInit()"); - } catch (...) { - PrintException(NULL, "OnInit()"); - } - if (!fRet) - Shutdown(NULL); - return fRet; -} - -bool CMyApp::OnInit2() -{ -#ifdef _MSC_VER - // Turn off microsoft heap dump noise - _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE); - _CrtSetReportFile(_CRT_WARN, CreateFileA("NUL", GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0)); -#endif -#if defined(__WXMSW__) && defined(__WXDEBUG__) - // Disable malfunctioning wxWidgets debug assertion - g_isPainting = 10000; -#endif - wxImage::AddHandler(new wxPNGHandler); -#ifdef __WXMSW__ - SetAppName("Bitcoin"); -#else - SetAppName("bitcoin"); - umask(077); -#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//LC_MESSAGES/bitcoin.mo language file - m_locale.Init(wxLANGUAGE_DEFAULT, 0); - m_locale.AddCatalogLookupPathPrefix("locale"); - if (!fWindows) - { - m_locale.AddCatalogLookupPathPrefix("/usr/share/locale"); - m_locale.AddCatalogLookupPathPrefix("/usr/local/share/locale"); - } - m_locale.AddCatalog("wxstd"); // wxWidgets standard translations, if any - m_locale.AddCatalog("bitcoin"); - - // - // Parameters - // - if (fCommandLine) - { - int ret = CommandLineRPC(argc, argv); - exit(ret); - } - - ParseParameters(argc, argv); - if (mapArgs.count("-?") || mapArgs.count("--help")) - { - wxString strUsage = string() + - _("Usage: bitcoin [options]") + "\t\t\t\t\t\t\n" + - _("Options:\n") + - " -gen \t\t " + _("Generate coins\n") + - " -gen=0 \t\t " + _("Don't generate coins\n") + - " -min \t\t " + _("Start minimized\n") + - " -datadir= \t " + _("Specify data directory\n") + - " -proxy=\t " + _("Connect through socks4 proxy\n") + - " -addnode= \t " + _("Add a node to connect to\n") + - " -connect= \t " + _("Connect only to the specified node\n") + - " -? \t\t " + _("This help message\n"); - - if (fWindows) - { - // Remove spaces, the tabs make the columns line up in the message box - for (int i = 0; i < 50; i++) - strUsage.Replace(" \t", "\t"); - wxMessageBox(strUsage, "Bitcoin", wxOK); - } - else - { - // Remove tabs - strUsage.Replace("\t", ""); - fprintf(stderr, "%s", ((string)strUsage).c_str()); - } - return false; - } - - if (mapArgs.count("-datadir")) - strlcpy(pszSetDataDir, mapArgs["-datadir"].c_str(), sizeof(pszSetDataDir)); - - if (mapArgs.count("-debug")) - fDebug = true; - - if (mapArgs.count("-printtodebugger")) - fPrintToDebugger = true; - - if (!fDebug && !pszSetDataDir[0]) - 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 0.%d.%d%s beta, OS version %s\n", VERSION/100, VERSION%100, pszSubVer, ((string)wxGetOsDescription()).c_str()); - printf("System default language is %d %s\n", m_locale.GetSystemLanguage(), ((string)m_locale.GetSysName()).c_str()); - printf("Language file %s (%s)\n", (string("locale/") + (string)m_locale.GetCanonicalName() + "/LC_MESSAGES/bitcoin.mo").c_str(), ((string)m_locale.GetLocale()).c_str()); - - if (mapArgs.count("-loadblockindextest")) - { - CTxDB txdb("r"); - txdb.LoadBlockIndex(); - PrintBlockTree(); - return false; - } - - // - // Limit to single instance per user - // Required to protect the database files if we're going to keep deleting log.* - // -#ifdef __WXMSW__ - // todo: wxSingleInstanceChecker wasn't working on Linux, never deleted its lock file - // maybe should go by whether successfully bind port 8333 instead - 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 - { - // TODO: find out how to do this in Linux, or replace with wxWidgets commands - // 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 - - // Bind to the port early so we can tell if another instance is already running. - // This is a backup to wxSingleInstanceChecker, which doesn't work on Linux. - string strErrors; - if (!BindListenPort(strErrors)) - { - wxMessageBox(strErrors, "Bitcoin"); - return false; - } - - // - // Load data files - // - bool fFirstRun; - strErrors = ""; - int64 nStart; - - printf("Loading addresses...\n"); - nStart = GetTimeMillis(); - if (!LoadAddresses()) - strErrors += _("Error loading addr.dat \n"); - printf(" addresses %15"PRI64d"ms\n", GetTimeMillis() - nStart); - - printf("Loading block index...\n"); - nStart = GetTimeMillis(); - if (!LoadBlockIndex()) - strErrors += _("Error loading blkindex.dat \n"); - printf(" block index %15"PRI64d"ms\n", GetTimeMillis() - nStart); - - printf("Loading wallet...\n"); - nStart = GetTimeMillis(); - if (!LoadWallet(fFirstRun)) - strErrors += _("Error loading wallet.dat \n"); - printf(" wallet %15"PRI64d"ms\n", GetTimeMillis() - nStart); - - printf("Done loading\n"); - - //// debug print - printf("mapBlockIndex.size() = %d\n", mapBlockIndex.size()); - printf("nBestHeight = %d\n", nBestHeight); - printf("mapKeys.size() = %d\n", mapKeys.size()); - printf("mapPubKeys.size() = %d\n", mapPubKeys.size()); - printf("mapWallet.size() = %d\n", mapWallet.size()); - printf("mapAddressBook.size() = %d\n", mapAddressBook.size()); - - if (!strErrors.empty()) - { - wxMessageBox(strErrors, "Bitcoin"); - return false; - } - - // Add wallet transactions that aren't already in a block to mapTransactions - ReacceptWalletTransactions(); - - // - // Parameters - // - if (mapArgs.count("-printblockindex") || mapArgs.count("-printblocktree")) - { - PrintBlockTree(); - return false; - } - - if (mapArgs.count("-printblock")) - { - string strMatch = mapArgs["-printblock"]; - int nFound = 0; - for (map::iterator mi = mapBlockIndex.begin(); mi != mapBlockIndex.end(); ++mi) - { - uint256 hash = (*mi).first; - if (strncmp(hash.ToString().c_str(), strMatch.c_str(), strMatch.size()) == 0) - { - CBlockIndex* pindex = (*mi).second; - CBlock block; - block.ReadFromDisk(pindex); - block.BuildMerkleTree(); - block.print(); - printf("\n"); - nFound++; - } - } - if (nFound == 0) - printf("No blocks matching %s were found\n", strMatch.c_str()); - return false; - } - - if (mapArgs.count("-gen")) - { - if (mapArgs["-gen"].empty()) - fGenerateBitcoins = true; - else - fGenerateBitcoins = (atoi(mapArgs["-gen"].c_str()) != 0); - } - - if (mapArgs.count("-proxy")) - { - fUseProxy = true; - addrProxy = CAddress(mapArgs["-proxy"]); - if (!addrProxy.IsValid()) - { - wxMessageBox(_("Invalid -proxy address"), "Bitcoin"); - return false; - } - } - - if (mapArgs.count("-addnode")) - { - foreach(string strAddr, mapMultiArgs["-addnode"]) - { - CAddress addr(strAddr, NODE_NETWORK); - addr.nTime = 0; // so it won't relay unless successfully connected - if (addr.IsValid()) - AddAddress(addr); - } - } - - // - // Create the main frame window - // - if (!fDaemon) - { - pframeMain = new CMainFrame(NULL); - if (mapArgs.count("-min")) - pframeMain->Iconize(true); - 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); - } - - if (!CheckDiskSpace()) - return false; - - RandAddSeedPerfmon(); - - if (!CreateThread(StartNode, NULL)) - wxMessageBox("Error: CreateThread(StartNode) failed", "Bitcoin"); - - if (mapArgs.count("-server") || fDaemon) - CreateThread(ThreadRPCServer, NULL); - - if (fFirstRun) - SetStartOnSystemStartup(true); - - - // - // Tests - // -#ifdef __WXMSW__ - if (argc >= 2 && stricmp(argv[1], "-send") == 0) -#else - if (argc >= 2 && strcmp(argv[1], "-send") == 0) -#endif - { - int64 nValue = 1; - if (argc >= 3) - ParseMoney(argv[2], nValue); - - string strAddress; - if (argc >= 4) - strAddress = argv[3]; - CAddress addr(strAddress); - - CWalletTx wtx; - wtx.mapValue["to"] = strAddress; - wtx.mapValue["from"] = addrLocalHost.ToString(); - wtx.mapValue["message"] = "command line send"; - - // Send to IP address - CSendingDialog* pdialog = new CSendingDialog(pframeMain, addr, nValue, wtx); - if (!pdialog->ShowModal()) - return false; - } - - return true; -} - -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); -} - - - - - -#ifdef __WXMSW__ -typedef WINSHELLAPI BOOL (WINAPI *PSHGETSPECIALFOLDERPATHA)(HWND hwndOwner, LPSTR lpszPath, int nFolder, BOOL fCreate); - -string MyGetSpecialFolderPath(int nFolder, bool fCreate) -{ - char pszPath[MAX_PATH+100] = ""; - - // SHGetSpecialFolderPath is not usually available on NT 4.0 - HMODULE hShell32 = LoadLibraryA("shell32.dll"); - if (hShell32) - { - PSHGETSPECIALFOLDERPATHA pSHGetSpecialFolderPath = - (PSHGETSPECIALFOLDERPATHA)GetProcAddress(hShell32, "SHGetSpecialFolderPathA"); - if (pSHGetSpecialFolderPath) - (*pSHGetSpecialFolderPath)(NULL, pszPath, nFolder, fCreate); - FreeModule(hShell32); - } - - // Backup option - if (pszPath[0] == '\0') - { - if (nFolder == CSIDL_STARTUP) - { - strcpy(pszPath, getenv("USERPROFILE")); - strcat(pszPath, "\\Start Menu\\Programs\\Startup"); - } - else if (nFolder == CSIDL_APPDATA) - { - strcpy(pszPath, getenv("APPDATA")); - } - } - - return pszPath; -} -string StartupShortcutPath() -{ - return MyGetSpecialFolderPath(CSIDL_STARTUP, true) + "\\Bitcoin.lnk"; -} -bool GetStartOnSystemStartup() -{ - return wxFileExists(StartupShortcutPath()); -} -void SetStartOnSystemStartup(bool fAutoStart) +void CreateMainWindow() { - // 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(&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(&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(); - } + pframeMain = new CMainFrame(NULL); + if (mapArgs.count("-min")) + pframeMain->Iconize(true); + 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); } -#else -bool GetStartOnSystemStartup() { return false; } -void SetStartOnSystemStartup(bool fAutoStart) { } -#endif - diff --git a/ui.h b/ui.h index acabd5514a..e944eb9339 100644 --- a/ui.h +++ b/ui.h @@ -4,26 +4,61 @@ DECLARE_EVENT_TYPE(wxEVT_UITHREADCALL, -1) +#if wxUSE_GUI +static const bool fGUI=true; +#else +static const bool fGUI=false; +#endif -extern map mapArgs; +inline int MyMessageBox(const wxString& message, const wxString& caption="Message", int style=wxOK, wxWindow* parent=NULL, int x=-1, int y=-1) +{ +#if wxUSE_GUI + if (!fDaemon) + return wxMessageBox(message, caption, style, parent, x, y); +#endif + printf("wxMessageBox %s: %s\n", string(caption).c_str(), string(message).c_str()); + fprintf(stderr, "%s: %s\n", string(caption).c_str(), string(message).c_str()); + return wxOK; +} +#define wxMessageBox MyMessageBox -// Settings -extern int fMinimizeToTray; -extern int fMinimizeOnClose; void HandleCtrlA(wxKeyEvent& event); string FormatTxStatus(const CWalletTx& wtx); void UIThreadCall(boost::function0); -void MainFrameRepaint(); -void Shutdown(void* parg); int ThreadSafeMessageBox(const string& message, const string& caption="Message", int style=wxOK, wxWindow* parent=NULL, int x=-1, int y=-1); bool ThreadSafeAskFee(int64 nFeeRequired, const string& strCaption, wxWindow* parent); +void MainFrameRepaint(); +void CreateMainWindow(); + +#if !wxUSE_GUI +inline int ThreadSafeMessageBox(const string& message, const string& caption, int style, wxWindow* parent, int x, int y) +{ + return MyMessageBox(message, caption, style, parent, x, y); +} + +inline bool ThreadSafeAskFee(int64 nFeeRequired, const string& strCaption, wxWindow* parent) +{ + return true; +} + +inline void MainFrameRepaint() +{ +} + +inline void CreateMainWindow() +{ +} +#else // wxUSE_GUI + + + class CMainFrame : public CMainFrameBase @@ -331,3 +366,5 @@ public: DECLARE_EVENT_TABLE() }; + +#endif // wxUSE_GUI diff --git a/util.cpp b/util.cpp index 6ea735d1e2..d90cdc48f9 100644 --- a/util.cpp +++ b/util.cpp @@ -459,6 +459,7 @@ const char* wxGetTranslation(const char* pszEnglish) mapCache[pszEnglish] = pszCached; return pszCached; } + return NULL; } @@ -502,8 +503,8 @@ void PrintException(std::exception* pex, const char* pszThread) FormatException(pszMessage, pex, pszThread); printf("\n\n************************\n%s\n", pszMessage); fprintf(stderr, "\n\n************************\n%s\n", pszMessage); - if (wxTheApp && !fDaemon) - wxMessageBox(pszMessage, "Error", wxOK | wxICON_ERROR); + if (wxTheApp && !fDaemon && fGUI) + MyMessageBox(pszMessage, "Error", wxOK | wxICON_ERROR); throw; //DebugBreak(); } -- cgit v1.2.3 From c2430126d75318508836a24f90d3524320190465 Mon Sep 17 00:00:00 2001 From: s_nakamoto Date: Thu, 25 Feb 2010 21:55:27 +0000 Subject: GUI-less build target bitcoind that links to wxBase and shouldn't need GTK, split init and shutdown from ui.cpp into init.cpp, support wxUSE_GUI=0 -- version 0.2.7 git-svn-id: https://bitcoin.svn.sourceforge.net/svnroot/bitcoin/trunk@71 1a98c847-1fd6-4fd8-948a-caf3550aa51b --- headers.h | 7 +- init.cpp | 625 +++++++++++++++++++++++++++++++++++++++++++++++++++++ init.h | 7 + main.cpp | 4 +- main.h | 2 + makefile.mingw | 62 +++--- makefile.unix | 61 +++--- makefile.vc | 87 +++++--- rpc.cpp | 10 +- serialize.h | 2 +- ui.cpp | 669 ++------------------------------------------------------- ui.h | 49 ++++- util.cpp | 5 +- 13 files changed, 817 insertions(+), 773 deletions(-) create mode 100644 init.cpp create mode 100644 init.h diff --git a/headers.h b/headers.h index 7fb227ec42..3c8d32cad9 100644 --- a/headers.h +++ b/headers.h @@ -21,9 +21,11 @@ #include #include #include -#include #include #include +#if wxUSE_GUI +#include +#endif #include #include #include @@ -100,8 +102,11 @@ using namespace boost; #include "irc.h" #include "main.h" #include "rpc.h" +#if wxUSE_GUI #include "uibase.h" +#endif #include "ui.h" +#include "init.h" #include "xpm/addressbook16.xpm" #include "xpm/addressbook20.xpm" diff --git a/init.cpp b/init.cpp new file mode 100644 index 0000000000..06d8f4c933 --- /dev/null +++ b/init.cpp @@ -0,0 +1,625 @@ +// 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" + + + + +void ExitTimeout(void* parg) +{ +#ifdef __WXMSW__ + Sleep(5000); + ExitProcess(0); +#endif +} + +void Shutdown(void* parg) +{ + static CCriticalSection cs_Shutdown; + static bool fTaken; + bool fFirstThread; + CRITICAL_BLOCK(cs_Shutdown) + { + fFirstThread = !fTaken; + fTaken = true; + } + static bool fExit; + if (fFirstThread) + { + fShutdown = true; + nTransactionsUpdated++; + DBFlush(false); + StopNode(); + DBFlush(true); + CreateThread(ExitTimeout, NULL); + Sleep(50); + printf("Bitcoin exiting\n\n"); + fExit = true; + exit(0); + } + else + { + while (!fExit) + Sleep(500); + Sleep(100); + ExitThread(0); + } +} + + + + + + +////////////////////////////////////////////////////////////////////////////// +// +// Startup folder +// + +#ifdef __WXMSW__ +typedef WINSHELLAPI BOOL (WINAPI *PSHGETSPECIALFOLDERPATHA)(HWND hwndOwner, LPSTR lpszPath, int nFolder, BOOL fCreate); + +string MyGetSpecialFolderPath(int nFolder, bool fCreate) +{ + char pszPath[MAX_PATH+100] = ""; + + // SHGetSpecialFolderPath is not usually available on NT 4.0 + HMODULE hShell32 = LoadLibraryA("shell32.dll"); + if (hShell32) + { + PSHGETSPECIALFOLDERPATHA pSHGetSpecialFolderPath = + (PSHGETSPECIALFOLDERPATHA)GetProcAddress(hShell32, "SHGetSpecialFolderPathA"); + if (pSHGetSpecialFolderPath) + (*pSHGetSpecialFolderPath)(NULL, pszPath, nFolder, fCreate); + FreeModule(hShell32); + } + + // Backup option + if (pszPath[0] == '\0') + { + if (nFolder == CSIDL_STARTUP) + { + strcpy(pszPath, getenv("USERPROFILE")); + strcat(pszPath, "\\Start Menu\\Programs\\Startup"); + } + else if (nFolder == CSIDL_APPDATA) + { + strcpy(pszPath, getenv("APPDATA")); + } + } + + return pszPath; +} + +string StartupShortcutPath() +{ + return MyGetSpecialFolderPath(CSIDL_STARTUP, true) + "\\Bitcoin.lnk"; +} + +bool GetStartOnSystemStartup() +{ + return wxFileExists(StartupShortcutPath()); +} + +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(&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(&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(); + } +} +#else +bool GetStartOnSystemStartup() { return false; } +void SetStartOnSystemStartup(bool fAutoStart) { } +#endif + + + + + + + +////////////////////////////////////////////////////////////////////////////// +// +// CMyApp +// + +// Define a new application +class CMyApp: public wxApp +{ +public: + wxLocale m_locale; + + 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) +{ + if (argc > 1 && argv[1][0] != '-' && (!fWindows || argv[1][0] != '/') && + wxString(argv[1]) != "start") + { + fCommandLine = true; + } + else if (!fGUI) + { + fDaemon = true; + } + else + { + // 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] = '-'; + str = str.MakeLower(); + #endif + // haven't decided which argument to use for this yet + if (str == "-daemon" || str == "-d" || str == "start") + fDaemon = true; + } + } + + if (fDaemon) + fprintf(stdout, "bitcoin server starting\n"); + +#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); + } + + return true; + } +#endif + + return wxApp::Initialize(argc, argv); +} + +bool CMyApp::OnInit() +{ + bool fRet = false; + try + { + fRet = OnInit2(); + } + catch (std::exception& e) { + PrintException(&e, "OnInit()"); + } catch (...) { + PrintException(NULL, "OnInit()"); + } + if (!fRet) + Shutdown(NULL); + return fRet; +} + +extern int g_isPainting; + +bool CMyApp::OnInit2() +{ +#ifdef _MSC_VER + // Turn off microsoft heap dump noise + _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE); + _CrtSetReportFile(_CRT_WARN, CreateFileA("NUL", GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0)); +#endif +#if defined(__WXMSW__) && defined(__WXDEBUG__) && wxUSE_GUI + // Disable malfunctioning wxWidgets debug assertion + g_isPainting = 10000; +#endif +#if wxUSE_GUI + wxImage::AddHandler(new wxPNGHandler); +#endif +#ifdef __WXMSW__ + SetAppName("Bitcoin"); +#else + SetAppName("bitcoin"); + umask(077); +#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//LC_MESSAGES/bitcoin.mo language file + m_locale.Init(wxLANGUAGE_DEFAULT, 0); + m_locale.AddCatalogLookupPathPrefix("locale"); + if (!fWindows) + { + m_locale.AddCatalogLookupPathPrefix("/usr/share/locale"); + m_locale.AddCatalogLookupPathPrefix("/usr/local/share/locale"); + } + m_locale.AddCatalog("wxstd"); // wxWidgets standard translations, if any + m_locale.AddCatalog("bitcoin"); + + // + // Parameters + // + if (fCommandLine) + { + int ret = CommandLineRPC(argc, argv); + exit(ret); + } + + ParseParameters(argc, argv); + if (mapArgs.count("-?") || mapArgs.count("--help")) + { + wxString strUsage = string() + + _("Usage: bitcoin [options]") + "\t\t\t\t\t\t\n" + + _("Options:\n") + + " -gen \t\t " + _("Generate coins\n") + + " -gen=0 \t\t " + _("Don't generate coins\n") + + " -min \t\t " + _("Start minimized\n") + + " -datadir= \t " + _("Specify data directory\n") + + " -proxy=\t " + _("Connect through socks4 proxy\n") + + " -addnode= \t " + _("Add a node to connect to\n") + + " -connect= \t " + _("Connect only to the specified node\n") + + " -? \t\t " + _("This help message\n"); + + if (fWindows && fGUI) + { + // Remove spaces, the tabs make the columns line up in the message box + for (int i = 0; i < 50; i++) + strUsage.Replace(" \t", "\t"); + wxMessageBox(strUsage, "Bitcoin", wxOK); + } + else + { + // Remove tabs + strUsage.Replace("\t", ""); + fprintf(stderr, "%s", ((string)strUsage).c_str()); + } + return false; + } + + if (mapArgs.count("-datadir")) + strlcpy(pszSetDataDir, mapArgs["-datadir"].c_str(), sizeof(pszSetDataDir)); + + if (mapArgs.count("-debug")) + fDebug = true; + + if (mapArgs.count("-printtodebugger")) + fPrintToDebugger = true; + + if (!fDebug && !pszSetDataDir[0]) + 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 0.%d.%d%s beta, OS version %s\n", VERSION/100, VERSION%100, pszSubVer, ((string)wxGetOsDescription()).c_str()); + printf("System default language is %d %s\n", m_locale.GetSystemLanguage(), ((string)m_locale.GetSysName()).c_str()); + printf("Language file %s (%s)\n", (string("locale/") + (string)m_locale.GetCanonicalName() + "/LC_MESSAGES/bitcoin.mo").c_str(), ((string)m_locale.GetLocale()).c_str()); + + if (mapArgs.count("-loadblockindextest")) + { + CTxDB txdb("r"); + txdb.LoadBlockIndex(); + PrintBlockTree(); + return false; + } + + // + // Limit to single instance per user + // Required to protect the database files if we're going to keep deleting log.* + // +#ifdef __WXMSW__ + // todo: wxSingleInstanceChecker wasn't working on Linux, never deleted its lock file + // maybe should go by whether successfully bind port 8333 instead + 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 + { + // TODO: find out how to do this in Linux, or replace with wxWidgets commands + // 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 + + // Bind to the port early so we can tell if another instance is already running. + // This is a backup to wxSingleInstanceChecker, which doesn't work on Linux. + string strErrors; + if (!BindListenPort(strErrors)) + { + wxMessageBox(strErrors, "Bitcoin"); + return false; + } + + // + // Load data files + // + bool fFirstRun; + strErrors = ""; + int64 nStart; + + printf("Loading addresses...\n"); + nStart = GetTimeMillis(); + if (!LoadAddresses()) + strErrors += _("Error loading addr.dat \n"); + printf(" addresses %15"PRI64d"ms\n", GetTimeMillis() - nStart); + + printf("Loading block index...\n"); + nStart = GetTimeMillis(); + if (!LoadBlockIndex()) + strErrors += _("Error loading blkindex.dat \n"); + printf(" block index %15"PRI64d"ms\n", GetTimeMillis() - nStart); + + printf("Loading wallet...\n"); + nStart = GetTimeMillis(); + if (!LoadWallet(fFirstRun)) + strErrors += _("Error loading wallet.dat \n"); + printf(" wallet %15"PRI64d"ms\n", GetTimeMillis() - nStart); + + printf("Done loading\n"); + + //// debug print + printf("mapBlockIndex.size() = %d\n", mapBlockIndex.size()); + printf("nBestHeight = %d\n", nBestHeight); + printf("mapKeys.size() = %d\n", mapKeys.size()); + printf("mapPubKeys.size() = %d\n", mapPubKeys.size()); + printf("mapWallet.size() = %d\n", mapWallet.size()); + printf("mapAddressBook.size() = %d\n", mapAddressBook.size()); + + if (!strErrors.empty()) + { + wxMessageBox(strErrors, "Bitcoin"); + return false; + } + + // Add wallet transactions that aren't already in a block to mapTransactions + ReacceptWalletTransactions(); + + // + // Parameters + // + if (mapArgs.count("-printblockindex") || mapArgs.count("-printblocktree")) + { + PrintBlockTree(); + return false; + } + + if (mapArgs.count("-printblock")) + { + string strMatch = mapArgs["-printblock"]; + int nFound = 0; + for (map::iterator mi = mapBlockIndex.begin(); mi != mapBlockIndex.end(); ++mi) + { + uint256 hash = (*mi).first; + if (strncmp(hash.ToString().c_str(), strMatch.c_str(), strMatch.size()) == 0) + { + CBlockIndex* pindex = (*mi).second; + CBlock block; + block.ReadFromDisk(pindex); + block.BuildMerkleTree(); + block.print(); + printf("\n"); + nFound++; + } + } + if (nFound == 0) + printf("No blocks matching %s were found\n", strMatch.c_str()); + return false; + } + + if (mapArgs.count("-gen")) + { + if (mapArgs["-gen"].empty()) + fGenerateBitcoins = true; + else + fGenerateBitcoins = (atoi(mapArgs["-gen"].c_str()) != 0); + } + + if (mapArgs.count("-proxy")) + { + fUseProxy = true; + addrProxy = CAddress(mapArgs["-proxy"]); + if (!addrProxy.IsValid()) + { + wxMessageBox(_("Invalid -proxy address"), "Bitcoin"); + return false; + } + } + + if (mapArgs.count("-addnode")) + { + foreach(string strAddr, mapMultiArgs["-addnode"]) + { + CAddress addr(strAddr, NODE_NETWORK); + addr.nTime = 0; // so it won't relay unless successfully connected + if (addr.IsValid()) + AddAddress(addr); + } + } + + // + // Create the main window and start the node + // + if (!fDaemon) + CreateMainWindow(); + + if (!CheckDiskSpace()) + return false; + + RandAddSeedPerfmon(); + + if (!CreateThread(StartNode, NULL)) + wxMessageBox("Error: CreateThread(StartNode) failed", "Bitcoin"); + + if (mapArgs.count("-server") || fDaemon) + CreateThread(ThreadRPCServer, NULL); + + if (fFirstRun) + SetStartOnSystemStartup(true); + + return true; +} + +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/init.h b/init.h new file mode 100644 index 0000000000..bd5e365941 --- /dev/null +++ b/init.h @@ -0,0 +1,7 @@ +// 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. + +void Shutdown(void* parg); +bool GetStartOnSystemStartup(); +void SetStartOnSystemStartup(bool fAutoStart); diff --git a/main.cpp b/main.cpp index bd69de92a4..f7416230f6 100644 --- a/main.cpp +++ b/main.cpp @@ -55,6 +55,8 @@ int64 nTransactionFee = 0; CAddress addrIncoming; int fLimitProcessors = false; int nLimitProcessors = 1; +int fMinimizeToTray = true; +int fMinimizeOnClose = true; @@ -2990,7 +2992,7 @@ string SendMoneyToBitcoinAddress(string strAddress, int64 nValue, CWalletTx& wtx if (nValue <= 0) return _("Invalid amount"); if (nValue + nTransactionFee > GetBalance()) - return _("You don't have enough money"); + return _("Insufficient funds"); // Parse bitcoin address CScript scriptPubKey; diff --git a/main.h b/main.h index 452ce85b63..83b8469937 100644 --- a/main.h +++ b/main.h @@ -45,6 +45,8 @@ extern int64 nTransactionFee; extern CAddress addrIncoming; extern int fLimitProcessors; extern int nLimitProcessors; +extern int fMinimizeToTray; +extern int fMinimizeOnClose; diff --git a/makefile.mingw b/makefile.mingw index 2644cbaad1..449a96072c 100644 --- a/makefile.mingw +++ b/makefile.mingw @@ -18,69 +18,59 @@ LIBPATHS= \ -L"/openssl/out" \ -L"/wxwidgets/lib/gcc_lib" +WXLIBS= \ + -l wxmsw29ud_html -l wxmsw29ud_core -l wxmsw29ud_adv -l wxbase29ud -l wxtiffd -l wxjpegd -l wxpngd -l wxzlibd + LIBS= \ -l libboost_system-mgw34-mt-d -l libboost_filesystem-mgw34-mt-d \ -l db_cxx \ -l eay32 \ - -l wxmsw29ud_html -l wxmsw29ud_core -l wxmsw29ud_adv -l wxbase29ud -l wxtiffd -l wxjpegd -l wxpngd -l wxzlibd \ -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 WXDEFS=-DWIN32 -D__WXMSW__ -D_WINDOWS -DNOPCH DEBUGFLAGS=-g -D__WXDEBUG__ CFLAGS=-mthreads -O0 -w -Wno-invalid-offsetof -Wformat $(DEBUGFLAGS) $(WXDEFS) $(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 - +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 init.h sha.h all: bitcoin.exe -headers.h.gch: headers.h $(HEADERS) - g++ -c $(CFLAGS) -o $@ $< - -obj/util.o: util.cpp $(HEADERS) - g++ -c $(CFLAGS) -o $@ $< - -obj/script.o: script.cpp $(HEADERS) - g++ -c $(CFLAGS) -o $@ $< - -obj/db.o: db.cpp $(HEADERS) - g++ -c $(CFLAGS) -o $@ $< - -obj/net.o: net.cpp $(HEADERS) - g++ -c $(CFLAGS) -o $@ $< - -obj/main.o: main.cpp $(HEADERS) sha.h +headers.h.gch: headers.h $(HEADERS) g++ -c $(CFLAGS) -o $@ $< -obj/ui.o: ui.cpp $(HEADERS) +obj/%.o: %.cpp $(HEADERS) headers.h.gch g++ -c $(CFLAGS) -o $@ $< -obj/uibase.o: uibase.cpp uibase.h - g++ -c $(CFLAGS) -o $@ $< - -obj/sha.o: sha.cpp sha.h +obj/sha.o: sha.cpp sha.h g++ -c $(CFLAGS) -O3 -o $@ $< -obj/irc.o: irc.cpp $(HEADERS) - g++ -c $(CFLAGS) -o $@ $< - -obj/rpc.o: rpc.cpp $(HEADERS) - g++ -c $(CFLAGS) -o $@ $< - obj/ui_res.o: ui.rc rc/bitcoin.ico rc/check.ico rc/send16.bmp rc/send16mask.bmp rc/send16masknoshadow.bmp rc/send20.bmp rc/send20mask.bmp rc/addressbook16.bmp rc/addressbook16mask.bmp rc/addressbook20.bmp rc/addressbook20mask.bmp windres $(WXDEFS) $(INCLUDEPATHS) -o $@ -i $< +OBJS= \ + obj/util.o \ + obj/script.o \ + obj/db.o \ + obj/net.o \ + obj/irc.o \ + obj/main.o \ + obj/rpc.o \ + obj/init.o + +bitcoin.exe: $(OBJS) obj/ui.o obj/uibase.o obj/sha.o obj/ui_res.o + g++ $(CFLAGS) -mwindows -Wl,--subsystem,windows -o $@ $(LIBPATHS) $^ $(WXLIBS) $(LIBS) + +obj/nogui/%.o: %.cpp $(HEADERS) + g++ -c $(CFLAGS) -DwxUSE_GUI=0 -o $@ $< -OBJS=obj/util.o obj/script.o obj/db.o obj/net.o obj/main.o \ - obj/ui.o obj/uibase.o obj/sha.o obj/irc.o obj/rpc.o \ - obj/ui_res.o +bitcoind.exe: $(OBJS:obj/%=obj/nogui/%) obj/sha.o obj/ui_res.o + g++ $(CFLAGS) -o $@ $(LIBPATHS) $^ -l wxbase29ud $(LIBS) -bitcoin.exe: headers.h.gch $(OBJS) - -kill /f bitcoin.exe - g++ $(CFLAGS) -mwindows -Wl,--subsystem,windows -o $@ $(LIBPATHS) $(OBJS) $(LIBS) clean: -del /Q obj\* + -del /Q obj\nogui\* -del /Q headers.h.gch diff --git a/makefile.unix b/makefile.unix index a8ec936776..10c4eece73 100644 --- a/makefile.unix +++ b/makefile.unix @@ -13,66 +13,61 @@ LIBPATHS= \ -L"/usr/lib" \ -L"/usr/local/lib" +WXLIBS= \ + -Wl,-Bstatic \ + -l wx_gtk2ud-2.9 \ + -Wl,-Bdynamic \ + -l gtk-x11-2.0 -l SM + LIBS= \ -Wl,-Bstatic \ -l boost_system-mt -l boost_filesystem-mt \ -l db_cxx \ - -l wx_gtk2ud-2.9 \ -Wl,-Bdynamic \ -l crypto \ - -l gtk-x11-2.0 -l gthread-2.0 -l SM + -l gthread-2.0 WXDEFS=-D__WXGTK__ -DNOPCH DEBUGFLAGS=-g -D__WXDEBUG__ CFLAGS=-O0 -Wno-invalid-offsetof -Wformat $(DEBUGFLAGS) $(WXDEFS) $(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 - +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 init.h sha.h all: bitcoin -headers.h.gch: headers.h $(HEADERS) - g++ -c $(CFLAGS) -o $@ $< - -obj/util.o: util.cpp $(HEADERS) - g++ -c $(CFLAGS) -o $@ $< - -obj/script.o: script.cpp $(HEADERS) - g++ -c $(CFLAGS) -o $@ $< - -obj/db.o: db.cpp $(HEADERS) - g++ -c $(CFLAGS) -o $@ $< - -obj/net.o: net.cpp $(HEADERS) - g++ -c $(CFLAGS) -o $@ $< - -obj/main.o: main.cpp $(HEADERS) sha.h - g++ -c $(CFLAGS) -o $@ $< - -obj/ui.o: ui.cpp $(HEADERS) +headers.h.gch: headers.h $(HEADERS) g++ -c $(CFLAGS) -o $@ $< -obj/uibase.o: uibase.cpp uibase.h +obj/%.o: %.cpp $(HEADERS) headers.h.gch g++ -c $(CFLAGS) -o $@ $< -obj/sha.o: sha.cpp sha.h +obj/sha.o: sha.cpp sha.h g++ -c $(CFLAGS) -O3 -o $@ $< -obj/irc.o: irc.cpp $(HEADERS) - g++ -c $(CFLAGS) -o $@ $< +OBJS= \ + obj/util.o \ + obj/script.o \ + obj/db.o \ + obj/net.o \ + obj/irc.o \ + obj/main.o \ + obj/rpc.o \ + obj/init.o -obj/rpc.o: rpc.cpp $(HEADERS) - g++ -c $(CFLAGS) -o $@ $< +bitcoin: $(OBJS) obj/ui.o obj/uibase.o obj/sha.o + g++ $(CFLAGS) -o $@ $(LIBPATHS) $^ $(WXLIBS) $(LIBS) +obj/nogui/%.o: %.cpp $(HEADERS) + g++ -c $(CFLAGS) -DwxUSE_GUI=0 -o $@ $< -OBJS=obj/util.o obj/script.o obj/db.o obj/net.o obj/main.o \ - obj/ui.o obj/uibase.o obj/sha.o obj/irc.o obj/rpc.o +bitcoind: $(OBJS:obj/%=obj/nogui/%) obj/sha.o + g++ $(CFLAGS) -o $@ $(LIBPATHS) $^ -l wx_baseud-2.9 $(LIBS) -bitcoin: headers.h.gch $(OBJS) - g++ $(CFLAGS) -o $@ $(LIBPATHS) $(OBJS) $(LIBS) clean: -rm obj/* + -rm obj/nogui/* -rm headers.h.gch diff --git a/makefile.vc b/makefile.vc index c407be3d2f..41f13522a0 100644 --- a/makefile.vc +++ b/makefile.vc @@ -28,57 +28,80 @@ LIBS= \ WXDEFS=/DWIN32 /D__WXMSW__ /D_WINDOWS /DNOPCH DEBUGFLAGS=/Zi /Od /D__WXDEBUG__ CFLAGS=/c /nologo /Ob0 /MDd /EHsc /GR /Zm300 $(DEBUGFLAGS) $(WXDEFS) $(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 - +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 init.h sha.h all: bitcoin.exe -obj\util.obj: util.cpp $(HEADERS) - cl $(CFLAGS) /Fo$@ %s +.cpp{obj}.obj: + cl $(CFLAGS) /Fo$@ %s + +obj\util.obj: $(HEADERS) -obj\script.obj: script.cpp $(HEADERS) - cl $(CFLAGS) /Fo$@ %s +obj\script.obj: $(HEADERS) -obj\db.obj: db.cpp $(HEADERS) - cl $(CFLAGS) /Fo$@ %s +obj\db.obj: $(HEADERS) -obj\net.obj: net.cpp $(HEADERS) - cl $(CFLAGS) /Fo$@ %s +obj\net.obj: $(HEADERS) -obj\main.obj: main.cpp $(HEADERS) sha.h - cl $(CFLAGS) /Fo$@ %s +obj\irc.obj: $(HEADERS) -obj\ui.obj: ui.cpp $(HEADERS) - cl $(CFLAGS) /Fo$@ %s +obj\main.obj: $(HEADERS) -obj\uibase.obj: uibase.cpp uibase.h - cl $(CFLAGS) /Fo$@ %s +obj\rpc.obj: $(HEADERS) -obj\sha.obj: sha.cpp sha.h - cl $(CFLAGS) /O2 /Fo$@ %s +obj\init.obj: $(HEADERS) -obj\irc.obj: irc.cpp $(HEADERS) - cl $(CFLAGS) /Fo$@ %s +obj\ui.obj: $(HEADERS) -obj\rpc.obj: rpc.cpp $(HEADERS) - cl $(CFLAGS) /Fo$@ %s +obj\uibase.obj: $(HEADERS) + +obj\sha.obj: sha.cpp sha.h + cl $(CFLAGS) /O2 /Fo$@ %s obj\ui.res: ui.rc rc/bitcoin.ico rc/check.ico rc/send16.bmp rc/send16mask.bmp rc/send16masknoshadow.bmp rc/send20.bmp rc/send20mask.bmp rc/addressbook16.bmp rc/addressbook16mask.bmp rc/addressbook20.bmp rc/addressbook20mask.bmp - rc $(INCLUDEPATHS) $(WXDEFS) /Fo$@ %s + rc $(INCLUDEPATHS) $(WXDEFS) /Fo$@ %s + +OBJS= \ + obj\util.obj \ + obj\script.obj \ + obj\db.obj \ + obj\net.obj \ + obj\irc.obj \ + obj\main.obj \ + obj\rpc.obj \ + obj\init.obj + +bitcoin.exe: $(OBJS) obj\ui.obj obj\uibase.obj obj\sha.obj obj\ui.res + link /nologo /DEBUG /SUBSYSTEM:WINDOWS /OUT:$@ $(LIBPATHS) $** $(LIBS) + + +.cpp{obj\nogui}.obj: + cl $(CFLAGS) /DwxUSE_GUI=0 /Fo$@ %s + +obj\nogui\util.obj: $(HEADERS) + +obj\nogui\script.obj: $(HEADERS) + +obj\nogui\db.obj: $(HEADERS) + +obj\nogui\net.obj: $(HEADERS) + +obj\nogui\irc.obj: $(HEADERS) + +obj\nogui\main.obj: $(HEADERS) +obj\nogui\rpc.obj: $(HEADERS) +obj\nogui\init.obj: $(HEADERS) -OBJS=obj\util.obj obj\script.obj obj\db.obj obj\net.obj obj\main.obj \ - obj\ui.obj obj\uibase.obj obj\sha.obj obj\irc.obj obj\rpc.obj \ - obj\ui.res +bitcoind.exe: $(OBJS:obj\=obj\nogui\) obj\sha.obj obj\ui.res + link /nologo /DEBUG /OUT:$@ $(LIBPATHS) $** $(LIBS) -bitcoin.exe: $(OBJS) - -kill /f bitcoin.exe & sleep 1 - link /nologo /DEBUG /SUBSYSTEM:WINDOWS /OUT:$@ $(LIBPATHS) $** $(LIBS) clean: - -del /Q obj\* - -del *.ilk - -del *.pdb + -del /Q obj\* + -del *.ilk + -del *.pdb diff --git a/rpc.cpp b/rpc.cpp index 7f3e71dbac..f298137aa2 100644 --- a/rpc.cpp +++ b/rpc.cpp @@ -676,18 +676,18 @@ int CommandLineRPC(int argc, char *argv[]) string strResult = (result.type() == str_type ? result.get_str() : write_string(result, true)); if (result.type() != null_type) { - if (fWindows) + if (fWindows && fGUI) // Windows GUI apps can't print to command line, - // so for now settle for a message box yuck - wxMessageBox(strResult.c_str(), "Bitcoin", wxOK); + // so settle for a message box yuck + MyMessageBox(strResult.c_str(), "Bitcoin", wxOK); else fprintf(stdout, "%s\n", strResult.c_str()); } return 0; } catch (std::exception& e) { - if (fWindows) - wxMessageBox(strprintf("error: %s\n", e.what()).c_str(), "Bitcoin", wxOK); + if (fWindows && fGUI) + MyMessageBox(strprintf("error: %s\n", e.what()).c_str(), "Bitcoin", wxOK); else fprintf(stderr, "error: %s\n", e.what()); } catch (...) { diff --git a/serialize.h b/serialize.h index 8fb72a0aab..5399c23d02 100644 --- a/serialize.h +++ b/serialize.h @@ -19,7 +19,7 @@ class CScript; class CDataStream; class CAutoFile; -static const int VERSION = 206; +static const int VERSION = 207; static const char* pszSubVer = ".0"; diff --git a/ui.cpp b/ui.cpp index 748b4dad93..efb05385ec 100644 --- a/ui.cpp +++ b/ui.cpp @@ -7,38 +7,18 @@ #include #endif -bool GetStartOnSystemStartup(); -void SetStartOnSystemStartup(bool fAutoStart); - DEFINE_EVENT_TYPE(wxEVT_UITHREADCALL) CMainFrame* pframeMain = NULL; CMyTaskBarIcon* ptaskbaricon = NULL; -extern int g_isPainting; bool fClosedToTray = false; -// Settings -int fMinimizeToTray = true; -int fMinimizeOnClose = true; -int MyMessageBox(const wxString& message, const wxString& caption="Message", int style=wxOK, wxWindow* parent=NULL, int x=-1, int y=-1) -{ - if (fDaemon) - { - printf("wxMessageBox %s: %s\n", string(caption).c_str(), string(message).c_str()); - fprintf(stderr, "%s: %s\n", string(caption).c_str(), string(message).c_str()); - return wxOK; - } - return wxMessageBox(message, caption, style, parent, x, y); -} -#define wxMessageBox MyMessageBox - - @@ -48,47 +28,6 @@ int MyMessageBox(const wxString& message, const wxString& caption="Message", int // Util // -void ExitTimeout(void* parg) -{ -#ifdef __WXMSW__ - Sleep(5000); - ExitProcess(0); -#endif -} - -void Shutdown(void* parg) -{ - static CCriticalSection cs_Shutdown; - static bool fTaken; - bool fFirstThread; - CRITICAL_BLOCK(cs_Shutdown) - { - fFirstThread = !fTaken; - fTaken = true; - } - static bool fExit; - if (fFirstThread) - { - fShutdown = true; - nTransactionsUpdated++; - DBFlush(false); - StopNode(); - DBFlush(true); - CreateThread(ExitTimeout, NULL); - Sleep(50); - printf("Bitcoin exiting\n\n"); - fExit = true; - exit(0); - } - else - { - while (!fExit) - Sleep(500); - Sleep(100); - ExitThread(0); - } -} - void HandleCtrlA(wxKeyEvent& event) { // Ctrl-a select all @@ -312,7 +251,7 @@ CMainFrame::CMainFrame(wxWindow* parent) : CMainFrameBase(parent) m_staticTextBalance->SetSize(140, 17); // resize to fit ubuntu's huge default font dResize = 1.22; - SetSize(dResize * GetSize().GetWidth(), 1.09 * GetSize().GetHeight()); + SetSize(dResize * GetSize().GetWidth(), 1.15 * GetSize().GetHeight()); #endif m_staticTextBalance->SetLabel(FormatMoney(GetBalance()) + " "); m_listCtrl->SetFocus(); @@ -1630,7 +1569,6 @@ void COptionsDialog::OnButtonApply(wxCommandEvent& event) - ////////////////////////////////////////////////////////////////////////////// // // CAboutDialog @@ -2014,7 +1952,7 @@ void CSendingDialog::StartTransfer() // Make sure we have enough money if (nPrice + nTransactionFee > GetBalance()) { - Error(_("You don't have enough money")); + Error(_("Insufficient funds")); return; } @@ -2081,7 +2019,7 @@ void CSendingDialog::OnReply2(CDataStream& vRecv) return; if (nPrice + nTransactionFee > GetBalance()) { - Error(_("You don't have enough money")); + Error(_("Insufficient funds")); return; } CKey key; @@ -2562,602 +2500,21 @@ wxMenu* CMyTaskBarIcon::CreatePopupMenu() -////////////////////////////////////////////////////////////////////////////// -// -// CMyApp -// - -// Define a new application -class CMyApp: public wxApp -{ -public: - wxLocale m_locale; - - 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) -{ - if (argc > 1 && argv[1][0] != '-' && (!fWindows || argv[1][0] != '/') && - wxString(argv[1]) != "start") - { - fCommandLine = true; - } - else - { - // 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] = '-'; - str = str.MakeLower(); - #endif - // haven't decided which argument to use for this yet - if (str == "-daemon" || str == "-d" || str == "start") - 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) - { - fprintf(stdout, "bitcoin server starting\n"); - - // 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); - } - - return true; - } -#endif - - return wxApp::Initialize(argc, argv); -} - -bool CMyApp::OnInit() -{ - bool fRet = false; - try - { - fRet = OnInit2(); - } - catch (std::exception& e) { - PrintException(&e, "OnInit()"); - } catch (...) { - PrintException(NULL, "OnInit()"); - } - if (!fRet) - Shutdown(NULL); - return fRet; -} - -bool CMyApp::OnInit2() -{ -#ifdef _MSC_VER - // Turn off microsoft heap dump noise - _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE); - _CrtSetReportFile(_CRT_WARN, CreateFileA("NUL", GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0)); -#endif -#if defined(__WXMSW__) && defined(__WXDEBUG__) - // Disable malfunctioning wxWidgets debug assertion - g_isPainting = 10000; -#endif - wxImage::AddHandler(new wxPNGHandler); -#ifdef __WXMSW__ - SetAppName("Bitcoin"); -#else - SetAppName("bitcoin"); - umask(077); -#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//LC_MESSAGES/bitcoin.mo language file - m_locale.Init(wxLANGUAGE_DEFAULT, 0); - m_locale.AddCatalogLookupPathPrefix("locale"); - if (!fWindows) - { - m_locale.AddCatalogLookupPathPrefix("/usr/share/locale"); - m_locale.AddCatalogLookupPathPrefix("/usr/local/share/locale"); - } - m_locale.AddCatalog("wxstd"); // wxWidgets standard translations, if any - m_locale.AddCatalog("bitcoin"); - - // - // Parameters - // - if (fCommandLine) - { - int ret = CommandLineRPC(argc, argv); - exit(ret); - } - - ParseParameters(argc, argv); - if (mapArgs.count("-?") || mapArgs.count("--help")) - { - wxString strUsage = string() + - _("Usage: bitcoin [options]") + "\t\t\t\t\t\t\n" + - _("Options:\n") + - " -gen \t\t " + _("Generate coins\n") + - " -gen=0 \t\t " + _("Don't generate coins\n") + - " -min \t\t " + _("Start minimized\n") + - " -datadir= \t " + _("Specify data directory\n") + - " -proxy=\t " + _("Connect through socks4 proxy\n") + - " -addnode= \t " + _("Add a node to connect to\n") + - " -connect= \t " + _("Connect only to the specified node\n") + - " -? \t\t " + _("This help message\n"); - - if (fWindows) - { - // Remove spaces, the tabs make the columns line up in the message box - for (int i = 0; i < 50; i++) - strUsage.Replace(" \t", "\t"); - wxMessageBox(strUsage, "Bitcoin", wxOK); - } - else - { - // Remove tabs - strUsage.Replace("\t", ""); - fprintf(stderr, "%s", ((string)strUsage).c_str()); - } - return false; - } - - if (mapArgs.count("-datadir")) - strlcpy(pszSetDataDir, mapArgs["-datadir"].c_str(), sizeof(pszSetDataDir)); - - if (mapArgs.count("-debug")) - fDebug = true; - - if (mapArgs.count("-printtodebugger")) - fPrintToDebugger = true; - - if (!fDebug && !pszSetDataDir[0]) - 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 0.%d.%d%s beta, OS version %s\n", VERSION/100, VERSION%100, pszSubVer, ((string)wxGetOsDescription()).c_str()); - printf("System default language is %d %s\n", m_locale.GetSystemLanguage(), ((string)m_locale.GetSysName()).c_str()); - printf("Language file %s (%s)\n", (string("locale/") + (string)m_locale.GetCanonicalName() + "/LC_MESSAGES/bitcoin.mo").c_str(), ((string)m_locale.GetLocale()).c_str()); - - if (mapArgs.count("-loadblockindextest")) - { - CTxDB txdb("r"); - txdb.LoadBlockIndex(); - PrintBlockTree(); - return false; - } - - // - // Limit to single instance per user - // Required to protect the database files if we're going to keep deleting log.* - // -#ifdef __WXMSW__ - // todo: wxSingleInstanceChecker wasn't working on Linux, never deleted its lock file - // maybe should go by whether successfully bind port 8333 instead - 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 - { - // TODO: find out how to do this in Linux, or replace with wxWidgets commands - // 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 - - // Bind to the port early so we can tell if another instance is already running. - // This is a backup to wxSingleInstanceChecker, which doesn't work on Linux. - string strErrors; - if (!BindListenPort(strErrors)) - { - wxMessageBox(strErrors, "Bitcoin"); - return false; - } - - // - // Load data files - // - bool fFirstRun; - strErrors = ""; - int64 nStart; - - printf("Loading addresses...\n"); - nStart = GetTimeMillis(); - if (!LoadAddresses()) - strErrors += _("Error loading addr.dat \n"); - printf(" addresses %15"PRI64d"ms\n", GetTimeMillis() - nStart); - - printf("Loading block index...\n"); - nStart = GetTimeMillis(); - if (!LoadBlockIndex()) - strErrors += _("Error loading blkindex.dat \n"); - printf(" block index %15"PRI64d"ms\n", GetTimeMillis() - nStart); - - printf("Loading wallet...\n"); - nStart = GetTimeMillis(); - if (!LoadWallet(fFirstRun)) - strErrors += _("Error loading wallet.dat \n"); - printf(" wallet %15"PRI64d"ms\n", GetTimeMillis() - nStart); - - printf("Done loading\n"); - - //// debug print - printf("mapBlockIndex.size() = %d\n", mapBlockIndex.size()); - printf("nBestHeight = %d\n", nBestHeight); - printf("mapKeys.size() = %d\n", mapKeys.size()); - printf("mapPubKeys.size() = %d\n", mapPubKeys.size()); - printf("mapWallet.size() = %d\n", mapWallet.size()); - printf("mapAddressBook.size() = %d\n", mapAddressBook.size()); - - if (!strErrors.empty()) - { - wxMessageBox(strErrors, "Bitcoin"); - return false; - } - - // Add wallet transactions that aren't already in a block to mapTransactions - ReacceptWalletTransactions(); - - // - // Parameters - // - if (mapArgs.count("-printblockindex") || mapArgs.count("-printblocktree")) - { - PrintBlockTree(); - return false; - } - - if (mapArgs.count("-printblock")) - { - string strMatch = mapArgs["-printblock"]; - int nFound = 0; - for (map::iterator mi = mapBlockIndex.begin(); mi != mapBlockIndex.end(); ++mi) - { - uint256 hash = (*mi).first; - if (strncmp(hash.ToString().c_str(), strMatch.c_str(), strMatch.size()) == 0) - { - CBlockIndex* pindex = (*mi).second; - CBlock block; - block.ReadFromDisk(pindex); - block.BuildMerkleTree(); - block.print(); - printf("\n"); - nFound++; - } - } - if (nFound == 0) - printf("No blocks matching %s were found\n", strMatch.c_str()); - return false; - } - - if (mapArgs.count("-gen")) - { - if (mapArgs["-gen"].empty()) - fGenerateBitcoins = true; - else - fGenerateBitcoins = (atoi(mapArgs["-gen"].c_str()) != 0); - } - - if (mapArgs.count("-proxy")) - { - fUseProxy = true; - addrProxy = CAddress(mapArgs["-proxy"]); - if (!addrProxy.IsValid()) - { - wxMessageBox(_("Invalid -proxy address"), "Bitcoin"); - return false; - } - } - - if (mapArgs.count("-addnode")) - { - foreach(string strAddr, mapMultiArgs["-addnode"]) - { - CAddress addr(strAddr, NODE_NETWORK); - addr.nTime = 0; // so it won't relay unless successfully connected - if (addr.IsValid()) - AddAddress(addr); - } - } - - // - // Create the main frame window - // - if (!fDaemon) - { - pframeMain = new CMainFrame(NULL); - if (mapArgs.count("-min")) - pframeMain->Iconize(true); - 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); - } - - if (!CheckDiskSpace()) - return false; - - RandAddSeedPerfmon(); - - if (!CreateThread(StartNode, NULL)) - wxMessageBox("Error: CreateThread(StartNode) failed", "Bitcoin"); - - if (mapArgs.count("-server") || fDaemon) - CreateThread(ThreadRPCServer, NULL); - - if (fFirstRun) - SetStartOnSystemStartup(true); - - - // - // Tests - // -#ifdef __WXMSW__ - if (argc >= 2 && stricmp(argv[1], "-send") == 0) -#else - if (argc >= 2 && strcmp(argv[1], "-send") == 0) -#endif - { - int64 nValue = 1; - if (argc >= 3) - ParseMoney(argv[2], nValue); - - string strAddress; - if (argc >= 4) - strAddress = argv[3]; - CAddress addr(strAddress); - - CWalletTx wtx; - wtx.mapValue["to"] = strAddress; - wtx.mapValue["from"] = addrLocalHost.ToString(); - wtx.mapValue["message"] = "command line send"; - - // Send to IP address - CSendingDialog* pdialog = new CSendingDialog(pframeMain, addr, nValue, wtx); - if (!pdialog->ShowModal()) - return false; - } - - return true; -} - -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); -} - - - - - -#ifdef __WXMSW__ -typedef WINSHELLAPI BOOL (WINAPI *PSHGETSPECIALFOLDERPATHA)(HWND hwndOwner, LPSTR lpszPath, int nFolder, BOOL fCreate); - -string MyGetSpecialFolderPath(int nFolder, bool fCreate) -{ - char pszPath[MAX_PATH+100] = ""; - - // SHGetSpecialFolderPath is not usually available on NT 4.0 - HMODULE hShell32 = LoadLibraryA("shell32.dll"); - if (hShell32) - { - PSHGETSPECIALFOLDERPATHA pSHGetSpecialFolderPath = - (PSHGETSPECIALFOLDERPATHA)GetProcAddress(hShell32, "SHGetSpecialFolderPathA"); - if (pSHGetSpecialFolderPath) - (*pSHGetSpecialFolderPath)(NULL, pszPath, nFolder, fCreate); - FreeModule(hShell32); - } - - // Backup option - if (pszPath[0] == '\0') - { - if (nFolder == CSIDL_STARTUP) - { - strcpy(pszPath, getenv("USERPROFILE")); - strcat(pszPath, "\\Start Menu\\Programs\\Startup"); - } - else if (nFolder == CSIDL_APPDATA) - { - strcpy(pszPath, getenv("APPDATA")); - } - } - - return pszPath; -} -string StartupShortcutPath() -{ - return MyGetSpecialFolderPath(CSIDL_STARTUP, true) + "\\Bitcoin.lnk"; -} -bool GetStartOnSystemStartup() -{ - return wxFileExists(StartupShortcutPath()); -} -void SetStartOnSystemStartup(bool fAutoStart) +void CreateMainWindow() { - // 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(&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(&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(); - } + pframeMain = new CMainFrame(NULL); + if (mapArgs.count("-min")) + pframeMain->Iconize(true); + 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); } -#else -bool GetStartOnSystemStartup() { return false; } -void SetStartOnSystemStartup(bool fAutoStart) { } -#endif - diff --git a/ui.h b/ui.h index acabd5514a..e944eb9339 100644 --- a/ui.h +++ b/ui.h @@ -4,26 +4,61 @@ DECLARE_EVENT_TYPE(wxEVT_UITHREADCALL, -1) +#if wxUSE_GUI +static const bool fGUI=true; +#else +static const bool fGUI=false; +#endif -extern map mapArgs; +inline int MyMessageBox(const wxString& message, const wxString& caption="Message", int style=wxOK, wxWindow* parent=NULL, int x=-1, int y=-1) +{ +#if wxUSE_GUI + if (!fDaemon) + return wxMessageBox(message, caption, style, parent, x, y); +#endif + printf("wxMessageBox %s: %s\n", string(caption).c_str(), string(message).c_str()); + fprintf(stderr, "%s: %s\n", string(caption).c_str(), string(message).c_str()); + return wxOK; +} +#define wxMessageBox MyMessageBox -// Settings -extern int fMinimizeToTray; -extern int fMinimizeOnClose; void HandleCtrlA(wxKeyEvent& event); string FormatTxStatus(const CWalletTx& wtx); void UIThreadCall(boost::function0); -void MainFrameRepaint(); -void Shutdown(void* parg); int ThreadSafeMessageBox(const string& message, const string& caption="Message", int style=wxOK, wxWindow* parent=NULL, int x=-1, int y=-1); bool ThreadSafeAskFee(int64 nFeeRequired, const string& strCaption, wxWindow* parent); +void MainFrameRepaint(); +void CreateMainWindow(); + +#if !wxUSE_GUI +inline int ThreadSafeMessageBox(const string& message, const string& caption, int style, wxWindow* parent, int x, int y) +{ + return MyMessageBox(message, caption, style, parent, x, y); +} + +inline bool ThreadSafeAskFee(int64 nFeeRequired, const string& strCaption, wxWindow* parent) +{ + return true; +} + +inline void MainFrameRepaint() +{ +} + +inline void CreateMainWindow() +{ +} +#else // wxUSE_GUI + + + class CMainFrame : public CMainFrameBase @@ -331,3 +366,5 @@ public: DECLARE_EVENT_TABLE() }; + +#endif // wxUSE_GUI diff --git a/util.cpp b/util.cpp index 6ea735d1e2..d90cdc48f9 100644 --- a/util.cpp +++ b/util.cpp @@ -459,6 +459,7 @@ const char* wxGetTranslation(const char* pszEnglish) mapCache[pszEnglish] = pszCached; return pszCached; } + return NULL; } @@ -502,8 +503,8 @@ void PrintException(std::exception* pex, const char* pszThread) FormatException(pszMessage, pex, pszThread); printf("\n\n************************\n%s\n", pszMessage); fprintf(stderr, "\n\n************************\n%s\n", pszMessage); - if (wxTheApp && !fDaemon) - wxMessageBox(pszMessage, "Error", wxOK | wxICON_ERROR); + if (wxTheApp && !fDaemon && fGUI) + MyMessageBox(pszMessage, "Error", wxOK | wxICON_ERROR); throw; //DebugBreak(); } -- cgit v1.2.3 From 8a46ed83cc65707fab87f93ab59e9a611dd02a06 Mon Sep 17 00:00:00 2001 From: s_nakamoto Date: Fri, 26 Feb 2010 16:09:43 +0000 Subject: wx/utils.h and wx/clipbrd.h not needed on bitcoind wxbase build --- headers.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/headers.h b/headers.h index 3c8d32cad9..44a00debed 100644 --- a/headers.h +++ b/headers.h @@ -19,11 +19,11 @@ #define WIN32_LEAN_AND_MEAN 1 #define __STDC_LIMIT_MACROS // to enable UINT64_MAX from stdint.h #include -#include -#include #include -#include +#include #if wxUSE_GUI +#include +#include #include #endif #include -- cgit v1.2.3 From 6557910ccf36e098b1a0de4841be7c04c4ffd58a Mon Sep 17 00:00:00 2001 From: s_nakamoto Date: Fri, 26 Feb 2010 16:09:43 +0000 Subject: wx/utils.h and wx/clipbrd.h not needed on bitcoind wxbase build git-svn-id: https://bitcoin.svn.sourceforge.net/svnroot/bitcoin/trunk@72 1a98c847-1fd6-4fd8-948a-caf3550aa51b --- headers.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/headers.h b/headers.h index 3c8d32cad9..44a00debed 100644 --- a/headers.h +++ b/headers.h @@ -19,11 +19,11 @@ #define WIN32_LEAN_AND_MEAN 1 #define __STDC_LIMIT_MACROS // to enable UINT64_MAX from stdint.h #include -#include -#include #include -#include +#include #if wxUSE_GUI +#include +#include #include #endif #include -- cgit v1.2.3 From 9a3358220449e75966bb188f2dc49310107b676d Mon Sep 17 00:00:00 2001 From: s_nakamoto Date: Sun, 28 Feb 2010 15:00:32 +0000 Subject: fix unsafe string handling in wxGetTranslation --- makefile.vc | 18 +++++++++--------- serialize.h | 2 +- util.cpp | 8 ++++---- 3 files changed, 14 insertions(+), 14 deletions(-) diff --git a/makefile.vc b/makefile.vc index 41f13522a0..9f821771e7 100644 --- a/makefile.vc +++ b/makefile.vc @@ -36,7 +36,7 @@ all: bitcoin.exe .cpp{obj}.obj: - cl $(CFLAGS) /Fo$@ %s + cl $(CFLAGS) /Fo$@ %s obj\util.obj: $(HEADERS) @@ -59,10 +59,10 @@ obj\ui.obj: $(HEADERS) obj\uibase.obj: $(HEADERS) obj\sha.obj: sha.cpp sha.h - cl $(CFLAGS) /O2 /Fo$@ %s + cl $(CFLAGS) /O2 /Fo$@ %s obj\ui.res: ui.rc rc/bitcoin.ico rc/check.ico rc/send16.bmp rc/send16mask.bmp rc/send16masknoshadow.bmp rc/send20.bmp rc/send20mask.bmp rc/addressbook16.bmp rc/addressbook16mask.bmp rc/addressbook20.bmp rc/addressbook20mask.bmp - rc $(INCLUDEPATHS) $(WXDEFS) /Fo$@ %s + rc $(INCLUDEPATHS) $(WXDEFS) /Fo$@ %s OBJS= \ obj\util.obj \ @@ -75,11 +75,11 @@ OBJS= \ obj\init.obj bitcoin.exe: $(OBJS) obj\ui.obj obj\uibase.obj obj\sha.obj obj\ui.res - link /nologo /DEBUG /SUBSYSTEM:WINDOWS /OUT:$@ $(LIBPATHS) $** $(LIBS) + link /nologo /DEBUG /SUBSYSTEM:WINDOWS /OUT:$@ $(LIBPATHS) $** $(LIBS) .cpp{obj\nogui}.obj: - cl $(CFLAGS) /DwxUSE_GUI=0 /Fo$@ %s + cl $(CFLAGS) /DwxUSE_GUI=0 /Fo$@ %s obj\nogui\util.obj: $(HEADERS) @@ -98,10 +98,10 @@ obj\nogui\rpc.obj: $(HEADERS) obj\nogui\init.obj: $(HEADERS) bitcoind.exe: $(OBJS:obj\=obj\nogui\) obj\sha.obj obj\ui.res - link /nologo /DEBUG /OUT:$@ $(LIBPATHS) $** $(LIBS) + link /nologo /DEBUG /OUT:$@ $(LIBPATHS) $** $(LIBS) clean: - -del /Q obj\* - -del *.ilk - -del *.pdb + -del /Q obj\* + -del *.ilk + -del *.pdb diff --git a/serialize.h b/serialize.h index 5399c23d02..77dfa95bb9 100644 --- a/serialize.h +++ b/serialize.h @@ -20,7 +20,7 @@ class CDataStream; class CAutoFile; static const int VERSION = 207; -static const char* pszSubVer = ".0"; +static const char* pszSubVer = ".1"; diff --git a/util.cpp b/util.cpp index d90cdc48f9..09de89b10f 100644 --- a/util.cpp +++ b/util.cpp @@ -445,17 +445,17 @@ const char* wxGetTranslation(const char* pszEnglish) return (*mi).second; // wxWidgets translation - const char* pszTranslated = wxGetTranslation(wxString(pszEnglish, wxConvUTF8)).utf8_str(); + wxString strTranslated = wxGetTranslation(wxString(pszEnglish, wxConvUTF8)); // 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, pszTranslated) == 0) + if (strcmp(pszEnglish, strTranslated.utf8_str()) == 0) return pszEnglish; // 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(pszTranslated)+1]; - strcpy(pszCached, pszTranslated); + char* pszCached = new char[strlen(strTranslated.utf8_str())+1]; + strcpy(pszCached, strTranslated.utf8_str()); mapCache[pszEnglish] = pszCached; return pszCached; } -- cgit v1.2.3 From d7d80a74d58152453cfb0c71a08f6b424d2493c9 Mon Sep 17 00:00:00 2001 From: s_nakamoto Date: Sun, 28 Feb 2010 15:00:32 +0000 Subject: fix unsafe string handling in wxGetTranslation git-svn-id: https://bitcoin.svn.sourceforge.net/svnroot/bitcoin/trunk@73 1a98c847-1fd6-4fd8-948a-caf3550aa51b --- makefile.vc | 18 +++++++++--------- serialize.h | 2 +- util.cpp | 8 ++++---- 3 files changed, 14 insertions(+), 14 deletions(-) diff --git a/makefile.vc b/makefile.vc index 41f13522a0..9f821771e7 100644 --- a/makefile.vc +++ b/makefile.vc @@ -36,7 +36,7 @@ all: bitcoin.exe .cpp{obj}.obj: - cl $(CFLAGS) /Fo$@ %s + cl $(CFLAGS) /Fo$@ %s obj\util.obj: $(HEADERS) @@ -59,10 +59,10 @@ obj\ui.obj: $(HEADERS) obj\uibase.obj: $(HEADERS) obj\sha.obj: sha.cpp sha.h - cl $(CFLAGS) /O2 /Fo$@ %s + cl $(CFLAGS) /O2 /Fo$@ %s obj\ui.res: ui.rc rc/bitcoin.ico rc/check.ico rc/send16.bmp rc/send16mask.bmp rc/send16masknoshadow.bmp rc/send20.bmp rc/send20mask.bmp rc/addressbook16.bmp rc/addressbook16mask.bmp rc/addressbook20.bmp rc/addressbook20mask.bmp - rc $(INCLUDEPATHS) $(WXDEFS) /Fo$@ %s + rc $(INCLUDEPATHS) $(WXDEFS) /Fo$@ %s OBJS= \ obj\util.obj \ @@ -75,11 +75,11 @@ OBJS= \ obj\init.obj bitcoin.exe: $(OBJS) obj\ui.obj obj\uibase.obj obj\sha.obj obj\ui.res - link /nologo /DEBUG /SUBSYSTEM:WINDOWS /OUT:$@ $(LIBPATHS) $** $(LIBS) + link /nologo /DEBUG /SUBSYSTEM:WINDOWS /OUT:$@ $(LIBPATHS) $** $(LIBS) .cpp{obj\nogui}.obj: - cl $(CFLAGS) /DwxUSE_GUI=0 /Fo$@ %s + cl $(CFLAGS) /DwxUSE_GUI=0 /Fo$@ %s obj\nogui\util.obj: $(HEADERS) @@ -98,10 +98,10 @@ obj\nogui\rpc.obj: $(HEADERS) obj\nogui\init.obj: $(HEADERS) bitcoind.exe: $(OBJS:obj\=obj\nogui\) obj\sha.obj obj\ui.res - link /nologo /DEBUG /OUT:$@ $(LIBPATHS) $** $(LIBS) + link /nologo /DEBUG /OUT:$@ $(LIBPATHS) $** $(LIBS) clean: - -del /Q obj\* - -del *.ilk - -del *.pdb + -del /Q obj\* + -del *.ilk + -del *.pdb diff --git a/serialize.h b/serialize.h index 5399c23d02..77dfa95bb9 100644 --- a/serialize.h +++ b/serialize.h @@ -20,7 +20,7 @@ class CDataStream; class CAutoFile; static const int VERSION = 207; -static const char* pszSubVer = ".0"; +static const char* pszSubVer = ".1"; diff --git a/util.cpp b/util.cpp index d90cdc48f9..09de89b10f 100644 --- a/util.cpp +++ b/util.cpp @@ -445,17 +445,17 @@ const char* wxGetTranslation(const char* pszEnglish) return (*mi).second; // wxWidgets translation - const char* pszTranslated = wxGetTranslation(wxString(pszEnglish, wxConvUTF8)).utf8_str(); + wxString strTranslated = wxGetTranslation(wxString(pszEnglish, wxConvUTF8)); // 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, pszTranslated) == 0) + if (strcmp(pszEnglish, strTranslated.utf8_str()) == 0) return pszEnglish; // 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(pszTranslated)+1]; - strcpy(pszCached, pszTranslated); + char* pszCached = new char[strlen(strTranslated.utf8_str())+1]; + strcpy(pszCached, strTranslated.utf8_str()); mapCache[pszEnglish] = pszCached; return pszCached; } -- cgit v1.2.3 From 91e615bfecaa0958cb178176a52318edca3dfda5 Mon Sep 17 00:00:00 2001 From: s_nakamoto Date: Fri, 5 Mar 2010 01:13:27 +0000 Subject: fixed runaway memory alloc bug on 64-bit in ParseString found by sirius-m --- util.cpp | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/util.cpp b/util.cpp index 09de89b10f..acfbcd6c90 100644 --- a/util.cpp +++ b/util.cpp @@ -282,15 +282,21 @@ bool error(const char* format, ...) void ParseString(const string& str, char c, vector& v) { - unsigned int i1 = 0; - unsigned int i2; - do + if (str.empty()) + return; + string::size_type i1 = 0; + string::size_type i2; + loop { i2 = str.find(c, i1); + if (i2 == str.npos) + { + v.push_back(str.substr(i1)); + return; + } v.push_back(str.substr(i1, i2-i1)); i1 = i2+1; } - while (i2 != str.npos); } -- cgit v1.2.3 From 2cffa7ce315d9b98d35192d16927b44d21b9e1a7 Mon Sep 17 00:00:00 2001 From: s_nakamoto Date: Fri, 5 Mar 2010 01:13:27 +0000 Subject: fixed runaway memory alloc bug on 64-bit in ParseString found by sirius-m git-svn-id: https://bitcoin.svn.sourceforge.net/svnroot/bitcoin/trunk@74 1a98c847-1fd6-4fd8-948a-caf3550aa51b --- util.cpp | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/util.cpp b/util.cpp index 09de89b10f..acfbcd6c90 100644 --- a/util.cpp +++ b/util.cpp @@ -282,15 +282,21 @@ bool error(const char* format, ...) void ParseString(const string& str, char c, vector& v) { - unsigned int i1 = 0; - unsigned int i2; - do + if (str.empty()) + return; + string::size_type i1 = 0; + string::size_type i2; + loop { i2 = str.find(c, i1); + if (i2 == str.npos) + { + v.push_back(str.substr(i1)); + return; + } v.push_back(str.substr(i1, i2-i1)); i1 = i2+1; } - while (i2 != str.npos); } -- cgit v1.2.3 From 288424ad632da2eade1d8937bb513add131e22dd Mon Sep 17 00:00:00 2001 From: s_nakamoto Date: Fri, 5 Mar 2010 02:55:09 +0000 Subject: misc --- irc.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/irc.cpp b/irc.cpp index 9d563cce8d..de0b997abe 100644 --- a/irc.cpp +++ b/irc.cpp @@ -76,6 +76,8 @@ bool RecvLine(SOCKET hSocket, string& strLine) if (c == '\r') return true; strLine += c; + if (strLine.size() >= 9000) + return true; } else if (nBytes <= 0) { @@ -109,7 +111,7 @@ bool RecvLineIRC(SOCKET hSocket, string& strLine) return false; vector vWords; ParseString(strLine, ' ', vWords); - if (vWords[0] == "PING") + if (vWords.size() >= 1 && vWords[0] == "PING") { strLine[1] = 'O'; strLine += '\r'; @@ -156,6 +158,7 @@ bool Wait(int nSeconds) void ThreadIRCSeed(void* parg) { + printf("ThreadIRCSeed started\n"); SetThreadPriority(THREAD_PRIORITY_NORMAL); int nErrorWait = 10; int nRetryWait = 10; -- cgit v1.2.3 From 966cca4bd4a6d869583fb47f5f66ed4672c007ff Mon Sep 17 00:00:00 2001 From: s_nakamoto Date: Fri, 5 Mar 2010 02:55:09 +0000 Subject: misc git-svn-id: https://bitcoin.svn.sourceforge.net/svnroot/bitcoin/trunk@75 1a98c847-1fd6-4fd8-948a-caf3550aa51b --- irc.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/irc.cpp b/irc.cpp index 9d563cce8d..de0b997abe 100644 --- a/irc.cpp +++ b/irc.cpp @@ -76,6 +76,8 @@ bool RecvLine(SOCKET hSocket, string& strLine) if (c == '\r') return true; strLine += c; + if (strLine.size() >= 9000) + return true; } else if (nBytes <= 0) { @@ -109,7 +111,7 @@ bool RecvLineIRC(SOCKET hSocket, string& strLine) return false; vector vWords; ParseString(strLine, ' ', vWords); - if (vWords[0] == "PING") + if (vWords.size() >= 1 && vWords[0] == "PING") { strLine[1] = 'O'; strLine += '\r'; @@ -156,6 +158,7 @@ bool Wait(int nSeconds) void ThreadIRCSeed(void* parg) { + printf("ThreadIRCSeed started\n"); SetThreadPriority(THREAD_PRIORITY_NORMAL); int nErrorWait = 10; int nRetryWait = 10; -- cgit v1.2.3 From 240f3fbe2faca50a99e171afade28104cd7b0e30 Mon Sep 17 00:00:00 2001 From: s_nakamoto Date: Wed, 19 May 2010 00:26:56 +0000 Subject: Mac OS build fixes by laszlo -- version 0.2.8 --- init.cpp | 8 +++++++- main.cpp | 6 +++--- net.cpp | 4 +--- net.h | 43 +++++++++++++++++++++++++++---------------- rpc.cpp | 23 ++++++++++++++--------- serialize.h | 4 ++-- ui.cpp | 15 ++++++++++++--- uibase.cpp | 14 +++++++------- uibase.h | 45 ++++++++++++++++++++++----------------------- uiproject.fbp | 14 +++++++------- util.cpp | 6 ++++++ util.h | 1 + 12 files changed, 109 insertions(+), 74 deletions(-) diff --git a/init.cpp b/init.cpp index 06d8f4c933..db8886e119 100644 --- a/init.cpp +++ b/init.cpp @@ -284,6 +284,10 @@ bool CMyApp::OnInit2() _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE); _CrtSetReportFile(_CRT_WARN, CreateFileA("NUL", GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0)); #endif +#if _MSC_VER >= 1400 + // Disable confusing "helpful" text message on abort, ctrl-c + _set_abort_behavior(0, _WRITE_ABORT_MSG | _CALL_REPORTFAULT); +#endif #if defined(__WXMSW__) && defined(__WXDEBUG__) && wxUSE_GUI // Disable malfunctioning wxWidgets debug assertion g_isPainting = 10000; @@ -291,10 +295,12 @@ bool CMyApp::OnInit2() #if wxUSE_GUI wxImage::AddHandler(new wxPNGHandler); #endif -#ifdef __WXMSW__ +#if defined(__WXMSW__ ) || defined(__WXMAC__) SetAppName("Bitcoin"); #else SetAppName("bitcoin"); +#endif +#ifndef __WXMSW__ umask(077); #endif #ifdef __WXMSW__ diff --git a/main.cpp b/main.cpp index f7416230f6..ad0208a252 100644 --- a/main.cpp +++ b/main.cpp @@ -1338,7 +1338,7 @@ bool CBlock::AcceptBlock() // Don't relay old inventory during initial block download. // Please keep this number updated to a few thousand below current block count. - if (hashBestChain == hash && nBestHeight > 40000) + if (hashBestChain == hash && nBestHeight > 55000) RelayInventory(CInv(MSG_BLOCK, hash)); // // Add atoms to user reviews for coins created @@ -2255,9 +2255,9 @@ bool SendMessages(CNode* pto) // Delay tx inv messages to protect privacy, // trickle them out to a few nodes at a time. bool fSendTxInv = false; - if (GetTimeMillis() - pto->nLastSentTxInv > 1800 + GetRand(200)) + if (GetTimeMillis() > pto->nNextSendTxInv) { - pto->nLastSentTxInv = GetTimeMillis(); + pto->nNextSendTxInv = GetTimeMillis() + 3000 + GetRand(2000); fSendTxInv = true; } diff --git a/net.cpp b/net.cpp index 8e8127d73b..fbfa746221 100644 --- a/net.cpp +++ b/net.cpp @@ -927,9 +927,7 @@ void ThreadOpenConnections2(void* parg) continue; // Only try the old stuff if we don't have enough connections - if (vNodes.size() >= 2 && nSinceLastSeen > 7 * 24 * 60 * 60) - continue; - if (vNodes.size() >= 5 && nSinceLastSeen > 24 * 60 * 60) + if (vNodes.size() >= 8 && nSinceLastSeen > 24 * 60 * 60) continue; // If multiple addresses are ready, prioritize by time since diff --git a/net.h b/net.h index c7d15460a4..1593a975a3 100644 --- a/net.h +++ b/net.h @@ -45,6 +45,7 @@ bool StopNode(); // (4) message start // (12) command // (4) size +// (4) checksum // 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 @@ -58,6 +59,7 @@ public: char pchMessageStart[sizeof(::pchMessageStart)]; char pchCommand[COMMAND_SIZE]; unsigned int nMessageSize; + //unsigned int nChecksum; CMessageHeader() { @@ -65,6 +67,7 @@ public: memset(pchCommand, 0, sizeof(pchCommand)); pchCommand[1] = 1; nMessageSize = -1; + //nChecksum = 0; } CMessageHeader(const char* pszCommand, unsigned int nMessageSizeIn) @@ -79,6 +82,8 @@ public: READWRITE(FLATDATA(pchMessageStart)); READWRITE(FLATDATA(pchCommand)); READWRITE(nMessageSize); + //if (nVersion >= 209 && GetCommand() != "version") + // READWRITE(nChecksum); ) string GetCommand() @@ -484,7 +489,8 @@ public: int64 nLastRecv; int64 nLastSendEmpty; int64 nTimeConnected; - unsigned int nPushPos; + unsigned int nHeaderStart; + unsigned int nMessageStart; CAddress addr; int nVersion; bool fClient; @@ -512,7 +518,7 @@ public: vector vInventoryToSend; CCriticalSection cs_inventory; multimap mapAskFor; - int64 nLastSentTxInv; + int64 nNextSendTxInv; // publish and subscription vector vfSubscribe; @@ -528,7 +534,8 @@ public: nLastRecv = 0; nLastSendEmpty = GetTime(); nTimeConnected = GetTime(); - nPushPos = -1; + nHeaderStart = -1; + nMessageStart = -1; addr = addrIn; nVersion = 0; fClient = false; // set by version message @@ -542,6 +549,7 @@ public: pindexLastGetBlocksBegin = 0; hashLastGetBlocksEnd = 0; fGetAddr = false; + nNextSendTxInv = 0; vfSubscribe.assign(256, false); // Push a version message @@ -639,10 +647,11 @@ public: void BeginMessage(const char* pszCommand) { cs_vSend.Enter(); - if (nPushPos != -1) + if (nHeaderStart != -1) AbortMessage(); - nPushPos = vSend.size(); + nHeaderStart = vSend.size(); vSend << CMessageHeader(pszCommand, 0); + nMessageStart = vSend.size(); if (fDebug) printf("%s ", DateTimeStrFormat("%x %H:%M:%S", GetTime()).c_str()); printf("sending: %s ", pszCommand); @@ -650,10 +659,11 @@ public: void AbortMessage() { - if (nPushPos == -1) + if (nHeaderStart == -1) return; - vSend.resize(nPushPos); - nPushPos = -1; + vSend.resize(nHeaderStart); + nHeaderStart = -1; + nMessageStart = -1; cs_vSend.Leave(); printf("(aborted)\n"); } @@ -667,25 +677,26 @@ public: return; } - if (nPushPos == -1) + if (nHeaderStart == -1) return; // Patch in the size - unsigned int nSize = vSend.size() - nPushPos - sizeof(CMessageHeader); - memcpy((char*)&vSend[nPushPos] + offsetof(CMessageHeader, nMessageSize), &nSize, sizeof(nSize)); + unsigned int nSize = vSend.size() - nMessageStart; + memcpy((char*)&vSend[nHeaderStart] + offsetof(CMessageHeader, nMessageSize), &nSize, sizeof(nSize)); printf("(%d bytes) ", nSize); printf("\n"); - nPushPos = -1; + nHeaderStart = -1; + nMessageStart = -1; cs_vSend.Leave(); } void EndMessageAbortIfEmpty() { - if (nPushPos == -1) + if (nHeaderStart == -1) return; - int nSize = vSend.size() - nPushPos - sizeof(CMessageHeader); + int nSize = vSend.size() - nMessageStart; if (nSize > 0) EndMessage(); else @@ -694,9 +705,9 @@ public: const char* GetMessageCommand() const { - if (nPushPos == -1) + if (nHeaderStart == -1) return ""; - return &vSend[nPushPos] + offsetof(CMessageHeader, pchCommand); + return &vSend[nHeaderStart] + offsetof(CMessageHeader, pchCommand); } diff --git a/rpc.cpp b/rpc.cpp index f298137aa2..c56ce263fb 100644 --- a/rpc.cpp +++ b/rpc.cpp @@ -77,24 +77,28 @@ Value getconnectioncount(const Array& params) } -Value getdifficulty(const Array& params) +double GetDifficulty() { - if (params.size() != 0) - throw runtime_error( - "getdifficulty (no parameters)\n" - "Returns the proof-of-work difficulty as a multiple of the minimum difficulty."); - - if (pindexBest == NULL) - throw runtime_error("block chain not loaded"); - // Floating point number that is a multiple of the minimum difficulty, // minimum difficulty = 1.0. + if (pindexBest == NULL) + return 1.0; int nShift = 256 - 32 - 31; // to fit in a uint double dMinimum = (CBigNum().SetCompact(bnProofOfWorkLimit.GetCompact()) >> nShift).getuint(); double dCurrently = (CBigNum().SetCompact(pindexBest->nBits) >> nShift).getuint(); return dMinimum / dCurrently; } +Value getdifficulty(const Array& params) +{ + if (params.size() != 0) + throw runtime_error( + "getdifficulty (no parameters)\n" + "Returns the proof-of-work difficulty as a multiple of the minimum difficulty."); + + return GetDifficulty(); +} + Value getbalance(const Array& params) { @@ -157,6 +161,7 @@ Value getinfo(const Array& params) obj.push_back(Pair("proxy", (fUseProxy ? addrProxy.ToStringIPPort() : string()))); obj.push_back(Pair("generate", (bool)fGenerateBitcoins)); obj.push_back(Pair("genproclimit", (int)(fLimitProcessors ? nLimitProcessors : -1))); + obj.push_back(Pair("difficulty", (double)GetDifficulty())); return obj; } diff --git a/serialize.h b/serialize.h index 77dfa95bb9..c47dddc87c 100644 --- a/serialize.h +++ b/serialize.h @@ -19,8 +19,8 @@ class CScript; class CDataStream; class CAutoFile; -static const int VERSION = 207; -static const char* pszSubVer = ".1"; +static const int VERSION = 208; +static const char* pszSubVer = ".0"; diff --git a/ui.cpp b/ui.cpp index efb05385ec..5c7311f997 100644 --- a/ui.cpp +++ b/ui.cpp @@ -256,11 +256,20 @@ CMainFrame::CMainFrame(wxWindow* parent) : CMainFrameBase(parent) m_staticTextBalance->SetLabel(FormatMoney(GetBalance()) + " "); m_listCtrl->SetFocus(); ptaskbaricon = new CMyTaskBarIcon(); +#ifdef __WXMAC__ + // 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__ + nDateWidth += 2; +#endif wxListCtrl* pplistCtrl[] = {m_listCtrlAll, m_listCtrlSentReceived, m_listCtrlSent, m_listCtrlReceived}; foreach(wxListCtrl* p, pplistCtrl) { @@ -274,7 +283,7 @@ CMainFrame::CMainFrame(wxWindow* parent) : CMainFrameBase(parent) } // Init status bar - int pnWidths[3] = { -100, 88, 290 }; + int pnWidths[3] = { -100, 88, 300 }; #ifndef __WXMSW__ pnWidths[1] = pnWidths[1] * 1.1 * dResize; pnWidths[2] = pnWidths[2] * 1.1 * dResize; @@ -2157,7 +2166,7 @@ CAddressBookDialog::CAddressBookDialog(wxWindow* parent, const wxString& strInit 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 : strInitSelected)) + if (strAddress == (fMine ? strDefaultReceiving : string(strInitSelected))) plistCtrl->SetItemState(nIndex, wxLIST_STATE_SELECTED|wxLIST_STATE_FOCUSED, wxLIST_STATE_SELECTED|wxLIST_STATE_FOCUSED); } } @@ -2444,7 +2453,7 @@ void CMyTaskBarIcon::OnMenuRestore(wxCommandEvent& event) void CMyTaskBarIcon::OnMenuOptions(wxCommandEvent& event) { // Since it's modal, get the main window to do it - wxCommandEvent event2(wxEVT_COMMAND_MENU_SELECTED, wxID_MENUOPTIONSOPTIONS); + wxCommandEvent event2(wxEVT_COMMAND_MENU_SELECTED, wxID_PREFERENCES); pframeMain->GetEventHandler()->AddPendingEvent(event2); } diff --git a/uibase.cpp b/uibase.cpp index 03ca13db92..5fd83ee4df 100644 --- a/uibase.cpp +++ b/uibase.cpp @@ -24,7 +24,7 @@ CMainFrameBase::CMainFrameBase( wxWindow* parent, wxWindowID id, const wxString& m_menuFile = new wxMenu(); wxMenuItem* m_menuFileExit; - m_menuFileExit = new wxMenuItem( m_menuFile, wxID_ANY, wxString( _("E&xit") ) , wxEmptyString, wxITEM_NORMAL ); + 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") ); @@ -39,14 +39,14 @@ CMainFrameBase::CMainFrameBase( wxWindow* parent, wxWindowID id, const wxString& m_menuOptions->Append( m_menuOptionsChangeYourAddress ); wxMenuItem* m_menuOptionsOptions; - m_menuOptionsOptions = new wxMenuItem( m_menuOptions, wxID_MENUOPTIONSOPTIONS, wxString( _("&Options...") ) , wxEmptyString, wxITEM_NORMAL ); + 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_ANY, wxString( _("&About...") ) , wxEmptyString, wxITEM_NORMAL ); + m_menuHelpAbout = new wxMenuItem( m_menuHelp, wxID_ABOUT, wxString( _("&About...") ) , wxEmptyString, wxITEM_NORMAL ); m_menuHelp->Append( m_menuHelpAbout ); m_menubar->Append( m_menuHelp, _("&Help") ); @@ -133,7 +133,7 @@ CMainFrameBase::CMainFrameBase( wxWindow* parent, wxWindowID id, const wxString& 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|wxVSCROLL ); + 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 ); @@ -144,7 +144,7 @@ CMainFrameBase::CMainFrameBase( wxWindow* parent, wxWindowID id, const wxString& 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|wxVSCROLL ); + 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 ); @@ -155,7 +155,7 @@ CMainFrameBase::CMainFrameBase( wxWindow* parent, wxWindowID id, const wxString& 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|wxVSCROLL ); + 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 ); @@ -166,7 +166,7 @@ CMainFrameBase::CMainFrameBase( wxWindow* parent, wxWindowID id, const wxString& 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|wxVSCROLL ); + 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 ); diff --git a/uibase.h b/uibase.h index 1686cbfa8b..e2f0a1c095 100644 --- a/uibase.h +++ b/uibase.h @@ -42,29 +42,28 @@ #define wxID_MAINFRAME 1000 #define wxID_OPTIONSGENERATEBITCOINS 1001 -#define wxID_MENUOPTIONSOPTIONS 1002 -#define wxID_BUTTONSEND 1003 -#define wxID_BUTTONRECEIVE 1004 -#define wxID_TEXTCTRLADDRESS 1005 -#define wxID_BUTTONNEW 1006 -#define wxID_BUTTONCOPY 1007 -#define wxID_TRANSACTIONFEE 1008 -#define wxID_PROXYIP 1009 -#define wxID_PROXYPORT 1010 -#define wxID_TEXTCTRLPAYTO 1011 -#define wxID_BUTTONPASTE 1012 -#define wxID_BUTTONADDRESSBOOK 1013 -#define wxID_TEXTCTRLAMOUNT 1014 -#define wxID_CHOICETRANSFERTYPE 1015 -#define wxID_LISTCTRL 1016 -#define wxID_BUTTONRENAME 1017 -#define wxID_PANELSENDING 1018 -#define wxID_LISTCTRLSENDING 1019 -#define wxID_PANELRECEIVING 1020 -#define wxID_LISTCTRLRECEIVING 1021 -#define wxID_BUTTONDELETE 1022 -#define wxID_BUTTONEDIT 1023 -#define wxID_TEXTCTRL 1024 +#define wxID_BUTTONSEND 1002 +#define wxID_BUTTONRECEIVE 1003 +#define wxID_TEXTCTRLADDRESS 1004 +#define wxID_BUTTONNEW 1005 +#define wxID_BUTTONCOPY 1006 +#define wxID_TRANSACTIONFEE 1007 +#define wxID_PROXYIP 1008 +#define wxID_PROXYPORT 1009 +#define wxID_TEXTCTRLPAYTO 1010 +#define wxID_BUTTONPASTE 1011 +#define wxID_BUTTONADDRESSBOOK 1012 +#define wxID_TEXTCTRLAMOUNT 1013 +#define wxID_CHOICETRANSFERTYPE 1014 +#define wxID_LISTCTRL 1015 +#define wxID_BUTTONRENAME 1016 +#define wxID_PANELSENDING 1017 +#define wxID_LISTCTRLSENDING 1018 +#define wxID_PANELRECEIVING 1019 +#define wxID_LISTCTRLRECEIVING 1020 +#define wxID_BUTTONDELETE 1021 +#define wxID_BUTTONEDIT 1022 +#define wxID_TEXTCTRL 1023 /////////////////////////////////////////////////////////////////////////////// /// Class CMainFrameBase diff --git a/uiproject.fbp b/uiproject.fbp index 8643fbab49..990af52196 100644 --- a/uiproject.fbp +++ b/uiproject.fbp @@ -123,7 +123,7 @@ 0 1 - wxID_ANY + wxID_EXIT wxITEM_NORMAL E&xit m_menuFileExit @@ -173,7 +173,7 @@ 0 1 - wxID_MENUOPTIONSOPTIONS + wxID_PREFERENCES wxITEM_NORMAL &Options... m_menuOptionsOptions @@ -193,7 +193,7 @@ 0 1 - wxID_ANY + wxID_ABOUT wxITEM_NORMAL &About... m_menuHelpAbout @@ -924,7 +924,7 @@ - wxVSCROLL + @@ -1047,7 +1047,7 @@ - wxVSCROLL + @@ -1170,7 +1170,7 @@ - wxVSCROLL + @@ -1293,7 +1293,7 @@ - wxVSCROLL + diff --git a/util.cpp b/util.cpp index acfbcd6c90..8f6bf38c4d 100644 --- a/util.cpp +++ b/util.cpp @@ -314,6 +314,12 @@ string FormatMoney(int64 n, bool fPlus) return str; } + +bool ParseMoney(const string& str, int64& nRet) +{ + return ParseMoney(str.c_str(), nRet); +} + bool ParseMoney(const char* pszIn, int64& nRet) { string strWhole; diff --git a/util.h b/util.h index 75f0956f2d..1a25c7ddcc 100644 --- a/util.h +++ b/util.h @@ -133,6 +133,7 @@ void PrintException(std::exception* pex, const char* pszThread); void LogException(std::exception* pex, const char* pszThread); void ParseString(const string& str, char c, vector& v); string FormatMoney(int64 n, bool fPlus=false); +bool ParseMoney(const string& str, int64& nRet); bool ParseMoney(const char* pszIn, int64& nRet); vector ParseHex(const char* psz); vector ParseHex(const std::string& str); -- cgit v1.2.3 From 2d98de1b3ae2ade8b1e5493bc63c0c1d776deeb1 Mon Sep 17 00:00:00 2001 From: s_nakamoto Date: Wed, 19 May 2010 00:26:56 +0000 Subject: Mac OS build fixes by laszlo -- version 0.2.8 git-svn-id: https://bitcoin.svn.sourceforge.net/svnroot/bitcoin/trunk@76 1a98c847-1fd6-4fd8-948a-caf3550aa51b --- init.cpp | 8 +++++++- main.cpp | 6 +++--- net.cpp | 4 +--- net.h | 43 +++++++++++++++++++++++++++---------------- rpc.cpp | 23 ++++++++++++++--------- serialize.h | 4 ++-- ui.cpp | 15 ++++++++++++--- uibase.cpp | 14 +++++++------- uibase.h | 45 ++++++++++++++++++++++----------------------- uiproject.fbp | 14 +++++++------- util.cpp | 6 ++++++ util.h | 1 + 12 files changed, 109 insertions(+), 74 deletions(-) diff --git a/init.cpp b/init.cpp index 06d8f4c933..db8886e119 100644 --- a/init.cpp +++ b/init.cpp @@ -284,6 +284,10 @@ bool CMyApp::OnInit2() _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE); _CrtSetReportFile(_CRT_WARN, CreateFileA("NUL", GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0)); #endif +#if _MSC_VER >= 1400 + // Disable confusing "helpful" text message on abort, ctrl-c + _set_abort_behavior(0, _WRITE_ABORT_MSG | _CALL_REPORTFAULT); +#endif #if defined(__WXMSW__) && defined(__WXDEBUG__) && wxUSE_GUI // Disable malfunctioning wxWidgets debug assertion g_isPainting = 10000; @@ -291,10 +295,12 @@ bool CMyApp::OnInit2() #if wxUSE_GUI wxImage::AddHandler(new wxPNGHandler); #endif -#ifdef __WXMSW__ +#if defined(__WXMSW__ ) || defined(__WXMAC__) SetAppName("Bitcoin"); #else SetAppName("bitcoin"); +#endif +#ifndef __WXMSW__ umask(077); #endif #ifdef __WXMSW__ diff --git a/main.cpp b/main.cpp index f7416230f6..ad0208a252 100644 --- a/main.cpp +++ b/main.cpp @@ -1338,7 +1338,7 @@ bool CBlock::AcceptBlock() // Don't relay old inventory during initial block download. // Please keep this number updated to a few thousand below current block count. - if (hashBestChain == hash && nBestHeight > 40000) + if (hashBestChain == hash && nBestHeight > 55000) RelayInventory(CInv(MSG_BLOCK, hash)); // // Add atoms to user reviews for coins created @@ -2255,9 +2255,9 @@ bool SendMessages(CNode* pto) // Delay tx inv messages to protect privacy, // trickle them out to a few nodes at a time. bool fSendTxInv = false; - if (GetTimeMillis() - pto->nLastSentTxInv > 1800 + GetRand(200)) + if (GetTimeMillis() > pto->nNextSendTxInv) { - pto->nLastSentTxInv = GetTimeMillis(); + pto->nNextSendTxInv = GetTimeMillis() + 3000 + GetRand(2000); fSendTxInv = true; } diff --git a/net.cpp b/net.cpp index 8e8127d73b..fbfa746221 100644 --- a/net.cpp +++ b/net.cpp @@ -927,9 +927,7 @@ void ThreadOpenConnections2(void* parg) continue; // Only try the old stuff if we don't have enough connections - if (vNodes.size() >= 2 && nSinceLastSeen > 7 * 24 * 60 * 60) - continue; - if (vNodes.size() >= 5 && nSinceLastSeen > 24 * 60 * 60) + if (vNodes.size() >= 8 && nSinceLastSeen > 24 * 60 * 60) continue; // If multiple addresses are ready, prioritize by time since diff --git a/net.h b/net.h index c7d15460a4..1593a975a3 100644 --- a/net.h +++ b/net.h @@ -45,6 +45,7 @@ bool StopNode(); // (4) message start // (12) command // (4) size +// (4) checksum // 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 @@ -58,6 +59,7 @@ public: char pchMessageStart[sizeof(::pchMessageStart)]; char pchCommand[COMMAND_SIZE]; unsigned int nMessageSize; + //unsigned int nChecksum; CMessageHeader() { @@ -65,6 +67,7 @@ public: memset(pchCommand, 0, sizeof(pchCommand)); pchCommand[1] = 1; nMessageSize = -1; + //nChecksum = 0; } CMessageHeader(const char* pszCommand, unsigned int nMessageSizeIn) @@ -79,6 +82,8 @@ public: READWRITE(FLATDATA(pchMessageStart)); READWRITE(FLATDATA(pchCommand)); READWRITE(nMessageSize); + //if (nVersion >= 209 && GetCommand() != "version") + // READWRITE(nChecksum); ) string GetCommand() @@ -484,7 +489,8 @@ public: int64 nLastRecv; int64 nLastSendEmpty; int64 nTimeConnected; - unsigned int nPushPos; + unsigned int nHeaderStart; + unsigned int nMessageStart; CAddress addr; int nVersion; bool fClient; @@ -512,7 +518,7 @@ public: vector vInventoryToSend; CCriticalSection cs_inventory; multimap mapAskFor; - int64 nLastSentTxInv; + int64 nNextSendTxInv; // publish and subscription vector vfSubscribe; @@ -528,7 +534,8 @@ public: nLastRecv = 0; nLastSendEmpty = GetTime(); nTimeConnected = GetTime(); - nPushPos = -1; + nHeaderStart = -1; + nMessageStart = -1; addr = addrIn; nVersion = 0; fClient = false; // set by version message @@ -542,6 +549,7 @@ public: pindexLastGetBlocksBegin = 0; hashLastGetBlocksEnd = 0; fGetAddr = false; + nNextSendTxInv = 0; vfSubscribe.assign(256, false); // Push a version message @@ -639,10 +647,11 @@ public: void BeginMessage(const char* pszCommand) { cs_vSend.Enter(); - if (nPushPos != -1) + if (nHeaderStart != -1) AbortMessage(); - nPushPos = vSend.size(); + nHeaderStart = vSend.size(); vSend << CMessageHeader(pszCommand, 0); + nMessageStart = vSend.size(); if (fDebug) printf("%s ", DateTimeStrFormat("%x %H:%M:%S", GetTime()).c_str()); printf("sending: %s ", pszCommand); @@ -650,10 +659,11 @@ public: void AbortMessage() { - if (nPushPos == -1) + if (nHeaderStart == -1) return; - vSend.resize(nPushPos); - nPushPos = -1; + vSend.resize(nHeaderStart); + nHeaderStart = -1; + nMessageStart = -1; cs_vSend.Leave(); printf("(aborted)\n"); } @@ -667,25 +677,26 @@ public: return; } - if (nPushPos == -1) + if (nHeaderStart == -1) return; // Patch in the size - unsigned int nSize = vSend.size() - nPushPos - sizeof(CMessageHeader); - memcpy((char*)&vSend[nPushPos] + offsetof(CMessageHeader, nMessageSize), &nSize, sizeof(nSize)); + unsigned int nSize = vSend.size() - nMessageStart; + memcpy((char*)&vSend[nHeaderStart] + offsetof(CMessageHeader, nMessageSize), &nSize, sizeof(nSize)); printf("(%d bytes) ", nSize); printf("\n"); - nPushPos = -1; + nHeaderStart = -1; + nMessageStart = -1; cs_vSend.Leave(); } void EndMessageAbortIfEmpty() { - if (nPushPos == -1) + if (nHeaderStart == -1) return; - int nSize = vSend.size() - nPushPos - sizeof(CMessageHeader); + int nSize = vSend.size() - nMessageStart; if (nSize > 0) EndMessage(); else @@ -694,9 +705,9 @@ public: const char* GetMessageCommand() const { - if (nPushPos == -1) + if (nHeaderStart == -1) return ""; - return &vSend[nPushPos] + offsetof(CMessageHeader, pchCommand); + return &vSend[nHeaderStart] + offsetof(CMessageHeader, pchCommand); } diff --git a/rpc.cpp b/rpc.cpp index f298137aa2..c56ce263fb 100644 --- a/rpc.cpp +++ b/rpc.cpp @@ -77,24 +77,28 @@ Value getconnectioncount(const Array& params) } -Value getdifficulty(const Array& params) +double GetDifficulty() { - if (params.size() != 0) - throw runtime_error( - "getdifficulty (no parameters)\n" - "Returns the proof-of-work difficulty as a multiple of the minimum difficulty."); - - if (pindexBest == NULL) - throw runtime_error("block chain not loaded"); - // Floating point number that is a multiple of the minimum difficulty, // minimum difficulty = 1.0. + if (pindexBest == NULL) + return 1.0; int nShift = 256 - 32 - 31; // to fit in a uint double dMinimum = (CBigNum().SetCompact(bnProofOfWorkLimit.GetCompact()) >> nShift).getuint(); double dCurrently = (CBigNum().SetCompact(pindexBest->nBits) >> nShift).getuint(); return dMinimum / dCurrently; } +Value getdifficulty(const Array& params) +{ + if (params.size() != 0) + throw runtime_error( + "getdifficulty (no parameters)\n" + "Returns the proof-of-work difficulty as a multiple of the minimum difficulty."); + + return GetDifficulty(); +} + Value getbalance(const Array& params) { @@ -157,6 +161,7 @@ Value getinfo(const Array& params) obj.push_back(Pair("proxy", (fUseProxy ? addrProxy.ToStringIPPort() : string()))); obj.push_back(Pair("generate", (bool)fGenerateBitcoins)); obj.push_back(Pair("genproclimit", (int)(fLimitProcessors ? nLimitProcessors : -1))); + obj.push_back(Pair("difficulty", (double)GetDifficulty())); return obj; } diff --git a/serialize.h b/serialize.h index 77dfa95bb9..c47dddc87c 100644 --- a/serialize.h +++ b/serialize.h @@ -19,8 +19,8 @@ class CScript; class CDataStream; class CAutoFile; -static const int VERSION = 207; -static const char* pszSubVer = ".1"; +static const int VERSION = 208; +static const char* pszSubVer = ".0"; diff --git a/ui.cpp b/ui.cpp index efb05385ec..5c7311f997 100644 --- a/ui.cpp +++ b/ui.cpp @@ -256,11 +256,20 @@ CMainFrame::CMainFrame(wxWindow* parent) : CMainFrameBase(parent) m_staticTextBalance->SetLabel(FormatMoney(GetBalance()) + " "); m_listCtrl->SetFocus(); ptaskbaricon = new CMyTaskBarIcon(); +#ifdef __WXMAC__ + // 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__ + nDateWidth += 2; +#endif wxListCtrl* pplistCtrl[] = {m_listCtrlAll, m_listCtrlSentReceived, m_listCtrlSent, m_listCtrlReceived}; foreach(wxListCtrl* p, pplistCtrl) { @@ -274,7 +283,7 @@ CMainFrame::CMainFrame(wxWindow* parent) : CMainFrameBase(parent) } // Init status bar - int pnWidths[3] = { -100, 88, 290 }; + int pnWidths[3] = { -100, 88, 300 }; #ifndef __WXMSW__ pnWidths[1] = pnWidths[1] * 1.1 * dResize; pnWidths[2] = pnWidths[2] * 1.1 * dResize; @@ -2157,7 +2166,7 @@ CAddressBookDialog::CAddressBookDialog(wxWindow* parent, const wxString& strInit 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 : strInitSelected)) + if (strAddress == (fMine ? strDefaultReceiving : string(strInitSelected))) plistCtrl->SetItemState(nIndex, wxLIST_STATE_SELECTED|wxLIST_STATE_FOCUSED, wxLIST_STATE_SELECTED|wxLIST_STATE_FOCUSED); } } @@ -2444,7 +2453,7 @@ void CMyTaskBarIcon::OnMenuRestore(wxCommandEvent& event) void CMyTaskBarIcon::OnMenuOptions(wxCommandEvent& event) { // Since it's modal, get the main window to do it - wxCommandEvent event2(wxEVT_COMMAND_MENU_SELECTED, wxID_MENUOPTIONSOPTIONS); + wxCommandEvent event2(wxEVT_COMMAND_MENU_SELECTED, wxID_PREFERENCES); pframeMain->GetEventHandler()->AddPendingEvent(event2); } diff --git a/uibase.cpp b/uibase.cpp index 03ca13db92..5fd83ee4df 100644 --- a/uibase.cpp +++ b/uibase.cpp @@ -24,7 +24,7 @@ CMainFrameBase::CMainFrameBase( wxWindow* parent, wxWindowID id, const wxString& m_menuFile = new wxMenu(); wxMenuItem* m_menuFileExit; - m_menuFileExit = new wxMenuItem( m_menuFile, wxID_ANY, wxString( _("E&xit") ) , wxEmptyString, wxITEM_NORMAL ); + 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") ); @@ -39,14 +39,14 @@ CMainFrameBase::CMainFrameBase( wxWindow* parent, wxWindowID id, const wxString& m_menuOptions->Append( m_menuOptionsChangeYourAddress ); wxMenuItem* m_menuOptionsOptions; - m_menuOptionsOptions = new wxMenuItem( m_menuOptions, wxID_MENUOPTIONSOPTIONS, wxString( _("&Options...") ) , wxEmptyString, wxITEM_NORMAL ); + 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_ANY, wxString( _("&About...") ) , wxEmptyString, wxITEM_NORMAL ); + m_menuHelpAbout = new wxMenuItem( m_menuHelp, wxID_ABOUT, wxString( _("&About...") ) , wxEmptyString, wxITEM_NORMAL ); m_menuHelp->Append( m_menuHelpAbout ); m_menubar->Append( m_menuHelp, _("&Help") ); @@ -133,7 +133,7 @@ CMainFrameBase::CMainFrameBase( wxWindow* parent, wxWindowID id, const wxString& 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|wxVSCROLL ); + 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 ); @@ -144,7 +144,7 @@ CMainFrameBase::CMainFrameBase( wxWindow* parent, wxWindowID id, const wxString& 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|wxVSCROLL ); + 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 ); @@ -155,7 +155,7 @@ CMainFrameBase::CMainFrameBase( wxWindow* parent, wxWindowID id, const wxString& 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|wxVSCROLL ); + 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 ); @@ -166,7 +166,7 @@ CMainFrameBase::CMainFrameBase( wxWindow* parent, wxWindowID id, const wxString& 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|wxVSCROLL ); + 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 ); diff --git a/uibase.h b/uibase.h index 1686cbfa8b..e2f0a1c095 100644 --- a/uibase.h +++ b/uibase.h @@ -42,29 +42,28 @@ #define wxID_MAINFRAME 1000 #define wxID_OPTIONSGENERATEBITCOINS 1001 -#define wxID_MENUOPTIONSOPTIONS 1002 -#define wxID_BUTTONSEND 1003 -#define wxID_BUTTONRECEIVE 1004 -#define wxID_TEXTCTRLADDRESS 1005 -#define wxID_BUTTONNEW 1006 -#define wxID_BUTTONCOPY 1007 -#define wxID_TRANSACTIONFEE 1008 -#define wxID_PROXYIP 1009 -#define wxID_PROXYPORT 1010 -#define wxID_TEXTCTRLPAYTO 1011 -#define wxID_BUTTONPASTE 1012 -#define wxID_BUTTONADDRESSBOOK 1013 -#define wxID_TEXTCTRLAMOUNT 1014 -#define wxID_CHOICETRANSFERTYPE 1015 -#define wxID_LISTCTRL 1016 -#define wxID_BUTTONRENAME 1017 -#define wxID_PANELSENDING 1018 -#define wxID_LISTCTRLSENDING 1019 -#define wxID_PANELRECEIVING 1020 -#define wxID_LISTCTRLRECEIVING 1021 -#define wxID_BUTTONDELETE 1022 -#define wxID_BUTTONEDIT 1023 -#define wxID_TEXTCTRL 1024 +#define wxID_BUTTONSEND 1002 +#define wxID_BUTTONRECEIVE 1003 +#define wxID_TEXTCTRLADDRESS 1004 +#define wxID_BUTTONNEW 1005 +#define wxID_BUTTONCOPY 1006 +#define wxID_TRANSACTIONFEE 1007 +#define wxID_PROXYIP 1008 +#define wxID_PROXYPORT 1009 +#define wxID_TEXTCTRLPAYTO 1010 +#define wxID_BUTTONPASTE 1011 +#define wxID_BUTTONADDRESSBOOK 1012 +#define wxID_TEXTCTRLAMOUNT 1013 +#define wxID_CHOICETRANSFERTYPE 1014 +#define wxID_LISTCTRL 1015 +#define wxID_BUTTONRENAME 1016 +#define wxID_PANELSENDING 1017 +#define wxID_LISTCTRLSENDING 1018 +#define wxID_PANELRECEIVING 1019 +#define wxID_LISTCTRLRECEIVING 1020 +#define wxID_BUTTONDELETE 1021 +#define wxID_BUTTONEDIT 1022 +#define wxID_TEXTCTRL 1023 /////////////////////////////////////////////////////////////////////////////// /// Class CMainFrameBase diff --git a/uiproject.fbp b/uiproject.fbp index 8643fbab49..990af52196 100644 --- a/uiproject.fbp +++ b/uiproject.fbp @@ -123,7 +123,7 @@ 0 1 - wxID_ANY + wxID_EXIT wxITEM_NORMAL E&xit m_menuFileExit @@ -173,7 +173,7 @@ 0 1 - wxID_MENUOPTIONSOPTIONS + wxID_PREFERENCES wxITEM_NORMAL &Options... m_menuOptionsOptions @@ -193,7 +193,7 @@ 0 1 - wxID_ANY + wxID_ABOUT wxITEM_NORMAL &About... m_menuHelpAbout @@ -924,7 +924,7 @@ - wxVSCROLL + @@ -1047,7 +1047,7 @@ - wxVSCROLL + @@ -1170,7 +1170,7 @@ - wxVSCROLL + @@ -1293,7 +1293,7 @@ - wxVSCROLL + diff --git a/util.cpp b/util.cpp index acfbcd6c90..8f6bf38c4d 100644 --- a/util.cpp +++ b/util.cpp @@ -314,6 +314,12 @@ string FormatMoney(int64 n, bool fPlus) return str; } + +bool ParseMoney(const string& str, int64& nRet) +{ + return ParseMoney(str.c_str(), nRet); +} + bool ParseMoney(const char* pszIn, int64& nRet) { string strWhole; diff --git a/util.h b/util.h index 75f0956f2d..1a25c7ddcc 100644 --- a/util.h +++ b/util.h @@ -133,6 +133,7 @@ void PrintException(std::exception* pex, const char* pszThread); void LogException(std::exception* pex, const char* pszThread); void ParseString(const string& str, char c, vector& v); string FormatMoney(int64 n, bool fPlus=false); +bool ParseMoney(const string& str, int64& nRet); bool ParseMoney(const char* pszIn, int64& nRet); vector ParseHex(const char* psz); vector ParseHex(const std::string& str); -- cgit v1.2.3 From 9c1e9f0b6a1d073a5f450c847850ef1d8df74137 Mon Sep 17 00:00:00 2001 From: s_nakamoto Date: Tue, 25 May 2010 23:58:27 +0000 Subject: build-osx.txt build instructions and makefile.osx from Laszlo --- build-osx.txt | 209 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ makefile.osx | 65 ++++++++++++++++++ 2 files changed, 274 insertions(+) create mode 100644 build-osx.txt create mode 100644 makefile.osx diff --git a/build-osx.txt b/build-osx.txt new file mode 100644 index 0000000000..c7e3a218ea --- /dev/null +++ b/build-osx.txt @@ -0,0 +1,209 @@ +Mac OS X build instructions +Laszlo Hanyecz (solar@heliacal.net) + + +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 +/Applications/Utilities + +You need to install XCode with all the options checked so that the compiler +and 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/trunk # source code +~/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 trunk version of the bitcoin code from subversion: + +cd ~/bitcoin +svn checkout https://bitcoin.svn.sourceforge.net/svnroot/bitcoin/trunk + +This will make ~/bitcoin/trunk for you with all the files from subversion. + +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.6 macosx-version-min=10.5 link=static runtime-link=static --toolset=darwin --prefix=/Users/macosuser/bitcoin/deps install + +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 +------- + +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/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/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: + +ib/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 + + +Berkeley DB +----------- + +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 +--------- + +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/trunk +make -f makefile.osx bitcoin + +Before you can run it, you need to create an application bundle for Mac OS. +Create the directories in terminal using mkdir and copy the files into place. +They are available at http://heliacal.net/~solar/bitcoin/mac-build/ +You need the Info.plist and the .ins file. The Contents/MacOS/bitcoin file is +the output of the build. +Your directory structure should look like this: + +Bitcoin.app +Bitcoin.app/Contents +Bitcoin.app/Contents/Info.plist +Bitcoin.app/Contents/MacOS +Bitcoin.app/Contents/MacOS/bitcoin +Bitcoin.app/Contents/Resources +Bitcoin.app/Contents/Resources/BitcoinAppIcon.icns + +To run it you can just click the Bitcoin.app in Finder, or just do open +~/bitcoin/Bitcoin.app +If you want to run it with arguments you can just run it without backgrounding +by specifying the full name in terminal: +~/bitcoin/Bitcoin.app/Contents/MacOS/bitcoin -addnode=192.75.207.66 diff --git a/makefile.osx b/makefile.osx new file mode 100644 index 0000000000..264f0b1629 --- /dev/null +++ b/makefile.osx @@ -0,0 +1,65 @@ +# 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. + +# Mac OS X makefile for bitcoin +# Laszlo Hanyecz (solar@heliacal.net) + +DEPSDIR=/Users/macosuser/bitcoin/deps + +INCLUDEPATHS= \ + -I"$(DEPSDIR)/include" + +LIBPATHS= \ + -L"$(DEPSDIR)/lib" + +WXLIBS=$(shell $(DEPSDIR)/bin/wx-config --libs --static) + +LIBS= -dead_strip \ + $(DEPSDIR)/lib/libdb_cxx-4.8.a \ + $(DEPSDIR)/lib/libboost_system.a \ + $(DEPSDIR)/lib/libboost_filesystem.a \ + $(DEPSDIR)/lib/libcrypto.a + +WXDEFS=$(shell $(DEPSDIR)/bin/wx-config --cxxflags) -DNOPCH -DMSG_NOSIGNAL=0 + +DEBUGFLAGS=-g -DwxDEBUG_LEVEL=0 +# ppc doesn't work because we don't support big-endian +CFLAGS=-mmacosx-version-min=10.5 -arch i386 -arch x86_64 -O2 -Wno-invalid-offsetof -Wformat $(DEBUGFLAGS) $(WXDEFS) $(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 init.h sha.h + + +all: bitcoin + + +obj/%.o: %.cpp $(HEADERS) + g++ -c $(CFLAGS) -o $@ $< + +obj/sha.o: sha.cpp sha.h + g++ -c $(CFLAGS) -O3 -o $@ $< + +OBJS= \ + obj/util.o \ + obj/script.o \ + obj/db.o \ + obj/net.o \ + obj/irc.o \ + obj/main.o \ + obj/rpc.o \ + obj/init.o + +bitcoin: $(OBJS) obj/ui.o obj/uibase.o obj/sha.o + g++ $(CFLAGS) -o $@ $(LIBPATHS) $^ $(WXLIBS) $(LIBS) + + +obj/nogui/%.o: %.cpp $(HEADERS) + g++ -c $(CFLAGS) -DwxUSE_GUI=0 -o $@ $< + +bitcoind: $(OBJS:obj/%=obj/nogui/%) obj/sha.o + g++ $(CFLAGS) -o $@ $(LIBPATHS) $^ $(WXLIBS) $(LIBS) + + +clean: + -rm -f obj/*.o + -rm -f obj/nogui/*.o -- cgit v1.2.3 From 124baa4ccbf3ecb78eab7ecdd40105fb54ee0369 Mon Sep 17 00:00:00 2001 From: s_nakamoto Date: Tue, 25 May 2010 23:58:27 +0000 Subject: build-osx.txt build instructions and makefile.osx from Laszlo git-svn-id: https://bitcoin.svn.sourceforge.net/svnroot/bitcoin/trunk@77 1a98c847-1fd6-4fd8-948a-caf3550aa51b --- build-osx.txt | 209 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ makefile.osx | 65 ++++++++++++++++++ 2 files changed, 274 insertions(+) create mode 100644 build-osx.txt create mode 100644 makefile.osx diff --git a/build-osx.txt b/build-osx.txt new file mode 100644 index 0000000000..c7e3a218ea --- /dev/null +++ b/build-osx.txt @@ -0,0 +1,209 @@ +Mac OS X build instructions +Laszlo Hanyecz (solar@heliacal.net) + + +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 +/Applications/Utilities + +You need to install XCode with all the options checked so that the compiler +and 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/trunk # source code +~/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 trunk version of the bitcoin code from subversion: + +cd ~/bitcoin +svn checkout https://bitcoin.svn.sourceforge.net/svnroot/bitcoin/trunk + +This will make ~/bitcoin/trunk for you with all the files from subversion. + +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.6 macosx-version-min=10.5 link=static runtime-link=static --toolset=darwin --prefix=/Users/macosuser/bitcoin/deps install + +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 +------- + +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/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/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: + +ib/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 + + +Berkeley DB +----------- + +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 +--------- + +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/trunk +make -f makefile.osx bitcoin + +Before you can run it, you need to create an application bundle for Mac OS. +Create the directories in terminal using mkdir and copy the files into place. +They are available at http://heliacal.net/~solar/bitcoin/mac-build/ +You need the Info.plist and the .ins file. The Contents/MacOS/bitcoin file is +the output of the build. +Your directory structure should look like this: + +Bitcoin.app +Bitcoin.app/Contents +Bitcoin.app/Contents/Info.plist +Bitcoin.app/Contents/MacOS +Bitcoin.app/Contents/MacOS/bitcoin +Bitcoin.app/Contents/Resources +Bitcoin.app/Contents/Resources/BitcoinAppIcon.icns + +To run it you can just click the Bitcoin.app in Finder, or just do open +~/bitcoin/Bitcoin.app +If you want to run it with arguments you can just run it without backgrounding +by specifying the full name in terminal: +~/bitcoin/Bitcoin.app/Contents/MacOS/bitcoin -addnode=192.75.207.66 diff --git a/makefile.osx b/makefile.osx new file mode 100644 index 0000000000..264f0b1629 --- /dev/null +++ b/makefile.osx @@ -0,0 +1,65 @@ +# 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. + +# Mac OS X makefile for bitcoin +# Laszlo Hanyecz (solar@heliacal.net) + +DEPSDIR=/Users/macosuser/bitcoin/deps + +INCLUDEPATHS= \ + -I"$(DEPSDIR)/include" + +LIBPATHS= \ + -L"$(DEPSDIR)/lib" + +WXLIBS=$(shell $(DEPSDIR)/bin/wx-config --libs --static) + +LIBS= -dead_strip \ + $(DEPSDIR)/lib/libdb_cxx-4.8.a \ + $(DEPSDIR)/lib/libboost_system.a \ + $(DEPSDIR)/lib/libboost_filesystem.a \ + $(DEPSDIR)/lib/libcrypto.a + +WXDEFS=$(shell $(DEPSDIR)/bin/wx-config --cxxflags) -DNOPCH -DMSG_NOSIGNAL=0 + +DEBUGFLAGS=-g -DwxDEBUG_LEVEL=0 +# ppc doesn't work because we don't support big-endian +CFLAGS=-mmacosx-version-min=10.5 -arch i386 -arch x86_64 -O2 -Wno-invalid-offsetof -Wformat $(DEBUGFLAGS) $(WXDEFS) $(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 init.h sha.h + + +all: bitcoin + + +obj/%.o: %.cpp $(HEADERS) + g++ -c $(CFLAGS) -o $@ $< + +obj/sha.o: sha.cpp sha.h + g++ -c $(CFLAGS) -O3 -o $@ $< + +OBJS= \ + obj/util.o \ + obj/script.o \ + obj/db.o \ + obj/net.o \ + obj/irc.o \ + obj/main.o \ + obj/rpc.o \ + obj/init.o + +bitcoin: $(OBJS) obj/ui.o obj/uibase.o obj/sha.o + g++ $(CFLAGS) -o $@ $(LIBPATHS) $^ $(WXLIBS) $(LIBS) + + +obj/nogui/%.o: %.cpp $(HEADERS) + g++ -c $(CFLAGS) -DwxUSE_GUI=0 -o $@ $< + +bitcoind: $(OBJS:obj/%=obj/nogui/%) obj/sha.o + g++ $(CFLAGS) -o $@ $(LIBPATHS) $^ $(WXLIBS) $(LIBS) + + +clean: + -rm -f obj/*.o + -rm -f obj/nogui/*.o -- cgit v1.2.3 From 7a47324c7846ab0e500b974cd1f40e4030a7c0d2 Mon Sep 17 00:00:00 2001 From: s_nakamoto Date: Wed, 26 May 2010 00:05:26 +0000 Subject: better prevention of inventory relaying during initial download, message checksum between nodes with 0.2.9 or higher, optimization level up from -O0 to -O2, rpc functions: setlabel, getlabel, getaddressesbylabel, getreceivedbyaddress, getreceivedbylabel, listreceivedbyaddress, listreceivedbylabel -- version 0.2.9 --- db.h | 2 + init.cpp | 7 +- main.cpp | 76 +++++++++----- makefile.mingw | 2 +- makefile.unix | 2 +- net.h | 30 ++++-- rpc.cpp | 305 +++++++++++++++++++++++++++++++++++++++++++++++---------- serialize.h | 14 ++- ui.cpp | 9 +- ui.h | 9 ++ uibase.h | 2 +- uiproject.fbp | 2 +- util.cpp | 5 - 13 files changed, 364 insertions(+), 101 deletions(-) diff --git a/db.h b/db.h index fb4e9268c8..0b778d5fea 100644 --- a/db.h +++ b/db.h @@ -328,6 +328,8 @@ public: bool EraseName(const string& strAddress) { + // This should only be used for sending addresses, never for receiving addresses, + // receiving addresses must always have an address book entry if they're not change return. CRITICAL_BLOCK(cs_mapAddressBook) mapAddressBook.erase(strAddress); nWalletDBUpdated++; diff --git a/init.cpp b/init.cpp index db8886e119..833a8a3f0b 100644 --- a/init.cpp +++ b/init.cpp @@ -224,9 +224,6 @@ bool CMyApp::Initialize(int& argc, wxChar** argv) } } - if (fDaemon) - fprintf(stdout, "bitcoin server starting\n"); - #ifdef __WXGTK__ if (fDaemon || fCommandLine) { @@ -447,7 +444,8 @@ bool CMyApp::OnInit2() // // Load data files // - bool fFirstRun; + if (fDaemon) + fprintf(stdout, "bitcoin server starting\n"); strErrors = ""; int64 nStart; @@ -465,6 +463,7 @@ bool CMyApp::OnInit2() printf("Loading wallet...\n"); nStart = GetTimeMillis(); + bool fFirstRun; if (!LoadWallet(fFirstRun)) strErrors += _("Error loading wallet.dat \n"); printf(" wallet %15"PRI64d"ms\n", GetTimeMillis() - nStart); diff --git a/main.cpp b/main.cpp index ad0208a252..05a182c183 100644 --- a/main.cpp +++ b/main.cpp @@ -1336,19 +1336,12 @@ bool CBlock::AcceptBlock() if (!AddToBlockIndex(nFile, nBlockPos)) return error("AcceptBlock() : AddToBlockIndex failed"); - // Don't relay old inventory during initial block download. - // Please keep this number updated to a few thousand below current block count. - if (hashBestChain == hash && nBestHeight > 55000) - RelayInventory(CInv(MSG_BLOCK, hash)); - - // // Add atoms to user reviews for coins created - // vector vchPubKey; - // if (ExtractPubKey(vtx[0].vout[0].scriptPubKey, false, vchPubKey)) - // { - // unsigned short nAtom = GetRand(USHRT_MAX - 100) + 100; - // vector vAtoms(1, nAtom); - // AddAtomsAndPropagate(Hash(vchPubKey.begin(), vchPubKey.end()), vAtoms, true); - // } + // Relay inventory, but don't relay old inventory during initial block download + if (hashBestChain == hash) + CRITICAL_BLOCK(cs_vNodes) + foreach(CNode* pnode, vNodes) + if (nBestHeight > (pnode->nStartingHeight != -1 ? pnode->nStartingHeight - 2000 : 55000)) + pnode->PushInventory(CInv(MSG_BLOCK, hash)); return true; } @@ -1721,6 +1714,7 @@ bool ProcessMessages(CNode* pfrom) // (4) message start // (12) command // (4) size + // (4) checksum // (x) data // @@ -1728,12 +1722,13 @@ bool ProcessMessages(CNode* pfrom) { // Scan for message start CDataStream::iterator pstart = search(vRecv.begin(), vRecv.end(), BEGIN(pchMessageStart), END(pchMessageStart)); - if (vRecv.end() - pstart < sizeof(CMessageHeader)) + int nHeaderSize = vRecv.GetSerializeSize(CMessageHeader()); + if (vRecv.end() - pstart < nHeaderSize) { - if (vRecv.size() > sizeof(CMessageHeader)) + if (vRecv.size() > nHeaderSize) { printf("\n\nPROCESSMESSAGE MESSAGESTART NOT FOUND\n\n"); - vRecv.erase(vRecv.begin(), vRecv.end() - sizeof(CMessageHeader)); + vRecv.erase(vRecv.begin(), vRecv.end() - nHeaderSize); } break; } @@ -1742,6 +1737,7 @@ bool ProcessMessages(CNode* pfrom) vRecv.erase(vRecv.begin(), pstart); // Read header + vector vHeaderSave(vRecv.begin(), vRecv.begin() + nHeaderSize); CMessageHeader hdr; vRecv >> hdr; if (!hdr.IsValid()) @@ -1757,10 +1753,9 @@ bool ProcessMessages(CNode* pfrom) { // Rewind and wait for rest of message ///// need a mechanism to give up waiting for overlong message size error - //if (fDebug) - // printf("message-break\n"); - vRecv.insert(vRecv.begin(), BEGIN(hdr), END(hdr)); - Sleep(100); + if (fDebug) + printf("message-break\n"); + vRecv.insert(vRecv.begin(), vHeaderSave.begin(), vHeaderSave.end()); break; } @@ -1768,6 +1763,20 @@ bool ProcessMessages(CNode* pfrom) CDataStream vMsg(vRecv.begin(), vRecv.begin() + nMessageSize, vRecv.nType, vRecv.nVersion); vRecv.ignore(nMessageSize); + // Checksum + if (vRecv.GetVersion() >= 209) + { + uint256 hash = Hash(vMsg.begin(), vMsg.end()); + unsigned int nChecksum = 0; + memcpy(&nChecksum, &hash, sizeof(nChecksum)); + if (nChecksum != hdr.nChecksum) + { + printf("ProcessMessage(%s, %d bytes) : CHECKSUM ERROR nChecksum=%08x hdr.nChecksum=%08x\n", + strCommand.c_str(), nMessageSize, nChecksum, hdr.nChecksum); + continue; + } + } + // Process message bool fRet = false; try @@ -1844,6 +1853,9 @@ bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) vRecv >> addrFrom >> nNonce; if (pfrom->nVersion >= 106 && !vRecv.empty()) vRecv >> strSubVer; + if (pfrom->nVersion >= 209 && !vRecv.empty()) + vRecv >> pfrom->nStartingHeight; + if (pfrom->nVersion == 0) return false; @@ -1854,9 +1866,6 @@ bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) return true; } - pfrom->vSend.SetVersion(min(pfrom->nVersion, VERSION)); - pfrom->vRecv.SetVersion(min(pfrom->nVersion, VERSION)); - pfrom->fClient = !(pfrom->nServices & NODE_NETWORK); if (pfrom->fClient) { @@ -1866,6 +1875,13 @@ bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) AddTimeData(pfrom->addr.ip, nTime); + // Change version + if (pfrom->nVersion >= 209) + pfrom->PushMessage("verack"); + pfrom->vSend.SetVersion(min(pfrom->nVersion, VERSION)); + if (pfrom->nVersion < 209) + pfrom->vRecv.SetVersion(min(pfrom->nVersion, VERSION)); + // Ask the first connected node for block updates static bool fAskedForBlocks; if (!fAskedForBlocks && !pfrom->fClient) @@ -1876,7 +1892,7 @@ bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) pfrom->fSuccessfullyConnected = true; - printf("version message: version %d\n", pfrom->nVersion); + printf("version message: version %d, blocks=%d\n", pfrom->nVersion, pfrom->nStartingHeight); } @@ -1887,6 +1903,12 @@ bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) } + else if (strCommand == "verack") + { + pfrom->vRecv.SetVersion(min(pfrom->nVersion, VERSION)); + } + + else if (strCommand == "addr") { vector vAddr; @@ -2101,9 +2123,8 @@ bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) vRecv >> *pblock; //// debug print - // printf("received block:\n"); - // pblock->print(); printf("received block %s\n", pblock->GetHash().ToString().substr(0,16).c_str()); + // pblock->print(); CInv inv(MSG_BLOCK, pblock->GetHash()); pfrom->AddInventoryKnown(inv); @@ -2388,8 +2409,11 @@ void GenerateBitcoins(bool fGenerate) int nAddThreads = nProcessors - vnThreadsRunning[3]; printf("Starting %d BitcoinMiner threads\n", nAddThreads); for (int i = 0; i < nAddThreads; i++) + { if (!CreateThread(ThreadBitcoinMiner, NULL)) printf("Error: CreateThread(ThreadBitcoinMiner) failed\n"); + Sleep(10); + } } } diff --git a/makefile.mingw b/makefile.mingw index 449a96072c..ee63d11ead 100644 --- a/makefile.mingw +++ b/makefile.mingw @@ -29,7 +29,7 @@ LIBS= \ WXDEFS=-DWIN32 -D__WXMSW__ -D_WINDOWS -DNOPCH DEBUGFLAGS=-g -D__WXDEBUG__ -CFLAGS=-mthreads -O0 -w -Wno-invalid-offsetof -Wformat $(DEBUGFLAGS) $(WXDEFS) $(INCLUDEPATHS) +CFLAGS=-mthreads -O2 -w -Wno-invalid-offsetof -Wformat $(DEBUGFLAGS) $(WXDEFS) $(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 init.h sha.h diff --git a/makefile.unix b/makefile.unix index 10c4eece73..e7729adcaa 100644 --- a/makefile.unix +++ b/makefile.unix @@ -29,7 +29,7 @@ LIBS= \ WXDEFS=-D__WXGTK__ -DNOPCH DEBUGFLAGS=-g -D__WXDEBUG__ -CFLAGS=-O0 -Wno-invalid-offsetof -Wformat $(DEBUGFLAGS) $(WXDEFS) $(INCLUDEPATHS) +CFLAGS=-O2 -Wno-invalid-offsetof -Wformat $(DEBUGFLAGS) $(WXDEFS) $(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 init.h sha.h diff --git a/net.h b/net.h index 1593a975a3..46344ed928 100644 --- a/net.h +++ b/net.h @@ -8,6 +8,7 @@ class CInv; class CRequestTracker; class CNode; class CBlockIndex; +extern int nBestHeight; @@ -59,7 +60,7 @@ public: char pchMessageStart[sizeof(::pchMessageStart)]; char pchCommand[COMMAND_SIZE]; unsigned int nMessageSize; - //unsigned int nChecksum; + unsigned int nChecksum; CMessageHeader() { @@ -67,7 +68,7 @@ public: memset(pchCommand, 0, sizeof(pchCommand)); pchCommand[1] = 1; nMessageSize = -1; - //nChecksum = 0; + nChecksum = 0; } CMessageHeader(const char* pszCommand, unsigned int nMessageSizeIn) @@ -75,6 +76,7 @@ public: memcpy(pchMessageStart, ::pchMessageStart, sizeof(pchMessageStart)); strncpy(pchCommand, pszCommand, COMMAND_SIZE); nMessageSize = nMessageSizeIn; + nChecksum = 0; } IMPLEMENT_SERIALIZE @@ -82,8 +84,8 @@ public: READWRITE(FLATDATA(pchMessageStart)); READWRITE(FLATDATA(pchCommand)); READWRITE(nMessageSize); - //if (nVersion >= 209 && GetCommand() != "version") - // READWRITE(nChecksum); + if (nVersion >= 209) + READWRITE(nChecksum); ) string GetCommand() @@ -475,6 +477,7 @@ extern CAddress addrProxy; + class CNode { public: @@ -507,6 +510,7 @@ public: uint256 hashContinue; CBlockIndex* pindexLastGetBlocksBegin; uint256 hashLastGetBlocksEnd; + int nStartingHeight; // flood vector vAddrToSend; @@ -529,7 +533,9 @@ public: nServices = 0; hSocket = hSocketIn; vSend.SetType(SER_NETWORK); + vSend.SetVersion(0); vRecv.SetType(SER_NETWORK); + vRecv.SetVersion(0); nLastSend = 0; nLastRecv = 0; nLastSendEmpty = GetTime(); @@ -548,6 +554,7 @@ public: hashContinue = 0; pindexLastGetBlocksBegin = 0; hashLastGetBlocksEnd = 0; + nStartingHeight = -1; fGetAddr = false; nNextSendTxInv = 0; vfSubscribe.assign(256, false); @@ -558,7 +565,8 @@ public: CAddress addrYou = (fUseProxy ? CAddress("0.0.0.0") : addr); CAddress addrMe = (fUseProxy ? CAddress("0.0.0.0") : addrLocalHost); RAND_bytes((unsigned char*)&nLocalHostNonce, sizeof(nLocalHostNonce)); - PushMessage("version", VERSION, nLocalServices, nTime, addrYou, addrMe, nLocalHostNonce, string(pszSubVer)); + PushMessage("version", VERSION, nLocalServices, nTime, addrYou, addrMe, + nLocalHostNonce, string(pszSubVer), nBestHeight); } ~CNode() @@ -680,10 +688,20 @@ public: if (nHeaderStart == -1) return; - // Patch in the size + // Set the size unsigned int nSize = vSend.size() - nMessageStart; memcpy((char*)&vSend[nHeaderStart] + offsetof(CMessageHeader, nMessageSize), &nSize, sizeof(nSize)); + // Set the checksum + if (vSend.GetVersion() >= 209) + { + uint256 hash = Hash(vSend.begin() + nMessageStart, vSend.end()); + unsigned int nChecksum = 0; + memcpy(&nChecksum, &hash, sizeof(nChecksum)); + assert(nMessageStart - nHeaderStart >= offsetof(CMessageHeader, nChecksum) + sizeof(nChecksum)); + memcpy((char*)&vSend[nHeaderStart] + offsetof(CMessageHeader, nChecksum), &nChecksum, sizeof(nChecksum)); + } + printf("(%d bytes) ", nSize); printf("\n"); diff --git a/rpc.cpp b/rpc.cpp index c56ce263fb..d988786ef1 100644 --- a/rpc.cpp +++ b/rpc.cpp @@ -26,7 +26,7 @@ void ThreadRPCServer2(void* parg); /// -/// Note: I'm not finished designing this interface, it's still subject to change. +/// Note: This interface may still be subject to change. /// @@ -188,6 +188,73 @@ Value getnewaddress(const Array& params) } +Value setlabel(const Array& params) +{ + if (params.size() < 1 || params.size() > 2) + throw runtime_error( + "setlabel