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) 2005-2008 Dévai Tamás ( gonosztopi@amule.org )
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
29 #include "OtherFunctions.h"
33 #include <common/Format.h> // Needed for CFormat
35 #define a_brackets_b(a,b) (a + wxT(" (") + b + wxT(")"))
37 #endif /* !EC_REMOTE */
39 #include <ec/cpp/ECTag.h> // Needed for CECTag
42 #include <ec/cpp/ECSpecialTags.h> // Needed for CEC_StatTree_Node_Tag
47 uint32_t NewStatTreeItemId()
49 static uint32_t lastid
= 0;
55 /* CStatTreeItemBase */
58 CStatTreeItemBase::CStatTreeItemBase(const CECTag
*tag
)
59 : m_label(((CEC_StatTree_Node_Tag
*)tag
)->GetDisplayString())
60 , m_uniqueid(tag
->GetTagByNameSafe(EC_TAG_STATTREE_NODEID
)->GetInt())
62 wxASSERT(tag
->GetTagName() == EC_TAG_STATTREE_NODE
);
64 for (size_t i
= 0; i
< tag
->GetTagCount(); ++i
) {
65 const CECTag
*tmp
= tag
->GetTagByIndex(i
);
66 if (tmp
->GetTagName() == EC_TAG_STATTREE_NODE
) {
67 m_children
.push_back(new CStatTreeItemBase(tmp
));
71 #endif /* EC_REMOTE */
73 CStatTreeItemBase::~CStatTreeItemBase()
75 for (std::list
<CStatTreeItemBase
*>::iterator it
= m_children
.begin();
76 it
!= m_children
.end(); ++it
) {
83 CStatTreeItemBase
* CStatTreeItemBase::AddChild(
84 CStatTreeItemBase
* child
,
88 wxMutexLocker
lock(m_lock
);
91 child
->m_parent
= m_parent
;
93 child
->m_parent
= this;
97 if (m_flags
& stSortChildren
) {
98 std::list
<CStatTreeItemBase
*>::iterator it
= m_children
.begin();
99 while (it
!= m_children
.end() && id
< (*it
)->m_id
) {
102 m_children
.insert(it
, child
);
104 m_children
.push_back(child
);
108 #endif /* !EC_REMOTE */
110 bool CStatTreeItemBase::HasVisibleChildren()
112 wxMutexLocker
lock(m_lock
);
114 for (std::list
<CStatTreeItemBase
*>::const_iterator it
= m_children
.begin();
115 it
!= m_children
.end(); ++it
) {
116 if ((*it
)->IsVisible()) {
124 bool CStatTreeItemBase::HasChildWithId(uint32_t id
)
126 wxMutexLocker
lock(m_lock
);
128 for (std::list
<CStatTreeItemBase
*>::const_iterator it
= m_children
.begin();
129 it
!= m_children
.end(); ++it
) {
130 if ((*it
)->m_id
== id
) {
137 CStatTreeItemBase
* CStatTreeItemBase::GetChildById(uint32_t id
)
139 wxMutexLocker
lock(m_lock
);
141 for (std::list
<CStatTreeItemBase
*>::const_iterator it
= m_children
.begin();
142 it
!= m_children
.end(); ++it
) {
143 if ((*it
)->m_id
== id
) {
149 #endif /* !EC_REMOTE */
151 // Note: these functions do not lock the list, because it is already locked at the time they're called
153 StatTreeItemIterator
CStatTreeItemBase::GetFirstVisibleChild(uint32_t max_children
)
155 StatTreeItemIterator it
= m_children
.begin();
156 m_visible_counter
= --max_children
;
157 while (it
!= m_children
.end() && !(*it
)->IsVisible()) ++it
;
161 void CStatTreeItemBase::GetNextVisibleChild(StatTreeItemIterator
& it
)
163 if (m_flags
& stCapChildren
) {
164 if (m_visible_counter
== 0) {
165 it
= m_children
.end();
171 if (it
!= m_children
.end()) ++it
;
172 while (it
!= m_children
.end() && !(*it
)->IsVisible()) ++it
;
177 // Anything below is only for core.
181 bool CStatTreeItemBase::ValueSort(const CStatTreeItemBase
* a
, const CStatTreeItemBase
* b
)
183 if (a
->m_id
< 0x00000100 || a
->m_id
> 0x7fffffff || b
->m_id
< 0x00000100 || b
->m_id
> 0x7fffffff) {
184 return a
->m_id
> b
->m_id
;
186 return ((CStatTreeItemCounter
*)a
)->GetValue() > ((CStatTreeItemCounter
*)b
)->GetValue();
191 wxString
CStatTreeItemBase::GetDisplayString() const
193 return wxGetTranslation(m_label
);
197 CECTag
*CStatTreeItemBase::CreateECTag(uint32_t max_children
)
200 wxMutexLocker
lock(m_lock
);
201 CECTag
*tag
= new CECTag(EC_TAG_STATTREE_NODE
, m_label
);
202 tag
->AddTag(CECTag(EC_TAG_STATTREE_NODEID
, m_uniqueid
));
204 m_visible_counter
= max_children
- 1;
205 for (std::list
<CStatTreeItemBase
*>::const_iterator it
= m_children
.begin();
206 it
!= m_children
.end(); ++it
) {
207 CECTag
*tmp
= (*it
)->CreateECTag(max_children
);
211 if (m_flags
& stCapChildren
) {
212 if (m_visible_counter
== 0) {
227 /* CStatTreeItemSimple */
230 wxString
CStatTreeItemSimple::GetDisplayString() const
232 switch (m_valuetype
) {
234 switch (m_displaymode
) {
235 case dmTime
: return CFormat(wxGetTranslation(m_label
)) % CastSecondsToHM(m_intvalue
);
236 case dmBytes
: return CFormat(wxGetTranslation(m_label
)) % CastItoXBytes(m_intvalue
);
237 default: return CFormat(wxGetTranslation(m_label
)) % m_intvalue
;
239 case vtFloat
: return wxString::Format(wxGetTranslation(m_label
), m_floatvalue
);
240 case vtString
: return CFormat(wxGetTranslation(m_label
)) % m_stringvalue
;
241 default: return wxGetTranslation(m_label
);
246 bool CStatTreeItemSimple::IsVisible() const
248 if (m_flags
& stHideIfZero
) {
249 switch (m_valuetype
) {
250 case vtInteger
: return m_intvalue
!= 0;
251 case vtFloat
: return m_floatvalue
!= 0.0;
252 case vtString
: return !m_stringvalue
.IsEmpty();
253 default: return false;
259 void CStatTreeItemSimple::AddECValues(CECTag
*tag
) const
261 switch (m_valuetype
) {
263 if (m_displaymode
== dmTime
) {
264 CECTag
value(EC_TAG_STAT_NODE_VALUE
, (uint32
)m_intvalue
);
265 value
.AddTag(CECTag(EC_TAG_STAT_VALUE_TYPE
, (uint8
)EC_VALUE_TIME
));
268 CECTag
value(EC_TAG_STAT_NODE_VALUE
, (uint64
)m_intvalue
);
269 if (m_displaymode
== dmBytes
) {
270 value
.AddTag(CECTag(EC_TAG_STAT_VALUE_TYPE
, (uint8
)EC_VALUE_BYTES
));
277 CECTag
value(EC_TAG_STAT_NODE_VALUE
, m_floatvalue
);
278 value
.AddTag(CECTag(EC_TAG_STAT_VALUE_TYPE
, (uint8
)EC_VALUE_DOUBLE
));
283 CECTag
value(EC_TAG_STAT_NODE_VALUE
, m_stringvalue
);
284 value
.AddTag(CECTag(EC_TAG_STAT_VALUE_TYPE
, (uint8
)EC_VALUE_STRING
));
294 /* CStatTreeItemCounterTmpl */
297 template<typename _Tp
>
298 wxString CStatTreeItemCounterTmpl
<_Tp
>::GetDisplayString() const
300 wxString my_label
= wxGetTranslation(m_label
);
301 // This is needed for client names, for example
302 if (my_label
== m_label
) {
303 if (m_label
.Right(4) == wxT(": %s")) {
304 my_label
= wxGetTranslation(
305 m_label
.Mid(0, m_label
.Length() - 4)) +
306 wxString(wxT(": %s"));
309 CFormat
label(my_label
);
310 if (m_displaymode
== dmBytes
) {
311 return label
% CastItoXBytes(m_value
);
313 wxString result
= CFormat(wxT("%u")) % m_value
;
314 if ((m_flags
& stShowPercent
) && m_parent
) {
315 result
.append(wxString::Format(wxT(" (%.2f%%)"),
316 ((double)m_value
/ ((CStatTreeItemCounterTmpl
<_Tp
>*)m_parent
)->m_value
) * 100.0));
318 return label
% result
;
322 template wxString
CStatTreeItemCounter::GetDisplayString() const;
323 template wxString
CStatTreeItemNativeCounter::GetDisplayString() const;
327 template<typename _Tp
>
328 void CStatTreeItemCounterTmpl
<_Tp
>::AddECValues(CECTag
*tag
) const
330 CECTag
value(EC_TAG_STAT_NODE_VALUE
, (uint64
)m_value
);
331 if (m_displaymode
== dmBytes
) {
332 value
.AddTag(CECTag(EC_TAG_STAT_VALUE_TYPE
, (uint8
)EC_VALUE_BYTES
));
334 value
.AddTag(CECTag(EC_TAG_STAT_VALUE_TYPE
, (uint8
)EC_VALUE_ISTRING
));
335 if ((m_flags
& stShowPercent
) && m_parent
) {
336 CECTag
tmp(EC_TAG_STAT_NODE_VALUE
,
337 ((double)m_value
/ ((CStatTreeItemCounterTmpl
<_Tp
>*)m_parent
)->m_value
) * 100.0);
338 tmp
.AddTag(CECTag(EC_TAG_STAT_VALUE_TYPE
, (uint8
)EC_VALUE_DOUBLE
));
345 template void CStatTreeItemCounter::AddECValues(CECTag
*tag
) const;
346 template void CStatTreeItemNativeCounter::AddECValues(CECTag
*tag
) const;
348 /* CStatTreeItemUlDlCounter */
351 wxString
CStatTreeItemUlDlCounter::GetDisplayString() const
353 return CFormat(wxGetTranslation(m_label
)) %
354 a_brackets_b(CastItoXBytes(m_value
), CastItoXBytes(m_value
+ m_totalfunc()));
358 void CStatTreeItemUlDlCounter::AddECValues(CECTag
*tag
) const
360 CECTag
value(EC_TAG_STAT_NODE_VALUE
, m_value
);
361 value
.AddTag(CECTag(EC_TAG_STAT_VALUE_TYPE
, (uint8
)EC_VALUE_BYTES
));
362 CECTag
tmp(EC_TAG_STAT_NODE_VALUE
, m_value
+ m_totalfunc());
363 tmp
.AddTag(CECTag(EC_TAG_STAT_VALUE_TYPE
, (uint8
)EC_VALUE_BYTES
));
369 /* CStatTreeItemCounterMax */
372 wxString
CStatTreeItemCounterMax::GetDisplayString() const
374 return wxString::Format(wxGetTranslation(m_label
), m_value
);
378 void CStatTreeItemCounterMax::AddECValues(CECTag
*tag
) const
380 tag
->AddTag(CECTag(EC_TAG_STAT_NODE_VALUE
, (uint64
)m_value
));
384 /* CStatTreeItemPackets */
387 wxString
CStatTreeItemPackets::GetDisplayString() const
389 return CFormat(wxGetTranslation(m_label
)) %
390 a_brackets_b(CastItoXBytes(m_bytes
), CastItoIShort(m_packets
));
394 void CStatTreeItemPackets::AddECValues(CECTag
*tag
) const
396 CECTag
value(EC_TAG_STAT_NODE_VALUE
, m_bytes
);
397 value
.AddTag(CECTag(EC_TAG_STAT_VALUE_TYPE
, (uint8
)EC_VALUE_BYTES
));
398 CECTag
tmp(EC_TAG_STAT_NODE_VALUE
, (uint64
)m_packets
);
399 tmp
.AddTag(CECTag(EC_TAG_STAT_VALUE_TYPE
, (uint8
)EC_VALUE_ISHORT
));
405 /* CStatTreeItemPacketTotals */
408 wxString
CStatTreeItemPacketTotals::GetDisplayString() const
410 uint32_t tmp_packets
= m_packets
;
411 uint64_t tmp_bytes
= m_bytes
;
412 for (std::vector
<CStatTreeItemPackets
*>::const_iterator it
= m_counters
.begin();
413 it
!= m_counters
.end(); ++it
) {
414 tmp_packets
+= (*it
)->m_packets
;
415 tmp_bytes
+= (*it
)->m_bytes
;
418 return CFormat(wxGetTranslation(m_label
)) %
419 a_brackets_b(CastItoXBytes(tmp_bytes
), CastItoIShort(tmp_packets
));
423 void CStatTreeItemPacketTotals::AddECValues(CECTag
*tag
) const
425 uint32_t tmp_packets
= m_packets
;
426 uint64_t tmp_bytes
= m_bytes
;
427 for (std::vector
<CStatTreeItemPackets
*>::const_iterator it
= m_counters
.begin();
428 it
!= m_counters
.end(); ++it
) {
429 tmp_packets
+= (*it
)->m_packets
;
430 tmp_bytes
+= (*it
)->m_bytes
;
433 CECTag
value(EC_TAG_STAT_NODE_VALUE
, tmp_bytes
);
434 value
.AddTag(CECTag(EC_TAG_STAT_VALUE_TYPE
, (uint8
)EC_VALUE_BYTES
));
435 CECTag
tmp(EC_TAG_STAT_NODE_VALUE
, (uint64
)tmp_packets
);
436 tmp
.AddTag(CECTag(EC_TAG_STAT_VALUE_TYPE
, (uint8
)EC_VALUE_ISHORT
));
442 /* CStatTreeItemTimer */
445 wxString
CStatTreeItemTimer::GetDisplayString() const
447 return CFormat(wxGetTranslation(m_label
)) %
448 CastSecondsToHM(m_value
? GetTimerSeconds() : 0);
452 void CStatTreeItemTimer::AddECValues(CECTag
*tag
) const
454 CECTag
value(EC_TAG_STAT_NODE_VALUE
,
455 m_value
? (uint32
)GetTimerSeconds() : (uint32
)0);
456 value
.AddTag(CECTag(EC_TAG_STAT_VALUE_TYPE
, (uint8
)EC_VALUE_TIME
));
461 /* CStatTreeItemAverage */
464 wxString
CStatTreeItemAverage::GetDisplayString() const
466 if ((*m_divisor
) != 0) {
467 switch (m_displaymode
) {
469 return CFormat(wxGetTranslation(m_label
)) %
470 CastItoXBytes((*m_dividend
)/(*m_divisor
));
472 return CFormat(wxGetTranslation(m_label
)) %
473 CastSecondsToHM((*m_dividend
)/(*m_divisor
));
475 return CFormat(wxGetTranslation(m_label
)) %
476 (CFormat(wxT("%u")) % ((uint64
)(*m_dividend
)/(*m_divisor
))).GetString();
479 return CFormat(wxGetTranslation(m_label
)) % wxT("-");
484 void CStatTreeItemAverage::AddECValues(CECTag
*tag
) const
486 if ((*m_divisor
) != 0) {
487 uint64 data
= (*m_dividend
)/(*m_divisor
);
488 if (m_displaymode
== dmTime
) {
489 CECTag
value(EC_TAG_STAT_NODE_VALUE
, (uint32
)data
);
490 value
.AddTag(CECTag(EC_TAG_STAT_VALUE_TYPE
, (uint8
)EC_VALUE_TIME
));
493 CECTag
value(EC_TAG_STAT_NODE_VALUE
, data
);
494 if (m_displaymode
== dmBytes
) {
495 value
.AddTag(CECTag(EC_TAG_STAT_VALUE_TYPE
, (uint8
)EC_VALUE_BYTES
));
500 CECTag
value(EC_TAG_STAT_NODE_VALUE
, wxString(wxT("-")));
501 value
.AddTag(CECTag(EC_TAG_STAT_VALUE_TYPE
, (uint8
)EC_VALUE_STRING
));
507 /* CStatTreeItemAverageSpeed */
510 wxString
CStatTreeItemAverageSpeed::GetDisplayString() const
512 uint64 time
= m_timer
->GetTimerSeconds();
514 return CFormat(wxGetTranslation(m_label
)) % CastItoSpeed((*m_counter
)/time
);
516 return CFormat(wxGetTranslation(m_label
)) % CastItoSpeed(0);
521 void CStatTreeItemAverageSpeed::AddECValues(CECTag
*tag
) const
523 uint64 time
= m_timer
->GetTimerSeconds();
525 CECTag
value(EC_TAG_STAT_NODE_VALUE
, (uint32
)((*m_counter
)/time
));
526 value
.AddTag(CECTag(EC_TAG_STAT_VALUE_TYPE
, (uint8
)EC_VALUE_SPEED
));
529 CECTag
value(EC_TAG_STAT_NODE_VALUE
, (uint32
)0);
530 value
.AddTag(CECTag(EC_TAG_STAT_VALUE_TYPE
, (uint8
)EC_VALUE_SPEED
));
536 /* CStatTreeItemRatio */
538 wxString
CStatTreeItemRatio::GetString() const
541 double v1
= m_counter1
->GetValue();
542 double v2
= m_counter2
->GetValue();
543 if (v1
> 0 && v2
> 0) {
545 ret
= CFormat(wxT("%.2f : 1")) % (v1
/ v2
);
547 ret
= CFormat(wxT("1 : %.2f")) % (v2
/ v1
);
550 if (m_totalfunc1
&& m_totalfunc2
) {
551 double t1
= m_totalfunc1() + v1
;
552 double t2
= m_totalfunc2() + v2
;
554 ret
+= CFormat(wxT(" (%.2f : 1)")) % (t1
/ t2
);
556 ret
+= CFormat(wxT(" (1 : %.2f)")) % (t2
/ t1
);
560 ret
= _("Not available");
566 wxString
CStatTreeItemRatio::GetDisplayString() const
568 return CFormat(wxGetTranslation(m_label
)) % GetString();
572 void CStatTreeItemRatio::AddECValues(CECTag
*tag
) const
574 CECTag
value(EC_TAG_STAT_NODE_VALUE
, GetString());
575 value
.AddTag(CECTag(EC_TAG_STAT_VALUE_TYPE
, (uint8
)EC_VALUE_STRING
));
580 /* CStatTreeItemReconnects */
583 wxString
CStatTreeItemReconnects::GetDisplayString() const
585 return CFormat(wxGetTranslation(m_label
)) % (m_value
? m_value
- 1 : 0);
589 void CStatTreeItemReconnects::AddECValues(CECTag
*tag
) const
591 tag
->AddTag(CECTag(EC_TAG_STAT_NODE_VALUE
,
592 m_value
? (uint64
)(m_value
- 1) : (uint64
)0));
595 /* CStatTreeItemMaxConnLimitReached */
598 wxString
CStatTreeItemMaxConnLimitReached::GetDisplayString() const
601 return CFormat(wxGetTranslation(m_label
)) %
602 (wxString::Format(wxT("%i : "), m_count
) +
603 m_time
.FormatISODate() +
605 m_time
.FormatISOTime());
607 return CFormat(wxGetTranslation(m_label
)) % _("Never");
612 void CStatTreeItemMaxConnLimitReached::AddECValues(CECTag
*tag
) const
616 result
= wxString::Format(wxT("%i : "), m_count
) +
617 m_time
.FormatISODate() +
619 m_time
.FormatISOTime();
621 result
= wxTRANSLATE("Never");
623 CECTag
value(EC_TAG_STAT_NODE_VALUE
, result
);
624 value
.AddTag(CECTag(EC_TAG_STAT_VALUE_TYPE
, (uint8
)EC_VALUE_STRING
));
628 /* CStatTreeItemTotalClients */
631 wxString
CStatTreeItemTotalClients::GetDisplayString() const
633 return CFormat(wxGetTranslation(m_label
)) %
634 (m_known
->GetValue() + m_unknown
->GetValue()) %
639 void CStatTreeItemTotalClients::AddECValues(CECTag
*tag
) const
641 CECTag
value1(EC_TAG_STAT_NODE_VALUE
,
642 (uint64
)(m_known
->GetValue() + m_unknown
->GetValue()));
644 CECTag
value2(EC_TAG_STAT_NODE_VALUE
,
645 (uint64
)m_known
->GetValue());
649 #endif /* !EC_REMOTE */
650 // File_checked_for_headers