PageRenderTime 117ms CodeModel.GetById 6ms app.highlight 95ms RepoModel.GetById 1ms app.codeStats 1ms

/srchybrid/StatisticsDlg.cpp

https://github.com/acat/emule
C++ | 3498 lines | 2949 code | 277 blank | 272 comment | 646 complexity | d574d37a32225f8da8c164e512d36778 MD5 | raw file

Large files files are truncated, but you can click here to view the full file

   1//this file is part of eMule
   2//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net )
   3//
   4//This program is free software; you can redistribute it and/or
   5//modify it under the terms of the GNU General Public License
   6//as published by the Free Software Foundation; either
   7//version 2 of the License, or (at your option) any later version.
   8//
   9//This program is distributed in the hope that it will be useful,
  10//but WITHOUT ANY WARRANTY; without even the implied warranty of
  11//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12//GNU General Public License for more details.
  13//
  14//You should have received a copy of the GNU General Public License
  15//along with this program; if not, write to the Free Software
  16//Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  17#include "stdafx.h"
  18#include "emule.h"
  19#include "StatisticsDlg.h"
  20#include "UploadQueue.h"
  21#include "Statistics.h"
  22#include "emuledlg.h"
  23#include "OtherFunctions.h"
  24#include "WebServer.h"
  25#include "DownloadQueue.h"
  26#include "ClientList.h"
  27#include "Preferences.h"
  28#include "ListenSocket.h"
  29#include "ServerList.h"
  30#include "SharedFileList.h"
  31#include "UpDownClient.h"
  32#include "UserMsgs.h"
  33#include "HelpIDs.h"
  34#include "Kademlia/Kademlia/kademlia.h"
  35#include "Kademlia/Kademlia/Prefs.h"
  36#include "kademlia/kademlia/UDPFirewallTester.h"
  37
  38
  39#ifdef _DEBUG
  40#define new DEBUG_NEW
  41#undef THIS_FILE
  42static char THIS_FILE[] = __FILE__;
  43#endif
  44
  45#ifdef _DEBUG
  46extern _CRT_ALLOC_HOOK g_pfnPrevCrtAllocHook;
  47#endif
  48
  49
  50// CStatisticsDlg dialog
  51
  52IMPLEMENT_DYNAMIC(CStatisticsDlg, CDialog)
  53
  54BEGIN_MESSAGE_MAP(CStatisticsDlg, CResizableDialog)
  55	ON_WM_SHOWWINDOW()
  56	ON_WM_SIZE()
  57	ON_BN_CLICKED(IDC_BNMENU, OnMenuButtonClicked)	
  58	ON_WM_SYSCOLORCHANGE()
  59	ON_WM_CTLCOLOR()
  60	ON_STN_DBLCLK(IDC_SCOPE_D, OnStnDblclickScopeD)
  61	ON_STN_DBLCLK(IDC_SCOPE_U, OnStnDblclickScopeU)
  62	ON_STN_DBLCLK(IDC_STATSSCOPE, OnStnDblclickStatsscope)
  63	ON_MESSAGE(UM_OSCOPEPOSITION, OnOscopePositionMsg)
  64	ON_WM_HELPINFO()
  65END_MESSAGE_MAP()
  66
  67CStatisticsDlg::CStatisticsDlg(CWnd* pParent /*=NULL*/)
  68	: CResizableDialog(CStatisticsDlg::IDD, pParent)
  69	, m_DownloadOMeter(3)
  70	, m_Statistics(4)
  71	, m_UploadOMeter(5)
  72
  73{
  74	m_oldcx=0;
  75	m_oldcy=0;
  76	m_TimeToolTips = NULL;
  77}
  78
  79CStatisticsDlg::~CStatisticsDlg()
  80{
  81	delete m_TimeToolTips;
  82
  83#ifdef _DEBUG
  84	POSITION pos = blockFiles.GetStartPosition();
  85	while (pos != NULL) 
  86	{
  87		const unsigned char* fileName;
  88		HTREEITEM* pTag;
  89		blockFiles.GetNextAssoc(pos, fileName, pTag);
  90		delete pTag;
  91	}
  92#endif
  93}
  94
  95void CStatisticsDlg::DoDataExchange(CDataExchange* pDX)
  96{
  97	CResizableDialog::DoDataExchange(pDX);
  98	DDX_Control(pDX, IDC_STATTREE, stattree);
  99}
 100
 101void CStatisticsDlg::OnSysColorChange()
 102{
 103	CResizableDialog::OnSysColorChange();
 104	SetAllIcons();
 105}
 106
 107void CStatisticsDlg::SetAllIcons()
 108{
 109	InitWindowStyles(this);
 110
 111	CImageList iml;
 112	iml.Create(16, 16, theApp.m_iDfltImageListColorFlags | ILC_MASK, 0, 1);
 113	iml.Add(CTempIconLoader(_T("StatsGeneric")));			// Dots & Arrow (Default icon for stats)
 114	iml.Add(CTempIconLoader(_T("TransferUpDown")));			// Transfer
 115	iml.Add(CTempIconLoader(_T("Connection")));				// Connection
 116	iml.Add(CTempIconLoader(_T("StatsClients")));			// Clients
 117	iml.Add(CTempIconLoader(_T("Server")));					// Server
 118	iml.Add(CTempIconLoader(_T("SharedFiles")));			// Shared Files
 119	iml.Add(CTempIconLoader(_T("Upload")));					// Transfer > Upload
 120	iml.Add(CTempIconLoader(_T("Download")));				// Transfer > Download
 121	iml.Add(CTempIconLoader(_T("StatsDetail")));			// Session Sections
 122	iml.Add(CTempIconLoader(_T("StatsCumulative")));		// Cumulative Sections
 123	iml.Add(CTempIconLoader(_T("StatsRecords")));			// Records
 124	iml.Add(CTempIconLoader(_T("TransferUpDown")));			// Connection > General
 125	iml.Add(CTempIconLoader(_T("StatsTime")));				// Time Section
 126	iml.Add(CTempIconLoader(_T("StatsProjected")));			// Time > Averages and Projections
 127	iml.Add(CTempIconLoader(_T("StatsDay")));				// Time > Averages and Projections > Daily
 128	iml.Add(CTempIconLoader(_T("StatsMonth")));				// Time > Averages and Projections > Monthly
 129	iml.Add(CTempIconLoader(_T("StatsYear")));				// Time > Averages and Projections > Yearly
 130	iml.Add(CTempIconLoader(_T("HardDisk")));				// Diskspace
 131	stattree.SetImageList(&iml, TVSIL_NORMAL);
 132	imagelistStatTree.DeleteImageList();
 133	imagelistStatTree.Attach(iml.Detach());
 134
 135	COLORREF crBk = GetSysColor(COLOR_WINDOW);
 136	COLORREF crFg = GetSysColor(COLOR_WINDOWTEXT);
 137
 138	theApp.LoadSkinColorAlt(_T("StatisticsTvBk"), _T("DefLvBk"), crBk);
 139	theApp.LoadSkinColorAlt(_T("StatisticsTvFg"), _T("DefLvFg"), crFg);
 140
 141	stattree.SetBkColor(crBk);
 142	stattree.SetTextColor(crFg);
 143	// can't use 'TVM_SETLINECOLOR' because the color may not match that one used in "StatsGeneric" item image.
 144	//stattree.SendMessage(TVM_SETLINECOLOR, 0, (LPARAM)crFg);
 145}
 146
 147BOOL CStatisticsDlg::OnInitDialog()
 148{
 149	CResizableDialog::OnInitDialog();
 150	EnableWindow(FALSE);
 151	SetAllIcons();
 152	m_bTreepaneHidden=false;
 153
 154	if (theApp.m_fontSymbol.m_hObject)
 155	{
 156		GetDlgItem(IDC_BNMENU)->SetFont(&theApp.m_fontSymbol);
 157		GetDlgItem(IDC_BNMENU)->SetWindowText(_T("6")); // show a down-arrow
 158	}
 159
 160	// Win98: Explicitly set to Unicode to receive Unicode notifications.
 161	stattree.SendMessage(CCM_SETUNICODEFORMAT, TRUE);
 162	if (thePrefs.GetUseSystemFontForMainControls())
 163		stattree.SendMessage(WM_SETFONT, NULL, FALSE);
 164	CreateMyTree();
 165
 166	// Setup download-scope
 167	CRect rcDown;
 168	GetDlgItem(IDC_SCOPE_D)->GetWindowRect(rcDown);
 169	GetDlgItem(IDC_SCOPE_D)->DestroyWindow();
 170	ScreenToClient(rcDown);
 171	m_DownloadOMeter.Create(WS_VISIBLE | WS_CHILD, rcDown, this, IDC_SCOPE_D);
 172	SetARange(true, thePrefs.GetMaxGraphDownloadRate());
 173	m_DownloadOMeter.SetYUnits(GetResString(IDS_KBYTESPERSEC));
 174	
 175	// Setup upload-scope
 176	CRect rcUp;
 177	GetDlgItem(IDC_SCOPE_U)->GetWindowRect(rcUp);
 178	GetDlgItem(IDC_SCOPE_U)->DestroyWindow();
 179	ScreenToClient(rcUp);
 180	// compensate rounding errors due to dialog units, make each of the 3 panes with same height
 181	rcUp.top = rcDown.bottom + 4;
 182	rcUp.bottom = rcUp.top + rcDown.Height();
 183	m_UploadOMeter.Create(WS_VISIBLE | WS_CHILD, rcUp, this, IDC_SCOPE_U);
 184	SetARange(false, thePrefs.GetMaxGraphUploadRate(true));
 185	m_UploadOMeter.SetYUnits(GetResString(IDS_KBYTESPERSEC));
 186	
 187	// Setup additional graph-scope
 188	CRect rcConn;
 189	GetDlgItem(IDC_STATSSCOPE)->GetWindowRect(rcConn);
 190	GetDlgItem(IDC_STATSSCOPE)->DestroyWindow();
 191	ScreenToClient(rcConn);
 192	// compensate rounding errors due to dialog units, make each of the 3 panes with same height
 193	rcConn.top = rcUp.bottom + 4;
 194	rcConn.bottom = rcConn.top + rcDown.Height();
 195	m_Statistics.Create(WS_VISIBLE | WS_CHILD, rcConn, this, IDC_STATSSCOPE);
 196	m_Statistics.SetRanges(0, thePrefs.GetStatsMax());
 197	m_Statistics.autofitYscale = false;
 198	// Set the trend ratio of the Active Connections trend in the Connection Statistics scope.
 199	m_Statistics.SetTrendRatio(0, thePrefs.GetStatsConnectionsGraphRatio());
 200
 201	m_Statistics.SetYUnits(_T(""));
 202	m_Statistics.SetXUnits(GetResString(IDS_TIME));
 203
 204	RepaintMeters();
 205	m_Statistics.SetBackgroundColor(thePrefs.GetStatsColor(0)) ;
 206	m_Statistics.SetGridColor(thePrefs.GetStatsColor(1)) ;
 207	
 208	m_DownloadOMeter.InvalidateCtrl();
 209	m_UploadOMeter.InvalidateCtrl();
 210	m_Statistics.InvalidateCtrl();
 211
 212	if (thePrefs.GetStatsInterval()==0) 
 213		GetDlgItem(IDC_STATTREE)->EnableWindow(false);
 214
 215	UpdateData(FALSE);
 216
 217	EnableWindow( TRUE );
 218
 219	m_ilastMaxConnReached = 0;
 220	CRect rcW,rcSpl,rcTree,rcStat;
 221	
 222	GetWindowRect(rcW);
 223	ScreenToClient(rcW);
 224
 225	GetDlgItem(IDC_STATTREE)->GetWindowRect(rcTree);
 226	ScreenToClient(rcTree);
 227	m_DownloadOMeter.GetWindowRect(rcDown);
 228	ScreenToClient(rcDown);
 229	m_UploadOMeter.GetWindowRect(rcUp);
 230	ScreenToClient(rcUp);
 231	m_Statistics.GetWindowRect(rcStat);
 232	ScreenToClient(rcStat);
 233		
 234	//vertical splitter
 235	rcSpl.left = rcTree.right;
 236	rcSpl.right = rcSpl.left + 4;
 237	rcSpl.top = rcW.top + 2;
 238	rcSpl.bottom = rcW.bottom - 5;
 239	m_wndSplitterstat.Create(WS_CHILD | WS_VISIBLE, rcSpl, this, IDC_SPLITTER_STAT);
 240	int PosStatVinitX = rcSpl.left;
 241	int PosStatVnewX = thePrefs.GetSplitterbarPositionStat()*rcW.Width()/100;
 242	int maxX = rcW.right-13;
 243	int minX = rcW.left+8;
 244	if (thePrefs.GetSplitterbarPositionStat() > 90)
 245		PosStatVnewX = maxX;
 246	else if (thePrefs.GetSplitterbarPositionStat() < 10)
 247		PosStatVnewX = minX;
 248	rcSpl.left = PosStatVnewX;
 249	rcSpl.right = PosStatVnewX + 4;
 250	m_wndSplitterstat.MoveWindow(rcSpl);
 251
 252	//HR splitter
 253	rcSpl.left = rcDown.left;
 254	rcSpl.right = rcDown.right;
 255	rcSpl.top = rcDown.bottom;
 256	rcSpl.bottom = rcSpl.top + 4;
 257	m_wndSplitterstat_HR.Create(WS_CHILD | WS_VISIBLE, rcSpl, this, IDC_SPLITTER_STAT_HR);
 258	int PosStatVinitZ = rcSpl.top;
 259	int PosStatVnewZ = thePrefs.GetSplitterbarPositionStat_HR()*rcW.Height()/100;
 260	int maxZ = rcW.bottom-14;
 261	int minZ = 0;
 262	if (thePrefs.GetSplitterbarPositionStat_HR() > 90) 
 263		PosStatVnewZ = maxZ;
 264	else if (thePrefs.GetSplitterbarPositionStat_HR() < 10)
 265		PosStatVnewZ = minZ;
 266	rcSpl.top = PosStatVnewZ;
 267	rcSpl.bottom = PosStatVnewZ+4;
 268	m_wndSplitterstat_HR.MoveWindow(rcSpl);
 269
 270	//HL splitter
 271	rcSpl.left = rcUp.left;
 272	rcSpl.right = rcUp.right;
 273	rcSpl.top = rcUp.bottom;
 274	rcSpl.bottom = rcSpl.top + 4;
 275	m_wndSplitterstat_HL.Create(WS_CHILD | WS_VISIBLE, rcSpl, this, IDC_SPLITTER_STAT_HL);
 276	int PosStatVinitY = rcSpl.top;
 277	int PosStatVnewY = thePrefs.GetSplitterbarPositionStat_HL()*rcW.Height()/100;
 278	int maxY = rcW.bottom-9;
 279	int minY = 10;
 280	if (thePrefs.GetSplitterbarPositionStat_HL() > 90)
 281		PosStatVnewY = maxY;
 282	else if (thePrefs.GetSplitterbarPositionStat_HL() < 10)
 283		PosStatVnewY = minY;
 284	rcSpl.top = PosStatVnewY;
 285	rcSpl.bottom = PosStatVnewY+4;
 286	m_wndSplitterstat_HL.MoveWindow(rcSpl);
 287
 288	DoResize_V(PosStatVnewX - PosStatVinitX);
 289	DoResize_HL(PosStatVnewY - PosStatVinitY);
 290	DoResize_HR(PosStatVnewZ - PosStatVinitZ);
 291
 292	Localize();
 293	ShowStatistics(true);
 294	
 295	m_TimeToolTips = new CToolTipCtrl();
 296	m_TimeToolTips->Create(this);
 297	m_TimeToolTips->AddTool(GetDlgItem(IDC_SCOPE_D), _T(""), NULL, 0);
 298	m_TimeToolTips->AddTool(GetDlgItem(IDC_SCOPE_U), _T(""), NULL, 0);
 299	m_TimeToolTips->AddTool(GetDlgItem(IDC_STATSSCOPE),	_T(""), NULL, 0);
 300	// Any Autopop-Time which is specified higher than ~30 sec. will get reset to 5 sec.
 301	m_TimeToolTips->SetDelayTime(TTDT_AUTOPOP, 30000);
 302	m_TimeToolTips->SetDelayTime(TTDT_INITIAL, 30000);
 303	m_TimeToolTips->SetDelayTime(TTDT_RESHOW,  30000);
 304	EnableToolTips(TRUE);
 305
 306	return true;
 307}
 308
 309void CStatisticsDlg::initCSize()
 310{
 311	UINT x = thePrefs.GetSplitterbarPositionStat();
 312	UINT y = thePrefs.GetSplitterbarPositionStat_HL();
 313	UINT z = thePrefs.GetSplitterbarPositionStat_HR();
 314	if (x > 90)
 315		x = 100;
 316	else if (x < 10)
 317		x = 0;
 318	if (y > 90)
 319		y = 100;
 320	else if (y < 10)
 321		y = 0;
 322	if (z > 90)
 323		z = 100;
 324	else if (z < 10)
 325		z = 0;
 326
 327	RemoveAnchor(IDC_BNMENU);
 328	AddAnchor(IDC_BNMENU,CSize(0,0));
 329
 330	//StatTitle
 331	RemoveAnchor(IDC_STATIC_LASTRESET);
 332	AddAnchor(IDC_STATIC_LASTRESET,CSize(0,0),CSize(x,0));
 333	//stattree
 334	RemoveAnchor(stattree);
 335	AddAnchor(stattree,CSize(0,0),CSize(x,100));
 336
 337	//graph
 338	RemoveAnchor(m_DownloadOMeter);
 339	AddAnchor(m_DownloadOMeter,CSize(x,0),CSize(100,z));
 340
 341	RemoveAnchor(m_UploadOMeter);
 342	AddAnchor(m_UploadOMeter,CSize(x,z),CSize(100,y));
 343
 344	RemoveAnchor(m_Statistics);
 345	AddAnchor(m_Statistics,CSize(x,y),CSize(100,100));
 346	
 347	//set range
 348	CRect rcW;
 349	GetWindowRect(rcW);
 350	ScreenToClient(rcW);
 351
 352	CRect rcHR,rcHL;
 353	m_wndSplitterstat_HR.GetWindowRect(rcHR);
 354	m_wndSplitterstat_HL.GetWindowRect(rcHL);
 355	ScreenToClient(rcHR);
 356	ScreenToClient(rcHL);
 357
 358	m_wndSplitterstat.SetRange(rcW.left+11, rcW.right-11);
 359	m_wndSplitterstat_HL.SetRange(rcHR.bottom+5, rcW.bottom-7);
 360	m_wndSplitterstat_HR.SetRange(rcW.top+3, rcHL.top-5);
 361}
 362
 363
 364void CStatisticsDlg::DoResize_HL(int delta)
 365{
 366	if(!delta)
 367		return;
 368	m_DownloadOMeter.InvalidateCtrl(true);
 369	CSplitterControl::ChangeHeight(&m_UploadOMeter, delta , CW_TOPALIGN);
 370	CSplitterControl::ChangeHeight(&m_Statistics, -delta, CW_BOTTOMALIGN);
 371
 372	CRect rcW;
 373 
 374	GetWindowRect(rcW);
 375	ScreenToClient(rcW);
 376
 377	CRect rcspl;
 378
 379	m_UploadOMeter.GetWindowRect(rcspl);
 380	ScreenToClient(rcspl);
 381	thePrefs.SetSplitterbarPositionStat_HL(rcspl.bottom*100/rcW.Height());
 382
 383	initCSize();
 384
 385	ShowInterval();
 386	Invalidate();
 387	UpdateWindow();
 388}
 389
 390void CStatisticsDlg::DoResize_HR(int delta)
 391{
 392	if(!delta)
 393		return;
 394	CSplitterControl::ChangeHeight(&m_DownloadOMeter, delta , CW_TOPALIGN);
 395	CSplitterControl::ChangeHeight(&m_UploadOMeter, -delta, CW_BOTTOMALIGN);
 396	m_Statistics.InvalidateCtrl(true);
 397	CRect rcW;
 398 
 399	GetWindowRect(rcW);
 400	ScreenToClient(rcW);
 401
 402	CRect rcspl;
 403
 404	m_DownloadOMeter.GetWindowRect(rcspl);
 405	ScreenToClient(rcspl);
 406	thePrefs.SetSplitterbarPositionStat_HR(rcspl.bottom*100/rcW.Height());
 407
 408	initCSize();
 409
 410	ShowInterval();
 411	Invalidate();
 412	UpdateWindow();
 413}
 414
 415void CStatisticsDlg::DoResize_V(int delta)
 416{
 417	if(!delta)
 418		return;
 419	CSplitterControl::ChangeWidth(GetDlgItem(IDC_STATIC_LASTRESET), delta);
 420	CSplitterControl::ChangeWidth(&stattree, delta);
 421	CSplitterControl::ChangeWidth(&m_DownloadOMeter, -delta, CW_RIGHTALIGN);
 422	CSplitterControl::ChangeWidth(&m_UploadOMeter, -delta, CW_RIGHTALIGN);
 423	CSplitterControl::ChangeWidth(&m_Statistics, -delta, CW_RIGHTALIGN);
 424
 425	CRect rcW;
 426 
 427	GetWindowRect(rcW);
 428	ScreenToClient(rcW);
 429
 430	CRect rcspl;
 431
 432	GetDlgItem(IDC_STATTREE)->GetWindowRect(rcspl);
 433	ScreenToClient(rcspl);
 434	thePrefs.SetSplitterbarPositionStat(rcspl.right*100/rcW.Width());
 435
 436	if (rcspl.left==rcspl.right) {
 437		GetDlgItem(IDC_STATTREE)->ShowWindow(SW_HIDE);
 438		GetDlgItem(IDC_BNMENU)->ShowWindow(SW_HIDE);
 439		GetDlgItem(IDC_STATIC_LASTRESET)->ShowWindow(SW_HIDE);
 440		m_bTreepaneHidden=true;
 441	} else if (m_bTreepaneHidden) {
 442		m_bTreepaneHidden=false;
 443		GetDlgItem(IDC_STATTREE)->ShowWindow(SW_SHOW);
 444		GetDlgItem(IDC_BNMENU)->ShowWindow(SW_SHOW);
 445		GetDlgItem(IDC_STATIC_LASTRESET)->ShowWindow(SW_SHOW);
 446	}
 447
 448	initCSize();
 449
 450	ShowInterval();
 451	Invalidate();
 452	UpdateWindow();
 453}
 454
 455LRESULT CStatisticsDlg::DefWindowProc(UINT message, WPARAM wParam, LPARAM lParam) 
 456{
 457	switch (message) 
 458	{
 459		case WM_PAINT:
 460			if (m_wndSplitterstat) 
 461			{
 462				CRect rctree,rcSpl,rcW;
 463				GetWindowRect(rcW);
 464				ScreenToClient(rcW);
 465
 466				GetDlgItem(IDC_STATTREE)->GetWindowRect(rctree);
 467				ScreenToClient(rctree);
 468				
 469				if (rcW.Width()>0) 
 470				{
 471					rcSpl.left = rctree.right;
 472					rcSpl.right = rcSpl.left + 4;
 473					rcSpl.top = rcW.top + 2;
 474					rcSpl.bottom = rcW.bottom - 5;
 475					m_wndSplitterstat.MoveWindow(rcSpl,true);
 476				}
 477			}
 478			if (m_wndSplitterstat_HL) 
 479			{
 480				CRect rcUp,rcSpl,rcW;
 481				CWnd* pWnd;
 482
 483				GetWindowRect(rcW);
 484				ScreenToClient(rcW);
 485
 486				pWnd = &m_UploadOMeter;
 487				pWnd->GetWindowRect(rcUp);
 488
 489				ScreenToClient(rcUp);
 490
 491				if (rcW.Height()>0) 
 492				{
 493					rcSpl.left = rcUp.left;
 494					rcSpl.right = rcUp.right;
 495					rcSpl.top = rcUp.bottom;
 496					rcSpl.bottom = rcUp.bottom + 4;
 497					m_wndSplitterstat_HL.MoveWindow(rcSpl,true);
 498				}
 499			}
 500			if (m_wndSplitterstat_HR) 
 501			{
 502				CRect rcDown,rcSpl,rcW;
 503				CWnd* pWnd;
 504
 505				GetWindowRect(rcW);
 506				ScreenToClient(rcW);
 507
 508				pWnd = &m_DownloadOMeter;
 509				pWnd->GetWindowRect(rcDown);
 510				ScreenToClient(rcDown);
 511
 512				if (rcW.Height()>0) 
 513				{
 514					rcSpl.left = rcDown.left;
 515					rcSpl.right = rcDown.right;
 516					rcSpl.top = rcDown.bottom;
 517					rcSpl.bottom = rcDown.bottom + 4;
 518					m_wndSplitterstat_HR.MoveWindow(rcSpl,true);
 519				}
 520			}
 521			break;
 522		case WM_NOTIFY:
 523			if (wParam == IDC_SPLITTER_STAT)
 524			{ 
 525				SPC_NMHDR* pHdr = (SPC_NMHDR*) lParam;
 526				DoResize_V(pHdr->delta);
 527			}
 528			else if (wParam == IDC_SPLITTER_STAT_HL)
 529			{ 
 530				SPC_NMHDR* pHdr = (SPC_NMHDR*) lParam;
 531				DoResize_HL(pHdr->delta);
 532			}
 533			else if (wParam == IDC_SPLITTER_STAT_HR)
 534			{ 
 535				SPC_NMHDR* pHdr = (SPC_NMHDR*) lParam;
 536				DoResize_HR(pHdr->delta);
 537			}
 538			break;
 539		case WM_WINDOWPOSCHANGED: 
 540		{
 541			CRect rcW;
 542			GetWindowRect(rcW);
 543			ScreenToClient(rcW);
 544			if (m_wndSplitterstat && rcW.Width()>0) Invalidate();
 545			if (m_wndSplitterstat_HL && rcW.Height()>0) Invalidate();
 546			if (m_wndSplitterstat_HR && rcW.Height()>0) Invalidate();
 547			break;
 548		}
 549		case WM_SIZE:
 550		{
 551			//set range
 552			if (m_wndSplitterstat)
 553			{
 554				CRect rcW;
 555				GetWindowRect(rcW);
 556				ScreenToClient(rcW);
 557				if (rcW.Width()>0)
 558				{
 559					CRect rcSpl;
 560					CRect rcTree,rcDown;
 561					stattree.GetWindowRect(rcTree);
 562					m_DownloadOMeter.GetWindowRect(rcDown);
 563					ScreenToClient(rcTree);
 564					ScreenToClient(rcDown);
 565					long splitposstat=thePrefs.GetSplitterbarPositionStat()*rcW.Width()/100;
 566					rcSpl.left = splitposstat; 
 567					rcSpl.right = rcSpl.left + 4; 
 568					rcSpl.top = rcW.top + 2; 
 569					rcSpl.bottom = rcW.bottom - 5;
 570	   				m_wndSplitterstat.MoveWindow(rcSpl,true);
 571					m_wndSplitterstat.SetRange(rcW.left+11, rcW.right-11);
 572				}
 573			}
 574			if (m_wndSplitterstat_HR)
 575			{
 576				CRect rcW;
 577				GetWindowRect(rcW);
 578				ScreenToClient(rcW);
 579				if (rcW.Width()>0)
 580				{
 581					CRect rcSpl;
 582					CRect rcDown;
 583					m_DownloadOMeter.GetWindowRect(rcDown);
 584					ScreenToClient(rcDown);
 585					long splitposstat=thePrefs.GetSplitterbarPositionStat()*rcW.Width()/100;
 586					long splitposstat_HR=thePrefs.GetSplitterbarPositionStat_HR()*rcW.Height()/100;
 587					long splitposstat_HL=thePrefs.GetSplitterbarPositionStat_HL()*rcW.Height()/100;
 588					rcSpl.left = splitposstat + 7;
 589					rcSpl.right = rcW.right - 14; 
 590					rcSpl.top = splitposstat_HR; 
 591					rcSpl.bottom = rcSpl.top + 4;
 592					m_wndSplitterstat_HR.MoveWindow(rcSpl,true);
 593					m_wndSplitterstat_HR.SetRange(rcW.top+3, splitposstat_HL-4);
 594				}
 595			}
 596			if (m_wndSplitterstat_HL)
 597			{
 598				CRect rcW;
 599				GetWindowRect(rcW);
 600				ScreenToClient(rcW);
 601				if (rcW.Width()>0)
 602				{
 603					CRect rcSpl;
 604					CRect rcStat;
 605					m_Statistics.GetWindowRect(rcStat);
 606					ScreenToClient(rcStat);
 607					long splitposstat=thePrefs.GetSplitterbarPositionStat()*rcW.Width()/100;
 608					long splitposstat_HR=thePrefs.GetSplitterbarPositionStat_HR()*rcW.Height()/100;
 609					long splitposstat_HL=thePrefs.GetSplitterbarPositionStat_HL()*rcW.Height()/100;
 610					rcSpl.left = splitposstat + 7; 
 611					rcSpl.right = rcW.right - 14; 
 612					rcSpl.top = splitposstat_HL; 
 613					rcSpl.bottom = rcSpl.top + 4;
 614					m_wndSplitterstat_HL.MoveWindow(rcSpl,true);
 615					m_wndSplitterstat_HL.SetRange(splitposstat_HR+14, rcW.bottom-7);
 616				}
 617			}
 618			break;
 619		}
 620	}
 621	return CResizableDialog::DefWindowProc(message, wParam, lParam);
 622}
 623
 624void CStatisticsDlg::RepaintMeters() 
 625{
 626	CString Buffer;
 627	m_DownloadOMeter.SetBackgroundColor(thePrefs.GetStatsColor(0));	// Background
 628	m_DownloadOMeter.SetGridColor(thePrefs.GetStatsColor(1));		// Grid
 629	m_DownloadOMeter.SetPlotColor(thePrefs.GetStatsColor(4), 0);	// Download session
 630	m_DownloadOMeter.SetPlotColor(thePrefs.GetStatsColor(3), 1);	// Download average
 631	m_DownloadOMeter.SetPlotColor(thePrefs.GetStatsColor(2), 2);	// Download current
 632	m_DownloadOMeter.SetBarsPlot(thePrefs.GetFillGraphs(), 2);
 633
 634	m_UploadOMeter.SetBackgroundColor(thePrefs.GetStatsColor(0));
 635	m_UploadOMeter.SetGridColor(thePrefs.GetStatsColor(1));			// Grid
 636	m_UploadOMeter.SetPlotColor(thePrefs.GetStatsColor(7), 0);		// Upload session
 637	m_UploadOMeter.SetPlotColor(thePrefs.GetStatsColor(6), 1);		// Upload average
 638	m_UploadOMeter.SetPlotColor(thePrefs.GetStatsColor(5), 2);		// Upload current
 639	m_UploadOMeter.SetPlotColor(thePrefs.GetStatsColor(14), 3);		// Upload current (excl. overhead)
 640	m_UploadOMeter.SetPlotColor(thePrefs.GetStatsColor(13), 4);		// Upload friend slots
 641	m_UploadOMeter.SetBarsPlot(thePrefs.GetFillGraphs(), 2);
 642
 643	m_Statistics.SetBackgroundColor(thePrefs.GetStatsColor(0));
 644	m_Statistics.SetGridColor(thePrefs.GetStatsColor(1));
 645	m_Statistics.SetPlotColor(thePrefs.GetStatsColor(8), 0);	// Active Connections
 646	m_Statistics.SetPlotColor(thePrefs.GetStatsColor(10), 1);	// Active Uploads
 647	m_Statistics.SetPlotColor(thePrefs.GetStatsColor(9), 2);	// Total Uploads
 648	m_Statistics.SetPlotColor(thePrefs.GetStatsColor(12), 3);	// Active Downloads
 649	m_Statistics.SetBarsPlot(thePrefs.GetFillGraphs(), 0);
 650
 651	m_DownloadOMeter.SetYUnits(GetResString(IDS_ST_DOWNLOAD));
 652	m_DownloadOMeter.SetLegendLabel(GetResString(IDS_ST_SESSION), 0);			// Download session
 653	Buffer.Format(_T(" (%u %s)"), thePrefs.GetStatsAverageMinutes(), GetResString(IDS_MINS));
 654	m_DownloadOMeter.SetLegendLabel(GetResString(IDS_AVG) + Buffer, 1);			// Download average
 655	m_DownloadOMeter.SetLegendLabel(GetResString(IDS_ST_CURRENT), 2);			// Download current
 656
 657	m_UploadOMeter.SetYUnits(GetResString(IDS_ST_UPLOAD));
 658	m_UploadOMeter.SetLegendLabel(GetResString(IDS_ST_SESSION), 0);				// Upload session
 659	Buffer.Format(_T(" (%u %s)"), thePrefs.GetStatsAverageMinutes(), GetResString(IDS_MINS));
 660	m_UploadOMeter.SetLegendLabel(GetResString(IDS_AVG) + Buffer, 1);			// Upload average
 661	m_UploadOMeter.SetLegendLabel(GetResString(IDS_ST_ULCURRENT), 2);			// Upload current
 662	m_UploadOMeter.SetLegendLabel(GetResString(IDS_ST_ULSLOTSNOOVERHEAD), 3);	// Upload current (excl. overhead)
 663	m_UploadOMeter.SetLegendLabel(GetResString(IDS_ST_ULFRIEND), 4);			// Upload friend slots
 664
 665	m_Statistics.SetYUnits(GetResString(IDS_FSTAT_CONNECTION));
 666	Buffer.Format(_T("%s (1:%u)"), GetResString(IDS_ST_ACTIVEC), thePrefs.GetStatsConnectionsGraphRatio());
 667	m_Statistics.SetLegendLabel(Buffer, 0);										// Active Connections
 668	m_Statistics.SetLegendLabel(GetResString(IDS_ST_ACTIVEU_ZZ), 1);			// Active Uploads
 669	m_Statistics.SetLegendLabel(GetResString(IDS_SP_TOTALUL), 2);				// Total Uploads
 670	m_Statistics.SetLegendLabel(GetResString(IDS_ST_ACTIVED), 3);				// Active Downloads
 671}
 672
 673void CStatisticsDlg::SetCurrentRate(float uploadrate, float downloadrate)
 674{
 675	if (!theApp.emuledlg->IsRunning())
 676		return;
 677
 678	// Download
 679	double m_dPlotDataDown[3];
 680	m_dPlotDataDown[0] = theStats.GetAvgDownloadRate(AVG_SESSION);
 681	m_dPlotDataDown[1] = theStats.GetAvgDownloadRate(AVG_TIME);
 682	m_dPlotDataDown[2] = downloadrate;
 683	m_DownloadOMeter.AppendPoints(m_dPlotDataDown);
 684
 685	// Upload
 686	double m_dPlotDataUp[5];
 687	m_dPlotDataUp[0] = theStats.GetAvgUploadRate(AVG_SESSION);
 688	m_dPlotDataUp[1] = theStats.GetAvgUploadRate(AVG_TIME);
 689	// current rate to network (standardPackets + controlPackets)
 690	m_dPlotDataUp[2] = uploadrate;
 691	// current rate (excl. overhead)
 692	m_dPlotDataUp[3] = uploadrate - (float)theStats.GetUpDatarateOverhead() / 1024;
 693	// current rate to friends
 694	m_dPlotDataUp[4] = uploadrate - (float)theApp.uploadqueue->GetToNetworkDatarate() / 1024;
 695	m_UploadOMeter.AppendPoints(m_dPlotDataUp);
 696
 697	// Connections
 698	CDownloadQueue::SDownloadStats myStats;
 699	theApp.downloadqueue->GetDownloadSourcesStats(myStats);
 700	m_dPlotDataMore[0] = theApp.listensocket->GetActiveConnections();
 701	m_dPlotDataMore[1] = theApp.uploadqueue->GetActiveUploadsCount();
 702	m_dPlotDataMore[2] = theApp.uploadqueue->GetUploadQueueLength();
 703	m_dPlotDataMore[3] = myStats.a[1];
 704	m_Statistics.AppendPoints(m_dPlotDataMore);
 705
 706	// Websever
 707	UpDown updown;
 708	updown.upload = uploadrate;
 709	updown.download = downloadrate;
 710	updown.connections = theApp.listensocket->GetActiveConnections();
 711	theApp.webserver->AddStatsLine(updown);
 712}
 713
 714
 715void CStatisticsDlg::ShowStatistics(bool forceUpdate) 
 716{
 717	stattree.SetRedraw(false);
 718	CString	cbuffer;
 719	// Set Tree Values
 720
 721	// TRANSFER SECTION
 722	// If a section is not expanded, don't waste CPU cycles updating it.
 723	if (forceUpdate || stattree.IsExpanded(h_transfer)) 
 724	{
 725		uint32	statGoodSessions =				0;
 726		uint32	statBadSessions =				0;
 727		double	percentSessions =				0;
 728		// Transfer Ratios
 729		if ( theStats.sessionReceivedBytes>0 && theStats.sessionSentBytes>0 ) 
 730		{
 731			// Session
 732			if (theStats.sessionReceivedBytes<theStats.sessionSentBytes) 
 733			{
 734				cbuffer.Format(_T("%s %.2f : 1"),GetResString(IDS_STATS_SRATIO),(float)theStats.sessionSentBytes/theStats.sessionReceivedBytes);
 735				stattree.SetItemText(trans[0], cbuffer);
 736			} 
 737			else 
 738			{
 739				cbuffer.Format(_T("%s 1 : %.2f"),GetResString(IDS_STATS_SRATIO),(float)theStats.sessionReceivedBytes/theStats.sessionSentBytes);
 740				stattree.SetItemText(trans[0], cbuffer);
 741			}
 742		}
 743		else 
 744		{
 745			cbuffer.Format(_T("%s %s"), GetResString(IDS_STATS_SRATIO), GetResString(IDS_FSTAT_WAITING)); // Localize
 746			stattree.SetItemText(trans[0], cbuffer);
 747		}
 748
 749		if ( theStats.sessionReceivedBytes>0 && theStats.sessionSentBytes>0) 
 750		{
 751			// Session
 752			if (theStats.sessionSentBytes > theStats.sessionSentBytesToFriend && theStats.sessionReceivedBytes<theStats.sessionSentBytes-theStats.sessionSentBytesToFriend) 
 753			{
 754				cbuffer.Format(_T("%s %.2f : 1"),GetResString(IDS_STATS_FRATIO),(float)(theStats.sessionSentBytes-theStats.sessionSentBytesToFriend)/theStats.sessionReceivedBytes);
 755				stattree.SetItemText(trans[1], cbuffer);
 756			} 
 757			else 
 758			{
 759				cbuffer.Format(_T("%s 1 : %.2f"),GetResString(IDS_STATS_FRATIO),(float)theStats.sessionReceivedBytes/(theStats.sessionSentBytes-theStats.sessionSentBytesToFriend));
 760				stattree.SetItemText(trans[1], cbuffer);
 761			}
 762		}
 763		else 
 764		{
 765			cbuffer.Format(_T("%s %s"), GetResString(IDS_STATS_FRATIO), GetResString(IDS_FSTAT_WAITING)); // Localize
 766			stattree.SetItemText(trans[1], cbuffer);
 767		}
 768
 769		if ( (thePrefs.GetTotalDownloaded()>0 && thePrefs.GetTotalUploaded()>0) || (theStats.sessionReceivedBytes>0 && theStats.sessionSentBytes>0) ) 
 770		{
 771			// Cumulative
 772			if ((theStats.sessionReceivedBytes+thePrefs.GetTotalDownloaded())<(theStats.sessionSentBytes+thePrefs.GetTotalUploaded())) 
 773			{
 774				cbuffer.Format(_T("%s %.2f : 1"),GetResString(IDS_STATS_CRATIO),(float)(theStats.sessionSentBytes+thePrefs.GetTotalUploaded())/(theStats.sessionReceivedBytes+thePrefs.GetTotalDownloaded()));
 775				stattree.SetItemText(trans[2], cbuffer);
 776			} 
 777			else 
 778			{
 779				cbuffer.Format(_T("%s 1 : %.2f"),GetResString(IDS_STATS_CRATIO),(float)(theStats.sessionReceivedBytes+thePrefs.GetTotalDownloaded())/(theStats.sessionSentBytes+thePrefs.GetTotalUploaded()));
 780				stattree.SetItemText(trans[2], cbuffer);
 781			}
 782		}
 783		else 
 784		{
 785			cbuffer.Format(_T("%s %s"), GetResString(IDS_STATS_CRATIO), GetResString(IDS_FSTAT_WAITING)); // Localize
 786			stattree.SetItemText(trans[2], cbuffer);
 787		}
 788		// TRANSFER -> DOWNLOADS SECTION
 789		if (forceUpdate || stattree.IsExpanded(h_download)) 
 790		{
 791			uint64	DownOHTotal = 0;
 792			uint64	DownOHTotalPackets = 0;
 793			CDownloadQueue::SDownloadStats myStats;
 794			theApp.downloadqueue->GetDownloadSourcesStats(myStats);
 795			// TRANSFER -> DOWNLOADS -> SESSION SECTION
 796			if (forceUpdate || stattree.IsExpanded(h_down_session)) 
 797			{
 798				// Downloaded Data
 799				cbuffer.Format( GetResString( IDS_STATS_DDATA ) , CastItoXBytes( theStats.sessionReceivedBytes, false, false ) );
 800				stattree.SetItemText( down_S[0] , cbuffer );
 801				if (forceUpdate || stattree.IsExpanded(down_S[0])) 
 802				{
 803					// Downloaded Data By Client
 804					if (forceUpdate || stattree.IsExpanded(hdown_scb)) 
 805					{
 806						int i = 0;
 807						uint64 DownDataTotal =		thePrefs.GetDownSessionClientData();
 808						uint64 DownDataClient =		thePrefs.GetDownData_EMULE();
 809						double percentClientTransferred = 0;
 810						if ( DownDataTotal!=0 && DownDataClient!=0 )
 811							percentClientTransferred = (double) 100 * DownDataClient / DownDataTotal;
 812						cbuffer.Format( _T("eMule: %s (%1.1f%%)") , CastItoXBytes( DownDataClient, false, false ) , percentClientTransferred);
 813						stattree.SetItemText( down_scb[i] , cbuffer );
 814						i++;
 815
 816						DownDataClient = thePrefs.GetDownData_EDONKEYHYBRID();
 817						if ( DownDataTotal!=0 && DownDataClient!=0 )
 818							percentClientTransferred = (double) 100 * DownDataClient / DownDataTotal;
 819						else
 820							percentClientTransferred = 0;
 821						cbuffer.Format( _T("eD Hybrid: %s (%1.1f%%)") , CastItoXBytes( DownDataClient, false, false ) , percentClientTransferred );
 822						stattree.SetItemText( down_scb[i] , cbuffer );
 823						i++;
 824
 825						DownDataClient = thePrefs.GetDownData_EDONKEY();
 826						if ( DownDataTotal!=0 && DownDataClient!=0 )
 827							percentClientTransferred = (double) 100 * DownDataClient / DownDataTotal;
 828						else
 829							percentClientTransferred = 0;
 830						cbuffer.Format( _T("eDonkey: %s (%1.1f%%)") , CastItoXBytes( DownDataClient, false, false ), percentClientTransferred );
 831						stattree.SetItemText( down_scb[i] , cbuffer );
 832						i++;
 833
 834						DownDataClient = thePrefs.GetDownData_AMULE();
 835						if ( DownDataTotal!=0 && DownDataClient!=0 )
 836							percentClientTransferred = (double) 100 * DownDataClient / DownDataTotal;
 837						else
 838							percentClientTransferred = 0;
 839						cbuffer.Format( _T("aMule: %s (%1.1f%%)") , CastItoXBytes( DownDataClient, false, false ), percentClientTransferred );
 840						stattree.SetItemText( down_scb[i] , cbuffer );
 841						i++;
 842
 843						DownDataClient = thePrefs.GetDownData_MLDONKEY();
 844						if ( DownDataTotal!=0 && DownDataClient!=0 )
 845							percentClientTransferred = (double) 100 * DownDataClient / DownDataTotal;
 846						else
 847							percentClientTransferred = 0;
 848						cbuffer.Format( _T("MLdonkey: %s (%1.1f%%)") , CastItoXBytes( DownDataClient, false, false ), percentClientTransferred );
 849						stattree.SetItemText( down_scb[i] , cbuffer );
 850						i++;
 851
 852						DownDataClient = thePrefs.GetDownData_SHAREAZA();
 853						if ( DownDataTotal!=0 && DownDataClient!=0 )
 854							percentClientTransferred = (double) 100 * DownDataClient / DownDataTotal;
 855						else
 856							percentClientTransferred = 0;
 857						cbuffer.Format( _T("Shareaza: %s (%1.1f%%)") , CastItoXBytes( DownDataClient, false, false ), percentClientTransferred );
 858						stattree.SetItemText( down_scb[i] , cbuffer );
 859						i++;
 860
 861						DownDataClient = thePrefs.GetDownData_EMULECOMPAT();
 862						if ( DownDataTotal!=0 && DownDataClient!=0 )
 863							percentClientTransferred = (double) 100 * DownDataClient / DownDataTotal;
 864						else
 865							percentClientTransferred = 0;
 866						cbuffer.Format( _T("eM Compat: %s (%1.1f%%)") , CastItoXBytes( DownDataClient, false, false ), percentClientTransferred );
 867						stattree.SetItemText( down_scb[i] , cbuffer );
 868						i++;
 869
 870						DownDataClient = thePrefs.GetDownData_URL();
 871						if ( DownDataTotal!=0 && DownDataClient!=0 )
 872							percentClientTransferred = (double) 100 * DownDataClient / DownDataTotal;
 873						else
 874							percentClientTransferred = 0;
 875						cbuffer.Format( _T("URL: %s (%1.1f%%)") , CastItoXBytes( DownDataClient, false, false ), percentClientTransferred );
 876						stattree.SetItemText( down_scb[i] , cbuffer );
 877						i++;
 878					}
 879					// Downloaded Data By Port
 880					if (forceUpdate || stattree.IsExpanded(hdown_spb)) 
 881					{
 882						int i = 0;
 883						uint64	PortDataDefault =	thePrefs.GetDownDataPort_4662();
 884						uint64	PortDataOther =		thePrefs.GetDownDataPort_OTHER();
 885						uint64	PortDataPeerCache =	thePrefs.GetDownDataPort_PeerCache();
 886						uint64	PortDataTotal =		thePrefs.GetDownSessionDataPort();
 887						double	percentPortTransferred = 0;
 888
 889						if ( PortDataTotal!=0 && PortDataDefault!=0 )
 890							percentPortTransferred = (double) 100 * PortDataDefault / PortDataTotal;
 891						cbuffer.Format( _T("%s: %s (%1.1f%%)") , GetResString(IDS_STATS_PRTDEF) , CastItoXBytes( PortDataDefault, false, false ) , percentPortTransferred);
 892						stattree.SetItemText( down_spb[i] , cbuffer );
 893						i++;
 894
 895						if ( PortDataTotal!=0 && PortDataOther!=0 )
 896							percentPortTransferred = (double) 100 * PortDataOther / PortDataTotal;
 897						else
 898							percentPortTransferred = 0;
 899						cbuffer.Format( _T("%s: %s (%1.1f%%)") , GetResString(IDS_STATS_PRTOTHER) , CastItoXBytes( PortDataOther, false, false ) , percentPortTransferred);
 900						stattree.SetItemText( down_spb[i] , cbuffer );
 901						i++;
 902
 903						if ( PortDataTotal!=0 && PortDataPeerCache!=0 )
 904							percentPortTransferred = (double) 100 * PortDataPeerCache / PortDataTotal;
 905						else
 906							percentPortTransferred = 0;
 907						cbuffer.Format( _T("%s: %s (%1.1f%%)") , thePrefs.GetPeerCacheShow() ? _T("PeerCache") : GetResString(IDS_STATS_PRTOTHER) , CastItoXBytes( PortDataPeerCache, false, false ) , percentPortTransferred);
 908						stattree.SetItemText( down_spb[i] , cbuffer );
 909						i++;
 910					}
 911				}
 912				// Completed Downloads
 913				cbuffer.Format( _T("%s: %u") , GetResString( IDS_STATS_COMPDL ) , thePrefs.GetDownSessionCompletedFiles() );
 914				stattree.SetItemText( down_S[1] , cbuffer );
 915				// Active Downloads
 916				cbuffer.Format( GetResString( IDS_STATS_ACTDL ) , myStats.a[1] );
 917				stattree.SetItemText( down_S[2] , cbuffer );
 918				// Found Sources
 919				cbuffer.Format( GetResString( IDS_STATS_FOUNDSRC ) , myStats.a[0] );
 920				stattree.SetItemText( down_S[3] , cbuffer );
 921				if (forceUpdate || stattree.IsExpanded(down_S[3])) 
 922				{ 
 923					int i = 0;
 924					// Sources By Status
 925					cbuffer.Format( _T("%s: %u") , GetResString( IDS_ONQUEUE ) , myStats.a[2] );
 926					stattree.SetItemText( down_sources[i] , cbuffer );
 927					i++;
 928					cbuffer.Format( _T("%s: %u") , GetResString( IDS_QUEUEFULL ) , myStats.a[3] );
 929					stattree.SetItemText( down_sources[i] , cbuffer );
 930					i++;
 931					cbuffer.Format( _T("%s: %u") , GetResString( IDS_NONEEDEDPARTS ) , myStats.a[4] );
 932					stattree.SetItemText( down_sources[i] , cbuffer );
 933					i++;
 934					cbuffer.Format( _T("%s: %u") , GetResString( IDS_ASKING ) , myStats.a[5] );
 935					stattree.SetItemText( down_sources[i] , cbuffer );
 936					i++;
 937					cbuffer.Format( _T("%s: %u") , GetResString( IDS_RECHASHSET ) , myStats.a[6] );
 938					stattree.SetItemText( down_sources[i] , cbuffer );
 939					i++;
 940					cbuffer.Format( _T("%s: %u") , GetResString( IDS_CONNECTING ) , myStats.a[7] );
 941					stattree.SetItemText( down_sources[i] , cbuffer );
 942					i++;
 943					cbuffer.Format( _T("%s: %u") , GetResString(IDS_CONNVIASERVER) , myStats.a[8] );
 944					stattree.SetItemText( down_sources[i] , cbuffer );
 945					i++;
 946					cbuffer.Format( _T("%s: %u") , GetResString(IDS_TOOMANYCONNS) , myStats.a[9] );
 947					stattree.SetItemText( down_sources[i] , cbuffer );
 948					i++;
 949					cbuffer.Format( _T("%s: %u") , GetResString(IDS_NOCONNECTLOW2LOW) , myStats.a[10] );
 950					stattree.SetItemText( down_sources[i] , cbuffer );
 951					i++;
 952					cbuffer.Format( _T("%s: %u") , GetResString(IDS_STATS_PROBLEMATIC) , myStats.a[12] );
 953					stattree.SetItemText( down_sources[i] , cbuffer );
 954					i++;
 955					cbuffer.Format( _T("%s: %u") , GetResString(IDS_BANNED) , myStats.a[13] );
 956					stattree.SetItemText( down_sources[i] , cbuffer );
 957					i++;
 958					cbuffer.Format( _T("%s: %u") , GetResString(IDS_ASKED4ANOTHERFILE) , myStats.a[15] );
 959					stattree.SetItemText( down_sources[i] , cbuffer );
 960					i++;
 961					cbuffer.Format( _T("%s: %u") , GetResString(IDS_UNKNOWN) , myStats.a[11] );
 962					stattree.SetItemText( down_sources[i] , cbuffer );
 963					i++;
 964
 965					// where from? (3)
 966					cbuffer.Format( _T("%s: %u") , GetResString( IDS_VIAED2KSQ ) , myStats.a[16] );
 967					stattree.SetItemText( down_sources[i] , cbuffer );
 968					i++;
 969					cbuffer.Format( _T("%s: %u") , GetResString( IDS_VIAKAD ) , myStats.a[17] );
 970					stattree.SetItemText( down_sources[i] , cbuffer );
 971					i++;
 972					cbuffer.Format( _T("%s: %u") , GetResString( IDS_VIASE ) , myStats.a[18] );
 973					stattree.SetItemText( down_sources[i] , cbuffer );
 974					i++;
 975					cbuffer.Format( _T("%s: %u") , GetResString( IDS_VIAPASSIVE ) , myStats.a[14] );
 976					stattree.SetItemText( down_sources[i] , cbuffer );
 977					i++;
 978					cbuffer.Format( _T("eD2K: %u (%.1f%%)") , myStats.a[19], myStats.a[0] ? (myStats.a[19] * 100.0 / myStats.a[0]) : 0.0 );
 979					stattree.SetItemText( down_sources[i] , cbuffer );
 980					i++;
 981					cbuffer.Format( _T("Kad: %u (%.1f%%)") , myStats.a[20], myStats.a[0] ? (myStats.a[20] * 100.0 / myStats.a[0]) : 0.0 );
 982					stattree.SetItemText( down_sources[i] , cbuffer );
 983					i++;
 984					cbuffer.Format( _T("eD2K/Kad: %u (%.1f%%)") , myStats.a[21], myStats.a[0] ? (myStats.a[21] * 100.0 / myStats.a[0]) : 0.0 );
 985					stattree.SetItemText( down_sources[i] , cbuffer );
 986					i++;
 987
 988					cbuffer.Format(_T("%s: %s, %s: %s (%.1f%%)"), GetResString(IDS_UDPREASKS), CastItoIShort(theApp.downloadqueue->GetUDPFileReasks()), GetResString(IDS_UFAILED), CastItoIShort(theApp.downloadqueue->GetFailedUDPFileReasks()), theApp.downloadqueue->GetUDPFileReasks() ? (theApp.downloadqueue->GetFailedUDPFileReasks() * 100.0 / theApp.downloadqueue->GetUDPFileReasks()) : 0.0 );
 989					stattree.SetItemText( down_sources[i] , cbuffer );
 990					i++;
 991
 992					cbuffer.Format(_T("%s: %s (%s + %s)"), GetResString(IDS_DEADSOURCES), CastItoIShort(theApp.clientlist->m_globDeadSourceList.GetDeadSourcesCount() + myStats.a[22]), CastItoIShort(theApp.clientlist->m_globDeadSourceList.GetDeadSourcesCount()), CastItoIShort((UINT)myStats.a[22]));
 993					stattree.SetItemText( down_sources[i] , cbuffer );
 994					i++;
 995				}
 996				// Set Download Sessions
 997				statGoodSessions =	thePrefs.GetDownS_SuccessfulSessions() + myStats.a[1]; // Add Active Downloads
 998				statBadSessions =	thePrefs.GetDownS_FailedSessions();
 999				cbuffer.Format( _T("%s: %u") , GetResString(IDS_STATS_DLSES) , statGoodSessions + statBadSessions );
1000				stattree.SetItemText( down_S[4] , cbuffer );
1001				if (forceUpdate || stattree.IsExpanded(down_S[4])) 
1002				{
1003					// Set Successful Download Sessions and Average Downloaded Per Session
1004					percentSessions = 0;
1005					if (statGoodSessions > 0) 
1006					{
1007						percentSessions = (double) 100 * statGoodSessions / (statGoodSessions + statBadSessions);
1008						cbuffer.Format( _T("%s: %s") , GetResString(IDS_STATS_AVGDATADLSES) , CastItoXBytes( theStats.sessionReceivedBytes / statGoodSessions, false, false ) ); 
1009					}
1010					else 
1011						cbuffer.Format( _T("%s: %s") , GetResString(IDS_STATS_AVGDATADLSES) , CastItoXBytes((uint32)0, false, false) );
1012					stattree.SetItemText( down_ssessions[2] , cbuffer ); // Set Avg DL/Session
1013					cbuffer.Format( _T("%s: %u (%1.1f%%)") , GetResString(IDS_STATS_SDLSES) , statGoodSessions , percentSessions );
1014					stattree.SetItemText( down_ssessions[0] , cbuffer ); // Set Succ Sessions
1015					// Set Failed Download Sessions (Avoid Division)
1016					if (percentSessions != 0 && statBadSessions > 0) 
1017						percentSessions = 100 - percentSessions; // There were some good sessions and bad ones...
1018					else if (percentSessions == 0 && statBadSessions > 0) 
1019						percentSessions = 100; // There were bad sessions and no good ones, must be 100%
1020					else 
1021						percentSessions = 0; // No sessions at all, or no bad ones.
1022					cbuffer.Format( _T("%s: %u (%1.1f%%)") , GetResString(IDS_STATS_FDLSES) , statBadSessions , percentSessions );
1023					stattree.SetItemText( down_ssessions[1] , cbuffer );
1024					// Set Average Download Time
1025					cbuffer.Format(_T("%s: %s"), GetResString(IDS_STATS_AVGDLTIME), CastSecondsToLngHM(thePrefs.GetDownS_AvgTime()));
1026					stattree.SetItemText( down_ssessions[3] , cbuffer );
1027				}
1028				// Set Gain Due To Compression
1029				cbuffer.Format(GetResString(IDS_STATS_GAINCOMP) + _T(" (%.1f%%)"), CastItoXBytes(thePrefs.GetSesSavedFromCompression(), false, false), theStats.sessionReceivedBytes!=0 ? (thePrefs.GetSesSavedFromCompression() * 100.0 / theStats.sessionReceivedBytes) : 0.0);
1030				stattree.SetItemText( down_S[5] , cbuffer );
1031				// Set Lost Due To Corruption
1032				cbuffer.Format(GetResString(IDS_STATS_LOSTCORRUPT) + _T(" (%.1f%%)"), CastItoXBytes(thePrefs.GetSesLostFromCorruption(), false, false), theStats.sessionReceivedBytes!=0 ? (thePrefs.GetSesLostFromCorruption() * 100.0 / theStats.sessionReceivedBytes) : 0.0);
1033				stattree.SetItemText( down_S[6] , cbuffer );
1034				// Set Parts Saved Due To ICH
1035				cbuffer.Format(GetResString(IDS_STATS_ICHSAVED), thePrefs.GetSesPartsSavedByICH());
1036				stattree.SetItemText( down_S[7] , cbuffer );
1037
1038				// Calculate downline OH totals
1039				DownOHTotal =	theStats.GetDownDataOverheadFileRequest() + 
1040								theStats.GetDownDataOverheadSourceExchange() + 
1041								theStats.GetDownDataOverheadServer() + 
1042								theStats.GetDownDataOverheadKad() + 
1043								theStats.GetDownDataOverheadOther();
1044				DownOHTotalPackets = 
1045								theStats.GetDownDataOverheadFileRequestPackets() + 
1046								theStats.GetDownDataOverheadSourceExchangePackets() + 
1047								theStats.GetDownDataOverheadServerPackets() + 
1048								theStats.GetDownDataOverheadKadPackets() + 
1049								theStats.GetDownDataOverheadOtherPackets();
1050
1051				// Downline Overhead
1052				cbuffer.Format( GetResString( IDS_TOVERHEAD ) , CastItoXBytes( DownOHTotal, false, false ) , CastItoIShort( DownOHTotalPackets ) );
1053				stattree.SetItemText( hdown_soh , cbuffer );
1054				if (forceUpdate || stattree.IsExpanded(hdown_soh)) 
1055				{
1056					int i = 0;
1057					// Set down session file req OH
1058					cbuffer.Format( GetResString( IDS_FROVERHEAD ) , CastItoXBytes( theStats.GetDownDataOverheadFileRequest(), false, false ) , CastItoIShort( theStats.GetDownDataOverheadFileRequestPackets() ) );
1059					stattree.SetItemText( down_soh[i] , cbuffer );
1060					i++;
1061					// Set down session source exch OH
1062					cbuffer.Format( GetResString( IDS_SSOVERHEAD ) , CastItoXBytes( theStats.GetDownDataOverheadSourceExchange(), false, false ), CastItoIShort( theStats.GetDownDataOverheadSourceExchangePackets() ) );
1063					stattree.SetItemText( down_soh[i] , cbuffer );
1064					i++;
1065					// Set down session server OH
1066					cbuffer.Format(GetResString(IDS_SOVERHEAD),
1067								   CastItoXBytes(theStats.GetDownDataOverheadServer(), false, false), 
1068								   CastItoIShort(theStats.GetDownDataOverheadServerPackets()));
1069					stattree.SetItemText( down_soh[i] , cbuffer );
1070					i++;
1071					// Set down session Kad OH
1072					cbuffer.Format(GetResString(IDS_KADOVERHEAD),
1073								   CastItoXBytes(theStats.GetDownDataOverheadKad(), false, false), 
1074								   CastItoIShort(theStats.GetDownDataOverheadKadPackets()));
1075					stattree.SetItemText( down_soh[i] , cbuffer );
1076					i++;
1077				}
1078			}
1079			// TRANSFER -> DOWNLOADS -> CUMULATIVE SECTION
1080			if (forceUpdate || stattree.IsExpanded(h_down_total)) 
1081			{
1082				// Downloaded Data
1083				uint64 ullCumReceived = theStats.sessionReceivedBytes + thePrefs.GetTotalDownloaded();
1084				cbuffer.Format(GetResString(IDS_STATS_DDATA), CastItoXBytes(ullCumReceived, false, false));
1085				stattree.SetItemText(down_T[0], cbuffer);
1086				if (forceUpdate || stattree.IsExpanded(down_T[0])) 
1087				{
1088					// Downloaded Data By Client
1089					if (forceUpdate || stattree.IsExpanded(hdown_tcb)) 
1090					{
1091						int i = 0;
1092						uint64 DownDataTotal =		thePrefs.GetDownTotalClientData();
1093						uint64 DownDataClient =		thePrefs.GetCumDownData_EMULE();
1094						double percentClientTransferred = 0;
1095						if ( DownDataTotal!=0 && DownDataClient!=0 )
1096							percentClientTransferred = (double) 100 * DownDataClient / DownDataTotal;
1097						cbuffer.Format( _T("eMule: %s (%1.1f%%)") , CastItoXBytes( DownDataClient, false, false ) , percentClientTransferred);
1098						stattree.SetItemText( down_tcb[i] , cbuffer );
1099						i++;
1100
1101						DownDataClient = thePrefs.GetCumDownData_EDONKEYHYBRID();
1102						if ( DownDataTotal!=0 && DownDataClient!=0 )
1103							percentClientTransferred = (double) 100 * DownDataClient / DownDataTotal;
1104						else
1105							percentClientTransferred = 0;
1106						cbuffer.Format( _T("eD Hybrid: %s (%1.1f%%)") , CastItoXBytes( DownDataClient, false, false ) , percentClientTransferred );
1107						stattree.SetItemText( down_tcb[i] , cbuffer );
1108						i++;
1109
1110						DownDataClient = thePrefs.GetCumDownData_EDONKEY();
1111						if ( DownDataTotal!=0 && DownDataClient!=0 )
1112							percentClientTransferred = (double) 100 * DownDataClient / DownDataTotal;
1113						else
1114							percentClientTransferred = 0;
1115						cbuffer.Format( _T("eDonkey: %s (%1.1f%%)") , CastItoXBytes( DownDataClient, false, false ), percentClientTransferred );
1116						stattree.SetItemText( down_tcb[i] , cbuffer );
1117						i++;
1118
1119						DownDataClient = thePrefs.GetCumDownData_AMULE();
1120						if ( DownDataTotal!=0 && DownDataClient!=0 )
1121							percentClientTransferred = (double) 100 * DownDataClient / DownDataTotal;
1122						else
1123							percentClientTransferred = 0;
1124						cbuffer.Format( _T("aMule: %s (%1.1f%%)") , CastItoXBytes( DownDataClient, false, false ), percentClientTransferred );
1125						stattree.SetItemText( down_tcb[i] , cbuffer );
1126						i++;
1127
1128						DownDataClient = thePrefs.GetCumDownData_MLDONKEY();
1129						if ( DownDataTotal!=0 && DownDataClient!=0 )
1130							percentClientTransferred = (double) 100 * DownDataClient / DownDataTotal;
1131						else
1132							percentClientTransferred = 0;
1133						cbuffer.Format( _T("MLdonkey: %s (%1.1f%%)") , CastItoXBytes( DownDataClient, false, false ), percentClientTransferred );
1134						stattree.SetItemText( down_tcb[i] , cbuffer );
1135						i++;
1136
1137						DownDataClient = thePrefs.GetCumDownData_SHAREAZA();
1138						if ( DownDataTotal!=0 && DownDataClient!=0 )
1139							percentClientTransferred = (double) 100 * DownDataClient / DownDataTotal;
1140						else
1141							percentClientTransferred = 0;
1142						cbuffer.Format( _T("Shareaza: %s (%1.1f%%)") , CastItoXBytes( DownDataClient, false, false ), percentClientTransferred );
1143						stattree.SetItemText( down_tcb[i] , cbuffer );
1144						i++;
1145
1146						DownDataClient = thePrefs.GetCumDownData_EMULECOMPAT();
1147						if ( DownDataTotal!=0 && DownDataClient!=0 )
1148							percentClientTransferred = (double) 100 * DownDataClient / DownDataTotal;
1149						else
1150							percentClientTransferred = 0;
1151						cbuffer.Format( _T("eM Compat: %s (%1.1f%%)") , CastItoXBytes( DownDataClient, false, false ), percentClientTransferred );
1152						stattree.SetItemText( down_tcb[i] , cbuffer );
1153						i++;
1154
1155						DownDataClient = thePrefs.GetCumDownData_URL();
1156						if ( DownDataTotal!=0 && DownDataClient!=0 )
1157							percentClientTransferred = (double) 100 * DownDataClient / DownDataTotal;
1158						else
1159							percentClientTransferred = 0;
1160						cbuffer.Format( _T("URL: %s (%1.1f%%)") , CastItoXBytes( DownDataClient, false, false ), percentClientTransferred );
1161						stattree.SetItemText( down_tcb[i] , cbuffer );
1162						i++;
1163					}
1164					// Downloaded Data By Port
1165					if (forceUpdate || stattree.IsExpanded(hdown_tpb)) 
1166					{
1167						int i = 0;
1168						uint64	PortDataDefault =	thePrefs.GetCumDownDataPort_4662();
1169						uint64	PortDataOther =		thePrefs.GetCumDownDataPort_OTHER();
1170						uint64	PortDataPeerCache =	thePrefs.GetCumDownDataPort_PeerCache();
1171						uint64	PortDataTotal =		thePrefs.GetDownTotalPortData();
1172						double	percentPortTransferred = 0;
1173
1174						if ( PortDataTotal!=0 && PortDataDefault!=0 )
1175							percentPortTransferred = (double) 100 * PortDataDefault / PortDataTotal;
1176						cbuffer.Format( _T("%s: %s (%1.1f%%)") , GetResString(IDS_STATS_PRTDEF) , CastItoXBytes( PortDataDefault, false, false ) , percentPortTransferred);
1177						stattree.SetItemText( down_tpb[i] , cbuffer );
1178						i++;
1179
1180						if ( PortDataTotal!=0 && PortDataOther!=0 )
1181							percentPortTransferred = (double) 100 * PortDataOther / PortDataTotal;
1182						else
1183							percentPortTransferred = 0;
1184						cbuffer.Format( _T("%s: %s (%1.1f%%)") , GetResString(IDS_STATS_PRTOTHER) , CastItoXBytes( PortDataOther, false, false ) , percentPortTransferred);
1185						stattree.SetItemText( down_tpb[i] , cbuffer );
1186						i++;
1187
1188						if ( PortDataTotal!=0 && PortDataPeerCache!=0 )
1189							percentPortTransferred = (double) 100 * PortDataPeerCache / PortDataTotal;
1190						else
1191							percentPortTransferred = 0;
1192						cbuffer.Format( _T("%s: %s (%1.1f%%)") , thePrefs.GetPeerCacheShow() ? _T("PeerCache") : GetResString(IDS_STATS_PRTOTHER) , CastItoXBytes( PortDataPeerCache, false, false ) , percentPortTransferred);
1193						stattree.SetItemText( down_tpb[i] , cbuffer );
1194						i++;
1195					}
1196				}
1197				// Set Cum Completed Downloads
1198				cbuffer.Format(_T("%s: %u"), GetResString(IDS_STATS_COMPDL), thePrefs.GetDownCompletedFiles() );
1199				stattree.SetItemText(down_T[1], cbuffer);
1200				// Set Cum Download Sessions
1201				statGoodSessions = thePrefs.GetDownC_SuccessfulSessions() + myStats.a[1]; // Need to reset these from the session section.  Declared up there.
1202				statBadSessions = thePrefs.GetDownC_FailedSessions(); // ^^^^^^^^^^^^^^
1203				cbuffer.Format(_T("%s: %u"), GetResString(IDS_STATS_DLSES), statGoodSessions+statBadSessions );
1204				stattree.SetItemText(down_T[2], cbuffer);
1205				if (forceUpdate || stattree.IsExpanded(down_T[2])) 
1206				{
1207					// Set Cum Successful Download Sessions & Cum Average Download Per Sessions (Save an if-else statement)
1208					if (statGoodSessions > 0) 
1209					{
1210						percentSessions = (double) 100 * statGoodSessions / (statGoodSessions + statBadSessions);
1211						cbuffer.Format( _T("%s: %s") , GetResString(IDS_STATS_AVGDATADLSES), CastItoXBytes(ullCumReceived / statGoodSessions, false, false));
1212					}
1213					else 
1214					{
1215						percentSessions = 0;
1216						cbuffer.Format( _T("%s: %s") , GetResString(IDS_STATS_AVGDATADLSES) , CastItoXBytes((uint32)0, false, false) );
1217					}
1218					stattree.SetItemText( down_tsessions[2] , cbuffer ); // Set Avg DL/Session
1219					cbuffer.Format( _T("%s: %u (%1.1f%%)"), GetResString(IDS_STATS_SDLSES) , statGoodSessions , percentSessions );
1220					stattree.SetItemText( down_tsessions[0] , cbuffer ); // Set Successful Sessions
1221					// Set Cum Failed Download Sessions
1222					if (percentSessions != 0 && statBadSessions > 0) 
1223						percentSessions = 100 - percentSessions; // There were some good sessions and bad ones...
1224					else if (percentSessions == 0 && statBadSessions > 0) 
1225						percentSessions = 100; // There were bad sessions and no good ones, must be 100%
1226					else 
1227						percentSessions = 0; // No sessions at all, or no bad ones.
1228					cbuffer.Format( _T("%s: %u (%1.1f%%)") , GetResString(IDS_STATS_FDLSES) , statBadSessions , percentSessions);
1229					stattree.SetItemText( down_tsessions[1] , cbuffer );
1230					// Set Cumulative Average Download Time
1231					uint32 avgDownTime = thePrefs.GetDownS_AvgTime();
1232					if (thePrefs.GetDownC_AvgTime()<=0) 
1233						thePrefs.SetDownCAvgTime(avgDownTime);
1234					avgDownTime = (uint32) (avgDownTime+thePrefs.GetDownC_AvgTime())/2;
1235					cbuffer.Format(_T("%s: %s"), GetResString(IDS_STATS_AVGDLTIME), CastSecondsToLngHM(avgDownTime));
1236					stattree.SetItemText(down_tsessions[3], cbuffer);
1237				}
1238				// Set Cumulative Gained Due To Compression
1239				uint64 ullCumCompressed = thePrefs.GetSesSavedFromCompression() + thePrefs.GetCumSavedFromCompression();
1240				cbuffer.Format(GetResString(IDS_STATS_GAINCOMP) + _T(" (%.1f%%)"), CastItoXBytes(ullCumCompressed, false, false), ullCumReceived!=0 ? (ullCumCompressed * 100.0 / ullCumReceived) : 0.0);
1241				stattree.SetItemText( down_T[3] , cbuffer );
1242				// Set Cumulative Lost Due To Corruption
1243				uint64 ullCumCorrupted = thePrefs.GetSesLostFromCorruption() + thePrefs.GetCumLostFromCorruption();
1244				cbuffer.Format(GetResString(IDS_STATS_LOSTCORRUPT) + _T(" (%.1f%%)"), CastItoXBytes(ullCumCorrupted, false, false

Large files files are truncated, but you can click here to view the full file