Compare commits

...

6 Commits

Author SHA1 Message Date
s_nakamoto
2d98de1b3a Mac OS build fixes by laszlo
-- version 0.2.8

git-svn-id: https://bitcoin.svn.sourceforge.net/svnroot/bitcoin/trunk@76 1a98c847-1fd6-4fd8-948a-caf3550aa51b
2010-05-19 00:26:56 +00:00
s_nakamoto
966cca4bd4 misc
git-svn-id: https://bitcoin.svn.sourceforge.net/svnroot/bitcoin/trunk@75 1a98c847-1fd6-4fd8-948a-caf3550aa51b
2010-03-05 02:55:09 +00:00
s_nakamoto
2cffa7ce31 fixed runaway memory alloc bug on 64-bit in ParseString found by sirius-m
git-svn-id: https://bitcoin.svn.sourceforge.net/svnroot/bitcoin/trunk@74 1a98c847-1fd6-4fd8-948a-caf3550aa51b
2010-03-05 01:13:27 +00:00
s_nakamoto
d7d80a74d5 fix unsafe string handling in wxGetTranslation
git-svn-id: https://bitcoin.svn.sourceforge.net/svnroot/bitcoin/trunk@73 1a98c847-1fd6-4fd8-948a-caf3550aa51b
2010-02-28 15:00:32 +00:00
s_nakamoto
6557910ccf wx/utils.h and wx/clipbrd.h not needed on bitcoind wxbase build
git-svn-id: https://bitcoin.svn.sourceforge.net/svnroot/bitcoin/trunk@72 1a98c847-1fd6-4fd8-948a-caf3550aa51b
2010-02-26 16:09:43 +00:00
s_nakamoto
c2430126d7 GUI-less build target bitcoind that links to wxBase and shouldn't need GTK,
split init and shutdown from ui.cpp into init.cpp,
support wxUSE_GUI=0
-- version 0.2.7

git-svn-id: https://bitcoin.svn.sourceforge.net/svnroot/bitcoin/trunk@71 1a98c847-1fd6-4fd8-948a-caf3550aa51b
2010-02-25 21:55:27 +00:00
20 changed files with 942 additions and 854 deletions

View File

@@ -19,11 +19,13 @@
#define WIN32_LEAN_AND_MEAN 1
#define __STDC_LIMIT_MACROS // to enable UINT64_MAX from stdint.h
#include <wx/wx.h>
#include <wx/clipbrd.h>
#include <wx/snglinst.h>
#include <wx/taskbar.h>
#include <wx/stdpaths.h>
#include <wx/snglinst.h>
#if wxUSE_GUI
#include <wx/utils.h>
#include <wx/clipbrd.h>
#include <wx/taskbar.h>
#endif
#include <openssl/ecdsa.h>
#include <openssl/evp.h>
#include <openssl/rand.h>
@@ -100,8 +102,11 @@ using namespace boost;
#include "irc.h"
#include "main.h"
#include "rpc.h"
#if wxUSE_GUI
#include "uibase.h"
#endif
#include "ui.h"
#include "init.h"
#include "xpm/addressbook16.xpm"
#include "xpm/addressbook20.xpm"

631
init.cpp Normal file
View File

