Remove 'estimated total blocks' field from gui
[novacoin.git] / src / qt / clientmodel.cpp
1 #include "clientmodel.h"
2 #include "guiconstants.h"
3 #include "optionsmodel.h"
4 #include "addresstablemodel.h"
5 #include "transactiontablemodel.h"
6
7 #include "alert.h"
8 #include "main.h"
9 #include "ui_interface.h"
10
11 #include <QDateTime>
12 #include <QTimer>
13
14 extern double GetPoSKernelPS();
15 extern double GetDifficulty(const CBlockIndex* blockindex);
16
17 static const int64_t nClientStartupTime = GetTime();
18
19 ClientModel::ClientModel(OptionsModel *optionsModel, QObject *parent) :
20     QObject(parent), optionsModel(optionsModel), cachedNumBlocks(0), pollTimer(0)
21 {
22     numBlocksAtStartup = -1;
23
24     pollTimer = new QTimer(this);
25     pollTimer->setInterval(MODEL_UPDATE_DELAY);
26     pollTimer->start();
27     connect(pollTimer, SIGNAL(timeout()), this, SLOT(updateTimer()));
28
29     subscribeToCoreSignals();
30 }
31
32 ClientModel::~ClientModel()
33 {
34     unsubscribeFromCoreSignals();
35 }
36
37 double ClientModel::getPoSKernelPS()
38 {
39     return GetPoSKernelPS();
40 }
41
42 double ClientModel::getDifficulty(bool fProofofStake)
43 {
44     if (fProofofStake)
45        return GetDifficulty(GetLastBlockIndex(pindexBest,true));
46     else
47        return GetDifficulty(GetLastBlockIndex(pindexBest,false));
48 }
49
50 int ClientModel::getNumConnections(uint8_t flags) const
51 {
52     LOCK(cs_vNodes);
53     if (flags == CONNECTIONS_ALL) // Shortcut if we want total
54         return (int)(vNodes.size());
55
56     int nNum = 0;
57     for(CNode* pnode :  vNodes)
58     if (flags & (pnode->fInbound ? CONNECTIONS_IN : CONNECTIONS_OUT))
59         nNum++;
60
61     return nNum;
62 }
63
64 int ClientModel::getNumBlocks() const
65 {
66     return nBestHeight;
67 }
68
69 int ClientModel::getNumBlocksAtStartup()
70 {
71     if (numBlocksAtStartup == -1) numBlocksAtStartup = getNumBlocks();
72     return numBlocksAtStartup;
73 }
74
75 quint64 ClientModel::getTotalBytesRecv() const
76 {
77     return CNode::GetTotalBytesRecv();
78 }
79
80 quint64 ClientModel::getTotalBytesSent() const
81 {
82     return CNode::GetTotalBytesSent();
83 }
84
85 QDateTime ClientModel::getLastBlockDate() const
86 {
87     if (pindexBest)
88         return QDateTime::fromTime_t(pindexBest->GetBlockTime());
89     else
90         return QDateTime::fromTime_t(1360105017); // Genesis block's time
91 }
92
93 void ClientModel::updateTimer()
94 {
95     // Some quantities (such as number of blocks) change so fast that we don't want to be notified for each change.
96     // Periodically check and update with a timer.
97     int newNumBlocks = getNumBlocks();
98
99     if(cachedNumBlocks != newNumBlocks)
100     {
101         cachedNumBlocks = newNumBlocks;
102         emit numBlocksChanged(newNumBlocks);
103     }
104
105     emit bytesChanged(getTotalBytesRecv(), getTotalBytesSent());
106 }
107
108 void ClientModel::updateNumConnections(int numConnections)
109 {
110     emit numConnectionsChanged(numConnections);
111 }
112
113 void ClientModel::updateAlert(const QString &hash, int status)
114 {
115     // Show error message notification for new alert
116     if(status == CT_NEW)
117     {
118         uint256 hash_256;
119         hash_256.SetHex(hash.toStdString());
120         CAlert alert = CAlert::getAlertByHash(hash_256);
121         if(!alert.IsNull())
122         {
123             emit error(tr("Network Alert"), QString::fromStdString(alert.strStatusBar), false);
124         }
125     }
126
127     // Emit a numBlocksChanged when the status message changes,
128     // so that the view recomputes and updates the status bar.
129     emit numBlocksChanged(getNumBlocks());
130 }
131
132 bool ClientModel::isTestNet() const
133 {
134     return fTestNet;
135 }
136
137 bool ClientModel::inInitialBlockDownload() const
138 {
139     return IsInitialBlockDownload();
140 }
141
142 QString ClientModel::getStatusBarWarnings() const
143 {
144     return QString::fromStdString(GetWarnings("statusbar"));
145 }
146
147 OptionsModel *ClientModel::getOptionsModel()
148 {
149     return optionsModel;
150 }
151
152 QString ClientModel::formatFullVersion() const
153 {
154     return QString::fromStdString(FormatFullVersion());
155 }
156
157 QString ClientModel::formatBuildDate() const
158 {
159     return QString::fromStdString(CLIENT_DATE);
160 }
161
162 QString ClientModel::clientName() const
163 {
164     return QString::fromStdString(CLIENT_NAME);
165 }
166
167 QString ClientModel::formatClientStartupTime() const
168 {
169     return QDateTime::fromTime_t(nClientStartupTime).toString();
170 }
171
172 // Handlers for core signals
173 static void NotifyBlocksChanged(ClientModel *clientmodel)
174 {
175     // This notification is too frequent. Don't trigger a signal.
176     // Don't remove it, though, as it might be useful later.
177 }
178
179 static void NotifyNumConnectionsChanged(ClientModel *clientmodel, int newNumConnections)
180 {
181     // Too noisy: OutputDebugStringF("NotifyNumConnectionsChanged %i\n", newNumConnections);
182     QMetaObject::invokeMethod(clientmodel, "updateNumConnections", Qt::QueuedConnection,
183                               Q_ARG(int, newNumConnections));
184 }
185
186 static void NotifyAlertChanged(ClientModel *clientmodel, const uint256 &hash, ChangeType status)
187 {
188     OutputDebugStringF("NotifyAlertChanged %s status=%i\n", hash.GetHex().c_str(), status);
189     QMetaObject::invokeMethod(clientmodel, "updateAlert", Qt::QueuedConnection,
190                               Q_ARG(QString, QString::fromStdString(hash.GetHex())),
191                               Q_ARG(int, status));
192 }
193
194 void ClientModel::subscribeToCoreSignals()
195 {
196     // Connect signals to client
197     uiInterface.NotifyBlocksChanged.connect(boost::bind(NotifyBlocksChanged, this));
198     uiInterface.NotifyNumConnectionsChanged.connect(boost::bind(NotifyNumConnectionsChanged, this, _1));
199     uiInterface.NotifyAlertChanged.connect(boost::bind(NotifyAlertChanged, this, _1, _2));
200 }
201
202 void ClientModel::unsubscribeFromCoreSignals()
203 {
204     // Disconnect signals from client
205     uiInterface.NotifyBlocksChanged.disconnect(boost::bind(NotifyBlocksChanged, this));
206     uiInterface.NotifyNumConnectionsChanged.disconnect(boost::bind(NotifyNumConnectionsChanged, this, _1));
207     uiInterface.NotifyAlertChanged.disconnect(boost::bind(NotifyAlertChanged, this, _1, _2));
208 }