3b3af1ed1002d3bb925fabe66915457e71f26c6a
[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 static const int64 nClientStartupTime = GetTime();
15
16 ClientModel::ClientModel(OptionsModel *optionsModel, QObject *parent) :
17     QObject(parent), optionsModel(optionsModel),
18     cachedNumBlocks(0), cachedNumBlocksOfPeers(0), pollTimer(0)
19 {
20     numBlocksAtStartup = -1;
21
22     pollTimer = new QTimer(this);
23     pollTimer->setInterval(MODEL_UPDATE_DELAY);
24     pollTimer->start();
25     connect(pollTimer, SIGNAL(timeout()), this, SLOT(updateTimer()));
26
27     subscribeToCoreSignals();
28 }
29
30 ClientModel::~ClientModel()
31 {
32     unsubscribeFromCoreSignals();
33 }
34
35 int ClientModel::getNumConnections() const
36 {
37     return vNodes.size();
38 }
39
40 int ClientModel::getNumBlocks() const
41 {
42     return nBestHeight;
43 }
44
45 int ClientModel::getNumBlocksAtStartup()
46 {
47     if (numBlocksAtStartup == -1) numBlocksAtStartup = getNumBlocks();
48     return numBlocksAtStartup;
49 }
50
51 QDateTime ClientModel::getLastBlockDate() const
52 {
53     if (pindexBest)
54         return QDateTime::fromTime_t(pindexBest->GetBlockTime());
55     else
56         return QDateTime::fromTime_t(1360105017); // Genesis block's time
57 }
58
59 void ClientModel::updateTimer()
60 {
61     // Some quantities (such as number of blocks) change so fast that we don't want to be notified for each change.
62     // Periodically check and update with a timer.
63     int newNumBlocks = getNumBlocks();
64     int newNumBlocksOfPeers = getNumBlocksOfPeers();
65
66     if(cachedNumBlocks != newNumBlocks || cachedNumBlocksOfPeers != newNumBlocksOfPeers)
67     {
68         cachedNumBlocks = newNumBlocks;
69         cachedNumBlocksOfPeers = newNumBlocksOfPeers;
70
71         emit numBlocksChanged(newNumBlocks, newNumBlocksOfPeers);
72     }
73 }
74
75 void ClientModel::updateNumConnections(int numConnections)
76 {
77     emit numConnectionsChanged(numConnections);
78 }
79
80 void ClientModel::updateAlert(const QString &hash, int status)
81 {
82     // Show error message notification for new alert
83     if(status == CT_NEW)
84     {
85         uint256 hash_256;
86         hash_256.SetHex(hash.toStdString());
87         CAlert alert = CAlert::getAlertByHash(hash_256);
88         if(!alert.IsNull())
89         {
90             emit error(tr("Network Alert"), QString::fromStdString(alert.strStatusBar), false);
91         }
92     }
93
94     // Emit a numBlocksChanged when the status message changes,
95     // so that the view recomputes and updates the status bar.
96     emit numBlocksChanged(getNumBlocks(), getNumBlocksOfPeers());
97 }
98
99 bool ClientModel::isTestNet() const
100 {
101     return fTestNet;
102 }
103
104 bool ClientModel::inInitialBlockDownload() const
105 {
106     return IsInitialBlockDownload();
107 }
108
109 int ClientModel::getNumBlocksOfPeers() const
110 {
111     return GetNumBlocksOfPeers();
112 }
113
114 QString ClientModel::getStatusBarWarnings() const
115 {
116     return QString::fromStdString(GetWarnings("statusbar"));
117 }
118
119 OptionsModel *ClientModel::getOptionsModel()
120 {
121     return optionsModel;
122 }
123
124 QString ClientModel::formatFullVersion() const
125 {
126     return QString::fromStdString(FormatFullVersion());
127 }
128
129 QString ClientModel::formatBuildDate() const
130 {
131     return QString::fromStdString(CLIENT_DATE);
132 }
133
134 QString ClientModel::clientName() const
135 {
136     return QString::fromStdString(CLIENT_NAME);
137 }
138
139 QString ClientModel::formatClientStartupTime() const
140 {
141     return QDateTime::fromTime_t(nClientStartupTime).toString();
142 }
143
144 // Handlers for core signals
145 static void NotifyBlocksChanged(ClientModel *clientmodel)
146 {
147     // This notification is too frequent. Don't trigger a signal.
148     // Don't remove it, though, as it might be useful later.
149 }
150
151 static void NotifyNumConnectionsChanged(ClientModel *clientmodel, int newNumConnections)
152 {
153     // Too noisy: OutputDebugStringF("NotifyNumConnectionsChanged %i\n", newNumConnections);
154     QMetaObject::invokeMethod(clientmodel, "updateNumConnections", Qt::QueuedConnection,
155                               Q_ARG(int, newNumConnections));
156 }
157
158 static void NotifyAlertChanged(ClientModel *clientmodel, const uint256 &hash, ChangeType status)
159 {
160     OutputDebugStringF("NotifyAlertChanged %s status=%i\n", hash.GetHex().c_str(), status);
161     QMetaObject::invokeMethod(clientmodel, "updateAlert", Qt::QueuedConnection,
162                               Q_ARG(QString, QString::fromStdString(hash.GetHex())),
163                               Q_ARG(int, status));
164 }
165
166 void ClientModel::subscribeToCoreSignals()
167 {
168     // Connect signals to client
169     uiInterface.NotifyBlocksChanged.connect(boost::bind(NotifyBlocksChanged, this));
170     uiInterface.NotifyNumConnectionsChanged.connect(boost::bind(NotifyNumConnectionsChanged, this, _1));
171     uiInterface.NotifyAlertChanged.connect(boost::bind(NotifyAlertChanged, this, _1, _2));
172 }
173
174 void ClientModel::unsubscribeFromCoreSignals()
175 {
176     // Disconnect signals from client
177     uiInterface.NotifyBlocksChanged.disconnect(boost::bind(NotifyBlocksChanged, this));
178     uiInterface.NotifyNumConnectionsChanged.disconnect(boost::bind(NotifyNumConnectionsChanged, this, _1));
179     uiInterface.NotifyAlertChanged.disconnect(boost::bind(NotifyAlertChanged, this, _1, _2));
180 }