20 #include <openssl/crypto.h> 33 #include <QSignalMapper> 37 #include <QStringList> 39 #if QT_VERSION < 0x050000 55 const QString
RESCAN(
"-rescan");
56 const QString
ZAPTXES1(
"-zapwallettxes=1");
57 const QString
ZAPTXES2(
"-zapwallettxes=2");
59 const QString
REINDEX(
"-reindex");
65 {
"cmd-request",
"tx_input"},
66 {
"cmd-reply",
"tx_output"},
67 {
"cmd-error",
"tx_output"},
79 void request(
const QString &command);
82 void reply(
int category,
const QString &command);
95 timer.setSingleShot(
true);
104 boost::function<void(void)>
func;
111 const char *
Name() {
return "Qt"; }
119 #include "rpcconsole.moc" 144 STATE_ESCAPE_DOUBLEQUOTED
145 } state = STATE_EATING_SPACES;
147 Q_FOREACH(
char ch, strCommand)
152 case STATE_EATING_SPACES:
155 case '"': state = STATE_DOUBLEQUOTED;
break;
156 case '\'': state = STATE_SINGLEQUOTED;
break;
157 case '\\': state = STATE_ESCAPE_OUTER;
break;
158 case ' ':
case '\n':
case '\t':
159 if(state == STATE_ARGUMENT)
161 args.push_back(curarg);
164 state = STATE_EATING_SPACES;
166 default: curarg += ch; state = STATE_ARGUMENT;
169 case STATE_SINGLEQUOTED:
172 case '\'': state = STATE_ARGUMENT;
break;
173 default: curarg += ch;
176 case STATE_DOUBLEQUOTED:
179 case '"': state = STATE_ARGUMENT;
break;
180 case '\\': state = STATE_ESCAPE_DOUBLEQUOTED;
break;
181 default: curarg += ch;
184 case STATE_ESCAPE_OUTER:
185 curarg += ch; state = STATE_ARGUMENT;
187 case STATE_ESCAPE_DOUBLEQUOTED:
188 if(ch !=
'"' && ch !=
'\\') curarg +=
'\\';
189 curarg += ch; state = STATE_DOUBLEQUOTED;
195 case STATE_EATING_SPACES:
198 args.push_back(curarg);
207 std::vector<std::string> args;
217 std::string strPrint;
222 RPCConvertValues(args[0], std::vector<std::string>(args.begin() + 1, args.end())));
228 strPrint =
result.get_str();
230 strPrint =
result.write(2);
242 catch (
const std::runtime_error&)
247 catch (
const std::exception& e)
258 platformStyle(platformStyle),
259 peersTableContextMenu(0),
260 banTableContextMenu(0),
270 ui->
clearButton->setIcon(QIcon(
":/icons/" + theme +
"/remove"));
296 std::string walletPath =
GetDataDir().string();
297 walletPath += QDir::separator().toLatin1() +
GetArg(
"-wallet",
"wallet.dat");
298 ui->
wallet_path->setText(QString::fromStdString(walletPath));
309 ui->
peerHeading->setText(tr(
"Select a peer to view detailed information."));
326 if(event->type() == QEvent::KeyPress)
328 QKeyEvent *keyevt =
static_cast<QKeyEvent*
>(event);
329 int key = keyevt->key();
330 Qt::KeyboardModifiers mod = keyevt->modifiers();
336 case Qt::Key_PageDown:
347 QApplication::postEvent(
ui->
lineEdit,
new QKeyEvent(*keyevt));
355 (!mod && !keyevt->text().isEmpty() &&
key != Qt::Key_Tab) ||
356 ((mod & Qt::ControlModifier) &&
key == Qt::Key_V) ||
357 ((mod & Qt::ShiftModifier) &&
key == Qt::Key_Insert)))
360 QApplication::postEvent(
ui->
lineEdit,
new QKeyEvent(*keyevt));
365 return QWidget::eventFilter(obj, event);
375 connect(model, SIGNAL(numConnectionsChanged(
int)),
this, SLOT(
setNumConnections(
int)));
378 connect(model, SIGNAL(numBlocksChanged(
int,QDateTime,
double,
bool)),
this, SLOT(
setNumBlocks(
int,QDateTime,
double,
bool)));
381 connect(model, SIGNAL(networkActiveChanged(
bool)),
this, SLOT(
setNetworkActive(
bool)));
384 connect(model, SIGNAL(strMasternodesChanged(QString)),
this, SLOT(
setMasternodeCount(QString)));
387 connect(model, SIGNAL(bytesChanged(quint64,quint64)),
this, SLOT(
updateTrafficStats(quint64, quint64)));
389 connect(model, SIGNAL(mempoolSizeChanged(
long,
size_t)),
this, SLOT(
setMempoolSize(
long,
size_t)));
394 ui->
peerWidget->setEditTriggers(QAbstractItemView::NoEditTriggers);
395 ui->
peerWidget->setSelectionBehavior(QAbstractItemView::SelectRows);
396 ui->
peerWidget->setSelectionMode(QAbstractItemView::ExtendedSelection);
397 ui->
peerWidget->setContextMenuPolicy(Qt::CustomContextMenu);
401 ui->
peerWidget->horizontalHeader()->setStretchLastSection(
true);
404 QAction* disconnectAction =
new QAction(tr(
"&Disconnect"),
this);
405 QAction* banAction1h =
new QAction(tr(
"Ban for") +
" " + tr(
"1 &hour"),
this);
406 QAction* banAction24h =
new QAction(tr(
"Ban for") +
" " + tr(
"1 &day"),
this);
407 QAction* banAction7d =
new QAction(tr(
"Ban for") +
" " + tr(
"1 &week"),
this);
408 QAction* banAction365d =
new QAction(tr(
"Ban for") +
" " + tr(
"1 &year"),
this);
421 QSignalMapper* signalMapper =
new QSignalMapper(
this);
422 signalMapper->setMapping(banAction1h, 60*60);
423 signalMapper->setMapping(banAction24h, 60*60*24);
424 signalMapper->setMapping(banAction7d, 60*60*24*7);
425 signalMapper->setMapping(banAction365d, 60*60*24*365);
426 connect(banAction1h, SIGNAL(triggered()), signalMapper, SLOT(map()));
427 connect(banAction24h, SIGNAL(triggered()), signalMapper, SLOT(map()));
428 connect(banAction7d, SIGNAL(triggered()), signalMapper, SLOT(map()));
429 connect(banAction365d, SIGNAL(triggered()), signalMapper, SLOT(map()));
430 connect(signalMapper, SIGNAL(mapped(
int)),
this, SLOT(
banSelectedNode(
int)));
437 connect(
ui->
peerWidget->selectionModel(), SIGNAL(selectionChanged(
const QItemSelection &,
const QItemSelection &)),
438 this, SLOT(
peerSelected(
const QItemSelection &,
const QItemSelection &)));
448 ui->
banlistWidget->setSelectionBehavior(QAbstractItemView::SelectRows);
449 ui->
banlistWidget->setSelectionMode(QAbstractItemView::SingleSelection);
456 QAction* unbanAction =
new QAction(tr(
"&Unban"),
this);
481 QStringList wordList;
483 for (
size_t i = 0; i < commandList.size(); ++i)
485 wordList << commandList[i].c_str();
509 default:
return "misc";
535 str.replace(QString(
"font-size:%1pt").arg(
consoleFontSize), QString(
"font-size:%1pt").arg(newSize));
588 QStringList args = QApplication::arguments();
620 QString iconName =
"";
626 QTextDocument::ImageResource,
636 "td.time { color: #808080; font-size: %2; padding-top: 3px; } " 637 "td.message { font-family: %1; font-size: %2; white-space:pre-wrap; } " 638 "td.cmd-request { color: #006060; } " 639 "td.cmd-error { color: red; } " 640 "b { color: #006060; } " 645 tr(
"Use up and down arrows to navigate history, and <b>Ctrl-L</b> to clear screen.") +
"<br>" +
646 tr(
"Type <b>help</b> for an overview of available commands.")),
true);
651 if(windowType() != Qt::Widget && event->key() == Qt::Key_Escape)
659 QTime time = QTime::currentTime();
660 QString timeString = time.toString();
662 out +=
"<table><tr><td class=\"time\" width=\"65\">" + timeString +
"</td>";
663 out +=
"<td class=\"icon\" width=\"32\"><img src=\"" +
categoryClass(category) +
"\"></td>";
664 out +=
"<td class=\"message " +
categoryClass(category) +
"\" valign=\"middle\">";
669 out +=
"</td></tr></table>";
680 connections +=
" (" + tr(
"Network activity disabled") +
")";
716 if (dynUsage < 1000000)
717 ui->
mempoolSize->setText(QString::number(dynUsage/1000.0,
'f', 2) +
" KB");
719 ui->
mempoolSize->setText(QString::number(dynUsage/1000000.0,
'f', 2) +
" MB");
761 executor->moveToThread(&
thread);
764 connect(executor, SIGNAL(reply(
int,QString)),
this, SLOT(
message(
int,QString)));
766 connect(
this, SIGNAL(
cmdRequest(QString)), executor, SLOT(request(QString)));
772 connect(&
thread, SIGNAL(finished()), executor, SLOT(deleteLater()), Qt::DirectConnection);
795 scrollbar->setValue(scrollbar->maximum());
806 return QString(tr(
"%1 B")).arg(bytes);
807 if(bytes < 1024 * 1024)
808 return QString(tr(
"%1 KB")).arg(bytes / 1024);
809 if(bytes < 1024 * 1024 * 1024)
810 return QString(tr(
"%1 MB")).arg(bytes / 1024 / 1024);
812 return QString(tr(
"%1 GB")).arg(bytes / 1024 / 1024 / 1024);
829 Q_UNUSED(deselected);
841 QModelIndexList selected =
ui->
peerWidget->selectionModel()->selectedIndexes();
843 for(
int i = 0; i < selected.size(); i++)
856 bool fUnselect =
false;
857 bool fReselect =
false;
863 int selectedRow = -1;
864 QModelIndexList selectedModelIndex =
ui->
peerWidget->selectionModel()->selectedIndexes();
865 if (!selectedModelIndex.isEmpty()) {
866 selectedRow = selectedModelIndex.first().row();
873 if (detailNodeRow < 0)
880 if (detailNodeRow != selectedRow)
891 if (fUnselect && selectedRow >= 0) {
910 QString peerAddrDetails(QString::fromStdString(stats->
nodeStats.
addrName) +
" ");
911 peerAddrDetails += tr(
"(node id: %1)").arg(QString::number(stats->
nodeStats.
nodeid));
913 peerAddrDetails +=
"<br />" + tr(
"via %1").arg(QString::fromStdString(stats->
nodeStats.
addrLocal));
955 QWidget::resizeEvent(event);
960 QWidget::showEvent(event);
971 QWidget::hideEvent(event);
1001 for(
int i = 0; i < nodes.count(); i++)
1004 NodeId id = nodes.at(i).data().toInt();
1018 for(
int i = 0; i < nodes.count(); i++)
1021 NodeId id = nodes.at(i).data().toInt();
1025 if(detailNodeRow < 0)
1045 for(
int i = 0; i < nodes.count(); i++)
1048 QString strNode = nodes.at(i).data().toString();
1051 LookupSubNet(strNode.toStdString().c_str(), possibleSubnet);
1065 ui->
peerHeading->setText(tr(
"Select a peer to view detailed information."));
const boost::filesystem::path & GetDataDir(bool fNetSpecific)
QtRPCTimerBase(boost::function< void(void)> &func, int64_t millis)
void on_sldGraphRange_valueChanged(int value)
void peerSelected(const QItemSelection &selected, const QItemSelection &deselected)
void setFontSize(int newSize)
const QString SALVAGEWALLET("-salvagewallet")
QPushButton * btn_zapwallettxes1
void updateNodeDetail(const CNodeCombinedStats *stats)
void buildParameterlist(QString arg)
void cmdRequest(const QString &command)
virtual bool eventFilter(QObject *obj, QEvent *event)
const PlatformStyle * platformStyle
void banSelectedNode(int bantime)
void setTabFocus(enum TabTypes tabType)
void setMempoolSize(long numberOfTxs, size_t dynUsage)
RPCConsole(const PlatformStyle *platformStyle, QWidget *parent)
bool parseCommandLine(std::vector< std::string > &args, const std::string &strCommand)
void updateTrafficStats(quint64 totalBytesIn, quint64 totalBytesOut)
const QString REINDEX("-reindex")
void saveWindowGeometry(const QString &strSetting, QWidget *parent)
const QString ZAPTXES2("-zapwallettxes=2")
void showPeersTableContextMenu(const QPoint &point)
QTableView * banlistWidget
void on_lineEdit_returnPressed()
static QString categoryClass(int category)
TrafficGraphWidget * trafficGraph
const struct @19 ICON_MAPPING[]
bool fNodeStateStatsAvailable
void showEvent(QShowEvent *event)
const QString UPGRADEWALLET("-upgradewallet")
void setNumBlocks(int count, const QDateTime &blockDate, double nVerificationProgress, bool headers)
void restoreWindowGeometry(const QString &strSetting, const QSize &defaultSize, QWidget *parent)
QLabel * numberOfConnections
void disconnectSelectedNode()
const UniValue & find_value(const UniValue &obj, const std::string &name)
void setClientModel(ClientModel *model)
void setTrafficGraphRange(TrafficGraphData::GraphRange range)
void handleRestart(QStringList args)
UniValue RPCConvertValues(const std::string &strMethod, const std::vector< std::string > &strParams)
QCompleter * autoCompleter
QPushButton * fontBiggerButton
QMenu * banTableContextMenu
void showOrHideBanTableIfRequired()
void browseHistory(int offset)
QLabel * label_berkeleyDBVersion
const TrafficGraphData::GraphRange INITIAL_TRAFFIC_GRAPH_SETTING
int getRowByNodeId(NodeId nodeid)
void updateNetworkState()
void resizeEvent(QResizeEvent *event)
int64_t GetSystemTimeInSeconds()
void hideEvent(QHideEvent *event)
RPCTimerInterface * rpcTimerInterface
QPushButton * btnClearTrafficGraph
const int CONSOLE_HISTORY
const QString RESCAN("-rescan")
void on_tabWidget_currentChanged(int index)
QPushButton * btn_salvagewallet
void reply(int category, const QString &command)
QString getMasternodeCountString() const
QPushButton * btn_upgradewallet
void peerLayoutAboutToChange()
void setNetworkActive(bool networkActive)
QString formatTimeOffset(int64_t nTimeOffset)
QMenu * peersTableContextMenu
QString HtmlEscape(const QString &str, bool fMultiLine)
QString formatSubVersion() const
void showBanTableContextMenu(const QPoint &point)
void request(const QString &command)
const QString ZAPTXES1("-zapwallettxes=1")
QPushButton * btn_zapwallettxes2
CNodeStateStats nodeStateStats
QPushButton * fontSmallerButton
void clear(bool clearHistory=true)
static const int RangeMinutes[]
void keyPressEvent(QKeyEvent *)
bool LookupSubNet(const char *pszName, CSubNet &ret)
QLabel * peerCommonHeight
QLabel * berkeleyDBVersion
QPushButton * openDebugLogfileButton
QString formatFullVersion() const
QString formatClientStartupTime() const
bool getNetworkActive() const
Return true if network activity in core is enabled.
boost::function< void(void)> func
void RPCRegisterTimerInterface(RPCTimerInterface *iface)
quint64 getTotalBytesRecv() const
const CChainParams & Params()
std::string write(unsigned int prettyIndent=0, unsigned int indentLevel=0) const
const CNodeCombinedStats * getNodeStats(int idx)
static QString FormatBytes(quint64 bytes)
QPushButton * clearButton
void setMasternodeCount(const QString &strMasternodes)
std::unique_ptr< CConnman > g_connman
QList< QModelIndex > getEntryData(QAbstractItemView *view, int column)
const char fontSizeSettingsKey[]
QString formatServicesStr(quint64 mask)
void setNumConnections(int count)
QString formatPingTime(double dPingTime)
double getVerificationProgress(const CBlockIndex *tip) const
std::string GetArg(const std::string &strArg, const std::string &strDefault)
const QSize FONT_RANGE(4, 40)
RPCTimerBase * NewTimer(boost::function< void(void)> &func, int64_t millis)
void setupUi(QWidget *RPCConsole)
QString formatDurationStr(int secs)
void on_openDebugLogfileButton_clicked()
UniValue execute(const std::string &method, const UniValue ¶ms) const
quint64 getTotalBytesSent() const
QLabel * mempoolNumberTxs
std::vector< std::string > listCommands() const
QPushButton * btn_reindex
QDateTime getLastBlockDate() const
void message(int category, const QString &message, bool html=false)
QString clientName() const
QList< NodeId > cachedNodeids
std::string get_str() const
ClientModel * clientModel
BanTableModel * getBanTableModel()
QTextEdit * messagesWidget
void RPCUnregisterTimerInterface(RPCTimerInterface *iface)
int getNumConnections(unsigned int flags=CONNECTIONS_ALL) const
Return number of connections, default is in- and outbound (total)
PeerTableModel * getPeerTableModel()