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