From: Wladimir J. van der Laan Date: Fri, 15 Jul 2011 14:08:38 +0000 (+0200) Subject: Merge branch 'master' of https://github.com/bitcoin/bitcoin X-Git-Tag: v0.4.0-unstable~226^2~57^2~123 X-Git-Url: https://git.novaco.in/?p=novacoin.git;a=commitdiff_plain;h=d4211176208b5e4ae4a699c6ce3239447752cdb2 Merge branch 'master' of https://github.com/bitcoin/bitcoin --- d4211176208b5e4ae4a699c6ce3239447752cdb2 diff --cc bitcoin-qt.pro index 9708b82,0000000..9af4c67 mode 100644,000000..100644 --- a/bitcoin-qt.pro +++ b/bitcoin-qt.pro @@@ -1,139 -1,0 +1,141 @@@ +TEMPLATE = app +TARGET = +INCLUDEPATH += src src/json src/cryptopp src/qt +DEFINES += QT_GUI +# DEFINES += SSL +CONFIG += no_include_pwd + +# for boost 1.37, add -mt to the boost libraries +unix:LIBS += -lssl -lcrypto -lboost_system -lboost_filesystem -lboost_program_options -lboost_thread -ldb_cxx +macx:DEFINES += __WXMAC_OSX__ MSG_NOSIGNAL=0 BOOST_FILESYSTEM_VERSION=3 +macx:LIBS += -lboost_thread-mt -lboost_system-mt -lboost_filesystem-mt -lboost_program_options-mt +windows:DEFINES += __WXMSW__ +windows:LIBS += -lssl -lcrypto -lboost_system-mgw44-mt-1_43 -lboost_filesystem-mgw44-mt-1_43 -lboost_program_options-mgw44-mt-1_43 -lboost_thread-mgw44-mt-1_43 -ldb_cxx -lws2_32 -lgdi32 + +# for extra security against potential buffer overflows +QMAKE_CXXFLAGS += -fstack-protector +QMAKE_LFLAGS += -fstack-protector + +# disable quite some warnings because bitcoin core "sins" a lot +QMAKE_CXXFLAGS_WARN_ON = -fdiagnostics-show-option -Wall -Wno-invalid-offsetof -Wno-unused-variable -Wno-unused-parameter -Wno-sign-compare -Wno-char-subscripts -Wno-unused-value -Wno-sequence-point -Wno-parentheses -Wno-unknown-pragmas -Wno-switch + +# Input +DEPENDPATH += src/qt src src/cryptopp src json/include +HEADERS += src/qt/bitcoingui.h \ + src/qt/transactiontablemodel.h \ + src/qt/addresstablemodel.h \ + src/qt/optionsdialog.h \ + src/qt/sendcoinsdialog.h \ + src/qt/addressbookpage.h \ + src/qt/aboutdialog.h \ + src/qt/editaddressdialog.h \ + src/qt/bitcoinaddressvalidator.h \ + src/base58.h \ + src/bignum.h \ + src/util.h \ + src/uint256.h \ + src/serialize.h \ + src/cryptopp/stdcpp.h \ + src/cryptopp/smartptr.h \ + src/cryptopp/simple.h \ + src/cryptopp/sha.h \ + src/cryptopp/secblock.h \ + src/cryptopp/pch.h \ + src/cryptopp/misc.h \ + src/cryptopp/iterhash.h \ + src/cryptopp/cryptlib.h \ + src/cryptopp/cpu.h \ + src/cryptopp/config.h \ + src/strlcpy.h \ + src/main.h \ + src/net.h \ + src/key.h \ + src/db.h \ + src/script.h \ + src/noui.h \ + src/init.h \ + src/headers.h \ + src/irc.h \ + src/json/json_spirit_writer_template.h \ + src/json/json_spirit_writer.h \ + src/json/json_spirit_value.h \ + src/json/json_spirit_utils.h \ + src/json/json_spirit_stream_reader.h \ + src/json/json_spirit_reader_template.h \ + src/json/json_spirit_reader.h \ + src/json/json_spirit_error_position.h \ + src/json/json_spirit.h \ + src/qt/clientmodel.h \ + src/qt/guiutil.h \ + src/qt/transactionrecord.h \ + src/qt/guiconstants.h \ + src/qt/optionsmodel.h \ + src/qt/monitoreddatamapper.h \ + src/qtui.h \ + src/qt/transactiondesc.h \ + src/qt/transactiondescdialog.h \ + src/qt/bitcoinamountfield.h \ + src/wallet.h \ + src/keystore.h \ + src/qt/transactionfilterproxy.h \ + src/qt/transactionview.h \ + src/qt/walletmodel.h \ + src/bitcoinrpc.h \ + src/qt/overviewpage.h \ + src/qt/csvmodelwriter.h \ - src/qt/qtwin.h ++ src/qt/qtwin.h \ ++ src/crypter.h +SOURCES += src/qt/bitcoin.cpp src/qt/bitcoingui.cpp \ + src/qt/transactiontablemodel.cpp \ + src/qt/addresstablemodel.cpp \ + src/qt/optionsdialog.cpp \ + src/qt/sendcoinsdialog.cpp \ + src/qt/addressbookpage.cpp \ + src/qt/aboutdialog.cpp \ + src/qt/editaddressdialog.cpp \ + src/qt/bitcoinaddressvalidator.cpp \ + src/cryptopp/sha.cpp \ + src/cryptopp/cpu.cpp \ + src/util.cpp \ + src/script.cpp \ + src/main.cpp \ + src/init.cpp \ + src/net.cpp \ + src/irc.cpp \ + src/db.cpp \ + src/json/json_spirit_writer.cpp \ + src/json/json_spirit_value.cpp \ + src/json/json_spirit_reader.cpp \ + src/qt/clientmodel.cpp \ + src/qt/guiutil.cpp \ + src/qt/transactionrecord.cpp \ + src/qt/optionsmodel.cpp \ + src/qt/monitoreddatamapper.cpp \ + src/qt/transactiondesc.cpp \ + src/qt/transactiondescdialog.cpp \ + src/qt/bitcoinstrings.cpp \ + src/qt/bitcoinamountfield.cpp \ + src/wallet.cpp \ + src/keystore.cpp \ + src/qt/transactionfilterproxy.cpp \ + src/qt/transactionview.cpp \ + src/qt/walletmodel.cpp \ + src/bitcoinrpc.cpp \ + src/qt/overviewpage.cpp \ + src/qt/csvmodelwriter.cpp \ - src/qt/qtwin.cpp ++ src/qt/qtwin.cpp \ ++ src/crypter.cpp + +RESOURCES += \ + src/qt/bitcoin.qrc + +FORMS += \ + src/qt/forms/sendcoinsdialog.ui \ + src/qt/forms/addressbookpage.ui \ + src/qt/forms/aboutdialog.ui \ + src/qt/forms/editaddressdialog.ui \ + src/qt/forms/transactiondescdialog.ui \ + src/qt/forms/overviewpage.ui + +CODECFORTR = UTF-8 +TRANSLATIONS = src/qt/locale/bitcoin_nl.ts src/qt/locale/bitcoin_de.ts diff --cc src/qt/addresstablemodel.cpp index 9ca7542,0000000..4578ca7 mode 100644,000000..100644 --- a/src/qt/addresstablemodel.cpp +++ b/src/qt/addresstablemodel.cpp @@@ -1,328 -1,0 +1,329 @@@ +#include "addresstablemodel.h" +#include "guiutil.h" + +#include "headers.h" + +#include +#include + +const QString AddressTableModel::Send = "S"; +const QString AddressTableModel::Receive = "R"; + +struct AddressTableEntry +{ + enum Type { + Sending, + Receiving + }; + + Type type; + QString label; + QString address; + + AddressTableEntry() {} + AddressTableEntry(Type type, const QString &label, const QString &address): + type(type), label(label), address(address) {} +}; + +// Private implementation +struct AddressTablePriv +{ + CWallet *wallet; + QList cachedAddressTable; + + AddressTablePriv(CWallet *wallet): + wallet(wallet) {} + + void refreshAddressTable() + { + cachedAddressTable.clear(); + - CRITICAL_BLOCK(wallet->cs_mapKeys) ++ CRITICAL_BLOCK(cs_mapPubKeys) + CRITICAL_BLOCK(wallet->cs_mapAddressBook) + { + BOOST_FOREACH(const PAIRTYPE(std::string, std::string)& item, wallet->mapAddressBook) + { + std::string strAddress = item.first; + std::string strName = item.second; + uint160 hash160; + bool fMine = (AddressToHash160(strAddress, hash160) && mapPubKeys.count(hash160)); + cachedAddressTable.append(AddressTableEntry(fMine ? AddressTableEntry::Receiving : AddressTableEntry::Sending, + QString::fromStdString(strName), + QString::fromStdString(strAddress))); + } + } + } + + int size() + { + return cachedAddressTable.size(); + } + + AddressTableEntry *index(int idx) + { + if(idx >= 0 && idx < cachedAddressTable.size()) + { + return &cachedAddressTable[idx]; + } + else + { + return 0; + } + } +}; + +AddressTableModel::AddressTableModel(CWallet *wallet, QObject *parent) : + QAbstractTableModel(parent),wallet(wallet),priv(0) +{ + columns << tr("Label") << tr("Address"); + priv = new AddressTablePriv(wallet); + priv->refreshAddressTable(); +} + +AddressTableModel::~AddressTableModel() +{ + delete priv; +} + +int AddressTableModel::rowCount(const QModelIndex &parent) const +{ + Q_UNUSED(parent); + return priv->size(); +} + +int AddressTableModel::columnCount(const QModelIndex &parent) const +{ + Q_UNUSED(parent); + return columns.length(); +} + +QVariant AddressTableModel::data(const QModelIndex &index, int role) const +{ + if(!index.isValid()) + return QVariant(); + + AddressTableEntry *rec = static_cast(index.internalPointer()); + + if(role == Qt::DisplayRole || role == Qt::EditRole) + { + switch(index.column()) + { + case Label: + if(rec->label.isEmpty() && role == Qt::DisplayRole) + { + return tr("(no label)"); + } + else + { + return rec->label; + } + case Address: + return rec->address; + } + } + else if (role == Qt::FontRole) + { + QFont font; + if(index.column() == Address) + { + font = GUIUtil::bitcoinAddressFont(); + } + return font; + } + else if (role == TypeRole) + { + switch(rec->type) + { + case AddressTableEntry::Sending: + return Send; + case AddressTableEntry::Receiving: + return Receive; + default: break; + } + } + return QVariant(); +} + +bool AddressTableModel::setData(const QModelIndex & index, const QVariant & value, int role) +{ + if(!index.isValid()) + return false; + AddressTableEntry *rec = static_cast(index.internalPointer()); + + if(role == Qt::EditRole) + { + switch(index.column()) + { + case Label: + wallet->SetAddressBookName(rec->address.toStdString(), value.toString().toStdString()); + rec->label = value.toString(); + break; + case Address: + // Refuse to set invalid address + if(!validateAddress(value.toString())) + return false; + // Double-check that we're not overwriting receiving address + if(rec->type == AddressTableEntry::Sending) + { + CRITICAL_BLOCK(wallet->cs_mapAddressBook) + { + // Remove old entry + wallet->DelAddressBookName(rec->address.toStdString()); + // Add new entry with new address + wallet->SetAddressBookName(value.toString().toStdString(), rec->label.toStdString()); + } + + rec->address = value.toString(); + } + break; + } + emit dataChanged(index, index); + + return true; + } + return false; +} + +QVariant AddressTableModel::headerData(int section, Qt::Orientation orientation, int role) const +{ + if(orientation == Qt::Horizontal) + { + if(role == Qt::DisplayRole) + { + return columns[section]; + } + } + return QVariant(); +} + +Qt::ItemFlags AddressTableModel::flags(const QModelIndex & index) const +{ + if(!index.isValid()) + return 0; + AddressTableEntry *rec = static_cast(index.internalPointer()); + + Qt::ItemFlags retval = Qt::ItemIsSelectable | Qt::ItemIsEnabled; + // Can edit address and label for sending addresses, + // and only label for receiving addresses. + if(rec->type == AddressTableEntry::Sending || + (rec->type == AddressTableEntry::Receiving && index.column()==Label)) + { + retval |= Qt::ItemIsEditable; + } + return retval; +} + +QModelIndex AddressTableModel::index(int row, int column, const QModelIndex & parent) const +{ + Q_UNUSED(parent); + AddressTableEntry *data = priv->index(row); + if(data) + { + return createIndex(row, column, priv->index(row)); + } + else + { + return QModelIndex(); + } +} + +void AddressTableModel::updateList() +{ + // Update internal model from Bitcoin core + beginResetModel(); + priv->refreshAddressTable(); + endResetModel(); +} + +QString AddressTableModel::addRow(const QString &type, const QString &label, const QString &address) +{ + std::string strLabel = label.toStdString(); + std::string strAddress = address.toStdString(); + + if(type == Send) + { + // Check for duplicate + CRITICAL_BLOCK(wallet->cs_mapAddressBook) + { + if(wallet->mapAddressBook.count(strAddress)) + { + return QString(); + } + } + } + else if(type == Receive) + { + // Generate a new address to associate with given label, optionally + // set as default receiving address. - strAddress = PubKeyToAddress(wallet->GetKeyFromKeyPool()); ++ strAddress = PubKeyToAddress(wallet->GetOrReuseKeyFromPool()); + } + else + { + return QString(); + } + // Add entry and update list - wallet->SetAddressBookName(strAddress, strLabel); ++ CRITICAL_BLOCK(wallet->cs_mapAddressBook) ++ wallet->SetAddressBookName(strAddress, strLabel); + updateList(); + return QString::fromStdString(strAddress); +} + +bool AddressTableModel::removeRows(int row, int count, const QModelIndex & parent) +{ + Q_UNUSED(parent); + AddressTableEntry *rec = priv->index(row); + if(count != 1 || !rec || rec->type == AddressTableEntry::Receiving) + { + // Can only remove one row at a time, and cannot remove rows not in model. + // Also refuse to remove receiving addresses. + return false; + } + CRITICAL_BLOCK(wallet->cs_mapAddressBook) + { + wallet->DelAddressBookName(rec->address.toStdString()); + } + updateList(); + return true; +} + +void AddressTableModel::update() +{ + +} + +bool AddressTableModel::validateAddress(const QString &address) +{ + uint160 hash160 = 0; + + return AddressToHash160(address.toStdString(), hash160); +} + +/* Look up label for address in address book, if not found return empty string. + */ +QString AddressTableModel::labelForAddress(const QString &address) const +{ + CRITICAL_BLOCK(wallet->cs_mapAddressBook) + { + std::map::iterator mi = wallet->mapAddressBook.find(address.toStdString()); + if (mi != wallet->mapAddressBook.end()) + { + return QString::fromStdString(mi->second); + } + } + return QString(); +} + +int AddressTableModel::lookupAddress(const QString &address) const +{ + QModelIndexList lst = match(index(0, Address, QModelIndex()), + Qt::EditRole, address, 1, Qt::MatchExactly); + if(lst.isEmpty()) + { + return -1; + } + else + { + return lst.at(0).row(); + } +} + diff --cc src/wallet.cpp index fa57755,2ee918f..3e1bb8e --- a/src/wallet.cpp +++ b/src/wallet.cpp @@@ -98,9 -269,12 +269,12 @@@ bool CWallet::AddToWallet(const CWallet BOOST_FOREACH(const CTxOut& txout, wtx.vout) { if (txout.scriptPubKey == scriptDefaultKey) - SetDefaultKey(GetKeyFromKeyPool()); + { + SetDefaultKey(GetOrReuseKeyFromPool()); + SetAddressBookName(PubKeyToAddress(vchDefaultKey), ""); + } } - +#endif // Notify UI vWalletUpdated.push_back(hash);