diff --git a/main.cpp b/main.cpp index 665a78e2..e5cc881b 100644 --- a/main.cpp +++ b/main.cpp @@ -2645,7 +2645,12 @@ void BitcoinMiner() do { pindexTmp = pindexBest; - Sleep(10000); + for (int i = 0; i < 10; i++) + { + Sleep(1000); + if (fShutdown) + return; + } } while (pindexTmp != pindexBest); } @@ -2852,10 +2857,13 @@ bool CreateTransaction(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew, CK if (keyRet.IsNull()) keyRet.MakeNewKey(); - // Fill a vout to ourself - CScript scriptPubKey; - scriptPubKey << keyRet.GetPubKey() << OP_CHECKSIG; - wtxNew.vout.push_back(CTxOut(nValueIn - nTotalValue, scriptPubKey)); + // Fill a vout to ourself, using same address type as the payment + CScript scriptChange; + if (scriptPubKey.GetBitcoinAddressHash160() != 0) + scriptChange.SetBitcoinAddress(keyRet.GetPubKey()); + else + scriptChange << keyRet.GetPubKey() << OP_CHECKSIG; + wtxNew.vout.push_back(CTxOut(nValueIn - nTotalValue, scriptChange)); } // Fill a vout to the payee @@ -2894,42 +2902,50 @@ bool CreateTransaction(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew, CK } // Call after CreateTransaction unless you want to abort -bool CommitTransactionSpent(const CWalletTx& wtxNew, const CKey& key) +bool CommitTransaction(CWalletTx& wtxNew, const CKey& key) { CRITICAL_BLOCK(cs_main) - CRITICAL_BLOCK(cs_mapWallet) { - //// old: eventually should make this transactional, never want to add a - //// transaction without marking spent transactions, although the risk of - //// interruption during this step is remote. - //// update: This matters even less now that fSpent can get corrected - //// when transactions are seen in VerifySignature. The remote chance of - //// unmarked fSpent will be handled by that. Don't need to make this - //// transactional. Pls delete this comment block later. - - // This is only to keep the database open to defeat the auto-flush for the - // duration of this scope. This is the only place where this optimization - // maybe makes sense; please don't do it anywhere else. - CWalletDB walletdb("r"); - - // Add the change's private key to wallet - if (!key.IsNull() && !AddKey(key)) - throw runtime_error("CommitTransactionSpent() : AddKey failed\n"); - - // Add tx to wallet, because if it has change it's also ours, - // otherwise just for transaction history. - AddToWallet(wtxNew); + printf("CommitTransaction:\n%s", wtxNew.ToString().c_str()); + CRITICAL_BLOCK(cs_mapWallet) + { + // This is only to keep the database open to defeat the auto-flush for the + // duration of this scope. This is the only place where this optimization + // maybe makes sense; please don't do it anywhere else. + CWalletDB walletdb("r"); + + // Add the change's private key to wallet + if (!key.IsNull() && !AddKey(key)) + throw runtime_error("CommitTransaction() : AddKey failed\n"); + + // Add tx to wallet, because if it has change it's also ours, + // otherwise just for transaction history. + AddToWallet(wtxNew); + + // Mark old coins as spent + set setCoins; + foreach(const CTxIn& txin, wtxNew.vin) + setCoins.insert(&mapWallet[txin.prevout.hash]); + foreach(CWalletTx* pcoin, setCoins) + { + pcoin->fSpent = true; + pcoin->WriteToDisk(); + vWalletUpdated.push_back(pcoin->GetHash()); + } + } + + // Track how many getdata requests our transaction gets + CRITICAL_BLOCK(cs_mapRequestCount) + mapRequestCount[wtxNew.GetHash()] = 0; - // Mark old coins as spent - set setCoins; - foreach(const CTxIn& txin, wtxNew.vin) - setCoins.insert(&mapWallet[txin.prevout.hash]); - foreach(CWalletTx* pcoin, setCoins) + // Broadcast + if (!wtxNew.AcceptTransaction()) { - pcoin->fSpent = true; - pcoin->WriteToDisk(); - vWalletUpdated.push_back(pcoin->GetHash()); + // This must not fail. The transaction has already been signed and recorded. + printf("CommitTransaction() : Error: Transaction not valid"); + return false; } + wtxNew.RelayWalletTransaction(); } MainFrameRepaint(); return true; @@ -2938,7 +2954,7 @@ bool CommitTransactionSpent(const CWalletTx& wtxNew, const CKey& key) -string SendMoney(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew) +string SendMoney(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew, bool fAskFee) { CRITICAL_BLOCK(cs_main) { @@ -2954,26 +2970,12 @@ string SendMoney(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew) printf("SendMoney() : %s", strError.c_str()); return strError; } - if (!CommitTransactionSpent(wtxNew, key)) - { - printf("SendMoney() : Error finalizing transaction"); - return _("Error finalizing transaction"); - } - - // Track how many getdata requests our transaction gets - CRITICAL_BLOCK(cs_mapRequestCount) - mapRequestCount[wtxNew.GetHash()] = 0; - printf("SendMoney: %s\n", wtxNew.GetHash().ToString().substr(0,6).c_str()); + if (fAskFee && !ThreadSafeAskFee(nFeeRequired, _("Sending..."), NULL)) + return "ABORTED"; - // Broadcast - if (!wtxNew.AcceptTransaction()) - { - // This must not fail. The transaction has already been signed and recorded. - printf("SendMoney() : Error: Transaction not valid"); + if (!CommitTransaction(wtxNew, key)) return _("Error: The transaction was rejected. This might happen if some of the coins in your wallet were already spent, such as if you used a copy of wallet.dat and coins were spent in the copy but not marked as spent here."); - } - wtxNew.RelayWalletTransaction(); } MainFrameRepaint(); return ""; @@ -2981,7 +2983,7 @@ string SendMoney(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew) -string SendMoneyToBitcoinAddress(string strAddress, int64 nValue, CWalletTx& wtxNew) +string SendMoneyToBitcoinAddress(string strAddress, int64 nValue, CWalletTx& wtxNew, bool fAskFee) { // Check amount if (nValue <= 0) @@ -2994,5 +2996,5 @@ string SendMoneyToBitcoinAddress(string strAddress, int64 nValue, CWalletTx& wtx if (!scriptPubKey.SetBitcoinAddress(strAddress)) return _("Invalid bitcoin address"); - return SendMoney(scriptPubKey, nValue, wtxNew); + return SendMoney(scriptPubKey, nValue, wtxNew, fAskFee); } diff --git a/main.h b/main.h index bcb6ec7d..4027f87e 100644 --- a/main.h +++ b/main.h @@ -67,9 +67,10 @@ bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv); bool SendMessages(CNode* pto); int64 GetBalance(); bool CreateTransaction(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew, CKey& keyRet, int64& nFeeRequiredRet); -bool CommitTransactionSpent(const CWalletTx& wtxNew, const CKey& key); -string SendMoney(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew); -string SendMoneyToBitcoinAddress(string strAddress, int64 nValue, CWalletTx& wtxNew); +bool CommitTransaction(CWalletTx& wtxNew, const CKey& key); +bool BroadcastTransaction(CWalletTx& wtxNew); +string SendMoney(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew, bool fAskFee=false); +string SendMoneyToBitcoinAddress(string strAddress, int64 nValue, CWalletTx& wtxNew, bool fAskFee=false); void GenerateBitcoins(bool fGenerate); void ThreadBitcoinMiner(void* parg); void BitcoinMiner(); diff --git a/script.h b/script.h index 9e418891..dc47e1d8 100644 --- a/script.h +++ b/script.h @@ -580,6 +580,11 @@ public: *this << OP_DUP << OP_HASH160 << hash160 << OP_EQUALVERIFY << OP_CHECKSIG; } + void SetBitcoinAddress(const vector& vchPubKey) + { + SetBitcoinAddress(Hash160(vchPubKey)); + } + bool SetBitcoinAddress(const string& strAddress) { this->clear(); diff --git a/serialize.h b/serialize.h index aaf3f990..23d61fe9 100644 --- a/serialize.h +++ b/serialize.h @@ -19,7 +19,7 @@ class CScript; class CDataStream; class CAutoFile; -static const int VERSION = 203; +static const int VERSION = 204; static const char* pszSubVer = ".0"; diff --git a/ui.cpp b/ui.cpp index 87ba19e0..9bd34e09 100644 --- a/ui.cpp +++ b/ui.cpp @@ -35,13 +35,54 @@ int fMinimizeOnClose = true; // Util // +void ExitTimeout(void* parg) +{ +#ifdef __WXMSW__ + Sleep(5000); + ExitProcess(0); +#endif +} + +void Shutdown(void* parg) +{ + static CCriticalSection cs_Shutdown; + static bool fTaken; + bool fFirstThread; + CRITICAL_BLOCK(cs_Shutdown) + { + fFirstThread = !fTaken; + fTaken = true; + } + static bool fExit; + if (fFirstThread) + { + fShutdown = true; + nTransactionsUpdated++; + DBFlush(false); + StopNode(); + DBFlush(true); + CreateThread(ExitTimeout, NULL); + Sleep(50); + printf("Bitcoin exiting\n\n"); + fExit = true; + exit(0); + } + else + { + while (!fExit) + Sleep(500); + Sleep(100); + ExitThread(0); + } +} + void HandleCtrlA(wxKeyEvent& event) { // Ctrl-a select all + event.Skip(); wxTextCtrl* textCtrl = (wxTextCtrl*)event.GetEventObject(); if (event.GetModifiers() == wxMOD_CONTROL && event.GetKeyCode() == 'A') textCtrl->SetSelection(-1, -1); - event.Skip(); } bool Is24HourTime() @@ -194,6 +235,35 @@ int ThreadSafeMessageBox(const string& message, const string& caption, int style #endif } +bool ThreadSafeAskFee(int64 nFeeRequired, const string& strCaption, wxWindow* parent) +{ + if (nFeeRequired == 0 || fDaemon) + return true; + string strMessage = strprintf( + _("This transaction is over the size limit. You can still send it for a fee of %s, " + "which goes to the nodes that process your transaction and helps to support the network. " + "Do you want to pay the fee?"), + FormatMoney(nFeeRequired).c_str()); + return (ThreadSafeMessageBox(strMessage, strCaption, wxYES_NO, parent) == wxYES); +} + +void SetDefaultReceivingAddress(const string& strAddress) +{ + // Update main window address and database + if (pframeMain == NULL) + return; + if (strAddress != pframeMain->m_textCtrlAddress->GetValue()) + { + uint160 hash160; + if (!AddressToHash160(strAddress, hash160)) + return; + if (!mapPubKeys.count(hash160)) + return; + CWalletDB().WriteDefaultKey(mapPubKeys[hash160]); + pframeMain->m_textCtrlAddress->SetValue(strAddress); + } +} + @@ -227,11 +297,6 @@ CMainFrame::CMainFrame(wxWindow* parent) : CMainFrameBase(parent) fontTmp.SetFamily(wxFONTFAMILY_TELETYPE); m_staticTextBalance->SetFont(fontTmp); m_staticTextBalance->SetSize(140, 17); - // & underlines don't work on the toolbar buttons on gtk - m_toolBar->ClearTools(); - m_toolBar->AddTool(wxID_BUTTONSEND, _("Send Coins"), wxBitmap(send20_xpm), wxNullBitmap, wxITEM_NORMAL, wxEmptyString, wxEmptyString); - m_toolBar->AddTool(wxID_BUTTONRECEIVE, _("Address Book"), wxBitmap(addressbook20_xpm), wxNullBitmap, wxITEM_NORMAL, wxEmptyString, wxEmptyString); - m_toolBar->Realize(); // resize to fit ubuntu's huge default font dResize = 1.20; SetSize((dResize + 0.02) * GetSize().GetWidth(), 1.09 * GetSize().GetHeight()); @@ -276,47 +341,6 @@ CMainFrame::~CMainFrame() ptaskbaricon = NULL; } -void ExitTimeout(void* parg) -{ -#ifdef __WXMSW__ - Sleep(5000); - ExitProcess(0); -#endif -} - -void Shutdown(void* parg) -{ - static CCriticalSection cs_Shutdown; - static bool fTaken; - bool fFirstThread; - CRITICAL_BLOCK(cs_Shutdown) - { - fFirstThread = !fTaken; - fTaken = true; - } - static bool fExit; - if (fFirstThread) - { - fShutdown = true; - nTransactionsUpdated++; - DBFlush(false); - StopNode(); - DBFlush(true); - CreateThread(ExitTimeout, NULL); - Sleep(50); - printf("Bitcoin exiting\n\n"); - fExit = true; - exit(0); - } - else - { - while (!fExit) - Sleep(500); - Sleep(100); - ExitThread(0); - } -} - void CMainFrame::OnClose(wxCloseEvent& event) { if (fMinimizeOnClose && event.CanVeto() && !IsIconized()) @@ -335,6 +359,7 @@ void CMainFrame::OnClose(wxCloseEvent& event) void CMainFrame::OnIconize(wxIconizeEvent& event) { + event.Skip(); // Hide the task bar button when minimized. // Event is sent when the frame is minimized or restored. // wxWidgets 2.8.9 doesn't have IsIconized() so there's no way @@ -342,7 +367,7 @@ void CMainFrame::OnIconize(wxIconizeEvent& event) if (!event.Iconized()) fClosedToTray = false; #ifndef __WXMSW__ - // Tray is not reliable on Linux gnome + // Tray is not reliable on ubuntu 9.10 gnome fClosedToTray = false; #endif if (fMinimizeToTray && event.Iconized()) @@ -353,6 +378,7 @@ void CMainFrame::OnIconize(wxIconizeEvent& event) void CMainFrame::OnMouseEvents(wxMouseEvent& event) { + event.Skip(); RandAddSeed(); RAND_add(&event.m_x, sizeof(event.m_x), 0.25); RAND_add(&event.m_y, sizeof(event.m_y), 0.25); @@ -360,9 +386,11 @@ void CMainFrame::OnMouseEvents(wxMouseEvent& event) void CMainFrame::OnListColBeginDrag(wxListEvent& event) { - // Hidden columns not resizeable - if (event.GetColumn() <= 1 && !fDebug) + // Hidden columns not resizeable + if (event.GetColumn() <= 1 && !fDebug) event.Veto(); + else + event.Skip(); } int CMainFrame::GetSortIndex(const string& strSort) @@ -546,7 +574,7 @@ bool CMainFrame::InsertTransaction(const CWalletTx& wtx, bool fNew, int nIndex) if (wtx.IsCoinBase()) { - // Coinbase + // Generated strDescription = _("Generated"); if (nCredit == 0) { @@ -569,7 +597,7 @@ bool CMainFrame::InsertTransaction(const CWalletTx& wtx, bool fNew, int nIndex) } else if (!mapValue["from"].empty() || !mapValue["message"].empty()) { - // Online transaction + // Received by IP connection if (!mapValue["from"].empty()) strDescription += _("From: ") + mapValue["from"]; if (!mapValue["message"].empty()) @@ -581,7 +609,7 @@ bool CMainFrame::InsertTransaction(const CWalletTx& wtx, bool fNew, int nIndex) } else { - // Offline transaction + // Received by Bitcoin Address foreach(const CTxOut& txout, wtx.vout) { if (txout.IsMine()) @@ -591,20 +619,19 @@ bool CMainFrame::InsertTransaction(const CWalletTx& wtx, bool fNew, int nIndex) { CRITICAL_BLOCK(cs_mapAddressBook) { + //strDescription += _("Received payment to "); + //strDescription += _("Received with address "); + strDescription += _("From: unknown, Received with: "); string strAddress = PubKeyToAddress(vchPubKey); - if (mapAddressBook.count(strAddress)) + map::iterator mi = mapAddressBook.find(strAddress); + if (mi != mapAddressBook.end() && !(*mi).second.empty()) { - //strDescription += _("Received payment to "); - //strDescription += _("Received with address "); - strDescription += _("From: unknown, To: "); - strDescription += strAddress; - /// The labeling feature is just too confusing, so I hid it - /// by putting it at the end where it runs off the screen. - /// It can still be seen by widening the column, or in the - /// details dialog. - if (!mapAddressBook[strAddress].empty()) - strDescription += " (" + mapAddressBook[strAddress] + ")"; + string strLabel = (*mi).second; + strDescription += strAddress.substr(0,12) + "... "; + strDescription += "(" + strLabel + ")"; } + else + strDescription += strAddress; } } break; @@ -659,12 +686,12 @@ bool CMainFrame::InsertTransaction(const CWalletTx& wtx, bool fNew, int nIndex) string strAddress; if (!mapValue["to"].empty()) { - // Online transaction + // Sent to IP strAddress = mapValue["to"]; } else { - // Offline transaction + // Sent to Bitcoin Address uint160 hash160; if (ExtractHash160(txout.scriptPubKey, hash160)) strAddress = Hash160ToAddress(hash160); @@ -683,8 +710,11 @@ bool CMainFrame::InsertTransaction(const CWalletTx& wtx, bool fNew, int nIndex) } int64 nValue = txout.nValue; - if (nOut == 0 && nTxFee > 0) + if (nTxFee > 0) + { nValue += nTxFee; + nTxFee = 0; + } InsertLine(fNew, nIndex, hash, strprintf("%s-%d", strSort.c_str(), nOut), strStatus, @@ -846,12 +876,12 @@ void CMainFrame::RefreshStatusColumn() void CMainFrame::OnPaint(wxPaintEvent& event) { + event.Skip(); if (fRefresh) { fRefresh = false; Refresh(); } - event.Skip(); } @@ -903,6 +933,9 @@ void MainFrameRepaint() void CMainFrame::OnPaintListCtrl(wxPaintEvent& event) { + // Skip lets the listctrl do the paint, we're just hooking the message + event.Skip(); + if (ptaskbaricon) ptaskbaricon->UpdateTooltip(); @@ -970,11 +1003,6 @@ void CMainFrame::OnPaintListCtrl(wxPaintEvent& event) if (fDebug && GetTime() - nThreadSocketHandlerHeartbeat > 60) m_statusBar->SetStatusText(" ERROR: ThreadSocketHandler has stopped", 0); - - // Pass through to listctrl to actually do the paint, we're just hooking the message - m_listCtrl->Disconnect(wxEVT_PAINT, (wxObjectEventFunction)NULL, NULL, this); - m_listCtrl->GetEventHandler()->ProcessEvent(event); - m_listCtrl->Connect(wxEVT_PAINT, wxPaintEventHandler(CMainFrame::OnPaintListCtrl), NULL, this); } @@ -1033,8 +1061,10 @@ void CMainFrame::OnUpdateUIOptionsGenerate(wxUpdateUIEvent& event) void CMainFrame::OnMenuOptionsChangeYourAddress(wxCommandEvent& event) { - // Options->Change Your Address - OnButtonChange(event); + // Options->Your Receiving Addresses + CAddressBookDialog dialog(this, "", CAddressBookDialog::RECEIVING, false); + if (!dialog.ShowModal()) + return; } void CMainFrame::OnMenuOptionsOptions(wxCommandEvent& event) @@ -1061,11 +1091,11 @@ void CMainFrame::OnButtonSend(wxCommandEvent& event) void CMainFrame::OnButtonAddressBook(wxCommandEvent& event) { // Toolbar: Address Book - CAddressBookDialog dialogAddr(this, "", false); + CAddressBookDialog dialogAddr(this, "", CAddressBookDialog::SENDING, false); if (dialogAddr.ShowModal() == 2) { // Send - CSendDialog dialogSend(this, dialogAddr.GetAddress()); + CSendDialog dialogSend(this, dialogAddr.GetSelectedAddress()); dialogSend.ShowModal(); } } @@ -1073,35 +1103,36 @@ void CMainFrame::OnButtonAddressBook(wxCommandEvent& event) void CMainFrame::OnSetFocusAddress(wxFocusEvent& event) { // Automatically select-all when entering window + event.Skip(); m_textCtrlAddress->SetSelection(-1, -1); fOnSetFocusAddress = true; - event.Skip(); } void CMainFrame::OnMouseEventsAddress(wxMouseEvent& event) { + event.Skip(); if (fOnSetFocusAddress) m_textCtrlAddress->SetSelection(-1, -1); fOnSetFocusAddress = false; - event.Skip(); } -void CMainFrame::OnButtonChange(wxCommandEvent& event) +void CMainFrame::OnButtonNew(wxCommandEvent& event) { - CYourAddressDialog dialog(this, string(m_textCtrlAddress->GetValue())); + // Ask name + CGetTextFromUserDialog dialog(this, + _("New Receiving Address"), + _("It's good policy to use a new address for each payment you receive.\n\nLabel"), + ""); if (!dialog.ShowModal()) return; - string strAddress = (string)dialog.GetAddress(); - if (strAddress != m_textCtrlAddress->GetValue()) - { - uint160 hash160; - if (!AddressToHash160(strAddress, hash160)) - return; - if (!mapPubKeys.count(hash160)) - return; - CWalletDB().WriteDefaultKey(mapPubKeys[hash160]); - m_textCtrlAddress->SetValue(strAddress); - } + string strName = dialog.GetValue(); + + // Generate new key + string strAddress = PubKeyToAddress(GenerateNewKey()); + + // Save + SetAddressBookName(strAddress, strName); + SetDefaultReceivingAddress(strAddress); } void CMainFrame::OnButtonCopy(wxCommandEvent& event) @@ -1139,7 +1170,6 @@ void CMainFrame::OnListItemActivated(wxListEvent& event) - ////////////////////////////////////////////////////////////////////////////// // // CTxDetailsDialog @@ -1452,6 +1482,7 @@ void COptionsDialog::OnListBox(wxCommandEvent& event) void COptionsDialog::OnKillFocusTransactionFee(wxFocusEvent& event) { + event.Skip(); int64 nTmp = nTransactionFee; ParseMoney(m_textCtrlTransactionFee->GetValue(), nTmp); m_textCtrlTransactionFee->SetValue(FormatMoney(nTmp)); @@ -1485,6 +1516,7 @@ CAddress COptionsDialog::GetProxyAddr() void COptionsDialog::OnKillFocusProxy(wxFocusEvent& event) { + event.Skip(); m_textCtrlProxyIP->SetValue(GetProxyAddr().ToStringIP()); m_textCtrlProxyPort->SetValue(GetProxyAddr().ToStringPort()); } @@ -1632,6 +1664,7 @@ CSendDialog::CSendDialog(wxWindow* parent, const wxString& strAddress) : CSendDi void CSendDialog::OnTextAddress(wxCommandEvent& event) { // Check mark + event.Skip(); bool fBitcoinAddress = IsValidBitcoinAddress(m_textCtrlAddress->GetValue()); m_bitmapCheckMark->Show(fBitcoinAddress); @@ -1660,6 +1693,7 @@ void CSendDialog::OnTextAddress(wxCommandEvent& event) void CSendDialog::OnKillFocusAmount(wxFocusEvent& event) { // Reformat the amount + event.Skip(); if (m_textCtrlAmount->GetValue().Trim().empty()) return; int64 nTmp; @@ -1670,9 +1704,9 @@ void CSendDialog::OnKillFocusAmount(wxFocusEvent& event) void CSendDialog::OnButtonAddressBook(wxCommandEvent& event) { // Open address book - CAddressBookDialog dialog(this, m_textCtrlAddress->GetValue(), true); + CAddressBookDialog dialog(this, m_textCtrlAddress->GetValue(), CAddressBookDialog::SENDING, true); if (dialog.ShowModal()) - m_textCtrlAddress->SetValue(dialog.GetAddress()); + m_textCtrlAddress->SetValue(dialog.GetSelectedAddress()); } void CSendDialog::OnButtonPaste(wxCommandEvent& event) @@ -1723,11 +1757,11 @@ void CSendDialog::OnButtonSend(wxCommandEvent& event) CScript scriptPubKey; scriptPubKey << OP_DUP << OP_HASH160 << hash160 << OP_EQUALVERIFY << OP_CHECKSIG; - string strError = SendMoney(scriptPubKey, nValue, wtx); - if (strError != "") - wxMessageBox(strError + " ", _("Sending...")); - else + string strError = SendMoney(scriptPubKey, nValue, wtx, true); + if (strError == "") wxMessageBox(_("Payment sent "), _("Sending...")); + else if (strError != "ABORTED") + wxMessageBox(strError + " ", _("Sending...")); } else { @@ -1846,6 +1880,7 @@ void CSendingDialog::OnButtonCancel(wxCommandEvent& event) void CSendingDialog::OnPaint(wxPaintEvent& event) { + event.Skip(); if (strlen(pszStatus) > 130) m_textCtrlStatus->SetValue(string("\n") + pszStatus); else @@ -1869,7 +1904,6 @@ void CSendingDialog::OnPaint(wxPaintEvent& event) Close(); wxMessageBox(_("Transfer cancelled "), _("Sending..."), wxOK, this); } - event.Skip(); } @@ -2016,6 +2050,13 @@ void CSendingDialog::OnReply2(CDataStream& vRecv) return; } + // Transaction fee + if (!ThreadSafeAskFee(nFeeRequired, _("Sending..."), this)) + { + Error(_("Transaction aborted")); + return; + } + // Make sure we're still connected CNode* pnode = ConnectNode(addr, 2 * 60 * 60); if (!pnode) @@ -2040,20 +2081,15 @@ void CSendingDialog::OnReply2(CDataStream& vRecv) return; // Commit - if (!CommitTransactionSpent(wtx, key)) + if (!CommitTransaction(wtx, key)) { - Error(_("Error finalizing payment")); + Error(_("The transaction was rejected. This might happen if some of the coins in your wallet were already spent, such as if you used a copy of wallet.dat and coins were spent in the copy but not marked as spent here.")); return; } // Send payment tx to seller, with response going to OnReply3 via event handler pnode->PushRequest("submitorder", wtx, SendingDialogOnReply3, this); - // Accept and broadcast transaction - if (!wtx.AcceptTransaction()) - printf("ERROR: CSendingDialog : wtxNew.AcceptTransaction() %s failed\n", wtx.GetHash().ToString().c_str()); - wtx.RelayWalletTransaction(); - Status(_("Waiting for confirmation...")); MainFrameRepaint(); } @@ -2097,37 +2133,54 @@ void CSendingDialog::OnReply3(CDataStream& vRecv) ////////////////////////////////////////////////////////////////////////////// // -// CYourAddressDialog +// CAddressBookDialog // -CYourAddressDialog::CYourAddressDialog(wxWindow* parent, const string& strInitSelected) : CYourAddressDialogBase(parent) +CAddressBookDialog::CAddressBookDialog(wxWindow* parent, const wxString& strInitSelected, int nPageIn, bool fDuringSendIn) : CAddressBookDialogBase(parent) { + // Set initially selected page + wxNotebookEvent event; + event.SetSelection(nPageIn); + OnNotebookPageChanged(event); + m_notebook->ChangeSelection(nPageIn); + + fDuringSend = fDuringSendIn; + if (!fDuringSend) + m_buttonCancel->Show(false); + + // Set Icon + wxIcon iconAddressBook; + iconAddressBook.CopyFromBitmap(wxBitmap(addressbook16_xpm)); + SetIcon(iconAddressBook); + // Init column headers - m_listCtrl->InsertColumn(0, _("Label"), wxLIST_FORMAT_LEFT, 200); - m_listCtrl->InsertColumn(1, _("Bitcoin Address"), wxLIST_FORMAT_LEFT, 350); - m_listCtrl->SetFocus(); + m_listCtrlSending->InsertColumn(0, _("Name"), wxLIST_FORMAT_LEFT, 200); + m_listCtrlSending->InsertColumn(1, _("Address"), wxLIST_FORMAT_LEFT, 350); + m_listCtrlSending->SetFocus(); + m_listCtrlReceiving->InsertColumn(0, _("Label"), wxLIST_FORMAT_LEFT, 200); + m_listCtrlReceiving->InsertColumn(1, _("Bitcoin Address"), wxLIST_FORMAT_LEFT, 350); + m_listCtrlReceiving->SetFocus(); // Fill listctrl with address book data CRITICAL_BLOCK(cs_mapKeys) CRITICAL_BLOCK(cs_mapAddressBook) { + string strDefaultReceiving = (string)pframeMain->m_textCtrlAddress->GetValue(); foreach(const PAIRTYPE(string, string)& item, mapAddressBook) { string strAddress = item.first; string strName = item.second; uint160 hash160; bool fMine = (AddressToHash160(strAddress, hash160) && mapPubKeys.count(hash160)); - if (fMine) - { - int nIndex = InsertLine(m_listCtrl, strName, strAddress); - if (strAddress == strInitSelected) - m_listCtrl->SetItemState(nIndex, wxLIST_STATE_SELECTED|wxLIST_STATE_FOCUSED, wxLIST_STATE_SELECTED|wxLIST_STATE_FOCUSED); - } + wxListCtrl* plistCtrl = fMine ? m_listCtrlReceiving : m_listCtrlSending; + int nIndex = InsertLine(plistCtrl, strName, strAddress); + if (strAddress == (fMine ? strDefaultReceiving : strInitSelected)) + plistCtrl->SetItemState(nIndex, wxLIST_STATE_SELECTED|wxLIST_STATE_FOCUSED, wxLIST_STATE_SELECTED|wxLIST_STATE_FOCUSED); } } } -wxString CYourAddressDialog::GetAddress() +wxString CAddressBookDialog::GetSelectedAddress() { int nIndex = GetSelection(m_listCtrl); if (nIndex == -1) @@ -2135,172 +2188,92 @@ wxString CYourAddressDialog::GetAddress() return GetItemText(m_listCtrl, nIndex, 1); } -void CYourAddressDialog::OnListEndLabelEdit(wxListEvent& event) +wxString CAddressBookDialog::GetSelectedSendingAddress() { - // Update address book with edited name - if (event.IsEditCancelled()) - return; - string strAddress = (string)GetItemText(m_listCtrl, event.GetIndex(), 1); - SetAddressBookName(strAddress, string(event.GetText())); - pframeMain->RefreshListCtrl(); + int nIndex = GetSelection(m_listCtrlSending); + if (nIndex == -1) + return ""; + return GetItemText(m_listCtrlSending, nIndex, 1); } -void CYourAddressDialog::OnListItemSelected(wxListEvent& event) +wxString CAddressBookDialog::GetSelectedReceivingAddress() { + int nIndex = GetSelection(m_listCtrlReceiving); + if (nIndex == -1) + return ""; + return GetItemText(m_listCtrlReceiving, nIndex, 1); } -void CYourAddressDialog::OnListItemActivated(wxListEvent& event) +void CAddressBookDialog::OnNotebookPageChanged(wxNotebookEvent& event) { - // Doubleclick edits item - wxCommandEvent event2; - OnButtonRename(event2); + event.Skip(); + nPage = event.GetSelection(); + if (nPage == SENDING) + m_listCtrl = m_listCtrlSending; + else if (nPage == RECEIVING) + m_listCtrl = m_listCtrlReceiving; + m_buttonDelete->Show(nPage == SENDING); + m_buttonCopy->Show(nPage == RECEIVING); + this->Layout(); + m_listCtrl->SetFocus(); } -void CYourAddressDialog::OnButtonRename(wxCommandEvent& event) +void CAddressBookDialog::OnListEndLabelEdit(wxListEvent& event) { - // Ask new name - int nIndex = GetSelection(m_listCtrl); - if (nIndex == -1) - return; - string strName = (string)m_listCtrl->GetItemText(nIndex); - string strAddress = (string)GetItemText(m_listCtrl, nIndex, 1); - CGetTextFromUserDialog dialog(this, _("Edit Address Label"), _("New Label"), strName); - if (!dialog.ShowModal()) + // Update address book with edited name + event.Skip(); + if (event.IsEditCancelled()) return; - strName = dialog.GetValue(); - - // Change name - SetAddressBookName(strAddress, strName); - m_listCtrl->SetItemText(nIndex, strName); + string strAddress = (string)GetItemText(m_listCtrl, event.GetIndex(), 1); + SetAddressBookName(strAddress, string(event.GetText())); pframeMain->RefreshListCtrl(); } -void CYourAddressDialog::OnButtonNew(wxCommandEvent& event) +void CAddressBookDialog::OnListItemSelected(wxListEvent& event) { - // Ask name - CGetTextFromUserDialog dialog(this, _("New Bitcoin Address"), _("Label"), ""); - if (!dialog.ShowModal()) - return; - string strName = dialog.GetValue(); - - // Generate new key - string strAddress = PubKeyToAddress(GenerateNewKey()); - SetAddressBookName(strAddress, strName); - - // Add to list and select it - int nIndex = InsertLine(m_listCtrl, strName, strAddress); - SetSelection(m_listCtrl, nIndex); - m_listCtrl->SetFocus(); + event.Skip(); + if (nPage == RECEIVING) + SetDefaultReceivingAddress((string)GetSelectedReceivingAddress()); } -void CYourAddressDialog::OnButtonCopy(wxCommandEvent& event) +void CAddressBookDialog::OnListItemActivated(wxListEvent& event) { - // Copy address box to clipboard - if (wxTheClipboard->Open()) + event.Skip(); + if (fDuringSend) { - wxTheClipboard->SetData(new wxTextDataObject(GetAddress())); - wxTheClipboard->Close(); + // Doubleclick returns selection + EndModal(GetSelectedAddress() != "" ? 2 : 0); + return; } -} -void CYourAddressDialog::OnButtonOK(wxCommandEvent& event) -{ - // OK - EndModal(true); -} - -void CYourAddressDialog::OnButtonCancel(wxCommandEvent& event) -{ - // Cancel - EndModal(false); -} - -void CYourAddressDialog::OnClose(wxCloseEvent& event) -{ - // Close - EndModal(false); + // Doubleclick edits item + wxCommandEvent event2; + OnButtonEdit(event2); } - - - - - -////////////////////////////////////////////////////////////////////////////// -// -// CAddressBookDialog -// - -CAddressBookDialog::CAddressBookDialog(wxWindow* parent, const wxString& strInitSelected, bool fSendingIn) : CAddressBookDialogBase(parent) +void CAddressBookDialog::OnButtonDelete(wxCommandEvent& event) { - fSending = fSendingIn; - if (!fSending) - m_buttonCancel->Show(false); - - // Init column headers - m_listCtrl->InsertColumn(0, _("Name"), wxLIST_FORMAT_LEFT, 200); - m_listCtrl->InsertColumn(1, _("Address"), wxLIST_FORMAT_LEFT, 350); - m_listCtrl->SetFocus(); - - // Set Icon - wxIcon iconAddressBook; - iconAddressBook.CopyFromBitmap(wxBitmap(addressbook16_xpm)); - SetIcon(iconAddressBook); - - // Fill listctrl with address book data - CRITICAL_BLOCK(cs_mapKeys) - CRITICAL_BLOCK(cs_mapAddressBook) + if (nPage != SENDING) + return; + for (int nIndex = m_listCtrl->GetItemCount()-1; nIndex >= 0; nIndex--) { - foreach(const PAIRTYPE(string, string)& item, mapAddressBook) + if (m_listCtrl->GetItemState(nIndex, wxLIST_STATE_SELECTED)) { - string strAddress = item.first; - string strName = item.second; - uint160 hash160; - bool fMine = (AddressToHash160(strAddress, hash160) && mapPubKeys.count(hash160)); - if (!fMine) - { - int nIndex = InsertLine(m_listCtrl, strName, strAddress); - if (strAddress == strInitSelected) - m_listCtrl->SetItemState(nIndex, wxLIST_STATE_SELECTED|wxLIST_STATE_FOCUSED, wxLIST_STATE_SELECTED|wxLIST_STATE_FOCUSED); - } + string strAddress = (string)GetItemText(m_listCtrl, nIndex, 1); + CWalletDB().EraseName(strAddress); + m_listCtrl->DeleteItem(nIndex); } } -} - -wxString CAddressBookDialog::GetAddress() -{ - int nIndex = GetSelection(m_listCtrl); - if (nIndex == -1) - return ""; - return GetItemText(m_listCtrl, nIndex, 1); -} - -void CAddressBookDialog::OnListEndLabelEdit(wxListEvent& event) -{ - // Update address book with edited name - if (event.IsEditCancelled()) - return; - string strAddress = (string)GetItemText(m_listCtrl, event.GetIndex(), 1); - SetAddressBookName(strAddress, string(event.GetText())); pframeMain->RefreshListCtrl(); } -void CAddressBookDialog::OnListItemSelected(wxListEvent& event) -{ -} - -void CAddressBookDialog::OnListItemActivated(wxListEvent& event) +void CAddressBookDialog::OnButtonCopy(wxCommandEvent& event) { - if (fSending) - { - // Doubleclick returns selection - EndModal(GetAddress() != "" ? 2 : 0); - } - else + // Copy address box to clipboard + if (wxTheClipboard->Open()) { - // Doubleclick edits item - wxCommandEvent event2; - OnButtonEdit(event2); + wxTheClipboard->SetData(new wxTextDataObject(GetSelectedAddress())); + wxTheClipboard->Close(); } } @@ -2315,24 +2288,37 @@ bool CAddressBookDialog::CheckIfMine(const string& strAddress, const string& str void CAddressBookDialog::OnButtonEdit(wxCommandEvent& event) { - // Ask new name int nIndex = GetSelection(m_listCtrl); if (nIndex == -1) return; string strName = (string)m_listCtrl->GetItemText(nIndex); string strAddress = (string)GetItemText(m_listCtrl, nIndex, 1); string strAddressOrg = strAddress; - do + + if (nPage == SENDING) { - CGetTextFromUserDialog dialog(this, _("Edit Address"), _("Name"), strName, _("Address"), strAddress); + // Ask name and address + do + { + CGetTextFromUserDialog dialog(this, _("Edit Address"), _("Name"), strName, _("Address"), strAddress); + if (!dialog.ShowModal()) + return; + strName = dialog.GetValue1(); + strAddress = dialog.GetValue2(); + } + while (CheckIfMine(strAddress, _("Edit Address"))); + + } + else if (nPage == RECEIVING) + { + // Ask name + CGetTextFromUserDialog dialog(this, _("Edit Address Label"), _("Label"), strName); if (!dialog.ShowModal()) return; - strName = dialog.GetValue1(); - strAddress = dialog.GetValue2(); + strName = dialog.GetValue(); } - while (CheckIfMine(strAddress, _("Edit Address"))); - // Change name + // Write back if (strAddress != strAddressOrg) CWalletDB().EraseName(strAddressOrg); SetAddressBookName(strAddress, strName); @@ -2343,55 +2329,50 @@ void CAddressBookDialog::OnButtonEdit(wxCommandEvent& event) void CAddressBookDialog::OnButtonNew(wxCommandEvent& event) { - // Ask name string strName; string strAddress; - do + + if (nPage == SENDING) { - CGetTextFromUserDialog dialog(this, _("New Address"), _("Name"), strName, _("Address"), strAddress); + // Ask name and address + do + { + CGetTextFromUserDialog dialog(this, _("Add Address"), _("Name"), strName, _("Address"), strAddress); + if (!dialog.ShowModal()) + return; + strName = dialog.GetValue1(); + strAddress = dialog.GetValue2(); + } + while (CheckIfMine(strAddress, _("Add Address"))); + } + else if (nPage == RECEIVING) + { + // Ask name + CGetTextFromUserDialog dialog(this, + _("New Receiving Address"), + _("It's good policy to use a new address for each payment you receive.\n\nLabel"), + ""); if (!dialog.ShowModal()) return; - strName = dialog.GetValue1(); - strAddress = dialog.GetValue2(); + strName = dialog.GetValue(); + + // Generate new key + strAddress = PubKeyToAddress(GenerateNewKey()); } - while (CheckIfMine(strAddress, _("New Address"))); // Add to list and select it SetAddressBookName(strAddress, strName); int nIndex = InsertLine(m_listCtrl, strName, strAddress); SetSelection(m_listCtrl, nIndex); m_listCtrl->SetFocus(); - pframeMain->RefreshListCtrl(); -} - -void CAddressBookDialog::OnButtonDelete(wxCommandEvent& event) -{ - for (int nIndex = m_listCtrl->GetItemCount()-1; nIndex >= 0; nIndex--) - { - if (m_listCtrl->GetItemState(nIndex, wxLIST_STATE_SELECTED)) - { - string strAddress = (string)GetItemText(m_listCtrl, nIndex, 1); - CWalletDB().EraseName(strAddress); - m_listCtrl->DeleteItem(nIndex); - } - } - pframeMain->RefreshListCtrl(); -} - -void CAddressBookDialog::OnButtonCopy(wxCommandEvent& event) -{ - // Copy address box to clipboard - if (wxTheClipboard->Open()) - { - wxTheClipboard->SetData(new wxTextDataObject(GetAddress())); - wxTheClipboard->Close(); - } + if (nPage == SENDING) + pframeMain->RefreshListCtrl(); } void CAddressBookDialog::OnButtonOK(wxCommandEvent& event) { // OK - EndModal(GetAddress() != "" ? 1 : 0); + EndModal(GetSelectedAddress() != "" ? 1 : 0); } void CAddressBookDialog::OnButtonCancel(wxCommandEvent& event) @@ -2644,14 +2625,14 @@ bool CMyApp::OnInit2() wxString strUsage = string() + _("Usage: bitcoin [options]") + "\t\t\t\t\t\t\n" + _("Options:\n") + - " -gen \t\t " + _("Generate coins\n") + - " -gen=0 \t\t " + _("Don't generate coins\n") + - " -min \t\t " + _("Start minimized\n") + - " -datadir= \t " + _("Specify data directory\n") + - " -proxy=\t " + _("Connect through socks4 proxy\n") + - " -addnode= \t " + _("Add a node to connect to\n") + - " -connect= \t " + _("Connect only to the specified node\n") + - " -? \t\t " + _("This help message\n"); + " -gen \t\t " + _("Generate coins\n") + + " -gen=0 \t\t " + _("Don't generate coins\n") + + " -min \t\t " + _("Start minimized\n") + + " -datadir= \t " + _("Specify data directory\n") + + " -proxy=\t " + _("Connect through socks4 proxy\n") + + " -addnode= \t " + _("Add a node to connect to\n") + + " -connect= \t " + _("Connect only to the specified node\n") + + " -? \t\t " + _("This help message\n"); if (fWindows) { @@ -2947,7 +2928,6 @@ bool CMyApp::OnExceptionInMainLoop() Sleep(1000); throw; } - return true; } diff --git a/ui.h b/ui.h index 50d39ab7..317b87e9 100644 --- a/ui.h +++ b/ui.h @@ -2,11 +2,9 @@ // Distributed under the MIT/X11 software license, see the accompanying // file license.txt or http://www.opensource.org/licenses/mit-license.php. - - - DECLARE_EVENT_TYPE(wxEVT_UITHREADCALL, -1) + extern map mapArgs; // Settings @@ -22,6 +20,7 @@ void UIThreadCall(boost::function0); void MainFrameRepaint(); void Shutdown(void* parg); int ThreadSafeMessageBox(const string& message, const string& caption="Message", int style=wxOK, wxWindow* parent=NULL, int x=-1, int y=-1); +bool ThreadSafeAskFee(int64 nFeeRequired, const string& strCaption, wxWindow* parent); @@ -51,7 +50,7 @@ protected: void OnButtonAddressBook(wxCommandEvent& event); void OnSetFocusAddress(wxFocusEvent& event); void OnMouseEventsAddress(wxMouseEvent& event); - void OnButtonChange(wxCommandEvent& event); + void OnButtonNew(wxCommandEvent& event); void OnButtonCopy(wxCommandEvent& event); void OnListColBeginDrag(wxListEvent& event); void OnListItemActivated(wxListEvent& event); @@ -205,53 +204,39 @@ void SendingDialogOnReply3(void* parg, CDataStream& vRecv); -class CYourAddressDialog : public CYourAddressDialogBase -{ -protected: - // Event handlers - void OnListEndLabelEdit(wxListEvent& event); - void OnListItemSelected(wxListEvent& event); - void OnListItemActivated(wxListEvent& event); - void OnButtonRename(wxCommandEvent& event); - void OnButtonNew(wxCommandEvent& event); - void OnButtonCopy(wxCommandEvent& event); - void OnButtonOK(wxCommandEvent& event); - void OnButtonCancel(wxCommandEvent& event); - void OnClose(wxCloseEvent& event); - -public: - /** Constructor */ - CYourAddressDialog(wxWindow* parent); - CYourAddressDialog(wxWindow* parent, const string& strInitSelected); - - // Custom - wxString GetAddress(); -}; - - - class CAddressBookDialog : public CAddressBookDialogBase { protected: // Event handlers + void OnNotebookPageChanged(wxNotebookEvent& event); void OnListEndLabelEdit(wxListEvent& event); void OnListItemSelected(wxListEvent& event); void OnListItemActivated(wxListEvent& event); - void OnButtonEdit(wxCommandEvent& event); void OnButtonDelete(wxCommandEvent& event); - void OnButtonNew(wxCommandEvent& event); void OnButtonCopy(wxCommandEvent& event); + void OnButtonEdit(wxCommandEvent& event); + void OnButtonNew(wxCommandEvent& event); void OnButtonOK(wxCommandEvent& event); void OnButtonCancel(wxCommandEvent& event); void OnClose(wxCloseEvent& event); public: /** Constructor */ - CAddressBookDialog(wxWindow* parent, const wxString& strInitSelected, bool fSendingIn); + CAddressBookDialog(wxWindow* parent, const wxString& strInitSelected, int nPageIn, bool fDuringSendIn); // Custom - bool fSending; + enum + { + SENDING = 0, + RECEIVING = 1, + }; + int nPage; + wxListCtrl* m_listCtrl; + bool fDuringSend; wxString GetAddress(); + wxString GetSelectedAddress(); + wxString GetSelectedSendingAddress(); + wxString GetSelectedReceivingAddress(); bool CheckIfMine(const string& strAddress, const string& strTitle); }; @@ -282,18 +267,25 @@ public: const string& strMessage2="", const string& strValue2="") : CGetTextFromUserDialogBase(parent, wxID_ANY, strCaption) { + int x = GetSize().GetWidth(); + int y = GetSize().GetHeight(); m_staticTextMessage1->SetLabel(strMessage1); m_textCtrl1->SetValue(strValue1); + y += wxString(strMessage1).Freq('\n') * 14; if (!strMessage2.empty()) { m_staticTextMessage2->Show(true); m_staticTextMessage2->SetLabel(strMessage2); m_textCtrl2->Show(true); m_textCtrl2->SetValue(strValue2); - SetSize(wxDefaultCoord, 180); + y += 46 + wxString(strMessage2).Freq('\n') * 14; } if (!fWindows) - SetSize(1.14 * GetSize().GetWidth(), 1.14 * GetSize().GetHeight()); + { + x *= 1.14; + y *= 1.14; + } + SetSize(x, y); } // Custom diff --git a/uibase.cpp b/uibase.cpp index 5b3f9abc..340c7abc 100644 --- a/uibase.cpp +++ b/uibase.cpp @@ -42,14 +42,14 @@ CMainFrameBase::CMainFrameBase( wxWindow* parent, wxWindowID id, const wxString& m_menuOptions->Append( m_menuOptionsGenerateBitcoins ); wxMenuItem* m_menuOptionsChangeYourAddress; - m_menuOptionsChangeYourAddress = new wxMenuItem( m_menuOptions, wxID_ANY, wxString( _("&Change Your Address...") ) , wxEmptyString, wxITEM_NORMAL ); + m_menuOptionsChangeYourAddress = new wxMenuItem( m_menuOptions, wxID_ANY, wxString( _("&Your Receiving Addresses...") ) , wxEmptyString, wxITEM_NORMAL ); m_menuOptions->Append( m_menuOptionsChangeYourAddress ); wxMenuItem* m_menuOptionsOptions; m_menuOptionsOptions = new wxMenuItem( m_menuOptions, wxID_MENUOPTIONSOPTIONS, wxString( _("&Options...") ) , wxEmptyString, wxITEM_NORMAL ); m_menuOptions->Append( m_menuOptionsOptions ); - m_menubar->Append( m_menuOptions, _("&Options") ); + m_menubar->Append( m_menuOptions, _("&Settings") ); m_menuHelp = new wxMenu(); wxMenuItem* m_menuHelpAbout; @@ -65,8 +65,8 @@ CMainFrameBase::CMainFrameBase( wxWindow* parent, wxWindowID id, const wxString& m_toolBar->SetToolSeparation( 1 ); m_toolBar->SetFont( wxFont( wxNORMAL_FONT->GetPointSize(), 70, 90, 90, false, wxEmptyString ) ); - m_toolBar->AddTool( wxID_BUTTONSEND, _("&Send Coins"), wxBitmap( send20_xpm ), wxNullBitmap, wxITEM_NORMAL, wxEmptyString, wxEmptyString ); - m_toolBar->AddTool( wxID_BUTTONRECEIVE, _("&Address Book"), wxBitmap( addressbook20_xpm ), wxNullBitmap, wxITEM_NORMAL, wxEmptyString, wxEmptyString ); + m_toolBar->AddTool( wxID_BUTTONSEND, _("Send Coins"), wxBitmap( send20_xpm ), wxNullBitmap, wxITEM_NORMAL, wxEmptyString, wxEmptyString ); + m_toolBar->AddTool( wxID_BUTTONRECEIVE, _("Address Book"), wxBitmap( addressbook20_xpm ), wxNullBitmap, wxITEM_NORMAL, wxEmptyString, wxEmptyString ); m_toolBar->Realize(); m_statusBar = this->CreateStatusBar( 1, wxST_SIZEGRIP, wxID_ANY ); @@ -86,14 +86,10 @@ CMainFrameBase::CMainFrameBase( wxWindow* parent, wxWindowID id, const wxString& bSizer85->Add( m_staticText32, 0, wxALIGN_CENTER_VERTICAL|wxLEFT, 5 ); m_textCtrlAddress = new wxTextCtrl( this, wxID_TEXTCTRLADDRESS, wxEmptyString, wxDefaultPosition, wxSize( 340,-1 ), wxTE_READONLY ); - m_textCtrlAddress->SetBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_MENU ) ); - bSizer85->Add( m_textCtrlAddress, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 ); - m_buttonNew = new wxButton( this, wxID_BUTTONCHANGE, _("&New..."), wxDefaultPosition, wxDefaultSize, 0 ); - m_buttonNew->Hide(); - - bSizer85->Add( m_buttonNew, 0, wxRIGHT, 5 ); + m_buttonNew = new wxButton( this, wxID_BUTTONNEW, _(" &New... "), wxDefaultPosition, wxSize( -1,-1 ), wxBU_EXACTFIT ); + bSizer85->Add( m_buttonNew, 0, wxRIGHT|wxALIGN_CENTER_VERTICAL, 5 ); m_buttonCopy = new wxButton( this, wxID_BUTTONCOPY, _(" &Copy to Clipboard "), wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT ); bSizer85->Add( m_buttonCopy, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 5 ); @@ -188,7 +184,7 @@ CMainFrameBase::CMainFrameBase( wxWindow* parent, wxWindowID id, const wxString& m_textCtrlAddress->Connect( wxEVT_ENTER_WINDOW, wxMouseEventHandler( CMainFrameBase::OnMouseEventsAddress ), NULL, this ); m_textCtrlAddress->Connect( wxEVT_MOUSEWHEEL, wxMouseEventHandler( CMainFrameBase::OnMouseEventsAddress ), NULL, this ); m_textCtrlAddress->Connect( wxEVT_SET_FOCUS, wxFocusEventHandler( CMainFrameBase::OnSetFocusAddress ), NULL, this ); - m_buttonNew->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CMainFrameBase::OnButtonChange ), NULL, this ); + m_buttonNew->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CMainFrameBase::OnButtonNew ), NULL, this ); m_buttonCopy->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CMainFrameBase::OnButtonCopy ), NULL, this ); m_listCtrl->Connect( wxEVT_COMMAND_LIST_COL_BEGIN_DRAG, wxListEventHandler( CMainFrameBase::OnListColBeginDrag ), NULL, this ); m_listCtrl->Connect( wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler( CMainFrameBase::OnListItemActivated ), NULL, this ); @@ -240,7 +236,7 @@ CMainFrameBase::~CMainFrameBase() m_textCtrlAddress->Disconnect( wxEVT_ENTER_WINDOW, wxMouseEventHandler( CMainFrameBase::OnMouseEventsAddress ), NULL, this ); m_textCtrlAddress->Disconnect( wxEVT_MOUSEWHEEL, wxMouseEventHandler( CMainFrameBase::OnMouseEventsAddress ), NULL, this ); m_textCtrlAddress->Disconnect( wxEVT_SET_FOCUS, wxFocusEventHandler( CMainFrameBase::OnSetFocusAddress ), NULL, this ); - m_buttonNew->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CMainFrameBase::OnButtonChange ), NULL, this ); + m_buttonNew->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CMainFrameBase::OnButtonNew ), NULL, this ); m_buttonCopy->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CMainFrameBase::OnButtonCopy ), NULL, this ); m_listCtrl->Disconnect( wxEVT_COMMAND_LIST_COL_BEGIN_DRAG, wxListEventHandler( CMainFrameBase::OnListColBeginDrag ), NULL, this ); m_listCtrl->Disconnect( wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler( CMainFrameBase::OnListItemActivated ), NULL, this ); @@ -844,20 +840,53 @@ CAddressBookDialogBase::CAddressBookDialogBase( wxWindow* parent, wxWindowID id, { this->SetSizeHints( wxDefaultSize, wxDefaultSize ); + wxBoxSizer* bSizer58; + bSizer58 = new wxBoxSizer( wxVERTICAL ); + + m_notebook = new wxNotebook( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 ); + m_panelSending = new wxPanel( m_notebook, wxID_PANELSENDING, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL ); wxBoxSizer* bSizer68; bSizer68 = new wxBoxSizer( wxVERTICAL ); - bSizer68->Add( 0, 5, 0, wxEXPAND, 5 ); + bSizer68->Add( 0, 0, 0, wxEXPAND, 5 ); - m_staticText55 = new wxStaticText( this, wxID_ANY, _("Bitcoin Address"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticText55 = new wxStaticText( m_panelSending, wxID_ANY, _("Bitcoin Address"), wxDefaultPosition, wxDefaultSize, 0 ); m_staticText55->Wrap( -1 ); m_staticText55->Hide(); bSizer68->Add( m_staticText55, 0, wxTOP|wxRIGHT|wxLEFT, 5 ); - m_listCtrl = new wxListCtrl( this, wxID_LISTCTRL, wxDefaultPosition, wxDefaultSize, wxLC_NO_SORT_HEADER|wxLC_REPORT|wxLC_SORT_ASCENDING ); - bSizer68->Add( m_listCtrl, 1, wxALL|wxEXPAND, 5 ); + m_listCtrlSending = new wxListCtrl( m_panelSending, wxID_LISTCTRLSENDING, wxDefaultPosition, wxDefaultSize, wxLC_NO_SORT_HEADER|wxLC_REPORT|wxLC_SORT_ASCENDING ); + bSizer68->Add( m_listCtrlSending, 1, wxALL|wxEXPAND, 5 ); + + m_panelSending->SetSizer( bSizer68 ); + m_panelSending->Layout(); + bSizer68->Fit( m_panelSending ); + m_notebook->AddPage( m_panelSending, _("Sending"), false ); + m_panelReceiving = new wxPanel( m_notebook, wxID_PANELRECEIVING, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL ); + wxBoxSizer* bSizer681; + bSizer681 = new wxBoxSizer( wxVERTICAL ); + + + bSizer681->Add( 0, 0, 0, wxEXPAND, 5 ); + + m_staticText45 = new wxStaticText( m_panelReceiving, wxID_ANY, _("These are your Bitcoin addresses for receiving payments. You can give a different one to each sender to keep track of who is paying you. The highlighted address will be displayed in the main window."), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticText45->Wrap( 570 ); + bSizer681->Add( m_staticText45, 0, wxTOP|wxRIGHT|wxLEFT, 6 ); + + + bSizer681->Add( 0, 2, 0, wxEXPAND, 5 ); + + m_listCtrlReceiving = new wxListCtrl( m_panelReceiving, wxID_LISTCTRLRECEIVING, wxDefaultPosition, wxDefaultSize, wxLC_NO_SORT_HEADER|wxLC_REPORT|wxLC_SORT_ASCENDING ); + bSizer681->Add( m_listCtrlReceiving, 1, wxALL|wxEXPAND, 5 ); + + m_panelReceiving->SetSizer( bSizer681 ); + m_panelReceiving->Layout(); + bSizer681->Fit( m_panelReceiving ); + m_notebook->AddPage( m_panelReceiving, _("Receiving"), true ); + + bSizer58->Add( m_notebook, 1, wxEXPAND|wxTOP|wxRIGHT|wxLEFT, 5 ); wxBoxSizer* bSizer69; bSizer69 = new wxBoxSizer( wxHORIZONTAL ); @@ -865,34 +894,42 @@ CAddressBookDialogBase::CAddressBookDialogBase( wxWindow* parent, wxWindowID id, bSizer69->Add( 0, 0, 1, wxEXPAND, 5 ); + m_buttonDelete = new wxButton( this, wxID_BUTTONDELETE, _("&Delete"), wxDefaultPosition, wxDefaultSize, 0 ); + bSizer69->Add( m_buttonDelete, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); + + m_buttonCopy = new wxButton( this, wxID_BUTTONCOPY, _(" &Copy to Clipboard "), wxDefaultPosition, wxSize( -1,-1 ), 0 ); + bSizer69->Add( m_buttonCopy, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); + m_buttonEdit = new wxButton( this, wxID_BUTTONEDIT, _("&Edit..."), wxDefaultPosition, wxDefaultSize, 0 ); bSizer69->Add( m_buttonEdit, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); m_buttonNew = new wxButton( this, wxID_BUTTONNEW, _(" &New Address... "), wxDefaultPosition, wxDefaultSize, 0 ); bSizer69->Add( m_buttonNew, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); - m_buttonDelete = new wxButton( this, wxID_BUTTONDELETE, _("&Delete"), wxDefaultPosition, wxDefaultSize, 0 ); - bSizer69->Add( m_buttonDelete, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); - m_buttonOK = new wxButton( this, wxID_OK, _("OK"), wxDefaultPosition, wxSize( -1,-1 ), 0 ); bSizer69->Add( m_buttonOK, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); m_buttonCancel = new wxButton( this, wxID_CANCEL, _("Cancel"), wxDefaultPosition, wxSize( -1,-1 ), 0 ); bSizer69->Add( m_buttonCancel, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); - bSizer68->Add( bSizer69, 0, wxEXPAND, 5 ); + bSizer58->Add( bSizer69, 0, wxEXPAND, 5 ); - this->SetSizer( bSizer68 ); + this->SetSizer( bSizer58 ); this->Layout(); // Connect Events this->Connect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( CAddressBookDialogBase::OnClose ) ); - m_listCtrl->Connect( wxEVT_COMMAND_LIST_END_LABEL_EDIT, wxListEventHandler( CAddressBookDialogBase::OnListEndLabelEdit ), NULL, this ); - m_listCtrl->Connect( wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler( CAddressBookDialogBase::OnListItemActivated ), NULL, this ); - m_listCtrl->Connect( wxEVT_COMMAND_LIST_ITEM_SELECTED, wxListEventHandler( CAddressBookDialogBase::OnListItemSelected ), NULL, this ); + m_notebook->Connect( wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGED, wxNotebookEventHandler( CAddressBookDialogBase::OnNotebookPageChanged ), NULL, this ); + m_listCtrlSending->Connect( wxEVT_COMMAND_LIST_END_LABEL_EDIT, wxListEventHandler( CAddressBookDialogBase::OnListEndLabelEdit ), NULL, this ); + m_listCtrlSending->Connect( wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler( CAddressBookDialogBase::OnListItemActivated ), NULL, this ); + m_listCtrlSending->Connect( wxEVT_COMMAND_LIST_ITEM_SELECTED, wxListEventHandler( CAddressBookDialogBase::OnListItemSelected ), NULL, this ); + m_listCtrlReceiving->Connect( wxEVT_COMMAND_LIST_END_LABEL_EDIT, wxListEventHandler( CAddressBookDialogBase::OnListEndLabelEdit ), NULL, this ); + m_listCtrlReceiving->Connect( wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler( CAddressBookDialogBase::OnListItemActivated ), NULL, this ); + m_listCtrlReceiving->Connect( wxEVT_COMMAND_LIST_ITEM_SELECTED, wxListEventHandler( CAddressBookDialogBase::OnListItemSelected ), NULL, this ); + m_buttonDelete->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CAddressBookDialogBase::OnButtonDelete ), NULL, this ); + m_buttonCopy->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CAddressBookDialogBase::OnButtonCopy ), NULL, this ); m_buttonEdit->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CAddressBookDialogBase::OnButtonEdit ), NULL, this ); m_buttonNew->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CAddressBookDialogBase::OnButtonNew ), NULL, this ); - m_buttonDelete->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CAddressBookDialogBase::OnButtonDelete ), NULL, this ); m_buttonOK->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CAddressBookDialogBase::OnButtonOK ), NULL, this ); m_buttonCancel->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CAddressBookDialogBase::OnButtonCancel ), NULL, this ); } @@ -901,12 +938,17 @@ CAddressBookDialogBase::~CAddressBookDialogBase() { // Disconnect Events this->Disconnect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( CAddressBookDialogBase::OnClose ) ); - m_listCtrl->Disconnect( wxEVT_COMMAND_LIST_END_LABEL_EDIT, wxListEventHandler( CAddressBookDialogBase::OnListEndLabelEdit ), NULL, this ); - m_listCtrl->Disconnect( wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler( CAddressBookDialogBase::OnListItemActivated ), NULL, this ); - m_listCtrl->Disconnect( wxEVT_COMMAND_LIST_ITEM_SELECTED, wxListEventHandler( CAddressBookDialogBase::OnListItemSelected ), NULL, this ); + m_notebook->Disconnect( wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGED, wxNotebookEventHandler( CAddressBookDialogBase::OnNotebookPageChanged ), NULL, this ); + m_listCtrlSending->Disconnect( wxEVT_COMMAND_LIST_END_LABEL_EDIT, wxListEventHandler( CAddressBookDialogBase::OnListEndLabelEdit ), NULL, this ); + m_listCtrlSending->Disconnect( wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler( CAddressBookDialogBase::OnListItemActivated ), NULL, this ); + m_listCtrlSending->Disconnect( wxEVT_COMMAND_LIST_ITEM_SELECTED, wxListEventHandler( CAddressBookDialogBase::OnListItemSelected ), NULL, this ); + m_listCtrlReceiving->Disconnect( wxEVT_COMMAND_LIST_END_LABEL_EDIT, wxListEventHandler( CAddressBookDialogBase::OnListEndLabelEdit ), NULL, this ); + m_listCtrlReceiving->Disconnect( wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler( CAddressBookDialogBase::OnListItemActivated ), NULL, this ); + m_listCtrlReceiving->Disconnect( wxEVT_COMMAND_LIST_ITEM_SELECTED, wxListEventHandler( CAddressBookDialogBase::OnListItemSelected ), NULL, this ); + m_buttonDelete->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CAddressBookDialogBase::OnButtonDelete ), NULL, this ); + m_buttonCopy->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CAddressBookDialogBase::OnButtonCopy ), NULL, this ); m_buttonEdit->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CAddressBookDialogBase::OnButtonEdit ), NULL, this ); m_buttonNew->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CAddressBookDialogBase::OnButtonNew ), NULL, this ); - m_buttonDelete->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CAddressBookDialogBase::OnButtonDelete ), NULL, this ); m_buttonOK->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CAddressBookDialogBase::OnButtonOK ), NULL, this ); m_buttonCancel->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CAddressBookDialogBase::OnButtonCancel ), NULL, this ); } diff --git a/uibase.h b/uibase.h index 494ed10f..90abd00f 100644 --- a/uibase.h +++ b/uibase.h @@ -36,6 +36,7 @@ #include #include #include +#include /////////////////////////////////////////////////////////////////////////// @@ -46,7 +47,7 @@ #define wxID_BUTTONSEND 1004 #define wxID_BUTTONRECEIVE 1005 #define wxID_TEXTCTRLADDRESS 1006 -#define wxID_BUTTONCHANGE 1007 +#define wxID_BUTTONNEW 1007 #define wxID_BUTTONCOPY 1008 #define wxID_TRANSACTIONFEE 1009 #define wxID_PROXYIP 1010 @@ -58,10 +59,13 @@ #define wxID_CHOICETRANSFERTYPE 1016 #define wxID_LISTCTRL 1017 #define wxID_BUTTONRENAME 1018 -#define wxID_BUTTONNEW 1019 -#define wxID_BUTTONEDIT 1020 -#define wxID_BUTTONDELETE 1021 -#define wxID_TEXTCTRL 1022 +#define wxID_PANELSENDING 1019 +#define wxID_LISTCTRLSENDING 1020 +#define wxID_PANELRECEIVING 1021 +#define wxID_LISTCTRLRECEIVING 1022 +#define wxID_BUTTONDELETE 1023 +#define wxID_BUTTONEDIT 1024 +#define wxID_TEXTCTRL 1025 /////////////////////////////////////////////////////////////////////////////// /// Class CMainFrameBase @@ -79,7 +83,6 @@ class CMainFrameBase : public wxFrame wxStatusBar* m_statusBar; wxStaticText* m_staticText32; - wxTextCtrl* m_textCtrlAddress; wxButton* m_buttonNew; wxButton* m_buttonCopy; @@ -108,7 +111,7 @@ class CMainFrameBase : public wxFrame virtual void OnKeyDown( wxKeyEvent& event ){ event.Skip(); } virtual void OnMouseEventsAddress( wxMouseEvent& event ){ event.Skip(); } virtual void OnSetFocusAddress( wxFocusEvent& event ){ event.Skip(); } - virtual void OnButtonChange( wxCommandEvent& event ){ event.Skip(); } + virtual void OnButtonNew( wxCommandEvent& event ){ event.Skip(); } virtual void OnButtonCopy( wxCommandEvent& event ){ event.Skip(); } virtual void OnListColBeginDrag( wxListEvent& event ){ event.Skip(); } virtual void OnListItemActivated( wxListEvent& event ){ event.Skip(); } @@ -117,6 +120,7 @@ class CMainFrameBase : public wxFrame public: wxMenu* m_menuOptions; + wxTextCtrl* m_textCtrlAddress; wxListCtrl* m_listCtrl; CMainFrameBase( wxWindow* parent, wxWindowID id = wxID_MAINFRAME, const wxString& title = _("Bitcoin"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 712,484 ), long style = wxDEFAULT_FRAME_STYLE|wxRESIZE_BORDER|wxTAB_TRAVERSAL ); ~CMainFrameBase(); @@ -343,23 +347,33 @@ class CAddressBookDialogBase : public wxDialog private: protected: + wxNotebook* m_notebook; + wxPanel* m_panelSending; wxStaticText* m_staticText55; - wxListCtrl* m_listCtrl; + wxListCtrl* m_listCtrlSending; + wxPanel* m_panelReceiving; + + wxStaticText* m_staticText45; + + wxListCtrl* m_listCtrlReceiving; + wxButton* m_buttonDelete; + wxButton* m_buttonCopy; wxButton* m_buttonEdit; wxButton* m_buttonNew; - wxButton* m_buttonDelete; wxButton* m_buttonOK; // Virtual event handlers, overide them in your derived class virtual void OnClose( wxCloseEvent& event ){ event.Skip(); } + virtual void OnNotebookPageChanged( wxNotebookEvent& event ){ event.Skip(); } virtual void OnListEndLabelEdit( wxListEvent& event ){ event.Skip(); } virtual void OnListItemActivated( wxListEvent& event ){ event.Skip(); } virtual void OnListItemSelected( wxListEvent& event ){ event.Skip(); } + virtual void OnButtonDelete( wxCommandEvent& event ){ event.Skip(); } + virtual void OnButtonCopy( wxCommandEvent& event ){ event.Skip(); } virtual void OnButtonEdit( wxCommandEvent& event ){ event.Skip(); } virtual void OnButtonNew( wxCommandEvent& event ){ event.Skip(); } - virtual void OnButtonDelete( wxCommandEvent& event ){ event.Skip(); } virtual void OnButtonOK( wxCommandEvent& event ){ event.Skip(); } virtual void OnButtonCancel( wxCommandEvent& event ){ event.Skip(); } @@ -397,7 +411,7 @@ class CGetTextFromUserDialogBase : public wxDialog public: - CGetTextFromUserDialogBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxEmptyString, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 403,138 ), long style = wxDEFAULT_DIALOG_STYLE ); + CGetTextFromUserDialogBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxEmptyString, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 440,138 ), long style = wxDEFAULT_DIALOG_STYLE ); ~CGetTextFromUserDialogBase(); }; diff --git a/uiproject.fbp b/uiproject.fbp index 988df2a9..113a1579 100644 --- a/uiproject.fbp +++ b/uiproject.fbp @@ -155,7 +155,7 @@ - &Options + &Settings m_menuOptions public @@ -180,7 +180,7 @@ wxID_ANY wxITEM_NORMAL - &Change Your Address... + &Your Receiving Addresses... m_menuOptionsChangeYourAddress none @@ -276,7 +276,7 @@ xpm/send20.xpm; Load From File wxID_BUTTONSEND wxITEM_NORMAL - &Send Coins + Send Coins m_tool1 @@ -290,7 +290,7 @@ xpm/addressbook20.xpm; Load From File wxID_BUTTONRECEIVE wxITEM_NORMAL - &Address Book + Address Book m_tool2 @@ -426,7 +426,7 @@ wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT 0 - wxSYS_COLOUR_MENU + 1 @@ -437,7 +437,7 @@ 0 -1,-1 m_textCtrlAddress - protected + public 340,-1 wxTE_READONLY @@ -478,7 +478,7 @@ 5 - wxRIGHT + wxRIGHT|wxALIGN_CENTER_VERTICAL 0 @@ -487,22 +487,22 @@ 1 - 1 - wxID_BUTTONCHANGE - &New... + 0 + wxID_BUTTONNEW + &New... m_buttonNew protected - - + -1,-1 + wxBU_EXACTFIT - OnButtonChange + OnButtonNew @@ -4388,7 +4388,7 @@ 5 wxEXPAND 0 - + bSizer69 wxHORIZONTAL @@ -4721,89 +4721,29 @@ - bSizer68 + bSizer58 wxVERTICAL none 5 - wxEXPAND - 0 - - 5 - protected - 0 - - - - 5 - wxTOP|wxRIGHT|wxLEFT - 0 - - - - 1 - - - 1 - wxID_ANY - Bitcoin Address - - - m_staticText55 - protected - - - - - - - - - -1 - - - - - - - - - - - - - - - - - - - - - - - - - - - 5 - wxALL|wxEXPAND + wxEXPAND|wxTOP|wxRIGHT|wxLEFT 1 - + + 1 0 - wxID_LISTCTRL + wxID_ANY - m_listCtrl + m_notebook protected - wxLC_NO_SORT_HEADER|wxLC_REPORT|wxLC_SORT_ASCENDING + @@ -4819,32 +4759,14 @@ - - - - - - - - - - - - OnListEndLabelEdit - - OnListItemActivated - - - - - OnListItemSelected - + OnNotebookPageChanged + @@ -4852,6 +4774,384 @@ + + + Sending + 0 + + + + 1 + + + 0 + wxID_PANELSENDING + + + m_panelSending + protected + + + + + + + wxTAB_TRAVERSAL + + + + + + + + + + + + + + + + + + + + + + + + + + bSizer68 + wxVERTICAL + none + + 5 + wxEXPAND + 0 + + 0 + protected + 0 + + + + 5 + wxTOP|wxRIGHT|wxLEFT + 0 + + + + 1 + + + 1 + wxID_ANY + Bitcoin Address + + + m_staticText55 + protected + + + + + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL|wxEXPAND + 1 + + + + 1 + + + 0 + wxID_LISTCTRLSENDING + + + m_listCtrlSending + protected + + + wxLC_NO_SORT_HEADER|wxLC_REPORT|wxLC_SORT_ASCENDING + + + + + + + + + + + + + + + + + + + + + + + + + + + OnListEndLabelEdit + + OnListItemActivated + + + + + OnListItemSelected + + + + + + + + + + + + + + + + + + + + + + Receiving + 1 + + + + 1 + + + 0 + wxID_PANELRECEIVING + + + m_panelReceiving + protected + + + + + + + wxTAB_TRAVERSAL + + + + + + + + + + + + + + + + + + + + + + + + + + bSizer681 + wxVERTICAL + none + + 5 + wxEXPAND + 0 + + 0 + protected + 0 + + + + 6 + wxTOP|wxRIGHT|wxLEFT + 0 + + + + 1 + + + 0 + wxID_ANY + These are your Bitcoin addresses for receiving payments. You can give a different one to each sender to keep track of who is paying you. The highlighted address will be displayed in the main window. + + + m_staticText45 + protected + + + + + + + + + 570 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND + 0 + + 2 + protected + 0 + + + + 5 + wxALL|wxEXPAND + 1 + + + + 1 + + + 0 + wxID_LISTCTRLRECEIVING + + + m_listCtrlReceiving + protected + + + wxLC_NO_SORT_HEADER|wxLC_REPORT|wxLC_SORT_ASCENDING + + + + + + + + + + + + + + + + + + + + + + + + + + + OnListEndLabelEdit + + OnListItemActivated + + + + + OnListItemSelected + + + + + + + + + + + + + + + + + + + @@ -4885,11 +5185,11 @@ 0 - wxID_BUTTONEDIT - &Edit... + wxID_BUTTONDELETE + &Delete -1,-1 - m_buttonEdit + m_buttonDelete protected @@ -4899,7 +5199,7 @@ - OnButtonEdit + OnButtonDelete @@ -4937,11 +5237,63 @@ 0 - wxID_BUTTONNEW - &New Address... + wxID_BUTTONCOPY + &Copy to Clipboard -1,-1 - m_buttonNew + m_buttonCopy + protected + + -1,-1 + + + + + + + OnButtonCopy + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND + 0 + + + + 0 + 1 + + + 0 + wxID_BUTTONEDIT + &Edit... + + -1,-1 + m_buttonEdit protected @@ -4951,7 +5303,7 @@ - OnButtonNew + OnButtonEdit @@ -4989,11 +5341,11 @@ 0 - wxID_BUTTONDELETE - &Delete + wxID_BUTTONNEW + &New Address... -1,-1 - m_buttonDelete + m_buttonNew protected @@ -5003,7 +5355,7 @@ - OnButtonDelete + OnButtonNew @@ -5151,7 +5503,7 @@ CGetTextFromUserDialogBase - 403,138 + 440,138 wxDEFAULT_DIALOG_STYLE diff --git a/util.cpp b/util.cpp index f4ce5566..40f7af34 100644 --- a/util.cpp +++ b/util.cpp @@ -445,10 +445,14 @@ const char* wxGetTranslation(const char* pszEnglish) // wxWidgets translation const char* pszTranslated = wxGetTranslation(wxString(pszEnglish, wxConvUTF8)).utf8_str(); + + // We don't cache unknown strings because caller might be passing in a + // dynamic string and we would keep allocating memory for each variation. if (strcmp(pszEnglish, pszTranslated) == 0) return pszEnglish; - // Add to cache, memory doesn't need to be freed + // Add to cache, memory doesn't need to be freed. We only cache because + // we must pass back a pointer to permanently allocated memory. char* pszCached = new char[strlen(pszTranslated)+1]; strcpy(pszCached, pszTranslated); mapCache[pszEnglish] = pszCached;