Upstream tarball 9964
[amule.git] / src / StatisticsDlg.cpp
blobe1edabbb15ebdd871d8aee615598e5554068749c
1 //
2 // This file is part of the aMule Project.
3 //
4 // Copyright (c) 2003-2008 aMule Team ( admin@amule.org / http://www.amule.org )
5 // Copyright (c) 2002-2008 Merkur ( devs@emule-project.net / http://www.emule-project.net )
6 //
7 // Any parts of this program derived from the xMule, lMule or eMule project,
8 // or contributed by third-party developers are copyrighted by their
9 // respective authors.
11 // This program is free software; you can redistribute it and/or modify
12 // it under the terms of the GNU General Public License as published by
13 // the Free Software Foundation; either version 2 of the License, or
14 // (at your option) any later version.
16 // This program is distributed in the hope that it will be useful,
17 // but WITHOUT ANY WARRANTY; without even the implied warranty of
18 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 // GNU General Public License for more details.
20 //
21 // You should have received a copy of the GNU General Public License
22 // along with this program; if not, write to the Free Software
23 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
27 #include <cmath> // Needed for std::ceil
29 #include "ColorFrameCtrl.h" // Needed for CColorFrameCtrl
30 #include "OtherFunctions.h" // Needed for CastChild()
31 #include "OScopeCtrl.h" // Needed for COScopeCtrl
32 #include "Preferences.h" // Needed for thePrefs
33 #include "muuli_wdr.h" // Needed for statsDlg()
34 #include "StatisticsDlg.h" // Interface declarations
37 class CTreeItemData : public wxTreeItemData
39 public:
40 explicit CTreeItemData(uint32_t uniqueid)
41 : m_uniqueid(uniqueid)
44 uint32_t GetUniqueId() const throw() { return m_uniqueid; }
45 void SetUniqueId(uint32_t val) throw() { m_uniqueid = val; }
47 private:
48 uint32_t m_uniqueid;
52 // CStatisticsDlg panel
54 const wxColour& CStatisticsDlg::getColors(unsigned num)
56 wxCHECK(num < 15, *wxBLACK);
58 return acrStat[num];
61 CStatisticsDlg::CStatisticsDlg(wxWindow* pParent, CStatistics* stats)
62 : wxPanel(pParent, -1)
64 wxSizer* content=statsDlg(this,TRUE);
65 content->Show(this,TRUE);
67 pscopeDL = CastChild( wxT("dloadScope"), COScopeCtrl );
68 pscopeDL->graph_type = GRAPH_DOWN;
69 pscopeUL = CastChild( wxT("uloadScope"), COScopeCtrl );
70 pscopeUL->graph_type = GRAPH_UP;
71 pscopeConn = CastChild( wxT("otherScope"), COScopeCtrl );
72 pscopeConn->graph_type = GRAPH_CONN;
73 stattree = CastChild( wxT("statTree"), wxTreeCtrl );
75 m_stats = stats;
80 CStatisticsDlg::~CStatisticsDlg()
85 void CStatisticsDlg::Init()
87 InitGraphs();
88 InitTree();
92 void CStatisticsDlg::InitGraphs()
94 // called after preferences get initialised
95 for (int index=0; index<=10; ++index) {
96 ApplyStatsColor(index);
99 pscopeDL->SetRanges(0.0, (float)(thePrefs::GetMaxGraphDownloadRate()+4));
100 pscopeDL->SetYUnits(_("kB/s"));
101 pscopeUL->SetRanges(0.0, (float)(thePrefs::GetMaxGraphUploadRate()+4));
102 pscopeUL->SetYUnits(_("kB/s"));
103 pscopeConn->SetRanges(0.0, (float)(thePrefs::GetStatsMax()));
104 pscopeConn->SetYUnits(wxEmptyString);
106 SetUpdatePeriod(thePrefs::GetTrafficOMeterInterval());
110 // this array is now used to store the current color settings and to define the defaults
111 wxColour CStatisticsDlg::acrStat[cntStatColors] =
113 wxColour(0,0,64), wxColour(192,192,255), wxColour(128, 255, 128), wxColour(0, 210, 0),
114 wxColour(0, 128, 0), wxColour(255, 128, 128), wxColour(200, 0, 0), wxColour(140, 0, 0),
115 wxColour(150, 150, 255), wxColour(192, 0, 192), wxColour(255, 255, 128), wxColour(0, 0, 0),
116 wxColour(128, 255, 128), wxColour(0, 210, 0), wxColour(0, 128, 0)
119 void CStatisticsDlg::ApplyStatsColor(int index)
121 static char aTrend[] = { 0,0, 2, 1, 0, 2, 1, 0, 1, 2, 0 };
122 static int aRes[] = { 0,0, IDC_C0,IDC_C0_3,IDC_C0_2, IDC_C1,IDC_C1_3,IDC_C1_2, IDC_S0,IDC_S3,IDC_S1 };
123 static COScopeCtrl** apscope[] = { NULL, NULL, &pscopeDL,&pscopeDL,&pscopeDL, &pscopeUL,&pscopeUL,&pscopeUL, &pscopeConn,&pscopeConn,&pscopeConn };
125 const wxColour& cr = acrStat[index];
127 int iRes = aRes[index];
128 int iTrend = aTrend[index];
129 COScopeCtrl** ppscope = apscope[index];
130 CColorFrameCtrl* ctrl;
131 switch (index) {
132 case 0:
133 pscopeDL->SetBackgroundColor(cr);
134 pscopeUL->SetBackgroundColor(cr);
135 pscopeConn->SetBackgroundColor(cr);
136 break;
137 case 1:
138 pscopeDL->SetGridColor(cr);
139 pscopeUL->SetGridColor(cr);
140 pscopeConn->SetGridColor(cr);
141 break;
142 case 2: case 3: case 4:
143 case 5: case 6: case 7:
144 case 8: case 9: case 10:
145 (*ppscope)->SetPlotColor(cr, iTrend);
146 if ((ctrl = CastChild(iRes, CColorFrameCtrl)) == NULL) {
147 throw wxString::Format(wxT("CStatisticsDlg::ApplyStatsColor: control missing (%d)\n"),iRes);
149 ctrl->SetBackgroundBrushColour(cr);
150 ctrl->SetFrameBrushColour(*wxBLACK);
151 break;
152 default:
153 break; // ignore unknown index, like SysTray speedbar color
157 void CStatisticsDlg::UpdateStatGraphs(const uint32 peakconnections, const GraphUpdateInfo& update)
160 std::vector<float *> v1(3);
161 v1[0] = const_cast<float *>(&update.downloads[0]);
162 v1[1] = const_cast<float *>(&update.downloads[1]);
163 v1[2] = const_cast<float *>(&update.downloads[2]);
164 const std::vector<float *> &apfDown(v1);
165 std::vector<float *> v2(3);
166 v2[0] = const_cast<float *>(&update.uploads[0]);
167 v2[1] = const_cast<float *>(&update.uploads[1]);
168 v2[2] = const_cast<float *>(&update.uploads[2]);
169 const std::vector<float *> &apfUp(v2);
170 std::vector<float *> v3(3);
171 v3[0] = const_cast<float *>(&update.connections[0]);
172 v3[1] = const_cast<float *>(&update.connections[1]);
173 v3[2] = const_cast<float *>(&update.connections[2]);
174 const std::vector<float *> &apfConn(v3);
176 if (!IsShownOnScreen()) {
177 pscopeDL->DelayPoints();
178 pscopeUL->DelayPoints();
179 pscopeConn->DelayPoints();
182 static unsigned nScalePrev=1;
183 unsigned nScale = (unsigned)std::ceil((float)peakconnections / pscopeConn->GetUpperLimit());
184 if (nScale != nScalePrev) {
185 nScalePrev = nScale;
186 wxStaticText* label = CastChild( ID_ACTIVEC, wxStaticText );
188 label->SetLabel(wxString::Format(_("Active connections (1:%u)"), nScale));
189 label->GetParent()->Layout();
191 pscopeConn->SetRange(0.0, (float)nScale*pscopeConn->GetUpperLimit(), 1);
194 if (!IsShownOnScreen()) {
195 return;
198 pscopeDL->AppendPoints(update.timestamp, apfDown);
199 pscopeUL->AppendPoints(update.timestamp, apfUp);
200 pscopeConn->AppendPoints(update.timestamp, apfConn);
204 void CStatisticsDlg::SetUpdatePeriod(int step)
206 // this gets called after the value in Preferences/Statistics/Update delay has been changed
207 if (step == 0) {
208 pscopeDL->Stop();
209 pscopeUL->Stop();
210 pscopeConn->Stop();
211 } else {
212 pscopeDL->Reset(step);
213 pscopeUL->Reset(step);
214 pscopeConn->Reset(step);
219 void CStatisticsDlg::ResetAveragingTime()
221 // this gets called after the value in Preferences/Statistics/time for running avg has been changed
222 pscopeDL->InvalidateGraph();
223 pscopeUL->InvalidateGraph();
227 void CStatisticsDlg::SetARange(bool SetDownload,int maxValue)
229 if ( SetDownload ) {
230 pscopeDL->SetRanges( 0, maxValue + 4 );
231 } else {
232 pscopeUL->SetRanges( 0, maxValue + 4 );
237 void CStatisticsDlg::InitTree()
239 wxTreeItemId root=stattree->AddRoot(theStats::GetTreeRoot()->GetDisplayString());
241 ShowStatistics(true);
243 #ifndef CLIENT_GUI
244 // Expand root
245 stattree->Expand(root);
247 // Expand main items
248 wxTreeItemIdValue cookie;
249 wxTreeItemId expand_it = stattree->GetFirstChild(root,cookie);
251 while(expand_it.IsOk()) {
252 stattree->Expand(expand_it);
253 // Next on this level
254 expand_it = stattree->GetNextSibling(expand_it);
256 #endif
259 void CStatisticsDlg::GetExpandedNodes(NodeIdSet& nodeset, const wxTreeItemId& root)
261 wxTreeItemIdValue cookie;
262 wxTreeItemId temp_it = stattree->GetFirstChild(root,cookie);
264 while (temp_it.IsOk()) {
265 if (stattree->IsExpanded(temp_it)) {
266 nodeset.insert(dynamic_cast<CTreeItemData*>(stattree->GetItemData(temp_it))->GetUniqueId());
268 if (stattree->ItemHasChildren(temp_it)) {
269 GetExpandedNodes(nodeset, temp_it);
271 temp_it = stattree->GetNextSibling(temp_it);
275 void CStatisticsDlg::ShowStatistics(bool init)
277 NodeIdSet ExpandedNodes;
279 // If it's not the first initialization of the tree, i.e. application startup
280 if (!init) {
281 GetExpandedNodes(ExpandedNodes, stattree->GetRootItem());
282 // Update sorting / get tree via EC
283 m_stats->UpdateStatsTree();
286 CStatTreeItemBase* treeRoot = theStats::GetTreeRoot();
287 wxTreeItemId root = stattree->GetRootItem();
288 FillTree(treeRoot, root, ExpandedNodes);
289 #ifdef CLIENT_GUI
290 if (!init) {
291 static bool firstUpdate = true;
292 if (firstUpdate) {
293 // Expand root
294 root = stattree->GetRootItem();
295 stattree->Expand(root);
297 // Expand main items
298 wxTreeItemIdValue cookie;
299 wxTreeItemId expand_it = stattree->GetFirstChild(root,cookie);
301 while(expand_it.IsOk()) {
302 stattree->Expand(expand_it);
303 // Next on this level
304 expand_it = stattree->GetNextSibling(expand_it);
306 firstUpdate = false;
309 #endif
313 void CStatisticsDlg::FillTree(CStatTreeItemBase* statssubtree, wxTreeItemId& StatsGUITree, const NodeIdSet& expandednodes)
315 wxMutexLocker lock(statssubtree->GetLock());
317 #ifndef CLIENT_GUI
318 StatTreeItemIterator temp_it = statssubtree->GetFirstVisibleChild(thePrefs::GetMaxClientVersions());
319 #else
320 StatTreeItemIterator temp_it = statssubtree->GetFirstVisibleChild();
321 #endif
323 wxTreeItemIdValue cookie;
324 wxTreeItemId temp_GUI_it = stattree->GetFirstChild(StatsGUITree,cookie);
326 while (!statssubtree->IsAtEndOfList(temp_it)) {
327 wxTreeItemId temp_item;
328 if (temp_GUI_it.IsOk()) {
329 // There's already a child there, update it.
330 stattree->SetItemText(temp_GUI_it, (*temp_it)->GetDisplayString());
331 temp_item = temp_GUI_it;
332 uint32_t uid = (*temp_it)->GetUniqueId();
333 dynamic_cast<CTreeItemData*>(stattree->GetItemData(temp_GUI_it))->SetUniqueId(uid);
334 if (expandednodes.find(uid) != expandednodes.end()) {
335 stattree->Expand(temp_GUI_it);
336 } else {
337 stattree->Collapse(temp_GUI_it);
339 temp_GUI_it = stattree->GetNextSibling(temp_GUI_it);
340 } else {
341 // No more child on GUI, add them.
342 temp_item = stattree->AppendItem(StatsGUITree,(*temp_it)->GetDisplayString());
343 stattree->SetItemData(temp_item, new CTreeItemData((*temp_it)->GetUniqueId()));
345 // Has childs?
346 if ((*temp_it)->HasVisibleChildren()) {
347 FillTree((*temp_it), temp_item, expandednodes);
348 } else {
349 stattree->DeleteChildren(temp_item);
351 statssubtree->GetNextVisibleChild(temp_it);
354 // What if GUI has more items than tree?
355 // Delete the extra items.
356 while (temp_GUI_it.IsOk()) {
357 wxTreeItemId backup_node = stattree->GetNextSibling(temp_GUI_it);
358 stattree->DeleteChildren(temp_GUI_it);
359 stattree->Delete(temp_GUI_it);
360 temp_GUI_it = backup_node;
363 // File_checked_for_headers