aboutsummaryrefslogtreecommitdiff
path: root/src/qt
diff options
context:
space:
mode:
Diffstat (limited to 'src/qt')
-rw-r--r--src/qt/bitcoin.cpp28
-rw-r--r--src/qt/bitcoin.qrc2
-rw-r--r--src/qt/bitcoingui.cpp13
-rw-r--r--src/qt/bitcoingui.h3
-rw-r--r--src/qt/clientmodel.cpp5
-rw-r--r--src/qt/clientmodel.h1
-rw-r--r--src/qt/forms/aboutdialog.ui12
-rw-r--r--src/qt/forms/addressbookpage.ui2
-rw-r--r--src/qt/forms/messagepage.ui19
-rw-r--r--src/qt/forms/overviewpage.ui12
-rw-r--r--src/qt/forms/qrcodedialog.ui6
-rw-r--r--src/qt/forms/rpcconsole.ui323
-rw-r--r--src/qt/messagepage.cpp12
-rw-r--r--src/qt/messagepage.h1
-rw-r--r--src/qt/optionsdialog.cpp1
-rw-r--r--src/qt/res/icons/qrcode.pngbin0 -> 237 bytes
-rw-r--r--src/qt/res/images/qrcode.pngbin5993 -> 0 bytes
-rw-r--r--src/qt/rpcconsole.cpp316
-rw-r--r--src/qt/rpcconsole.h64
-rw-r--r--src/qt/sendcoinsentry.cpp4
-rw-r--r--src/qt/walletmodel.cpp13
21 files changed, 800 insertions, 37 deletions
diff --git a/src/qt/bitcoin.cpp b/src/qt/bitcoin.cpp
index 7c262e14cd..4a77bf9b70 100644
--- a/src/qt/bitcoin.cpp
+++ b/src/qt/bitcoin.cpp
@@ -187,30 +187,31 @@ int main(int argc, char *argv[])
// ... then GUI settings:
OptionsModel optionsModel;
- // Get desired locale ("en_US") from command line or system locale
+ // Get desired locale (e.g. "de_DE") from command line or use system locale
QString lang_territory = QString::fromStdString(GetArg("-lang", QLocale::system().name().toStdString()));
- // Load language files for configured locale:
- // - First load the translator for the base language, without territory
- // - Then load the more specific locale translator
QString lang = lang_territory;
+ // Convert to "de" only by truncating "_DE"
+ lang.truncate(lang_territory.lastIndexOf('_'));
- lang.truncate(lang_territory.lastIndexOf('_')); // "en"
QTranslator qtTranslatorBase, qtTranslator, translatorBase, translator;
+ // Load language files for configured locale:
+ // - First load the translator for the base language, without territory
+ // - Then load the more specific locale translator
- qtTranslatorBase.load(QLibraryInfo::location(QLibraryInfo::TranslationsPath) + "/qt_" + lang);
- if (!qtTranslatorBase.isEmpty())
+ // Load e.g. qt_de.qm
+ if (qtTranslatorBase.load("qt_" + lang, QLibraryInfo::location(QLibraryInfo::TranslationsPath)))
app.installTranslator(&qtTranslatorBase);
- qtTranslator.load(QLibraryInfo::location(QLibraryInfo::TranslationsPath) + "/qt_" + lang_territory);
- if (!qtTranslator.isEmpty())
+ // Load e.g. qt_de_DE.qm
+ if (qtTranslator.load("qt_" + lang_territory, QLibraryInfo::location(QLibraryInfo::TranslationsPath)))
app.installTranslator(&qtTranslator);
- translatorBase.load(":/translations/"+lang);
- if (!translatorBase.isEmpty())
+ // Load e.g. bitcoin_de.qm (shortcut "de" needs to be defined in bitcoin.qrc)
+ if (translatorBase.load(lang, ":/translations/"))
app.installTranslator(&translatorBase);
- translator.load(":/translations/"+lang_territory);
- if (!translator.isEmpty())
+ // Load e.g. bitcoin_de_DE.qm (shortcut "de_DE" needs to be defined in bitcoin.qrc)
+ if (translator.load(lang_territory, ":/translations/"))
app.installTranslator(&translator);
QSplashScreen splash(QPixmap(":/images/splash"), 0);
@@ -281,6 +282,7 @@ int main(int argc, char *argv[])
#endif
app.exec();
+ window.hide();
window.setClientModel(0);
window.setWalletModel(0);
guiref = 0;
diff --git a/src/qt/bitcoin.qrc b/src/qt/bitcoin.qrc
index e631a65155..e696170312 100644
--- a/src/qt/bitcoin.qrc
+++ b/src/qt/bitcoin.qrc
@@ -38,11 +38,11 @@
<file alias="lock_open">res/icons/lock_open.png</file>
<file alias="key">res/icons/key.png</file>
<file alias="filesave">res/icons/filesave.png</file>
+ <file alias="qrcode">res/icons/qrcode.png</file>
</qresource>
<qresource prefix="/images">
<file alias="about">res/images/about.png</file>
<file alias="splash">res/images/splash2.jpg</file>
- <file alias="qrcode">res/images/qrcode.png</file>
</qresource>
<qresource prefix="/movies">
<file alias="update_spinner">res/movies/update_spinner.mng</file>
diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp
index bcf90917ed..007f185d06 100644
--- a/src/qt/bitcoingui.cpp
+++ b/src/qt/bitcoingui.cpp
@@ -24,6 +24,7 @@
#include "askpassphrasedialog.h"
#include "notificator.h"
#include "guiutil.h"
+#include "rpcconsole.h"
#ifdef Q_WS_MAC
#include "macdockiconhandler.h"
@@ -64,7 +65,8 @@ BitcoinGUI::BitcoinGUI(QWidget *parent):
changePassphraseAction(0),
aboutQtAction(0),
trayIcon(0),
- notificator(0)
+ notificator(0),
+ rpcConsole(0)
{
resize(850, 550);
setWindowTitle(tr("Bitcoin Wallet"));
@@ -158,6 +160,9 @@ BitcoinGUI::BitcoinGUI(QWidget *parent):
// Doubleclicking on a transaction on the transaction history page shows details
connect(transactionView, SIGNAL(doubleClicked(QModelIndex)), transactionView, SLOT(showDetails()));
+ rpcConsole = new RPCConsole(this);
+ connect(openRPCConsoleAction, SIGNAL(triggered()), rpcConsole, SLOT(show()));
+
gotoOverviewPage();
}
@@ -248,6 +253,8 @@ void BitcoinGUI::createActions()
backupWalletAction->setToolTip(tr("Backup wallet to another location"));
changePassphraseAction = new QAction(QIcon(":/icons/key"), tr("&Change Passphrase"), this);
changePassphraseAction->setToolTip(tr("Change the passphrase used for wallet encryption"));
+ openRPCConsoleAction = new QAction(tr("&Debug window"), this);
+ openRPCConsoleAction->setToolTip(tr("Open debugging and diagnostic console"));
connect(quitAction, SIGNAL(triggered()), qApp, SLOT(quit()));
connect(optionsAction, SIGNAL(triggered()), this, SLOT(optionsClicked()));
@@ -286,6 +293,8 @@ void BitcoinGUI::createMenuBar()
settings->addAction(optionsAction);
QMenu *help = appMenuBar->addMenu(tr("&Help"));
+ help->addAction(openRPCConsoleAction);
+ help->addSeparator();
help->addAction(aboutAction);
help->addAction(aboutQtAction);
}
@@ -338,6 +347,8 @@ void BitcoinGUI::setClientModel(ClientModel *clientModel)
// Report errors from network/worker thread
connect(clientModel, SIGNAL(error(QString,QString, bool)), this, SLOT(error(QString,QString,bool)));
+
+ rpcConsole->setClientModel(clientModel);
}
}
diff --git a/src/qt/bitcoingui.h b/src/qt/bitcoingui.h
index 2cce8d3459..eb4f883496 100644
--- a/src/qt/bitcoingui.h
+++ b/src/qt/bitcoingui.h
@@ -13,6 +13,7 @@ class AddressBookPage;
class SendCoinsDialog;
class MessagePage;
class Notificator;
+class RPCConsole;
QT_BEGIN_NAMESPACE
class QLabel;
@@ -87,10 +88,12 @@ private:
QAction *backupWalletAction;
QAction *changePassphraseAction;
QAction *aboutQtAction;
+ QAction *openRPCConsoleAction;
QSystemTrayIcon *trayIcon;
Notificator *notificator;
TransactionView *transactionView;
+ RPCConsole *rpcConsole;
QMovie *syncIconMovie;
diff --git a/src/qt/clientmodel.cpp b/src/qt/clientmodel.cpp
index cb602ce327..d7172fd9cd 100644
--- a/src/qt/clientmodel.cpp
+++ b/src/qt/clientmodel.cpp
@@ -93,3 +93,8 @@ QString ClientModel::formatBuildDate() const
{
return QString::fromStdString(CLIENT_DATE);
}
+
+QString ClientModel::clientName() const
+{
+ return QString::fromStdString(CLIENT_NAME);
+}
diff --git a/src/qt/clientmodel.h b/src/qt/clientmodel.h
index 8e7431a2f3..74e0c0688f 100644
--- a/src/qt/clientmodel.h
+++ b/src/qt/clientmodel.h
@@ -38,6 +38,7 @@ public:
QString formatFullVersion() const;
QString formatBuildDate() const;
+ QString clientName() const;
private:
OptionsModel *optionsModel;
diff --git a/src/qt/forms/aboutdialog.ui b/src/qt/forms/aboutdialog.ui
index 6e342e5e8a..21fc7b2019 100644
--- a/src/qt/forms/aboutdialog.ui
+++ b/src/qt/forms/aboutdialog.ui
@@ -22,9 +22,6 @@
<verstretch>0</verstretch>
</sizepolicy>
</property>
- <property name="text">
- <string/>
- </property>
<property name="pixmap">
<pixmap resource="../bitcoin.qrc">:/images/about</pixmap>
</property>
@@ -49,6 +46,9 @@
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLabel" name="label">
+ <property name="cursor">
+ <cursorShape>IBeamCursor</cursorShape>
+ </property>
<property name="text">
<string>&lt;b&gt;Bitcoin&lt;/b&gt; version</string>
</property>
@@ -59,6 +59,9 @@
</item>
<item>
<widget class="QLabel" name="versionLabel">
+ <property name="cursor">
+ <cursorShape>IBeamCursor</cursorShape>
+ </property>
<property name="text">
<string notr="true">0.3.666-beta</string>
</property>
@@ -87,6 +90,9 @@
</item>
<item>
<widget class="QLabel" name="label_2">
+ <property name="cursor">
+ <cursorShape>IBeamCursor</cursorShape>
+ </property>
<property name="text">
<string>Copyright © 2009-2012 Bitcoin Developers
diff --git a/src/qt/forms/addressbookpage.ui b/src/qt/forms/addressbookpage.ui
index b31a9ce997..3ccebd40d9 100644
--- a/src/qt/forms/addressbookpage.ui
+++ b/src/qt/forms/addressbookpage.ui
@@ -86,7 +86,7 @@
</property>
<property name="icon">
<iconset resource="../bitcoin.qrc">
- <normaloff>:/images/qrcode</normaloff>:/images/qrcode</iconset>
+ <normaloff>:/icons/qrcode</normaloff>:/icons/qrcode</iconset>
</property>
</widget>
</item>
diff --git a/src/qt/forms/messagepage.ui b/src/qt/forms/messagepage.ui
index ae1e062fca..512e47ad6d 100644
--- a/src/qt/forms/messagepage.ui
+++ b/src/qt/forms/messagepage.ui
@@ -101,9 +101,6 @@
<italic>true</italic>
</font>
</property>
- <property name="text">
- <string>Click &quot;Sign Message&quot; to get signature</string>
- </property>
<property name="readOnly">
<bool>true</bool>
</property>
@@ -131,7 +128,7 @@
<string>Copy the current signature to the system clipboard</string>
</property>
<property name="text">
- <string>&amp;Copy to Clipboard</string>
+ <string>&amp;Copy Signature</string>
</property>
<property name="icon">
<iconset resource="../bitcoin.qrc">
@@ -140,6 +137,20 @@
</widget>
</item>
<item>
+ <widget class="QPushButton" name="clearButton">
+ <property name="toolTip">
+ <string>Reset all sign message fields</string>
+ </property>
+ <property name="text">
+ <string>Clear &amp;All</string>
+ </property>
+ <property name="icon">
+ <iconset resource="../bitcoin.qrc">
+ <normaloff>:/icons/remove</normaloff>:/icons/remove</iconset>
+ </property>
+ </widget>
+ </item>
+ <item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
diff --git a/src/qt/forms/overviewpage.ui b/src/qt/forms/overviewpage.ui
index cc67fae533..3cf7dd0ed3 100644
--- a/src/qt/forms/overviewpage.ui
+++ b/src/qt/forms/overviewpage.ui
@@ -78,12 +78,14 @@
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_5">
+ <property name="font">
+ <font>
+ <pointsize>11</pointsize>
+ <bold>true</bold>
+ </font>
+ </property>
<property name="text">
- <string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
-&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
-p, li { white-space: pre-wrap; }
-&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'Ubuntu'; font-size:11pt; font-weight:400; font-style:normal;&quot;&gt;
-&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;Wallet&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
+ <string>Wallet</string>
</property>
</widget>
</item>
diff --git a/src/qt/forms/qrcodedialog.ui b/src/qt/forms/qrcodedialog.ui
index 714b1d6cd8..ef21841c26 100644
--- a/src/qt/forms/qrcodedialog.ui
+++ b/src/qt/forms/qrcodedialog.ui
@@ -6,12 +6,12 @@
<rect>
<x>0</x>
<y>0</y>
- <width>320</width>
- <height>404</height>
+ <width>334</width>
+ <height>423</height>
</rect>
</property>
<property name="windowTitle">
- <string>Dialog</string>
+ <string>QR-Code Dialog</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_3">
<item>
diff --git a/src/qt/forms/rpcconsole.ui b/src/qt/forms/rpcconsole.ui
new file mode 100644
index 0000000000..bde607c527
--- /dev/null
+++ b/src/qt/forms/rpcconsole.ui
@@ -0,0 +1,323 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>RPCConsole</class>
+ <widget class="QDialog" name="RPCConsole">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>706</width>
+ <height>382</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Bitcoin debug window</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout_2">
+ <item>
+ <widget class="QTabWidget" name="tabWidget">
+ <property name="currentIndex">
+ <number>0</number>
+ </property>
+ <widget class="QWidget" name="tab">
+ <attribute name="title">
+ <string>Information</string>
+ </attribute>
+ <layout class="QGridLayout" name="gridLayout" columnstretch="0,1">
+ <property name="horizontalSpacing">
+ <number>12</number>
+ </property>
+ <item row="1" column="0">
+ <widget class="QLabel" name="label_5">
+ <property name="text">
+ <string>Client name</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="QLabel" name="clientName">
+ <property name="text">
+ <string>N/A</string>
+ </property>
+ <property name="textFormat">
+ <enum>Qt::PlainText</enum>
+ </property>
+ <property name="textInteractionFlags">
+ <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="0">
+ <widget class="QLabel" name="label_6">
+ <property name="text">
+ <string>Client version</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="1">
+ <widget class="QLabel" name="clientVersion">
+ <property name="text">
+ <string>N/A</string>
+ </property>
+ <property name="textFormat">
+ <enum>Qt::PlainText</enum>
+ </property>
+ <property name="textInteractionFlags">
+ <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="0">
+ <widget class="QLabel" name="label_9">
+ <property name="font">
+ <font>
+ <weight>75</weight>
+ <bold>true</bold>
+ </font>
+ </property>
+ <property name="text">
+ <string>Version</string>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="0">
+ <widget class="QLabel" name="label_11">
+ <property name="font">
+ <font>
+ <weight>75</weight>
+ <bold>true</bold>
+ </font>
+ </property>
+ <property name="text">
+ <string>Network</string>
+ </property>
+ </widget>
+ </item>
+ <item row="5" column="0">
+ <widget class="QLabel" name="label_7">
+ <property name="text">
+ <string>Number of connections</string>
+ </property>
+ </widget>
+ </item>
+ <item row="5" column="1">
+ <widget class="QLabel" name="numberOfConnections">
+ <property name="text">
+ <string>N/A</string>
+ </property>
+ <property name="textFormat">
+ <enum>Qt::PlainText</enum>
+ </property>
+ <property name="textInteractionFlags">
+ <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
+ </property>
+ </widget>
+ </item>
+ <item row="6" column="0">
+ <widget class="QLabel" name="label_8">
+ <property name="text">
+ <string>On testnet</string>
+ </property>
+ </widget>
+ </item>
+ <item row="6" column="1">
+ <widget class="QCheckBox" name="isTestNet">
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ </widget>
+ </item>
+ <item row="7" column="0">
+ <widget class="QLabel" name="label_10">
+ <property name="font">
+ <font>
+ <weight>75</weight>
+ <bold>true</bold>
+ </font>
+ </property>
+ <property name="text">
+ <string>Block chain</string>
+ </property>
+ </widget>
+ </item>
+ <item row="8" column="0">
+ <widget class="QLabel" name="label_3">
+ <property name="text">
+ <string>Current number of blocks</string>
+ </property>
+ </widget>
+ </item>
+ <item row="8" column="1">
+ <widget class="QLabel" name="numberOfBlocks">
+ <property name="text">
+ <string>N/A</string>
+ </property>
+ <property name="textFormat">
+ <enum>Qt::PlainText</enum>
+ </property>
+ <property name="textInteractionFlags">
+ <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
+ </property>
+ </widget>
+ </item>
+ <item row="9" column="0">
+ <widget class="QLabel" name="label_4">
+ <property name="text">
+ <string>Estimated total blocks</string>
+ </property>
+ </widget>
+ </item>
+ <item row="9" column="1">
+ <widget class="QLabel" name="totalBlocks">
+ <property name="text">
+ <string>N/A</string>
+ </property>
+ <property name="textFormat">
+ <enum>Qt::PlainText</enum>
+ </property>
+ <property name="textInteractionFlags">
+ <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
+ </property>
+ </widget>
+ </item>
+ <item row="10" column="0">
+ <widget class="QLabel" name="label_2">
+ <property name="text">
+ <string>Last block time</string>
+ </property>
+ </widget>
+ </item>
+ <item row="10" column="1">
+ <widget class="QLabel" name="lastBlockTime">
+ <property name="text">
+ <string>N/A</string>
+ </property>
+ <property name="textFormat">
+ <enum>Qt::PlainText</enum>
+ </property>
+ <property name="textInteractionFlags">
+ <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
+ </property>
+ </widget>
+ </item>
+ <item row="11" column="0">
+ <spacer name="verticalSpacer">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item row="3" column="0">
+ <widget class="QLabel" name="label_12">
+ <property name="text">
+ <string>Build date</string>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="1">
+ <widget class="QLabel" name="buildDate">
+ <property name="text">
+ <string>N/A</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QWidget" name="tab_2">
+ <attribute name="title">
+ <string>Console</string>
+ </attribute>
+ <layout class="QVBoxLayout" name="verticalLayout_3">
+ <property name="spacing">
+ <number>3</number>
+ </property>
+ <item>
+ <widget class="QTableWidget" name="messagesWidget">
+ <property name="minimumSize">
+ <size>
+ <width>0</width>
+ <height>100</height>
+ </size>
+ </property>
+ <property name="tabKeyNavigation">
+ <bool>false</bool>
+ </property>
+ <property name="selectionBehavior">
+ <enum>QAbstractItemView::SelectRows</enum>
+ </property>
+ <property name="columnCount">
+ <number>2</number>
+ </property>
+ <attribute name="horizontalHeaderVisible">
+ <bool>false</bool>
+ </attribute>
+ <attribute name="verticalHeaderVisible">
+ <bool>false</bool>
+ </attribute>
+ <column/>
+ <column/>
+ </widget>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <property name="spacing">
+ <number>3</number>
+ </property>
+ <item>
+ <widget class="QLabel" name="label">
+ <property name="text">
+ <string>&gt;</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLineEdit" name="lineEdit"/>
+ </item>
+ <item>
+ <widget class="QPushButton" name="clearButton">
+ <property name="maximumSize">
+ <size>
+ <width>24</width>
+ <height>24</height>
+ </size>
+ </property>
+ <property name="toolTip">
+ <string>Clear console</string>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="icon">
+ <iconset resource="../bitcoin.qrc">
+ <normaloff>:/icons/remove</normaloff>:/icons/remove</iconset>
+ </property>
+ <property name="shortcut">
+ <string notr="true">Ctrl+L</string>
+ </property>
+ <property name="autoDefault">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <resources>
+ <include location="../bitcoin.qrc"/>
+ </resources>
+ <connections/>
+</ui>
diff --git a/src/qt/messagepage.cpp b/src/qt/messagepage.cpp
index 18bb64fe6c..57ad8292dc 100644
--- a/src/qt/messagepage.cpp
+++ b/src/qt/messagepage.cpp
@@ -24,6 +24,11 @@ MessagePage::MessagePage(QWidget *parent) :
ui(new Ui::MessagePage)
{
ui->setupUi(this);
+
+#if (QT_VERSION >= 0x040700)
+ /* Do not move this to the XML file, Qt before 4.7 will choke on it */
+ ui->signature->setPlaceholderText(tr("Click \"Sign Message\" to get signature"));
+#endif
GUIUtil::setupAddressWidget(ui->signFrom, this);
}
@@ -105,3 +110,10 @@ void MessagePage::on_signMessage_clicked()
ui->signature->setText(QString::fromStdString(EncodeBase64(&vchSig[0], vchSig.size())));
ui->signature->setFont(GUIUtil::bitcoinAddressFont());
}
+
+void MessagePage::on_clearButton_clicked()
+{
+ ui->signFrom->clear();
+ ui->message->clear();
+ ui->signature->clear();
+}
diff --git a/src/qt/messagepage.h b/src/qt/messagepage.h
index 55e6228124..b5a38166da 100644
--- a/src/qt/messagepage.h
+++ b/src/qt/messagepage.h
@@ -33,6 +33,7 @@ private slots:
void on_signMessage_clicked();
void on_copyToClipboard_clicked();
+ void on_clearButton_clicked();
};
#endif // MESSAGEPAGE_H
diff --git a/src/qt/optionsdialog.cpp b/src/qt/optionsdialog.cpp
index 59c44ac5f9..416880d462 100644
--- a/src/qt/optionsdialog.cpp
+++ b/src/qt/optionsdialog.cpp
@@ -222,7 +222,6 @@ MainOptionsPage::MainOptionsPage(QWidget *parent):
QLabel *fee_label = new QLabel(tr("Pay transaction &fee"));
fee_hbox->addWidget(fee_label);
fee_edit = new BitcoinAmountField();
- fee_edit->setToolTip(tr("Optional transaction fee per kB that helps make sure your transactions are processed quickly. Most transactions are 1 kB. Fee 0.01 recommended."));
fee_label->setBuddy(fee_edit);
fee_hbox->addWidget(fee_edit);
diff --git a/src/qt/res/icons/qrcode.png b/src/qt/res/icons/qrcode.png
new file mode 100644
index 0000000000..a8d97174b3
--- /dev/null
+++ b/src/qt/res/icons/qrcode.png
Binary files differ
diff --git a/src/qt/res/images/qrcode.png b/src/qt/res/images/qrcode.png
deleted file mode 100644
index c89a49bbce..0000000000
--- a/src/qt/res/images/qrcode.png
+++ /dev/null
Binary files differ
diff --git a/src/qt/rpcconsole.cpp b/src/qt/rpcconsole.cpp
new file mode 100644
index 0000000000..d59f5c6a38
--- /dev/null
+++ b/src/qt/rpcconsole.cpp
@@ -0,0 +1,316 @@
+#include "rpcconsole.h"
+#include "ui_rpcconsole.h"
+
+#include "clientmodel.h"
+#include "bitcoinrpc.h"
+#include "guiutil.h"
+
+#include <QTime>
+#include <QTimer>
+#include <QThread>
+#include <QTextEdit>
+#include <QKeyEvent>
+
+#include <boost/tokenizer.hpp>
+
+// TODO: make it possible to filter out categories (esp debug messages when implemented)
+// TODO: receive errors and debug messages through ClientModel
+
+const int CONSOLE_SCROLLBACK = 50;
+const int CONSOLE_HISTORY = 50;
+
+/* Object for executing console RPC commands in a separate thread.
+*/
+class RPCExecutor: public QObject
+{
+ Q_OBJECT
+public slots:
+ void start();
+ void request(const QString &command);
+signals:
+ void reply(int category, const QString &command);
+};
+
+#include "rpcconsole.moc"
+
+void RPCExecutor::start()
+{
+ // Nothing to do
+}
+
+void RPCExecutor::request(const QString &command)
+{
+ // Parse shell-like command line into separate arguments
+ boost::escaped_list_separator<char> els('\\',' ','\"');
+ std::string strCommand = command.toStdString();
+ boost::tokenizer<boost::escaped_list_separator<char> > tok(strCommand, els);
+
+ std::string strMethod;
+ std::vector<std::string> strParams;
+ int n = 0;
+ for(boost::tokenizer<boost::escaped_list_separator<char> >::iterator beg=tok.begin(); beg!=tok.end();++beg,++n)
+ {
+ if(n == 0) // First parameter is the command
+ strMethod = *beg;
+ else
+ strParams.push_back(*beg);
+ }
+
+ try {
+ std::string strPrint;
+ json_spirit::Value result = tableRPC.execute(strMethod, RPCConvertValues(strMethod, strParams));
+
+ // Format result reply
+ if (result.type() == json_spirit::null_type)
+ strPrint = "";
+ else if (result.type() == json_spirit::str_type)
+ strPrint = result.get_str();
+ else
+ strPrint = write_string(result, true);
+
+ emit reply(RPCConsole::CMD_REPLY, QString::fromStdString(strPrint));
+ }
+ catch (json_spirit::Object& objError)
+ {
+ emit reply(RPCConsole::CMD_ERROR, QString::fromStdString(write_string(json_spirit::Value(objError), false)));
+ }
+ catch (std::exception& e)
+ {
+ emit reply(RPCConsole::CMD_ERROR, QString("Error: ") + QString::fromStdString(e.what()));
+ }
+}
+
+RPCConsole::RPCConsole(QWidget *parent) :
+ QDialog(parent),
+ ui(new Ui::RPCConsole),
+ firstLayout(true),
+ historyPtr(0)
+{
+ ui->setupUi(this);
+ ui->messagesWidget->horizontalHeader()->setResizeMode(1, QHeaderView::Stretch);
+ ui->messagesWidget->setContextMenuPolicy(Qt::ActionsContextMenu);
+
+ // Install event filter for up and down arrow
+ ui->lineEdit->installEventFilter(this);
+
+ // Add "Copy message" to context menu explicitly
+ QAction *copyMessageAction = new QAction(tr("&Copy"), this);
+ copyMessageAction->setShortcut(QKeySequence(Qt::CTRL | Qt::Key_C));
+ copyMessageAction->setShortcutContext(Qt::WidgetShortcut);
+ connect(copyMessageAction, SIGNAL(triggered()), this, SLOT(copyMessage()));
+ ui->messagesWidget->addAction(copyMessageAction);
+
+ connect(ui->clearButton, SIGNAL(clicked()), this, SLOT(clear()));
+
+ startExecutor();
+
+ clear();
+}
+
+RPCConsole::~RPCConsole()
+{
+ emit stopExecutor();
+ delete ui;
+}
+
+bool RPCConsole::event(QEvent *event)
+{
+ int returnValue = QWidget::event(event);
+
+ if (event->type() == QEvent::LayoutRequest && firstLayout)
+ {
+ // Work around QTableWidget issue:
+ // Call resizeRowsToContents on first Layout request with widget visible,
+ // to make sure multiline messages that were added before the console was shown
+ // have the right height.
+ if(ui->messagesWidget->isVisible())
+ {
+ firstLayout = false;
+ ui->messagesWidget->resizeRowsToContents();
+ }
+ return true;
+ }
+
+ return returnValue;
+}
+
+bool RPCConsole::eventFilter(QObject* obj, QEvent *event)
+{
+ if(obj == ui->lineEdit)
+ {
+ if(event->type() == QEvent::KeyPress)
+ {
+ QKeyEvent *key = static_cast<QKeyEvent*>(event);
+ switch(key->key())
+ {
+ case Qt::Key_Up: browseHistory(-1); return true;
+ case Qt::Key_Down: browseHistory(1); return true;
+ }
+ }
+ }
+ return QDialog::eventFilter(obj, event);
+}
+
+void RPCConsole::setClientModel(ClientModel *model)
+{
+ this->clientModel = model;
+ if(model)
+ {
+ // Subscribe to information, replies, messages, errors
+ connect(model, SIGNAL(numConnectionsChanged(int)), this, SLOT(setNumConnections(int)));
+ connect(model, SIGNAL(numBlocksChanged(int)), this, SLOT(setNumBlocks(int)));
+
+ // Provide initial values
+ ui->clientVersion->setText(model->formatFullVersion());
+ ui->clientName->setText(model->clientName());
+ ui->buildDate->setText(model->formatBuildDate());
+
+ setNumConnections(model->getNumConnections());
+ ui->isTestNet->setChecked(model->isTestNet());
+
+ setNumBlocks(model->getNumBlocks());
+ }
+}
+
+static QColor categoryColor(int category)
+{
+ switch(category)
+ {
+ case RPCConsole::MC_ERROR: return QColor(255,0,0); break;
+ case RPCConsole::MC_DEBUG: return QColor(192,192,192); break;
+ case RPCConsole::CMD_REQUEST: return QColor(128,128,128); break;
+ case RPCConsole::CMD_REPLY: return QColor(128,255,128); break;
+ case RPCConsole::CMD_ERROR: return QColor(255,128,128); break;
+ default: return QColor(0,0,0);
+ }
+}
+
+void RPCConsole::clear()
+{
+ ui->messagesWidget->clear();
+ ui->messagesWidget->setRowCount(0);
+ ui->lineEdit->clear();
+ ui->lineEdit->setFocus();
+
+ message(CMD_REPLY, tr("Welcome to the bitcoin RPC console.")+"\n"+
+ tr("Use up and down arrows to navigate history, and Ctrl-L to clear screen.")+"\n"+
+ tr("Type \"help\" for an overview of available commands."));
+}
+
+void RPCConsole::message(int category, const QString &message)
+{
+ // Add row to messages widget
+ int row = ui->messagesWidget->rowCount();
+ ui->messagesWidget->setRowCount(row+1);
+
+ QTime time = QTime::currentTime();
+ QTableWidgetItem *newTime = new QTableWidgetItem(time.toString());
+ newTime->setData(Qt::DecorationRole, categoryColor(category));
+ newTime->setForeground(QColor(128,128,128));
+ newTime->setFlags(Qt::ItemIsSelectable|Qt::ItemIsEnabled); // make non-editable
+
+ int numLines = message.count("\n") + 1;
+ // As Qt doesn't like very tall cells (they break scrolling) keep only short messages in
+ // the cell text, longer messages trigger a display widget with scroll bar
+ if(numLines < 5)
+ {
+ QTableWidgetItem *newItem = new QTableWidgetItem(message);
+ newItem->setFlags(Qt::ItemIsSelectable|Qt::ItemIsEnabled); // make non-editable
+ if(category == CMD_ERROR) // Coloring error messages in red
+ newItem->setForeground(QColor(255,16,16));
+ ui->messagesWidget->setItem(row, 1, newItem);
+ } else {
+ QTextEdit *newWidget = new QTextEdit;
+ newWidget->setText(message);
+ newWidget->setMaximumHeight(100);
+ newWidget->setReadOnly(true);
+ ui->messagesWidget->setCellWidget(row, 1, newWidget);
+ }
+
+ ui->messagesWidget->setItem(row, 0, newTime);
+ ui->messagesWidget->resizeRowToContents(row);
+ // Preserve only limited scrollback buffer
+ while(ui->messagesWidget->rowCount() > CONSOLE_SCROLLBACK)
+ ui->messagesWidget->removeRow(0);
+ // Scroll to bottom after table is updated
+ QTimer::singleShot(0, ui->messagesWidget, SLOT(scrollToBottom()));
+}
+
+void RPCConsole::setNumConnections(int count)
+{
+ ui->numberOfConnections->setText(QString::number(count));
+}
+
+void RPCConsole::setNumBlocks(int count)
+{
+ ui->numberOfBlocks->setText(QString::number(count));
+ if(clientModel)
+ {
+ ui->totalBlocks->setText(QString::number(clientModel->getNumBlocksOfPeers()));
+ ui->lastBlockTime->setText(clientModel->getLastBlockDate().toString());
+ }
+}
+
+void RPCConsole::on_lineEdit_returnPressed()
+{
+ QString cmd = ui->lineEdit->text();
+ ui->lineEdit->clear();
+
+ if(!cmd.isEmpty())
+ {
+ message(CMD_REQUEST, cmd);
+ emit cmdRequest(cmd);
+ // Truncate history from current position
+ history.erase(history.begin() + historyPtr, history.end());
+ // Append command to history
+ history.append(cmd);
+ // Enforce maximum history size
+ while(history.size() > CONSOLE_HISTORY)
+ history.removeFirst();
+ // Set pointer to end of history
+ historyPtr = history.size();
+ }
+}
+
+void RPCConsole::browseHistory(int offset)
+{
+ historyPtr += offset;
+ if(historyPtr < 0)
+ historyPtr = 0;
+ if(historyPtr > history.size())
+ historyPtr = history.size();
+ QString cmd;
+ if(historyPtr < history.size())
+ cmd = history.at(historyPtr);
+ ui->lineEdit->setText(cmd);
+}
+
+void RPCConsole::startExecutor()
+{
+ QThread* thread = new QThread;
+ RPCExecutor *executor = new RPCExecutor();
+ executor->moveToThread(thread);
+
+ // Notify executor when thread started (in executor thread)
+ connect(thread, SIGNAL(started()), executor, SLOT(start()));
+ // Replies from executor object must go to this object
+ connect(executor, SIGNAL(reply(int,QString)), this, SLOT(message(int,QString)));
+ // Requests from this object must go to executor
+ connect(this, SIGNAL(cmdRequest(QString)), executor, SLOT(request(QString)));
+ // On stopExecutor signal
+ // - queue executor for deletion (in execution thread)
+ // - quit the Qt event loop in the execution thread
+ connect(this, SIGNAL(stopExecutor()), executor, SLOT(deleteLater()));
+ connect(this, SIGNAL(stopExecutor()), thread, SLOT(quit()));
+ // Queue the thread for deletion (in this thread) when it is finished
+ connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));
+
+ // Default implementation of QThread::run() simply spins up an event loop in the thread,
+ // which is what we want.
+ thread->start();
+}
+
+void RPCConsole::copyMessage()
+{
+ GUIUtil::copyEntryData(ui->messagesWidget, 1, Qt::EditRole);
+}
diff --git a/src/qt/rpcconsole.h b/src/qt/rpcconsole.h
new file mode 100644
index 0000000000..a0a73bedd3
--- /dev/null
+++ b/src/qt/rpcconsole.h
@@ -0,0 +1,64 @@
+#ifndef RPCCONSOLE_H
+#define RPCCONSOLE_H
+
+#include <QDialog>
+
+namespace Ui {
+ class RPCConsole;
+}
+class ClientModel;
+
+/** Local bitcoin RPC console. */
+class RPCConsole: public QDialog
+{
+ Q_OBJECT
+
+public:
+ explicit RPCConsole(QWidget *parent = 0);
+ ~RPCConsole();
+
+ void setClientModel(ClientModel *model);
+
+ enum MessageClass {
+ MC_ERROR,
+ MC_DEBUG,
+ CMD_REQUEST,
+ CMD_REPLY,
+ CMD_ERROR
+ };
+
+protected:
+ virtual bool event(QEvent *event);
+ virtual bool eventFilter(QObject* obj, QEvent *event);
+
+private slots:
+ void on_lineEdit_returnPressed();
+
+public slots:
+ void clear();
+ void message(int category, const QString &message);
+ /** Set number of connections shown in the UI */
+ void setNumConnections(int count);
+ /** Set number of blocks shown in the UI */
+ void setNumBlocks(int count);
+ /** Go forward or back in history */
+ void browseHistory(int offset);
+ /** Copy currently selected message to clipboard */
+ void copyMessage();
+
+signals:
+ // For RPC command executor
+ void stopExecutor();
+ void cmdRequest(const QString &command);
+
+private:
+ Ui::RPCConsole *ui;
+ ClientModel *clientModel;
+ bool firstLayout;
+ QStringList history;
+ int historyPtr;
+
+ void startExecutor();
+};
+
+#endif // RPCCONSOLE_H
diff --git a/src/qt/sendcoinsentry.cpp b/src/qt/sendcoinsentry.cpp
index c8242d8352..5960597c77 100644
--- a/src/qt/sendcoinsentry.cpp
+++ b/src/qt/sendcoinsentry.cpp
@@ -20,10 +20,10 @@ SendCoinsEntry::SendCoinsEntry(QWidget *parent) :
#ifdef Q_WS_MAC
ui->payToLayout->setSpacing(4);
#endif
-
#if QT_VERSION >= 0x040700
- ui->payTo->setPlaceholderText(tr("Enter a Bitcoin address (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L)"));
+ /* Do not move this to the XML file, Qt before 4.7 will choke on it */
ui->addAsLabel->setPlaceholderText(tr("Enter a label for this address to add it to your address book"));
+ ui->payTo->setPlaceholderText(tr("Enter a Bitcoin address (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L)"));
#endif
setFocusPolicy(Qt::TabFocus);
setFocusProxy(ui->payTo);
diff --git a/src/qt/walletmodel.cpp b/src/qt/walletmodel.cpp
index a915274da3..b9ccb06c09 100644
--- a/src/qt/walletmodel.cpp
+++ b/src/qt/walletmodel.cpp
@@ -150,14 +150,21 @@ WalletModel::SendCoinsReturn WalletModel::sendCoins(const QList<SendCoinsRecipie
hex = QString::fromStdString(wtx.GetHash().GetHex());
}
- // Add addresses that we've sent to to the address book
+ // Add addresses / update labels that we've sent to to the address book
foreach(const SendCoinsRecipient &rcp, recipients)
{
std::string strAddress = rcp.address.toStdString();
+ std::string strLabel = rcp.label.toStdString();
{
LOCK(wallet->cs_wallet);
- if (!wallet->mapAddressBook.count(strAddress))
- wallet->SetAddressBookName(strAddress, rcp.label.toStdString());
+
+ std::map<CBitcoinAddress, std::string>::iterator mi = wallet->mapAddressBook.find(strAddress);
+
+ // Check if we have a new address or an updated label
+ if (mi == wallet->mapAddressBook.end() || mi->second != strLabel)
+ {
+ wallet->SetAddressBookName(strAddress, strLabel);
+ }
}
}