@@ -0,0 +1,631 @@
// Copyright (c) 2009-2010 Satoshi Nakamoto
// Distributed under the MIT/X11 software license, see the accompanying
// file license.txt or http://www.opensource.org/licenses/mit-license.php.
#include "headers.h"
void ExitTimeout(void* parg)
{
#ifdef __WXMSW__
Sleep(5000);
ExitProcess(0);
#endif
}
void Shutdown(void* parg)
{
static CCriticalSection cs_Shutdown;
static bool fTaken;
bool fFirstThread;
CRITICAL_BLOCK(cs_Shutdown)
{
fFirstThread = !fTaken;
fTaken = true;
}
static bool fExit;
if (fFirstThread)
{
fShutdown = true;
nTransactionsUpdated++;
DBFlush(false);
StopNode();
DBFlush(true);
CreateThread(ExitTimeout, NULL);
Sleep(50);
printf("Bitcoin exiting\n\n");
fExit = true;
exit(0);
}
else
{
while (!fExit)
Sleep(500);
Sleep(100);
ExitThread(0);
}
}
//////////////////////////////////////////////////////////////////////////////
//
// Startup folder
//
#ifdef __WXMSW__
typedef WINSHELLAPI BOOL (WINAPI *PSHGETSPECIALFOLDERPATHA)(HWND hwndOwner, LPSTR lpszPath, int nFolder, BOOL fCreate);
string MyGetSpecialFolderPath(int nFolder, bool fCreate)
{
char pszPath[MAX_PATH+100] = "";
// SHGetSpecialFolderPath is not usually available on NT 4.0
HMODULE hShell32 = LoadLibraryA("shell32.dll");
if (hShell32)
{
PSHGETSPECIALFOLDERPATHA pSHGetSpecialFolderPath =
(PSHGETSPECIALFOLDERPATHA)GetProcAddress(hShell32, "SHGetSpecialFolderPathA");
if (pSHGetSpecialFolderPath)
(*pSHGetSpecialFolderPath)(NULL, pszPath, nFolder, fCreate);
FreeModule(hShell32);
}
// Backup option
if (pszPath[0] == '\0')
{
if (nFolder == CSIDL_STARTUP)
{
strcpy(pszPath, getenv("USERPROFILE"));
strcat(pszPath, "\\Start Menu\\Programs\\Startup");
}
else if (nFolder == CSIDL_APPDATA)
{
strcpy(pszPath, getenv("APPDATA"));
}
}
return pszPath;
}
string StartupShortcutPath()
{
return MyGetSpecialFolderPath(CSIDL_STARTUP, true) + "\\Bitcoin.lnk";
}
bool GetStartOnSystemStartup()
{
return wxFileExists(StartupShortcutPath());
}
void SetStartOnSystemStartup(bool fAutoStart)
{
// If the shortcut exists already, remove it for updating
remove(StartupShortcutPath().c_str());
if (fAutoStart)
{
CoInitialize(NULL);
// Get a pointer to the IShellLink interface.
IShellLink* psl = NULL;
HRESULT hres = CoCreateInstance(CLSID_ShellLink, NULL,
CLSCTX_INPROC_SERVER, IID_IShellLink,
reinterpret_cast<void**>(&psl));
if (SUCCEEDED(hres))
{
// Get the current executable path
TCHAR pszExePath[MAX_PATH];
GetModuleFileName(NULL, pszExePath, sizeof(pszExePath));
// Set the path to the shortcut target
psl->SetPath(pszExePath);
PathRemoveFileSpec(pszExePath);
psl->SetWorkingDirectory(pszExePath);
psl->SetShowCmd(SW_SHOWMINNOACTIVE);
// Query IShellLink for the IPersistFile interface for
// saving the shortcut in persistent storage.
IPersistFile* ppf = NULL;
hres = psl->QueryInterface(IID_IPersistFile,
reinterpret_cast<void**>(&ppf));
if (SUCCEEDED(hres))
{
WCHAR pwsz[MAX_PATH];
// Ensure that the string is ANSI.
MultiByteToWideChar(CP_ACP, 0, StartupShortcutPath().c_str(), -1, pwsz, MAX_PATH);
// Save the link by calling IPersistFile::Save.
hres = ppf->Save(pwsz, TRUE);
ppf->Release();
}
psl->Release();
}
CoUninitialize();
}
}
#else
bool GetStartOnSystemStartup() { return false; }
void SetStartOnSystemStartup(bool fAutoStart) { }
#endif
//////////////////////////////////////////////////////////////////////////////
//
// CMyApp
//
// Define a new application
class CMyApp: public wxApp
{
public:
wxLocale m_locale;
CMyApp(){};
~CMyApp(){};
bool OnInit();
bool OnInit2();
int OnExit();
// Hook Initialize so we can start without GUI
virtual bool Initialize(int& argc, wxChar** argv);
// 2nd-level exception handling: we get all the exceptions occurring in any
// event handler here
virtual bool OnExceptionInMainLoop();
// 3rd, and final, level exception handling: whenever an unhandled
// exception is caught, this function is called
virtual void OnUnhandledException();
// and now for something different: this function is called in case of a
// crash (e.g. dereferencing null pointer, division by 0, ...)
virtual void OnFatalException();
};
IMPLEMENT_APP(CMyApp)
bool CMyApp::Initialize(int& argc, wxChar** argv)
{
if (argc > 1 && argv[1][0] != '-' && (!fWindows || argv[1][0] != '/') &&
wxString(argv[1]) != "start")
{
fCommandLine = true;
}
else if (!fGUI)
{
fDaemon = true;
}
else
{
// wxApp::Initialize will remove environment-specific parameters,
// so it's too early to call ParseParameters yet
for (int i = 1; i < argc; i++)
{
wxString str = argv[i];
#ifdef __WXMSW__
if (str.size() >= 1 && str[0] == '/')
str[0] = '-';
str = str.MakeLower();
#endif
// haven't decided which argument to use for this yet
if (str == "-daemon" || str == "-d" || str == "start")
fDaemon = true;
}
}
if (fDaemon)
fprintf(stdout, "bitcoin server starting\n");
#ifdef __WXGTK__
if (fDaemon || fCommandLine)
{
// Call the original Initialize while suppressing error messages
// and ignoring failure. If unable to initialize GTK, it fails
// near the end so hopefully the last few things don't matter.
{
wxLogNull logNo;
wxApp::Initialize(argc, argv);
}
if (fDaemon)
{
// Daemonize
pid_t pid = fork();
if (pid < 0)
{
fprintf(stderr, "Error: fork() returned %d errno %d\n", pid, errno);
return false;
}
if (pid > 0)
pthread_exit((void*)0);
}
return true;
}
#endif
return wxApp::Initialize(argc, argv);
}
bool CMyApp::OnInit()
{
bool fRet = false;
try
{
fRet = OnInit2();
}
catch (std::exception& e) {
PrintException(&e, "OnInit()");
} catch (...) {
PrintException(NULL, "OnInit()");
}
if (!fRet)
Shutdown(NULL);
return fRet;
}
extern int g_isPainting;
bool CMyApp::OnInit2()
{
#ifdef _MSC_VER
// Turn off microsoft heap dump noise
_CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE);
_CrtSetReportFile(_CRT_WARN, CreateFileA("NUL", GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0));
#endif
#if _MSC_VER >= 1400
// Disable confusing "helpful" text message on abort, ctrl-c
_set_abort_behavior(0, _WRITE_ABORT_MSG | _CALL_REPORTFAULT);
#endif
#if defined(__WXMSW__) && defined(__WXDEBUG__) && wxUSE_GUI
// Disable malfunctioning wxWidgets debug assertion
g_isPainting = 10000;
#endif
#if wxUSE_GUI
wxImage::AddHandler(new wxPNGHandler);
#endif
#if defined(__WXMSW__ ) || defined(__WXMAC__)
SetAppName("Bitcoin");
#else
SetAppName("bitcoin");
#endif
#ifndef __WXMSW__
umask(077);
#endif
#ifdef __WXMSW__
#if wxUSE_UNICODE
// Hack to set wxConvLibc codepage to UTF-8 on Windows,
// may break if wxMBConv_win32 implementation in strconv.cpp changes.
class wxMBConv_win32 : public wxMBConv
{
public:
long m_CodePage;
size_t m_minMBCharWidth;
};
if (((wxMBConv_win32*)&wxConvLibc)->m_CodePage == CP_ACP)
((wxMBConv_win32*)&wxConvLibc)->m_CodePage = CP_UTF8;
#endif
#endif
// Load locale/<lang>/LC_MESSAGES/bitcoin.mo language file
m_locale.Init(wxLANGUAGE_DEFAULT, 0);
m_locale.AddCatalogLookupPathPrefix("locale");
if (!fWindows)
{
m_locale.AddCatalogLookupPathPrefix("/usr/share/locale");
m_locale.AddCatalogLookupPathPrefix("/usr/local/share/locale");
}
m_locale.AddCatalog("wxstd"); // wxWidgets standard translations, if any
m_locale.AddCatalog("bitcoin");
//
// Parameters
//
if (fCommandLine)
{
int ret = CommandLineRPC(argc, argv);
exit(ret);
}
ParseParameters(argc, argv);
if (mapArgs.count("-?") || mapArgs.count("--help"))
{
wxString strUsage = string() +
_("Usage: bitcoin [options]") + "\t\t\t\t\t\t\n" +
_("Options:\n") +
" -gen \t\t " + _("Generate coins\n") +
" -gen=0 \t\t " + _("Don't generate coins\n") +
" -min \t\t " + _("Start minimized\n") +
" -datadir=<dir> \t " + _("Specify data directory\n") +
" -proxy=<ip:port>\t " + _("Connect through socks4 proxy\n") +
" -addnode=<ip> \t " + _("Add a node to connect to\n") +
" -connect=<ip> \t " + _("Connect only to the specified node\n") +
" -? \t\t " + _("This help message\n");
if (fWindows && fGUI)
{
// Remove spaces, the tabs make the columns line up in the message box
for (int i = 0; i < 50; i++)
strUsage.Replace(" \t", "\t");
wxMessageBox(strUsage, "Bitcoin", wxOK);
}
else
{
// Remove tabs
strUsage.Replace("\t", "");
fprintf(stderr, "%s", ((string)strUsage).c_str());
}
return false;
}
if (mapArgs.count("-datadir"))
strlcpy(pszSetDataDir, mapArgs["-datadir"].c_str(), sizeof(pszSetDataDir));
if (mapArgs.count("-debug"))
fDebug = true;
if (mapArgs.count("-printtodebugger"))
fPrintToDebugger = true;
if (!fDebug && !pszSetDataDir[0])
ShrinkDebugFile();
printf("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n");
printf("Bitcoin version 0.%d.%d%s beta, OS version %s\n", VERSION/100, VERSION%100, pszSubVer, ((string)wxGetOsDescription()).c_str());
printf("System default language is %d %s\n", m_locale.GetSystemLanguage(), ((string)m_locale.GetSysName()).c_str());
printf("Language file %s (%s)\n", (string("locale/") + (string)m_locale.GetCanonicalName() + "/LC_MESSAGES/bitcoin.mo").c_str(), ((string)m_locale.GetLocale()).c_str());
if (mapArgs.count("-loadblockindextest"))
{
CTxDB txdb("r");
txdb.LoadBlockIndex();
PrintBlockTree();
return false;
}
//
// Limit to single instance per user
// Required to protect the database files if we're going to keep deleting log.*
//
#ifdef __WXMSW__
// todo: wxSingleInstanceChecker wasn't working on Linux, never deleted its lock file
// maybe should go by whether successfully bind port 8333 instead
wxString strMutexName = wxString("bitcoin_running.") + getenv("HOMEPATH");
for (int i = 0; i < strMutexName.size(); i++)
if (!isalnum(strMutexName[i]))
strMutexName[i] = '.';
wxSingleInstanceChecker* psingleinstancechecker = new wxSingleInstanceChecker(strMutexName);
if (psingleinstancechecker->IsAnotherRunning())
{
printf("Existing instance found\n");
unsigned int nStart = GetTime();
loop
{
// TODO: find out how to do this in Linux, or replace with wxWidgets commands
// Show the previous instance and exit
HWND hwndPrev = FindWindowA("wxWindowClassNR", "Bitcoin");
if (hwndPrev)
{
if (IsIconic(hwndPrev))
ShowWindow(hwndPrev, SW_RESTORE);
SetForegroundWindow(hwndPrev);
return false;
}
if (GetTime() > nStart + 60)
return false;
// Resume this instance if the other exits
delete psingleinstancechecker;
Sleep(1000);
psingleinstancechecker = new wxSingleInstanceChecker(strMutexName);
if (!psingleinstancechecker->IsAnotherRunning())
break;
}
}
#endif
// Bind to the port early so we can tell if another instance is already running.
// This is a backup to wxSingleInstanceChecker, which doesn't work on Linux.
string strErrors;
if (!BindListenPort(strErrors))
{
wxMessageBox(strErrors, "Bitcoin");
return false;
}
//
// Load data files
//
bool fFirstRun;
strErrors = "";
int64 nStart;
printf("Loading addresses...\n");
nStart = GetTimeMillis();
if (!LoadAddresses())
strErrors += _("Error loading addr.dat \n");
printf(" addresses %15"PRI64d"ms\n", GetTimeMillis() - nStart);
printf("Loading block index...\n");
nStart = GetTimeMillis();
if (!LoadBlockIndex())
strErrors += _("Error loading blkindex.dat \n");
printf(" block index %15"PRI64d"ms\n", GetTimeMillis() - nStart);
printf("Loading wallet...\n");
nStart = GetTimeMillis();
if (!LoadWallet(fFirstRun))
strErrors += _("Error loading wallet.dat \n");
printf(" wallet %15"PRI64d"ms\n", GetTimeMillis() - nStart);
printf("Done loading\n");
//// debug print
printf("mapBlockIndex.size() = %d\n", mapBlockIndex.size());
printf("nBestHeight = %d\n", nBestHeight);
printf("mapKeys.size() = %d\n", mapKeys.size());
printf("mapPubKeys.size() = %d\n", mapPubKeys.size());
printf("mapWallet.size() = %d\n", mapWallet.size());
printf("mapAddressBook.size() = %d\n", mapAddressBook.size());
if (!strErrors.empty())
{
wxMessageBox(strErrors, "Bitcoin");
return false;
}
// Add wallet transactions that aren't already in a block to mapTransactions
ReacceptWalletTransactions();
//
// Parameters
//
if (mapArgs.count("-printblockindex") || mapArgs.count("-printblocktree"))
{
PrintBlockTree();
return false;
}
if (mapArgs.count("-printblock"))
{
string strMatch = mapArgs["-printblock"];
int nFound = 0;
for (map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.begin(); mi != mapBlockIndex.end(); ++mi)
{
uint256 hash = (*mi).first;
if (strncmp(hash.ToString().c_str(), strMatch.c_str(), strMatch.size()) == 0)
{
CBlockIndex* pindex = (*mi).second;
CBlock block;
block.ReadFromDisk(pindex);
block.BuildMerkleTree();
block.print();
printf("\n");
nFound++;
}
}
if (nFound == 0)
printf("No blocks matching %s were found\n", strMatch.c_str());
return false;
}
if (mapArgs.count("-gen"))
{
if (mapArgs["-gen"].empty())
fGenerateBitcoins = true;
else
fGenerateBitcoins = (atoi(mapArgs["-gen"].c_str()) != 0);
}
if (mapArgs.count("-proxy"))
{
fUseProxy = true;
addrProxy = CAddress(mapArgs["-proxy"]);
if (!addrProxy.IsValid())
{
wxMessageBox(_("Invalid -proxy address"), "Bitcoin");
return false;
}
}
if (mapArgs.count("-addnode"))
{
foreach(string strAddr, mapMultiArgs["-addnode"])
{
CAddress addr(strAddr, NODE_NETWORK);
addr.nTime = 0; // so it won't relay unless successfully connected
if (addr.IsValid())
AddAddress(addr);
}
}
//
// Create the main window and start the node
//
if (!fDaemon)
CreateMainWindow();
if (!CheckDiskSpace())
return false;
RandAddSeedPerfmon();
if (!CreateThread(StartNode, NULL))
wxMessageBox("Error: CreateThread(StartNode) failed", "Bitcoin");
if (mapArgs.count("-server") || fDaemon)
CreateThread(ThreadRPCServer, NULL);
if (fFirstRun)
SetStartOnSystemStartup(true);
return true;
}
int CMyApp::OnExit()
{
Shutdown(NULL);
return wxApp::OnExit();
}
bool CMyApp::OnExceptionInMainLoop()
{
try
{
throw;
}
catch (std::exception& e)
{
PrintException(&e, "CMyApp::OnExceptionInMainLoop()");
wxLogWarning("Exception %s %s", typeid(e).name(), e.what());
Sleep(1000);
throw;
}
catch (...)
{
PrintException(NULL, "CMyApp::OnExceptionInMainLoop()");
wxLogWarning("Unknown exception");
Sleep(1000);
throw;
}
return true;
}
void CMyApp::OnUnhandledException()
{
// this shows how we may let some exception propagate uncaught
try
{
throw;
}
catch (std::exception& e)
{
PrintException(&e, "CMyApp::OnUnhandledException()");
wxLogWarning("Exception %s %s", typeid(e).name(), e.what());
Sleep(1000);
throw;
}
catch (...)
{
PrintException(NULL, "CMyApp::OnUnhandledException()");
wxLogWarning("Unknown exception");
Sleep(1000);
throw;
}
}
void CMyApp::OnFatalException()
{
wxMessageBox(_("Program has crashed and will terminate. "), "Bitcoin", wxOK | wxICON_ERROR);
}

7
init.h Normal file
View File

