[Qt] tweak new peers tab in console window
- remove starting height as table header and replace with ping time - remove columnResizingFixer - add local address (if available) in detailed node view (on top of the right view below the remote address) - remove some .c_str() by using QString::fromStdString() - rename Address to Address/Hostname - rename secs to just s for ping time - use MODEL_UPDATE_DELAY from guiconstants.h for the peer refresh time - make PeerTableModel::columnCount() return no hard-coded value - remove and cleanup dup private: section in RPCConsole header - add new defaults for column sizes - remove behaviour which keeps disconnected peers selected and also remove code which keeps track of last selected peer stats - add sync height to detail view - add some additional NULL pointer checks for clientModel in rpcconsole.cpp
This commit is contained in:
parent
d97a58f883
commit
a5b2d9c82e
7 changed files with 445 additions and 356 deletions
|
@ -428,7 +428,7 @@
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
<widget class="QWidget" name="tab">
|
<widget class="QWidget" name="tab_nettraffic">
|
||||||
<attribute name="title">
|
<attribute name="title">
|
||||||
<string>&Network Traffic</string>
|
<string>&Network Traffic</string>
|
||||||
</attribute>
|
</attribute>
|
||||||
|
@ -683,6 +683,19 @@
|
||||||
<string>&Peers</string>
|
<string>&Peers</string>
|
||||||
</attribute>
|
</attribute>
|
||||||
<layout class="QGridLayout" name="gridLayout_2">
|
<layout class="QGridLayout" name="gridLayout_2">
|
||||||
|
<item row="0" column="0" rowspan="2">
|
||||||
|
<widget class="QTableView" name="peerWidget">
|
||||||
|
<property name="horizontalScrollBarPolicy">
|
||||||
|
<enum>Qt::ScrollBarAlwaysOff</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sortingEnabled">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<attribute name="horizontalHeaderHighlightSections">
|
||||||
|
<bool>false</bool>
|
||||||
|
</attribute>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
<item row="0" column="1">
|
<item row="0" column="1">
|
||||||
<widget class="QLabel" name="peerHeading">
|
<widget class="QLabel" name="peerHeading">
|
||||||
<property name="sizePolicy">
|
<property name="sizePolicy">
|
||||||
|
@ -691,262 +704,377 @@
|
||||||
<verstretch>0</verstretch>
|
<verstretch>0</verstretch>
|
||||||
</sizepolicy>
|
</sizepolicy>
|
||||||
</property>
|
</property>
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>300</width>
|
||||||
|
<height>32</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="font">
|
||||||
|
<font>
|
||||||
|
<pointsize>10</pointsize>
|
||||||
|
</font>
|
||||||
|
</property>
|
||||||
|
<property name="cursor">
|
||||||
|
<cursorShape>IBeamCursor</cursorShape>
|
||||||
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Select a peer to view detailed information.</string>
|
<string>Select a peer to view detailed information.</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="margin">
|
<property name="alignment">
|
||||||
<number>3</number>
|
<set>Qt::AlignHCenter|Qt::AlignTop</set>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
<property name="wordWrap">
|
||||||
</item>
|
|
||||||
<item row="0" column="0" rowspan="2">
|
|
||||||
<widget class="QTableView" name="peerWidget">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="horizontalScrollBarPolicy">
|
|
||||||
<enum>Qt::ScrollBarAlwaysOff</enum>
|
|
||||||
</property>
|
|
||||||
<property name="editTriggers">
|
|
||||||
<set>QAbstractItemView::AnyKeyPressed|QAbstractItemView::DoubleClicked|QAbstractItemView::EditKeyPressed</set>
|
|
||||||
</property>
|
|
||||||
<property name="sortingEnabled">
|
|
||||||
<bool>true</bool>
|
<bool>true</bool>
|
||||||
</property>
|
</property>
|
||||||
|
<property name="textInteractionFlags">
|
||||||
|
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
|
||||||
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="1" column="1">
|
<item row="1" column="1">
|
||||||
<widget class="QWidget" name="detailWidget" native="true">
|
<widget class="QWidget" name="detailWidget" native="true">
|
||||||
<property name="sizePolicy">
|
<property name="minimumSize">
|
||||||
<sizepolicy hsizetype="Preferred" vsizetype="Expanding">
|
<size>
|
||||||
<horstretch>0</horstretch>
|
<width>300</width>
|
||||||
<verstretch>0</verstretch>
|
<height>0</height>
|
||||||
</sizepolicy>
|
</size>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QGridLayout" name="gridLayout_3">
|
<layout class="QGridLayout" name="gridLayout_3">
|
||||||
<property name="leftMargin">
|
<item row="0" column="0">
|
||||||
<number>3</number>
|
<widget class="QLabel" name="label_23">
|
||||||
</property>
|
|
||||||
<item row="12" column="0">
|
|
||||||
<widget class="QLabel" name="label_21">
|
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Version:</string>
|
<string>Direction</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="11" column="1">
|
<item row="0" column="2">
|
||||||
<widget class="QLabel" name="peerPingTime">
|
<widget class="QLabel" name="peerDirection">
|
||||||
|
<property name="cursor">
|
||||||
|
<cursorShape>IBeamCursor</cursorShape>
|
||||||
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>N/A</string>
|
<string>N/A</string>
|
||||||
</property>
|
</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="1" column="0">
|
||||||
|
<widget class="QLabel" name="label_21">
|
||||||
|
<property name="text">
|
||||||
|
<string>Version</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="2">
|
||||||
|
<widget class="QLabel" name="peerVersion">
|
||||||
|
<property name="cursor">
|
||||||
|
<cursorShape>IBeamCursor</cursorShape>
|
||||||
|
</property>
|
||||||
|
<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_28">
|
||||||
|
<property name="text">
|
||||||
|
<string>User Agent</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="2">
|
||||||
|
<widget class="QLabel" name="peerSubversion">
|
||||||
|
<property name="cursor">
|
||||||
|
<cursorShape>IBeamCursor</cursorShape>
|
||||||
|
</property>
|
||||||
|
<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="3" column="0">
|
||||||
|
<widget class="QLabel" name="label_4">
|
||||||
|
<property name="text">
|
||||||
|
<string>Services</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="3" column="2">
|
||||||
|
<widget class="QLabel" name="peerServices">
|
||||||
|
<property name="cursor">
|
||||||
|
<cursorShape>IBeamCursor</cursorShape>
|
||||||
|
</property>
|
||||||
|
<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="4" column="0">
|
||||||
|
<widget class="QLabel" name="label_25">
|
||||||
|
<property name="text">
|
||||||
|
<string>Sync Node</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="4" column="2">
|
||||||
|
<widget class="QLabel" name="peerSyncNode">
|
||||||
|
<property name="cursor">
|
||||||
|
<cursorShape>IBeamCursor</cursorShape>
|
||||||
|
</property>
|
||||||
|
<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>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="5" column="0">
|
<item row="5" column="0">
|
||||||
<widget class="QLabel" name="label_19">
|
<widget class="QLabel" name="label_29">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Last Receive:</string>
|
<string>Starting Height</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="14" column="0">
|
<item row="5" column="2">
|
||||||
<widget class="QLabel" name="label_28">
|
<widget class="QLabel" name="peerHeight">
|
||||||
<property name="text">
|
<property name="cursor">
|
||||||
<string>User Agent:</string>
|
<cursorShape>IBeamCursor</cursorShape>
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="12" column="1">
|
|
||||||
<widget class="QLabel" name="peerVersion">
|
|
||||||
<property name="text">
|
|
||||||
<string>N/A</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="8" column="1">
|
|
||||||
<widget class="QLabel" name="peerConnTime">
|
|
||||||
<property name="minimumSize">
|
|
||||||
<size>
|
|
||||||
<width>160</width>
|
|
||||||
<height>0</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>N/A</string>
|
<string>N/A</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
<property name="textFormat">
|
||||||
</item>
|
<enum>Qt::PlainText</enum>
|
||||||
<item row="11" column="0">
|
</property>
|
||||||
<widget class="QLabel" name="label_26">
|
<property name="textInteractionFlags">
|
||||||
<property name="text">
|
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
|
||||||
<string>Ping Time:</string>
|
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="5" column="1">
|
<item row="6" column="0">
|
||||||
<widget class="QLabel" name="peerLastRecv">
|
<widget class="QLabel" name="label_27">
|
||||||
<property name="sizePolicy">
|
<property name="text">
|
||||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
<string>Sync Height</string>
|
||||||
<horstretch>0</horstretch>
|
</property>
|
||||||
<verstretch>0</verstretch>
|
</widget>
|
||||||
</sizepolicy>
|
</item>
|
||||||
|
<item row="6" column="2">
|
||||||
|
<widget class="QLabel" name="peerSyncHeight">
|
||||||
|
<property name="cursor">
|
||||||
|
<cursorShape>IBeamCursor</cursorShape>
|
||||||
</property>
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>N/A</string>
|
<string>N/A</string>
|
||||||
</property>
|
</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="7" column="0">
|
||||||
|
<widget class="QLabel" name="label_24">
|
||||||
|
<property name="text">
|
||||||
|
<string>Ban Score</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="7" column="2">
|
||||||
|
<widget class="QLabel" name="peerBanScore">
|
||||||
|
<property name="cursor">
|
||||||
|
<cursorShape>IBeamCursor</cursorShape>
|
||||||
|
</property>
|
||||||
|
<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>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="8" column="0">
|
<item row="8" column="0">
|
||||||
<widget class="QLabel" name="label_22">
|
<widget class="QLabel" name="label_22">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Connection Time:</string>
|
<string>Connection Time</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="6" column="1">
|
<item row="8" column="2">
|
||||||
<widget class="QLabel" name="peerBytesSent">
|
<widget class="QLabel" name="peerConnTime">
|
||||||
|
<property name="cursor">
|
||||||
|
<cursorShape>IBeamCursor</cursorShape>
|
||||||
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>N/A</string>
|
<string>N/A</string>
|
||||||
</property>
|
</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_15">
|
||||||
|
<property name="text">
|
||||||
|
<string>Last Send</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="9" column="2">
|
||||||
|
<widget class="QLabel" name="peerLastSend">
|
||||||
|
<property name="cursor">
|
||||||
|
<cursorShape>IBeamCursor</cursorShape>
|
||||||
|
</property>
|
||||||
|
<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_19">
|
||||||
|
<property name="text">
|
||||||
|
<string>Last Receive</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="10" column="2">
|
||||||
|
<widget class="QLabel" name="peerLastRecv">
|
||||||
|
<property name="cursor">
|
||||||
|
<cursorShape>IBeamCursor</cursorShape>
|
||||||
|
</property>
|
||||||
|
<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">
|
||||||
|
<widget class="QLabel" name="label_18">
|
||||||
|
<property name="text">
|
||||||
|
<string>Bytes Sent</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="11" column="2">
|
||||||
|
<widget class="QLabel" name="peerBytesSent">
|
||||||
|
<property name="cursor">
|
||||||
|
<cursorShape>IBeamCursor</cursorShape>
|
||||||
|
</property>
|
||||||
|
<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="12" column="0">
|
||||||
|
<widget class="QLabel" name="label_20">
|
||||||
|
<property name="text">
|
||||||
|
<string>Bytes Received</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="12" column="2">
|
||||||
|
<widget class="QLabel" name="peerBytesRecv">
|
||||||
|
<property name="cursor">
|
||||||
|
<cursorShape>IBeamCursor</cursorShape>
|
||||||
|
</property>
|
||||||
|
<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="13" column="0">
|
||||||
|
<widget class="QLabel" name="label_26">
|
||||||
|
<property name="text">
|
||||||
|
<string>Ping Time</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="13" column="2">
|
||||||
|
<widget class="QLabel" name="peerPingTime">
|
||||||
|
<property name="cursor">
|
||||||
|
<cursorShape>IBeamCursor</cursorShape>
|
||||||
|
</property>
|
||||||
|
<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>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="14" column="1">
|
<item row="14" column="1">
|
||||||
<widget class="QLabel" name="peerSubversion">
|
<spacer name="verticalSpacer_3">
|
||||||
<property name="text">
|
<property name="orientation">
|
||||||
<string>N/A</string>
|
<enum>Qt::Vertical</enum>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
<property name="sizeHint" stdset="0">
|
||||||
</item>
|
<size>
|
||||||
<item row="15" column="0">
|
<width>20</width>
|
||||||
<widget class="QLabel" name="label_29">
|
<height>40</height>
|
||||||
<property name="text">
|
</size>
|
||||||
<string>Starting Height:</string>
|
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</spacer>
|
||||||
</item>
|
|
||||||
<item row="7" column="1">
|
|
||||||
<widget class="QLabel" name="peerBytesRecv">
|
|
||||||
<property name="text">
|
|
||||||
<string>N/A</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="6" column="0">
|
|
||||||
<widget class="QLabel" name="label_18">
|
|
||||||
<property name="text">
|
|
||||||
<string>Bytes Sent:</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="7" column="0">
|
|
||||||
<widget class="QLabel" name="label_20">
|
|
||||||
<property name="text">
|
|
||||||
<string>Bytes Received:</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="15" column="1">
|
|
||||||
<widget class="QLabel" name="peerHeight">
|
|
||||||
<property name="text">
|
|
||||||
<string>N/A</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="16" column="0">
|
|
||||||
<widget class="QLabel" name="label_24">
|
|
||||||
<property name="text">
|
|
||||||
<string>Ban Score:</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="16" column="1">
|
|
||||||
<widget class="QLabel" name="peerBanScore">
|
|
||||||
<property name="text">
|
|
||||||
<string>N/A</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="17" column="0">
|
|
||||||
<widget class="QLabel" name="label_23">
|
|
||||||
<property name="text">
|
|
||||||
<string>Direction:</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="17" column="1">
|
|
||||||
<widget class="QLabel" name="peerDirection">
|
|
||||||
<property name="text">
|
|
||||||
<string>N/A</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="19" column="0">
|
|
||||||
<widget class="QLabel" name="label_25">
|
|
||||||
<property name="text">
|
|
||||||
<string>Sync Node:</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="19" column="1">
|
|
||||||
<widget class="QLabel" name="peerSyncNode">
|
|
||||||
<property name="text">
|
|
||||||
<string>N/A</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="3" column="0">
|
|
||||||
<widget class="QLabel" name="label_15">
|
|
||||||
<property name="text">
|
|
||||||
<string>Last Send:</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="2" column="0">
|
|
||||||
<widget class="QLabel" name="label_4">
|
|
||||||
<property name="text">
|
|
||||||
<string>Services:</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="1" column="0">
|
|
||||||
<widget class="QLabel" name="label_27">
|
|
||||||
<property name="text">
|
|
||||||
<string>IP Address/port:</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="3" column="1">
|
|
||||||
<widget class="QLabel" name="peerLastSend">
|
|
||||||
<property name="text">
|
|
||||||
<string>N/A</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="2" column="1">
|
|
||||||
<widget class="QLabel" name="peerServices">
|
|
||||||
<property name="text">
|
|
||||||
<string>N/A</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="1" column="1">
|
|
||||||
<widget class="QLabel" name="peerAddr">
|
|
||||||
<property name="text">
|
|
||||||
<string>N/A</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="20" column="0">
|
|
||||||
<widget class="QWidget" name="widget" native="true">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Preferred" vsizetype="Expanding">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
|
|
|
@ -804,4 +804,9 @@ QString formatServicesStr(uint64_t mask)
|
||||||
return QObject::tr("None");
|
return QObject::tr("None");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString formatPingTime(double dPingTime)
|
||||||
|
{
|
||||||
|
return dPingTime == 0 ? QObject::tr("N/A") : QString(QObject::tr("%1 s")).arg(QString::number(dPingTime, 'f', 3));
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace GUIUtil
|
} // namespace GUIUtil
|
||||||
|
|
|
@ -178,6 +178,9 @@ namespace GUIUtil
|
||||||
|
|
||||||
/* Format CNodeStats.nServices bitmask into a user-readable string */
|
/* Format CNodeStats.nServices bitmask into a user-readable string */
|
||||||
QString formatServicesStr(uint64_t mask);
|
QString formatServicesStr(uint64_t mask);
|
||||||
|
|
||||||
|
/* Format a CNodeCombinedStats.dPingTime into a user-readable string or display N/A, if 0*/
|
||||||
|
QString formatPingTime(double dPingTime);
|
||||||
} // namespace GUIUtil
|
} // namespace GUIUtil
|
||||||
|
|
||||||
#endif // GUIUTIL_H
|
#endif // GUIUTIL_H
|
||||||
|
|
|
@ -5,6 +5,8 @@
|
||||||
#include "peertablemodel.h"
|
#include "peertablemodel.h"
|
||||||
|
|
||||||
#include "clientmodel.h"
|
#include "clientmodel.h"
|
||||||
|
#include "guiconstants.h"
|
||||||
|
#include "guiutil.h"
|
||||||
|
|
||||||
#include "net.h"
|
#include "net.h"
|
||||||
#include "sync.h"
|
#include "sync.h"
|
||||||
|
@ -15,8 +17,8 @@
|
||||||
|
|
||||||
bool NodeLessThan::operator()(const CNodeCombinedStats &left, const CNodeCombinedStats &right) const
|
bool NodeLessThan::operator()(const CNodeCombinedStats &left, const CNodeCombinedStats &right) const
|
||||||
{
|
{
|
||||||
const CNodeStats *pLeft = &(left.nodestats);
|
const CNodeStats *pLeft = &(left.nodeStats);
|
||||||
const CNodeStats *pRight = &(right.nodestats);
|
const CNodeStats *pRight = &(right.nodeStats);
|
||||||
|
|
||||||
if (order == Qt::DescendingOrder)
|
if (order == Qt::DescendingOrder)
|
||||||
std::swap(pLeft, pRight);
|
std::swap(pLeft, pRight);
|
||||||
|
@ -27,8 +29,8 @@ bool NodeLessThan::operator()(const CNodeCombinedStats &left, const CNodeCombine
|
||||||
return pLeft->addrName.compare(pRight->addrName) < 0;
|
return pLeft->addrName.compare(pRight->addrName) < 0;
|
||||||
case PeerTableModel::Subversion:
|
case PeerTableModel::Subversion:
|
||||||
return pLeft->cleanSubVer.compare(pRight->cleanSubVer) < 0;
|
return pLeft->cleanSubVer.compare(pRight->cleanSubVer) < 0;
|
||||||
case PeerTableModel::Height:
|
case PeerTableModel::Ping:
|
||||||
return pLeft->nStartingHeight < pRight->nStartingHeight;
|
return pLeft->dPingTime < pRight->dPingTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
@ -48,7 +50,8 @@ public:
|
||||||
std::map<NodeId, int> mapNodeRows;
|
std::map<NodeId, int> mapNodeRows;
|
||||||
|
|
||||||
/** Pull a full list of peers from vNodes into our cache */
|
/** Pull a full list of peers from vNodes into our cache */
|
||||||
void refreshPeers() {
|
void refreshPeers()
|
||||||
|
{
|
||||||
{
|
{
|
||||||
TRY_LOCK(cs_vNodes, lockNodes);
|
TRY_LOCK(cs_vNodes, lockNodes);
|
||||||
if (!lockNodes)
|
if (!lockNodes)
|
||||||
|
@ -63,23 +66,17 @@ public:
|
||||||
BOOST_FOREACH(CNode* pnode, vNodes)
|
BOOST_FOREACH(CNode* pnode, vNodes)
|
||||||
{
|
{
|
||||||
CNodeCombinedStats stats;
|
CNodeCombinedStats stats;
|
||||||
stats.statestats.nMisbehavior = -1;
|
stats.nodeStateStats.nMisbehavior = 0;
|
||||||
pnode->copyStats(stats.nodestats);
|
stats.nodeStateStats.nSyncHeight = -1;
|
||||||
|
stats.fNodeStateStatsAvailable = false;
|
||||||
|
pnode->copyStats(stats.nodeStats);
|
||||||
cachedNodeStats.append(stats);
|
cachedNodeStats.append(stats);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// if we can, retrieve the CNodeStateStats for each node.
|
// Try to retrieve the CNodeStateStats for each node.
|
||||||
{
|
|
||||||
TRY_LOCK(cs_main, lockMain);
|
|
||||||
if (lockMain)
|
|
||||||
{
|
|
||||||
BOOST_FOREACH(CNodeCombinedStats &stats, cachedNodeStats)
|
BOOST_FOREACH(CNodeCombinedStats &stats, cachedNodeStats)
|
||||||
{
|
stats.fNodeStateStatsAvailable = GetNodeStateStats(stats.nodeStats.nodeid, stats.nodeStateStats);
|
||||||
GetNodeStateStats(stats.nodestats.nodeid, stats.statestats);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sortColumn >= 0)
|
if (sortColumn >= 0)
|
||||||
// sort cacheNodeStats (use stable sort to prevent rows jumping around unneceesarily)
|
// sort cacheNodeStats (use stable sort to prevent rows jumping around unneceesarily)
|
||||||
|
@ -89,9 +86,7 @@ public:
|
||||||
mapNodeRows.clear();
|
mapNodeRows.clear();
|
||||||
int row = 0;
|
int row = 0;
|
||||||
BOOST_FOREACH(CNodeCombinedStats &stats, cachedNodeStats)
|
BOOST_FOREACH(CNodeCombinedStats &stats, cachedNodeStats)
|
||||||
{
|
mapNodeRows.insert(std::pair<NodeId, int>(stats.nodeStats.nodeid, row++));
|
||||||
mapNodeRows.insert(std::pair<NodeId, int>(stats.nodestats.nodeid, row++));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int size()
|
int size()
|
||||||
|
@ -103,18 +98,18 @@ public:
|
||||||
{
|
{
|
||||||
if(idx >= 0 && idx < cachedNodeStats.size()) {
|
if(idx >= 0 && idx < cachedNodeStats.size()) {
|
||||||
return &cachedNodeStats[idx];
|
return &cachedNodeStats[idx];
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
PeerTableModel::PeerTableModel(ClientModel *parent) :
|
PeerTableModel::PeerTableModel(ClientModel *parent) :
|
||||||
QAbstractTableModel(parent),clientModel(parent),timer(0)
|
QAbstractTableModel(parent),
|
||||||
|
clientModel(parent),
|
||||||
|
timer(0)
|
||||||
{
|
{
|
||||||
columns << tr("Address") << tr("User Agent") << tr("Start Height");
|
columns << tr("Address/Hostname") << tr("User Agent") << tr("Ping Time");
|
||||||
priv = new PeerTablePriv();
|
priv = new PeerTablePriv();
|
||||||
// default to unsorted
|
// default to unsorted
|
||||||
priv->sortColumn = -1;
|
priv->sortColumn = -1;
|
||||||
|
@ -122,14 +117,14 @@ PeerTableModel::PeerTableModel(ClientModel *parent) :
|
||||||
// set up timer for auto refresh
|
// set up timer for auto refresh
|
||||||
timer = new QTimer();
|
timer = new QTimer();
|
||||||
connect(timer, SIGNAL(timeout()), SLOT(refresh()));
|
connect(timer, SIGNAL(timeout()), SLOT(refresh()));
|
||||||
|
timer->setInterval(MODEL_UPDATE_DELAY);
|
||||||
|
|
||||||
// load initial data
|
// load initial data
|
||||||
refresh();
|
refresh();
|
||||||
}
|
}
|
||||||
|
|
||||||
void PeerTableModel::startAutoRefresh(int msecs)
|
void PeerTableModel::startAutoRefresh()
|
||||||
{
|
{
|
||||||
timer->setInterval(1000);
|
|
||||||
timer->start();
|
timer->start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -147,7 +142,7 @@ int PeerTableModel::rowCount(const QModelIndex &parent) const
|
||||||
int PeerTableModel::columnCount(const QModelIndex &parent) const
|
int PeerTableModel::columnCount(const QModelIndex &parent) const
|
||||||
{
|
{
|
||||||
Q_UNUSED(parent);
|
Q_UNUSED(parent);
|
||||||
return 3;
|
return columns.length();;
|
||||||
}
|
}
|
||||||
|
|
||||||
QVariant PeerTableModel::data(const QModelIndex &index, int role) const
|
QVariant PeerTableModel::data(const QModelIndex &index, int role) const
|
||||||
|
@ -162,11 +157,11 @@ QVariant PeerTableModel::data(const QModelIndex &index, int role) const
|
||||||
switch(index.column())
|
switch(index.column())
|
||||||
{
|
{
|
||||||
case Address:
|
case Address:
|
||||||
return QVariant(rec->nodestats.addrName.c_str());
|
return QString::fromStdString(rec->nodeStats.addrName);
|
||||||
case Subversion:
|
case Subversion:
|
||||||
return QVariant(rec->nodestats.cleanSubVer.c_str());
|
return QString::fromStdString(rec->nodeStats.cleanSubVer);
|
||||||
case Height:
|
case Ping:
|
||||||
return rec->nodestats.nStartingHeight;
|
return GUIUtil::formatPingTime(rec->nodeStats.dPingTime);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return QVariant();
|
return QVariant();
|
||||||
|
@ -208,7 +203,8 @@ QModelIndex PeerTableModel::index(int row, int column, const QModelIndex &parent
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const CNodeCombinedStats *PeerTableModel::getNodeStats(int idx) {
|
const CNodeCombinedStats *PeerTableModel::getNodeStats(int idx)
|
||||||
|
{
|
||||||
return priv->index(idx);
|
return priv->index(idx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,8 +19,9 @@ class QTimer;
|
||||||
QT_END_NAMESPACE
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
struct CNodeCombinedStats {
|
struct CNodeCombinedStats {
|
||||||
CNodeStats nodestats;
|
CNodeStats nodeStats;
|
||||||
CNodeStateStats statestats;
|
CNodeStateStats nodeStateStats;
|
||||||
|
bool fNodeStateStatsAvailable;
|
||||||
};
|
};
|
||||||
|
|
||||||
class NodeLessThan
|
class NodeLessThan
|
||||||
|
@ -47,13 +48,13 @@ public:
|
||||||
explicit PeerTableModel(ClientModel *parent = 0);
|
explicit PeerTableModel(ClientModel *parent = 0);
|
||||||
const CNodeCombinedStats *getNodeStats(int idx);
|
const CNodeCombinedStats *getNodeStats(int idx);
|
||||||
int getRowByNodeId(NodeId nodeid);
|
int getRowByNodeId(NodeId nodeid);
|
||||||
void startAutoRefresh(int msecs);
|
void startAutoRefresh();
|
||||||
void stopAutoRefresh();
|
void stopAutoRefresh();
|
||||||
|
|
||||||
enum ColumnIndex {
|
enum ColumnIndex {
|
||||||
Address = 0,
|
Address = 0,
|
||||||
Subversion = 1,
|
Subversion = 1,
|
||||||
Height = 2
|
Ping = 2
|
||||||
};
|
};
|
||||||
|
|
||||||
/** @name Methods overridden from QAbstractTableModel
|
/** @name Methods overridden from QAbstractTableModel
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
#include "peertablemodel.h"
|
#include "peertablemodel.h"
|
||||||
|
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
|
#include "chainparams.h"
|
||||||
#include "rpcserver.h"
|
#include "rpcserver.h"
|
||||||
#include "rpcclient.h"
|
#include "rpcclient.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
@ -200,12 +201,9 @@ RPCConsole::RPCConsole(QWidget *parent) :
|
||||||
QDialog(parent),
|
QDialog(parent),
|
||||||
ui(new Ui::RPCConsole),
|
ui(new Ui::RPCConsole),
|
||||||
clientModel(0),
|
clientModel(0),
|
||||||
historyPtr(0)
|
historyPtr(0),
|
||||||
|
cachedNodeid(-1)
|
||||||
{
|
{
|
||||||
detailNodeStats = CNodeCombinedStats();
|
|
||||||
detailNodeStats.nodestats.nodeid = -1;
|
|
||||||
detailNodeStats.statestats.nMisbehavior = -1;
|
|
||||||
|
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
GUIUtil::restoreWindowGeometry("nRPCConsoleWindow", this->size(), this);
|
GUIUtil::restoreWindowGeometry("nRPCConsoleWindow", this->size(), this);
|
||||||
|
|
||||||
|
@ -233,6 +231,7 @@ RPCConsole::RPCConsole(QWidget *parent) :
|
||||||
setTrafficGraphRange(INITIAL_TRAFFIC_GRAPH_MINS);
|
setTrafficGraphRange(INITIAL_TRAFFIC_GRAPH_MINS);
|
||||||
|
|
||||||
ui->detailWidget->hide();
|
ui->detailWidget->hide();
|
||||||
|
ui->peerHeading->setText(tr("Select a peer to view detailed information."));
|
||||||
|
|
||||||
clear();
|
clear();
|
||||||
}
|
}
|
||||||
|
@ -303,11 +302,11 @@ void RPCConsole::setClientModel(ClientModel *model)
|
||||||
ui->peerWidget->setSelectionBehavior(QAbstractItemView::SelectRows);
|
ui->peerWidget->setSelectionBehavior(QAbstractItemView::SelectRows);
|
||||||
ui->peerWidget->setSelectionMode(QAbstractItemView::SingleSelection);
|
ui->peerWidget->setSelectionMode(QAbstractItemView::SingleSelection);
|
||||||
ui->peerWidget->setColumnWidth(PeerTableModel::Address, ADDRESS_COLUMN_WIDTH);
|
ui->peerWidget->setColumnWidth(PeerTableModel::Address, ADDRESS_COLUMN_WIDTH);
|
||||||
columnResizingFixer = new GUIUtil::TableViewLastColumnResizingFixer(ui->peerWidget, MINIMUM_COLUMN_WIDTH, MINIMUM_COLUMN_WIDTH);
|
ui->peerWidget->setColumnWidth(PeerTableModel::Subversion, SUBVERSION_COLUMN_WIDTH);
|
||||||
|
ui->peerWidget->setColumnWidth(PeerTableModel::Ping, PING_COLUMN_WIDTH);
|
||||||
|
|
||||||
// connect the peerWidget's selection model to our peerSelected() handler
|
// connect the peerWidget selection model to our peerSelected() handler
|
||||||
QItemSelectionModel *peerSelectModel = ui->peerWidget->selectionModel();
|
connect(ui->peerWidget->selectionModel(), SIGNAL(selectionChanged(const QItemSelection &, const QItemSelection &)),
|
||||||
connect(peerSelectModel, SIGNAL(selectionChanged(const QItemSelection &, const QItemSelection &)),
|
|
||||||
this, SLOT(peerSelected(const QItemSelection &, const QItemSelection &)));
|
this, SLOT(peerSelected(const QItemSelection &, const QItemSelection &)));
|
||||||
connect(model->getPeerTableModel(), SIGNAL(layoutChanged()), this, SLOT(peerLayoutChanged()));
|
connect(model->getPeerTableModel(), SIGNAL(layoutChanged()), this, SLOT(peerLayoutChanged()));
|
||||||
|
|
||||||
|
@ -473,10 +472,6 @@ void RPCConsole::on_tabWidget_currentChanged(int index)
|
||||||
{
|
{
|
||||||
ui->lineEdit->setFocus();
|
ui->lineEdit->setFocus();
|
||||||
}
|
}
|
||||||
else if(ui->tabWidget->widget(index) == ui->tab_peers)
|
|
||||||
{
|
|
||||||
initPeerTable();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void RPCConsole::on_openDebugLogfileButton_clicked()
|
void RPCConsole::on_openDebugLogfileButton_clicked()
|
||||||
|
@ -525,30 +520,24 @@ void RPCConsole::peerSelected(const QItemSelection &selected, const QItemSelecti
|
||||||
{
|
{
|
||||||
Q_UNUSED(deselected);
|
Q_UNUSED(deselected);
|
||||||
|
|
||||||
if (selected.indexes().isEmpty())
|
if (!clientModel || selected.indexes().isEmpty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// mark the cached banscore as unknown
|
|
||||||
detailNodeStats.statestats.nMisbehavior = -1;
|
|
||||||
|
|
||||||
const CNodeCombinedStats *stats = clientModel->getPeerTableModel()->getNodeStats(selected.indexes().first().row());
|
const CNodeCombinedStats *stats = clientModel->getPeerTableModel()->getNodeStats(selected.indexes().first().row());
|
||||||
|
|
||||||
if (stats)
|
if (stats)
|
||||||
{
|
|
||||||
detailNodeStats.nodestats.nodeid = stats->nodestats.nodeid;
|
|
||||||
updateNodeDetail(stats);
|
updateNodeDetail(stats);
|
||||||
ui->detailWidget->show();
|
|
||||||
ui->detailWidget->setDisabled(false);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void RPCConsole::peerLayoutChanged()
|
void RPCConsole::peerLayoutChanged()
|
||||||
{
|
{
|
||||||
const CNodeCombinedStats *stats = NULL;
|
if (!clientModel)
|
||||||
bool fUnselect = false, fReselect = false, fDisconnected = false;
|
return;
|
||||||
|
|
||||||
if (detailNodeStats.nodestats.nodeid == -1)
|
const CNodeCombinedStats *stats = NULL;
|
||||||
// no node selected yet
|
bool fUnselect = false;
|
||||||
|
bool fReselect = false;
|
||||||
|
|
||||||
|
if (cachedNodeid == -1) // no node selected yet
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// find the currently selected row
|
// find the currently selected row
|
||||||
|
@ -561,14 +550,15 @@ void RPCConsole::peerLayoutChanged()
|
||||||
|
|
||||||
// check if our detail node has a row in the table (it may not necessarily
|
// check if our detail node has a row in the table (it may not necessarily
|
||||||
// be at selectedRow since its position can change after a layout change)
|
// be at selectedRow since its position can change after a layout change)
|
||||||
int detailNodeRow = clientModel->getPeerTableModel()->getRowByNodeId(detailNodeStats.nodestats.nodeid);
|
int detailNodeRow = clientModel->getPeerTableModel()->getRowByNodeId(cachedNodeid);
|
||||||
|
|
||||||
if (detailNodeRow < 0)
|
if (detailNodeRow < 0)
|
||||||
{
|
{
|
||||||
// detail node dissapeared from table (node disconnected)
|
// detail node dissapeared from table (node disconnected)
|
||||||
fUnselect = true;
|
fUnselect = true;
|
||||||
fDisconnected = true;
|
cachedNodeid = -1;
|
||||||
detailNodeStats.nodestats.nodeid = 0;
|
ui->detailWidget->hide();
|
||||||
|
ui->peerHeading->setText(tr("Select a peer to view detailed information."));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -596,91 +586,64 @@ void RPCConsole::peerLayoutChanged()
|
||||||
|
|
||||||
if (stats)
|
if (stats)
|
||||||
updateNodeDetail(stats);
|
updateNodeDetail(stats);
|
||||||
|
|
||||||
if (fDisconnected)
|
|
||||||
{
|
|
||||||
ui->peerHeading->setText(QString(tr("Peer Disconnected")));
|
|
||||||
ui->detailWidget->setDisabled(true);
|
|
||||||
QDateTime dt = QDateTime::fromTime_t(detailNodeStats.nodestats.nLastSend);
|
|
||||||
if (detailNodeStats.nodestats.nLastSend)
|
|
||||||
ui->peerLastSend->setText(dt.toString("yyyy-MM-dd hh:mm:ss"));
|
|
||||||
dt.setTime_t(detailNodeStats.nodestats.nLastRecv);
|
|
||||||
if (detailNodeStats.nodestats.nLastRecv)
|
|
||||||
ui->peerLastRecv->setText(dt.toString("yyyy-MM-dd hh:mm:ss"));
|
|
||||||
dt.setTime_t(detailNodeStats.nodestats.nTimeConnected);
|
|
||||||
ui->peerConnTime->setText(dt.toString("yyyy-MM-dd hh:mm:ss"));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void RPCConsole::updateNodeDetail(const CNodeCombinedStats *combinedStats)
|
void RPCConsole::updateNodeDetail(const CNodeCombinedStats *stats)
|
||||||
{
|
{
|
||||||
CNodeStats stats = combinedStats->nodestats;
|
// Update cached nodeid
|
||||||
|
cachedNodeid = stats->nodeStats.nodeid;
|
||||||
// keep a copy of timestamps, used to display dates upon disconnect
|
|
||||||
detailNodeStats.nodestats.nLastSend = stats.nLastSend;
|
|
||||||
detailNodeStats.nodestats.nLastRecv = stats.nLastRecv;
|
|
||||||
detailNodeStats.nodestats.nTimeConnected = stats.nTimeConnected;
|
|
||||||
|
|
||||||
// update the detail ui with latest node information
|
// update the detail ui with latest node information
|
||||||
ui->peerHeading->setText(QString("<b>%1</b>").arg(tr("Node Detail")));
|
QString peerAddrDetails(QString::fromStdString(stats->nodeStats.addrName));
|
||||||
ui->peerAddr->setText(QString(stats.addrName.c_str()));
|
if (!stats->nodeStats.addrLocal.empty())
|
||||||
ui->peerServices->setText(GUIUtil::formatServicesStr(stats.nServices));
|
peerAddrDetails += "<br />" + tr("via %1").arg(QString::fromStdString(stats->nodeStats.addrLocal));
|
||||||
ui->peerLastSend->setText(stats.nLastSend ? GUIUtil::formatDurationStr(GetTime() - stats.nLastSend) : tr("never"));
|
ui->peerHeading->setText(peerAddrDetails);
|
||||||
ui->peerLastRecv->setText(stats.nLastRecv ? GUIUtil::formatDurationStr(GetTime() - stats.nLastRecv) : tr("never"));
|
ui->peerServices->setText(GUIUtil::formatServicesStr(stats->nodeStats.nServices));
|
||||||
ui->peerBytesSent->setText(FormatBytes(stats.nSendBytes));
|
ui->peerLastSend->setText(stats->nodeStats.nLastSend ? GUIUtil::formatDurationStr(GetTime() - stats->nodeStats.nLastSend) : tr("never"));
|
||||||
ui->peerBytesRecv->setText(FormatBytes(stats.nRecvBytes));
|
ui->peerLastRecv->setText(stats->nodeStats.nLastRecv ? GUIUtil::formatDurationStr(GetTime() - stats->nodeStats.nLastRecv) : tr("never"));
|
||||||
ui->peerConnTime->setText(GUIUtil::formatDurationStr(GetTime() - stats.nTimeConnected));
|
ui->peerBytesSent->setText(FormatBytes(stats->nodeStats.nSendBytes));
|
||||||
ui->peerPingTime->setText(stats.dPingTime == 0 ? tr("N/A") : QString(tr("%1 secs")).arg(QString::number(stats.dPingTime, 'f', 3)));
|
ui->peerBytesRecv->setText(FormatBytes(stats->nodeStats.nRecvBytes));
|
||||||
ui->peerVersion->setText(QString("%1").arg(stats.nVersion));
|
ui->peerConnTime->setText(GUIUtil::formatDurationStr(GetTime() - stats->nodeStats.nTimeConnected));
|
||||||
ui->peerSubversion->setText(QString(stats.cleanSubVer.c_str()));
|
ui->peerPingTime->setText(GUIUtil::formatPingTime(stats->nodeStats.dPingTime));
|
||||||
ui->peerDirection->setText(stats.fInbound ? tr("Inbound") : tr("Outbound"));
|
ui->peerVersion->setText(QString("%1").arg(stats->nodeStats.nVersion));
|
||||||
ui->peerHeight->setText(QString("%1").arg(stats.nStartingHeight));
|
ui->peerSubversion->setText(QString::fromStdString(stats->nodeStats.cleanSubVer));
|
||||||
ui->peerSyncNode->setText(stats.fSyncNode ? tr("Yes") : tr("No"));
|
ui->peerDirection->setText(stats->nodeStats.fInbound ? tr("Inbound") : tr("Outbound"));
|
||||||
|
ui->peerHeight->setText(QString("%1").arg(stats->nodeStats.nStartingHeight));
|
||||||
|
ui->peerSyncNode->setText(stats->nodeStats.fSyncNode ? tr("Yes") : tr("No"));
|
||||||
|
|
||||||
// if we can, display the peer's ban score
|
// This check fails for example if the lock was busy and
|
||||||
CNodeStateStats statestats = combinedStats->statestats;
|
// nodeStateStats couldn't be fetched.
|
||||||
if (statestats.nMisbehavior >= 0)
|
if (stats->fNodeStateStatsAvailable) {
|
||||||
{
|
// Ban score is init to 0
|
||||||
// we have a new nMisbehavor value - update the cache
|
ui->peerBanScore->setText(QString("%1").arg(stats->nodeStateStats.nMisbehavior));
|
||||||
detailNodeStats.statestats.nMisbehavior = statestats.nMisbehavior;
|
|
||||||
|
// Sync height is init to -1
|
||||||
|
if (stats->nodeStateStats.nSyncHeight > -1)
|
||||||
|
ui->peerSyncHeight->setText(QString("%1").arg(stats->nodeStateStats.nSyncHeight));
|
||||||
|
else
|
||||||
|
ui->peerSyncHeight->setText(tr("Unknown"));
|
||||||
|
} else {
|
||||||
|
ui->peerBanScore->setText(tr("Fetching..."));
|
||||||
|
ui->peerSyncHeight->setText(tr("Fetching..."));
|
||||||
}
|
}
|
||||||
|
|
||||||
// pull the ban score from cache. -1 means it hasn't been retrieved yet (lock busy).
|
ui->detailWidget->show();
|
||||||
if (detailNodeStats.statestats.nMisbehavior >= 0)
|
|
||||||
ui->peerBanScore->setText(QString("%1").arg(detailNodeStats.statestats.nMisbehavior));
|
|
||||||
else
|
|
||||||
ui->peerBanScore->setText(tr("Fetching..."));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void RPCConsole::initPeerTable()
|
|
||||||
{
|
|
||||||
if (!clientModel)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// peerWidget needs a resize in case the dialog has non-default geometry
|
|
||||||
columnResizingFixer->stretchColumnWidth(PeerTableModel::Address);
|
|
||||||
|
|
||||||
// start PeerTableModel auto refresh
|
|
||||||
clientModel->getPeerTableModel()->startAutoRefresh(1000);
|
|
||||||
}
|
|
||||||
|
|
||||||
// We override the virtual resizeEvent of the QWidget to adjust tables column
|
|
||||||
// sizes as the tables width is proportional to the dialogs width.
|
|
||||||
void RPCConsole::resizeEvent(QResizeEvent *event)
|
void RPCConsole::resizeEvent(QResizeEvent *event)
|
||||||
{
|
{
|
||||||
QWidget::resizeEvent(event);
|
QWidget::resizeEvent(event);
|
||||||
|
|
||||||
if (!clientModel)
|
|
||||||
return;
|
|
||||||
|
|
||||||
columnResizingFixer->stretchColumnWidth(PeerTableModel::Address);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void RPCConsole::showEvent(QShowEvent *event)
|
void RPCConsole::showEvent(QShowEvent *event)
|
||||||
{
|
{
|
||||||
QWidget::showEvent(event);
|
QWidget::showEvent(event);
|
||||||
|
|
||||||
initPeerTable();
|
if (!clientModel)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// start PeerTableModel auto refresh
|
||||||
|
clientModel->getPeerTableModel()->startAutoRefresh();
|
||||||
}
|
}
|
||||||
|
|
||||||
void RPCConsole::hideEvent(QHideEvent *event)
|
void RPCConsole::hideEvent(QHideEvent *event)
|
||||||
|
|
|
@ -44,21 +44,6 @@ public:
|
||||||
protected:
|
protected:
|
||||||
virtual bool eventFilter(QObject* obj, QEvent *event);
|
virtual bool eventFilter(QObject* obj, QEvent *event);
|
||||||
|
|
||||||
private:
|
|
||||||
/** show detailed information on ui about selected node */
|
|
||||||
void updateNodeDetail(const CNodeCombinedStats *combinedStats);
|
|
||||||
/** initialize peer table */
|
|
||||||
void initPeerTable();
|
|
||||||
|
|
||||||
enum ColumnWidths
|
|
||||||
{
|
|
||||||
ADDRESS_COLUMN_WIDTH = 250,
|
|
||||||
MINIMUM_COLUMN_WIDTH = 120
|
|
||||||
};
|
|
||||||
|
|
||||||
/** track the node that we are currently viewing detail on in the peers tab */
|
|
||||||
CNodeCombinedStats detailNodeStats;
|
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void on_lineEdit_returnPressed();
|
void on_lineEdit_returnPressed();
|
||||||
void on_tabWidget_currentChanged(int index);
|
void on_tabWidget_currentChanged(int index);
|
||||||
|
@ -96,15 +81,23 @@ signals:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static QString FormatBytes(quint64 bytes);
|
static QString FormatBytes(quint64 bytes);
|
||||||
|
void startExecutor();
|
||||||
void setTrafficGraphRange(int mins);
|
void setTrafficGraphRange(int mins);
|
||||||
|
/** show detailed information on ui about selected node */
|
||||||
|
void updateNodeDetail(const CNodeCombinedStats *stats);
|
||||||
|
|
||||||
|
enum ColumnWidths
|
||||||
|
{
|
||||||
|
ADDRESS_COLUMN_WIDTH = 200,
|
||||||
|
SUBVERSION_COLUMN_WIDTH = 100,
|
||||||
|
PING_COLUMN_WIDTH = 80
|
||||||
|
};
|
||||||
|
|
||||||
Ui::RPCConsole *ui;
|
Ui::RPCConsole *ui;
|
||||||
ClientModel *clientModel;
|
ClientModel *clientModel;
|
||||||
QStringList history;
|
QStringList history;
|
||||||
GUIUtil::TableViewLastColumnResizingFixer *columnResizingFixer;
|
|
||||||
int historyPtr;
|
int historyPtr;
|
||||||
|
NodeId cachedNodeid;
|
||||||
void startExecutor();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // RPCCONSOLE_H
|
#endif // RPCCONSOLE_H
|
||||||
|
|
Loading…
Reference in a new issue