flush wallet.dat, multi-proc, reorg options, revert to startup folder shortcut

This commit is contained in:
s_nakamoto 2009-10-21 01:08:05 +00:00
parent c199b8499d
commit 5210998688
19 changed files with 1924 additions and 1329 deletions

View file

@ -1,4 +1,4 @@
BitCoin v0.1.5 ALPHA BitCoin v0.1.6 ALPHA
Copyright (c) 2009 Satoshi Nakamoto Copyright (c) 2009 Satoshi Nakamoto
Distributed under the MIT/X11 software license, see the accompanying Distributed under the MIT/X11 software license, see the accompanying
@ -10,7 +10,7 @@ cryptographic software written by Eric Young (eay@cryptsoft.com).
Compilers Supported Compilers Supported
------------------- -------------------
MinGW GCC (v3.4.5) MinGW GCC (currently v3.4.5)
Microsoft Visual C++ 6.0 SP6 Microsoft Visual C++ 6.0 SP6
@ -31,6 +31,16 @@ Berkeley DB New BSD license with additional requirement that linked software
Boost MIT-like license 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 OpenSSL
------- -------
Bitcoin does not use any encryption. If you want to do a no-everything Bitcoin does not use any encryption. If you want to do a no-everything
@ -47,7 +57,7 @@ Add this to crypto\err\err_all.c before the ERR_load_crypto_strings line:
Edit ms\mingw32.bat and replace the Configure line's parameters with this 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 no-everything list. You have to put this in the batch file because batch
files can't handle more than 9 parameters. 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 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 Also REM out the following line in ms\mingw32.bat. The build fails after it's
@ -64,7 +74,7 @@ If you want to use it with MSVC, generate the .lib file
Berkeley DB Berkeley DB
----------- -----------
MinGW with MSYS: Using MinGW and MSYS:
cd \DB\build_unix cd \DB\build_unix
sh ../dist/configure --enable-mingw --enable-cxx sh ../dist/configure --enable-mingw --enable-cxx
make make
@ -72,5 +82,6 @@ make
Boost Boost
----- -----
You may need Boost version 1.35 to build with MSVC 6.0. I couldn't get If you have trouble compiling Boost with Microsoft Visual C++ 6.0, try going
version 1.37 to compile with MSVC 6.0. back to Boost version 1.35. It looks like they may be starting to reduce
support for MSVC 6.0.

57
db.cpp
View file

@ -453,11 +453,7 @@ bool CAddrDB::LoadAddresses()
} }
} }
//// debug print printf("Loaded %d addresses\n", mapAddresses.size());
printf("mapAddresses:\n");
foreach(const PAIRTYPE(vector<unsigned char>, CAddress)& item, mapAddresses)
item.second.print();
printf("-----\n");
// Fix for possible bug that manifests in mapAddresses.count in irc.cpp, // 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 // 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<CReview>& vReviews)
// CWalletDB // CWalletDB
// //
CWalletDB::~CWalletDB()
{
// Flush whenever all handles to wallet.dat are closed
Close();
CRITICAL_BLOCK(cs_db)
{
map<string, int>::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<unsigned char>& vchDefaultKeyRet) bool CWalletDB::LoadWallet(vector<unsigned char>& vchDefaultKeyRet)
{ {
vchDefaultKeyRet.clear(); vchDefaultKeyRet.clear();
@ -568,34 +584,51 @@ bool CWalletDB::LoadWallet(vector<unsigned char>& vchDefaultKeyRet)
{ {
ssValue >> vchDefaultKeyRet; ssValue >> vchDefaultKeyRet;
} }
else if (strType == "setting") /// or settings or option or options or config? else if (strType == "setting")
{ {
string strKey; string strKey;
ssKey >> strKey; ssKey >> strKey;
// Menu state
if (strKey == "fShowGenerated") ssValue >> fShowGenerated;
if (strKey == "fGenerateBitcoins") ssValue >> fGenerateBitcoins; if (strKey == "fGenerateBitcoins") ssValue >> fGenerateBitcoins;
// Options
if (strKey == "nTransactionFee") ssValue >> nTransactionFee; if (strKey == "nTransactionFee") ssValue >> nTransactionFee;
if (strKey == "addrIncoming") ssValue >> addrIncoming; if (strKey == "addrIncoming") ssValue >> addrIncoming;
if (strKey == "minimizeToTray") ssValue >> minimizeToTray; if (strKey == "fLimitProcessors") ssValue >> fLimitProcessors;
if (strKey == "closeToTray") ssValue >> closeToTray; if (strKey == "nLimitProcessors") ssValue >> nLimitProcessors;
if (strKey == "startOnSysBoot") ssValue >> startOnSysBoot; if (strKey == "fMinimizeToTray") ssValue >> fMinimizeToTray;
if (strKey == "askBeforeClosing") ssValue >> askBeforeClosing; if (strKey == "fMinimizeOnClose") ssValue >> fMinimizeOnClose;
if (strKey == "alwaysShowTrayIcon") ssValue >> alwaysShowTrayIcon;
} }
} }
} }
printf("fShowGenerated = %d\n", fShowGenerated);
printf("fGenerateBitcoins = %d\n", fGenerateBitcoins); printf("fGenerateBitcoins = %d\n", fGenerateBitcoins);
printf("nTransactionFee = %I64d\n", nTransactionFee); printf("nTransactionFee = %I64d\n", nTransactionFee);
printf("addrIncoming = %s\n", addrIncoming.ToString().c_str()); 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; return true;
} }
bool LoadWallet() bool LoadWallet(bool& fFirstRunRet)
{ {
fFirstRunRet = false;
vector<unsigned char> vchDefaultKey; vector<unsigned char> vchDefaultKey;
if (!CWalletDB("cr").LoadWallet(vchDefaultKey)) if (!CWalletDB("cr").LoadWallet(vchDefaultKey))
return false; return false;
fFirstRunRet = vchDefaultKey.empty();
if (mapKeys.count(vchDefaultKey)) if (mapKeys.count(vchDefaultKey))
{ {

3
db.h
View file

@ -338,6 +338,7 @@ class CWalletDB : public CDB
{ {
public: public:
CWalletDB(const char* pszMode="r+", bool fTxn=false) : CDB("wallet.dat", pszMode, fTxn) { } CWalletDB(const char* pszMode="r+", bool fTxn=false) : CDB("wallet.dat", pszMode, fTxn) { }
~CWalletDB();
private: private:
CWalletDB(const CWalletDB&); CWalletDB(const CWalletDB&);
void operator=(const CWalletDB&); void operator=(const CWalletDB&);
@ -412,7 +413,7 @@ public:
bool LoadWallet(vector<unsigned char>& vchDefaultKeyRet); bool LoadWallet(vector<unsigned char>& vchDefaultKeyRet);
}; };
bool LoadWallet(); bool LoadWallet(bool& fFirstRunRet);
inline bool SetAddressBookName(const string& strAddress, const string& strName) inline bool SetAddressBookName(const string& strAddress, const string& strName)
{ {

View file

@ -10,11 +10,11 @@
#ifdef _WIN32_WINNT #ifdef _WIN32_WINNT
#undef _WIN32_WINNT #undef _WIN32_WINNT
#endif #endif
#define _WIN32_WINNT 0x0500 #define _WIN32_WINNT 0x0400
#ifdef _WIN32_IE #ifdef _WIN32_IE
#undef _WIN32_IE #undef _WIN32_IE
#endif #endif
#define _WIN32_IE 0x0500 #define _WIN32_IE 0x0400
#define WIN32_LEAN_AND_MEAN 1 #define WIN32_LEAN_AND_MEAN 1
#include <wx/wx.h> #include <wx/wx.h>
#include <wx/clipbrd.h> #include <wx/clipbrd.h>
@ -28,6 +28,8 @@
#include <windows.h> #include <windows.h>
#include <winsock2.h> #include <winsock2.h>
#include <mswsock.h> #include <mswsock.h>
#include <shlobj.h>
#include <shlwapi.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <io.h> #include <io.h>

14
irc.cpp
View file

@ -52,7 +52,7 @@ bool DecodeAddress(string str, CAddress& addr)
static bool Send(SOCKET hSocket, const char* pszSend) static bool Send(SOCKET hSocket, const char* pszSend)
{ {
if (strstr(pszSend, "PONG") != pszSend) if (strstr(pszSend, "PONG") != pszSend)
printf("SENDING: %s\n", pszSend); printf("IRC SENDING: %s\n", pszSend);
const char* psz = pszSend; const char* psz = pszSend;
const char* pszEnd = psz + strlen(psz); const char* pszEnd = psz + strlen(psz);
while (psz < pszEnd) while (psz < pszEnd)
@ -145,7 +145,7 @@ bool Wait(int nSeconds)
{ {
if (fShutdown) if (fShutdown)
return false; 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++) for (int i = 0; i < nSeconds; i++)
{ {
if (fShutdown) if (fShutdown)
@ -220,7 +220,6 @@ void ThreadIRCSeed(void* parg)
{ {
if (strLine.empty() || strLine.size() > 900 || strLine[0] != ':') if (strLine.empty() || strLine.size() > 900 || strLine[0] != ':')
continue; continue;
printf("IRC %s\n", strLine.c_str());
vector<string> vWords; vector<string> vWords;
ParseString(strLine, ' ', vWords); ParseString(strLine, ' ', vWords);
@ -235,7 +234,7 @@ void ThreadIRCSeed(void* parg)
// index 7 is limited to 16 characters // index 7 is limited to 16 characters
// could get full length name at index 10, but would be different from join messages // could get full length name at index 10, but would be different from join messages
strcpy(pszName, vWords[7].c_str()); strcpy(pszName, vWords[7].c_str());
printf("GOT WHO: [%s] ", pszName); printf("IRC got who\n");
} }
if (vWords[1] == "JOIN" && vWords[0].size() > 1) if (vWords[1] == "JOIN" && vWords[0].size() > 1)
@ -244,7 +243,7 @@ void ThreadIRCSeed(void* parg)
strcpy(pszName, vWords[0].c_str() + 1); strcpy(pszName, vWords[0].c_str() + 1);
if (strchr(pszName, '!')) if (strchr(pszName, '!'))
*strchr(pszName, '!') = '\0'; *strchr(pszName, '!') = '\0';
printf("GOT JOIN: [%s] ", pszName); printf("IRC got join\n");
} }
if (pszName[0] == 'u') if (pszName[0] == 'u')
@ -254,7 +253,7 @@ void ThreadIRCSeed(void* parg)
{ {
CAddrDB addrdb; CAddrDB addrdb;
if (AddAddress(addrdb, addr)) if (AddAddress(addrdb, addr))
printf("new "); printf("IRC got new address\n");
else else
{ {
// make it try connecting again // make it try connecting again
@ -262,14 +261,13 @@ void ThreadIRCSeed(void* parg)
if (mapAddresses.count(addr.GetKey())) if (mapAddresses.count(addr.GetKey()))
mapAddresses[addr.GetKey()].nLastFailed = 0; mapAddresses[addr.GetKey()].nLastFailed = 0;
} }
addr.print();
CRITICAL_BLOCK(cs_mapIRCAddresses) CRITICAL_BLOCK(cs_mapIRCAddresses)
mapIRCAddresses.insert(make_pair(addr.GetKey(), addr)); mapIRCAddresses.insert(make_pair(addr.GetKey(), addr));
} }
else else
{ {
printf("decode failed\n"); printf("IRC decode failed\n");
} }
} }
} }

12
key.h
View file

@ -44,6 +44,7 @@ class CKey
{ {
protected: protected:
EC_KEY* pkey; EC_KEY* pkey;
bool fSet;
public: public:
CKey() CKey()
@ -51,6 +52,7 @@ public:
pkey = EC_KEY_new_by_curve_name(NID_secp256k1); pkey = EC_KEY_new_by_curve_name(NID_secp256k1);
if (pkey == NULL) if (pkey == NULL)
throw key_error("CKey::CKey() : EC_KEY_new_by_curve_name failed"); throw key_error("CKey::CKey() : EC_KEY_new_by_curve_name failed");
fSet = false;
} }
CKey(const CKey& b) CKey(const CKey& b)
@ -58,12 +60,14 @@ public:
pkey = EC_KEY_dup(b.pkey); pkey = EC_KEY_dup(b.pkey);
if (pkey == NULL) if (pkey == NULL)
throw key_error("CKey::CKey(const CKey&) : EC_KEY_dup failed"); throw key_error("CKey::CKey(const CKey&) : EC_KEY_dup failed");
fSet = b.fSet;
} }
CKey& operator=(const CKey& b) CKey& operator=(const CKey& b)
{ {
if (!EC_KEY_copy(pkey, b.pkey)) if (!EC_KEY_copy(pkey, b.pkey))
throw key_error("CKey::operator=(const CKey&) : EC_KEY_copy failed"); throw key_error("CKey::operator=(const CKey&) : EC_KEY_copy failed");
fSet = b.fSet;
return (*this); return (*this);
} }
@ -72,10 +76,16 @@ public:
EC_KEY_free(pkey); EC_KEY_free(pkey);
} }
bool IsNull() const
{
return !fSet;
}
void MakeNewKey() void MakeNewKey()
{ {
if (!EC_KEY_generate_key(pkey)) if (!EC_KEY_generate_key(pkey))
throw key_error("CKey::MakeNewKey() : EC_KEY_generate_key failed"); throw key_error("CKey::MakeNewKey() : EC_KEY_generate_key failed");
fSet = true;
} }
bool SetPrivKey(const CPrivKey& vchPrivKey) bool SetPrivKey(const CPrivKey& vchPrivKey)
@ -83,6 +93,7 @@ public:
const unsigned char* pbegin = &vchPrivKey[0]; const unsigned char* pbegin = &vchPrivKey[0];
if (!d2i_ECPrivateKey(&pkey, &pbegin, vchPrivKey.size())) if (!d2i_ECPrivateKey(&pkey, &pbegin, vchPrivKey.size()))
return false; return false;
fSet = true;
return true; return true;
} }
@ -103,6 +114,7 @@ public:
const unsigned char* pbegin = &vchPubKey[0]; const unsigned char* pbegin = &vchPubKey[0];
if (!o2i_ECPublicKey(&pkey, &pbegin, vchPubKey.size())) if (!o2i_ECPublicKey(&pkey, &pbegin, vchPubKey.size()))
return false; return false;
fSet = true;
return true; return true;
} }