@@ -0,0 +1,7 @@
// Copyright (c) 2009-2010 Satoshi Nakamoto
// Distributed under the MIT/X11 software license, see the accompanying
// file license.txt or http://www.opensource.org/licenses/mit-license.php.
void Shutdown(void* parg);
bool GetStartOnSystemStartup();
void SetStartOnSystemStartup(bool fAutoStart);

View File

@@ -76,6 +76,8 @@ bool RecvLine(SOCKET hSocket, string& strLine)
if (c == '\r')
return true;
strLine += c;
if (strLine.size() >= 9000)
return true;
}
else if (nBytes <= 0)
{
@@ -109,7 +111,7 @@ bool RecvLineIRC(SOCKET hSocket, string& strLine)
return false;
vector<string> vWords;
ParseString(strLine, ' ', vWords);
if (vWords[0] == "PING")
if (vWords.size() >= 1 && vWords[0] == "PING")
{
strLine[1] = 'O';
strLine += '\r';
@@ -156,6 +158,7 @@ bool Wait(int nSeconds)
void ThreadIRCSeed(void* parg)
{
printf("ThreadIRCSeed started\n");
SetThreadPriority(THREAD_PRIORITY_NORMAL);
int nErrorWait = 10;
int nRetryWait = 10;

View File

@@ -55,6 +55,8 @@ int64 nTransactionFee = 0;
CAddress addrIncoming;
int fLimitProcessors = false;
int nLimitProcessors = 1;
int fMinimizeToTray = true;
int fMinimizeOnClose = true;
@@ -1336,7 +1338,7 @@ bool CBlock::AcceptBlock()
// Don't relay old inventory during initial block download.
// Please keep this number updated to a few thousand below current block count.
if (hashBestChain == hash && nBestHeight > 40000)
if (hashBestChain == hash && nBestHeight > 55000)
RelayInventory(CInv(MSG_BLOCK, hash));
// // Add atoms to user reviews for coins created
@@ -2253,9 +2255,9 @@ bool SendMessages(CNode* pto)
// Delay tx inv messages to protect privacy,
// trickle them out to a few nodes at a time.
bool fSendTxInv = false;
if (GetTimeMillis() - pto->nLastSentTxInv > 1800 + GetRand(200))
if (GetTimeMillis() > pto->nNextSendTxInv)
{
pto->nLastSentTxInv = GetTimeMillis();
pto->nNextSendTxInv = GetTimeMillis() + 3000 + GetRand(2000);
fSendTxInv = true;
}
@@ -2990,7 +2992,7 @@ string SendMoneyToBitcoinAddress(string strAddress, int64 nValue, CWalletTx& wtx
if (nValue <= 0)
return _("Invalid amount");
if (nValue + nTransactionFee > GetBalance())
return _("You don't have enough money");
return _("Insufficient funds");
// Parse bitcoin address
CScript scriptPubKey;

2
main.h
View File

@@ -45,6 +45,8 @@ extern int64 nTransactionFee;
extern CAddress addrIncoming;
extern int fLimitProcessors;
extern int nLimitProcessors;
extern int fMinimizeToTray;
extern int fMinimizeOnClose;

View File

@@ -18,69 +18,59 @@ LIBPATHS= \
-L"/openssl/out" \
-L"/wxwidgets/lib/gcc_lib"
WXLIBS= \
-l wxmsw29ud_html -l wxmsw29ud_core -l wxmsw29ud_adv -l wxbase29ud -l wxtiffd -l wxjpegd -l wxpngd -l wxzlibd
LIBS= \
-l libboost_system-mgw34-mt-d -l libboost_filesystem-mgw34-mt-d \
-l db_cxx \
-l eay32 \
-l wxmsw29ud_html -l wxmsw29ud_core -l wxmsw29ud_adv -l wxbase29ud -l wxtiffd -l wxjpegd -l wxpngd -l wxzlibd \
-l kernel32 -l user32 -l gdi32 -l comdlg32 -l winspool -l winmm -l shell32 -l comctl32 -l ole32 -l oleaut32 -l uuid -l rpcrt4 -l advapi32 -l ws2_32 -l shlwapi
WXDEFS=-DWIN32 -D__WXMSW__ -D_WINDOWS -DNOPCH
DEBUGFLAGS=-g -D__WXDEBUG__
CFLAGS=-mthreads -O0 -w -Wno-invalid-offsetof -Wformat $(DEBUGFLAGS) $(WXDEFS) $(INCLUDEPATHS)
HEADERS=headers.h strlcpy.h serialize.h uint256.h util.h key.h bignum.h base58.h script.h db.h net.h irc.h main.h rpc.h uibase.h ui.h
HEADERS=headers.h strlcpy.h serialize.h uint256.h util.h key.h bignum.h base58.h \
script.h db.h net.h irc.h main.h rpc.h uibase.h ui.h init.h sha.h
all: bitcoin.exe
headers.h.gch: headers.h $(HEADERS)
headers.h.gch: headers.h $(HEADERS)
g++ -c $(CFLAGS) -o $@ $<
obj/util.o: util.cpp $(HEADERS)
obj/%.o: %.cpp $(HEADERS) headers.h.gch
g++ -c $(CFLAGS) -o $@ $<
obj/script.o: script.cpp $(HEADERS)
g++ -c $(CFLAGS) -o $@ $<
obj/db.o: db.cpp $(HEADERS)
g++ -c $(CFLAGS) -o $@ $<
obj/net.o: net.cpp $(HEADERS)
g++ -c $(CFLAGS) -o $@ $<
obj/main.o: main.cpp $(HEADERS) sha.h
g++ -c $(CFLAGS) -o $@ $<
obj/ui.o: ui.cpp $(HEADERS)
g++ -c $(CFLAGS) -o $@ $<
obj/uibase.o: uibase.cpp uibase.h
g++ -c $(CFLAGS) -o $@ $<
obj/sha.o: sha.cpp sha.h
obj/sha.o: sha.cpp sha.h
g++ -c $(CFLAGS) -O3 -o $@ $<
obj/irc.o: irc.cpp $(HEADERS)
g++ -c $(CFLAGS) -o $@ $<
obj/rpc.o: rpc.cpp $(HEADERS)
g++ -c $(CFLAGS) -o $@ $<
obj/ui_res.o: ui.rc rc/bitcoin.ico rc/check.ico rc/send16.bmp rc/send16mask.bmp rc/send16masknoshadow.bmp rc/send20.bmp rc/send20mask.bmp rc/addressbook16.bmp rc/addressbook16mask.bmp rc/addressbook20.bmp rc/addressbook20mask.bmp
windres $(WXDEFS) $(INCLUDEPATHS) -o $@ -i $<
OBJS= \
obj/util.o \
obj/script.o \
obj/db.o \
obj/net.o \
obj/irc.o \
obj/main.o \
obj/rpc.o \
obj/init.o
bitcoin.exe: $(OBJS) obj/ui.o obj/uibase.o obj/sha.o obj/ui_res.o
g++ $(CFLAGS) -mwindows -Wl,--subsystem,windows -o $@ $(LIBPATHS) $^ $(WXLIBS) $(LIBS)
OBJS=obj/util.o obj/script.o obj/db.o obj/net.o obj/main.o \
obj/ui.o obj/uibase.o obj/sha.o obj/irc.o obj/rpc.o \
obj/ui_res.o
obj/nogui/%.o: %.cpp $(HEADERS)
g++ -c $(CFLAGS) -DwxUSE_GUI=0 -o $@ $<
bitcoind.exe: $(OBJS:obj/%=obj/nogui/%) obj/sha.o obj/ui_res.o
g++ $(CFLAGS) -o $@ $(LIBPATHS) $^ -l wxbase29ud $(LIBS)
bitcoin.exe: headers.h.gch $(OBJS)
-kill /f bitcoin.exe
g++ $(CFLAGS) -mwindows -Wl,--subsystem,windows -o $@ $(LIBPATHS) $(OBJS) $(LIBS)
clean:
-del /Q obj\*
-del /Q obj\nogui\*
-del /Q headers.h.gch

View File

@@ -13,66 +13,61 @@ LIBPATHS= \
-L"/usr/lib" \
-L"/usr/local/lib"
WXLIBS= \
-Wl,-Bstatic \
-l wx_gtk2ud-2.9 \
-Wl,-Bdynamic \
-l gtk-x11-2.0 -l SM
LIBS= \
-Wl,-Bstatic \
-l boost_system-mt -l boost_filesystem-mt \
-l db_cxx \
-l wx_gtk2ud-2.9 \
-Wl,-Bdynamic \
-l crypto \
-l gtk-x11-2.0 -l gthread-2.0 -l SM
-l gthread-2.0
WXDEFS=-D__WXGTK__ -DNOPCH
DEBUGFLAGS=-g -D__WXDEBUG__
CFLAGS=-O0 -Wno-invalid-offsetof -Wformat $(DEBUGFLAGS) $(WXDEFS) $(INCLUDEPATHS)
HEADERS=headers.h strlcpy.h serialize.h uint256.h util.h key.h bignum.h base58.h script.h db.h net.h irc.h main.h rpc.h uibase.h ui.h
HEADERS=headers.h strlcpy.h serialize.h uint256.h util.h key.h bignum.h base58.h \
script.h db.h net.h irc.h main.h rpc.h uibase.h ui.h init.h sha.h
all: bitcoin
headers.h.gch: headers.h $(HEADERS)
headers.h.gch: headers.h $(HEADERS)
g++ -c $(CFLAGS) -o $@ $<
obj/util.o: util.cpp $(HEADERS)
obj/%.o: %.cpp $(HEADERS) headers.h.gch
g++ -c $(CFLAGS) -o $@ $<
obj/script.o: script.cpp $(HEADERS)
g++ -c $(CFLAGS) -o $@ $<
obj/db.o: db.cpp $(HEADERS)
g++ -c $(CFLAGS) -o $@ $<
obj/net.o: net.cpp $(HEADERS)
g++ -c $(CFLAGS) -o $@ $<
obj/main.o: main.cpp $(HEADERS) sha.h
g++ -c $(CFLAGS) -o $@ $<
obj/ui.o: ui.cpp $(HEADERS)
g++ -c $(CFLAGS) -o $@ $<
obj/uibase.o: uibase.cpp uibase.h
g++ -c $(CFLAGS) -o $@ $<
obj/sha.o: sha.cpp sha.h
obj/sha.o: sha.cpp sha.h
g++ -c $(CFLAGS) -O3 -o $@ $<
obj/irc.o: irc.cpp $(HEADERS)
g++ -c $(CFLAGS) -o $@ $<
OBJS= \
obj/util.o \
obj/script.o \
obj/db.o \
obj/net.o \
obj/irc.o \
obj/main.o \
obj/rpc.o \
obj/init.o
obj/rpc.o: rpc.cpp $(HEADERS)
g++ -c $(CFLAGS) -o $@ $<
bitcoin: $(OBJS) obj/ui.o obj/uibase.o obj/sha.o
g++ $(CFLAGS) -o $@ $(LIBPATHS) $^ $(WXLIBS) $(LIBS)
obj/nogui/%.o: %.cpp $(HEADERS)
g++ -c $(CFLAGS) -DwxUSE_GUI=0 -o $@ $<
OBJS=obj/util.o obj/script.o obj/db.o obj/net.o obj/main.o \
obj/ui.o obj/uibase.o obj/sha.o obj/irc.o obj/rpc.o
bitcoind: $(OBJS:obj/%=obj/nogui/%) obj/sha.o
g++ $(CFLAGS) -o $@ $(LIBPATHS) $^ -l wx_baseud-2.9 $(LIBS)
bitcoin: headers.h.gch $(OBJS)
g++ $(CFLAGS) -o $@ $(LIBPATHS) $(OBJS) $(LIBS)
clean:
-rm obj/*
-rm obj/nogui/*
-rm headers.h.gch

View File

@@ -28,56 +28,79 @@ LIBS= \
WXDEFS=/DWIN32 /D__WXMSW__ /D_WINDOWS /DNOPCH
DEBUGFLAGS=/Zi /Od /D__WXDEBUG__
CFLAGS=/c /nologo /Ob0 /MDd /EHsc /GR /Zm300 $(DEBUGFLAGS) $(WXDEFS) $(INCLUDEPATHS)
HEADERS=headers.h strlcpy.h serialize.h uint256.h util.h key.h bignum.h base58.h script.h db.h net.h irc.h main.h rpc.h uibase.h ui.h
HEADERS=headers.h strlcpy.h serialize.h uint256.h util.h key.h bignum.h base58.h \
script.h db.h net.h irc.h main.h rpc.h uibase.h ui.h init.h sha.h
all: bitcoin.exe
obj\util.obj: util.cpp $(HEADERS)
.cpp{obj}.obj:
cl $(CFLAGS) /Fo$@ %s
obj\script.obj: script.cpp $(HEADERS)
cl $(CFLAGS) /Fo$@ %s
obj\util.obj: $(HEADERS)
obj\db.obj: db.cpp $(HEADERS)
cl $(CFLAGS) /Fo$@ %s
obj\script.obj: $(HEADERS)
obj\net.obj: net.cpp $(HEADERS)
cl $(CFLAGS) /Fo$@ %s
obj\db.obj: $(HEADERS)
obj\main.obj: main.cpp $(HEADERS) sha.h
cl $(CFLAGS) /Fo$@ %s
obj\net.obj: $(HEADERS)
obj\ui.obj: ui.cpp $(HEADERS)
cl $(CFLAGS) /Fo$@ %s
obj\irc.obj: $(HEADERS)
obj\uibase.obj: uibase.cpp uibase.h
cl $(CFLAGS) /Fo$@ %s
obj\main.obj: $(HEADERS)
obj\sha.obj: sha.cpp sha.h
obj\rpc.obj: $(HEADERS)
obj\init.obj: $(HEADERS)
obj\ui.obj: $(HEADERS)
obj\uibase.obj: $(HEADERS)
obj\sha.obj: sha.cpp sha.h
cl $(CFLAGS) /O2 /Fo$@ %s
obj\irc.obj: irc.cpp $(HEADERS)
cl $(CFLAGS) /Fo$@ %s
obj\rpc.obj: rpc.cpp $(HEADERS)
cl $(CFLAGS) /Fo$@ %s
obj\ui.res: ui.rc rc/bitcoin.ico rc/check.ico rc/send16.bmp rc/send16mask.bmp rc/send16masknoshadow.bmp rc/send20.bmp rc/send20mask.bmp rc/addressbook16.bmp rc/addressbook16mask.bmp rc/addressbook20.bmp rc/addressbook20mask.bmp
rc $(INCLUDEPATHS) $(WXDEFS) /Fo$@ %s
OBJS= \
obj\util.obj \
obj\script.obj \
obj\db.obj \
obj\net.obj \
obj\irc.obj \
obj\main.obj \
obj\rpc.obj \
obj\init.obj
OBJS=obj\util.obj obj\script.obj obj\db.obj obj\net.obj obj\main.obj \
obj\ui.obj obj\uibase.obj obj\sha.obj obj\irc.obj obj\rpc.obj \
obj\ui.res
bitcoin.exe: $(OBJS)
-kill /f bitcoin.exe & sleep 1
bitcoin.exe: $(OBJS) obj\ui.obj obj\uibase.obj obj\sha.obj obj\ui.res
link /nologo /DEBUG /SUBSYSTEM:WINDOWS /OUT:$@ $(LIBPATHS) $** $(LIBS)
.cpp{obj\nogui}.obj:
cl $(CFLAGS) /DwxUSE_GUI=0 /Fo$@ %s
obj\nogui\util.obj: $(HEADERS)
obj\nogui\script.obj: $(HEADERS)
obj\nogui\db.obj: $(HEADERS)
obj\nogui\net.obj: $(HEADERS)
obj\nogui\irc.obj: $(HEADERS)
obj\nogui\main.obj: $(HEADERS)
obj\nogui\rpc.obj: $(HEADERS)
obj\nogui\init.obj: $(HEADERS)
bitcoind.exe: $(OBJS:obj\=obj\nogui\) obj\sha.obj obj\ui.res
link /nologo /DEBUG /OUT:$@ $(LIBPATHS) $** $(LIBS)
clean:
-del /Q obj\*
-del *.ilk

View File

@@ -927,9 +927,7 @@ void ThreadOpenConnections2(void* parg)
continue;
// Only try the old stuff if we don't have enough connections
if (vNodes.size() >= 2 && nSinceLastSeen > 7 * 24 * 60 * 60)
continue;
if (vNodes.size() >= 5 && nSinceLastSeen > 24 * 60 * 60)
if (vNodes.size() >= 8 && nSinceLastSeen > 24 * 60 * 60)
continue;
// If multiple addresses are ready, prioritize by time since

43
net.h
View File

@@ -45,6 +45,7 @@ bool StopNode();
// (4) message start
// (12) command
// (4) size
// (4) checksum
// The message start string is designed to be unlikely to occur in normal data.
// The characters are rarely used upper ascii, not valid as UTF-8, and produce
@@ -58,6 +59,7 @@ public:
char pchMessageStart[sizeof(::pchMessageStart)];
char pchCommand[COMMAND_SIZE];
unsigned int nMessageSize;
//unsigned int nChecksum;
CMessageHeader()
{
@@ -65,6 +67,7 @@ public:
memset(pchCommand, 0, sizeof(pchCommand));
pchCommand[1] = 1;
nMessageSize = -1;
//nChecksum = 0;
}
CMessageHeader(const char* pszCommand, unsigned int nMessageSizeIn)
@@ -79,6 +82,8 @@ public:
READWRITE(FLATDATA(pchMessageStart));
READWRITE(FLATDATA(pchCommand));
READWRITE(nMessageSize);
//if (nVersion >= 209 && GetCommand() != "version")
// READWRITE(nChecksum);
)
string GetCommand()
@@ -484,7 +489,8 @@ public:
int64 nLastRecv;
int64 nLastSendEmpty;
int64 nTimeConnected;
unsigned int nPushPos;
unsigned int nHeaderStart;
unsigned int nMessageStart;
CAddress addr;
int nVersion;
bool fClient;
@@ -512,7 +518,7 @@ public:
vector<CInv> vInventoryToSend;
CCriticalSection cs_inventory;
multimap<int64, CInv> mapAskFor;
int64 nLastSentTxInv;
int64 nNextSendTxInv;
// publish and subscription
vector<char> vfSubscribe;
@@ -528,7 +534,8 @@ public:
nLastRecv = 0;
nLastSendEmpty = GetTime();
nTimeConnected = GetTime();
nPushPos = -1;
nHeaderStart = -1;
nMessageStart = -1;
addr = addrIn;
nVersion = 0;
fClient = false; // set by version message
@@ -542,6 +549,7 @@ public:
pindexLastGetBlocksBegin = 0;
hashLastGetBlocksEnd = 0;
fGetAddr = false;
nNextSendTxInv = 0;
vfSubscribe.assign(256, false);
// Push a version message
@@ -639,10 +647,11 @@ public:
void BeginMessage(const char* pszCommand)
{
cs_vSend.Enter();
if (nPushPos != -1)
if (nHeaderStart != -1)
AbortMessage();
nPushPos = vSend.size();
nHeaderStart = vSend.size();
vSend << CMessageHeader(pszCommand, 0);
nMessageStart = vSend.size();
if (fDebug)
printf("%s ", DateTimeStrFormat("%x %H:%M:%S", GetTime()).c_str());
printf("sending: %s ", pszCommand);
@@ -650,10 +659,11 @@ public:
void AbortMessage()
{
if (nPushPos == -1)
if (nHeaderStart == -1)
return;
vSend.resize(nPushPos);
nPushPos = -1;
vSend.resize(nHeaderStart);
nHeaderStart = -1;
nMessageStart = -1;
cs_vSend.Leave();
printf("(aborted)\n");
}
@@ -667,25 +677,26 @@ public:
return;
}
if (nPushPos == -1)
if (nHeaderStart == -1)
return;
// Patch in the size
unsigned int nSize = vSend.size() - nPushPos - sizeof(CMessageHeader);
memcpy((char*)&vSend[nPushPos] + offsetof(CMessageHeader, nMessageSize), &nSize, sizeof(nSize));
unsigned int nSize = vSend.size() - nMessageStart;
memcpy((char*)&vSend[nHeaderStart] + offsetof(CMessageHeader, nMessageSize), &nSize, sizeof(nSize));
printf("(%d bytes) ", nSize);
printf("\n");
nPushPos = -1;
nHeaderStart = -1;
nMessageStart = -1;
cs_vSend.Leave();
}
void EndMessageAbortIfEmpty()
{
if (nPushPos == -1)
if (nHeaderStart == -1)
return;
int nSize = vSend.size() - nPushPos - sizeof(CMessageHeader);
int nSize = vSend.size() - nMessageStart;
if (nSize > 0)
EndMessage();
else
@@ -694,9 +705,9 @@ public:
const char* GetMessageCommand() const
{
if (nPushPos == -1)
if (nHeaderStart == -1)
return "";
return &vSend[nPushPos] + offsetof(CMessageHeader, pchCommand);
return &vSend[nHeaderStart] + offsetof(CMessageHeader, pchCommand);
}

33
rpc.cpp
View File

@@ -77,6 +77,18 @@ Value getconnectioncount(const Array& params)
}
double GetDifficulty()
{
// Floating point number that is a multiple of the minimum difficulty,
// minimum difficulty = 1.0.
if (pindexBest == NULL)
return 1.0;
int nShift = 256 - 32 - 31; // to fit in a uint
double dMinimum = (CBigNum().SetCompact(bnProofOfWorkLimit.GetCompact()) >> nShift).getuint();
double dCurrently = (CBigNum().SetCompact(pindexBest->nBits) >> nShift).getuint();
return dMinimum / dCurrently;
}
Value getdifficulty(const Array& params)
{
if (params.size() != 0)
@@ -84,15 +96,7 @@ Value getdifficulty(const Array& params)
"getdifficulty (no parameters)\n"
"Returns the proof-of-work difficulty as a multiple of the minimum difficulty.");
if (pindexBest == NULL)
throw runtime_error("block chain not loaded");
// Floating point number that is a multiple of the minimum difficulty,
// minimum difficulty = 1.0.
int nShift = 256 - 32 - 31; // to fit in a uint
double dMinimum = (CBigNum().SetCompact(bnProofOfWorkLimit.GetCompact()) >> nShift).getuint();
double dCurrently = (CBigNum().SetCompact(pindexBest->nBits) >> nShift).getuint();
return dMinimum / dCurrently;
return GetDifficulty();
}
@@ -157,6 +161,7 @@ Value getinfo(const Array& params)
obj.push_back(Pair("proxy", (fUseProxy ? addrProxy.ToStringIPPort() : string())));
obj.push_back(Pair("generate", (bool)fGenerateBitcoins));
obj.push_back(Pair("genproclimit", (int)(fLimitProcessors ? nLimitProcessors : -1)));
obj.push_back(Pair("difficulty", (double)GetDifficulty()));
return obj;
}
@@ -676,18 +681,18 @@ int CommandLineRPC(int argc, char *argv[])
string strResult = (result.type() == str_type ? result.get_str() : write_string(result, true));
if (result.type() != null_type)
{
if (fWindows)
if (fWindows && fGUI)
// Windows GUI apps can't print to command line,
// so for now settle for a message box yuck
wxMessageBox(strResult.c_str(), "Bitcoin", wxOK);
// so settle for a message box yuck
MyMessageBox(strResult.c_str(), "Bitcoin", wxOK);
else
fprintf(stdout, "%s\n", strResult.c_str());
}
return 0;
}
catch (std::exception& e) {
if (fWindows)
wxMessageBox(strprintf("error: %s\n", e.what()).c_str(), "Bitcoin", wxOK);
if (fWindows && fGUI)
MyMessageBox(strprintf("error: %s\n", e.what()).c_str(), "Bitcoin", wxOK);
else
fprintf(stderr, "error: %s\n", e.what());
} catch (...) {

View File

@@ -19,7 +19,7 @@ class CScript;
class CDataStream;
class CAutoFile;
static const int VERSION = 206;
static const int VERSION = 208;
static const char* pszSubVer = ".0";

688
ui.cpp
View File

@@ -7,38 +7,18 @@
#include <crtdbg.h>
#endif
bool GetStartOnSystemStartup();
void SetStartOnSystemStartup(bool fAutoStart);
DEFINE_EVENT_TYPE(wxEVT_UITHREADCALL)
CMainFrame* pframeMain = NULL;
CMyTaskBarIcon* ptaskbaricon = NULL;
extern int g_isPainting;
bool fClosedToTray = false;
// Settings
int fMinimizeToTray = true;
int fMinimizeOnClose = true;
int MyMessageBox(const wxString& message, const wxString& caption="Message", int style=wxOK, wxWindow* parent=NULL, int x=-1, int y=-1)
{
if (fDaemon)
{
printf("wxMessageBox %s: %s\n", string(caption).c_str(), string(message).c_str());
fprintf(stderr, "%s: %s\n", string(caption).c_str(), string(message).c_str());
return wxOK;
}
return wxMessageBox(message, caption, style, parent, x, y);
}
#define wxMessageBox MyMessageBox
@@ -48,47 +28,6 @@ int MyMessageBox(const wxString& message, const wxString& caption="Message", int
// Util
//
void ExitTimeout(void* parg)
{
#ifdef __WXMSW__
Sleep(5000);
ExitProcess(0);
#endif
}
void Shutdown(void* parg)
{
static CCriticalSection cs_Shutdown;
static bool fTaken;
bool fFirstThread;
CRITICAL_BLOCK(cs_Shutdown)
{
fFirstThread = !fTaken;
fTaken = true;
}
static bool fExit;
if (fFirstThread)
{
fShutdown = true;
nTransactionsUpdated++;
DBFlush(false);
StopNode();
DBFlush(true);
CreateThread(ExitTimeout, NULL);
Sleep(50);
printf("Bitcoin exiting\n\n");
fExit = true;
exit(0);
}
else
{
while (!fExit)
Sleep(500);
Sleep(100);
ExitThread(0);
}
}
void HandleCtrlA(wxKeyEvent& event)
{
// Ctrl-a select all
@@ -312,16 +251,25 @@ CMainFrame::CMainFrame(wxWindow* parent) : CMainFrameBase(parent)
m_staticTextBalance->SetSize(140, 17);
// resize to fit ubuntu's huge default font
dResize = 1.22;
SetSize(dResize * GetSize().GetWidth(), 1.09 * GetSize().GetHeight());
SetSize(dResize * GetSize().GetWidth(), 1.15 * GetSize().GetHeight());
#endif
m_staticTextBalance->SetLabel(FormatMoney(GetBalance()) + " ");
m_listCtrl->SetFocus();
ptaskbaricon = new CMyTaskBarIcon();
#ifdef __WXMAC__
// Mac automatically moves wxID_EXIT, wxID_PREFERENCES and wxID_ABOUT
// to their standard places, leaving these menus empty.
GetMenuBar()->Remove(2); // remove Help menu
GetMenuBar()->Remove(0); // remove File menu
#endif
// Init column headers
int nDateWidth = DateTimeStr(1229413914).size() * 6 + 8;
if (!strstr(DateTimeStr(1229413914).c_str(), "2008"))
nDateWidth += 12;
#ifdef __WXMAC__
nDateWidth += 2;
#endif
wxListCtrl* pplistCtrl[] = {m_listCtrlAll, m_listCtrlSentReceived, m_listCtrlSent, m_listCtrlReceived};
foreach(wxListCtrl* p, pplistCtrl)
{
@@ -335,7 +283,7 @@ CMainFrame::CMainFrame(wxWindow* parent) : CMainFrameBase(parent)
}
// Init status bar
int pnWidths[3] = { -100, 88, 290 };
int pnWidths[3] = { -100, 88, 300 };
#ifndef __WXMSW__
pnWidths[1] = pnWidths[1] * 1.1 * dResize;
pnWidths[2] = pnWidths[2] * 1.1 * dResize;
@@ -1630,7 +1578,6 @@ void COptionsDialog::OnButtonApply(wxCommandEvent& event)
//////////////////////////////////////////////////////////////////////////////
//
// CAboutDialog
@@ -2014,7 +1961,7 @@ void CSendingDialog::StartTransfer()
// Make sure we have enough money
if (nPrice + nTransactionFee > GetBalance())
{
Error(_("You don't have enough money"));
Error(_("Insufficient funds"));
return;
}
@@ -2081,7 +2028,7 @@ void CSendingDialog::OnReply2(CDataStream& vRecv)
return;
if (nPrice + nTransactionFee > GetBalance())
{
Error(_("You don't have enough money"));
Error(_("Insufficient funds"));
return;
}
CKey key;
@@ -2219,7 +2166,7 @@ CAddressBookDialog::CAddressBookDialog(wxWindow* parent, const wxString& strInit
bool fMine = (AddressToHash160(strAddress, hash160) && mapPubKeys.count(hash160));
wxListCtrl* plistCtrl = fMine ? m_listCtrlReceiving : m_listCtrlSending;
int nIndex = InsertLine(plistCtrl, strName, strAddress);
if (strAddress == (fMine ? strDefaultReceiving : strInitSelected))
if (strAddress == (fMine ? strDefaultReceiving : string(strInitSelected)))
plistCtrl->SetItemState(nIndex, wxLIST_STATE_SELECTED|wxLIST_STATE_FOCUSED, wxLIST_STATE_SELECTED|wxLIST_STATE_FOCUSED);
}
}
@@ -2506,7 +2453,7 @@ void CMyTaskBarIcon::OnMenuRestore(wxCommandEvent& event)
void CMyTaskBarIcon::OnMenuOptions(wxCommandEvent& event)
{
// Since it's modal, get the main window to do it
wxCommandEvent event2(wxEVT_COMMAND_MENU_SELECTED, wxID_MENUOPTIONSOPTIONS);
wxCommandEvent event2(wxEVT_COMMAND_MENU_SELECTED, wxID_PREFERENCES);
pframeMain->GetEventHandler()->AddPendingEvent(event2);
}
@@ -2562,607 +2509,26 @@ wxMenu* CMyTaskBarIcon::CreatePopupMenu()
//////////////////////////////////////////////////////////////////////////////
//
// CMyApp
//
// Define a new application
class CMyApp: public wxApp
void CreateMainWindow()
{
public:
wxLocale m_locale;
CMyApp(){};
~CMyApp(){};
bool OnInit();
bool OnInit2();
int OnExit();
// Hook Initialize so we can start without GUI
virtual bool Initialize(int& argc, wxChar** argv);
// 2nd-level exception handling: we get all the exceptions occurring in any
// event handler here
virtual bool OnExceptionInMainLoop();
// 3rd, and final, level exception handling: whenever an unhandled
// exception is caught, this function is called
virtual void OnUnhandledException();
// and now for something different: this function is called in case of a
// crash (e.g. dereferencing null pointer, division by 0, ...)
virtual void OnFatalException();
};
IMPLEMENT_APP(CMyApp)
bool CMyApp::Initialize(int& argc, wxChar** argv)
{
if (argc > 1 && argv[1][0] != '-' && (!fWindows || argv[1][0] != '/') &&
wxString(argv[1]) != "start")
{
fCommandLine = true;
}
else
{
// wxApp::Initialize will remove environment-specific parameters,
// so it's too early to call ParseParameters yet
for (int i = 1; i < argc; i++)
{
wxString str = argv[i];
#ifdef __WXMSW__
if (str.size() >= 1 && str[0] == '/')
str[0] = '-';
str = str.MakeLower();
#endif
// haven't decided which argument to use for this yet
if (str == "-daemon" || str == "-d" || str == "start")
fDaemon = true;
}
}
#ifdef __WXGTK__
if (fDaemon || fCommandLine)
{
// Call the original Initialize while suppressing error messages
// and ignoring failure. If unable to initialize GTK, it fails
// near the end so hopefully the last few things don't matter.
{
wxLogNull logNo;
wxApp::Initialize(argc, argv);
}
if (fDaemon)
{
fprintf(stdout, "bitcoin server starting\n");
// Daemonize
pid_t pid = fork();
if (pid < 0)
{
fprintf(stderr, "Error: fork() returned %d errno %d\n", pid, errno);
return false;
}
if (pid > 0)
pthread_exit((void*)0);
}
return true;
}
#endif
return wxApp::Initialize(argc, argv);
}
bool CMyApp::OnInit()
{
bool fRet = false;
try
{
fRet = OnInit2();
}
catch (std::exception& e) {
PrintException(&e, "OnInit()");
} catch (...) {
PrintException(NULL, "OnInit()");
}
if (!fRet)
Shutdown(NULL);
return fRet;
}
bool CMyApp::OnInit2()
{
#ifdef _MSC_VER
// Turn off microsoft heap dump noise
_CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE);
_CrtSetReportFile(_CRT_WARN, CreateFileA("NUL", GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0));
#endif
#if defined(__WXMSW__) && defined(__WXDEBUG__)
// Disable malfunctioning wxWidgets debug assertion
g_isPainting = 10000;
#endif
wxImage::AddHandler(new wxPNGHandler);
#ifdef __WXMSW__
SetAppName("Bitcoin");
#else
SetAppName("bitcoin");
umask(077);
#endif
#ifdef __WXMSW__
#if wxUSE_UNICODE
// Hack to set wxConvLibc codepage to UTF-8 on Windows,
// may break if wxMBConv_win32 implementation in strconv.cpp changes.
class wxMBConv_win32 : public wxMBConv
{
public:
long m_CodePage;
size_t m_minMBCharWidth;
};
if (((wxMBConv_win32*)&wxConvLibc)->m_CodePage == CP_ACP)
((wxMBConv_win32*)&wxConvLibc)->m_CodePage = CP_UTF8;
#endif
#endif
// Load locale/<lang>/LC_MESSAGES/bitcoin.mo language file
m_locale.Init(wxLANGUAGE_DEFAULT, 0);
m_locale.AddCatalogLookupPathPrefix("locale");
if (!fWindows)
{
m_locale.AddCatalogLookupPathPrefix("/usr/share/locale");
m_locale.AddCatalogLookupPathPrefix("/usr/local/share/locale");
}
m_locale.AddCatalog("wxstd"); // wxWidgets standard translations, if any
m_locale.AddCatalog("bitcoin");
//
// Parameters
//
if (fCommandLine)
{
int ret = CommandLineRPC(argc, argv);
exit(ret);
}
ParseParameters(argc, argv);
if (mapArgs.count("-?") || mapArgs.count("--help"))
{
wxString strUsage = string() +
_("Usage: bitcoin [options]") + "\t\t\t\t\t\t\n" +
_("Options:\n") +
" -gen \t\t " + _("Generate coins\n") +
" -gen=0 \t\t " + _("Don't generate coins\n") +
" -min \t\t " + _("Start minimized\n") +
" -datadir=<dir> \t " + _("Specify data directory\n") +
" -proxy=<ip:port>\t " + _("Connect through socks4 proxy\n") +
" -addnode=<ip> \t " + _("Add a node to connect to\n") +
" -connect=<ip> \t " + _("Connect only to the specified node\n") +
" -? \t\t " + _("This help message\n");
if (fWindows)
{
// Remove spaces, the tabs make the columns line up in the message box
for (int i = 0; i < 50; i++)
strUsage.Replace(" \t", "\t");
wxMessageBox(strUsage, "Bitcoin", wxOK);
}
else
{
// Remove tabs
strUsage.Replace("\t", "");
fprintf(stderr, "%s", ((string)strUsage).c_str());
}
return false;
}
if (mapArgs.count("-datadir"))
strlcpy(pszSetDataDir, mapArgs["-datadir"].c_str(), sizeof(pszSetDataDir));
if (mapArgs.count("-debug"))
fDebug = true;
if (mapArgs.count("-printtodebugger"))
fPrintToDebugger = true;
if (!fDebug && !pszSetDataDir[0])
ShrinkDebugFile();
printf("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n");
printf("Bitcoin version 0.%d.%d%s beta, OS version %s\n", VERSION/100, VERSION%100, pszSubVer, ((string)wxGetOsDescription()).c_str());
printf("System default language is %d %s\n", m_locale.GetSystemLanguage(), ((string)m_locale.GetSysName()).c_str());
printf("Language file %s (%s)\n", (string("locale/") + (string)m_locale.GetCanonicalName() + "/LC_MESSAGES/bitcoin.mo").c_str(), ((string)m_locale.GetLocale()).c_str());
if (mapArgs.count("-loadblockindextest"))
{
CTxDB txdb("r");
txdb.LoadBlockIndex();
PrintBlockTree();
return false;
}
//
// Limit to single instance per user
// Required to protect the database files if we're going to keep deleting log.*
//
#ifdef __WXMSW__
// todo: wxSingleInstanceChecker wasn't working on Linux, never deleted its lock file
// maybe should go by whether successfully bind port 8333 instead
wxString strMutexName = wxString("bitcoin_running.") + getenv("HOMEPATH");
for (int i = 0; i < strMutexName.size(); i++)
if (!isalnum(strMutexName[i]))
strMutexName[i] = '.';
wxSingleInstanceChecker* psingleinstancechecker = new wxSingleInstanceChecker(strMutexName);
if (psingleinstancechecker->IsAnotherRunning())
{
printf("Existing instance found\n");
unsigned int nStart = GetTime();
loop
{
// TODO: find out how to do this in Linux, or replace with wxWidgets commands
// Show the previous instance and exit
HWND hwndPrev = FindWindowA("wxWindowClassNR", "Bitcoin");
if (hwndPrev)
{
if (IsIconic(hwndPrev))
ShowWindow(hwndPrev, SW_RESTORE);
SetForegroundWindow(hwndPrev);
return false;
}
if (GetTime() > nStart + 60)
return false;
// Resume this instance if the other exits
delete psingleinstancechecker;
Sleep(1000);
psingleinstancechecker = new wxSingleInstanceChecker(strMutexName);
if (!psingleinstancechecker->IsAnotherRunning())
break;
}
}
#endif
// Bind to the port early so we can tell if another instance is already running.
// This is a backup to wxSingleInstanceChecker, which doesn't work on Linux.
string strErrors;
if (!BindListenPort(strErrors))
{
wxMessageBox(strErrors, "Bitcoin");
return false;
}
//
// Load data files
//
bool fFirstRun;
strErrors = "";
int64 nStart;
printf("Loading addresses...\n");
nStart = GetTimeMillis();
if (!LoadAddresses())
strErrors += _("Error loading addr.dat \n");
printf(" addresses %15"PRI64d"ms\n", GetTimeMillis() - nStart);
printf("Loading block index...\n");
nStart = GetTimeMillis();
if (!LoadBlockIndex())
strErrors += _("Error loading blkindex.dat \n");
printf(" block index %15"PRI64d"ms\n", GetTimeMillis() - nStart);
printf("Loading wallet...\n");
nStart = GetTimeMillis();
if (!LoadWallet(fFirstRun))
strErrors += _("Error loading wallet.dat \n");
printf(" wallet %15"PRI64d"ms\n", GetTimeMillis() - nStart);
printf("Done loading\n");
//// debug print
printf("mapBlockIndex.size() = %d\n", mapBlockIndex.size());
printf("nBestHeight = %d\n", nBestHeight);
printf("mapKeys.size() = %d\n", mapKeys.size());
printf("mapPubKeys.size() = %d\n", mapPubKeys.size());
printf("mapWallet.size() = %d\n", mapWallet.size());
printf("mapAddressBook.size() = %d\n", mapAddressBook.size());
if (!strErrors.empty())
{
wxMessageBox(strErrors, "Bitcoin");
return false;
}
// Add wallet transactions that aren't already in a block to mapTransactions
ReacceptWalletTransactions();
//
// Parameters
//
if (mapArgs.count("-printblockindex") || mapArgs.count("-printblocktree"))
{
PrintBlockTree();
return false;
}
if (mapArgs.count("-printblock"))
{
string strMatch = mapArgs["-printblock"];
int nFound = 0;
for (map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.begin(); mi != mapBlockIndex.end(); ++mi)
{
uint256 hash = (*mi).first;
if (strncmp(hash.ToString().c_str(), strMatch.c_str(), strMatch.size()) == 0)
{
CBlockIndex* pindex = (*mi).second;
CBlock block;
block.ReadFromDisk(pindex);
block.BuildMerkleTree();
block.print();
printf("\n");
nFound++;
}
}
if (nFound == 0)
printf("No blocks matching %s were found\n", strMatch.c_str());
return false;
}
if (mapArgs.count("-gen"))
{
if (mapArgs["-gen"].empty())
fGenerateBitcoins = true;
else
fGenerateBitcoins = (atoi(mapArgs["-gen"].c_str()) != 0);
}
if (mapArgs.count("-proxy"))
{
fUseProxy = true;
addrProxy = CAddress(mapArgs["-proxy"]);
if (!addrProxy.IsValid())
{
wxMessageBox(_("Invalid -proxy address"), "Bitcoin");
return false;
}
}
if (mapArgs.count("-addnode"))
{
foreach(string strAddr, mapMultiArgs["-addnode"])
{
CAddress addr(strAddr, NODE_NETWORK);
addr.nTime = 0; // so it won't relay unless successfully connected
if (addr.IsValid())
AddAddress(addr);
}
}
//
// Create the main frame window
//
if (!fDaemon)
{
pframeMain = new CMainFrame(NULL);
if (mapArgs.count("-min"))
pframeMain->Iconize(true);
pframeMain->Show(true); // have to show first to get taskbar button to hide
if (fMinimizeToTray && pframeMain->IsIconized())
fClosedToTray = true;
pframeMain->Show(!fClosedToTray);
ptaskbaricon->Show(fMinimizeToTray || fClosedToTray);
CreateThread(ThreadDelayedRepaint, NULL);
}
if (!CheckDiskSpace())
return false;
RandAddSeedPerfmon();
if (!CreateThread(StartNode, NULL))
wxMessageBox("Error: CreateThread(StartNode) failed", "Bitcoin");
if (mapArgs.count("-server") || fDaemon)
CreateThread(ThreadRPCServer, NULL);
if (fFirstRun)
SetStartOnSystemStartup(true);
//
// Tests
//
#ifdef __WXMSW__
if (argc >= 2 && stricmp(argv[1], "-send") == 0)
#else
if (argc >= 2 && strcmp(argv[1], "-send") == 0)
#endif
{
int64 nValue = 1;
if (argc >= 3)
ParseMoney(argv[2], nValue);
string strAddress;
if (argc >= 4)
strAddress = argv[3];
CAddress addr(strAddress);
CWalletTx wtx;
wtx.mapValue["to"] = strAddress;
wtx.mapValue["from"] = addrLocalHost.ToString();
wtx.mapValue["message"] = "command line send";
// Send to IP address
CSendingDialog* pdialog = new CSendingDialog(pframeMain, addr, nValue, wtx);
if (!pdialog->ShowModal())
return false;
}
return true;
}
int CMyApp::OnExit()
{
Shutdown(NULL);
return wxApp::OnExit();
}
bool CMyApp::OnExceptionInMainLoop()
{
try
{
throw;
}
catch (std::exception& e)
{
PrintException(&e, "CMyApp::OnExceptionInMainLoop()");
wxLogWarning("Exception %s %s", typeid(e).name(), e.what());
Sleep(1000);
throw;
}
catch (...)
{
PrintException(NULL, "CMyApp::OnExceptionInMainLoop()");
wxLogWarning("Unknown exception");
Sleep(1000);
throw;
}
return true;
}
void CMyApp::OnUnhandledException()
{
// this shows how we may let some exception propagate uncaught
try
{
throw;
}
catch (std::exception& e)
{
PrintException(&e, "CMyApp::OnUnhandledException()");
wxLogWarning("Exception %s %s", typeid(e).name(), e.what());
Sleep(1000);
throw;
}
catch (...)
{
PrintException(NULL, "CMyApp::OnUnhandledException()");
wxLogWarning("Unknown exception");
Sleep(1000);
throw;
}
}
void CMyApp::OnFatalException()
{
wxMessageBox(_("Program has crashed and will terminate. "), "Bitcoin", wxOK | wxICON_ERROR);
pframeMain = new CMainFrame(NULL);
if (mapArgs.count("-min"))
pframeMain->Iconize(true);
pframeMain->Show(true); // have to show first to get taskbar button to hide
if (fMinimizeToTray && pframeMain->IsIconized())
fClosedToTray = true;
pframeMain->Show(!fClosedToTray);
ptaskbaricon->Show(fMinimizeToTray || fClosedToTray);
CreateThread(ThreadDelayedRepaint, NULL);
}
#ifdef __WXMSW__
typedef WINSHELLAPI BOOL (WINAPI *PSHGETSPECIALFOLDERPATHA)(HWND hwndOwner, LPSTR lpszPath, int nFolder, BOOL fCreate);
string MyGetSpecialFolderPath(int nFolder, bool fCreate)
{
char pszPath[MAX_PATH+100] = "";
// SHGetSpecialFolderPath is not usually available on NT 4.0
HMODULE hShell32 = LoadLibraryA("shell32.dll");
if (hShell32)
{
PSHGETSPECIALFOLDERPATHA pSHGetSpecialFolderPath =
(PSHGETSPECIALFOLDERPATHA)GetProcAddress(hShell32, "SHGetSpecialFolderPathA");
if (pSHGetSpecialFolderPath)
(*pSHGetSpecialFolderPath)(NULL, pszPath, nFolder, fCreate);
FreeModule(hShell32);
}
// Backup option
if (pszPath[0] == '\0')
{
if (nFolder == CSIDL_STARTUP)
{
strcpy(pszPath, getenv("USERPROFILE"));
strcat(pszPath, "\\Start Menu\\Programs\\Startup");
}
else if (nFolder == CSIDL_APPDATA)
{
strcpy(pszPath, getenv("APPDATA"));
}
}
return pszPath;
}
string StartupShortcutPath()
{
return MyGetSpecialFolderPath(CSIDL_STARTUP, true) + "\\Bitcoin.lnk";
}
bool GetStartOnSystemStartup()
{
return wxFileExists(StartupShortcutPath());
}
void SetStartOnSystemStartup(bool fAutoStart)
{
// If the shortcut exists already, remove it for updating
remove(StartupShortcutPath().c_str());
if (fAutoStart)
{
CoInitialize(NULL);
// Get a pointer to the IShellLink interface.
IShellLink* psl = NULL;
HRESULT hres = CoCreateInstance(CLSID_ShellLink, NULL,
CLSCTX_INPROC_SERVER, IID_IShellLink,
reinterpret_cast<void**>(&psl));
if (SUCCEEDED(hres))
{
// Get the current executable path
TCHAR pszExePath[MAX_PATH];
GetModuleFileName(NULL, pszExePath, sizeof(pszExePath));
// Set the path to the shortcut target
psl->SetPath(pszExePath);
PathRemoveFileSpec(pszExePath);
psl->SetWorkingDirectory(pszExePath);
psl->SetShowCmd(SW_SHOWMINNOACTIVE);
// Query IShellLink for the IPersistFile interface for
// saving the shortcut in persistent storage.
IPersistFile* ppf = NULL;
hres = psl->QueryInterface(IID_IPersistFile,
reinterpret_cast<void**>(&ppf));
if (SUCCEEDED(hres))
{
WCHAR pwsz[MAX_PATH];
// Ensure that the string is ANSI.
MultiByteToWideChar(CP_ACP, 0, StartupShortcutPath().c_str(), -1, pwsz, MAX_PATH);
// Save the link by calling IPersistFile::Save.
hres = ppf->Save(pwsz, TRUE);
ppf->Release();
}
psl->Release();
}
CoUninitialize();
}
}
#else
bool GetStartOnSystemStartup() { return false; }
void SetStartOnSystemStartup(bool fAutoStart) { }
#endif

49
ui.h
View File

@@ -4,27 +4,62 @@
DECLARE_EVENT_TYPE(wxEVT_UITHREADCALL, -1)
#if wxUSE_GUI
static const bool fGUI=true;
#else
static const bool fGUI=false;
#endif
extern map<string, string> mapArgs;
inline int MyMessageBox(const wxString& message, const wxString& caption="Message", int style=wxOK, wxWindow* parent=NULL, int x=-1, int y=-1)
{
#if wxUSE_GUI
if (!fDaemon)
return wxMessageBox(message, caption, style, parent, x, y);
#endif
printf("wxMessageBox %s: %s\n", string(caption).c_str(), string(message).c_str());
fprintf(stderr, "%s: %s\n", string(caption).c_str(), string(message).c_str());
return wxOK;
}
#define wxMessageBox MyMessageBox
// Settings
extern int fMinimizeToTray;
extern int fMinimizeOnClose;
void HandleCtrlA(wxKeyEvent& event);
string FormatTxStatus(const CWalletTx& wtx);
void UIThreadCall(boost::function0<void>);
void MainFrameRepaint();
void Shutdown(void* parg);
int ThreadSafeMessageBox(const string& message, const string& caption="Message", int style=wxOK, wxWindow* parent=NULL, int x=-1, int y=-1);
bool ThreadSafeAskFee(int64 nFeeRequired, const string& strCaption, wxWindow* parent);
void MainFrameRepaint();
void CreateMainWindow();
#if !wxUSE_GUI
inline int ThreadSafeMessageBox(const string& message, const string& caption, int style, wxWindow* parent, int x, int y)
{
return MyMessageBox(message, caption, style, parent, x, y);
}
inline bool ThreadSafeAskFee(int64 nFeeRequired, const string& strCaption, wxWindow* parent)
{
return true;
}
inline void MainFrameRepaint()
{
}
inline void CreateMainWindow()
{
}
#else // wxUSE_GUI
class CMainFrame : public CMainFrameBase
{
@@ -331,3 +366,5 @@ public:
DECLARE_EVENT_TABLE()
};
#endif // wxUSE_GUI

View File

@@ -24,7 +24,7 @@ CMainFrameBase::CMainFrameBase( wxWindow* parent, wxWindowID id, const wxString&
m_menuFile = new wxMenu();
wxMenuItem* m_menuFileExit;
m_menuFileExit = new wxMenuItem( m_menuFile, wxID_ANY, wxString( _("E&xit") ) , wxEmptyString, wxITEM_NORMAL );
m_menuFileExit = new wxMenuItem( m_menuFile, wxID_EXIT, wxString( _("E&xit") ) , wxEmptyString, wxITEM_NORMAL );
m_menuFile->Append( m_menuFileExit );
m_menubar->Append( m_menuFile, _("&File") );
@@ -39,14 +39,14 @@ CMainFrameBase::CMainFrameBase( wxWindow* parent, wxWindowID id, const wxString&
m_menuOptions->Append( m_menuOptionsChangeYourAddress );
wxMenuItem* m_menuOptionsOptions;
m_menuOptionsOptions = new wxMenuItem( m_menuOptions, wxID_MENUOPTIONSOPTIONS, wxString( _("&Options...") ) , wxEmptyString, wxITEM_NORMAL );
m_menuOptionsOptions = new wxMenuItem( m_menuOptions, wxID_PREFERENCES, wxString( _("&Options...") ) , wxEmptyString, wxITEM_NORMAL );
m_menuOptions->Append( m_menuOptionsOptions );
m_menubar->Append( m_menuOptions, _("&Settings") );
m_menuHelp = new wxMenu();
wxMenuItem* m_menuHelpAbout;
m_menuHelpAbout = new wxMenuItem( m_menuHelp, wxID_ANY, wxString( _("&About...") ) , wxEmptyString, wxITEM_NORMAL );
m_menuHelpAbout = new wxMenuItem( m_menuHelp, wxID_ABOUT, wxString( _("&About...") ) , wxEmptyString, wxITEM_NORMAL );
m_menuHelp->Append( m_menuHelpAbout );
m_menubar->Append( m_menuHelp, _("&Help") );
@@ -133,7 +133,7 @@ CMainFrameBase::CMainFrameBase( wxWindow* parent, wxWindowID id, const wxString&
wxBoxSizer* bSizer11;
bSizer11 = new wxBoxSizer( wxVERTICAL );
m_listCtrlAll = new wxListCtrl( m_panel9, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_NO_SORT_HEADER|wxLC_REPORT|wxLC_SORT_DESCENDING|wxVSCROLL );
m_listCtrlAll = new wxListCtrl( m_panel9, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_NO_SORT_HEADER|wxLC_REPORT|wxLC_SORT_DESCENDING );
bSizer11->Add( m_listCtrlAll, 1, wxEXPAND, 5 );
m_panel9->SetSizer( bSizer11 );
@@ -144,7 +144,7 @@ CMainFrameBase::CMainFrameBase( wxWindow* parent, wxWindowID id, const wxString&
wxBoxSizer* bSizer111;
bSizer111 = new wxBoxSizer( wxVERTICAL );
m_listCtrlSentReceived = new wxListCtrl( m_panel91, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_NO_SORT_HEADER|wxLC_REPORT|wxLC_SORT_DESCENDING|wxVSCROLL );
m_listCtrlSentReceived = new wxListCtrl( m_panel91, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_NO_SORT_HEADER|wxLC_REPORT|wxLC_SORT_DESCENDING );
bSizer111->Add( m_listCtrlSentReceived, 1, wxEXPAND, 5 );
m_panel91->SetSizer( bSizer111 );
@@ -155,7 +155,7 @@ CMainFrameBase::CMainFrameBase( wxWindow* parent, wxWindowID id, const wxString&
wxBoxSizer* bSizer112;
bSizer112 = new wxBoxSizer( wxVERTICAL );
m_listCtrlSent = new wxListCtrl( m_panel92, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_NO_SORT_HEADER|wxLC_REPORT|wxLC_SORT_DESCENDING|wxVSCROLL );
m_listCtrlSent = new wxListCtrl( m_panel92, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_NO_SORT_HEADER|wxLC_REPORT|wxLC_SORT_DESCENDING );
bSizer112->Add( m_listCtrlSent, 1, wxEXPAND, 5 );
m_panel92->SetSizer( bSizer112 );
@@ -166,7 +166,7 @@ CMainFrameBase::CMainFrameBase( wxWindow* parent, wxWindowID id, const wxString&
wxBoxSizer* bSizer113;
bSizer113 = new wxBoxSizer( wxVERTICAL );
m_listCtrlReceived = new wxListCtrl( m_panel93, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_NO_SORT_HEADER|wxLC_REPORT|wxLC_SORT_DESCENDING|wxVSCROLL );
m_listCtrlReceived = new wxListCtrl( m_panel93, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_NO_SORT_HEADER|wxLC_REPORT|wxLC_SORT_DESCENDING );
bSizer113->Add( m_listCtrlReceived, 1, wxEXPAND, 5 );
m_panel93->SetSizer( bSizer113 );

View File

@@ -42,29 +42,28 @@
#define wxID_MAINFRAME 1000
#define wxID_OPTIONSGENERATEBITCOINS 1001
#define wxID_MENUOPTIONSOPTIONS 1002
#define wxID_BUTTONSEND 1003
#define wxID_BUTTONRECEIVE 1004
#define wxID_TEXTCTRLADDRESS 1005
#define wxID_BUTTONNEW 1006
#define wxID_BUTTONCOPY 1007
#define wxID_TRANSACTIONFEE 1008
#define wxID_PROXYIP 1009
#define wxID_PROXYPORT 1010
#define wxID_TEXTCTRLPAYTO 1011
#define wxID_BUTTONPASTE 1012
#define wxID_BUTTONADDRESSBOOK 1013
#define wxID_TEXTCTRLAMOUNT 1014
#define wxID_CHOICETRANSFERTYPE 1015
#define wxID_LISTCTRL 1016
#define wxID_BUTTONRENAME 1017
#define wxID_PANELSENDING 1018
#define wxID_LISTCTRLSENDING 1019
#define wxID_PANELRECEIVING 1020
#define wxID_LISTCTRLRECEIVING 1021
#define wxID_BUTTONDELETE 1022
#define wxID_BUTTONEDIT 1023
#define wxID_TEXTCTRL 1024
#define wxID_BUTTONSEND 1002
#define wxID_BUTTONRECEIVE 1003
#define wxID_TEXTCTRLADDRESS 1004
#define wxID_BUTTONNEW 1005
#define wxID_BUTTONCOPY 1006
#define wxID_TRANSACTIONFEE 1007
#define wxID_PROXYIP 1008
#define wxID_PROXYPORT 1009
#define wxID_TEXTCTRLPAYTO 1010
#define wxID_BUTTONPASTE 1011
#define wxID_BUTTONADDRESSBOOK 1012
#define wxID_TEXTCTRLAMOUNT 1013
#define wxID_CHOICETRANSFERTYPE 1014
#define wxID_LISTCTRL 1015
#define wxID_BUTTONRENAME 1016
#define wxID_PANELSENDING 1017
#define wxID_LISTCTRLSENDING 1018
#define wxID_PANELRECEIVING 1019
#define wxID_LISTCTRLRECEIVING 1020
#define wxID_BUTTONDELETE 1021
#define wxID_BUTTONEDIT 1022
#define wxID_TEXTCTRL 1023
///////////////////////////////////////////////////////////////////////////////
/// Class CMainFrameBase

View File

@@ -123,7 +123,7 @@
<property name="checked">0</property>
<property name="enabled">1</property>
<property name="help"></property>
<property name="id">wxID_ANY</property>
<property name="id">wxID_EXIT</property>
<property name="kind">wxITEM_NORMAL</property>
<property name="label">E&amp;xit</property>
<property name="name">m_menuFileExit</property>
@@ -173,7 +173,7 @@
<property name="checked">0</property>
<property name="enabled">1</property>
<property name="help"></property>
<property name="id">wxID_MENUOPTIONSOPTIONS</property>
<property name="id">wxID_PREFERENCES</property>
<property name="kind">wxITEM_NORMAL</property>
<property name="label">&amp;Options...</property>
<property name="name">m_menuOptionsOptions</property>
@@ -193,7 +193,7 @@
<property name="checked">0</property>
<property name="enabled">1</property>
<property name="help"></property>
<property name="id">wxID_ANY</property>
<property name="id">wxID_ABOUT</property>
<property name="kind">wxITEM_NORMAL</property>
<property name="label">&amp;About...</property>
<property name="name">m_menuHelpAbout</property>
@@ -924,7 +924,7 @@
<property name="tooltip"></property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style">wxVSCROLL</property>
<property name="window_style"></property>
<event name="OnChar"></event>
<event name="OnEnterWindow"></event>
<event name="OnEraseBackground"></event>
@@ -1047,7 +1047,7 @@
<property name="tooltip"></property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style">wxVSCROLL</property>
<property name="window_style"></property>
<event name="OnChar"></event>
<event name="OnEnterWindow"></event>
<event name="OnEraseBackground"></event>
@@ -1170,7 +1170,7 @@
<property name="tooltip"></property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style">wxVSCROLL</property>
<property name="window_style"></property>
<event name="OnChar"></event>
<event name="OnEnterWindow"></event>
<event name="OnEraseBackground"></event>
@@ -1293,7 +1293,7 @@
<property name="tooltip"></property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style">wxVSCROLL</property>
<property name="window_style"></property>
<event name="OnChar"></event>
<event name="OnEnterWindow"></event>
<event name="OnEraseBackground"></event>

View File

@@ -282,15 +282,21 @@ bool error(const char* format, ...)
void ParseString(const string& str, char c, vector<string>& v)
{
unsigned int i1 = 0;
unsigned int i2;
do
if (str.empty())
return;
string::size_type i1 = 0;
string::size_type i2;
loop
{
i2 = str.find(c, i1);
if (i2 == str.npos)
{
v.push_back(str.substr(i1));
return;
}
v.push_back(str.substr(i1, i2-i1));
i1 = i2+1;
}
while (i2 != str.npos);
}
@@ -308,6 +314,12 @@ string FormatMoney(int64 n, bool fPlus)
return str;
}
bool ParseMoney(const string& str, int64& nRet)
{
return ParseMoney(str.c_str(), nRet);
}
bool ParseMoney(const char* pszIn, int64& nRet)
{
string strWhole;
@@ -445,20 +457,21 @@ const char* wxGetTranslation(const char* pszEnglish)
return (*mi).second;
// wxWidgets translation
const char* pszTranslated = wxGetTranslation(wxString(pszEnglish, wxConvUTF8)).utf8_str();
wxString strTranslated = wxGetTranslation(wxString(pszEnglish, wxConvUTF8));
// We don't cache unknown strings because caller might be passing in a
// dynamic string and we would keep allocating memory for each variation.
if (strcmp(pszEnglish, pszTranslated) == 0)
if (strcmp(pszEnglish, strTranslated.utf8_str()) == 0)
return pszEnglish;
// Add to cache, memory doesn't need to be freed. We only cache because
// we must pass back a pointer to permanently allocated memory.
char* pszCached = new char[strlen(pszTranslated)+1];
strcpy(pszCached, pszTranslated);
char* pszCached = new char[strlen(strTranslated.utf8_str())+1];
strcpy(pszCached, strTranslated.utf8_str());
mapCache[pszEnglish] = pszCached;
return pszCached;
}
return NULL;
}
@@ -502,8 +515,8 @@ void PrintException(std::exception* pex, const char* pszThread)
FormatException(pszMessage, pex, pszThread);
printf("\n\n************************\n%s\n", pszMessage);
fprintf(stderr, "\n\n************************\n%s\n", pszMessage);
if (wxTheApp && !fDaemon)
wxMessageBox(pszMessage, "Error", wxOK | wxICON_ERROR);
if (wxTheApp && !fDaemon && fGUI)
MyMessageBox(pszMessage, "Error", wxOK | wxICON_ERROR);
throw;
//DebugBreak();
}

1
util.h
View File

@@ -133,6 +133,7 @@ void PrintException(std::exception* pex, const char* pszThread);
void LogException(std::exception* pex, const char* pszThread);
void ParseString(const string& str, char c, vector<string>& v);
string FormatMoney(int64 n, bool fPlus=false);
bool ParseMoney(const string& str, int64& nRet);
bool ParseMoney(const char* pszIn, int64& nRet);
vector<unsigned char> ParseHex(const char* psz);
vector<unsigned char> ParseHex(const std::string& str);