Browse Source

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

pull/145/head
s_nakamoto 15 years ago
parent
commit
5210998688
  1. 23
      build.txt
  2. 57
      db.cpp
  3. 3
      db.h
  4. 6
      headers.h
  5. 14
      irc.cpp
  6. 12
      key.h
  7. 152
      main.cpp
  8. 14
      main.h
  9. 4
      makefile
  10. 4
      makefile.vc
  11. 111
      net.cpp
  12. 17
      net.h
  13. 2
      serialize.h
  14. 663
      ui.cpp
  15. 108
      ui.h
  16. 233
      uibase.cpp
  17. 193
      uibase.h
  18. 1581
      uiproject.fbp
  19. 4
      util.cpp

23
readme.txt → build.txt

@ -1,4 +1,4 @@
BitCoin v0.1.5 ALPHA
BitCoin v0.1.6 ALPHA
Copyright (c) 2009 Satoshi Nakamoto
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
-------------------
MinGW GCC (v3.4.5)
MinGW GCC (currently v3.4.5)
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
Notes
-----
The UI layout is edited with wxFormBuilder. Open the project file
uiproject.fbp. It generates uibase.cpp and uibase.h, which define base
classes that do the rote work of constructing all the UI elements.
The release is built with GCC and then "strip bitcoin.exe" to strip the debug
symbols, which reduces the executable size by about 90%.
OpenSSL
-------
Bitcoin does not use any encryption. If you want to do a no-everything
@ -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
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
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
-----------
MinGW with MSYS:
Using MinGW and MSYS:
cd \DB\build_unix
sh ../dist/configure --enable-mingw --enable-cxx
make
@ -72,5 +82,6 @@ make
Boost
-----
You may need Boost version 1.35 to build with MSVC 6.0. I couldn't get
version 1.37 to compile with MSVC 6.0.
If you have trouble compiling Boost with Microsoft Visual C++ 6.0, try going
back to Boost version 1.35. It looks like they may be starting to reduce
support for MSVC 6.0.

57
db.cpp