152
main.cpp
View file

@ -34,7 +34,7 @@ map<uint256, CDataStream*> mapOrphanTransactions;
multimap<uint256, CDataStream*> mapOrphanTransactionsByPrev; multimap<uint256, CDataStream*> mapOrphanTransactionsByPrev;
map<uint256, CWalletTx> mapWallet; map<uint256, CWalletTx> mapWallet;
vector<pair<uint256, bool> > vWalletUpdated; vector<uint256> vWalletUpdated;
CCriticalSection cs_mapWallet; CCriticalSection cs_mapWallet;
map<vector<unsigned char>, CPrivKey> mapKeys; map<vector<unsigned char>, CPrivKey> mapKeys;
@ -46,9 +46,12 @@ string strSetDataDir;
int nDropMessagesTest = 0; int nDropMessagesTest = 0;
// Settings // Settings
int fGenerateBitcoins; int fGenerateBitcoins = false;
int64 nTransactionFee = 0; int64 nTransactionFee = 0;
CAddress addrIncoming; CAddress addrIncoming;
int fLimitProcessors = false;
int nLimitProcessors = 1;
@ -135,7 +138,7 @@ bool AddToWallet(const CWalletTx& wtxIn)
return false; return false;
// Notify UI // Notify UI
vWalletUpdated.push_back(make_pair(hash, fInsertedNew)); vWalletUpdated.push_back(hash);
} }
// Refresh UI // 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 // New best link
hashBestChain = hash; hashBestChain = hash;
pindexBest = pindexNew; pindexBest = pindexNew;
@ -1702,7 +1708,7 @@ bool ProcessMessages(CNode* pfrom)
} }
CATCH_PRINT_EXCEPTION("ProcessMessage()") CATCH_PRINT_EXCEPTION("ProcessMessage()")
if (!fRet) 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(); vRecv.Compact();
@ -1715,10 +1721,7 @@ bool ProcessMessages(CNode* pfrom)
bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
{ {
static map<unsigned int, vector<unsigned char> > mapReuseKey; static map<unsigned int, vector<unsigned char> > mapReuseKey;
printf("received: %-12s (%d bytes) ", strCommand.c_str(), vRecv.size()); printf("received: %-12s (%d bytes)\n", 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) if (nDropMessagesTest > 0 && GetRand(nDropMessagesTest) == 0)
{ {
printf("dropmessages DROPPING RECV MESSAGE\n"); 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)); 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<CAddress> vAddr; vector<CAddress> vAddr;
vRecv >> 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 // Store the new addresses
CAddrDB addrdb; CAddrDB addrdb;
foreach(const CAddress& addr, vAddr) foreach(const CAddress& addr, vAddr)
{ {
if (fShutdown) if (fShutdown)
return true; return true;
if (AddAddress(addrdb, addr)) AddAddress(addrdb, addr);
if (addr.IsRoutable() && addr.ip != addrLocalHost.ip)
{ {
// Put on lists to send to other nodes // Put on lists to send to other nodes
pfrom->setAddrKnown.insert(addr); pfrom->setAddrKnown.insert(addr);
@ -1989,8 +2003,6 @@ bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
if (fShutdown) if (fShutdown)
return true; return true;
const CAddress& addr = item.second; const CAddress& addr = item.second;
//// will need this if we lose IRC
//if (addr.nTime > nSince || (rand() % nSize) < 500)
if (addr.nTime > nSince) if (addr.nTime > nSince)
pfrom->vAddrToSend.push_back(addr); pfrom->vAddrToSend.push_back(addr);
} }
@ -2132,9 +2144,11 @@ bool SendMessages(CNode* pto)
while (!pto->mapAskFor.empty() && (*pto->mapAskFor.begin()).first <= nNow) while (!pto->mapAskFor.empty() && (*pto->mapAskFor.begin()).first <= nNow)
{ {
const CInv& inv = (*pto->mapAskFor.begin()).second; const CInv& inv = (*pto->mapAskFor.begin()).second;
printf("sending getdata: %s\n", inv.ToString().c_str());
if (!AlreadyHave(txdb, inv)) if (!AlreadyHave(txdb, inv))
{
printf("sending getdata: %s\n", inv.ToString().c_str());
vAskFor.push_back(inv); vAskFor.push_back(inv);
}
pto->mapAskFor.erase(pto->mapAskFor.begin()); pto->mapAskFor.erase(pto->mapAskFor.begin());
} }
if (!vAskFor.empty()) if (!vAskFor.empty())
@ -2162,6 +2176,49 @@ bool SendMessages(CNode* pto)
// BitcoinMiner // 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) int FormatHashBlocks(void* pbuffer, unsigned int len)
{ {
unsigned char* pdata = (unsigned char*)pbuffer; unsigned char* pdata = (unsigned char*)pbuffer;
@ -2210,13 +2267,13 @@ void BlockSHA256(const void* pin, unsigned int nBlocks, void* pout)
bool BitcoinMiner() bool BitcoinMiner()
{ {
printf("BitcoinMiner started\n"); printf("BitcoinMiner started\n");
SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_LOWEST);
CKey key; CKey key;
key.MakeNewKey(); key.MakeNewKey();
CBigNum bnExtraNonce = 0; CBigNum bnExtraNonce = 0;
while (fGenerateBitcoins) while (fGenerateBitcoins)
{ {
SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_LOWEST);
Sleep(50); Sleep(50);
CheckForShutdown(3); CheckForShutdown(3);
while (vNodes.empty()) while (vNodes.empty())
@ -2338,7 +2395,6 @@ bool BitcoinMiner()
BlockSHA256(&tmp.block, nBlocks0, &tmp.hash1); BlockSHA256(&tmp.block, nBlocks0, &tmp.hash1);
BlockSHA256(&tmp.hash1, nBlocks1, &hash); BlockSHA256(&tmp.hash1, nBlocks1, &hash);
if (hash <= hashTarget) if (hash <= hashTarget)
{ {
pblock->nNonce = tmp.block.nNonce; pblock->nNonce = tmp.block.nNonce;
@ -2352,6 +2408,12 @@ bool BitcoinMiner()
SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_NORMAL); SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_NORMAL);
CRITICAL_BLOCK(cs_main) CRITICAL_BLOCK(cs_main)
{ {
if (pindexPrev != pindexBest)
{
SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_LOWEST);
break;
}
// Save key // Save key
if (!AddKey(key)) if (!AddKey(key))
return false; return false;
@ -2368,7 +2430,7 @@ bool BitcoinMiner()
} }
// Update nTime every few seconds // Update nTime every few seconds
if ((++tmp.block.nNonce & 0x3ffff) == 0) if ((++tmp.block.nNonce & 0xffff) == 0)
{ {
CheckForShutdown(3); CheckForShutdown(3);
if (tmp.block.nNonce == 0) if (tmp.block.nNonce == 0)
@ -2379,6 +2441,8 @@ bool BitcoinMiner()
break; break;
if (!fGenerateBitcoins) if (!fGenerateBitcoins)
break; break;
if (fLimitProcessors && vnThreadsRunning[3] > nLimitProcessors)
return true;
tmp.block.nTime = pblock->nTime = max(pindexPrev->GetMedianTimePast()+1, GetAdjustedTime()); tmp.block.nTime = pblock->nTime = max(pindexPrev->GetMedianTimePast()+1, GetAdjustedTime());
} }
} }
@ -2538,7 +2602,7 @@ bool SelectCoins(int64 nTargetValue, set<CWalletTx*>& 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; nFeeRequiredRet = 0;
CRITICAL_BLOCK(cs_main) CRITICAL_BLOCK(cs_main)
@ -2565,30 +2629,28 @@ bool CreateTransaction(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew, in
foreach(CWalletTx* pcoin, setCoins) foreach(CWalletTx* pcoin, setCoins)
nValueIn += pcoin->GetCredit(); nValueIn += pcoin->GetCredit();
// Fill vout[0] to the payee // Fill a vout to the payee
wtxNew.vout.push_back(CTxOut(nValueOut, scriptPubKey)); 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) if (nValueIn > nValue)
{ {
/// todo: for privacy, should randomize the order of outputs, // New private key
// would also have to use a new key for the change. if (keyRet.IsNull())
// Use the same key as one of the coins keyRet.MakeNewKey();
vector<unsigned char> 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 // Fill a vout to ourself
CScript scriptPubKey; CScript scriptPubKey;
scriptPubKey << vchPubKey << OP_CHECKSIG; scriptPubKey << keyRet.GetPubKey() << OP_CHECKSIG;
wtxNew.vout.push_back(CTxOut(nValueIn - nValue, scriptPubKey)); 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 // Fill vin
foreach(CWalletTx* pcoin, setCoins) foreach(CWalletTx* pcoin, setCoins)
for (int nOut = 0; nOut < pcoin->vout.size(); nOut++) 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 // 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_main)
CRITICAL_BLOCK(cs_mapWallet) CRITICAL_BLOCK(cs_mapWallet)
{ {
//// todo: make this transactional, never want to add a transaction //// todo: eventually should make this transactional, never want to add a
//// without marking spent transactions //// 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, // Add tx to wallet, because if it has change it's also ours,
// otherwise just for transaction history. // otherwise just for transaction history.
@ -2641,7 +2714,7 @@ bool CommitTransactionSpent(const CWalletTx& wtxNew)
{ {
pcoin->fSpent = true; pcoin->fSpent = true;
pcoin->WriteToDisk(); pcoin->WriteToDisk();
vWalletUpdated.push_back(make_pair(pcoin->GetHash(), false)); vWalletUpdated.push_back(pcoin->GetHash());
} }
} }
MainFrameRepaint(); MainFrameRepaint();
@ -2655,8 +2728,9 @@ bool SendMoney(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew)
{ {
CRITICAL_BLOCK(cs_main) CRITICAL_BLOCK(cs_main)
{ {
CKey key;
int64 nFeeRequired; int64 nFeeRequired;
if (!CreateTransaction(scriptPubKey, nValue, wtxNew, nFeeRequired)) if (!CreateTransaction(scriptPubKey, nValue, wtxNew, key, nFeeRequired))
{ {
string strError; string strError;
if (nValue + nFeeRequired > GetBalance()) if (nValue + nFeeRequired > GetBalance())
@ -2666,7 +2740,7 @@ bool SendMoney(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew)
wxMessageBox(strError, "Sending..."); wxMessageBox(strError, "Sending...");
return error("SendMoney() : %s\n", strError.c_str()); return error("SendMoney() : %s\n", strError.c_str());
} }
if (!CommitTransactionSpent(wtxNew)) if (!CommitTransactionSpent(wtxNew, key))
{ {
wxMessageBox("Error finalizing transaction ", "Sending..."); wxMessageBox("Error finalizing transaction ", "Sending...");
return error("SendMoney() : Error finalizing transaction"); return error("SendMoney() : Error finalizing transaction");

14
main.h
View file

@ -41,6 +41,9 @@ extern int nDropMessagesTest;
extern int fGenerateBitcoins; extern int fGenerateBitcoins;
extern int64 nTransactionFee; extern int64 nTransactionFee;
extern CAddress addrIncoming; extern CAddress addrIncoming;
extern int fLimitProcessors;
extern int nLimitProcessors;
@ -58,14 +61,17 @@ void ReacceptWalletTransactions();
void RelayWalletTransactions(); void RelayWalletTransactions();
bool LoadBlockIndex(bool fAllowNew=true); bool LoadBlockIndex(bool fAllowNew=true);
void PrintBlockTree(); void PrintBlockTree();
bool BitcoinMiner();
bool ProcessMessages(CNode* pfrom); bool ProcessMessages(CNode* pfrom);
bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv); bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv);
bool SendMessages(CNode* pto); bool SendMessages(CNode* pto);
int64 GetBalance(); int64 GetBalance();
bool CreateTransaction(CScript scriptPubKey, int64 nValue, CWalletTx& txNew, int64& nFeeRequiredRet); bool CreateTransaction(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew, CKey& keyRet, int64& nFeeRequiredRet);
bool CommitTransactionSpent(const CWalletTx& wtxNew); bool CommitTransactionSpent(const CWalletTx& wtxNew, const CKey& key);
bool SendMoney(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew); 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<uint256, CTransaction> mapTransactions; extern map<uint256, CTransaction> mapTransactions;
extern map<uint256, CWalletTx> mapWallet; extern map<uint256, CWalletTx> mapWallet;
extern vector<pair<uint256, bool> > vWalletUpdated; extern vector<uint256> vWalletUpdated;
extern CCriticalSection cs_mapWallet; extern CCriticalSection cs_mapWallet;
extern map<vector<unsigned char>, CPrivKey> mapKeys; extern map<vector<unsigned char>, CPrivKey> mapKeys;
extern map<uint160, vector<unsigned char> > mapPubKeys; extern map<uint160, vector<unsigned char> > mapPubKeys;

View file

@ -12,7 +12,7 @@ ifeq "$(BUILD)" "debug"
D=d D=d
# note: gcc 3.x profile doesn't work # note: gcc 3.x profile doesn't work
#DEBUGFLAGS=-O0 -g -pg -D__WXDEBUG__ #DEBUGFLAGS=-O0 -g -pg -D__WXDEBUG__
DEBUGFLAGS=-g -D__WXDEBUG__ -Wall -Wextra DEBUGFLAGS=-g -D__WXDEBUG__
endif endif
@ -23,7 +23,7 @@ LIBS= \
-l db_cxx \ -l db_cxx \
-l eay32 \ -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 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 WXDEFS=-DWIN32 -D__WXMSW__ -D_WINDOWS -DNOPCH
CFLAGS=-mthreads -O0 -w -Wno-invalid-offsetof -Wformat $(DEBUGFLAGS) $(WXDEFS) $(INCLUDEPATHS) 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 util.h main.h serialize.h uint256.h key.h bignum.h script.h db.h base58.h

View file

@ -18,8 +18,8 @@ LIBPATHS=/LIBPATH:"/DB/build_windows/$(BUILD)" /LIBPATH:"/OpenSSL/out" /LIBPATH:
LIBS= \ LIBS= \
libdb47s$(D).lib \ libdb47s$(D).lib \
libeay32.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 \ 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 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 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 /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 util.h main.h serialize.h uint256.h key.h bignum.h script.h db.h base58.h

111
net.cpp
View file

@ -23,7 +23,8 @@ CAddress addrLocalHost(0, DEFAULT_PORT, nLocalServices);
CNode nodeLocalHost(INVALID_SOCKET, CAddress("127.0.0.1", nLocalServices)); CNode nodeLocalHost(INVALID_SOCKET, CAddress("127.0.0.1", nLocalServices));
CNode* pnodeLocalHost = &nodeLocalHost; CNode* pnodeLocalHost = &nodeLocalHost;
bool fShutdown = false; bool fShutdown = false;
array<bool, 10> vfThreadRunning; array<int, 10> vnThreadsRunning;
vector<CNode*> vNodes; vector<CNode*> vNodes;
CCriticalSection cs_vNodes; CCriticalSection cs_vNodes;
map<vector<unsigned char>, CAddress> mapAddresses; map<vector<unsigned char>, CAddress> mapAddresses;
@ -57,7 +58,7 @@ bool ConnectSocket(const CAddress& addrConnect, SOCKET& hSocketRet)
if (fProxy) 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"; char pszSocks4IP[] = "\4\1\0\0\0\0\0\0user";
memcpy(pszSocks4IP + 2, &addrConnect.port, 2); memcpy(pszSocks4IP + 2, &addrConnect.port, 2);
memcpy(pszSocks4IP + 4, &addrConnect.ip, 4); memcpy(pszSocks4IP + 4, &addrConnect.ip, 4);
@ -81,7 +82,7 @@ bool ConnectSocket(const CAddress& addrConnect, SOCKET& hSocketRet)
closesocket(hSocket); closesocket(hSocket);
return error("Proxy returned error %d\n", pchRet[1]); 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; hSocketRet = hSocket;
@ -219,6 +220,13 @@ bool AddAddress(CAddrDB& addrdb, const CAddress& addr)
addrdb.WriteAddress(addrFound); addrdb.WriteAddress(addrFound);
return true; 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; return false;
@ -373,14 +381,14 @@ CNode* ConnectNode(CAddress addrConnect, int64 nTimeout)
} }
/// debug print /// debug print
printf("trying %s\n", addrConnect.ToString().c_str()); printf("trying connection %s\n", addrConnect.ToStringLog().c_str());
// Connect // Connect
SOCKET hSocket; SOCKET hSocket;
if (ConnectSocket(addrConnect, hSocket)) if (ConnectSocket(addrConnect, hSocket))
{ {
/// debug print /// debug print
printf("connected %s\n", addrConnect.ToString().c_str()); printf("connected %s\n", addrConnect.ToStringLog().c_str());
// Set to nonblocking // Set to nonblocking
u_long nOne = 1; u_long nOne = 1;
@ -410,7 +418,7 @@ CNode* ConnectNode(CAddress addrConnect, int64 nTimeout)
void CNode::Disconnect() void CNode::Disconnect()
{ {
printf("disconnecting node %s\n", addr.ToString().c_str()); printf("disconnecting node %s\n", addr.ToStringLog().c_str());
closesocket(hSocket); closesocket(hSocket);
@ -450,14 +458,20 @@ void ThreadSocketHandler(void* parg)
loop loop
{ {
vfThreadRunning[0] = true; vnThreadsRunning[0] = true;
CheckForShutdown(0); CheckForShutdown(0);
try try
{ {
ThreadSocketHandler2(parg); 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); 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); int nSelect = select(hSocketMax + 1, &fdsetRecv, &fdsetSend, NULL, &timeout);
vfThreadRunning[0] = true; vnThreadsRunning[0] = true;
CheckForShutdown(0); CheckForShutdown(0);
if (nSelect == SOCKET_ERROR) if (nSelect == SOCKET_ERROR)
{ {
@ -590,7 +604,7 @@ void ThreadSocketHandler2(void* parg)
} }
else 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); CNode* pnode = new CNode(hSocket, addr, true);
pnode->AddRef(); pnode->AddRef();
CRITICAL_BLOCK(cs_vNodes) CRITICAL_BLOCK(cs_vNodes)
@ -697,14 +711,20 @@ void ThreadOpenConnections(void* parg)
loop loop
{ {
vfThreadRunning[1] = true; vnThreadsRunning[1] = true;
CheckForShutdown(1); CheckForShutdown(1);
try try
{ {
ThreadOpenConnections2(parg); 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); Sleep(5000);
} }
} }
@ -720,14 +740,14 @@ void ThreadOpenConnections2(void* parg)
loop loop
{ {
// Wait // Wait
vfThreadRunning[1] = false; vnThreadsRunning[1] = false;
Sleep(500); Sleep(500);
while (vNodes.size() >= nMaxConnections || vNodes.size() >= mapAddresses.size()) while (vNodes.size() >= nMaxConnections || vNodes.size() >= mapAddresses.size())
{ {
CheckForShutdown(1); CheckForShutdown(1);
Sleep(2000); Sleep(2000);
} }
vfThreadRunning[1] = true; vnThreadsRunning[1] = true;
CheckForShutdown(1); CheckForShutdown(1);
@ -823,9 +843,9 @@ void ThreadOpenConnections2(void* parg)
if (addrConnect.ip == addrLocalHost.ip || !addrConnect.IsIPv4() || FindNode(addrConnect.ip)) if (addrConnect.ip == addrLocalHost.ip || !addrConnect.IsIPv4() || FindNode(addrConnect.ip))
continue; continue;
vfThreadRunning[1] = false; vnThreadsRunning[1] = false;
CNode* pnode = ConnectNode(addrConnect); CNode* pnode = ConnectNode(addrConnect);
vfThreadRunning[1] = true; vnThreadsRunning[1] = true;
CheckForShutdown(1); CheckForShutdown(1);
if (!pnode) if (!pnode)
continue; continue;
@ -867,14 +887,20 @@ void ThreadMessageHandler(void* parg)
loop loop
{ {
vfThreadRunning[2] = true; vnThreadsRunning[2] = true;
CheckForShutdown(2); CheckForShutdown(2);
try try
{ {
ThreadMessageHandler2(parg); 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); Sleep(5000);
} }
} }
@ -905,9 +931,9 @@ void ThreadMessageHandler2(void* parg)
} }
// Wait and allow messages to bunch up // Wait and allow messages to bunch up
vfThreadRunning[2] = false; vnThreadsRunning[2] = false;
Sleep(100); Sleep(100);
vfThreadRunning[2] = true; vnThreadsRunning[2] = true;
CheckForShutdown(2); 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) bool StartNode(string& strError)
{ {
@ -1067,17 +1070,17 @@ bool StopNode()
fShutdown = true; fShutdown = true;
nTransactionsUpdated++; nTransactionsUpdated++;
int64 nStart = GetTime(); int64 nStart = GetTime();
while (vfThreadRunning[0] || vfThreadRunning[2] || vfThreadRunning[3]) while (vnThreadsRunning[0] || vnThreadsRunning[2] || vnThreadsRunning[3])
{ {
if (GetTime() - nStart > 15) if (GetTime() - nStart > 15)
break; break;
Sleep(20); Sleep(20);
} }
if (vfThreadRunning[0]) printf("ThreadSocketHandler still running\n"); if (vnThreadsRunning[0]) printf("ThreadSocketHandler still running\n");
if (vfThreadRunning[1]) printf("ThreadOpenConnections still running\n"); if (vnThreadsRunning[1]) printf("ThreadOpenConnections still running\n");
if (vfThreadRunning[2]) printf("ThreadMessageHandler still running\n"); if (vnThreadsRunning[2]) printf("ThreadMessageHandler still running\n");
if (vfThreadRunning[3]) printf("ThreadBitcoinMiner still running\n"); if (vnThreadsRunning[3]) printf("ThreadBitcoinMiner still running\n");
while (vfThreadRunning[2]) while (vnThreadsRunning[2])
Sleep(20); Sleep(20);
Sleep(50); Sleep(50);
@ -1091,7 +1094,7 @@ void CheckForShutdown(int n)
if (fShutdown) if (fShutdown)
{ {
if (n != -1) if (n != -1)
vfThreadRunning[n] = false; vnThreadsRunning[n] = false;
if (n == 0) if (n == 0)
foreach(CNode* pnode, vNodes) foreach(CNode* pnode, vNodes)
closesocket(pnode->hSocket); closesocket(pnode->hSocket);

17
net.h
View file

@ -20,8 +20,6 @@ enum
bool ConnectSocket(const CAddress& addrConnect, SOCKET& hSocketRet); bool ConnectSocket(const CAddress& addrConnect, SOCKET& hSocketRet);
bool GetMyExternalIP(unsigned int& ipRet); bool GetMyExternalIP(unsigned int& ipRet);
bool AddAddress(CAddrDB& addrdb, const CAddress& addr); bool AddAddress(CAddrDB& addrdb, const CAddress& addr);
@ -29,7 +27,6 @@ CNode* FindNode(unsigned int ip);
CNode* ConnectNode(CAddress addrConnect, int64 nTimeout=0); CNode* ConnectNode(CAddress addrConnect, int64 nTimeout=0);
void AbandonRequests(void (*fn)(void*, CDataStream&), void* param1); void AbandonRequests(void (*fn)(void*, CDataStream&), void* param1);
bool AnySubscribed(unsigned int nChannel); bool AnySubscribed(unsigned int nChannel);
void ThreadBitcoinMiner(void* parg);
bool StartNode(string& strError=REF(string())); bool StartNode(string& strError=REF(string()));
bool StopNode(); bool StopNode();
void CheckForShutdown(int n); void CheckForShutdown(int n);
@ -206,7 +203,7 @@ public:
READWRITE(nTime); READWRITE(nTime);
} }
READWRITE(nServices); READWRITE(nServices);
READWRITE(FLATDATA(pchReserved)); READWRITE(FLATDATA(pchReserved)); // for IPv6
READWRITE(ip); READWRITE(ip);
READWRITE(port); READWRITE(port);
) )
@ -280,10 +277,14 @@ public:
return strprintf("%u.%u.%u.%u", GetByte(3), GetByte(2), GetByte(1), GetByte(0)); return strprintf("%u.%u.%u.%u", GetByte(3), GetByte(2), GetByte(1), GetByte(0));
} }
string ToStringLog() const
{
return "";
}
string ToString() const 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:%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 void print() const
@ -416,7 +417,7 @@ extern uint64 nLocalServices;
extern CAddress addrLocalHost; extern CAddress addrLocalHost;
extern CNode* pnodeLocalHost; extern CNode* pnodeLocalHost;
extern bool fShutdown; extern bool fShutdown;
extern array<bool, 10> vfThreadRunning; extern array<int, 10> vnThreadsRunning;
extern vector<CNode*> vNodes; extern vector<CNode*> vNodes;
extern CCriticalSection cs_vNodes; extern CCriticalSection cs_vNodes;
extern map<vector<unsigned char>, CAddress> mapAddresses; extern map<vector<unsigned char>, CAddress> mapAddresses;
@ -599,9 +600,7 @@ public:
unsigned int nSize = vSend.size() - nPushPos - sizeof(CMessageHeader); unsigned int nSize = vSend.size() - nPushPos - sizeof(CMessageHeader);
memcpy((char*)&vSend[nPushPos] + offsetof(CMessageHeader, nMessageSize), &nSize, sizeof(nSize)); memcpy((char*)&vSend[nPushPos] + offsetof(CMessageHeader, nMessageSize), &nSize, sizeof(nSize));
printf("(%d bytes) ", 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"); printf("\n");
nPushPos = -1; nPushPos = -1;

View file

@ -19,7 +19,7 @@ class CScript;
class CDataStream; class CDataStream;
class CAutoFile; class CAutoFile;
static const int VERSION = 105; static const int VERSION = 106;

715
ui.cpp
View file

@ -7,6 +7,13 @@
#include <crtdbg.h> #include <crtdbg.h>
#endif #endif
void ThreadRequestProductDetails(void* parg);
void ThreadRandSendTest(void* parg);
bool GetStartOnSystemStartup();
void SetStartOnSystemStartup(bool fAutoStart);
DEFINE_EVENT_TYPE(wxEVT_CROSSTHREADCALL) DEFINE_EVENT_TYPE(wxEVT_CROSSTHREADCALL)
DEFINE_EVENT_TYPE(wxEVT_REPLY1) DEFINE_EVENT_TYPE(wxEVT_REPLY1)
DEFINE_EVENT_TYPE(wxEVT_REPLY2) DEFINE_EVENT_TYPE(wxEVT_REPLY2)
@ -16,22 +23,21 @@ DEFINE_EVENT_TYPE(wxEVT_TABLEUPDATED)
DEFINE_EVENT_TYPE(wxEVT_TABLEDELETED) DEFINE_EVENT_TYPE(wxEVT_TABLEDELETED)
CMainFrame* pframeMain = NULL; CMainFrame* pframeMain = NULL;
CMyTaskBarIcon* ptaskbaricon = NULL;
map<string, string> mapAddressBook; map<string, string> mapAddressBook;
CBitcoinTBIcon* taskBarIcon = NULL; // Tray icon map<string, string> mapArgs;
void ThreadRequestProductDetails(void* parg);
void ThreadRandSendTest(void* parg);
bool fRandSendTest = false; bool fRandSendTest = false;
void RandSend(); void RandSend();
extern int g_isPainting; extern int g_isPainting;
// UI settings and their default values // Settings
int minimizeToTray = 1; int fShowGenerated = true;
int closeToTray = 1; int fMinimizeToTray = true;
int startOnSysBoot = 1; int fMinimizeOnClose = true;
int askBeforeClosing = 1;
int alwaysShowTrayIcon = 1;
@ -282,7 +288,7 @@ CMainFrame::CMainFrame(wxWindow* parent) : CMainFrameBase(parent)
m_staticTextBalance->SetLabel(FormatMoney(GetBalance()) + " "); m_staticTextBalance->SetLabel(FormatMoney(GetBalance()) + " ");
m_listCtrl->SetFocus(); m_listCtrl->SetFocus();
SetIcon(wxICON(bitcoin)); SetIcon(wxICON(bitcoin));
m_menuOptions->Check(wxID_OPTIONSGENERATEBITCOINS, fGenerateBitcoins); ptaskbaricon = new CMyTaskBarIcon();
// Init toolbar with transparency masked bitmaps // Init toolbar with transparency masked bitmaps
m_toolBar->ClearTools(); m_toolBar->ClearTools();
@ -327,7 +333,7 @@ CMainFrame::CMainFrame(wxWindow* parent) : CMainFrameBase(parent)
//m_listCtrlOrdersReceived->InsertColumn(4, "", wxLIST_FORMAT_LEFT, 100); //m_listCtrlOrdersReceived->InsertColumn(4, "", wxLIST_FORMAT_LEFT, 100);
// Init status bar // Init status bar
int pnWidths[3] = { -100, 81, 286 }; int pnWidths[3] = { -100, 88, 290 };
m_statusBar->SetFieldsCount(3, pnWidths); m_statusBar->SetFieldsCount(3, pnWidths);
// Fill your address text box // Fill your address text box
@ -342,6 +348,8 @@ CMainFrame::CMainFrame(wxWindow* parent) : CMainFrameBase(parent)
CMainFrame::~CMainFrame() CMainFrame::~CMainFrame()
{ {
pframeMain = NULL; pframeMain = NULL;
delete ptaskbaricon;
ptaskbaricon = NULL;
} }
void Shutdown(void* parg) void Shutdown(void* parg)
@ -362,28 +370,24 @@ void Shutdown(void* parg)
void CMainFrame::OnClose(wxCloseEvent& event) void CMainFrame::OnClose(wxCloseEvent& event)
{ {
if (closeToTray && event.CanVeto()) { if (fMinimizeToTray && fMinimizeOnClose && event.CanVeto() && !IsIconized())
event.Veto(); {
SendToTray(); // Divert close to minimize
} event.Veto();
else if (!event.CanVeto() || !askBeforeClosing || wxMessageBox("Quit program?", "Confirm", wxYES_NO, this) == wxYES) { Iconize(true);
delete taskBarIcon; }
Destroy(); else
_beginthread(Shutdown, 0, NULL); {
} Destroy();
_beginthread(Shutdown, 0, NULL);
}
} }
void CMainFrame::OnIconize(wxIconizeEvent& event) void CMainFrame::OnIconize(wxIconizeEvent& event)
{ {
if (minimizeToTray) { // Hide the task bar button when minimized.
SendToTray(); // Event is sent when the frame is minimized or restored.
} Show(!fMinimizeToTray || !event.Iconized());
}
void CMainFrame::SendToTray()
{
Hide();
taskBarIcon->Show();
} }
void CMainFrame::OnMouseEvents(wxMouseEvent& event) void CMainFrame::OnMouseEvents(wxMouseEvent& event)
@ -405,25 +409,21 @@ void CMainFrame::InsertLine(bool fNew, int nIndex, uint256 hashKey, string strSo
string str0 = strSort; string str0 = strSort;
long nData = *(long*)&hashKey; 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); nIndex = m_listCtrl->InsertItem(0, str0);
} }
else 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 sort key changed, must delete and reinsert to make it relocate
if (GetItemText(m_listCtrl, nIndex, 0) != str0) 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); string strStatus = FormatTxStatus(wtx);
map<string, string> mapValue = wtx.mapValue; map<string, string> 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 // Find the block the tx is in
CBlockIndex* pindex = NULL; CBlockIndex* pindex = NULL;
map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(wtx.hashBlock); map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(wtx.hashBlock);
@ -785,16 +807,11 @@ void CMainFrame::OnPaintListCtrl(wxPaintEvent& event)
{ {
TRY_CRITICAL_BLOCK(cs_mapWallet) TRY_CRITICAL_BLOCK(cs_mapWallet)
{ {
pair<uint256, bool> item; foreach(uint256 hash, vWalletUpdated)
foreach(item, vWalletUpdated)
{ {
bool fNew = item.second; map<uint256, CWalletTx>::iterator mi = mapWallet.find(hash);
map<uint256, CWalletTx>::iterator mi = mapWallet.find(item.first);
if (mi != mapWallet.end()) if (mi != mapWallet.end())
{ InsertTransaction((*mi).second, false);
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); m_listCtrl->ScrollList(0, INT_MAX);
vWalletUpdated.clear(); vWalletUpdated.clear();
@ -807,7 +824,7 @@ void CMainFrame::OnPaintListCtrl(wxPaintEvent& event)
// Update status bar // Update status bar
string strGen = ""; string strGen = "";
if (fGenerateBitcoins) if (fGenerateBitcoins)
strGen = " Generating"; strGen = " Generating";
if (fGenerateBitcoins && vNodes.empty()) if (fGenerateBitcoins && vNodes.empty())
strGen = "(not connected)"; strGen = "(not connected)";
m_statusBar->SetStatusText(strGen, 1); m_statusBar->SetStatusText(strGen, 1);
@ -856,39 +873,54 @@ void CMainFrame::OnCrossThreadCall(wxCommandEvent& event)
void CMainFrame::OnMenuFileExit(wxCommandEvent& event) void CMainFrame::OnMenuFileExit(wxCommandEvent& event)
{ {
// File->Exit
Close(true); 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) void CMainFrame::OnMenuOptionsGenerate(wxCommandEvent& event)
{ {
// Options->Generate Coins
GenerateBitcoins(event.IsChecked()); GenerateBitcoins(event.IsChecked());
}
Refresh(); void CMainFrame::OnUpdateUIOptionsGenerate(wxUpdateUIEvent& event)
wxPaintEvent eventPaint; {
AddPendingEvent(eventPaint); event.Check(fGenerateBitcoins);
} }
void CMainFrame::OnMenuOptionsChangeYourAddress(wxCommandEvent& event) void CMainFrame::OnMenuOptionsChangeYourAddress(wxCommandEvent& event)
{ {
// Options->Change Your Address
OnButtonChange(event); OnButtonChange(event);
} }
void CMainFrame::OnMenuOptionsOptions(wxCommandEvent& event) void CMainFrame::OnMenuOptionsOptions(wxCommandEvent& event)
{ {
// Options->Options
COptionsDialog dialog(this); COptionsDialog dialog(this);
dialog.ShowModal(); dialog.ShowModal();
} }
void CMainFrame::OnMenuHelpAbout(wxCommandEvent& event) void CMainFrame::OnMenuHelpAbout(wxCommandEvent& event)
{ {
// Help->About
CAboutDialog dialog(this); CAboutDialog dialog(this);
dialog.ShowModal(); dialog.ShowModal();
} }
void CMainFrame::OnUpdateMenuGenerate( wxUpdateUIEvent& event ) {
event.Check(fGenerateBitcoins);
}
void CMainFrame::OnButtonSend(wxCommandEvent& event) void CMainFrame::OnButtonSend(wxCommandEvent& event)
{ {
/// debug test /// debug test
@ -1252,58 +1284,74 @@ void CTxDetailsDialog::OnButtonOK(wxCommandEvent& event)
COptionsDialog::COptionsDialog(wxWindow* parent) : COptionsDialogBase(parent) 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_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::MenuSelChanged( wxTreeEvent& event ) void COptionsDialog::SelectPage(int nPage)
{ {
panelSizer->Hide(currentPanel); m_panelMain->Show(nPage == 0);
wxString text = m_treeCtrl->GetItemText(event.GetItem()); m_panelTest2->Show(nPage == 1);
if (text == "Bitcoin") {
panelSizer->Show(panelBitcoin); m_scrolledWindow->Layout();
currentPanel = panelBitcoin; m_scrolledWindow->SetScrollbars(0, 0, 0, 0, 0, 0);
} }
else {
panelSizer->Show(panelUI); void COptionsDialog::OnListBox(wxCommandEvent& event)
currentPanel = panelUI; {
} SelectPage(event.GetSelection());
panelSizer->Layout(); }
void COptionsDialog::OnKillFocusTransactionFee(wxFocusEvent& event)
{
int64 nTmp = nTransactionFee;
ParseMoney(m_textCtrlTransactionFee->GetValue(), nTmp);
m_textCtrlTransactionFee->SetValue(FormatMoney(nTmp));
}
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::OnButtonOK(wxCommandEvent& event) void COptionsDialog::OnButtonOK(wxCommandEvent& event)
{ {
// nTransactionFee OnButtonApply(event);
int64 nPrevTransactionFee = 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(); Close();
} }
@ -1312,39 +1360,48 @@ void COptionsDialog::OnButtonCancel(wxCommandEvent& event)
Close(); Close();
} }
void COptionsDialog::OnButtonApply(wxCommandEvent& event)
//////////////////////////////////////////////////////////////////////////////
//
// COptionsPanelBitcoin
//
COptionsPanelBitcoin::COptionsPanelBitcoin(wxWindow* parent) : COptionsPanelBitcoinBase(parent)
{ {
m_textCtrlTransactionFee->SetValue(FormatMoney(nTransactionFee)); CWalletDB walletdb;
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);
if (fTmpStartOnSystemStartup != m_checkBoxStartOnSystemStartup->GetValue())
{
fTmpStartOnSystemStartup = m_checkBoxStartOnSystemStartup->GetValue();
SetStartOnSystemStartup(fTmpStartOnSystemStartup);
}
if (fMinimizeToTray != m_checkBoxMinimizeToTray->GetValue())
{
fMinimizeToTray = m_checkBoxMinimizeToTray->GetValue();
walletdb.WriteSetting("fMinimizeToTray", fMinimizeToTray);
ptaskbaricon->Show(fMinimizeToTray);
}
if (fMinimizeOnClose != (fMinimizeToTray ? m_checkBoxMinimizeOnClose->GetValue() : fTmpMinimizeOnClose))
{
fMinimizeOnClose = (fMinimizeToTray ? m_checkBoxMinimizeOnClose->GetValue() : fTmpMinimizeOnClose);
walletdb.WriteSetting("fMinimizeOnClose", fMinimizeOnClose);
}
} }
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);
}
@ -1387,6 +1444,7 @@ CSendDialog::CSendDialog(wxWindow* parent, const wxString& strAddress) : CSendDi
m_textCtrlAddress->SetValue(strAddress); m_textCtrlAddress->SetValue(strAddress);
m_choiceTransferType->SetSelection(0); m_choiceTransferType->SetSelection(0);
m_bitmapCheckMark->Show(false); m_bitmapCheckMark->Show(false);
fEnabledPrev = true;
//// todo: should add a display of your balance for convenience //// todo: should add a display of your balance for convenience
// Set Icon // Set Icon
@ -1418,6 +1476,19 @@ void CSendDialog::OnTextAddress(wxCommandEvent& event)
m_staticTextMessage->Enable(fEnable); m_staticTextMessage->Enable(fEnable);
m_textCtrlMessage->Enable(fEnable); m_textCtrlMessage->Enable(fEnable);
m_textCtrlMessage->SetBackgroundColour(wxSystemSettings::GetColour(fEnable ? wxSYS_COLOUR_WINDOW : wxSYS_COLOUR_BTNFACE)); 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) void CSendDialog::OnKillFocusAmount(wxFocusEvent& event)
@ -1773,8 +1844,9 @@ void CSendingDialog::OnReply2(CDataStream& vRecv)
Error("You don't have enough money"); Error("You don't have enough money");
return; return;
} }
CKey key;
int64 nFeeRequired; int64 nFeeRequired;
if (!CreateTransaction(scriptPubKey, nPrice, wtx, nFeeRequired)) if (!CreateTransaction(scriptPubKey, nPrice, wtx, key, nFeeRequired))
{ {
if (nPrice + nFeeRequired > GetBalance()) 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()));
@ -1799,7 +1871,7 @@ void CSendingDialog::OnReply2(CDataStream& vRecv)
return; return;
// Commit // Commit
if (!CommitTransactionSpent(wtx)) if (!CommitTransactionSpent(wtx, key))
{ {
Error("Error finalizing payment"); Error("Error finalizing payment");
return; return;
@ -2950,82 +3022,110 @@ void CEditReviewDialog::GetReview(CReview& review)
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
// //
// BitcoinTBIcon // CMyTaskBarIcon
// //
enum { enum
PU_RESTORE = 10001, {
PU_GENERATE, ID_TASKBAR_RESTORE = 10001,
PU_EXIT, ID_TASKBAR_GENERATE,
ID_TASKBAR_EXIT,
}; };
BEGIN_EVENT_TABLE(CBitcoinTBIcon, wxTaskBarIcon) BEGIN_EVENT_TABLE(CMyTaskBarIcon, wxTaskBarIcon)
EVT_TASKBAR_LEFT_DCLICK (CBitcoinTBIcon::OnLeftButtonDClick) EVT_TASKBAR_LEFT_DCLICK(CMyTaskBarIcon::OnLeftButtonDClick)
EVT_MENU(PU_RESTORE, CBitcoinTBIcon::OnMenuRestore) EVT_MENU(ID_TASKBAR_RESTORE, CMyTaskBarIcon::OnMenuRestore)
EVT_MENU(PU_GENERATE, CBitcoinTBIcon::OnMenuGenerate) EVT_MENU(ID_TASKBAR_GENERATE, CMyTaskBarIcon::OnMenuGenerate)
EVT_MENU(PU_EXIT, CBitcoinTBIcon::OnMenuExit) EVT_UPDATE_UI(ID_TASKBAR_GENERATE, CMyTaskBarIcon::OnUpdateUIGenerate)
EVT_MENU(ID_TASKBAR_EXIT, CMyTaskBarIcon::OnMenuExit)
END_EVENT_TABLE() END_EVENT_TABLE()
void CBitcoinTBIcon::Show() void CMyTaskBarIcon::Show(bool fShow)
{ {
string tooltip = "Bitcoin"; if (fShow)
tooltip += fGenerateBitcoins ? " - Generating" : ""; {
SetIcon(wxICON(bitcoin), tooltip); 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->Show();
pframeMain->Iconize(false); pframeMain->Iconize(false);
pframeMain->Raise(); pframeMain->Raise();
if (!alwaysShowTrayIcon)
Hide();
} }
void CBitcoinTBIcon::UpdateTooltip() { void CMyTaskBarIcon::OnMenuGenerate(wxCommandEvent& event)
if (IsIconInstalled())
Show();
}
wxMenu *CBitcoinTBIcon::CreatePopupMenu()
{ {
wxMenu *menu = new wxMenu; GenerateBitcoins(event.IsChecked());
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);
return menu;
} }
void CMyTaskBarIcon::OnUpdateUIGenerate(wxUpdateUIEvent& event)
{
event.Check(fGenerateBitcoins);
}
void CMyTaskBarIcon::OnMenuExit(wxCommandEvent& event)
{
pframeMain->Close(true);
}
void CMyTaskBarIcon::UpdateTooltip()
{
if (IsIconInstalled())
Show(true);
}
wxMenu* CMyTaskBarIcon::CreatePopupMenu()
{
wxMenu* pmenu = new wxMenu;
pmenu->Append(ID_TASKBAR_RESTORE, "&Open Bitcoin");
pmenu->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;
}
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
@ -3150,7 +3250,7 @@ bool CMyApp::OnInit2()
// Parameters // Parameters
// //
wxImage::AddHandler(new wxPNGHandler); wxImage::AddHandler(new wxPNGHandler);
map<string, string> mapArgs = ParseParameters(argc, argv); mapArgs = ParseParameters(argc, argv);
if (mapArgs.count("/datadir")) if (mapArgs.count("/datadir"))
strSetDataDir = mapArgs["/datadir"]; strSetDataDir = mapArgs["/datadir"];
@ -3179,6 +3279,7 @@ bool CMyApp::OnInit2()
// //
// Load data files // Load data files
// //
bool fFirstRun;
string strErrors; string strErrors;
int64 nStart, nEnd; int64 nStart, nEnd;
@ -3198,7 +3299,7 @@ bool CMyApp::OnInit2()
printf("Loading wallet...\n"); printf("Loading wallet...\n");
QueryPerformanceCounter((LARGE_INTEGER*)&nStart); QueryPerformanceCounter((LARGE_INTEGER*)&nStart);
if (!LoadWallet()) if (!LoadWallet(fFirstRun))
strErrors += "Error loading wallet.dat \n"; strErrors += "Error loading wallet.dat \n";
QueryPerformanceCounter((LARGE_INTEGER*)&nEnd); QueryPerformanceCounter((LARGE_INTEGER*)&nEnd);
printf(" wallet %20I64d\n", nEnd - nStart); printf(" wallet %20I64d\n", nEnd - nStart);
@ -3244,62 +3345,60 @@ bool CMyApp::OnInit2()
// //
// Create the main frame window // 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); OnExit();
pframeMain->Show(); return false;
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;
}
} }
taskBarIcon = new CBitcoinTBIcon(); if (!StartNode(strErrors))
ApplyUISettings(); wxMessageBox(strErrors, "Bitcoin");
if (mapArgs.count("/min") && minimizeToTray) {
pframeMain->Iconize(true); GenerateBitcoins(fGenerateBitcoins);
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;
} }
return true; return true;
@ -3320,14 +3419,14 @@ bool CMyApp::OnExceptionInMainLoop()
catch (std::exception& e) catch (std::exception& e)
{ {
PrintException(&e, "CMyApp::OnExceptionInMainLoop()"); 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); Sleep(1000);
throw; throw;
} }
catch (...) catch (...)
{ {
PrintException(NULL, "CMyApp::OnExceptionInMainLoop()"); PrintException(NULL, "CMyApp::OnExceptionInMainLoop()");
wxLogWarning(_T("Unknown exception")); wxLogWarning("Unknown exception");
Sleep(1000); Sleep(1000);
throw; throw;
} }
@ -3345,14 +3444,14 @@ void CMyApp::OnUnhandledException()
catch (std::exception& e) catch (std::exception& e)
{ {
PrintException(&e, "CMyApp::OnUnhandledException()"); 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); Sleep(1000);
throw; throw;
} }
catch (...) catch (...)
{ {
PrintException(NULL, "CMyApp::OnUnhandledException()"); PrintException(NULL, "CMyApp::OnUnhandledException()");
wxLogWarning(_T("Unknown exception")); wxLogWarning("Unknown exception");
Sleep(1000); Sleep(1000);
throw; throw;
} }
@ -3367,6 +3466,8 @@ void CMyApp::OnFatalException()
void MainFrameRepaint() 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) if (pframeMain)
{ {
printf("MainFrameRepaint()\n"); printf("MainFrameRepaint()\n");
@ -3374,69 +3475,85 @@ void MainFrameRepaint()
pframeMain->Refresh(); pframeMain->Refresh();
pframeMain->AddPendingEvent(event); pframeMain->AddPendingEvent(event);
} }
if (ptaskbaricon)
ptaskbaricon->UpdateTooltip();
} }
string StartupShortcutPath()
void ApplyUISettings() {
// Show the tray icon?
if (alwaysShowTrayIcon)
taskBarIcon->Show();
else
taskBarIcon->Hide();
// 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 ( 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");
}
}
RegCloseKey(hKey);
}
void GenerateBitcoins(bool flag)
{ {
fGenerateBitcoins = flag; // Get the startup folder shortcut path
nTransactionsUpdated++; char pszLinkPath[MAX_PATH+100];
CWalletDB().WriteSetting("fGenerateBitcoins", fGenerateBitcoins); pszLinkPath[0] = '\0';
if (fGenerateBitcoins) SHGetSpecialFolderPath(0, pszLinkPath, CSIDL_STARTUP, 0);
if (_beginthread(ThreadBitcoinMiner, 0, NULL) == -1) strcat(pszLinkPath, "\\Bitcoin.lnk");
printf("Error: _beginthread(ThreadBitcoinMiner) failed\n"); return pszLinkPath;
taskBarIcon->UpdateTooltip();
} }
bool GetStartOnSystemStartup()
{
return FileExists(StartupShortcutPath().c_str());
}
void SetStartOnSystemStartup(bool fAutoStart)
{
// If the shortcut exists already, remove it for updating
remove(StartupShortcutPath().c_str());
if (fAutoStart)
{
CoInitialize(NULL);
// Get a pointer to the IShellLink interface.
HRESULT hres = NULL;
IShellLink* psl = NULL;
hres = CoCreateInstance(CLSID_ShellLink, NULL,
CLSCTX_INPROC_SERVER, IID_IShellLink,
reinterpret_cast<void**>(&psl));
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<void**>(&ppf));
if (SUCCEEDED(hres))
{
WCHAR pwsz[MAX_PATH];
// Ensure that the string is ANSI.
MultiByteToWideChar(CP_ACP, 0, StartupShortcutPath().c_str(), -1, pwsz, MAX_PATH);
// Save the link by calling IPersistFile::Save.
hres = ppf->Save(pwsz, TRUE);
ppf->Release();
}
psl->Release();
}
CoUninitialize();
}
}
// randsendtest to bitcoin address // randsendtest to bitcoin address

