diff options
Diffstat (limited to 'src/qt')
32 files changed, 919 insertions, 260 deletions
diff --git a/src/qt/Makefile.am b/src/qt/Makefile.am index c6c4cb37a3..e7ae0a905f 100644 --- a/src/qt/Makefile.am +++ b/src/qt/Makefile.am @@ -4,7 +4,7 @@ AM_CPPFLAGS = $(INCLUDES) -I$(top_builddir)/src/obj \ -I$(top_srcdir)/src/leveldb/include -I$(top_srcdir)/src \ -I$(top_srcdir)/src/leveldb/helpers -I$(top_builddir)/src/qt \ -I$(top_builddir)/src/qt/forms $(BOOST_INCLUDES) $(PROTOBUF_CFLAGS) \ - $(QR_CFLAGS) + $(QR_CFLAGS) $(BDB_CPPFLAGS) AM_LDFLAGS = $(PTHREAD_CFLAGS) bin_PROGRAMS = bitcoin-qt noinst_LIBRARIES = libbitcoinqt.a @@ -48,11 +48,14 @@ QT_MOC_CPP = moc_aboutdialog.cpp moc_addressbookpage.cpp \ moc_optionsmodel.cpp moc_overviewpage.cpp moc_paymentserver.cpp \ moc_qrcodedialog.cpp moc_qvalidatedlineedit.cpp moc_qvaluecombobox.cpp \ moc_rpcconsole.cpp moc_sendcoinsdialog.cpp moc_sendcoinsentry.cpp \ - moc_signverifymessagedialog.cpp moc_splashscreen.cpp moc_transactiondesc.cpp \ + moc_signverifymessagedialog.cpp moc_splashscreen.cpp moc_trafficgraphwidget.cpp moc_transactiondesc.cpp \ moc_transactiondescdialog.cpp moc_transactionfilterproxy.cpp \ moc_transactiontablemodel.cpp moc_transactionview.cpp moc_walletframe.cpp \ moc_walletmodel.cpp moc_walletstack.cpp moc_walletview.cpp +BITCOIN_MM = macdockiconhandler.mm macnotificationhandler.mm +QR_CPP = qrcodedialog.cpp + QT_MOC = intro.moc overviewpage.moc rpcconsole.moc QT_QRC_CPP = qrc_bitcoin.cpp @@ -70,7 +73,7 @@ BITCOIN_QT_H = aboutdialog.h addressbookpage.h addresstablemodel.h \ optionsmodel.h overviewpage.h paymentrequestplus.h paymentserver.h \ qrcodedialog.h qvalidatedlineedit.h qvaluecombobox.h rpcconsole.h \ sendcoinsdialog.h sendcoinsentry.h signverifymessagedialog.h splashscreen.h \ - transactiondescdialog.h transactiondesc.h transactionfilterproxy.h \ + trafficgraphwidget.h transactiondescdialog.h transactiondesc.h transactionfilterproxy.h \ transactionrecord.h transactiontablemodel.h transactionview.h walletframe.h \ walletmodel.h walletmodeltransaction.h walletstack.h walletview.h @@ -91,6 +94,19 @@ RES_ICONS = res/icons/bitcoin.png res/icons/address-book.png \ res/icons/qrcode.png res/icons/debugwindow.png res/icons/bitcoin.ico \ res/icons/bitcoin_testnet.ico +BITCOIN_QT_CPP = aboutdialog.cpp addressbookpage.cpp \ + addresstablemodel.cpp askpassphrasedialog.cpp bitcoinaddressvalidator.cpp \ + bitcoinamountfield.cpp bitcoin.cpp bitcoingui.cpp \ + bitcoinunits.cpp clientmodel.cpp csvmodelwriter.cpp editaddressdialog.cpp \ + guiutil.cpp intro.cpp monitoreddatamapper.cpp notificator.cpp \ + optionsdialog.cpp optionsmodel.cpp overviewpage.cpp paymentrequestplus.cpp \ + paymentserver.cpp qvalidatedlineedit.cpp qvaluecombobox.cpp \ + rpcconsole.cpp sendcoinsdialog.cpp sendcoinsentry.cpp \ + signverifymessagedialog.cpp splashscreen.cpp trafficgraphwidget.cpp transactiondesc.cpp \ + transactiondescdialog.cpp transactionfilterproxy.cpp transactionrecord.cpp \ + transactiontablemodel.cpp transactionview.cpp walletframe.cpp \ + walletmodel.cpp walletmodeltransaction.cpp walletstack.cpp walletview.cpp + RES_IMAGES = res/images/about.png res/images/splash.png \ res/images/splash_testnet.png @@ -100,20 +116,8 @@ BITCOIN_RC = res/bitcoin-qt-res.rc libbitcoinqt_a_CPPFLAGS = $(AM_CPPFLAGS) $(QT_INCLUDES) \ -I$(top_srcdir)/src/qt/forms $(QT_DBUS_INCLUDES) -libbitcoinqt_a_SOURCES = aboutdialog.cpp addressbookpage.cpp \ - addresstablemodel.cpp askpassphrasedialog.cpp bitcoinaddressvalidator.cpp \ - bitcoinamountfield.cpp bitcoin.cpp bitcoingui.cpp bitcoinstrings.cpp \ - bitcoinunits.cpp clientmodel.cpp csvmodelwriter.cpp editaddressdialog.cpp \ - guiutil.cpp intro.cpp monitoreddatamapper.cpp notificator.cpp \ - optionsdialog.cpp optionsmodel.cpp overviewpage.cpp paymentrequestplus.cpp \ - paymentserver.cpp qvalidatedlineedit.cpp qvaluecombobox.cpp \ - rpcconsole.cpp sendcoinsdialog.cpp sendcoinsentry.cpp \ - signverifymessagedialog.cpp splashscreen.cpp transactiondesc.cpp \ - transactiondescdialog.cpp transactionfilterproxy.cpp transactionrecord.cpp \ - transactiontablemodel.cpp transactionview.cpp walletframe.cpp \ - walletmodel.cpp walletmodeltransaction.cpp walletstack.cpp walletview.cpp \ - $(BITCOIN_QT_H) $(QT_FORMS_UI) $(QT_QRC) $(QT_TS) $(PROTOBUF_PROTO) \ - $(RES_ICONS) $(RES_IMAGES) $(RES_MOVIES) +libbitcoinqt_a_SOURCES = $(BITCOIN_QT_CPP) $(BITCOIN_QT_H) $(QT_FORMS_UI) \ + $(QT_QRC) $(QT_TS) $(PROTOBUF_PROTO) $(RES_ICONS) $(RES_IMAGES) $(RES_MOVIES) nodist_libbitcoinqt_a_SOURCES = $(QT_MOC_CPP) $(QT_MOC) $(PROTOBUF_CC) \ $(PROTOBUF_H) $(QT_QRC_CPP) @@ -126,13 +130,13 @@ $(QT_MOC): $(PROTOBUF_H) $(QT_MOC_CPP): $(PROTOBUF_H) if TARGET_DARWIN - libbitcoinqt_a_SOURCES += macdockiconhandler.mm macnotificationhandler.mm + libbitcoinqt_a_SOURCES += $(BITCOIN_MM) endif if TARGET_WINDOWS libbitcoinqt_a_SOURCES += $(BITCOIN_RC) endif if USE_QRCODE - libbitcoinqt_a_SOURCES += qrcodedialog.cpp + libbitcoinqt_a_SOURCES += $(QR_CPP) endif # @@ -141,7 +145,7 @@ bitcoin_qt_CPPFLAGS = $(AM_CPPFLAGS) $(QT_INCLUDES) \ -I$(top_srcdir)/src/qt/forms bitcoin_qt_SOURCES = bitcoin.cpp bitcoin_qt_LDADD = libbitcoinqt.a $(LIBBITCOIN) $(LIBLEVELDB) $(LIBMEMENV) \ - $(BOOST_LIBS) $(QT_LIBS) $(QT_DBUS_LIBS) $(QR_LIBS) $(PROTOBUF_LIBS) + $(BOOST_LIBS) $(QT_LIBS) $(QT_DBUS_LIBS) $(QR_LIBS) $(PROTOBUF_LIBS) $(BDB_LIBS) # forms/foo.h -> forms/ui_foo.h QT_FORMS_H=$(join $(dir $(QT_FORMS_UI)),$(addprefix ui_, $(notdir $(QT_FORMS_UI:.ui=.h)))) @@ -149,8 +153,16 @@ QT_FORMS_H=$(join $(dir $(QT_FORMS_UI)),$(addprefix ui_, $(notdir $(QT_FORMS_UI: #locale/foo.ts -> locale/foo.qm QT_QM=$(QT_TS:.ts=.qm) +.PHONY: FORCE .SECONDARY: $(QT_QM) +bitcoinstrings.cpp: FORCE + $(MAKE) -C $(top_srcdir)/src qt/bitcoinstrings.cpp + +translate: bitcoinstrings.cpp $(QT_FORMS_UI) $(QT_FORMS_UI) $(BITCOIN_QT_CPP) $(BITCOIN_QT_H) $(BITCOIN_MM) $(QR_CPP) + @test -n $(LUPDATE) || echo "lupdate is required for updating translations" + @$(LUPDATE) $^ -locations relative -no-obsolete -ts locale/bitcoin_en.ts + $(QT_QRC_CPP): $(QT_QRC) $(QT_QM) $(QT_FORMS_H) $(RES_ICONS) $(RES_IMAGES) $(RES_MOVIES) $(PROTOBUF_H) @cd $(abs_srcdir); test -f $(RCC) && $(RCC) -name bitcoin -o $(abs_builddir)/$@ $< || \ echo error: could not build $@ diff --git a/src/qt/askpassphrasedialog.cpp b/src/qt/askpassphrasedialog.cpp index f165c11cb1..2b7671f209 100644 --- a/src/qt/askpassphrasedialog.cpp +++ b/src/qt/askpassphrasedialog.cpp @@ -16,6 +16,7 @@ AskPassphraseDialog::AskPassphraseDialog(Mode mode, QWidget *parent) : fCapsLock(false) { ui->setupUi(this); + ui->passEdit1->setMaxLength(MAX_PASSPHRASE_SIZE); ui->passEdit2->setMaxLength(MAX_PASSPHRASE_SIZE); ui->passEdit3->setMaxLength(MAX_PASSPHRASE_SIZE); diff --git a/src/qt/bitcoin.cpp b/src/qt/bitcoin.cpp index a4d589e167..78693971da 100644 --- a/src/qt/bitcoin.cpp +++ b/src/qt/bitcoin.cpp @@ -62,7 +62,7 @@ static bool ThreadSafeMessageBox(const std::string& message, const std::string& } else { - printf("%s: %s\n", caption.c_str(), message.c_str()); + LogPrintf("%s: %s\n", caption.c_str(), message.c_str()); fprintf(stderr, "%s: %s\n", caption.c_str(), message.c_str()); return false; } @@ -91,7 +91,7 @@ static void InitMessage(const std::string &message) splashref->showMessage(QString::fromStdString(message), Qt::AlignBottom|Qt::AlignHCenter, QColor(55,55,55)); qApp->processEvents(); } - printf("init message: %s\n", message.c_str()); + LogPrintf("init message: %s\n", message.c_str()); } /* @@ -155,12 +155,15 @@ static void initTranslations(QTranslator &qtTranslatorBase, QTranslator &qtTrans #if QT_VERSION < 0x050000 void DebugMessageHandler(QtMsgType type, const char * msg) { - OutputDebugStringF("Bitcoin-Qt: %s\n", msg); + Q_UNUSED(type); + LogPrint("qt", "Bitcoin-Qt: %s\n", msg); } #else void DebugMessageHandler(QtMsgType type, const QMessageLogContext& context, const QString &msg) { - OutputDebugStringF("Bitcoin-Qt: %s\n", qPrintable(msg)); + Q_UNUSED(type); + Q_UNUSED(context); + LogPrint("qt", "Bitcoin-Qt: %s\n", qPrintable(msg)); } #endif diff --git a/src/qt/bitcoinamountfield.cpp b/src/qt/bitcoinamountfield.cpp index d9d4e3b23d..37b8743eff 100644 --- a/src/qt/bitcoinamountfield.cpp +++ b/src/qt/bitcoinamountfield.cpp @@ -130,9 +130,10 @@ void BitcoinAmountField::setValue(qint64 value) setText(BitcoinUnits::format(currentUnit, value)); } -void BitcoinAmountField::setReadOnly(bool fReadeOnly) +void BitcoinAmountField::setReadOnly(bool fReadOnly) { - // TODO ... + amount->setReadOnly(fReadOnly); + unit->setEnabled(!fReadOnly); } void BitcoinAmountField::unitChanged(int idx) diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp index bb9eb60e5b..23a221120f 100644 --- a/src/qt/bitcoingui.cpp +++ b/src/qt/bitcoingui.cpp @@ -157,6 +157,8 @@ BitcoinGUI::BitcoinGUI(bool fIsTestnet, QWidget *parent) : rpcConsole = new RPCConsole(this); connect(openRPCConsoleAction, SIGNAL(triggered()), rpcConsole, SLOT(show())); + // prevents an oben debug window from becoming stuck/unusable on client shutdown + connect(quitAction, SIGNAL(triggered()), rpcConsole, SLOT(hide())); // Install event filter to be able to catch status tip events (QEvent::StatusTip) this->installEventFilter(this); @@ -233,7 +235,11 @@ void BitcoinGUI::createActions(bool fIsTestnet) aboutAction = new QAction(QIcon(":/icons/bitcoin_testnet"), tr("&About Bitcoin"), this); aboutAction->setStatusTip(tr("Show information about Bitcoin")); aboutAction->setMenuRole(QAction::AboutRole); +#if QT_VERSION < 0x050000 aboutQtAction = new QAction(QIcon(":/trolltech/qmessagebox/images/qtlogo-64.png"), tr("About &Qt"), this); +#else + aboutQtAction = new QAction(QIcon(":/qt-project.org/qmessagebox/images/qtlogo-64.png"), tr("About &Qt"), this); +#endif aboutQtAction->setStatusTip(tr("Show information about Qt")); aboutQtAction->setMenuRole(QAction::AboutQtRole); optionsAction = new QAction(QIcon(":/icons/options"), tr("&Options..."), this); @@ -590,21 +596,28 @@ void BitcoinGUI::message(const QString &title, const QString &message, unsigned int nMBoxIcon = QMessageBox::Information; int nNotifyIcon = Notificator::Information; - // Override title based on style QString msgType; - switch (style) { - case CClientUIInterface::MSG_ERROR: - msgType = tr("Error"); - break; - case CClientUIInterface::MSG_WARNING: - msgType = tr("Warning"); - break; - case CClientUIInterface::MSG_INFORMATION: - msgType = tr("Information"); - break; - default: - msgType = title; // Use supplied title + + // Prefer supplied title over style based title + if (!title.isEmpty()) { + msgType = title; } + else { + switch (style) { + case CClientUIInterface::MSG_ERROR: + msgType = tr("Error"); + break; + case CClientUIInterface::MSG_WARNING: + msgType = tr("Warning"); + break; + case CClientUIInterface::MSG_INFORMATION: + msgType = tr("Information"); + break; + default: + break; + } + } + // Append title to "Bitcoin - " if (!msgType.isEmpty()) strTitle += " - " + msgType; @@ -625,7 +638,7 @@ void BitcoinGUI::message(const QString &title, const QString &message, unsigned if (!(buttons = (QMessageBox::StandardButton)(style & CClientUIInterface::BTN_MASK))) buttons = QMessageBox::Ok; - QMessageBox mBox((QMessageBox::Icon)nMBoxIcon, strTitle, message, buttons); + QMessageBox mBox((QMessageBox::Icon)nMBoxIcon, strTitle, message, buttons, this); int r = mBox.exec(); if (ret != NULL) *ret = r == QMessageBox::Ok; @@ -744,13 +757,9 @@ void BitcoinGUI::handlePaymentRequest(const SendCoinsRecipient& recipient) walletFrame->handlePaymentRequest(recipient); } -void BitcoinGUI::showPaymentACK(QString msg) +void BitcoinGUI::showPaymentACK(const QString& msg) { -#if QT_VERSION < 0x050000 - message(tr("Payment acknowledged"), Qt::escape(msg), CClientUIInterface::MODAL); -#else - message(tr("Payment acknowledged"), msg.toHtmlEscaped(), CClientUIInterface::MODAL); -#endif + message(tr("Payment acknowledged"), GUIUtil::HtmlEscape(msg), CClientUIInterface::MODAL); } void BitcoinGUI::setEncryptionStatus(int status) diff --git a/src/qt/bitcoingui.h b/src/qt/bitcoingui.h index fc25e867fc..e2dd5dc6bc 100644 --- a/src/qt/bitcoingui.h +++ b/src/qt/bitcoingui.h @@ -154,7 +154,7 @@ public slots: void askFee(qint64 nFeeRequired, bool *payFee); void handlePaymentRequest(const SendCoinsRecipient& recipient); - void showPaymentACK(QString msg); + void showPaymentACK(const QString& msg); /** Show incoming transaction notification for new transactions. */ void incomingTransaction(const QString& date, int unit, qint64 amount, const QString& type, const QString& address); diff --git a/src/qt/clientmodel.cpp b/src/qt/clientmodel.cpp index f7dd8adb6b..2bab488135 100644 --- a/src/qt/clientmodel.cpp +++ b/src/qt/clientmodel.cpp @@ -24,9 +24,8 @@ ClientModel::ClientModel(OptionsModel *optionsModel, QObject *parent) : numBlocksAtStartup(-1), pollTimer(0) { pollTimer = new QTimer(this); - pollTimer->setInterval(MODEL_UPDATE_DELAY); - pollTimer->start(); connect(pollTimer, SIGNAL(timeout()), this, SLOT(updateTimer())); + pollTimer->start(MODEL_UPDATE_DELAY); subscribeToCoreSignals(); } @@ -43,7 +42,7 @@ int ClientModel::getNumConnections() const int ClientModel::getNumBlocks() const { - return nBestHeight; + return chainActive.Height(); } int ClientModel::getNumBlocksAtStartup() @@ -52,10 +51,20 @@ int ClientModel::getNumBlocksAtStartup() return numBlocksAtStartup; } +quint64 ClientModel::getTotalBytesRecv() const +{ + return CNode::GetTotalBytesRecv(); +} + +quint64 ClientModel::getTotalBytesSent() const +{ + return CNode::GetTotalBytesSent(); +} + QDateTime ClientModel::getLastBlockDate() const { - if (pindexBest) - return QDateTime::fromTime_t(pindexBest->GetBlockTime()); + if (chainActive.Tip()) + return QDateTime::fromTime_t(chainActive.Tip()->GetBlockTime()); else if(!isTestNet()) return QDateTime::fromTime_t(1231006505); // Genesis block's time else @@ -64,7 +73,7 @@ QDateTime ClientModel::getLastBlockDate() const double ClientModel::getVerificationProgress() const { - return Checkpoints::GuessVerificationProgress(pindexBest); + return Checkpoints::GuessVerificationProgress(chainActive.Tip()); } void ClientModel::updateTimer() @@ -86,6 +95,8 @@ void ClientModel::updateTimer() // ensure we return the maximum of newNumBlocksOfPeers and newNumBlocks to not create weird displays in the GUI emit numBlocksChanged(newNumBlocks, std::max(newNumBlocksOfPeers, newNumBlocks)); } + + emit bytesChanged(getTotalBytesRecv(), getTotalBytesSent()); } void ClientModel::updateNumConnections(int numConnections) diff --git a/src/qt/clientmodel.h b/src/qt/clientmodel.h index 15074300b4..925f20acd9 100644 --- a/src/qt/clientmodel.h +++ b/src/qt/clientmodel.h @@ -35,6 +35,9 @@ public: int getNumBlocks() const; int getNumBlocksAtStartup(); + quint64 getTotalBytesRecv() const; + quint64 getTotalBytesSent() const; + double getVerificationProgress() const; QDateTime getLastBlockDate() const; @@ -74,6 +77,7 @@ signals: void numConnectionsChanged(int count); void numBlocksChanged(int count, int countOfPeers); void alertsChanged(const QString &warnings); + void bytesChanged(quint64 totalBytesIn, quint64 totalBytesOut); //! Asynchronous message notification void message(const QString &title, const QString &message, unsigned int style); diff --git a/src/qt/csvmodelwriter.cpp b/src/qt/csvmodelwriter.cpp index 8a50bbab3f..ad8e0d618a 100644 --- a/src/qt/csvmodelwriter.cpp +++ b/src/qt/csvmodelwriter.cpp @@ -85,4 +85,3 @@ bool CSVModelWriter::write() return file.error() == QFile::NoError; } - diff --git a/src/qt/forms/optionsdialog.ui b/src/qt/forms/optionsdialog.ui index bb53021cfd..1e4335c645 100644 --- a/src/qt/forms/optionsdialog.ui +++ b/src/qt/forms/optionsdialog.ui @@ -461,7 +461,7 @@ <customwidgets> <customwidget> <class>BitcoinAmountField</class> - <extends>QSpinBox</extends> + <extends>QLineEdit</extends> <header>bitcoinamountfield.h</header> </customwidget> <customwidget> diff --git a/src/qt/forms/qrcodedialog.ui b/src/qt/forms/qrcodedialog.ui index 52e9db3762..1cec9066f8 100644 --- a/src/qt/forms/qrcodedialog.ui +++ b/src/qt/forms/qrcodedialog.ui @@ -186,7 +186,7 @@ <customwidgets> <customwidget> <class>BitcoinAmountField</class> - <extends>QSpinBox</extends> + <extends>QLineEdit</extends> <header>bitcoinamountfield.h</header> </customwidget> </customwidgets> diff --git a/src/qt/forms/rpcconsole.ui b/src/qt/forms/rpcconsole.ui index d1d8ab42a0..54c41ffb67 100644 --- a/src/qt/forms/rpcconsole.ui +++ b/src/qt/forms/rpcconsole.ui @@ -445,10 +445,271 @@ </item> </layout> </widget> + <widget class="QWidget" name="tab"> + <attribute name="title"> + <string>&Network Traffic</string> + </attribute> + <layout class="QHBoxLayout" name="horizontalLayout_3"> + <item> + <layout class="QVBoxLayout" name="verticalLayout_4"> + <item> + <widget class="TrafficGraphWidget" name="trafficGraph" native="true"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Expanding" vsizetype="Expanding"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + </widget> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_2"> + <item> + <widget class="QSlider" name="sldGraphRange"> + <property name="minimum"> + <number>1</number> + </property> + <property name="maximum"> + <number>288</number> + </property> + <property name="pageStep"> + <number>12</number> + </property> + <property name="value"> + <number>6</number> + </property> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + </widget> + </item> + <item> + <widget class="QLabel" name="lblGraphRange"> + <property name="minimumSize"> + <size> + <width>100</width> + <height>0</height> + </size> + </property> + <property name="alignment"> + <set>Qt::AlignCenter</set> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="btnClearTrafficGraph"> + <property name="text"> + <string>&Clear</string> + </property> + </widget> + </item> + </layout> + </item> + </layout> + </item> + <item> + <layout class="QVBoxLayout" name="verticalLayout"> + <item> + <widget class="QGroupBox" name="groupBox"> + <property name="title"> + <string>Totals</string> + </property> + <layout class="QVBoxLayout" name="verticalLayout_5"> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_4"> + <item> + <widget class="Line" name="line"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>10</width> + <height>0</height> + </size> + </property> + <property name="palette"> + <palette> + <active> + <colorrole role="Light"> + <brush brushstyle="SolidPattern"> + <color alpha="255"> + <red>0</red> + <green>255</green> + <blue>0</blue> + </color> + </brush> + </colorrole> + </active> + <inactive> + <colorrole role="Light"> + <brush brushstyle="SolidPattern"> + <color alpha="255"> + <red>0</red> + <green>255</green> + <blue>0</blue> + </color> + </brush> + </colorrole> + </inactive> + <disabled> + <colorrole role="Light"> + <brush brushstyle="SolidPattern"> + <color alpha="255"> + <red>0</red> + <green>255</green> + <blue>0</blue> + </color> + </brush> + </colorrole> + </disabled> + </palette> + </property> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + </widget> + </item> + <item> + <widget class="QLabel" name="label_16"> + <property name="text"> + <string>In:</string> + </property> + </widget> + </item> + <item> + <widget class="QLabel" name="lblBytesIn"> + <property name="minimumSize"> + <size> + <width>50</width> + <height>0</height> + </size> + </property> + <property name="alignment"> + <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + </property> + </widget> + </item> + </layout> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_5"> + <item> + <widget class="Line" name="line_2"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>10</width> + <height>0</height> + </size> + </property> + <property name="palette"> + <palette> + <active> + <colorrole role="Light"> + <brush brushstyle="SolidPattern"> + <color alpha="255"> + <red>255</red> + <green>0</green> + <blue>0</blue> + </color> + </brush> + </colorrole> + </active> + <inactive> + <colorrole role="Light"> + <brush brushstyle="SolidPattern"> + <color alpha="255"> + <red>255</red> + <green>0</green> + <blue>0</blue> + </color> + </brush> + </colorrole> + </inactive> + <disabled> + <colorrole role="Light"> + <brush brushstyle="SolidPattern"> + <color alpha="255"> + <red>255</red> + <green>0</green> + <blue>0</blue> + </color> + </brush> + </colorrole> + </disabled> + </palette> + </property> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + </widget> + </item> + <item> + <widget class="QLabel" name="label_17"> + <property name="text"> + <string>Out:</string> + </property> + </widget> + </item> + <item> + <widget class="QLabel" name="lblBytesOut"> + <property name="minimumSize"> + <size> + <width>50</width> + <height>0</height> + </size> + </property> + <property name="alignment"> + <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + </property> + </widget> + </item> + </layout> + </item> + <item> + <spacer name="verticalSpacer_4"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>407</height> + </size> + </property> + </spacer> + </item> + </layout> + </widget> + </item> + </layout> + </item> + </layout> + </widget> </widget> </item> </layout> </widget> + <customwidgets> + <customwidget> + <class>TrafficGraphWidget</class> + <extends>QWidget</extends> + <header>trafficgraphwidget.h</header> + <container>1</container> + <slots> + <slot>clear()</slot> + </slots> + </customwidget> + </customwidgets> <resources> <include location="../bitcoin.qrc"/> </resources> diff --git a/src/qt/forms/sendcoinsdialog.ui b/src/qt/forms/sendcoinsdialog.ui index 6e17565ab0..2a00fc5455 100644 --- a/src/qt/forms/sendcoinsdialog.ui +++ b/src/qt/forms/sendcoinsdialog.ui @@ -28,7 +28,7 @@ <height>165</height> </rect> </property> - <layout class="QVBoxLayout" name="verticalLayout_2"> + <layout class="QVBoxLayout" name="verticalLayout_2" stretch="0,1"> <property name="margin"> <number>0</number> </property> diff --git a/src/qt/forms/sendcoinsentry.ui b/src/qt/forms/sendcoinsentry.ui index a2ef9a0a38..5c6afd6c71 100644 --- a/src/qt/forms/sendcoinsentry.ui +++ b/src/qt/forms/sendcoinsentry.ui @@ -10,19 +10,13 @@ <height>150</height> </rect> </property> - <property name="windowTitle"> - <string>StackedWidget</string> - </property> <property name="autoFillBackground"> <bool>false</bool> </property> <property name="currentIndex"> - <number>1</number> + <number>0</number> </property> <widget class="QFrame" name="SendCoinsInsecure"> - <property name="windowTitle"> - <string>Form</string> - </property> <property name="frameShape"> <enum>QFrame::StyledPanel</enum> </property> @@ -34,7 +28,7 @@ <number>12</number> </property> <item row="5" column="0"> - <widget class="QLabel" name="label"> + <widget class="QLabel" name="amountLabel"> <property name="text"> <string>A&mount:</string> </property> @@ -47,7 +41,7 @@ </widget> </item> <item row="3" column="0"> - <widget class="QLabel" name="label_2"> + <widget class="QLabel" name="payToLabel"> <property name="text"> <string>Pay &To:</string> </property> @@ -63,7 +57,7 @@ <widget class="BitcoinAmountField" name="payAmount"/> </item> <item row="4" column="0"> - <widget class="QLabel" name="label_4"> + <widget class="QLabel" name="labellLabel"> <property name="text"> <string>&Label:</string> </property> @@ -592,9 +586,6 @@ </disabled> </palette> </property> - <property name="windowTitle"> - <string>SecureSend</string> - </property> <property name="autoFillBackground"> <bool>true</bool> </property> @@ -609,7 +600,7 @@ <number>12</number> </property> <item row="4" column="0"> - <widget class="QLabel" name="label_s4"> + <widget class="QLabel" name="memoLabel_s"> <property name="text"> <string>Memo:</string> </property> @@ -622,7 +613,7 @@ </widget> </item> <item row="5" column="0"> - <widget class="QLabel" name="label_s1"> + <widget class="QLabel" name="amountLabel_s"> <property name="text"> <string>A&mount:</string> </property> @@ -630,12 +621,12 @@ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> </property> <property name="buddy"> - <cstring>payAmount</cstring> + <cstring>payAmount_s</cstring> </property> </widget> </item> <item row="3" column="0"> - <widget class="QLabel" name="label_s2"> + <widget class="QLabel" name="payToLabel_s"> <property name="text"> <string>Pay &To:</string> </property> @@ -649,15 +640,9 @@ </item> <item row="5" column="2"> <widget class="BitcoinAmountField" name="payAmount_s"> - <property name="enabled"> - <bool>false</bool> - </property> <property name="acceptDrops"> <bool>false</bool> </property> - <property name="readOnly"> - <bool>true</bool> - </property> </widget> </item> <item row="3" column="2"> @@ -667,14 +652,17 @@ </property> <item> <widget class="QLabel" name="payTo_s"> + <property name="textFormat"> + <enum>Qt::PlainText</enum> + </property> </widget> </item> </layout> </item> <item row="4" column="2"> - <widget class="QLabel" name="memo_s"> - <property name="text"> - <string>message from merchant</string> + <widget class="QLabel" name="memoTextLabel_s"> + <property name="textFormat"> + <enum>Qt::PlainText</enum> </property> </widget> </item> diff --git a/src/qt/locale/bitcoin_en.ts b/src/qt/locale/bitcoin_en.ts index 7d419b6bd9..4d1a8574d0 100644 --- a/src/qt/locale/bitcoin_en.ts +++ b/src/qt/locale/bitcoin_en.ts @@ -67,7 +67,7 @@ This product includes software developed by the OpenSSL Project for use in the O <translation>&New Address</translation> </message> <message> - <location filename="../addressbookpage.cpp" line="+63"/> + <location filename="../addressbookpage.cpp" line="+67"/> <source>These are your Bitcoin addresses for receiving payments. You may want to give a different one to each sender so you can keep track of who is paying you.</source> <translation>These are your Bitcoin addresses for receiving payments. You may want to give a different one to each sender so you can keep track of who is paying you.</translation> </message> @@ -165,7 +165,7 @@ This product includes software developed by the OpenSSL Project for use in the O <context> <name>AddressTableModel</name> <message> - <location filename="../addresstablemodel.cpp" line="+144"/> + <location filename="../addresstablemodel.cpp" line="+164"/> <source>Label</source> <translation>Label</translation> </message> @@ -203,7 +203,7 @@ This product includes software developed by the OpenSSL Project for use in the O <translation>Repeat new passphrase</translation> </message> <message> - <location filename="../askpassphrasedialog.cpp" line="+33"/> + <location filename="../askpassphrasedialog.cpp" line="+34"/> <source>Enter the new passphrase to the wallet.<br/>Please use a passphrase of <b>10 or more random characters</b>, or <b>eight or more words</b>.</source> <translation>Enter the new passphrase to the wallet.<br/>Please use a passphrase of <b>10 or more random characters</b>, or <b>eight or more words</b>.</translation> </message> @@ -324,7 +324,7 @@ This product includes software developed by the OpenSSL Project for use in the O <context> <name>BitcoinGUI</name> <message> - <location filename="../bitcoingui.cpp" line="+254"/> + <location filename="../bitcoingui.cpp" line="+255"/> <source>Sign &message...</source> <translation>Sign &message...</translation> </message> @@ -623,12 +623,12 @@ This product includes software developed by the OpenSSL Project for use in the O <translation>Information</translation> </message> <message> - <location line="+70"/> + <location line="+73"/> <source>This transaction is over the size limit. You can still send it for a fee of %1, which goes to the nodes that process your transaction and helps to support the network. Do you want to pay the fee?</source> <translation>This transaction is over the size limit. You can still send it for a fee of %1, which goes to the nodes that process your transaction and helps to support the network. Do you want to pay the fee?</translation> </message> <message> - <location line="-140"/> + <location line="-143"/> <source>Up to date</source> <translation>Up to date</translation> </message> @@ -638,7 +638,7 @@ This product includes software developed by the OpenSSL Project for use in the O <translation>Catching up...</translation> </message> <message> - <location line="+113"/> + <location line="+116"/> <source>Confirm transaction fee</source> <translation>Confirm transaction fee</translation> </message> @@ -666,18 +666,22 @@ Address: %4 </translation> </message> <message> - <location line="+33"/> - <location line="+23"/> + <location line="+34"/> <source>URI handling</source> <translation>URI handling</translation> </message> <message> - <location line="-23"/> - <location line="+23"/> + <location line="+0"/> <source>URI can not be parsed! This can be caused by an invalid Bitcoin address or malformed URI parameters.</source> <translation>URI can not be parsed! This can be caused by an invalid Bitcoin address or malformed URI parameters.</translation> </message> <message> + <location line="+27"/> + <location line="+2"/> + <source>Payment acknowledged</source> + <translation type="unfinished"></translation> + </message> + <message> <location line="+17"/> <source>Wallet is <b>encrypted</b> and currently <b>unlocked</b></source> <translation>Wallet is <b>encrypted</b> and currently <b>unlocked</b></translation> @@ -696,7 +700,7 @@ Address: %4 <context> <name>ClientModel</name> <message> - <location filename="../clientmodel.cpp" line="+105"/> + <location filename="../clientmodel.cpp" line="+106"/> <source>Network Alert</source> <translation>Network Alert</translation> </message> @@ -800,7 +804,7 @@ Address: %4 <context> <name>GUIUtil::HelpMessageBox</name> <message> - <location filename="../guiutil.cpp" line="+517"/> + <location filename="../guiutil.cpp" line="+525"/> <location line="+13"/> <source>Bitcoin-Qt</source> <translation>Bitcoin-Qt</translation> @@ -879,7 +883,7 @@ Address: %4 <translation>Use a custom data directory:</translation> </message> <message> - <location filename="../intro.cpp" line="+100"/> + <location filename="../intro.cpp" line="+105"/> <source>Error</source> <translation>Error</translation> </message> @@ -1067,7 +1071,7 @@ Address: %4 <translation>&Apply</translation> </message> <message> - <location filename="../optionsdialog.cpp" line="+54"/> + <location filename="../optionsdialog.cpp" line="+58"/> <source>default</source> <translation>default</translation> </message> @@ -1177,29 +1181,68 @@ Address: %4 <context> <name>PaymentServer</name> <message> - <location filename="../paymentserver.cpp" line="+108"/> - <source>Cannot start bitcoin: click-to-pay handler</source> - <translation>Cannot start bitcoin: click-to-pay handler</translation> + <location filename="../paymentserver.cpp" line="+450"/> + <location line="+41"/> + <source>Payment request error</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+1"/> + <source>Insecure requests to custom payment scripts unsupported</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+38"/> + <source>Refund from</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+46"/> + <location line="+28"/> + <location line="+17"/> + <source>Network request error</source> + <translation type="unfinished"></translation> </message> </context> <context> <name>QObject</name> <message> - <location filename="../bitcoin.cpp" line="+92"/> + <location filename="../bitcoin.cpp" line="+111"/> + <location line="+5"/> <location filename="../intro.cpp" line="-32"/> <source>Bitcoin</source> <translation>Bitcoin</translation> </message> <message> - <location line="+1"/> + <location line="-4"/> <source>Error: Specified data directory "%1" does not exist.</source> <translation>Error: Specified data directory "%1" does not exist.</translation> </message> <message> + <location line="+4"/> + <source>Error: Invalid combination of -regtest and -testnet.</source> + <translation type="unfinished"></translation> + </message> + <message> <location filename="../intro.cpp" line="+1"/> <source>Error: Specified data directory "%1" can not be created.</source> <translation>Error: Specified data directory "%1" can not be created.</translation> </message> + <message> + <location filename="../paymentserver.cpp" line="-175"/> + <source>Requested payment amount (%1) too small</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+126"/> + <source>Error communicating with %1: %2</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+29"/> + <source>Bad response from server %1</source> + <translation type="unfinished"></translation> + </message> </context> <context> <name>QRCodeDialog</name> @@ -1410,13 +1453,15 @@ Address: %4 <name>SendCoinsDialog</name> <message> <location filename="../forms/sendcoinsdialog.ui" line="+14"/> - <location filename="../sendcoinsdialog.cpp" line="+128"/> + <location filename="../sendcoinsdialog.cpp" line="+138"/> <location line="+5"/> <location line="+5"/> <location line="+5"/> <location line="+6"/> <location line="+5"/> - <location line="+5"/> + <location line="+50"/> + <location line="+145"/> + <location line="+9"/> <source>Send Coins</source> <translation>Send Coins</translation> </message> @@ -1461,25 +1506,19 @@ Address: %4 <translation>S&end</translation> </message> <message> - <location filename="../sendcoinsdialog.cpp" line="-62"/> - <location line="+2"/> - <source><b>%1</b> to %2 (%3)</source> - <translation><b>%1</b> to %2 (%3)</translation> - </message> - <message> - <location line="+6"/> + <location filename="../sendcoinsdialog.cpp" line="-170"/> <source>Confirm send coins</source> <translation>Confirm send coins</translation> </message> <message> - <location line="+1"/> - <source>Are you sure you want to send %1?</source> - <translation>Are you sure you want to send %1?</translation> + <location line="-97"/> + <source>to</source> + <translation type="unfinished">to</translation> </message> <message> - <location line="+0"/> - <source> and </source> - <translation> and </translation> + <location line="+15"/> + <source><b>%1</b> to %2</source> + <translation type="unfinished"></translation> </message> <message> <location line="+23"/> @@ -1512,36 +1551,63 @@ Address: %4 <translation>Error: Transaction creation failed!</translation> </message> <message> - <location line="+5"/> + <location line="+15"/> + <source>Are you sure you want to send?</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+9"/> + <source>added as transaction fee</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+6"/> + <source>Total Amount %1</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+20"/> <source>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.</source> <translation>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.</translation> </message> + <message> + <location line="+145"/> + <source>Payment request expired</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+9"/> + <source>Invalid payment address %1</source> + <translation type="unfinished"></translation> + </message> </context> <context> <name>SendCoinsEntry</name> <message> - <location filename="../forms/sendcoinsentry.ui" line="+14"/> + <location filename="../forms/sendcoinsentry.ui" line="+24"/> <source>Form</source> <translation>Form</translation> </message> <message> <location line="+15"/> + <location line="+588"/> <source>A&mount:</source> <translation>A&mount:</translation> </message> <message> - <location line="+13"/> + <location line="-575"/> + <location line="+588"/> <source>Pay &To:</source> <translation>Pay &To:</translation> </message> <message> - <location line="+34"/> + <location line="-554"/> <source>The address to send the payment to (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L)</source> <translation>The address to send the payment to (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L)</translation> </message> <message> <location line="+60"/> - <location filename="../sendcoinsentry.cpp" line="+26"/> + <location filename="../sendcoinsentry.cpp" line="+28"/> <source>Enter a label for this address to add it to your address book</source> <translation>Enter a label for this address to add it to your address book</translation> </message> @@ -1551,7 +1617,12 @@ Address: %4 <translation>&Label:</translation> </message> <message> - <location line="+28"/> + <location line="-54"/> + <source>StackedWidget</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+82"/> <source>Choose address from address book</source> <translation>Choose address from address book</translation> </message> @@ -1576,6 +1647,21 @@ Address: %4 <translation>Remove this recipient</translation> </message> <message> + <location line="+466"/> + <source>SecureSend</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+18"/> + <source>Memo:</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+63"/> + <source>message from merchant</source> + <translation type="unfinished"></translation> + </message> + <message> <location filename="../sendcoinsentry.cpp" line="+1"/> <source>Enter a Bitcoin address (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L)</source> <translation>Enter a Bitcoin address (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L)</translation> @@ -1708,7 +1794,7 @@ Address: %4 <translation>Enter Bitcoin signature</translation> </message> <message> - <location line="+82"/> + <location line="+85"/> <location line="+81"/> <source>The entered address is invalid.</source> <translation>The entered address is invalid.</translation> @@ -1777,7 +1863,7 @@ Address: %4 <context> <name>SplashScreen</name> <message> - <location filename="../splashscreen.cpp" line="+22"/> + <location filename="../splashscreen.cpp" line="+23"/> <source>The Bitcoin developers</source> <translation>The Bitcoin developers</translation> </message> @@ -1790,7 +1876,7 @@ Address: %4 <context> <name>TransactionDesc</name> <message> - <location filename="../transactiondesc.cpp" line="+20"/> + <location filename="../transactiondesc.cpp" line="+22"/> <source>Open until %1</source> <translation>Open until %1</translation> </message> @@ -1866,12 +1952,12 @@ Address: %4 <location line="+12"/> <location line="+45"/> <location line="+17"/> - <location line="+30"/> + <location line="+45"/> <source>Credit</source> <translation>Credit</translation> </message> <message numerus="yes"> - <location line="-102"/> + <location line="-117"/> <source>matures in %n more block(s)</source> <translation> <numerusform>matures in %n more block</numerusform> @@ -1887,12 +1973,12 @@ Address: %4 <location line="+44"/> <location line="+8"/> <location line="+15"/> - <location line="+30"/> + <location line="+45"/> <source>Debit</source> <translation>Debit</translation> </message> <message> - <location line="-39"/> + <location line="-54"/> <source>Transaction fee</source> <translation>Transaction fee</translation> </message> @@ -1917,7 +2003,12 @@ Address: %4 <translation>Transaction ID</translation> </message> <message> - <location line="+3"/> + <location line="+13"/> + <source>Merchant</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+5"/> <source>Generated coins must mature 120 blocks before they can be spent. When you generated this block, it was broadcast to the network to be added to the block chain. If it fails to get into the chain, its state will change to "not accepted" and it won't be spendable. This may occasionally happen if another node generates a block within a few seconds of yours.</source> <translation>Generated coins must mature 120 blocks before they can be spent. When you generated this block, it was broadcast to the network to be added to the block chain. If it fails to get into the chain, its state will change to "not accepted" and it won't be spendable. This may occasionally happen if another node generates a block within a few seconds of yours.</translation> </message> @@ -1952,7 +2043,7 @@ Address: %4 <translation>false</translation> </message> <message> - <location line="-209"/> + <location line="-224"/> <source>, has not been successfully broadcast yet</source> <translation>, has not been successfully broadcast yet</translation> </message> @@ -1986,7 +2077,7 @@ Address: %4 <context> <name>TransactionTableModel</name> <message> - <location filename="../transactiontablemodel.cpp" line="+225"/> + <location filename="../transactiontablemodel.cpp" line="+227"/> <source>Date</source> <translation>Date</translation> </message> @@ -2279,7 +2370,7 @@ Address: %4 <context> <name>WalletModel</name> <message> - <location filename="../walletmodel.cpp" line="+193"/> + <location filename="../walletmodel.cpp" line="+218"/> <source>Send Coins</source> <translation>Send Coins</translation> </message> @@ -2297,7 +2388,7 @@ Address: %4 <translation>Export the data in the current tab to a file</translation> </message> <message> - <location line="+197"/> + <location line="+198"/> <source>Backup Wallet</source> <translation>Backup Wallet</translation> </message> diff --git a/src/qt/paymentrequestplus.cpp b/src/qt/paymentrequestplus.cpp index 50fb1bd777..f6a898ff7c 100644 --- a/src/qt/paymentrequestplus.cpp +++ b/src/qt/paymentrequestplus.cpp @@ -80,7 +80,7 @@ bool PaymentRequestPlus::getMerchant(X509_STORE* certStore, QString& merchant) c return false; } else { - qDebug() << "PaymentRequestPlus::getMerchant : Payment request: unknown pki_type " << paymentRequest.pki_type().c_str(); + qDebug() << "PaymentRequestPlus::getMerchant : Payment request: unknown pki_type " << QString::fromStdString(paymentRequest.pki_type()); return false; } @@ -152,7 +152,7 @@ bool PaymentRequestPlus::getMerchant(X509_STORE* certStore, QString& merchant) c // Valid cert; check signature: payments::PaymentRequest rcopy(paymentRequest); // Copy rcopy.set_signature(std::string("")); - std::string data_to_verify; // Everything but the signature + std::string data_to_verify; // Everything but the signature rcopy.SerializeToString(&data_to_verify); EVP_MD_CTX ctx; diff --git a/src/qt/paymentserver.cpp b/src/qt/paymentserver.cpp index 6c10d8a04d..96ba997943 100644 --- a/src/qt/paymentserver.cpp +++ b/src/qt/paymentserver.cpp @@ -44,12 +44,11 @@ #include "wallet.h" #include "walletmodel.h" -using namespace boost; - const int BITCOIN_IPC_CONNECT_TIMEOUT = 1000; // milliseconds const QString BITCOIN_IPC_PREFIX("bitcoin:"); const char* BITCOIN_REQUEST_MIMETYPE = "application/bitcoin-paymentrequest"; const char* BITCOIN_PAYMENTACK_MIMETYPE = "application/bitcoin-paymentack"; +const char* BITCOIN_PAYMENTACK_CONTENTTYPE = "application/bitcoin-payment"; X509_STORE* PaymentServer::certStore = NULL; void PaymentServer::freeCertStore() @@ -73,14 +72,14 @@ static QString ipcServerName() // Append a simple hash of the datadir // Note that GetDataDir(true) returns a different path // for -testnet versus main net - QString ddir(GetDataDir(true).string().c_str()); + QString ddir(QString::fromStdString(GetDataDir(true).string())); name.append(QString::number(qHash(ddir))); return name; } // -// We store payment URLs and requests received before +// We store payment URIs and requests received before // the main GUI window is up and ready to ask the user // to send payment. @@ -250,8 +249,7 @@ bool PaymentServer::ipcSendCommandLine(int argc, char* argv[]) return fResult; } -PaymentServer::PaymentServer(QObject* parent, - bool startLocalServer) : QObject(parent), saveURIs(true) +PaymentServer::PaymentServer(QObject* parent, bool startLocalServer) : QObject(parent), saveURIs(true) { // Verify that the version of the library that we linked against is // compatible with the version of the headers we compiled against. @@ -286,12 +284,12 @@ PaymentServer::~PaymentServer() } // -// OSX-specific way of handling bitcoin uris and +// OSX-specific way of handling bitcoin: URIs and // PaymentRequest mime types // bool PaymentServer::eventFilter(QObject *, QEvent *event) { - // clicking on bitcoin: URLs creates FileOpen events on the Mac: + // clicking on bitcoin: URIs creates FileOpen events on the Mac: if (event->type() == QEvent::FileOpen) { QFileOpenEvent* fileEvent = static_cast<QFileOpenEvent*>(event); @@ -356,13 +354,13 @@ void PaymentServer::handleURIOrFile(const QString& s) if (s.startsWith(BITCOIN_IPC_PREFIX, Qt::CaseInsensitive)) // bitcoin: { #if QT_VERSION >= 0x050000 - QUrlQuery url((QUrl(s))); + QUrlQuery uri((QUrl(s))); #else - QUrl url(s); + QUrl uri(s); #endif - if (url.hasQueryItem("request")) + if (uri.hasQueryItem("request")) { - QByteArray temp; temp.append(url.queryItemValue("request")); + QByteArray temp; temp.append(uri.queryItemValue("request")); QString decoded = QUrl::fromPercentEncoding(temp); QUrl fetchUrl(decoded, QUrl::StrictMode); @@ -436,9 +434,7 @@ bool PaymentServer::readPaymentRequest(const QString& filename, PaymentRequestPl return request.parse(data); } -bool -PaymentServer::processPaymentRequest(PaymentRequestPlus& request, - QList<SendCoinsRecipient>& recipients) +bool PaymentServer::processPaymentRequest(PaymentRequestPlus& request, QList<SendCoinsRecipient>& recipients) { if (!optionsModel) return false; @@ -476,11 +472,7 @@ PaymentServer::processPaymentRequest(PaymentRequestPlus& request, recipients.append(SendCoinsRecipient()); recipients[i].amount = sendingTo.second; QString memo = QString::fromStdString(request.getDetails().memo()); -#if QT_VERSION < 0x050000 - recipients[i].label = Qt::escape(memo); -#else - recipients[i].label = memo.toHtmlEscaped(); -#endif + recipients[i].label = GUIUtil::HtmlEscape(memo); CTxDestination dest; if (ExtractDestination(sendingTo.first, dest)) { if (i == 0) // Tie request to first pay-to, we don't want multiple ACKs @@ -493,7 +485,7 @@ PaymentServer::processPaymentRequest(PaymentRequestPlus& request, // Insecure payments to custom bitcoin addresses are not supported // (there is no good way to tell the user where they are paying in a way // they'd have a chance of understanding). - emit reportError(tr("Payment request error"), + emit reportError(tr("Payment request error"), tr("Insecure requests to custom payment scripts unsupported"), CClientUIInterface::MODAL); return false; @@ -504,8 +496,7 @@ PaymentServer::processPaymentRequest(PaymentRequestPlus& request, return true; } -void -PaymentServer::fetchRequest(const QUrl& url) +void PaymentServer::fetchRequest(const QUrl& url) { QNetworkRequest netRequest; netRequest.setAttribute(QNetworkRequest::User, "PaymentRequest"); @@ -515,8 +506,7 @@ PaymentServer::fetchRequest(const QUrl& url) netManager->get(netRequest); } -void -PaymentServer::fetchPaymentACK(CWallet* wallet, SendCoinsRecipient recipient, QByteArray transaction) +void PaymentServer::fetchPaymentACK(CWallet* wallet, SendCoinsRecipient recipient, QByteArray transaction) { const payments::PaymentDetails& details = recipient.paymentRequest.getDetails(); if (!details.has_payment_url()) @@ -525,7 +515,7 @@ PaymentServer::fetchPaymentACK(CWallet* wallet, SendCoinsRecipient recipient, QB QNetworkRequest netRequest; netRequest.setAttribute(QNetworkRequest::User, "PaymentACK"); netRequest.setUrl(QString::fromStdString(details.payment_url())); - netRequest.setHeader(QNetworkRequest::ContentTypeHeader, "application/bitcoin-payment"); + netRequest.setHeader(QNetworkRequest::ContentTypeHeader, BITCOIN_PAYMENTACK_CONTENTTYPE); netRequest.setRawHeader("User-Agent", CLIENT_NAME.c_str()); netRequest.setRawHeader("Accept", BITCOIN_PAYMENTACK_MIMETYPE); @@ -571,8 +561,7 @@ PaymentServer::fetchPaymentACK(CWallet* wallet, SendCoinsRecipient recipient, QB } } -void -PaymentServer::netRequestFinished(QNetworkReply* reply) +void PaymentServer::netRequestFinished(QNetworkReply* reply) { reply->deleteLater(); if (reply->error() != QNetworkReply::NoError) @@ -617,9 +606,10 @@ PaymentServer::netRequestFinished(QNetworkReply* reply) } } -void -PaymentServer::reportSslErrors(QNetworkReply* reply, const QList<QSslError> &errs) +void PaymentServer::reportSslErrors(QNetworkReply* reply, const QList<QSslError> &errs) { + Q_UNUSED(reply); + QString errString; foreach (const QSslError& err, errs) { qDebug() << "PaymentServer::reportSslErrors : " << err; diff --git a/src/qt/paymentserver.h b/src/qt/paymentserver.h index 131ede518e..f9d827204b 100644 --- a/src/qt/paymentserver.h +++ b/src/qt/paymentserver.h @@ -36,6 +36,8 @@ class CWallet; class OptionsModel; + +QT_BEGIN_NAMESPACE class QApplication; class QByteArray; class QLocalServer; @@ -43,6 +45,7 @@ class QNetworkAccessManager; class QNetworkReply; class QSslError; class QUrl; +QT_END_NAMESPACE class PaymentServer : public QObject { @@ -56,8 +59,8 @@ public: // will be called so we startup in the right mode. static bool ipcSendCommandLine(int argc, char *argv[]); - PaymentServer(QObject* parent, // parent should be QApplication object - bool startLocalServer=true); + // parent should be QApplication object + PaymentServer(QObject* parent, bool startLocalServer = true); ~PaymentServer(); // Load root certificate authorities. Pass NULL (default) @@ -65,7 +68,7 @@ public: // or, if that's not set, to use the system default root certificates. // If you pass in a store, you should not X509_STORE_free it: it will be // freed either at exit or when another set of CAs are loaded. - static void LoadRootCAs(X509_STORE* store=NULL); + static void LoadRootCAs(X509_STORE* store = NULL); // Return certificate store static X509_STORE* getCertStore() { return certStore; } diff --git a/src/qt/rpcconsole.cpp b/src/qt/rpcconsole.cpp index 8953c36579..e7dcdf62a1 100644 --- a/src/qt/rpcconsole.cpp +++ b/src/qt/rpcconsole.cpp @@ -22,6 +22,8 @@ const int CONSOLE_HISTORY = 50; const QSize ICON_SIZE(24, 24); +const int INITIAL_TRAFFIC_GRAPH_MINS = 30; + const struct { const char *url; const char *source; @@ -204,6 +206,7 @@ RPCConsole::RPCConsole(QWidget *parent) : ui->openSSLVersion->setText(SSLeay_version(SSLEAY_VERSION)); startExecutor(); + setTrafficGraphRange(INITIAL_TRAFFIC_GRAPH_MINS); clear(); } @@ -253,7 +256,8 @@ bool RPCConsole::eventFilter(QObject* obj, QEvent *event) void RPCConsole::setClientModel(ClientModel *model) { - this->clientModel = model; + clientModel = model; + ui->trafficGraph->setClientModel(model); if(model) { // Keep up to date with client @@ -263,6 +267,9 @@ void RPCConsole::setClientModel(ClientModel *model) setNumBlocks(model->getNumBlocks(), model->getNumBlocksOfPeers()); connect(model, SIGNAL(numBlocksChanged(int,int)), this, SLOT(setNumBlocks(int,int))); + updateTrafficStats(model->getTotalBytesRecv(), model->getTotalBytesSent()); + connect(model, SIGNAL(bytesChanged(quint64,quint64)), this, SLOT(updateTrafficStats(quint64, quint64))); + // Provide initial values ui->clientVersion->setText(model->formatFullVersion()); ui->clientName->setText(model->clientName()); @@ -431,3 +438,49 @@ void RPCConsole::on_showCLOptionsButton_clicked() GUIUtil::HelpMessageBox help; help.exec(); } + +void RPCConsole::on_sldGraphRange_valueChanged(int value) +{ + const int multiplier = 5; // each position on the slider represents 5 min + int mins = value * multiplier; + setTrafficGraphRange(mins); +} + +QString RPCConsole::FormatBytes(quint64 bytes) +{ + if(bytes < 1024) + return QString(tr("%1 B")).arg(bytes); + if(bytes < 1024 * 1024) + return QString(tr("%1 KB")).arg(bytes / 1024); + if(bytes < 1024 * 1024 * 1024) + return QString(tr("%1 MB")).arg(bytes / 1024 / 1024); + + return QString(tr("%1 GB")).arg(bytes / 1024 / 1024 / 1024); +} + +void RPCConsole::setTrafficGraphRange(int mins) +{ + ui->trafficGraph->setGraphRangeMins(mins); + if(mins < 60) { + ui->lblGraphRange->setText(QString(tr("%1 m")).arg(mins)); + } else { + int hours = mins / 60; + int minsLeft = mins % 60; + if(minsLeft == 0) { + ui->lblGraphRange->setText(QString(tr("%1 h")).arg(hours)); + } else { + ui->lblGraphRange->setText(QString(tr("%1 h %2 m")).arg(hours).arg(minsLeft)); + } + } +} + +void RPCConsole::updateTrafficStats(quint64 totalBytesIn, quint64 totalBytesOut) +{ + ui->lblBytesIn->setText(FormatBytes(totalBytesIn)); + ui->lblBytesOut->setText(FormatBytes(totalBytesOut)); +} + +void RPCConsole::on_btnClearTrafficGraph_clicked() +{ + ui->trafficGraph->clear(); +} diff --git a/src/qt/rpcconsole.h b/src/qt/rpcconsole.h index 3c38b4b8de..af92b55770 100644 --- a/src/qt/rpcconsole.h +++ b/src/qt/rpcconsole.h @@ -37,6 +37,12 @@ private slots: void on_openDebugLogfileButton_clicked(); /** display messagebox with program parameters (same as bitcoin-qt --help) */ void on_showCLOptionsButton_clicked(); + /** change the time range of the network traffic graph */ + void on_sldGraphRange_valueChanged(int value); + /** update traffic statistics */ + void updateTrafficStats(quint64 totalBytesIn, quint64 totalBytesOut); + /** clear traffic graph */ + void on_btnClearTrafficGraph_clicked(); public slots: void clear(); @@ -55,6 +61,9 @@ signals: void cmdRequest(const QString &command); private: + static QString FormatBytes(quint64 bytes); + void setTrafficGraphRange(int mins); + Ui::RPCConsole *ui; ClientModel *clientModel; QStringList history; diff --git a/src/qt/sendcoinsdialog.cpp b/src/qt/sendcoinsdialog.cpp index 809eff9c27..3fd4a26e76 100644 --- a/src/qt/sendcoinsdialog.cpp +++ b/src/qt/sendcoinsdialog.cpp @@ -94,27 +94,33 @@ void SendCoinsDialog::on_sendButton_clicked() QStringList formatted; foreach(const SendCoinsRecipient &rcp, recipients) { - QString amount = BitcoinUnits::formatWithUnit(model->getOptionsModel()->getDisplayUnit(), rcp.amount); + // generate bold amount string + QString amount = "<b>" + BitcoinUnits::formatWithUnit(model->getOptionsModel()->getDisplayUnit(), rcp.amount); + amount.append("</b>"); + // generate monospace address string + QString address = "<span style='font-family: monospace;'>" + rcp.address; + address.append("</span>"); + + QString recipientElement; + if (rcp.authenticatedMerchant.isEmpty()) { - QString recipientElement = QString("<b>%1</b> ").arg(BitcoinUnits::formatWithUnit(model->getOptionsModel()->getDisplayUnit(), rcp.amount)); - recipientElement.append(tr("to")); - - if(rcp.label.length() > 0) + if(rcp.label.length() > 0) // label with address { - recipientElement.append(QString(" %1 <span style='font-size:8px;'>%2</span><br />").arg(GUIUtil::HtmlEscape(rcp.label), rcp.address)); // add address with label + recipientElement = tr("%1 to %2").arg(amount, GUIUtil::HtmlEscape(rcp.label)); + recipientElement.append(QString(" (%1)").arg(address)); } - else + else // just address { - recipientElement.append(QString(" %1<br />").arg(rcp.address)); // add address WITHOUT label + recipientElement = tr("%1 to %2").arg(amount, address); } - formatted.append(recipientElement); } - else + else // just merchant { - QString merchant = GUIUtil::HtmlEscape(rcp.authenticatedMerchant); - formatted.append(tr("<b>%1</b> to %2").arg(amount, merchant)); + recipientElement = tr("%1 to %2").arg(amount, GUIUtil::HtmlEscape(rcp.authenticatedMerchant)); } + + formatted.append(recipientElement); } fNewRecipientAllowed = false; @@ -132,42 +138,38 @@ void SendCoinsDialog::on_sendButton_clicked() WalletModelTransaction currentTransaction(recipients); WalletModel::SendCoinsReturn prepareStatus = model->prepareTransaction(currentTransaction); + QString strSendCoins = tr("Send Coins"); switch(prepareStatus.status) { case WalletModel::InvalidAddress: - QMessageBox::warning(this, tr("Send Coins"), - tr("The recipient address is not valid, please recheck."), - QMessageBox::Ok, QMessageBox::Ok); + QMessageBox::warning(this, strSendCoins, + tr("The recipient address is not valid, please recheck.")); break; case WalletModel::InvalidAmount: - QMessageBox::warning(this, tr("Send Coins"), - tr("The amount to pay must be larger than 0."), - QMessageBox::Ok, QMessageBox::Ok); + QMessageBox::warning(this, strSendCoins, + tr("The amount to pay must be larger than 0.")); break; case WalletModel::AmountExceedsBalance: - QMessageBox::warning(this, tr("Send Coins"), - tr("The amount exceeds your balance."), - QMessageBox::Ok, QMessageBox::Ok); + QMessageBox::warning(this, strSendCoins, + tr("The amount exceeds your balance.")); break; case WalletModel::AmountWithFeeExceedsBalance: - QMessageBox::warning(this, tr("Send Coins"), + QMessageBox::warning(this, strSendCoins, tr("The total exceeds your balance when the %1 transaction fee is included."). - arg(BitcoinUnits::formatWithUnit(model->getOptionsModel()->getDisplayUnit(), currentTransaction.getTransactionFee())), - QMessageBox::Ok, QMessageBox::Ok); + arg(BitcoinUnits::formatWithUnit(model->getOptionsModel()->getDisplayUnit(), currentTransaction.getTransactionFee()))); break; case WalletModel::DuplicateAddress: - QMessageBox::warning(this, tr("Send Coins"), - tr("Duplicate address found, can only send to each address once per send operation."), - QMessageBox::Ok, QMessageBox::Ok); + QMessageBox::warning(this, strSendCoins, + tr("Duplicate address found, can only send to each address once per send operation.")); break; case WalletModel::TransactionCreationFailed: - QMessageBox::warning(this, tr("Send Coins"), - tr("Error: Transaction creation failed!"), - QMessageBox::Ok, QMessageBox::Ok); + QMessageBox::warning(this, strSendCoins, + tr("Error: Transaction creation failed!")); break; - case WalletModel::Aborted: // User aborted, nothing to do - case WalletModel::OK: case WalletModel::TransactionCommitFailed: + case WalletModel::OK: + case WalletModel::Aborted: // User aborted, nothing to do + default: break; } @@ -197,7 +199,7 @@ void SendCoinsDialog::on_sendButton_clicked() QMessageBox::StandardButton retval = QMessageBox::question(this, tr("Confirm send coins"), questionString.arg(formatted.join("<br />")), - QMessageBox::Yes|QMessageBox::Cancel, + QMessageBox::Yes | QMessageBox::Cancel, QMessageBox::Cancel); if(retval != QMessageBox::Yes) @@ -211,15 +213,13 @@ void SendCoinsDialog::on_sendButton_clicked() switch(sendstatus.status) { case WalletModel::TransactionCommitFailed: - QMessageBox::warning(this, tr("Send Coins"), - tr("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."), - QMessageBox::Ok, QMessageBox::Ok); - break; - case WalletModel::Aborted: // User aborted, nothing to do + QMessageBox::warning(this, strSendCoins, + tr("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.")); break; case WalletModel::OK: accept(); break; + case WalletModel::Aborted: // User aborted, nothing to do default: break; } @@ -351,22 +351,22 @@ void SendCoinsDialog::pasteEntry(const SendCoinsRecipient &rv) bool SendCoinsDialog::handlePaymentRequest(const SendCoinsRecipient &rv) { + QString strSendCoins = tr("Send Coins"); if (!rv.authenticatedMerchant.isEmpty()) { // Expired payment request? const payments::PaymentDetails& details = rv.paymentRequest.getDetails(); if (details.has_expires() && (int64)details.expires() < GetTime()) { - QMessageBox::warning(this, tr("Send Coins"), - tr("Payment request expired")); + QMessageBox::warning(this, strSendCoins, + tr("Payment request expired")); return false; } } else { CBitcoinAddress address(rv.address.toStdString()); if (!address.IsValid()) { - QString strAddress(address.ToString().c_str()); - QMessageBox::warning(this, tr("Send Coins"), - tr("Invalid payment address %1").arg(strAddress)); + QMessageBox::warning(this, strSendCoins, + tr("Invalid payment address %1").arg(rv.address)); return false; } } diff --git a/src/qt/sendcoinsentry.cpp b/src/qt/sendcoinsentry.cpp index 75610f199e..aa671e0540 100644 --- a/src/qt/sendcoinsentry.cpp +++ b/src/qt/sendcoinsentry.cpp @@ -85,10 +85,17 @@ void SendCoinsEntry::setRemoveEnabled(bool enabled) void SendCoinsEntry::clear() { + // clear UI elements for insecure payments ui->payTo->clear(); ui->addAsLabel->clear(); ui->payAmount->clear(); + // and the ones for secure payments just to be sure + ui->payTo_s->clear(); + ui->memoTextLabel_s->clear(); + ui->payAmount_s->clear(); + ui->payTo->setFocus(); + // update the display unit, to not use the default ("BTC") updateDisplayUnit(); } @@ -106,8 +113,8 @@ bool SendCoinsEntry::validate() if (!recipient.authenticatedMerchant.isEmpty()) return retval; - if(!ui->payTo->hasAcceptableInput() || - (model && !model->validateAddress(ui->payTo->text()))) + if (!ui->payTo->hasAcceptableInput() || + (model && !model->validateAddress(ui->payTo->text()))) { ui->payTo->setValid(false); retval = false; @@ -154,18 +161,20 @@ void SendCoinsEntry::setValue(const SendCoinsRecipient &value) { recipient = value; - ui->payTo->setText(value.address); - ui->addAsLabel->setText(value.label); - ui->payAmount->setValue(value.amount); - - if (!recipient.authenticatedMerchant.isEmpty()) + if (recipient.authenticatedMerchant.isEmpty()) + { + ui->payTo->setText(recipient.address); + ui->addAsLabel->setText(recipient.label); + ui->payAmount->setValue(recipient.amount); + } + else { - const payments::PaymentDetails& details = value.paymentRequest.getDetails(); + const payments::PaymentDetails& details = recipient.paymentRequest.getDetails(); - ui->payTo_s->setText(value.authenticatedMerchant); - ui->memo_s->setTextFormat(Qt::PlainText); - ui->memo_s->setText(QString::fromStdString(details.memo())); - ui->payAmount_s->setValue(value.amount); + ui->payTo_s->setText(recipient.authenticatedMerchant); + ui->memoTextLabel_s->setText(QString::fromStdString(details.memo())); + ui->payAmount_s->setValue(recipient.amount); + ui->payAmount_s->setReadOnly(true); setCurrentWidget(ui->SendCoinsSecure); } } diff --git a/src/qt/sendcoinsentry.h b/src/qt/sendcoinsentry.h index 9c7bfe9521..49e622daf1 100644 --- a/src/qt/sendcoinsentry.h +++ b/src/qt/sendcoinsentry.h @@ -33,7 +33,8 @@ public: void setValue(const SendCoinsRecipient &value); void setAddress(const QString &address); - /** Set up the tab chain manually, as Qt messes up the tab chain by default in some cases (issue https://bugreports.qt-project.org/browse/QTBUG-10907). + /** Set up the tab chain manually, as Qt messes up the tab chain by default in some cases + * (issue https://bugreports.qt-project.org/browse/QTBUG-10907). */ QWidget *setupTabChain(QWidget *prev); diff --git a/src/qt/test/Makefile.am b/src/qt/test/Makefile.am index f51ac9bd6d..f8fe97462b 100644 --- a/src/qt/test/Makefile.am +++ b/src/qt/test/Makefile.am @@ -4,7 +4,7 @@ AM_CPPFLAGS = $(INCLUDES) -I$(top_builddir)/src/obj \ -I$(top_srcdir)/src/leveldb/include -I$(top_srcdir)/src \ -I$(top_srcdir)/src/leveldb/helpers -I$(top_srcdir)/src/qt \ -I$(top_builddir)/src/qt $(BOOST_INCLUDES) $(PROTOBUF_CFLAGS) \ - $(QR_CFLAGS) + $(QR_CFLAGS) $(BDB_CPPFLAGS) AM_LDFLAGS = $(PTHREAD_CFLAGS) bin_PROGRAMS = test_bitcoin-qt TESTS = test_bitcoin-qt @@ -20,7 +20,7 @@ test_bitcoin_qt_SOURCES = test_main.cpp uritests.cpp paymentservertests.cpp $(TE nodist_test_bitcoin_qt_SOURCES = $(TEST_QT_MOC_CPP) test_bitcoin_qt_LDADD = $(LIBBITCOINQT) $(LIBBITCOIN) $(LIBLEVELDB) \ $(LIBMEMENV) $(BOOST_LIBS) $(QT_LIBS) $(QT_DBUS_LIBS) $(QT_TEST_LIBS) \ - $(QR_LIBS) $(PROTOBUF_LIBS) + $(QR_LIBS) $(PROTOBUF_LIBS) $(BDB_LIBS) CLEANFILES = $(BUILT_SOURCES) *.gcda *.gcno diff --git a/src/qt/trafficgraphwidget.cpp b/src/qt/trafficgraphwidget.cpp new file mode 100644 index 0000000000..d49bc31f3e --- /dev/null +++ b/src/qt/trafficgraphwidget.cpp @@ -0,0 +1,169 @@ +#include "trafficgraphwidget.h" +#include "clientmodel.h" + +#include <QPainter> +#include <QColor> +#include <QTimer> + +#include <cmath> + +#define DESIRED_SAMPLES 800 + +#define XMARGIN 10 +#define YMARGIN 10 + +TrafficGraphWidget::TrafficGraphWidget(QWidget *parent) : + QWidget(parent), + timer(0), + fMax(0.0f), + nMins(0), + vSamplesIn(), + vSamplesOut(), + nLastBytesIn(0), + nLastBytesOut(0), + clientModel(0) +{ + timer = new QTimer(this); + connect(timer, SIGNAL(timeout()), SLOT(updateRates())); +} + +void TrafficGraphWidget::setClientModel(ClientModel *model) +{ + clientModel = model; + if(model) { + nLastBytesIn = model->getTotalBytesRecv(); + nLastBytesOut = model->getTotalBytesSent(); + } +} + +int TrafficGraphWidget::getGraphRangeMins() const +{ + return nMins; +} + +void TrafficGraphWidget::paintPath(QPainterPath &path, QQueue<float> &samples) +{ + int h = height() - YMARGIN * 2, w = width() - XMARGIN * 2; + int sampleCount = samples.size(), x = XMARGIN + w, y; + if(sampleCount > 0) { + path.moveTo(x, YMARGIN + h); + for(int i = 0; i < sampleCount; ++i) { + x = XMARGIN + w - w * i / DESIRED_SAMPLES; + y = YMARGIN + h - (int)(h * samples.at(i) / fMax); + path.lineTo(x, y); + } + path.lineTo(x, YMARGIN + h); + } +} + +void TrafficGraphWidget::paintEvent(QPaintEvent *) +{ + QPainter painter(this); + painter.fillRect(rect(), Qt::black); + + if(fMax <= 0.0f) return; + + QColor axisCol(Qt::gray); + int h = height() - YMARGIN * 2; + painter.setPen(axisCol); + painter.drawLine(XMARGIN, YMARGIN + h, width() - XMARGIN, YMARGIN + h); + + // decide what order of magnitude we are + int base = floor(log10(fMax)); + float val = pow(10.0f, base); + + const QString units = tr("KB/s"); + // draw lines + painter.setPen(axisCol); + painter.drawText(XMARGIN, YMARGIN + h - h * val / fMax, QString("%1 %2").arg(val).arg(units)); + for(float y = val; y < fMax; y += val) { + int yy = YMARGIN + h - h * y / fMax; + painter.drawLine(XMARGIN, yy, width() - XMARGIN, yy); + } + // if we drew 3 or fewer lines, break them up at the next lower order of magnitude + if(fMax / val <= 3.0f) { + axisCol = axisCol.darker(); + val = pow(10.0f, base - 1); + painter.setPen(axisCol); + painter.drawText(XMARGIN, YMARGIN + h - h * val / fMax, QString("%1 %2").arg(val).arg(units)); + int count = 1; + for(float y = val; y < fMax; y += val, count++) { + // don't overwrite lines drawn above + if(count % 10 == 0) + continue; + int yy = YMARGIN + h - h * y / fMax; + painter.drawLine(XMARGIN, yy, width() - XMARGIN, yy); + } + } + + if(!vSamplesIn.empty()) { + QPainterPath p; + paintPath(p, vSamplesIn); + painter.fillPath(p, QColor(0, 255, 0, 128)); + painter.setPen(Qt::green); + painter.drawPath(p); + } + if(!vSamplesOut.empty()) { + QPainterPath p; + paintPath(p, vSamplesOut); + painter.fillPath(p, QColor(255, 0, 0, 128)); + painter.setPen(Qt::red); + painter.drawPath(p); + } +} + +void TrafficGraphWidget::updateRates() +{ + if(!clientModel) return; + + quint64 bytesIn = clientModel->getTotalBytesRecv(), + bytesOut = clientModel->getTotalBytesSent(); + float inRate = (bytesIn - nLastBytesIn) / 1024.0f * 1000 / timer->interval(); + float outRate = (bytesOut - nLastBytesOut) / 1024.0f * 1000 / timer->interval(); + vSamplesIn.push_front(inRate); + vSamplesOut.push_front(outRate); + nLastBytesIn = bytesIn; + nLastBytesOut = bytesOut; + + while(vSamplesIn.size() > DESIRED_SAMPLES) { + vSamplesIn.pop_back(); + } + while(vSamplesOut.size() > DESIRED_SAMPLES) { + vSamplesOut.pop_back(); + } + + float tmax = 0.0f; + foreach(float f, vSamplesIn) { + if(f > tmax) tmax = f; + } + foreach(float f, vSamplesOut) { + if(f > tmax) tmax = f; + } + fMax = tmax; + update(); +} + +void TrafficGraphWidget::setGraphRangeMins(int mins) +{ + nMins = mins; + int msecsPerSample = nMins * 60 * 1000 / DESIRED_SAMPLES; + timer->stop(); + timer->setInterval(msecsPerSample); + + clear(); +} + +void TrafficGraphWidget::clear() +{ + timer->stop(); + + vSamplesOut.clear(); + vSamplesIn.clear(); + fMax = 0.0f; + + if(clientModel) { + nLastBytesIn = clientModel->getTotalBytesRecv(); + nLastBytesOut = clientModel->getTotalBytesSent(); + } + timer->start(); +} diff --git a/src/qt/trafficgraphwidget.h b/src/qt/trafficgraphwidget.h new file mode 100644 index 0000000000..b31d1d5b0a --- /dev/null +++ b/src/qt/trafficgraphwidget.h @@ -0,0 +1,44 @@ +#ifndef TRAFFICGRAPHWIDGET_H +#define TRAFFICGRAPHWIDGET_H + +#include <QWidget> +#include <QQueue> + +class ClientModel; + +QT_BEGIN_NAMESPACE +class QPaintEvent; +class QTimer; +QT_END_NAMESPACE + +class TrafficGraphWidget : public QWidget +{ + Q_OBJECT + +public: + explicit TrafficGraphWidget(QWidget *parent = 0); + void setClientModel(ClientModel *model); + int getGraphRangeMins() const; + +protected: + void paintEvent(QPaintEvent *); + +public slots: + void updateRates(); + void setGraphRangeMins(int mins); + void clear(); + +private: + void paintPath(QPainterPath &path, QQueue<float> &samples); + + QTimer *timer; + float fMax; + int nMins; + QQueue<float> vSamplesIn; + QQueue<float> vSamplesOut; + quint64 nLastBytesIn; + quint64 nLastBytesOut; + ClientModel *clientModel; +}; + +#endif // TRAFFICGRAPHWIDGET_H diff --git a/src/qt/transactiondesc.cpp b/src/qt/transactiondesc.cpp index e27aa93a4a..93fc8cab22 100644 --- a/src/qt/transactiondesc.cpp +++ b/src/qt/transactiondesc.cpp @@ -17,7 +17,7 @@ QString TransactionDesc::FormatTxStatus(const CWalletTx& wtx) if (!IsFinalTx(wtx)) { if (wtx.nLockTime < LOCKTIME_THRESHOLD) - return tr("Open for %n more block(s)", "", wtx.nLockTime - nBestHeight + 1); + return tr("Open for %n more block(s)", "", wtx.nLockTime - chainActive.Height() + 1); else return tr("Open until %1").arg(GUIUtil::dateTimeStr(wtx.nLockTime)); } diff --git a/src/qt/transactionrecord.cpp b/src/qt/transactionrecord.cpp index ea2c1f0a5c..162908a9a4 100644 --- a/src/qt/transactionrecord.cpp +++ b/src/qt/transactionrecord.cpp @@ -160,14 +160,14 @@ void TransactionRecord::updateStatus(const CWalletTx &wtx) idx); status.confirmed = wtx.IsConfirmed(); status.depth = wtx.GetDepthInMainChain(); - status.cur_num_blocks = nBestHeight; + status.cur_num_blocks = chainActive.Height(); if (!IsFinalTx(wtx)) { if (wtx.nLockTime < LOCKTIME_THRESHOLD) { status.status = TransactionStatus::OpenUntilBlock; - status.open_for = wtx.nLockTime - nBestHeight + 1; + status.open_for = wtx.nLockTime - chainActive.Height() + 1; } else { @@ -221,7 +221,7 @@ void TransactionRecord::updateStatus(const CWalletTx &wtx) bool TransactionRecord::statusUpdateNeeded() { - return status.cur_num_blocks != nBestHeight; + return status.cur_num_blocks != chainActive.Height(); } QString TransactionRecord::getTxID() const diff --git a/src/qt/transactiontablemodel.cpp b/src/qt/transactiontablemodel.cpp index 07f6a62150..6f7a5933ab 100644 --- a/src/qt/transactiontablemodel.cpp +++ b/src/qt/transactiontablemodel.cpp @@ -250,9 +250,9 @@ void TransactionTableModel::updateTransaction(const QString &hash, int status) void TransactionTableModel::updateConfirmations() { - if(nBestHeight != cachedNumBlocks) + if(chainActive.Height() != cachedNumBlocks) { - cachedNumBlocks = nBestHeight; + cachedNumBlocks = chainActive.Height(); // Blocks came in since last poll. // Invalidate status (number of confirmations) and (possibly) description // for all rows. Qt is smart enough to only actually request the data for the diff --git a/src/qt/walletframe.cpp b/src/qt/walletframe.cpp index 99a6647a65..8d6a1b387e 100644 --- a/src/qt/walletframe.cpp +++ b/src/qt/walletframe.cpp @@ -56,12 +56,9 @@ bool WalletFrame::handlePaymentRequest(const SendCoinsRecipient &recipient) void WalletFrame::showOutOfSyncWarning(bool fShow) { - if (!walletStack) { - QMessageBox box; - box.setText("walletStack is null"); - box.exec(); + if (!walletStack) return; - } + walletStack->showOutOfSyncWarning(fShow); } diff --git a/src/qt/walletmodel.cpp b/src/qt/walletmodel.cpp index 1dcecbe60b..417bac9928 100644 --- a/src/qt/walletmodel.cpp +++ b/src/qt/walletmodel.cpp @@ -73,10 +73,10 @@ void WalletModel::updateStatus() void WalletModel::pollBalanceChanged() { - if(nBestHeight != cachedNumBlocks) + if(chainActive.Height() != cachedNumBlocks) { // Balance and number of transactions might have changed - cachedNumBlocks = nBestHeight; + cachedNumBlocks = chainActive.Height(); checkBalanceChanged(); } } @@ -143,7 +143,7 @@ WalletModel::SendCoinsReturn WalletModel::prepareTransaction(WalletModelTransact foreach(const SendCoinsRecipient &rcp, recipients) { if (rcp.paymentRequest.IsInitialized()) - { // PaymentRequest... + { // PaymentRequest... int64 subtotal = 0; const payments::PaymentDetails& details = rcp.paymentRequest.getDetails(); for (int i = 0; i < details.outputs_size(); i++) @@ -258,22 +258,26 @@ WalletModel::SendCoinsReturn WalletModel::sendCoins(WalletModelTransaction &tran // and emit coinsSent signal for each recipient foreach(const SendCoinsRecipient &rcp, transaction.getRecipients()) { - std::string strAddress = rcp.address.toStdString(); - CTxDestination dest = CBitcoinAddress(strAddress).Get(); - std::string strLabel = rcp.label.toStdString(); + // Don't touch the address book when we have a secure payment-request + if (rcp.authenticatedMerchant.isEmpty()) { - LOCK(wallet->cs_wallet); - - std::map<CTxDestination, CAddressBookData>::iterator mi = wallet->mapAddressBook.find(dest); - - // Check if we have a new address or an updated label - if (mi == wallet->mapAddressBook.end()) - { - wallet->SetAddressBook(dest, strLabel, "send"); - } - else if (mi->second.name != strLabel) + std::string strAddress = rcp.address.toStdString(); + CTxDestination dest = CBitcoinAddress(strAddress).Get(); + std::string strLabel = rcp.label.toStdString(); { - wallet->SetAddressBook(dest, strLabel, ""); // "" means don't change purpose + LOCK(wallet->cs_wallet); + + std::map<CTxDestination, CAddressBookData>::iterator mi = wallet->mapAddressBook.find(dest); + + // Check if we have a new address or an updated label + if (mi == wallet->mapAddressBook.end()) + { + wallet->SetAddressBook(dest, strLabel, "send"); + } + else if (mi->second.name != strLabel) + { + wallet->SetAddressBook(dest, strLabel, ""); // "" means don't change purpose + } } } emit coinsSent(wallet, rcp, transaction_array); diff --git a/src/qt/walletmodeltransaction.cpp b/src/qt/walletmodeltransaction.cpp index 96fc3edbb2..706ed60b77 100644 --- a/src/qt/walletmodeltransaction.cpp +++ b/src/qt/walletmodeltransaction.cpp @@ -32,7 +32,7 @@ qint64 WalletModelTransaction::getTransactionFee() void WalletModelTransaction::setTransactionFee(qint64 newFee) { - fee=newFee; + fee = newFee; } qint64 WalletModelTransaction::getTotalTransactionAmount() @@ -40,7 +40,7 @@ qint64 WalletModelTransaction::getTotalTransactionAmount() qint64 totalTransactionAmount = 0; foreach(const SendCoinsRecipient &rcp, recipients) { - totalTransactionAmount+=rcp.amount; + totalTransactionAmount += rcp.amount; } return totalTransactionAmount; } |