@ -453,11 +453,7 @@ bool CAddrDB::LoadAddresses()
}
}
//// debug print
printf("mapAddresses:\n");
foreach(const PAIRTYPE(vector<unsigned char>, CAddress)& item, mapAddresses)
item.second.print();
printf("-----\n");
printf("Loaded %d addresses\n", mapAddresses.size());
// Fix for possible bug that manifests in mapAddresses.count in irc.cpp,
// just need to call count here and it doesn't happen there. The bug was the
@ -501,6 +497,26 @@ bool CReviewDB::WriteReviews(uint256 hash, const vector<CReview>& vReviews)
// 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)
{
vchDefaultKeyRet.clear();
@ -568,34 +584,51 @@ bool CWalletDB::LoadWallet(vector<unsigned char>& vchDefaultKeyRet)
{
ssValue >> vchDefaultKeyRet;
}
else if (strType == "setting") /// or settings or option or options or config?
else if (strType == "setting")
{
string strKey;
ssKey >> strKey;
// Menu state
if (strKey == "fShowGenerated") ssValue >> fShowGenerated;
if (strKey == "fGenerateBitcoins") ssValue >> fGenerateBitcoins;
// Options
if (strKey == "nTransactionFee") ssValue >> nTransactionFee;
if (strKey == "addrIncoming") ssValue >> addrIncoming;
if (strKey == "minimizeToTray") ssValue >> minimizeToTray;
if (strKey == "closeToTray") ssValue >> closeToTray;
if (strKey == "startOnSysBoot") ssValue >> startOnSysBoot;
if (strKey == "askBeforeClosing") ssValue >> askBeforeClosing;
if (strKey == "alwaysShowTrayIcon") ssValue >> alwaysShowTrayIcon;
if (strKey == "fLimitProcessors") ssValue >> fLimitProcessors;
if (strKey == "nLimitProcessors") ssValue >> nLimitProcessors;
if (strKey == "fMinimizeToTray") ssValue >> fMinimizeToTray;
if (strKey == "fMinimizeOnClose") ssValue >> fMinimizeOnClose;
}
}
}
printf("fShowGenerated = %d\n", fShowGenerated);
printf("fGenerateBitcoins = %d\n", fGenerateBitcoins);
printf("nTransactionFee = %I64d\n", nTransactionFee);
printf("addrIncoming = %s\n", addrIncoming.ToString().c_str());
printf("fMinimizeToTray = %d\n", fMinimizeToTray);
printf("fMinimizeOnClose = %d\n", fMinimizeOnClose);
// The transaction fee setting won't be needed for many years to come.
// Setting it to zero here in case they set it to something in an earlier version.
if (nTransactionFee != 0)
{
nTransactionFee = 0;
WriteSetting("nTransactionFee", nTransactionFee);
}
return true;
}
bool LoadWallet()
bool LoadWallet(bool& fFirstRunRet)
{
fFirstRunRet = false;
vector<unsigned char> vchDefaultKey;
if (!CWalletDB("cr").LoadWallet(vchDefaultKey))
return false;
fFirstRunRet = vchDefaultKey.empty();
if (mapKeys.count(vchDefaultKey))
{

3
db.h

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

6
headers.h

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

14
irc.cpp

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

12
key.h

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

152
main.cpp

@ -34,7 +34,7 @@ map<uint256, CDataStream*> mapOrphanTransactions;
multimap<uint256, CDataStream*> mapOrphanTransactionsByPrev;
map<uint256, CWalletTx> mapWallet;
vector<pair<uint256, bool> > vWalletUpdated;
vector<uint256> vWalletUpdated;
CCriticalSection cs_mapWallet;
map<vector<unsigned char>, CPrivKey> mapKeys;
@ -46,9 +46,12 @@ string strSetDataDir;
int nDropMessagesTest = 0;
// Settings
int fGenerateBitcoins;
int fGenerateBitcoins = false;
int64 nTransactionFee = 0;
CAddress addrIncoming;
int fLimitProcessors = false;
int nLimitProcessors = 1;
@ -135,7 +138,7 @@ bool AddToWallet(const CWalletTx& wtxIn)
return false;
// Notify UI
vWalletUpdated.push_back(make_pair(hash, fInsertedNew));
vWalletUpdated.push_back(hash);
}
// Refresh UI
@ -1126,6 +1129,9 @@ bool CBlock::AddToBlockIndex(unsigned int nFile, unsigned int nBlockPos)
}
}
// Notify UI to update prev block coinbase if it was ours
vWalletUpdated.push_back(hashBestChain);
// New best link
hashBestChain = hash;
pindexBest = pindexNew;
@ -1702,7 +1708,7 @@ bool ProcessMessages(CNode* pfrom)
}
CATCH_PRINT_EXCEPTION("ProcessMessage()")
if (!fRet)
printf("ProcessMessage(%s, %d bytes) from %s to %s FAILED\n", strCommand.c_str(), nMessageSize, pfrom->addr.ToString().c_str(), addrLocalHost.ToString().c_str());
printf("ProcessMessage(%s, %d bytes) FAILED\n", strCommand.c_str(), nMessageSize);
}
vRecv.Compact();
@ -1715,10 +1721,7 @@ bool ProcessMessages(CNode* pfrom)
bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
{
static map<unsigned int, vector<unsigned char> > mapReuseKey;
printf("received: %-12s (%d bytes) ", strCommand.c_str(), vRecv.size());
for (int i = 0; i < min(vRecv.size(), (unsigned int)20); i++)
printf("%02x ", vRecv[i] & 0xff);
printf("\n");
printf("received: %-12s (%d bytes)\n", strCommand.c_str(), vRecv.size());
if (nDropMessagesTest > 0 && GetRand(nDropMessagesTest) == 0)
{
printf("dropmessages DROPPING RECV MESSAGE\n");
@ -1759,7 +1762,7 @@ bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
pfrom->PushMessage("getblocks", CBlockLocator(pindexBest), uint256(0));
}
printf("version message: %s has version %d, addrMe=%s\n", pfrom->addr.ToString().c_str(), pfrom->nVersion, addrMe.ToString().c_str());
printf("version message: version %d\n", pfrom->nVersion);
}
@ -1775,13 +1778,24 @@ bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
vector<CAddress> vAddr;
vRecv >> vAddr;
// Clear addrknown lists periodically to allow refresh broadcasts
static int64 nLastClearedAddrKnown;
if (nLastClearedAddrKnown < GetAdjustedTime() - 24 * 60 * 60)
{
nLastClearedAddrKnown = GetAdjustedTime();
CRITICAL_BLOCK(cs_vNodes)
foreach(CNode* pnode, vNodes)
pnode->setAddrKnown.clear();
}
// Store the new addresses
CAddrDB addrdb;
foreach(const CAddress& addr, vAddr)
{
if (fShutdown)
return true;
if (AddAddress(addrdb, addr))
AddAddress(addrdb, addr);
if (addr.IsRoutable() && addr.ip != addrLocalHost.ip)
{
// Put on lists to send to other nodes
pfrom->setAddrKnown.insert(addr);
@ -1989,8 +2003,6 @@ bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
if (fShutdown)
return true;
const CAddress& addr = item.second;
//// will need this if we lose IRC
//if (addr.nTime > nSince || (rand() % nSize) < 500)
if (addr.nTime > nSince)
pfrom->vAddrToSend.push_back(addr);
}
@ -2132,9 +2144,11 @@ bool SendMessages(CNode* pto)
while (!pto->mapAskFor.empty() && (*pto->mapAskFor.begin()).first <= nNow)
{
const CInv& inv = (*pto->mapAskFor.begin()).second;
printf("sending getdata: %s\n", inv.ToString().c_str());
if (!AlreadyHave(txdb, inv))
{
printf("sending getdata: %s\n", inv.ToString().c_str());
vAskFor.push_back(inv);
}
pto->mapAskFor.erase(pto->mapAskFor.begin());
}
if (!vAskFor.empty())
@ -2162,6 +2176,49 @@ bool SendMessages(CNode* pto)
// BitcoinMiner
//
void GenerateBitcoins(bool fGenerate)
{
if (fGenerateBitcoins != fGenerate)
{
fGenerateBitcoins = fGenerate;
CWalletDB().WriteSetting("fGenerateBitcoins", fGenerateBitcoins);
MainFrameRepaint();
}
if (fGenerateBitcoins)
{
int nProcessors = atoi(getenv("NUMBER_OF_PROCESSORS"));
printf("%d processors\n", nProcessors);
if (nProcessors < 1)
nProcessors = 1;
if (fLimitProcessors && nProcessors > nLimitProcessors)
nProcessors = nLimitProcessors;
int nAddThreads = nProcessors - vnThreadsRunning[3];
printf("starting %d bitcoinminer threads\n", nAddThreads);
for (int i = 0; i < nAddThreads; i++)
if (_beginthread(ThreadBitcoinMiner, 0, NULL) == -1)
printf("Error: _beginthread(ThreadBitcoinMiner) failed\n");
}
}
void ThreadBitcoinMiner(void* parg)
{
vnThreadsRunning[3]++;
CheckForShutdown(3);
try
{
bool fRet = BitcoinMiner();
printf("BitcoinMiner returned %s\n\n\n", fRet ? "true" : "false");
vnThreadsRunning[3]--;
}
catch (std::exception& e) {
vnThreadsRunning[3]--;
PrintException(&e, "ThreadBitcoinMiner()");
} catch (...) {
vnThreadsRunning[3]--;
PrintException(NULL, "ThreadBitcoinMiner()");
}
}
int FormatHashBlocks(void* pbuffer, unsigned int len)
{
unsigned char* pdata = (unsigned char*)pbuffer;
@ -2210,13 +2267,13 @@ void BlockSHA256(const void* pin, unsigned int nBlocks, void* pout)
bool BitcoinMiner()
{
printf("BitcoinMiner started\n");
SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_LOWEST);
CKey key;
key.MakeNewKey();
CBigNum bnExtraNonce = 0;
while (fGenerateBitcoins)
{
SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_LOWEST);
Sleep(50);
CheckForShutdown(3);
while (vNodes.empty())
@ -2338,7 +2395,6 @@ bool BitcoinMiner()
BlockSHA256(&tmp.block, nBlocks0, &tmp.hash1);
BlockSHA256(&tmp.hash1, nBlocks1, &hash);
if (hash <= hashTarget)
{
pblock->nNonce = tmp.block.nNonce;
@ -2352,6 +2408,12 @@ bool BitcoinMiner()
SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_NORMAL);
CRITICAL_BLOCK(cs_main)
{
if (pindexPrev != pindexBest)
{
SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_LOWEST);
break;
}
// Save key
if (!AddKey(key))
return false;
@ -2368,7 +2430,7 @@ bool BitcoinMiner()
}
// Update nTime every few seconds
if ((++tmp.block.nNonce & 0x3ffff) == 0)
if ((++tmp.block.nNonce & 0xffff) == 0)
{
CheckForShutdown(3);
if (tmp.block.nNonce == 0)
@ -2379,6 +2441,8 @@ bool BitcoinMiner()
break;
if (!fGenerateBitcoins)
break;
if (fLimitProcessors && vnThreadsRunning[3] > nLimitProcessors)
return true;
tmp.block.nTime = pblock->nTime = max(pindexPrev->GetMedianTimePast()+1, GetAdjustedTime());
}
}
@ -2538,7 +2602,7 @@ bool SelectCoins(int64 nTargetValue, set<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;
CRITICAL_BLOCK(cs_main)
@ -2565,30 +2629,28 @@ bool CreateTransaction(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew, in
foreach(CWalletTx* pcoin, setCoins)
nValueIn += pcoin->GetCredit();
// Fill vout[0] to the payee
wtxNew.vout.push_back(CTxOut(nValueOut, scriptPubKey));
// Fill a vout to the payee
bool fChangeFirst = GetRand(2);
if (!fChangeFirst)
wtxNew.vout.push_back(CTxOut(nValueOut, scriptPubKey));
// Fill vout[1] back to self with any change
// Fill a vout back to self with any change
if (nValueIn > nValue)
{
/// todo: for privacy, should randomize the order of outputs,
// would also have to use a new key for the change.
// Use the same key as one of the coins
vector<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;
// New private key
if (keyRet.IsNull())
keyRet.MakeNewKey();
// Fill vout[1] to ourself
// Fill a vout to ourself
CScript scriptPubKey;
scriptPubKey << vchPubKey << OP_CHECKSIG;
scriptPubKey << keyRet.GetPubKey() << OP_CHECKSIG;
wtxNew.vout.push_back(CTxOut(nValueIn - nValue, scriptPubKey));
}
// Fill a vout to the payee
if (fChangeFirst)
wtxNew.vout.push_back(CTxOut(nValueOut, scriptPubKey));
// Fill vin
foreach(CWalletTx* pcoin, setCoins)
for (int nOut = 0; nOut < pcoin->vout.size(); nOut++)
@ -2621,13 +2683,24 @@ bool CreateTransaction(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew, in
}
// Call after CreateTransaction unless you want to abort
bool CommitTransactionSpent(const CWalletTx& wtxNew)
bool CommitTransactionSpent(const CWalletTx& wtxNew, const CKey& key)
{
CRITICAL_BLOCK(cs_main)
CRITICAL_BLOCK(cs_mapWallet)
{
//// todo: make this transactional, never want to add a transaction
//// without marking spent transactions
//// todo: eventually should make this transactional, never want to add a
//// transaction without marking spent transactions, although the risk of
//// interruption during this step is remote.
// This is only to keep the database open to defeat the auto-flush for the
// duration of this scope. This is the only place where this optimization
// maybe makes sense; please don't do it anywhere else. Keeping databases
// open longer than necessary can create deadlocks.
CWalletDB walletdb("r");
// Add the change's private key to wallet
if (!key.IsNull() && !AddKey(key))
throw runtime_error("CommitTransactionSpent() : AddKey failed\n");
// Add tx to wallet, because if it has change it's also ours,
// otherwise just for transaction history.
@ -2641,7 +2714,7 @@ bool CommitTransactionSpent(const CWalletTx& wtxNew)
{
pcoin->fSpent = true;
pcoin->WriteToDisk();
vWalletUpdated.push_back(make_pair(pcoin->GetHash(), false));
vWalletUpdated.push_back(pcoin->GetHash());
}
}
MainFrameRepaint();
@ -2655,8 +2728,9 @@ bool SendMoney(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew)
{
CRITICAL_BLOCK(cs_main)
{
CKey key;
int64 nFeeRequired;
if (!CreateTransaction(scriptPubKey, nValue, wtxNew, nFeeRequired))
if (!CreateTransaction(scriptPubKey, nValue, wtxNew, key, nFeeRequired))
{
string strError;
if (nValue + nFeeRequired > GetBalance())
@ -2666,7 +2740,7 @@ bool SendMoney(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew)
wxMessageBox(strError, "Sending...");
return error("SendMoney() : %s\n", strError.c_str());
}
if (!CommitTransactionSpent(wtxNew))
if (!CommitTransactionSpent(wtxNew, key))
{
wxMessageBox("Error finalizing transaction ", "Sending...");
return error("SendMoney() : Error finalizing transaction");

14
main.h

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

4
makefile

@ -12,7 +12,7 @@ ifeq "$(BUILD)" "debug"
D=d
# note: gcc 3.x profile doesn't work
#DEBUGFLAGS=-O0 -g -pg -D__WXDEBUG__
DEBUGFLAGS=-g -D__WXDEBUG__ -Wall -Wextra
DEBUGFLAGS=-g -D__WXDEBUG__
endif
@ -23,7 +23,7 @@ LIBS= \
-l db_cxx \
-l eay32 \
-l wxmsw28$(D)_richtext -l wxmsw28$(D)_html -l wxmsw28$(D)_core -l wxmsw28$(D)_adv -l wxbase28$(D) -l wxtiff$(D) -l wxjpeg$(D) -l wxpng$(D) -l wxzlib$(D) -l wxregex$(D) -l wxexpat$(D) \
-l kernel32 -l user32 -l gdi32 -l comdlg32 -l winspool -l winmm -l shell32 -l comctl32 -l ole32 -l oleaut32 -l uuid -l rpcrt4 -l advapi32 -l ws2_32
-l kernel32 -l user32 -l gdi32 -l comdlg32 -l winspool -l winmm -l shell32 -l comctl32 -l ole32 -l oleaut32 -l uuid -l rpcrt4 -l advapi32 -l ws2_32 -l shlwapi
WXDEFS=-DWIN32 -D__WXMSW__ -D_WINDOWS -DNOPCH
CFLAGS=-mthreads -O0 -w -Wno-invalid-offsetof -Wformat $(DEBUGFLAGS) $(WXDEFS) $(INCLUDEPATHS)
HEADERS=headers.h util.h main.h serialize.h uint256.h key.h bignum.h script.h db.h base58.h

4
makefile.vc

@ -18,8 +18,8 @@ LIBPATHS=/LIBPATH:"/DB/build_windows/$(BUILD)" /LIBPATH:"/OpenSSL/out" /LIBPATH:
LIBS= \
libdb47s$(D).lib \
libeay32.lib \
wxmsw28$(D)_richtext.lib wxmsw28$(D)_html.lib wxmsw28$(D)_core.lib wxbase28$(D).lib wxtiff$(D).lib wxjpeg$(D).lib wxpng$(D).lib wxzlib$(D).lib wxregex$(D).lib wxexpat$(D).lib \
kernel32.lib user32.lib gdi32.lib comdlg32.lib winspool.lib winmm.lib shell32.lib comctl32.lib ole32.lib oleaut32.lib uuid.lib rpcrt4.lib advapi32.lib ws2_32.lib
wxmsw28$(D)_richtext.lib wxmsw28$(D)_html.lib wxmsw28$(D)_core.lib wxmsw28$(D)_adv.lib wxbase28$(D).lib wxtiff$(D).lib wxjpeg$(D).lib wxpng$(D).lib wxzlib$(D).lib wxregex$(D).lib wxexpat$(D).lib \
kernel32.lib user32.lib gdi32.lib comdlg32.lib winspool.lib winmm.lib shell32.lib comctl32.lib ole32.lib oleaut32.lib uuid.lib rpcrt4.lib advapi32.lib ws2_32.lib shlwapi.lib
WXDEFS=/DWIN32 /D__WXMSW__ /D_WINDOWS /DNOPCH
CFLAGS=/c /nologo /Ob0 /MD$(D) /EHsc /GR /Zm300 /YX /Fpobj/headers.pch $(DEBUGFLAGS) $(WXDEFS) $(INCLUDEPATHS)
HEADERS=headers.h util.h main.h serialize.h uint256.h key.h bignum.h script.h db.h base58.h

111
net.cpp

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

17
net.h

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

2
serialize.h

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

663
ui.cpp

@ -7,6 +7,13 @@
#include <crtdbg.h>
#endif
void ThreadRequestProductDetails(void* parg);
void ThreadRandSendTest(void* parg);
bool GetStartOnSystemStartup();
void SetStartOnSystemStartup(bool fAutoStart);
DEFINE_EVENT_TYPE(wxEVT_CROSSTHREADCALL)
DEFINE_EVENT_TYPE(wxEVT_REPLY1)
DEFINE_EVENT_TYPE(wxEVT_REPLY2)
@ -16,22 +23,21 @@ DEFINE_EVENT_TYPE(wxEVT_TABLEUPDATED)
DEFINE_EVENT_TYPE(wxEVT_TABLEDELETED)
CMainFrame* pframeMain = NULL;
CMyTaskBarIcon* ptaskbaricon = NULL;
map<string, string> mapAddressBook;
CBitcoinTBIcon* taskBarIcon = NULL; // Tray icon
void ThreadRequestProductDetails(void* parg);
void ThreadRandSendTest(void* parg);
map<string, string> mapArgs;
bool fRandSendTest = false;
void RandSend();
extern int g_isPainting;
// UI settings and their default values
int minimizeToTray = 1;
int closeToTray = 1;
int startOnSysBoot = 1;
int askBeforeClosing = 1;
int alwaysShowTrayIcon = 1;
// Settings
int fShowGenerated = true;
int fMinimizeToTray = true;
int fMinimizeOnClose = true;
@ -282,7 +288,7 @@ CMainFrame::CMainFrame(wxWindow* parent) : CMainFrameBase(parent)
m_staticTextBalance->SetLabel(FormatMoney(GetBalance()) + " ");
m_listCtrl->SetFocus();
SetIcon(wxICON(bitcoin));
m_menuOptions->Check(wxID_OPTIONSGENERATEBITCOINS, fGenerateBitcoins);
ptaskbaricon = new CMyTaskBarIcon();
// Init toolbar with transparency masked bitmaps
m_toolBar->ClearTools();
@ -327,7 +333,7 @@ CMainFrame::CMainFrame(wxWindow* parent) : CMainFrameBase(parent)
//m_listCtrlOrdersReceived->InsertColumn(4, "", wxLIST_FORMAT_LEFT, 100);
// Init status bar
int pnWidths[3] = { -100, 81, 286 };
int pnWidths[3] = { -100, 88, 290 };
m_statusBar->SetFieldsCount(3, pnWidths);
// Fill your address text box
@ -342,6 +348,8 @@ CMainFrame::CMainFrame(wxWindow* parent) : CMainFrameBase(parent)
CMainFrame::~CMainFrame()
{
pframeMain = NULL;
delete ptaskbaricon;
ptaskbaricon = NULL;
}
void Shutdown(void* parg)
@ -362,28 +370,24 @@ void Shutdown(void* parg)
void CMainFrame::OnClose(wxCloseEvent& event)
{
if (closeToTray && event.CanVeto()) {
event.Veto();
SendToTray();
}
else if (!event.CanVeto() || !askBeforeClosing || wxMessageBox("Quit program?", "Confirm", wxYES_NO, this) == wxYES) {
delete taskBarIcon;
Destroy();
_beginthread(Shutdown, 0, NULL);
}
if (fMinimizeToTray && fMinimizeOnClose && event.CanVeto() && !IsIconized())
{
// Divert close to minimize
event.Veto();
Iconize(true);
}
else
{
Destroy();
_beginthread(Shutdown, 0, NULL);
}
}
void CMainFrame::OnIconize(wxIconizeEvent& event)
{
if (minimizeToTray) {
SendToTray();
}
}
void CMainFrame::SendToTray()
{
Hide();
taskBarIcon->Show();
// Hide the task bar button when minimized.
// Event is sent when the frame is minimized or restored.
Show(!fMinimizeToTray || !event.Iconized());
}
void CMainFrame::OnMouseEvents(wxMouseEvent& event)
@ -405,25 +409,21 @@ void CMainFrame::InsertLine(bool fNew, int nIndex, uint256 hashKey, string strSo
string str0 = strSort;
long nData = *(long*)&hashKey;
if (fNew)
// Find item
if (!fNew && nIndex == -1)
{
while ((nIndex = m_listCtrl->FindItem(nIndex, nData)) != -1)
if (GetItemText(m_listCtrl, nIndex, 1) == hashKey.ToString())
break;
}
// fNew is for blind insert, only use if you're sure it's new
if (fNew || nIndex == -1)
{
nIndex = m_listCtrl->InsertItem(0, str0);
}
else
{
if (nIndex == -1)
{
// Find item
while ((nIndex = m_listCtrl->FindItem(nIndex, nData)) != -1)
if (GetItemText(m_listCtrl, nIndex, 1) == hashKey.ToString())
break;
if (nIndex == -1)
{
printf("CMainFrame::InsertLine : Couldn't find item to be updated\n");
return;
}
}
// If sort key changed, must delete and reinsert to make it relocate
if (GetItemText(m_listCtrl, nIndex, 0) != str0)
{
@ -484,6 +484,28 @@ void CMainFrame::InsertTransaction(const CWalletTx& wtx, bool fNew, int nIndex)
string strStatus = FormatTxStatus(wtx);
map<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
CBlockIndex* pindex = NULL;
map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(wtx.hashBlock);
@ -785,16 +807,11 @@ void CMainFrame::OnPaintListCtrl(wxPaintEvent& event)
{
TRY_CRITICAL_BLOCK(cs_mapWallet)
{
pair<uint256, bool> item;
foreach(item, vWalletUpdated)
foreach(uint256 hash, vWalletUpdated)
{
bool fNew = item.second;
map<uint256, CWalletTx>::iterator mi = mapWallet.find(item.first);
map<uint256, CWalletTx>::iterator mi = mapWallet.find(hash);
if (mi != mapWallet.end())
{
printf("vWalletUpdated: %s %s\n", (*mi).second.GetHash().ToString().substr(0,6).c_str(), fNew ? "new" : "");
InsertTransaction((*mi).second, fNew);
}
InsertTransaction((*mi).second, false);
}
m_listCtrl->ScrollList(0, INT_MAX);
vWalletUpdated.clear();
@ -807,7 +824,7 @@ void CMainFrame::OnPaintListCtrl(wxPaintEvent& event)
// Update status bar
string strGen = "";
if (fGenerateBitcoins)
strGen = " Generating";
strGen = " Generating";
if (fGenerateBitcoins && vNodes.empty())
strGen = "(not connected)";
m_statusBar->SetStatusText(strGen, 1);
@ -856,39 +873,54 @@ void CMainFrame::OnCrossThreadCall(wxCommandEvent& event)
void CMainFrame::OnMenuFileExit(wxCommandEvent& event)
{
// File->Exit
Close(true);
}
void CMainFrame::OnMenuViewShowGenerated(wxCommandEvent& event)
{
// View->Show Generated
fShowGenerated = event.IsChecked();
CWalletDB().WriteSetting("fShowGenerated", fShowGenerated);
RefreshListCtrl();
}
void CMainFrame::OnUpdateUIViewShowGenerated(wxUpdateUIEvent& event)
{
event.Check(fShowGenerated);
}
void CMainFrame::OnMenuOptionsGenerate(wxCommandEvent& event)
{
// Options->Generate Coins
GenerateBitcoins(event.IsChecked());
}
Refresh();
wxPaintEvent eventPaint;
AddPendingEvent(eventPaint);
void CMainFrame::OnUpdateUIOptionsGenerate(wxUpdateUIEvent& event)
{
event.Check(fGenerateBitcoins);
}
void CMainFrame::OnMenuOptionsChangeYourAddress(wxCommandEvent& event)
{
// Options->Change Your Address
OnButtonChange(event);
}
void CMainFrame::OnMenuOptionsOptions(wxCommandEvent& event)
{
// Options->Options
COptionsDialog dialog(this);
dialog.ShowModal();
}
void CMainFrame::OnMenuHelpAbout(wxCommandEvent& event)
{
// Help->About
CAboutDialog dialog(this);
dialog.ShowModal();
}
void CMainFrame::OnUpdateMenuGenerate( wxUpdateUIEvent& event ) {
event.Check(fGenerateBitcoins);
}
void CMainFrame::OnButtonSend(wxCommandEvent& event)
{
/// debug test
@ -1252,58 +1284,74 @@ void CTxDetailsDialog::OnButtonOK(wxCommandEvent& event)
COptionsDialog::COptionsDialog(wxWindow* parent) : COptionsDialogBase(parent)
{
// Set up list box of page choices
m_listBox->Append("Main");
//m_listBox->Append("Test 2");
m_listBox->SetSelection(0);
SelectPage(0);
// Init values
m_textCtrlTransactionFee->SetValue(FormatMoney(nTransactionFee));
m_checkBoxLimitProcessors->SetValue(fLimitProcessors);
m_spinCtrlLimitProcessors->Enable(fLimitProcessors);
m_spinCtrlLimitProcessors->SetValue(nLimitProcessors);
int nProcessors = atoi(getenv("NUMBER_OF_PROCESSORS"));
if (nProcessors < 1)
nProcessors = 999;
m_spinCtrlLimitProcessors->SetRange(1, nProcessors);
m_checkBoxStartOnSystemStartup->SetValue(fTmpStartOnSystemStartup = GetStartOnSystemStartup());
m_checkBoxMinimizeToTray->SetValue(fMinimizeToTray);
m_checkBoxMinimizeOnClose->Enable(fMinimizeToTray);
m_checkBoxMinimizeOnClose->SetValue(fMinimizeToTray && fMinimizeOnClose);
fTmpMinimizeOnClose = fMinimizeOnClose;
m_buttonOK->SetFocus();
m_treeCtrl->AddRoot(wxT("Settings"));
m_treeCtrl->AppendItem(m_treeCtrl->GetRootItem(), wxT("Bitcoin"));
m_treeCtrl->AppendItem(m_treeCtrl->GetRootItem(), wxT("UI"));
}
panelUI = new COptionsPanelUI(this);
panelBitcoin = new COptionsPanelBitcoin(this);
currentPanel = panelBitcoin;
void COptionsDialog::SelectPage(int nPage)
{
m_panelMain->Show(nPage == 0);
m_panelTest2->Show(nPage == 1);
panelSizer->Add(panelUI);
panelSizer->Hide(panelUI);
panelSizer->Add(panelBitcoin);
panelSizer->Layout();
m_scrolledWindow->Layout();
m_scrolledWindow->SetScrollbars(0, 0, 0, 0, 0, 0);
}
void COptionsDialog::OnListBox(wxCommandEvent& event)
{
SelectPage(event.GetSelection());
}
void COptionsDialog::MenuSelChanged( wxTreeEvent& event )
void COptionsDialog::OnKillFocusTransactionFee(wxFocusEvent& event)
{
panelSizer->Hide(currentPanel);
wxString text = m_treeCtrl->GetItemText(event.GetItem());
if (text == "Bitcoin") {
panelSizer->Show(panelBitcoin);
currentPanel = panelBitcoin;
}
else {
panelSizer->Show(panelUI);
currentPanel = panelUI;
}
panelSizer->Layout();
int64 nTmp = nTransactionFee;
ParseMoney(m_textCtrlTransactionFee->GetValue(), nTmp);
m_textCtrlTransactionFee->SetValue(FormatMoney(nTmp));
}
void COptionsDialog::OnButtonOK(wxCommandEvent& event)
void COptionsDialog::OnCheckBoxLimitProcessors(wxCommandEvent& event)
{
// nTransactionFee
int64 nPrevTransactionFee = nTransactionFee;
if (ParseMoney(panelBitcoin->m_textCtrlTransactionFee->GetValue(), nTransactionFee) && nTransactionFee != nPrevTransactionFee)
CWalletDB().WriteSetting("transactionFee", nTransactionFee);
m_spinCtrlLimitProcessors->Enable(event.IsChecked());
}
minimizeToTray = panelUI->m_checkMinToTray->IsChecked();
closeToTray = panelUI->m_checkCloseToTray->IsChecked();
startOnSysBoot = panelUI->m_checkStartOnSysBoot->IsChecked();
askBeforeClosing = panelUI->m_checkAskBeforeClosing->IsChecked();
alwaysShowTrayIcon = panelUI->m_checkAlwaysShowTray->IsChecked();
void COptionsDialog::OnCheckBoxMinimizeToTray(wxCommandEvent& event)
{
m_checkBoxMinimizeOnClose->Enable(event.IsChecked());
CWalletDB().WriteSetting("minimizeToTray", minimizeToTray);
CWalletDB().WriteSetting("closeToTray", closeToTray);
CWalletDB().WriteSetting("startOnSysBoot", startOnSysBoot);
CWalletDB().WriteSetting("askBeforeClosing", askBeforeClosing);
CWalletDB().WriteSetting("alwaysShowTrayIcon", alwaysShowTrayIcon);
// Save the value in fTmpMinimizeOnClose so we can
// show the checkbox unchecked when its parent is unchecked
if (event.IsChecked())
m_checkBoxMinimizeOnClose->SetValue(fTmpMinimizeOnClose);
else
{
fTmpMinimizeOnClose = m_checkBoxMinimizeOnClose->GetValue();
m_checkBoxMinimizeOnClose->SetValue(false);
}
ApplyUISettings();
}
void COptionsDialog::OnButtonOK(wxCommandEvent& event)
{
OnButtonApply(event);
Close();
}
@ -1312,44 +1360,53 @@ void COptionsDialog::OnButtonCancel(wxCommandEvent& event)
Close();
}
//////////////////////////////////////////////////////////////////////////////
//
// COptionsPanelBitcoin
//
COptionsPanelBitcoin::COptionsPanelBitcoin(wxWindow* parent) : COptionsPanelBitcoinBase(parent)
void COptionsDialog::OnButtonApply(wxCommandEvent& event)
{
m_textCtrlTransactionFee->SetValue(FormatMoney(nTransactionFee));
}
CWalletDB walletdb;
void COptionsPanelBitcoin::OnKillFocusTransactionFee(wxFocusEvent& event)
{
int64 nTmp = nTransactionFee;
ParseMoney(m_textCtrlTransactionFee->GetValue(), nTmp);
m_textCtrlTransactionFee->SetValue(FormatMoney(nTmp));
}
int64 nPrevTransactionFee = nTransactionFee;
if (ParseMoney(m_textCtrlTransactionFee->GetValue(), nTransactionFee) && nTransactionFee != nPrevTransactionFee)
walletdb.WriteSetting("nTransactionFee", nTransactionFee);
int nPrevMaxProc = (fLimitProcessors ? nLimitProcessors : INT_MAX);
if (fLimitProcessors != m_checkBoxLimitProcessors->GetValue())
{
fLimitProcessors = m_checkBoxLimitProcessors->GetValue();
walletdb.WriteSetting("fLimitProcessors", fLimitProcessors);
}
if (nLimitProcessors != m_spinCtrlLimitProcessors->GetValue())
{
nLimitProcessors = m_spinCtrlLimitProcessors->GetValue();
walletdb.WriteSetting("nLimitProcessors", nLimitProcessors);
}
if (fGenerateBitcoins && (fLimitProcessors ? nLimitProcessors : INT_MAX) > nPrevMaxProc)
GenerateBitcoins(fGenerateBitcoins);
//////////////////////////////////////////////////////////////////////////////
//
// COptionsPanelUI
//
if (fTmpStartOnSystemStartup != m_checkBoxStartOnSystemStartup->GetValue())
{
fTmpStartOnSystemStartup = m_checkBoxStartOnSystemStartup->GetValue();
SetStartOnSystemStartup(fTmpStartOnSystemStartup);
}
COptionsPanelUI::COptionsPanelUI(wxWindow* parent) : COptionsPanelUIBase(parent)
{
m_checkMinToTray->SetValue(minimizeToTray);
m_checkCloseToTray->SetValue(closeToTray);
m_checkStartOnSysBoot->SetValue(startOnSysBoot);
m_checkAskBeforeClosing->SetValue(askBeforeClosing);
m_checkAlwaysShowTray->SetValue(alwaysShowTrayIcon);
if (fMinimizeToTray != m_checkBoxMinimizeToTray->GetValue())
{
fMinimizeToTray = m_checkBoxMinimizeToTray->GetValue();
walletdb.WriteSetting("fMinimizeToTray", fMinimizeToTray);
ptaskbaricon->Show(fMinimizeToTray);
}
if (fMinimizeOnClose != (fMinimizeToTray ? m_checkBoxMinimizeOnClose->GetValue() : fTmpMinimizeOnClose))
{
fMinimizeOnClose = (fMinimizeToTray ? m_checkBoxMinimizeOnClose->GetValue() : fTmpMinimizeOnClose);
walletdb.WriteSetting("fMinimizeOnClose", fMinimizeOnClose);
}
}
//////////////////////////////////////////////////////////////////////////////
//
// CAboutDialog
@ -1387,6 +1444,7 @@ CSendDialog::CSendDialog(wxWindow* parent, const wxString& strAddress) : CSendDi
m_textCtrlAddress->SetValue(strAddress);
m_choiceTransferType->SetSelection(0);
m_bitmapCheckMark->Show(false);
fEnabledPrev = true;
//// todo: should add a display of your balance for convenience
// Set Icon
@ -1418,6 +1476,19 @@ void CSendDialog::OnTextAddress(wxCommandEvent& event)
m_staticTextMessage->Enable(fEnable);
m_textCtrlMessage->Enable(fEnable);
m_textCtrlMessage->SetBackgroundColour(wxSystemSettings::GetColour(fEnable ? wxSYS_COLOUR_WINDOW : wxSYS_COLOUR_BTNFACE));
if (!fEnable && fEnabledPrev)
{
strFromSave = m_textCtrlFrom->GetValue();
strMessageSave = m_textCtrlMessage->GetValue();
m_textCtrlFrom->SetValue("Will appear as \"From: Unknown\"");
m_textCtrlMessage->SetValue("Can't include a message when sending to a Bitcoin address");
}
else if (fEnable && !fEnabledPrev)
{
m_textCtrlFrom->SetValue(strFromSave);
m_textCtrlMessage->SetValue(strMessageSave);
}
fEnabledPrev = fEnable;
}
void CSendDialog::OnKillFocusAmount(wxFocusEvent& event)
@ -1773,8 +1844,9 @@ void CSendingDialog::OnReply2(CDataStream& vRecv)
Error("You don't have enough money");
return;
}
CKey key;
int64 nFeeRequired;
if (!CreateTransaction(scriptPubKey, nPrice, wtx, nFeeRequired))
if (!CreateTransaction(scriptPubKey, nPrice, wtx, key, nFeeRequired))
{
if (nPrice + nFeeRequired > GetBalance())
Error(strprintf("This is an oversized transaction that requires a transaction fee of %s", FormatMoney(nFeeRequired).c_str()));
@ -1799,7 +1871,7 @@ void CSendingDialog::OnReply2(CDataStream& vRecv)
return;
// Commit
if (!CommitTransactionSpent(wtx))
if (!CommitTransactionSpent(wtx, key))
{
Error("Error finalizing payment");
return;
@ -2950,84 +3022,112 @@ void CEditReviewDialog::GetReview(CReview& review)
//////////////////////////////////////////////////////////////////////////////
//
// BitcoinTBIcon
// CMyTaskBarIcon
//
enum {
PU_RESTORE = 10001,
PU_GENERATE,
PU_EXIT,
enum
{
ID_TASKBAR_RESTORE = 10001,
ID_TASKBAR_GENERATE,
ID_TASKBAR_EXIT,
};
BEGIN_EVENT_TABLE(CBitcoinTBIcon, wxTaskBarIcon)
EVT_TASKBAR_LEFT_DCLICK (CBitcoinTBIcon::OnLeftButtonDClick)
EVT_MENU(PU_RESTORE, CBitcoinTBIcon::OnMenuRestore)
EVT_MENU(PU_GENERATE, CBitcoinTBIcon::OnMenuGenerate)
EVT_MENU(PU_EXIT, CBitcoinTBIcon::OnMenuExit)
BEGIN_EVENT_TABLE(CMyTaskBarIcon, wxTaskBarIcon)
EVT_TASKBAR_LEFT_DCLICK(CMyTaskBarIcon::OnLeftButtonDClick)
EVT_MENU(ID_TASKBAR_RESTORE, CMyTaskBarIcon::OnMenuRestore)
EVT_MENU(ID_TASKBAR_GENERATE, CMyTaskBarIcon::OnMenuGenerate)
EVT_UPDATE_UI(ID_TASKBAR_GENERATE, CMyTaskBarIcon::OnUpdateUIGenerate)
EVT_MENU(ID_TASKBAR_EXIT, CMyTaskBarIcon::OnMenuExit)
END_EVENT_TABLE()
void CBitcoinTBIcon::Show()
void CMyTaskBarIcon::Show(bool fShow)
{
string tooltip = "Bitcoin";
tooltip += fGenerateBitcoins ? " - Generating" : "";
SetIcon(wxICON(bitcoin), tooltip);
if (fShow)
{
string strTooltip = "Bitcoin";
if (fGenerateBitcoins)
strTooltip = "Bitcoin - Generating";
if (fGenerateBitcoins && vNodes.empty())
strTooltip = "Bitcoin - (not connected)";
SetIcon(wxICON(bitcoin), strTooltip);
}
else
{
RemoveIcon();
}
}
void CBitcoinTBIcon::Hide()
void CMyTaskBarIcon::Hide()
{
RemoveIcon();
Show(false);
}
void CBitcoinTBIcon::OnLeftButtonDClick(wxTaskBarIconEvent&)
void CMyTaskBarIcon::OnLeftButtonDClick(wxTaskBarIconEvent& event)
{
Restore();
Restore();
}
void CBitcoinTBIcon::OnMenuExit(wxCommandEvent&)
void CMyTaskBarIcon::OnMenuRestore(wxCommandEvent& event)
{
pframeMain->Close(true);
Restore();
}
void CBitcoinTBIcon::OnMenuGenerate(wxCommandEvent& event)
void CMyTaskBarIcon::Restore()
{
GenerateBitcoins(event.IsChecked());
pframeMain->Refresh();
}
void CBitcoinTBIcon::OnMenuRestore(wxCommandEvent&) {
Restore();
}
void CBitcoinTBIcon::Restore() {
pframeMain->Show();
pframeMain->Iconize(false);
pframeMain->Raise();
if (!alwaysShowTrayIcon)
Hide();
}
void CBitcoinTBIcon::UpdateTooltip() {
if (IsIconInstalled())
Show();
void CMyTaskBarIcon::OnMenuGenerate(wxCommandEvent& event)
{
GenerateBitcoins(event.IsChecked());
}
void CMyTaskBarIcon::OnUpdateUIGenerate(wxUpdateUIEvent& event)
{
event.Check(fGenerateBitcoins);
}
wxMenu *CBitcoinTBIcon::CreatePopupMenu()
void CMyTaskBarIcon::OnMenuExit(wxCommandEvent& event)
{
wxMenu *menu = new wxMenu;
menu->Append(PU_RESTORE, _T("Open Bitcoin"));
wxMenuItem* generateCheck = menu->AppendCheckItem(PU_GENERATE, _T("Generate Coins"));
menu->InsertSeparator(2);
menu->Append(PU_EXIT, _T("Exit"));
pframeMain->Close(true);
}
generateCheck->Check(fGenerateBitcoins);
void CMyTaskBarIcon::UpdateTooltip()
{
if (IsIconInstalled())
Show(true);
}
return menu;
wxMenu* CMyTaskBarIcon::CreatePopupMenu()
{
wxMenu* pmenu = new wxMenu;
pmenu->Append(ID_TASKBAR_RESTORE, "&Open Bitcoin");
pmenu->AppendCheckItem(ID_TASKBAR_GENERATE, "&Generate Coins")->Check(fGenerateBitcoins);
#ifndef __WXMAC_OSX__ // Mac has built-in quit menu
pmenu->AppendSeparator();
pmenu->Append(ID_TASKBAR_EXIT, "E&xit");
#endif
return pmenu;
}
//////////////////////////////////////////////////////////////////////////////
//
// CMyApp
@ -3150,7 +3250,7 @@ bool CMyApp::OnInit2()
// Parameters
//
wxImage::AddHandler(new wxPNGHandler);
map<string, string> mapArgs = ParseParameters(argc, argv);
mapArgs = ParseParameters(argc, argv);
if (mapArgs.count("/datadir"))
strSetDataDir = mapArgs["/datadir"];
@ -3179,6 +3279,7 @@ bool CMyApp::OnInit2()
//
// Load data files
//
bool fFirstRun;
string strErrors;
int64 nStart, nEnd;
@ -3198,7 +3299,7 @@ bool CMyApp::OnInit2()
printf("Loading wallet...\n");
QueryPerformanceCounter((LARGE_INTEGER*)&nStart);
if (!LoadWallet())
if (!LoadWallet(fFirstRun))
strErrors += "Error loading wallet.dat \n";
QueryPerformanceCounter((LARGE_INTEGER*)&nEnd);
printf(" wallet %20I64d\n", nEnd - nStart);
@ -3244,62 +3345,60 @@ bool CMyApp::OnInit2()
//
// Create the main frame window
//
pframeMain = new CMainFrame(NULL);
if (mapArgs.count("/min"))
pframeMain->Iconize(true);
pframeMain->Show(true); // have to show first to get taskbar button to hide
pframeMain->Show(!fMinimizeToTray || !pframeMain->IsIconized());
ptaskbaricon->Show(fMinimizeToTray);
if (!CheckDiskSpace())
{
pframeMain = new CMainFrame(NULL);
pframeMain->Show();
OnExit();
return false;
}
if (!CheckDiskSpace())
{
OnExit();
return false;
}
if (!StartNode(strErrors))
wxMessageBox(strErrors, "Bitcoin");
if (!StartNode(strErrors))
wxMessageBox(strErrors, "Bitcoin");
GenerateBitcoins(fGenerateBitcoins);
if (fGenerateBitcoins)
if (_beginthread(ThreadBitcoinMiner, 0, NULL) == -1)
printf("Error: _beginthread(ThreadBitcoinMiner) failed\n");
if (fFirstRun)
SetStartOnSystemStartup(true);
//
// Tests
//
if (argc >= 2 && stricmp(argv[1], "/send") == 0)
{
int64 nValue = 1;
if (argc >= 3)
ParseMoney(argv[2], nValue);
string strAddress;
if (argc >= 4)
strAddress = argv[3];
CAddress addr(strAddress.c_str());
CWalletTx wtx;
wtx.mapValue["to"] = strAddress;
wtx.mapValue["from"] = addrLocalHost.ToString();
wtx.mapValue["message"] = "command line send";
// Send to IP address
CSendingDialog* pdialog = new CSendingDialog(pframeMain, addr, nValue, wtx);
if (!pdialog->ShowModal())
return false;
}
if (mapArgs.count("/randsendtest"))
{
if (!mapArgs["/randsendtest"].empty())
_beginthread(ThreadRandSendTest, 0, new string(mapArgs["/randsendtest"]));
else
fRandSendTest = true;
fDebug = true;
}
//
// Tests
//
if (argc >= 2 && stricmp(argv[1], "/send") == 0)
{
int64 nValue = 1;
if (argc >= 3)
ParseMoney(argv[2], nValue);
string strAddress;
if (argc >= 4)
strAddress = argv[3];
CAddress addr(strAddress.c_str());
CWalletTx wtx;
wtx.mapValue["to"] = strAddress;
wtx.mapValue["from"] = addrLocalHost.ToString();
wtx.mapValue["message"] = "command line send";
// Send to IP address
CSendingDialog* pdialog = new CSendingDialog(pframeMain, addr, nValue, wtx);
if (!pdialog->ShowModal())
return false;
}
taskBarIcon = new CBitcoinTBIcon();
ApplyUISettings();
if (mapArgs.count("/min") && minimizeToTray) {
pframeMain->Iconize(true);
if (mapArgs.count("/randsendtest"))
{
if (!mapArgs["/randsendtest"].empty())
_beginthread(ThreadRandSendTest, 0, new string(mapArgs["/randsendtest"]));
else
fRandSendTest = true;
fDebug = true;
}
return true;
@ -3320,14 +3419,14 @@ bool CMyApp::OnExceptionInMainLoop()
catch (std::exception& e)
{
PrintException(&e, "CMyApp::OnExceptionInMainLoop()");
wxLogWarning(_T("Exception %s %s"), typeid(e).name(), e.what());
wxLogWarning("Exception %s %s", typeid(e).name(), e.what());
Sleep(1000);
throw;
}
catch (...)
{
PrintException(NULL, "CMyApp::OnExceptionInMainLoop()");
wxLogWarning(_T("Unknown exception"));
wxLogWarning("Unknown exception");
Sleep(1000);
throw;
}
@ -3345,14 +3444,14 @@ void CMyApp::OnUnhandledException()
catch (std::exception& e)
{
PrintException(&e, "CMyApp::OnUnhandledException()");
wxLogWarning(_T("Exception %s %s"), typeid(e).name(), e.what());
wxLogWarning("Exception %s %s", typeid(e).name(), e.what());
Sleep(1000);
throw;
}
catch (...)
{
PrintException(NULL, "CMyApp::OnUnhandledException()");
wxLogWarning(_T("Unknown exception"));
wxLogWarning("Unknown exception");
Sleep(1000);
throw;
}
@ -3367,6 +3466,8 @@ void CMyApp::OnFatalException()
void MainFrameRepaint()
{
// This is called by network code that shouldn't access pframeMain and ptaskbaricon
// directly because it could still be running after the UI is closed.
if (pframeMain)
{
printf("MainFrameRepaint()\n");
@ -3374,68 +3475,84 @@ void MainFrameRepaint()
pframeMain->Refresh();
pframeMain->AddPendingEvent(event);
}
if (ptaskbaricon)
ptaskbaricon->UpdateTooltip();
}
string StartupShortcutPath()
{
// Get the startup folder shortcut path
char pszLinkPath[MAX_PATH+100];
pszLinkPath[0] = '\0';
SHGetSpecialFolderPath(0, pszLinkPath, CSIDL_STARTUP, 0);
strcat(pszLinkPath, "\\Bitcoin.lnk");
return pszLinkPath;
}
bool GetStartOnSystemStartup()
{
return FileExists(StartupShortcutPath().c_str());
}
void ApplyUISettings() {
// Show the tray icon?
if (alwaysShowTrayIcon)
taskBarIcon->Show();
else
taskBarIcon->Hide();
void SetStartOnSystemStartup(bool fAutoStart)
{
// If the shortcut exists already, remove it for updating
remove(StartupShortcutPath().c_str());
// Autostart on system startup?
// Open the startup registry key
HKEY hKey;
LONG lnRes = RegOpenKeyEx(
HKEY_CURRENT_USER,
"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run",
0,
KEY_ALL_ACCESS,
&hKey
);
if (fAutoStart)
{
CoInitialize(NULL);
if ( ERROR_SUCCESS == lnRes )
{
if (startOnSysBoot) {
// Get the current executable path
char exePath[ MAX_PATH ];
GetModuleFileName(NULL, exePath, _MAX_PATH + 1);
char runCmd[ MAX_PATH + 5 ];
strcat(runCmd, exePath);
strcat(runCmd," /min");
// Get a pointer to the IShellLink interface.
HRESULT hres = NULL;
IShellLink* psl = NULL;
hres = CoCreateInstance(CLSID_ShellLink, NULL,
CLSCTX_INPROC_SERVER, IID_IShellLink,
reinterpret_cast<void**>(&psl));
RegSetValueEx(hKey,
"Bitcoin",
0,
REG_SZ,
(BYTE*)runCmd,
sizeof(runCmd)
);
}
else {
RegDeleteValue(hKey, "Bitcoin");
}
}
RegCloseKey(hKey);
if (SUCCEEDED(hres))
{
// Get the current executable path
char pszExePath[MAX_PATH];
GetModuleFileName(NULL, pszExePath, sizeof(pszExePath));
_strlwr(pszExePath);
// Set the path to the shortcut target
psl->SetPath(pszExePath);
PathRemoveFileSpec(pszExePath);
psl->SetWorkingDirectory(pszExePath);
psl->SetShowCmd(SW_SHOWMINNOACTIVE);
// Query IShellLink for the IPersistFile interface for
// saving the shortcut in persistent storage.
IPersistFile* ppf = NULL;
hres = psl->QueryInterface(IID_IPersistFile,
reinterpret_cast<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();
}
}
void GenerateBitcoins(bool flag)
{
fGenerateBitcoins = flag;
nTransactionsUpdated++;
CWalletDB().WriteSetting("fGenerateBitcoins", fGenerateBitcoins);
if (fGenerateBitcoins)
if (_beginthread(ThreadBitcoinMiner, 0, NULL) == -1)
printf("Error: _beginthread(ThreadBitcoinMiner) failed\n");
taskBarIcon->UpdateTooltip();
}

108
ui.h

@ -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 string DateTimeStr(int64 nTime);
extern string FormatTxStatus(const CWalletTx& wtx);
extern void CrossThreadCall(int nID, void* pdata);
extern void MainFrameRepaint();
extern void Shutdown(void* parg);
void ApplyUISettings();
void GenerateBitcoins(bool flag);
// UI settings
extern int minimizeToTray;
extern int closeToTray;
extern int startOnSysBoot;
extern int askBeforeClosing;
extern int alwaysShowTrayIcon;
@ -44,14 +48,17 @@ class CMainFrame : public CMainFrameBase
protected:
// Event handlers
void OnClose(wxCloseEvent& event);
void OnIconize( wxIconizeEvent& event );
void OnIconize(wxIconizeEvent& event);
void OnMouseEvents(wxMouseEvent& event);
void OnKeyDown(wxKeyEvent& event) { HandleCtrlA(event); }
void OnIdle(wxIdleEvent& event);
void OnPaint(wxPaintEvent& event);
void OnPaintListCtrl(wxPaintEvent& event);
void OnMenuFileExit(wxCommandEvent& event);
void OnMenuViewShowGenerated(wxCommandEvent& event);
void OnUpdateUIViewShowGenerated(wxUpdateUIEvent& event);
void OnMenuOptionsGenerate(wxCommandEvent& event);
void OnUpdateUIOptionsGenerate(wxUpdateUIEvent& event);
void OnMenuOptionsChangeYourAddress(wxCommandEvent& event);
void OnMenuOptionsOptions(wxCommandEvent& event);
void OnMenuHelpAbout(wxCommandEvent& event);
@ -66,7 +73,6 @@ protected:
void OnListItemActivatedProductsSent(wxListEvent& event);
void OnListItemActivatedOrdersSent(wxListEvent& event);
void OnListItemActivatedOrdersReceived(wxListEvent& event);
void OnUpdateMenuGenerate( wxUpdateUIEvent& event );
public:
/** Constructor */
@ -85,7 +91,6 @@ public:
void InsertTransaction(const CWalletTx& wtx, bool fNew, int nIndex=-1);
void RefreshListCtrl();
void RefreshStatus();
void SendToTray();
};
@ -107,47 +112,26 @@ public:
class COptionsPanelBitcoin : public COptionsPanelBitcoinBase
{
protected:
// Event handlers
void OnKillFocusTransactionFee( wxFocusEvent& event );
public:
/** Constructor */
COptionsPanelBitcoin(wxWindow* parent);
};
class COptionsPanelUI : public COptionsPanelUIBase
{
protected:
// Event handlers
void OnOptionsChanged( wxCommandEvent& event );
public:
/** Constructor */
COptionsPanelUI(wxWindow* parent);
};
class COptionsDialog : public COptionsDialogBase
{
protected:
// Event handlers
void MenuSelChanged( wxTreeEvent& event );
void OnListBox(wxCommandEvent& event);
void OnKillFocusTransactionFee(wxFocusEvent& event);
void OnCheckBoxLimitProcessors(wxCommandEvent& event);
void OnCheckBoxMinimizeToTray(wxCommandEvent& event);
void OnButtonOK(wxCommandEvent& event);
void OnButtonCancel(wxCommandEvent& event);
void OnButtonApply(wxCommandEvent& event);
// Panels
COptionsPanelBitcoin* panelBitcoin;
COptionsPanelUI* panelUI;
wxPanel* currentPanel;
public:
/** Constructor */
COptionsDialog(wxWindow* parent);
// Custom
bool fTmpStartOnSystemStartup;
bool fTmpMinimizeOnClose;
void SelectPage(int nPage);
};
@ -180,6 +164,11 @@ protected:
public:
/** Constructor */
CSendDialog(wxWindow* parent, const wxString& strAddress="");
// Custom
bool fEnabledPrev;
string strFromSave;
string strMessageSave;
};
@ -455,22 +444,33 @@ public:
class CBitcoinTBIcon : public wxTaskBarIcon
class CMyTaskBarIcon : public wxTaskBarIcon
{
protected:
void Restore();
// Event handlers
void OnLeftButtonDClick(wxTaskBarIconEvent&);
void OnMenuExit(wxCommandEvent&);
void OnMenuGenerate(wxCommandEvent&);
void OnMenuRestore(wxCommandEvent&);
// Event handlers
void OnLeftButtonDClick(wxTaskBarIconEvent& event);
void OnMenuRestore(wxCommandEvent& event);
void OnUpdateUIGenerate(wxUpdateUIEvent& event);
void OnMenuGenerate(wxCommandEvent& event);
void OnMenuExit(wxCommandEvent& event);
public:
void Show();
void Hide();
void UpdateTooltip();
virtual wxMenu *CreatePopupMenu();
CMyTaskBarIcon() : wxTaskBarIcon()
{
Show(true);
}
void Show(bool fShow=true);
void Hide();
void Restore();
void UpdateTooltip();
virtual wxMenu* CreatePopupMenu();
DECLARE_EVENT_TABLE()
};

233
uibase.cpp

@ -24,14 +24,21 @@ CMainFrameBase::CMainFrameBase( wxWindow* parent, wxWindowID id, const wxString&
m_menubar->Append( m_menuFile, wxT("&File") );
m_menuView = new wxMenu();
wxMenuItem* m_menuViewShowGenerated;
m_menuViewShowGenerated = new wxMenuItem( m_menuView, wxID_VIEWSHOWGENERATED, wxString( wxT("&Show Generated Coins") ) , wxEmptyString, wxITEM_CHECK );
m_menuView->Append( m_menuViewShowGenerated );
m_menubar->Append( m_menuView, wxT("&View") );
m_menuOptions = new wxMenu();
wxMenuItem* m_menuOptionsGenerateBitcoins;
m_menuOptionsGenerateBitcoins = new wxMenuItem( m_menuOptions, wxID_OPTIONSGENERATEBITCOINS, wxString( wxT("&Generate Coins") ) , wxEmptyString, wxITEM_CHECK );
m_menuOptions->Append( m_menuOptionsGenerateBitcoins );
wxMenuItem* m_menuChangeYourAddress;
m_menuChangeYourAddress = new wxMenuItem( m_menuOptions, wxID_ANY, wxString( wxT("&Change Your Address...") ) , wxEmptyString, wxITEM_NORMAL );
m_menuOptions->Append( m_menuChangeYourAddress );
wxMenuItem* m_menuOptionsChangeYourAddress;
m_menuOptionsChangeYourAddress = new wxMenuItem( m_menuOptions, wxID_ANY, wxString( wxT("&Change Your Address...") ) , wxEmptyString, wxITEM_NORMAL );
m_menuOptions->Append( m_menuOptionsChangeYourAddress );
wxMenuItem* m_menuOptionsOptions;
m_menuOptionsOptions = new wxMenuItem( m_menuOptions, wxID_ANY, wxString( wxT("&Options...") ) , wxEmptyString, wxITEM_NORMAL );
@ -225,9 +232,11 @@ CMainFrameBase::CMainFrameBase( wxWindow* parent, wxWindowID id, const wxString&
this->Connect( wxEVT_MOUSEWHEEL, wxMouseEventHandler( CMainFrameBase::OnMouseEvents ) );
this->Connect( wxEVT_PAINT, wxPaintEventHandler( CMainFrameBase::OnPaint ) );
this->Connect( m_menuFileExit->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( CMainFrameBase::OnMenuFileExit ) );
this->Connect( m_menuViewShowGenerated->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( CMainFrameBase::OnMenuViewShowGenerated ) );
this->Connect( m_menuViewShowGenerated->GetId(), wxEVT_UPDATE_UI, wxUpdateUIEventHandler( CMainFrameBase::OnUpdateUIViewShowGenerated ) );
this->Connect( m_menuOptionsGenerateBitcoins->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( CMainFrameBase::OnMenuOptionsGenerate ) );
this->Connect( m_menuOptionsGenerateBitcoins->GetId(), wxEVT_UPDATE_UI, wxUpdateUIEventHandler( CMainFrameBase::OnUpdateMenuGenerate ) );
this->Connect( m_menuChangeYourAddress->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( CMainFrameBase::OnMenuOptionsChangeYourAddress ) );
this->Connect( m_menuOptionsGenerateBitcoins->GetId(), wxEVT_UPDATE_UI, wxUpdateUIEventHandler( CMainFrameBase::OnUpdateUIOptionsGenerate ) );
this->Connect( m_menuOptionsChangeYourAddress->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( CMainFrameBase::OnMenuOptionsChangeYourAddress ) );
this->Connect( m_menuOptionsOptions->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( CMainFrameBase::OnMenuOptionsOptions ) );
this->Connect( m_menuHelpAbout->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( CMainFrameBase::OnMenuHelpAbout ) );
this->Connect( wxID_BUTTONSEND, wxEVT_COMMAND_TOOL_CLICKED, wxCommandEventHandler( CMainFrameBase::OnButtonSend ) );
@ -278,8 +287,10 @@ CMainFrameBase::~CMainFrameBase()
this->Disconnect( wxEVT_MOUSEWHEEL, wxMouseEventHandler( CMainFrameBase::OnMouseEvents ) );
this->Disconnect( wxEVT_PAINT, wxPaintEventHandler( CMainFrameBase::OnPaint ) );
this->Disconnect( wxID_ANY, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( CMainFrameBase::OnMenuFileExit ) );
this->Disconnect( wxID_ANY, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( CMainFrameBase::OnMenuViewShowGenerated ) );
this->Disconnect( wxID_ANY, wxEVT_UPDATE_UI, wxUpdateUIEventHandler( CMainFrameBase::OnUpdateUIViewShowGenerated ) );
this->Disconnect( wxID_ANY, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( CMainFrameBase::OnMenuOptionsGenerate ) );
this->Disconnect( wxID_ANY, wxEVT_UPDATE_UI, wxUpdateUIEventHandler( CMainFrameBase::OnUpdateMenuGenerate ) );
this->Disconnect( wxID_ANY, wxEVT_UPDATE_UI, wxUpdateUIEventHandler( CMainFrameBase::OnUpdateUIOptionsGenerate ) );
this->Disconnect( wxID_ANY, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( CMainFrameBase::OnMenuOptionsChangeYourAddress ) );
this->Disconnect( wxID_ANY, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( CMainFrameBase::OnMenuOptionsOptions ) );
this->Disconnect( wxID_ANY, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( CMainFrameBase::OnMenuHelpAbout ) );
@ -353,15 +364,121 @@ COptionsDialogBase::COptionsDialogBase( wxWindow* parent, wxWindowID id, const w
wxBoxSizer* bSizer55;
bSizer55 = new wxBoxSizer( wxVERTICAL );
panelSizer = new wxBoxSizer( wxHORIZONTAL );
wxBoxSizer* bSizer66;
bSizer66 = new wxBoxSizer( wxHORIZONTAL );
m_listBox = new wxListBox( this, wxID_ANY, wxDefaultPosition, wxSize( 110,-1 ), 0, NULL, wxLB_NEEDED_SB|wxLB_SINGLE );
bSizer66->Add( m_listBox, 0, wxEXPAND|wxRIGHT, 5 );
m_scrolledWindow = new wxScrolledWindow( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 );
m_scrolledWindow->SetScrollRate( 5, 5 );
wxBoxSizer* bSizer63;
bSizer63 = new wxBoxSizer( wxVERTICAL );
m_panelMain = new wxPanel( m_scrolledWindow, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
wxBoxSizer* bSizer69;
bSizer69 = new wxBoxSizer( wxVERTICAL );
bSizer69->Add( 0, 14, 0, wxEXPAND, 5 );
m_staticText32 = new wxStaticText( m_panelMain, wxID_ANY, wxT("Optional transaction fee you give to the nodes that process your transactions."), wxDefaultPosition, wxDefaultSize, 0 );
m_staticText32->Wrap( -1 );
m_staticText32->Hide();
bSizer69->Add( m_staticText32, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
wxBoxSizer* bSizer56;
bSizer56 = new wxBoxSizer( wxHORIZONTAL );
m_staticText31 = new wxStaticText( m_panelMain, wxID_ANY, wxT("Transaction fee:"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticText31->Wrap( -1 );
m_staticText31->Hide();
bSizer56->Add( m_staticText31, 0, wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxLEFT, 5 );
m_textCtrlTransactionFee = new wxTextCtrl( m_panelMain, wxID_TRANSACTIONFEE, wxEmptyString, wxDefaultPosition, wxSize( 70,-1 ), 0 );
m_textCtrlTransactionFee->Hide();
bSizer56->Add( m_textCtrlTransactionFee, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 );
bSizer69->Add( bSizer56, 0, wxEXPAND, 5 );
wxBoxSizer* bSizer71;
bSizer71 = new wxBoxSizer( wxHORIZONTAL );
m_checkBoxLimitProcessors = new wxCheckBox( m_panelMain, wxID_ANY, wxT("&Limit coin generation to"), wxDefaultPosition, wxDefaultSize, 0 );
bSizer71->Add( m_checkBoxLimitProcessors, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
m_spinCtrlLimitProcessors = new wxSpinCtrl( m_panelMain, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize( 48,-1 ), wxSP_ARROW_KEYS, 1, 999, 1 );
bSizer71->Add( m_spinCtrlLimitProcessors, 0, wxTOP|wxBOTTOM, 5 );
m_staticText35 = new wxStaticText( m_panelMain, wxID_ANY, wxT("processors"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticText35->Wrap( -1 );
bSizer71->Add( m_staticText35, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
bSizer69->Add( bSizer71, 0, 0, 5 );
m_checkBoxStartOnSystemStartup = new wxCheckBox( m_panelMain, wxID_ANY, wxT("&Start Bitcoin on system startup"), wxDefaultPosition, wxDefaultSize, 0 );
bSizer69->Add( m_checkBoxStartOnSystemStartup, 0, wxALL, 5 );
m_checkBoxMinimizeToTray = new wxCheckBox( m_panelMain, wxID_ANY, wxT("&Minimize to the system tray instead of the taskbar"), wxDefaultPosition, wxDefaultSize, 0 );
bSizer69->Add( m_checkBoxMinimizeToTray, 0, wxALL, 5 );
wxBoxSizer* bSizer101;
bSizer101 = new wxBoxSizer( wxHORIZONTAL );
bSizer101->Add( 16, 0, 0, 0, 5 );
m_checkBoxMinimizeOnClose = new wxCheckBox( m_panelMain, wxID_ANY, wxT("M&inimize to system tray on close"), wxDefaultPosition, wxDefaultSize, 0 );
bSizer101->Add( m_checkBoxMinimizeOnClose, 0, wxALL, 5 );
bSizer69->Add( bSizer101, 1, wxEXPAND, 5 );
m_panelMain->SetSizer( bSizer69 );
m_panelMain->Layout();
bSizer69->Fit( m_panelMain );
bSizer63->Add( m_panelMain, 0, wxEXPAND, 5 );
m_panelTest2 = new wxPanel( m_scrolledWindow, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
wxBoxSizer* bSizer64;
bSizer64 = new wxBoxSizer( wxVERTICAL );
bSizer64->Add( 0, 14, 0, wxEXPAND, 5 );
m_staticText321 = new wxStaticText( m_panelTest2, wxID_ANY, wxT("Test panel 2 for future expansion"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticText321->Wrap( -1 );
bSizer64->Add( m_staticText321, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
m_treeCtrl = new wxTreeCtrl( this, wxID_ANY, wxDefaultPosition, wxSize( 100,-1 ), wxTR_HAS_BUTTONS|wxTR_HIDE_ROOT|wxTR_LINES_AT_ROOT );
panelSizer->Add( m_treeCtrl, 0, wxALL|wxEXPAND, 5 );
m_staticText69 = new wxStaticText( m_panelTest2, wxID_ANY, wxT("MyLabel"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticText69->Wrap( -1 );
bSizer64->Add( m_staticText69, 0, wxALL, 5 );
bSizer55->Add( panelSizer, 1, wxEXPAND, 5 );
m_staticText70 = new wxStaticText( m_panelTest2, wxID_ANY, wxT("MyLabel"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticText70->Wrap( -1 );
bSizer64->Add( m_staticText70, 0, wxALL, 5 );
m_staticline1 = new wxStaticLine( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL );
bSizer55->Add( m_staticline1, 0, wxEXPAND | wxALL, 5 );
m_staticText71 = new wxStaticText( m_panelTest2, wxID_ANY, wxT("MyLabel"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticText71->Wrap( -1 );
bSizer64->Add( m_staticText71, 0, wxALL, 5 );
m_panelTest2->SetSizer( bSizer64 );
m_panelTest2->Layout();
bSizer64->Fit( m_panelTest2 );
bSizer63->Add( m_panelTest2, 0, wxEXPAND, 5 );
m_scrolledWindow->SetSizer( bSizer63 );
m_scrolledWindow->Layout();
bSizer63->Fit( m_scrolledWindow );
bSizer66->Add( m_scrolledWindow, 1, wxEXPAND|wxLEFT, 5 );
bSizer55->Add( bSizer66, 1, wxEXPAND|wxALL, 9 );
wxBoxSizer* bSizer58;
bSizer58 = new wxBoxSizer( wxHORIZONTAL );
@ -374,9 +491,8 @@ COptionsDialogBase::COptionsDialogBase( wxWindow* parent, wxWindowID id, const w
bSizer58->Add( m_buttonCancel, 0, wxALL, 5 );
m_buttonApply = new wxButton( this, wxID_ANY, wxT("Apply"), wxDefaultPosition, wxDefaultSize, 0 );
m_buttonApply->Enable( false );
m_buttonApply->Hide();
m_buttonApply = new wxButton( this, wxID_APPLY, wxT("&Apply"), wxDefaultPosition, wxSize( -1,-1 ), 0 );
m_buttonApply->SetMinSize( wxSize( 85,25 ) );
bSizer58->Add( m_buttonApply, 0, wxALL, 5 );
@ -386,17 +502,25 @@ COptionsDialogBase::COptionsDialogBase( wxWindow* parent, wxWindowID id, const w
this->Layout();
// Connect Events
m_treeCtrl->Connect( wxEVT_COMMAND_TREE_SEL_CHANGED, wxTreeEventHandler( COptionsDialogBase::MenuSelChanged ), NULL, this );
m_listBox->Connect( wxEVT_COMMAND_LISTBOX_SELECTED, wxCommandEventHandler( COptionsDialogBase::OnListBox ), NULL, this );
m_textCtrlTransactionFee->Connect( wxEVT_KILL_FOCUS, wxFocusEventHandler( COptionsDialogBase::OnKillFocusTransactionFee ), NULL, this );
m_checkBoxLimitProcessors->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( COptionsDialogBase::OnCheckBoxLimitProcessors ), NULL, this );
m_checkBoxMinimizeToTray->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( COptionsDialogBase::OnCheckBoxMinimizeToTray ), NULL, this );
m_buttonOK->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( COptionsDialogBase::OnButtonOK ), NULL, this );
m_buttonCancel->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( COptionsDialogBase::OnButtonCancel ), NULL, this );
m_buttonApply->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( COptionsDialogBase::OnButtonApply ), NULL, this );
}
COptionsDialogBase::~COptionsDialogBase()
{
// Disconnect Events
m_treeCtrl->Disconnect( wxEVT_COMMAND_TREE_SEL_CHANGED, wxTreeEventHandler( COptionsDialogBase::MenuSelChanged ), NULL, this );
m_listBox->Disconnect( wxEVT_COMMAND_LISTBOX_SELECTED, wxCommandEventHandler( COptionsDialogBase::OnListBox ), NULL, this );
m_textCtrlTransactionFee->Disconnect( wxEVT_KILL_FOCUS, wxFocusEventHandler( COptionsDialogBase::OnKillFocusTransactionFee ), NULL, this );
m_checkBoxLimitProcessors->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( COptionsDialogBase::OnCheckBoxLimitProcessors ), NULL, this );
m_checkBoxMinimizeToTray->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( COptionsDialogBase::OnCheckBoxMinimizeToTray ), NULL, this );
m_buttonOK->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( COptionsDialogBase::OnButtonOK ), NULL, this );
m_buttonCancel->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( COptionsDialogBase::OnButtonCancel ), NULL, this );
m_buttonApply->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( COptionsDialogBase::OnButtonApply ), NULL, this );
}
CAboutDialogBase::CAboutDialogBase( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : wxDialog( parent, id, title, pos, size, style )
@ -1815,78 +1939,3 @@ CGetTextFromUserDialogBase::~CGetTextFromUserDialogBase()
m_buttonOK->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CGetTextFromUserDialogBase::OnButtonOK ), NULL, this );
m_buttonCancel->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CGetTextFromUserDialogBase::OnButtonCancel ), NULL, this );
}
COptionsPanelBitcoinBase::COptionsPanelBitcoinBase( wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style ) : wxPanel( parent, id, pos, size, style )
{
wxBoxSizer* bSizer62;
bSizer62 = new wxBoxSizer( wxVERTICAL );
bSizer62->Add( 0, 20, 0, wxEXPAND, 5 );
m_staticText32 = new wxStaticText( this, wxID_ANY, wxT("Optional transaction fee you give to the nodes that process your transactions."), wxDefaultPosition, wxDefaultSize, 0 );
m_staticText32->Wrap( -1 );
bSizer62->Add( m_staticText32, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
wxBoxSizer* bSizer56;
bSizer56 = new wxBoxSizer( wxHORIZONTAL );
m_staticText31 = new wxStaticText( this, wxID_ANY, wxT("Transaction fee:"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticText31->Wrap( -1 );
bSizer56->Add( m_staticText31, 0, wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxLEFT, 5 );
m_textCtrlTransactionFee = new wxTextCtrl( this, wxID_TRANSACTIONFEE, wxEmptyString, wxDefaultPosition, wxSize( 70,-1 ), 0 );
bSizer56->Add( m_textCtrlTransactionFee, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 );
bSizer62->Add( bSizer56, 0, wxEXPAND, 5 );
this->SetSizer( bSizer62 );
this->Layout();
bSizer62->Fit( this );
// Connect Events
m_textCtrlTransactionFee->Connect( wxEVT_KILL_FOCUS, wxFocusEventHandler( COptionsPanelBitcoinBase::OnKillFocusTransactionFee ), NULL, this );
}
COptionsPanelBitcoinBase::~COptionsPanelBitcoinBase()
{
// Disconnect Events
m_textCtrlTransactionFee->Disconnect( wxEVT_KILL_FOCUS, wxFocusEventHandler( COptionsPanelBitcoinBase::OnKillFocusTransactionFee ), NULL, this );
}
COptionsPanelUIBase::COptionsPanelUIBase( wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style ) : wxPanel( parent, id, pos, size, style )
{
wxBoxSizer* bSizer57;
bSizer57 = new wxBoxSizer( wxVERTICAL );
bSizer57->Add( 0, 20, 1, wxEXPAND, 5 );
m_checkMinToTray = new wxCheckBox( this, wxID_MINTOTRAY, wxT("Minimize to tray"), wxDefaultPosition, wxDefaultSize, 0 );
bSizer57->Add( m_checkMinToTray, 0, wxALL, 5 );
m_checkCloseToTray = new wxCheckBox( this, wxID_ANY, wxT("Close to tray"), wxDefaultPosition, wxDefaultSize, 0 );
bSizer57->Add( m_checkCloseToTray, 0, wxALL, 5 );
m_checkStartOnSysBoot = new wxCheckBox( this, wxID_ANY, wxT("Start with Windows"), wxDefaultPosition, wxDefaultSize, 0 );
bSizer57->Add( m_checkStartOnSysBoot, 0, wxALL, 5 );
m_checkAskBeforeClosing = new wxCheckBox( this, wxID_ANY, wxT("Ask before closing"), wxDefaultPosition, wxDefaultSize, 0 );
bSizer57->Add( m_checkAskBeforeClosing, 0, wxALL, 5 );
m_checkAlwaysShowTray = new wxCheckBox( this, wxID_ANY, wxT("Always show tray icon"), wxDefaultPosition, wxDefaultSize, 0 );
bSizer57->Add( m_checkAlwaysShowTray, 0, wxALL, 5 );
this->SetSizer( bSizer57 );
this->Layout();
bSizer57->Fit( this );
}
COptionsPanelUIBase::~COptionsPanelUIBase()
{
}

193
uibase.h

@ -30,69 +30,70 @@
#include <wx/frame.h>
#include <wx/html/htmlwin.h>
#include <wx/dialog.h>
#include <wx/treectrl.h>
#include <wx/statline.h>
#include <wx/listbox.h>
#include <wx/checkbox.h>
#include <wx/spinctrl.h>
#include <wx/scrolwin.h>
#include <wx/statbmp.h>
#include <wx/combobox.h>
#include <wx/scrolwin.h>
#include <wx/richtext/richtextctrl.h>
#include <wx/checkbox.h>
#include <wx/treectrl.h>
///////////////////////////////////////////////////////////////////////////
#define wxID_MAINFRAME 1000
#define wxID_OPTIONSGENERATEBITCOINS 1001
#define wxID_BUTTONSEND 1002
#define wxID_BUTTONRECEIVE 1003
#define wxID_TEXTCTRLADDRESS 1004
#define wxID_BUTTONCOPY 1005
#define wxID_BUTTONCHANGE 1006
#define wxID_TEXTCTRLPAYTO 1007
#define wxID_BUTTONPASTE 1008
#define wxID_BUTTONADDRESSBOOK 1009
#define wxID_TEXTCTRLAMOUNT 1010
#define wxID_CHOICETRANSFERTYPE 1011
#define wxID_LISTCTRL 1012
#define wxID_BUTTONRENAME 1013
#define wxID_BUTTONNEW 1014
#define wxID_BUTTONEDIT 1015
#define wxID_BUTTONDELETE 1016
#define wxID_DEL0 1017
#define wxID_DEL1 1018
#define wxID_DEL2 1019
#define wxID_DEL3 1020
#define wxID_DEL4 1021
#define wxID_DEL5 1022
#define wxID_DEL6 1023
#define wxID_DEL7 1024
#define wxID_DEL8 1025
#define wxID_DEL9 1026
#define wxID_DEL10 1027
#define wxID_DEL11 1028
#define wxID_DEL12 1029
#define wxID_DEL13 1030
#define wxID_DEL14 1031
#define wxID_DEL15 1032
#define wxID_DEL16 1033
#define wxID_DEL17 1034
#define wxID_DEL18 1035
#define wxID_DEL19 1036
#define wxID_BUTTONPREVIEW 1037
#define wxID_BUTTONSAMPLE 1038
#define wxID_CANCEL2 1039
#define wxID_BUTTONBACK 1040
#define wxID_BUTTONNEXT 1041
#define wxID_SUBMIT 1042
#define wxID_OPENNEWTABLE 1043
#define wxID_DEALHAND 1044
#define wxID_FOLD 1045
#define wxID_CALL 1046
#define wxID_RAISE 1047
#define wxID_LEAVETABLE 1048
#define wxID_DITCHPLAYER 1049
#define wxID_TEXTCTRL 1050
#define wxID_TRANSACTIONFEE 1051
#define wxID_MINTOTRAY 1052
#define wxID_VIEWSHOWGENERATED 1001
#define wxID_OPTIONSGENERATEBITCOINS 1002
#define wxID_BUTTONSEND 1003
#define wxID_BUTTONRECEIVE 1004
#define wxID_TEXTCTRLADDRESS 1005
#define wxID_BUTTONCOPY 1006
#define wxID_BUTTONCHANGE 1007
#define wxID_TRANSACTIONFEE 1008
#define wxID_TEXTCTRLPAYTO 1009
#define wxID_BUTTONPASTE 1010
#define wxID_BUTTONADDRESSBOOK 1011
#define wxID_TEXTCTRLAMOUNT 1012
#define wxID_CHOICETRANSFERTYPE 1013
#define wxID_LISTCTRL 1014
#define wxID_BUTTONRENAME 1015
#define wxID_BUTTONNEW 1016
#define wxID_BUTTONEDIT 1017
#define wxID_BUTTONDELETE 1018
#define wxID_DEL0 1019
#define wxID_DEL1 1020
#define wxID_DEL2 1021
#define wxID_DEL3 1022
#define wxID_DEL4 1023
#define wxID_DEL5 1024
#define wxID_DEL6 1025
#define wxID_DEL7 1026
#define wxID_DEL8 1027
#define wxID_DEL9 1028
#define wxID_DEL10 1029
#define wxID_DEL11 1030
#define wxID_DEL12 1031
#define wxID_DEL13 1032
#define wxID_DEL14 1033
#define wxID_DEL15 1034
#define wxID_DEL16 1035
#define wxID_DEL17 1036
#define wxID_DEL18 1037
#define wxID_DEL19 1038
#define wxID_BUTTONPREVIEW 1039
#define wxID_BUTTONSAMPLE 1040
#define wxID_CANCEL2 1041
#define wxID_BUTTONBACK 1042
#define wxID_BUTTONNEXT 1043
#define wxID_SUBMIT 1044
#define wxID_OPENNEWTABLE 1045
#define wxID_DEALHAND 1046
#define wxID_FOLD 1047
#define wxID_CALL 1048
#define wxID_RAISE 1049
#define wxID_LEAVETABLE 1050
#define wxID_DITCHPLAYER 1051
#define wxID_TEXTCTRL 1052
///////////////////////////////////////////////////////////////////////////////
/// Class CMainFrameBase
@ -104,6 +105,7 @@ class CMainFrameBase : public wxFrame
protected:
wxMenuBar* m_menubar;
wxMenu* m_menuFile;
wxMenu* m_menuView;
wxMenu* m_menuHelp;
wxToolBar* m_toolBar;
wxStatusBar* m_statusBar;
@ -132,8 +134,10 @@ class CMainFrameBase : public wxFrame
virtual void OnMouseEvents( wxMouseEvent& event ){ event.Skip(); }
virtual void OnPaint( wxPaintEvent& event ){ event.Skip(); }
virtual void OnMenuFileExit( wxCommandEvent& event ){ event.Skip(); }
virtual void OnMenuViewShowGenerated( wxCommandEvent& event ){ event.Skip(); }
virtual void OnUpdateUIViewShowGenerated( wxUpdateUIEvent& event ){ event.Skip(); }
virtual void OnMenuOptionsGenerate( wxCommandEvent& event ){ event.Skip(); }
virtual void OnUpdateMenuGenerate( wxUpdateUIEvent& event ){ event.Skip(); }
virtual void OnUpdateUIOptionsGenerate( wxUpdateUIEvent& event ){ event.Skip(); }
virtual void OnMenuOptionsChangeYourAddress( wxCommandEvent& event ){ event.Skip(); }
virtual void OnMenuOptionsOptions( wxCommandEvent& event ){ event.Skip(); }
virtual void OnMenuHelpAbout( wxCommandEvent& event ){ event.Skip(); }
@ -193,21 +197,42 @@ class COptionsDialogBase : public wxDialog
private:
protected:
wxBoxSizer* panelSizer;
wxTreeCtrl* m_treeCtrl;
wxStaticLine* m_staticline1;
wxListBox* m_listBox;
wxScrolledWindow* m_scrolledWindow;
wxPanel* m_panelMain;
wxStaticText* m_staticText32;
wxStaticText* m_staticText31;
wxTextCtrl* m_textCtrlTransactionFee;
wxCheckBox* m_checkBoxLimitProcessors;
wxSpinCtrl* m_spinCtrlLimitProcessors;
wxStaticText* m_staticText35;
wxCheckBox* m_checkBoxStartOnSystemStartup;
wxCheckBox* m_checkBoxMinimizeToTray;
wxCheckBox* m_checkBoxMinimizeOnClose;
wxPanel* m_panelTest2;
wxStaticText* m_staticText321;
wxStaticText* m_staticText69;
wxStaticText* m_staticText70;
wxStaticText* m_staticText71;
wxButton* m_buttonOK;
wxButton* m_buttonCancel;
wxButton* m_buttonApply;
// Virtual event handlers, overide them in your derived class
virtual void MenuSelChanged( wxTreeEvent& event ){ event.Skip(); }
virtual void OnListBox( wxCommandEvent& event ){ event.Skip(); }
virtual void OnKillFocusTransactionFee( wxFocusEvent& event ){ event.Skip(); }
virtual void OnCheckBoxLimitProcessors( wxCommandEvent& event ){ event.Skip(); }
virtual void OnCheckBoxMinimizeToTray( wxCommandEvent& event ){ event.Skip(); }
virtual void OnButtonOK( wxCommandEvent& event ){ event.Skip(); }
virtual void OnButtonCancel( wxCommandEvent& event ){ event.Skip(); }
virtual void OnButtonApply( wxCommandEvent& event ){ event.Skip(); }
public:
COptionsDialogBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxT("Options"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 555,377 ), long style = wxDEFAULT_DIALOG_STYLE );
COptionsDialogBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxT("Options"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 540,360 ), long style = wxDEFAULT_DIALOG_STYLE );
~COptionsDialogBase();
};
@ -720,48 +745,4 @@ class CGetTextFromUserDialogBase : public wxDialog
};
///////////////////////////////////////////////////////////////////////////////
/// Class COptionsPanelBitcoinBase
///////////////////////////////////////////////////////////////////////////////
class COptionsPanelBitcoinBase : public wxPanel
{
private:
protected:
wxStaticText* m_staticText32;
wxStaticText* m_staticText31;
// Virtual event handlers, overide them in your derived class
virtual void OnKillFocusTransactionFee( wxFocusEvent& event ){ event.Skip(); }
public:
wxTextCtrl* m_textCtrlTransactionFee;
COptionsPanelBitcoinBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxTAB_TRAVERSAL );
~COptionsPanelBitcoinBase();
};
///////////////////////////////////////////////////////////////////////////////
/// Class COptionsPanelUIBase
///////////////////////////////////////////////////////////////////////////////
class COptionsPanelUIBase : public wxPanel
{
private:
protected:
public:
wxCheckBox* m_checkMinToTray;
wxCheckBox* m_checkCloseToTray;
wxCheckBox* m_checkStartOnSysBoot;
wxCheckBox* m_checkAskBeforeClosing;
wxCheckBox* m_checkAlwaysShowTray;
COptionsPanelUIBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxTAB_TRAVERSAL );
~COptionsPanelUIBase();
};
#endif //__uibase__

1581
uiproject.fbp

File diff suppressed because it is too large

4
util.cpp

@ -86,7 +86,7 @@ void RandAddSeed(bool fPerfmon)
struct tm* ptmTime = gmtime(&nTime);
char pszTime[200];
strftime(pszTime, sizeof(pszTime), "%x %H:%M:%S", ptmTime);
printf("%s RandAddSeed() got %d bytes of performance data\n", pszTime, nSize);
printf("%s RandAddSeed() %d bytes\n", pszTime, nSize);
}
}
}
@ -174,7 +174,7 @@ bool error(const char* format, ...)
void PrintException(std::exception* pex, const char* pszThread)
{
char pszModule[260];
char pszModule[MAX_PATH];
pszModule[0] = '\0';
GetModuleFileName(NULL, pszModule, sizeof(pszModule));
_strlwr(pszModule);

Loading…
Cancel
Save