2 // This file is part of the aMule Project.
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 )
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
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.
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
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
; }
52 // CStatisticsDlg panel
54 COLORREF
CStatisticsDlg::getColors(unsigned num
)
56 wxCHECK(num
< 15, RGB(0, 0, 0));
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
);
80 CStatisticsDlg::~CStatisticsDlg()
85 void CStatisticsDlg::Init()
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
;
134 case 0: pscopeDL
->SetBackgroundColor(cr
);
135 pscopeUL
->SetBackgroundColor(cr
);
136 pscopeConn
->SetBackgroundColor(cr
);
138 case 1: pscopeDL
->SetGridColor(cr
);
139 pscopeUL
->SetGridColor(cr
);
140 pscopeConn
->SetGridColor(cr
);
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
);
150 ctrl
->SetBackgroundColor(cr
);
151 ctrl
->SetFrameColor((COLORREF
)RGB(0,0,0));
154 break; // ignore unknown index, like SysTray speedbar color
158 void CStatisticsDlg::UpdateStatGraphs(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 (!IsShownOnScreen()) {
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
) {
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);
195 if (!IsShownOnScreen()) {
199 pscopeDL
->AppendPoints(update
.timestamp
, apfDown
);
200 pscopeUL
->AppendPoints(update
.timestamp
, apfUp
);
201 pscopeConn
->AppendPoints(update
.timestamp
, apfConn
);
205 void CStatisticsDlg::SetUpdatePeriod(int step
)
207 // this gets called after the value in Preferences/Statistics/Update delay has been changed
213 pscopeDL
->Reset(step
);
214 pscopeUL
->Reset(step
);
215 pscopeConn
->Reset(step
);
220 void CStatisticsDlg::ResetAveragingTime()
222 // this gets called after the value in Preferences/Statistics/time for running avg has been changed
223 pscopeDL
->InvalidateGraph();
224 pscopeUL
->InvalidateGraph();
228 void CStatisticsDlg::SetARange(bool SetDownload
,int maxValue
)
231 pscopeDL
->SetRanges( 0, maxValue
+ 4 );
233 pscopeUL
->SetRanges( 0, maxValue
+ 4 );
238 void CStatisticsDlg::InitTree()
240 wxTreeItemId root
=stattree
->AddRoot(theStats::GetTreeRoot()->GetDisplayString());
242 ShowStatistics(true);
246 stattree
->Expand(root
);
249 wxTreeItemIdValue cookie
;
250 wxTreeItemId expand_it
= stattree
->GetFirstChild(root
,cookie
);
252 while(expand_it
.IsOk()) {
253 stattree
->Expand(expand_it
);
254 // Next on this level
255 expand_it
= stattree
->GetNextSibling(expand_it
);
260 void CStatisticsDlg::GetExpandedNodes(NodeIdSet
& nodeset
, const wxTreeItemId
& root
)
262 wxTreeItemIdValue cookie
;
263 wxTreeItemId temp_it
= stattree
->GetFirstChild(root
,cookie
);
265 while (temp_it
.IsOk()) {
266 if (stattree
->IsExpanded(temp_it
)) {
267 nodeset
.insert(dynamic_cast<CTreeItemData
*>(stattree
->GetItemData(temp_it
))->GetUniqueId());
269 if (stattree
->ItemHasChildren(temp_it
)) {
270 GetExpandedNodes(nodeset
, temp_it
);
272 temp_it
= stattree
->GetNextSibling(temp_it
);
276 void CStatisticsDlg::ShowStatistics(bool init
)
278 NodeIdSet ExpandedNodes
;
280 // If it's not the first initialization of the tree, i.e. application startup
282 GetExpandedNodes(ExpandedNodes
, stattree
->GetRootItem());
283 // Update sorting / get tree via EC
284 m_stats
->UpdateStatsTree();
287 CStatTreeItemBase
* treeRoot
= theStats::GetTreeRoot();
288 wxTreeItemId root
= stattree
->GetRootItem();
289 FillTree(treeRoot
, root
, ExpandedNodes
);
292 static bool firstUpdate
= true;
295 root
= stattree
->GetRootItem();
296 stattree
->Expand(root
);
299 wxTreeItemIdValue cookie
;
300 wxTreeItemId expand_it
= stattree
->GetFirstChild(root
,cookie
);
302 while(expand_it
.IsOk()) {
303 stattree
->Expand(expand_it
);
304 // Next on this level
305 expand_it
= stattree
->GetNextSibling(expand_it
);
314 void CStatisticsDlg::FillTree(CStatTreeItemBase
* statssubtree
, wxTreeItemId
& StatsGUITree
, const NodeIdSet
& expandednodes
)
316 wxMutexLocker
lock(statssubtree
->GetLock());
319 StatTreeItemIterator temp_it
= statssubtree
->GetFirstVisibleChild(thePrefs::GetMaxClientVersions());
321 StatTreeItemIterator temp_it
= statssubtree
->GetFirstVisibleChild();
324 wxTreeItemIdValue cookie
;
325 wxTreeItemId temp_GUI_it
= stattree
->GetFirstChild(StatsGUITree
,cookie
);
327 while (!statssubtree
->IsAtEndOfList(temp_it
)) {
328 wxTreeItemId temp_item
;
329 if (temp_GUI_it
.IsOk()) {
330 // There's already a child there, update it.
331 stattree
->SetItemText(temp_GUI_it
, (*temp_it
)->GetDisplayString());
332 temp_item
= temp_GUI_it
;
333 uint32_t uid
= (*temp_it
)->GetUniqueId();
334 dynamic_cast<CTreeItemData
*>(stattree
->GetItemData(temp_GUI_it
))->SetUniqueId(uid
);
335 if (expandednodes
.find(uid
) != expandednodes
.end()) {
336 stattree
->Expand(temp_GUI_it
);
338 stattree
->Collapse(temp_GUI_it
);
340 temp_GUI_it
= stattree
->GetNextSibling(temp_GUI_it
);
342 // No more child on GUI, add them.
343 temp_item
= stattree
->AppendItem(StatsGUITree
,(*temp_it
)->GetDisplayString());
344 stattree
->SetItemData(temp_item
, new CTreeItemData((*temp_it
)->GetUniqueId()));
347 if ((*temp_it
)->HasVisibleChildren()) {
348 FillTree((*temp_it
), temp_item
, expandednodes
);
350 stattree
->DeleteChildren(temp_item
);
352 statssubtree
->GetNextVisibleChild(temp_it
);
355 // What if GUI has more items than tree?
356 // Delete the extra items.
357 while (temp_GUI_it
.IsOk()) {
358 wxTreeItemId backup_node
= stattree
->GetNextSibling(temp_GUI_it
);
359 stattree
->DeleteChildren(temp_GUI_it
);
360 stattree
->Delete(temp_GUI_it
);
361 temp_GUI_it
= backup_node
;
364 // File_checked_for_headers