Upstream tarball 20080304
[amule.git] / src / StatisticsDlg.cpp
blob24cc8ba5e03f7ab553761ad6c2f993fed81f01f7
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 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 COLORREF CStatisticsDlg::getColors(unsigned num)
56 wxCHECK(num < 15, RGB(0, 0, 0));
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 COLORREF CStatisticsDlg::acrStat[cntStatColors] =
113 RGB(0,0,64), RGB(192,192,255), RGB(128, 255, 128), RGB(0, 210, 0),
114 RGB(0, 128, 0), RGB(255, 128, 128), RGB(200, 0, 0), RGB(140, 0, 0),
115 RGB(150, 150, 255), RGB(192, 0, 192), RGB(255, 255, 128), RGB(0, 0, 0),
116 RGB(128, 255, 128), RGB(0, 210, 0), RGB(0, 128, 0)
121 void CStatisticsDlg::ApplyStatsColor(int index)
123 static char aTrend[] = { 0,0, 2, 1, 0, 2, 1, 0, 1, 2, 0 };
124 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 };
125 static COScopeCtrl** apscope[] = { NULL, NULL, &pscopeDL,&pscopeDL,&pscopeDL, &pscopeUL,&pscopeUL,&pscopeUL, &pscopeConn,&pscopeConn,&pscopeConn };
127 COLORREF cr = acrStat[index];
129 int iRes = aRes[index];
130 int iTrend = aTrend[index];
131 COScopeCtrl** ppscope = apscope[index];
132 CColorFrameCtrl* ctrl;
133 switch (index) {
134 case 0: pscopeDL->SetBackgroundColor(cr);
135 pscopeUL->SetBackgroundColor(cr);
136 pscopeConn->SetBackgroundColor(cr);
137 break;
138 case 1: 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 printf("CStatisticsDlg::ApplyStatsColor: control missing (%d)\n",iRes);
148 exit(1);
150 ctrl->SetBackgroundColor(cr);
151 ctrl->SetFrameColor((COLORREF)RGB(0,0,0));
152 break;
153 default:
154 break; // ignore unknown index, like SysTray speedbar color
158 void CStatisticsDlg::UpdateStatGraphs(bool bStatsVisible, const uint32 peakconnections, const GraphUpdateInfo& update)
161 std::vector<float *> v1(3);
162 v1[0] = const_cast<float *>(&update.downloads[0]);
163 v1[1] = const_cast<float *>(&update.downloads[1]);
164 v1[2] = const_cast<float *>(&update.downloads[2]);
165 const std::vector<float *> &apfDown(v1);
166 std::vector<float *> v2(3);
167 v2[0] = const_cast<float *>(&update.uploads[0]);
168 v2[1] = const_cast<float *>(&update.uploads[1]);
169 v2[2] = const_cast<float *>(&update.uploads[2]);
170 const std::vector<float *> &apfUp(v2);
171 std::vector<float *> v3(3);
172 v3[0] = const_cast<float *>(&update.connections[0]);
173 v3[1] = const_cast<float *>(&update.connections[1]);
174 v3[2] = const_cast<float *>(&update.connections[2]);
175 const std::vector<float *> &apfConn(v3);
177 if (!bStatsVisible) {
178 pscopeDL->DelayPoints();
179 pscopeUL->DelayPoints();
180 pscopeConn->DelayPoints();
183 static unsigned nScalePrev=1;
184 unsigned nScale = (unsigned)std::ceil((float)peakconnections / pscopeConn->GetUpperLimit());
185 if (nScale != nScalePrev) {
186 nScalePrev = nScale;
187 wxStaticText* label = CastChild( ID_ACTIVEC, wxStaticText );
189 label->SetLabel(wxString::Format(_("Active connections (1:%u)"), nScale));
190 label->GetParent()->Layout();
192 pscopeConn->SetRange(0.0, (float)nScale*pscopeConn->GetUpperLimit(), 1);
194 if (!bStatsVisible)
195 return;
197 pscopeDL->AppendPoints(update.timestamp, apfDown);
198 pscopeUL->AppendPoints(update.timestamp, apfUp);
199 pscopeConn->AppendPoints(update.timestamp, apfConn);
203 void CStatisticsDlg::SetUpdatePeriod(int step)
205 // this gets called after the value in Preferences/Statistics/Update delay has been changed
206 if (step == 0) {
207 pscopeDL->Stop();
208 pscopeUL->Stop();
209 pscopeConn->Stop();
210 } else {
211 pscopeDL->Reset(step);
212 pscopeUL->Reset(step);
213 pscopeConn->Reset(step);
218 void CStatisticsDlg::ResetAveragingTime()
220 // this gets called after the value in Preferences/Statistics/time for running avg has been changed
221 pscopeDL->InvalidateGraph();
222 pscopeUL->InvalidateGraph();
226 void CStatisticsDlg::SetARange(bool SetDownload,int maxValue)
228 if ( SetDownload ) {
229 pscopeDL->SetRanges( 0, maxValue + 4 );
230 } else {
231 pscopeUL->SetRanges( 0, maxValue + 4 );
236 void CStatisticsDlg::InitTree()
238 wxTreeItemId root=stattree->AddRoot(theStats::GetTreeRoot()->GetDisplayString());
240 ShowStatistics(true);
242 #ifndef CLIENT_GUI
243 // Expand root
244 stattree->Expand(root);
246 // Expand main items
247 wxTreeItemIdValue cookie;
248 wxTreeItemId expand_it = stattree->GetFirstChild(root,cookie);
250 while(expand_it.IsOk()) {
251 stattree->Expand(expand_it);
252 // Next on this level
253 expand_it = stattree->GetNextSibling(expand_it);
255 #endif
258 void CStatisticsDlg::GetExpandedNodes(NodeIdSet& nodeset, const wxTreeItemId& root)
260 wxTreeItemIdValue cookie;
261 wxTreeItemId temp_it = stattree->GetFirstChild(root,cookie);
263 while (temp_it.IsOk()) {
264 if (stattree->IsExpanded(temp_it)) {
265 nodeset.insert(dynamic_cast<CTreeItemData*>(stattree->GetItemData(temp_it))->GetUniqueId());
267 if (stattree->ItemHasChildren(temp_it)) {
268 GetExpandedNodes(nodeset, temp_it);
270 temp_it = stattree->GetNextSibling(temp_it);
274 void CStatisticsDlg::ShowStatistics(bool init)
276 NodeIdSet ExpandedNodes;
278 // If it's not the first initialization of the tree, i.e. application startup
279 if (!init) {
280 GetExpandedNodes(ExpandedNodes, stattree->GetRootItem());
281 // Update sorting / get tree via EC
282 m_stats->UpdateStatsTree();
285 CStatTreeItemBase* treeRoot = theStats::GetTreeRoot();
286 wxTreeItemId root = stattree->GetRootItem();
287 FillTree(treeRoot, root, ExpandedNodes);
288 #ifdef CLIENT_GUI
289 if (!init) {
290 static bool firstUpdate = true;
291 if (firstUpdate) {
292 // Expand root
293 root = stattree->GetRootItem();
294 stattree->Expand(root);
296 // Expand main items
297 wxTreeItemIdValue cookie;
298 wxTreeItemId expand_it = stattree->GetFirstChild(root,cookie);
300 while(expand_it.IsOk()) {
301 stattree->Expand(expand_it);
302 // Next on this level
303 expand_it = stattree->GetNextSibling(expand_it);
305 firstUpdate = false;
308 #endif
312 void CStatisticsDlg::FillTree(CStatTreeItemBase* statssubtree, wxTreeItemId& StatsGUITree, const NodeIdSet& expandednodes)
314 wxMutexLocker lock(statssubtree->GetLock());
316 #ifndef CLIENT_GUI
317 StatTreeItemIterator temp_it = statssubtree->GetFirstVisibleChild(thePrefs::GetMaxClientVersions());
318 #else
319 StatTreeItemIterator temp_it = statssubtree->GetFirstVisibleChild();
320 #endif
322 wxTreeItemIdValue cookie;
323 wxTreeItemId temp_GUI_it = stattree->GetFirstChild(StatsGUITree,cookie);
325 while (!statssubtree->IsAtEndOfList(temp_it)) {
326 wxTreeItemId temp_item;
327 if (temp_GUI_it.IsOk()) {
328 // There's already a child there, update it.
329 stattree->SetItemText(temp_GUI_it, (*temp_it)->GetDisplayString());
330 temp_item = temp_GUI_it;
331 uint32_t uid = (*temp_it)->GetUniqueId();
332 dynamic_cast<CTreeItemData*>(stattree->GetItemData(temp_GUI_it))->SetUniqueId(uid);
333 if (expandednodes.find(uid) != expandednodes.end()) {
334 stattree->Expand(temp_GUI_it);
335 } else {
336 stattree->Collapse(temp_GUI_it);
338 temp_GUI_it = stattree->GetNextSibling(temp_GUI_it);
339 } else {
340 // No more child on GUI, add them.
341 temp_item = stattree->AppendItem(StatsGUITree,(*temp_it)->GetDisplayString());
342 stattree->SetItemData(temp_item, new CTreeItemData((*temp_it)->GetUniqueId()));
344 // Has childs?
345 if ((*temp_it)->HasVisibleChildren()) {
346 FillTree((*temp_it), temp_item, expandednodes);
347 } else {
348 stattree->DeleteChildren(temp_item);
350 statssubtree->GetNextVisibleChild(temp_it);
353 // What if GUI has more items than tree?
354 // Delete the extra items.
355 while (temp_GUI_it.IsOk()) {
356 wxTreeItemId backup_node = stattree->GetNextSibling(temp_GUI_it);
357 stattree->DeleteChildren(temp_GUI_it);
358 stattree->Delete(temp_GUI_it);
359 temp_GUI_it = backup_node;
362 // File_checked_for_headers