108
ui.h
View file

@ -21,21 +21,25 @@ enum
extern map<string, string> mapArgs;
// Settings
extern int fShowGenerated;
extern int fMinimizeToTray;
extern int fMinimizeOnClose;
extern void HandleCtrlA(wxKeyEvent& event); extern void HandleCtrlA(wxKeyEvent& event);
extern string DateTimeStr(int64 nTime); extern string DateTimeStr(int64 nTime);
extern string FormatTxStatus(const CWalletTx& wtx); extern string FormatTxStatus(const CWalletTx& wtx);
extern void CrossThreadCall(int nID, void* pdata); extern void CrossThreadCall(int nID, void* pdata);
extern void MainFrameRepaint(); extern void MainFrameRepaint();
extern void Shutdown(void* parg); 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: protected:
// Event handlers // Event handlers
void OnClose(wxCloseEvent& event); void OnClose(wxCloseEvent& event);
void OnIconize( wxIconizeEvent& event ); void OnIconize(wxIconizeEvent& event);
void OnMouseEvents(wxMouseEvent& event); void OnMouseEvents(wxMouseEvent& event);
void OnKeyDown(wxKeyEvent& event) { HandleCtrlA(event); } void OnKeyDown(wxKeyEvent& event) { HandleCtrlA(event); }
void OnIdle(wxIdleEvent& event); void OnIdle(wxIdleEvent& event);
void OnPaint(wxPaintEvent& event); void OnPaint(wxPaintEvent& event);
void OnPaintListCtrl(wxPaintEvent& event); void OnPaintListCtrl(wxPaintEvent& event);
void OnMenuFileExit(wxCommandEvent& event); void OnMenuFileExit(wxCommandEvent& event);
void OnMenuViewShowGenerated(wxCommandEvent& event);
void OnUpdateUIViewShowGenerated(wxUpdateUIEvent& event);
void OnMenuOptionsGenerate(wxCommandEvent& event); void OnMenuOptionsGenerate(wxCommandEvent& event);
void OnUpdateUIOptionsGenerate(wxUpdateUIEvent& event);
void OnMenuOptionsChangeYourAddress(wxCommandEvent& event); void OnMenuOptionsChangeYourAddress(wxCommandEvent& event);
void OnMenuOptionsOptions(wxCommandEvent& event); void OnMenuOptionsOptions(wxCommandEvent& event);
void OnMenuHelpAbout(wxCommandEvent& event); void OnMenuHelpAbout(wxCommandEvent& event);
@ -66,7 +73,6 @@ protected:
void OnListItemActivatedProductsSent(wxListEvent& event); void OnListItemActivatedProductsSent(wxListEvent& event);
void OnListItemActivatedOrdersSent(wxListEvent& event); void OnListItemActivatedOrdersSent(wxListEvent& event);
void OnListItemActivatedOrdersReceived(wxListEvent& event); void OnListItemActivatedOrdersReceived(wxListEvent& event);
void OnUpdateMenuGenerate( wxUpdateUIEvent& event );
public: public:
/** Constructor */ /** Constructor */
@ -85,7 +91,6 @@ public:
void InsertTransaction(const CWalletTx& wtx, bool fNew, int nIndex=-1); void InsertTransaction(const CWalletTx& wtx, bool fNew, int nIndex=-1);
void RefreshListCtrl(); void RefreshListCtrl();
void RefreshStatus(); 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 class COptionsDialog : public COptionsDialogBase
{ {
protected: protected:
// Event handlers // 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 OnButtonOK(wxCommandEvent& event);
void OnButtonCancel(wxCommandEvent& event); void OnButtonCancel(wxCommandEvent& event);
void OnButtonApply(wxCommandEvent& event);
// Panels
COptionsPanelBitcoin* panelBitcoin;
COptionsPanelUI* panelUI;
wxPanel* currentPanel;
public: public:
/** Constructor */ /** Constructor */
COptionsDialog(wxWindow* parent); COptionsDialog(wxWindow* parent);
// Custom
bool fTmpStartOnSystemStartup;
bool fTmpMinimizeOnClose;
void SelectPage(int nPage);
}; };
@ -180,6 +164,11 @@ protected:
public: public:
/** Constructor */ /** Constructor */
CSendDialog(wxWindow* parent, const wxString& strAddress=""); 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: protected:
void Restore(); // Event handlers
void OnLeftButtonDClick(wxTaskBarIconEvent& event);
// Event handlers void OnMenuRestore(wxCommandEvent& event);
void OnLeftButtonDClick(wxTaskBarIconEvent&); void OnUpdateUIGenerate(wxUpdateUIEvent& event);
void OnMenuExit(wxCommandEvent&); void OnMenuGenerate(wxCommandEvent& event);
void OnMenuGenerate(wxCommandEvent&); void OnMenuExit(wxCommandEvent& event);
void OnMenuRestore(wxCommandEvent&);
public: public:
void Show(); CMyTaskBarIcon() : wxTaskBarIcon()
void Hide(); {
void UpdateTooltip(); Show(true);
virtual wxMenu *CreatePopupMenu(); }
void Show(bool fShow=true);
void Hide();
void Restore();
void UpdateTooltip();
virtual wxMenu* CreatePopupMenu();
DECLARE_EVENT_TABLE() DECLARE_EVENT_TABLE()
}; };

View file

@ -24,14 +24,21 @@ CMainFrameBase::CMainFrameBase( wxWindow* parent, wxWindowID id, const wxString&
m_menubar->Append( m_menuFile, wxT("&File") ); 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(); m_menuOptions = new wxMenu();
wxMenuItem* m_menuOptionsGenerateBitcoins; 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( wxT("&Generate Coins") ) , wxEmptyString, wxITEM_CHECK );
m_menuOptions->Append( m_menuOptionsGenerateBitcoins ); m_menuOptions->Append( m_menuOptionsGenerateBitcoins );
wxMenuItem* m_menuChangeYourAddress; wxMenuItem* m_menuOptionsChangeYourAddress;
m_menuChangeYourAddress = new wxMenuItem( m_menuOptions, wxID_ANY, wxString( wxT("&Change Your Address...") ) , wxEmptyString, wxITEM_NORMAL ); m_menuOptionsChangeYourAddress = new wxMenuItem( m_menuOptions, wxID_ANY, wxString( wxT("&Change Your Address...") ) , wxEmptyString, wxITEM_NORMAL );
m_menuOptions->Append( m_menuChangeYourAddress ); m_menuOptions->Append( m_menuOptionsChangeYourAddress );
wxMenuItem* m_menuOptionsOptions; wxMenuItem* m_menuOptionsOptions;
m_menuOptionsOptions = new wxMenuItem( m_menuOptions, wxID_ANY, wxString( wxT("&Options...") ) , wxEmptyString, wxITEM_NORMAL ); 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_MOUSEWHEEL, wxMouseEventHandler( CMainFrameBase::OnMouseEvents ) );
this->Connect( wxEVT_PAINT, wxPaintEventHandler( CMainFrameBase::OnPaint ) ); this->Connect( wxEVT_PAINT, wxPaintEventHandler( CMainFrameBase::OnPaint ) );
this->Connect( m_menuFileExit->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( CMainFrameBase::OnMenuFileExit ) ); 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_COMMAND_MENU_SELECTED, wxCommandEventHandler( CMainFrameBase::OnMenuOptionsGenerate ) );
this->Connect( m_menuOptionsGenerateBitcoins->GetId(), wxEVT_UPDATE_UI, wxUpdateUIEventHandler( CMainFrameBase::OnUpdateMenuGenerate ) ); this->Connect( m_menuOptionsGenerateBitcoins->GetId(), wxEVT_UPDATE_UI, wxUpdateUIEventHandler( CMainFrameBase::OnUpdateUIOptionsGenerate ) );
this->Connect( m_menuChangeYourAddress->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( CMainFrameBase::OnMenuOptionsChangeYourAddress ) ); 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_menuOptionsOptions->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( CMainFrameBase::OnMenuOptionsOptions ) );
this->Connect( m_menuHelpAbout->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( CMainFrameBase::OnMenuHelpAbout ) ); 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_BUTTONSEND, wxEVT_COMMAND_TOOL_CLICKED, wxCommandEventHandler( CMainFrameBase::OnButtonSend ) );
@ -278,8 +287,10 @@ CMainFrameBase::~CMainFrameBase()
this->Disconnect( wxEVT_MOUSEWHEEL, wxMouseEventHandler( CMainFrameBase::OnMouseEvents ) ); this->Disconnect( wxEVT_MOUSEWHEEL, wxMouseEventHandler( CMainFrameBase::OnMouseEvents ) );
this->Disconnect( wxEVT_PAINT, wxPaintEventHandler( CMainFrameBase::OnPaint ) ); 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::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_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::OnMenuOptionsChangeYourAddress ) );
this->Disconnect( wxID_ANY, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( CMainFrameBase::OnMenuOptionsOptions ) ); 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_ANY, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( CMainFrameBase::OnMenuHelpAbout ) );
@ -353,15 +364,121 @@ COptionsDialogBase::COptionsDialogBase( wxWindow* parent, wxWindowID id, const w
wxBoxSizer* bSizer55; wxBoxSizer* bSizer55;
bSizer55 = new wxBoxSizer( wxVERTICAL ); bSizer55 = new wxBoxSizer( wxVERTICAL );
panelSizer = new wxBoxSizer( wxHORIZONTAL ); wxBoxSizer* bSizer66;
bSizer66 = new wxBoxSizer( wxHORIZONTAL );
m_treeCtrl = new wxTreeCtrl( this, wxID_ANY, wxDefaultPosition, wxSize( 100,-1 ), wxTR_HAS_BUTTONS|wxTR_HIDE_ROOT|wxTR_LINES_AT_ROOT ); m_listBox = new wxListBox( this, wxID_ANY, wxDefaultPosition, wxSize( 110,-1 ), 0, NULL, wxLB_NEEDED_SB|wxLB_SINGLE );
panelSizer->Add( m_treeCtrl, 0, wxALL|wxEXPAND, 5 ); bSizer66->Add( m_listBox, 0, wxEXPAND|wxRIGHT, 5 );
bSizer55->Add( panelSizer, 1, wxEXPAND, 5 ); m_scrolledWindow = new wxScrolledWindow( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 );
m_scrolledWindow->SetScrollRate( 5, 5 );
wxBoxSizer* bSizer63;
bSizer63 = new wxBoxSizer( wxVERTICAL );
m_staticline1 = new wxStaticLine( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL ); m_panelMain = new wxPanel( m_scrolledWindow, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
bSizer55->Add( m_staticline1, 0, wxEXPAND | wxALL, 5 ); 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_staticText69 = new wxStaticText( m_panelTest2, wxID_ANY, wxT("MyLabel"), 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->Wrap( -1 );
bSizer64->Add( m_staticText70, 0, 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; wxBoxSizer* bSizer58;
bSizer58 = new wxBoxSizer( wxHORIZONTAL ); bSizer58 = new wxBoxSizer( wxHORIZONTAL );
@ -374,9 +491,8 @@ COptionsDialogBase::COptionsDialogBase( wxWindow* parent, wxWindowID id, const w
bSizer58->Add( m_buttonCancel, 0, wxALL, 5 ); bSizer58->Add( m_buttonCancel, 0, wxALL, 5 );
m_buttonApply = new wxButton( this, wxID_ANY, wxT("Apply"), wxDefaultPosition, wxDefaultSize, 0 ); m_buttonApply = new wxButton( this, wxID_APPLY, wxT("&Apply"), wxDefaultPosition, wxSize( -1,-1 ), 0 );
m_buttonApply->Enable( false ); m_buttonApply->SetMinSize( wxSize( 85,25 ) );
m_buttonApply->Hide();
bSizer58->Add( m_buttonApply, 0, wxALL, 5 ); bSizer58->Add( m_buttonApply, 0, wxALL, 5 );
@ -386,17 +502,25 @@ COptionsDialogBase::COptionsDialogBase( wxWindow* parent, wxWindowID id, const w
this->Layout(); this->Layout();
// Connect Events // 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_buttonOK->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( COptionsDialogBase::OnButtonOK ), NULL, this );
m_buttonCancel->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( COptionsDialogBase::OnButtonCancel ), 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() COptionsDialogBase::~COptionsDialogBase()
{ {
// Disconnect Events // 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_buttonOK->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( COptionsDialogBase::OnButtonOK ), NULL, this );
m_buttonCancel->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( COptionsDialogBase::OnButtonCancel ), 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 ) 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_buttonOK->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CGetTextFromUserDialogBase::OnButtonOK ), NULL, this );
m_buttonCancel->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CGetTextFromUserDialogBase::OnButtonCancel ), 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()
{
}

193
uibase.h
View file

@ -30,69 +30,70 @@
#include <wx/frame.h> #include <wx/frame.h>
#include <wx/html/htmlwin.h> #include <wx/html/htmlwin.h>
#include <wx/dialog.h> #include <wx/dialog.h>
#include <wx/treectrl.h> #include <wx/listbox.h>
#include <wx/statline.h> #include <wx/checkbox.h>
#include <wx/spinctrl.h>
#include <wx/scrolwin.h>
#include <wx/statbmp.h> #include <wx/statbmp.h>
#include <wx/combobox.h> #include <wx/combobox.h>
#include <wx/scrolwin.h>
#include <wx/richtext/richtextctrl.h> #include <wx/richtext/richtextctrl.h>
#include <wx/checkbox.h> #include <wx/treectrl.h>
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
#define wxID_MAINFRAME 1000 #define wxID_MAINFRAME 1000
#define wxID_OPTIONSGENERATEBITCOINS 1001 #define wxID_VIEWSHOWGENERATED 1001
#define wxID_BUTTONSEND 1002 #define wxID_OPTIONSGENERATEBITCOINS 1002
#define wxID_BUTTONRECEIVE 1003 #define wxID_BUTTONSEND 1003
#define wxID_TEXTCTRLADDRESS 1004 #define wxID_BUTTONRECEIVE 1004
#define wxID_BUTTONCOPY 1005 #define wxID_TEXTCTRLADDRESS 1005
#define wxID_BUTTONCHANGE 1006 #define wxID_BUTTONCOPY 1006
#define wxID_TEXTCTRLPAYTO 1007 #define wxID_BUTTONCHANGE 1007
#define wxID_BUTTONPASTE 1008 #define wxID_TRANSACTIONFEE 1008
#define wxID_BUTTONADDRESSBOOK 1009 #define wxID_TEXTCTRLPAYTO 1009
#define wxID_TEXTCTRLAMOUNT 1010 #define wxID_BUTTONPASTE 1010
#define wxID_CHOICETRANSFERTYPE 1011 #define wxID_BUTTONADDRESSBOOK 1011
#define wxID_LISTCTRL 1012 #define wxID_TEXTCTRLAMOUNT 1012
#define wxID_BUTTONRENAME 1013 #define wxID_CHOICETRANSFERTYPE 1013
#define wxID_BUTTONNEW 1014 #define wxID_LISTCTRL 1014
#define wxID_BUTTONEDIT 1015 #define wxID_BUTTONRENAME 1015
#define wxID_BUTTONDELETE 1016 #define wxID_BUTTONNEW 1016
#define wxID_DEL0 1017 #define wxID_BUTTONEDIT 1017
#define wxID_DEL1 1018 #define wxID_BUTTONDELETE 1018
#define wxID_DEL2 1019 #define wxID_DEL0 1019
#define wxID_DEL3 1020 #define wxID_DEL1 1020
#define wxID_DEL4 1021 #define wxID_DEL2 1021
#define wxID_DEL5 1022 #define wxID_DEL3 1022
#define wxID_DEL6 1023 #define wxID_DEL4 1023
#define wxID_DEL7 1024 #define wxID_DEL5 1024
#define wxID_DEL8 1025 #define wxID_DEL6 1025
#define wxID_DEL9 1026 #define wxID_DEL7 1026
#define wxID_DEL10 1027 #define wxID_DEL8 1027
#define wxID_DEL11 1028 #define wxID_DEL9 1028
#define wxID_DEL12 1029 #define wxID_DEL10 1029
#define wxID_DEL13 1030 #define wxID_DEL11 1030
#define wxID_DEL14 1031 #define wxID_DEL12 1031
#define wxID_DEL15 1032 #define wxID_DEL13 1032
#define wxID_DEL16 1033 #define wxID_DEL14 1033
#define wxID_DEL17 1034 #define wxID_DEL15 1034
#define wxID_DEL18 1035 #define wxID_DEL16 1035
#define wxID_DEL19 1036 #define wxID_DEL17 1036
#define wxID_BUTTONPREVIEW 1037 #define wxID_DEL18 1037
#define wxID_BUTTONSAMPLE 1038 #define wxID_DEL19 1038
#define wxID_CANCEL2 1039 #define wxID_BUTTONPREVIEW 1039
#define wxID_BUTTONBACK 1040 #define wxID_BUTTONSAMPLE 1040
#define wxID_BUTTONNEXT 1041 #define wxID_CANCEL2 1041
#define wxID_SUBMIT 1042 #define wxID_BUTTONBACK 1042
#define wxID_OPENNEWTABLE 1043 #define wxID_BUTTONNEXT 1043
#define wxID_DEALHAND 1044 #define wxID_SUBMIT 1044
#define wxID_FOLD 1045 #define wxID_OPENNEWTABLE 1045
#define wxID_CALL 1046 #define wxID_DEALHAND 1046
#define wxID_RAISE 1047 #define wxID_FOLD 1047
#define wxID_LEAVETABLE 1048 #define wxID_CALL 1048
#define wxID_DITCHPLAYER 1049 #define wxID_RAISE 1049
#define wxID_TEXTCTRL 1050 #define wxID_LEAVETABLE 1050
#define wxID_TRANSACTIONFEE 1051 #define wxID_DITCHPLAYER 1051
#define wxID_MINTOTRAY 1052 #define wxID_TEXTCTRL 1052
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
/// Class CMainFrameBase /// Class CMainFrameBase
@ -104,6 +105,7 @@ class CMainFrameBase : public wxFrame
protected: protected:
wxMenuBar* m_menubar; wxMenuBar* m_menubar;
wxMenu* m_menuFile; wxMenu* m_menuFile;
wxMenu* m_menuView;
wxMenu* m_menuHelp; wxMenu* m_menuHelp;
wxToolBar* m_toolBar; wxToolBar* m_toolBar;
wxStatusBar* m_statusBar; wxStatusBar* m_statusBar;
@ -132,8 +134,10 @@ class CMainFrameBase : public wxFrame
virtual void OnMouseEvents( wxMouseEvent& event ){ event.Skip(); } virtual void OnMouseEvents( wxMouseEvent& event ){ event.Skip(); }
virtual void OnPaint( wxPaintEvent& event ){ event.Skip(); } virtual void OnPaint( wxPaintEvent& event ){ event.Skip(); }
virtual void OnMenuFileExit( wxCommandEvent& 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 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 OnMenuOptionsChangeYourAddress( wxCommandEvent& event ){ event.Skip(); }
virtual void OnMenuOptionsOptions( wxCommandEvent& event ){ event.Skip(); } virtual void OnMenuOptionsOptions( wxCommandEvent& event ){ event.Skip(); }
virtual void OnMenuHelpAbout( wxCommandEvent& event ){ event.Skip(); } virtual void OnMenuHelpAbout( wxCommandEvent& event ){ event.Skip(); }
@ -193,21 +197,42 @@ class COptionsDialogBase : public wxDialog
private: private:
protected: protected:
wxBoxSizer* panelSizer; wxListBox* m_listBox;
wxTreeCtrl* m_treeCtrl; wxScrolledWindow* m_scrolledWindow;
wxStaticLine* m_staticline1; 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_buttonOK;
wxButton* m_buttonCancel; wxButton* m_buttonCancel;
wxButton* m_buttonApply; wxButton* m_buttonApply;
// Virtual event handlers, overide them in your derived class // 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 OnButtonOK( wxCommandEvent& event ){ event.Skip(); }
virtual void OnButtonCancel( wxCommandEvent& event ){ event.Skip(); } virtual void OnButtonCancel( wxCommandEvent& event ){ event.Skip(); }
virtual void OnButtonApply( wxCommandEvent& event ){ event.Skip(); }
public: 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(); ~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__ #endif //__uibase__

File diff suppressed because it is too large Load diff

View file

@ -86,7 +86,7 @@ void RandAddSeed(bool fPerfmon)
struct tm* ptmTime = gmtime(&nTime); struct tm* ptmTime = gmtime(&nTime);
char pszTime[200]; char pszTime[200];
strftime(pszTime, sizeof(pszTime), "%x %H:%M:%S", ptmTime); 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) void PrintException(std::exception* pex, const char* pszThread)
{ {
char pszModule[260]; char pszModule[MAX_PATH];
pszModule[0] = '\0'; pszModule[0] = '\0';
GetModuleFileName(NULL, pszModule, sizeof(pszModule)); GetModuleFileName(NULL, pszModule, sizeof(pszModule));
_strlwr(pszModule); _strlwr(pszModule);