void CDownloads::ClearCompleted()
{
	CSingleLock pLock( &Transfers.m_pSection, TRUE );
	
	for ( POSITION pos = GetIterator() ; pos ; )
	{
		CDownload* pDownload = GetNext( pos );
		if ( ( pDownload->IsCompleted() ) && ( !pDownload->IsSeeding() ) ) pDownload->Remove();
	}
}
BOOL CDownloads::CheckActive(CDownload* pDownload, int nScope) const
{
	for ( POSITION pos = GetReverseIterator() ; pos && nScope > 0 ; )
	{
		CDownload* pTest = GetPrevious( pos );
		BOOL bActive = pTest->IsPaused() == FALSE && pTest->IsCompleted() == FALSE;
		
		if ( pDownload == pTest ) return bActive;
		if ( bActive ) nScope--;
	}
	
	return FALSE;
}
CDownload* CDownloads::FindByED2K(const MD4* pED2K, BOOL bSharedOnly) const
{
	for ( POSITION pos = GetIterator() ; pos ; )
	{
		CDownload* pDownload = GetNext( pos );
		if ( pDownload->m_bED2K && pDownload->m_pED2K == *pED2K )
		{
			if ( ! bSharedOnly || ( pDownload->IsShared() && pDownload->IsStarted() )
				&& ( pDownload->m_nSize > ED2K_PART_SIZE || pDownload->IsCompleted() ) )
				return pDownload;
		}
	}
	
	return NULL;
}
int CDownloads::GetActiveTorrentCount() const
{
	int nCount = 0;
	
	for ( POSITION pos = GetIterator() ; pos ; )
	{
		CDownload* pDownload = GetNext( pos );
		
		if ( pDownload->IsDownloading() && pDownload->m_bBTH &&
			! pDownload->IsSeeding()	&& ! pDownload->IsCompleted() &&
			! pDownload->IsMoving()		&& ! pDownload->IsPaused() )
				nCount++;
	}
	
	return nCount;
}
int CDownloads::GetSeedCount() const
{
	int nCount = 0;
	
	for ( POSITION pos = GetIterator() ; pos ; )
	{
		CDownload* pDownload = GetNext( pos );
		
		if ( pDownload->IsSeeding() )
			nCount++;		//Manually seeded Torrent
		else if ( pDownload->IsCompleted() && pDownload->m_bBTH && pDownload->IsFullyVerified() )
			nCount++;		//Torrent that has completed
	}
	
	return nCount;
}
int CDownloads::GetTryingCount(BOOL bTorrentsOnly) const
{
	int nCount = 0;
	
	for ( POSITION pos = GetIterator() ; pos ; )
	{
		CDownload* pDownload = GetNext( pos );
		
		if ( ( pDownload->IsTrying() ) && ( ! pDownload->IsCompleted() ) && ( ! pDownload->IsPaused() ) )
		{
			if ( ( pDownload->m_bBTH ) || ( ! bTorrentsOnly ) )
				nCount++;
		}
	}
	
	return nCount;
}
Beispiel #7
0
void CRemote::PageDownloads()
{
	if ( CheckCookie() ) return;
	m_nTab = tabDownloads;

	CString str;
	str.Format( L"%i", GetRandomNum( 0i32, _I32_MAX ) );

	CSingleLock pLock( &DownloadGroups.m_pSection, TRUE );

	Prepare();		// Header
	Add( L"random", str );
	Output( L"downloadsHeader" );

	BOOL bExclusive = ! GetKey( L"group_exclusive" ).IsEmpty();
	BOOL bReveal = ! GetKey( L"group_reveal" ).IsEmpty();

	for ( POSITION posGroup = DownloadGroups.GetIterator(); posGroup != NULL; )
	{
		CDownloadGroup* pGroup = DownloadGroups.GetNext( posGroup );

		CString strGroupID;
		strGroupID.Format( L"%p", pGroup );
		Add( L"group_id", strGroupID );

		if ( bExclusive )
			pGroup->m_bRemoteSelected = ( GetKey( L"group_exclusive" ) == strGroupID );
		else if ( bReveal )
			pGroup->m_bRemoteSelected = TRUE;
		else if ( GetKey( L"group_select" ) == strGroupID )
			pGroup->m_bRemoteSelected = TRUE;
		else if ( GetKey( L"group_deselect" ) == strGroupID )
			pGroup->m_bRemoteSelected = FALSE;

		Add( L"group_caption", pGroup->m_sName );
		if ( pGroup->m_bRemoteSelected )
			Add( L"group_selected", L"true" );
		Output( L"downloadsTab" );
		Prepare( L"group_" );
	}

	if ( ! GetKey( L"filter_set" ).IsEmpty() )
	{
		Settings.Downloads.FilterMask &= ~( DLF_ACTIVE | DLF_PAUSED | DLF_QUEUED | DLF_SOURCES | DLF_SEED );
		if ( GetKey( L"filter_active" ) == L"1" ) Settings.Downloads.FilterMask |= DLF_ACTIVE;
		if ( GetKey( L"filter_paused" ) == L"1" ) Settings.Downloads.FilterMask |= DLF_PAUSED;
		if ( GetKey( L"filter_queued" ) == L"1" ) Settings.Downloads.FilterMask |= DLF_QUEUED;
		if ( GetKey( L"filter_sources" ) == L"1" ) Settings.Downloads.FilterMask |= DLF_SOURCES;
		if ( GetKey( L"filter_seeds" ) == L"1" )  Settings.Downloads.FilterMask |= DLF_SEED;
		Settings.Downloads.ShowSources = ( GetKey( L"filter_show_all" ) == L"1" );
	}

	Add( L"filter_active", ( Settings.Downloads.FilterMask & DLF_ACTIVE ) ? L"checked=\"checked\"" : L"" );
	Add( L"filter_paused", ( Settings.Downloads.FilterMask & DLF_PAUSED ) ? L"checked=\"checked\"" : L"" );
	Add( L"filter_queued", ( Settings.Downloads.FilterMask & DLF_QUEUED ) ? L"checked=\"checked\"" : L"" );
	Add( L"filter_sources", ( Settings.Downloads.FilterMask & DLF_SOURCES ) ? L"checked=\"checked\"" : L"" );
	Add( L"filter_seeds", ( Settings.Downloads.FilterMask & DLF_PAUSED ) ? L"checked=\"checked\"" : L"" );
	Add( L"filter_show_all", Settings.Downloads.ShowSources ? L"checked=\"checked\"" : L"" );
	Output( L"downloadsTop" );

	for ( POSITION posDownload = Downloads.GetIterator(); posDownload != NULL; )
	{
		CDownload* pDownload = Downloads.GetNext( posDownload );

		CString strDownloadID;
		strDownloadID.Format( L"%p", pDownload );

		if ( GetKey( L"modify_id" ) == strDownloadID )
		{
			CString strAction = GetKey( L"modify_action" );
			strAction.MakeLower();

			if ( strAction == L"expand" )
			{
				if ( CDownloadsCtrl::IsExpandable( pDownload ) )
					pDownload->m_bExpanded = TRUE;
			}
			else if ( strAction == L"collapse" )
			{
				if ( CDownloadsCtrl::IsExpandable( pDownload ) )
					pDownload->m_bExpanded = FALSE;
			}
			else if ( strAction == L"resume" )
			{
				pDownload->Resume();
			}
			else if ( strAction == L"pause" )
			{
				if ( ! pDownload->IsPaused() && ! pDownload->IsTasking() )
					pDownload->Pause();
			}
			else if ( strAction == L"cancel" )
			{
				if ( ! pDownload->IsTasking() )
					pDownload->Remove();
				continue;
			}
			else if ( strAction == L"clear" )
			{
				if ( pDownload->IsCompleted() && ! pDownload->IsPreviewVisible() )
				{
					pDownload->Remove();
					continue;
				}
			}
			else if ( strAction == L"more_sources" )
			{
				// roo_koo_too improvement
				pDownload->FindMoreSources();
			}
		}

		if ( CDownloadsCtrl::IsFiltered( pDownload ) ) continue;

		CDownloadGroup* pGroup = NULL;

		for ( POSITION posGroup = DownloadGroups.GetIterator(); posGroup != NULL; )
		{
			pGroup = DownloadGroups.GetNext( posGroup );
			if ( pGroup->m_bRemoteSelected && pGroup->Contains( pDownload ) ) break;
			pGroup = NULL;
		}

		if ( pGroup == NULL ) continue;

		Add( L"download_id", strDownloadID );
		Add( L"download_filename", pDownload->GetDisplayName() );
		Add( L"download_size", ( pDownload->m_nSize == SIZE_UNKNOWN ) ?
			LoadString( IDS_STATUS_UNKNOWN ) : Settings.SmartVolume( pDownload->m_nSize ) );
		int nProgress = int( pDownload->GetProgress() );
		str.Format( L"%i", nProgress );
		Add( L"download_percent", str );
		str.Format( L"%i", 100 - nProgress );
		Add( L"download_percent_inverse", str );
		Add( L"download_speed", Settings.SmartSpeed( pDownload->GetMeasuredSpeed() ) );
		if ( CDownloadsCtrl::IsExpandable( pDownload ) )
		{
			if ( pDownload->m_bExpanded )
				Add( L"download_is_expanded", L"true" );
			else
				Add( L"download_is_collapsed", L"true" );
		}
		if ( pDownload->IsCompleted() )
			Add( L"download_is_complete", L"true" );
		else if ( pDownload->IsPaused() )
			Add( L"download_is_paused", L"true" );

		Add( L"download_status", pDownload->GetDownloadStatus() );
		Add( L"download_sources", pDownload->GetDownloadSources() );
		Output( L"downloadsDownload" );

		if ( pDownload->m_bExpanded && CDownloadsCtrl::IsExpandable( pDownload ) )
		{
			for ( POSITION posSource = pDownload->GetIterator(); posSource; )
			{
				CDownloadSource* pSource = pDownload->GetNext( posSource );

				ASSERT( pSource->m_pDownload == pDownload );

				CString strSourceID;
				strSourceID.Format( L"%p", pSource );

				if ( GetKey( L"modify_id" ) == strSourceID )
				{
					CString strModifyAction = GetKey( L"modify_action" );
					strModifyAction.MakeLower();

					if ( strModifyAction == L"access" )
					{
						// Only create a new Transfer if there isn't already one
						if ( pSource->IsIdle() && pSource->m_nProtocol != PROTOCOL_ED2K )
						{
							if ( pDownload->IsPaused() )
								pDownload->Resume();	// Workaround duplicate

							pDownload->Resume();

							if ( pSource->m_bPushOnly )
								pSource->PushRequest();
							else if ( CDownloadTransfer* pTransfer = pSource->CreateTransfer() )
								pTransfer->Initiate();
						}
					}
					else if ( strModifyAction == L"forget" )
					{
						pSource->Remove( TRUE, TRUE );
						continue;
					}
				}

				if ( Settings.Downloads.ShowSources || pSource->IsConnected() )
				{
					Add( L"source_id", strSourceID );
					Add( L"source_agent", pSource->m_sServer );
					Add( L"source_nick", pSource->m_sNick );

					if ( ! pSource->IsIdle() )
					{
						Add( L"source_status", pSource->GetState( FALSE ) );
						Add( L"source_volume", Settings.SmartVolume( pSource->GetDownloaded() ) );
						if ( DWORD nSpeed = pSource->GetMeasuredSpeed() )
							Add( L"source_speed", Settings.SmartSpeed( nSpeed ) );
						Add( L"source_address", pSource->GetAddress() );
						Add( L"source_caption", pSource->GetAddress() + L" - " + pSource->m_sNick );
					}
					else	// No transfer
					{
						Add( L"source_address", CString( inet_ntoa( pSource->m_pAddress ) ) );
						Add( L"source_caption", CString( inet_ntoa( pSource->m_pAddress ) ) + L" - " + pSource->m_sNick );

						if ( pSource->m_tAttempt > 0 )
						{
							DWORD tNow = GetTickCount();

							if ( pSource->m_tAttempt >= tNow )
							{
								tNow = ( pSource->m_tAttempt - tNow ) / 1000;
								CString strSourceStatus;
								strSourceStatus.Format( L"%.2u:%.2u", tNow / 60, tNow % 60 );
								Add( L"source_status", strSourceStatus );
							}
						}
					}

					Output( L"downloadsSource" );
					Prepare( L"source_" );
				}
			}
		}

		Prepare( L"download_" );
	} // for POSITION loop

	Output( L"downloadsBottom" );
	Output( L"downloadsFooter" );
}
void CHomeDownloadsBox::Update()
{
	if ( m_pDocument == NULL ) return;

	CSingleLock pLock( &Transfers.m_pSection );
	if ( ! pLock.Lock( 50 ) ) return;

	BOOL bChanged = FALSE;
	CString str;

	for ( INT_PTR nItem = m_pList.GetSize() - 1 ; nItem >= 0 ; nItem-- )
	{
		Item* pItem = m_pList.GetAt( nItem );

		if ( ! Downloads.CheckActive( pItem->m_pDownload, 6 ) )
		{
			delete pItem;
			m_pList.RemoveAt( nItem );
			bChanged = TRUE;
			m_pHover = NULL;
			KillTimer( 2 );
		}
	}

	int nCount = 0;
	int nInsert = 0;

	for ( POSITION pos = Downloads.GetReverseIterator() ; pos && nCount < 6 ; )
	{
		CDownload* pDownload = Downloads.GetPrevious( pos );
		if ( pDownload->IsPaused() ) continue;
		if ( pDownload->IsCompleted() ) continue;

		Item* pItem = NULL;

		for ( int nItem = 0 ; nItem < m_pList.GetSize() ; nItem++ )
		{
			pItem = m_pList.GetAt( nItem );
			if ( pItem->m_pDownload == pDownload ) break;
			pItem = NULL;
		}

		if ( pItem == NULL )
		{
			pItem				= new Item();
			pItem->m_pDownload	= pDownload;
			pItem->m_sText		= pDownload->GetDisplayName();
			pItem->m_nIcon16	= ShellIcons.Get( pItem->m_sText, 16 );
			m_pList.InsertAt( nInsert++, pItem );
			bChanged = TRUE;
			m_pHover = NULL;
			KillTimer( 2 );
		}

		QWORD nComplete	= pDownload->GetVolumeComplete();
		BOOL bPaused	= pDownload->GetFirstTransfer() == NULL;

		if ( pItem->m_nComplete != nComplete ||
			 pItem->m_bPaused != bPaused ||
			 pItem->m_nSize != pDownload->m_nSize )
		{
			pItem->m_nSize		= pDownload->m_nSize;
			pItem->m_nComplete	= nComplete;
			pItem->m_bPaused	= bPaused;
			bChanged = TRUE;
		}

		nCount++;
	}

	nCount = static_cast< int >( m_pList.GetSize() * 18 );
	if ( nCount ) nCount += 6;

	m_pDocument->ShowGroup( 1, m_pList.GetSize() == 0 );

	int nActive = (int)CGraphItem::GetValue( GRC_DOWNLOADS_FILES );

	if ( nActive > 1 )
	{
		if ( m_pdDownloadsMany )
		{
			str.Format( m_sDownloadsMany, nActive );
			m_pdDownloadsMany->SetText( str );
			m_pdDownloadsMany->Show( TRUE );
		}
		if ( m_pdDownloadsOne )  m_pdDownloadsOne->Show( FALSE );
		if ( m_pdDownloadsNone ) m_pdDownloadsNone->Show( FALSE );
	}
	else if ( nActive == 1 )
	{
		if ( m_pdDownloadsMany ) m_pdDownloadsMany->Show( FALSE );
		if ( m_pdDownloadsOne )  m_pdDownloadsOne->Show( TRUE );
		if ( m_pdDownloadsNone ) m_pdDownloadsNone->Show( FALSE );
	}
	else
	{
		if ( m_pdDownloadsMany ) m_pdDownloadsMany->Show( FALSE );
		if ( m_pdDownloadsOne )  m_pdDownloadsOne->Show( FALSE );
		if ( m_pdDownloadsNone ) m_pdDownloadsNone->Show( TRUE );
	}

	m_pDocument->ShowGroup( 1, nActive == 0 );

	// Download Stats Count
	if ( Statistics.Today.Downloads.Files == 0 )
	{
		if ( m_pdDownloadedNone ) m_pdDownloadedNone->Show( TRUE );
		if ( m_pdDownloadedOne )  m_pdDownloadedOne->Show( FALSE );
		if ( m_pdDownloadedMany ) m_pdDownloadedMany->Show( FALSE );
	}
	else if ( Statistics.Today.Downloads.Files == 1 )
	{
		if ( m_pdDownloadedNone ) m_pdDownloadedNone->Show( FALSE );
		if ( m_pdDownloadedOne )  m_pdDownloadedOne->Show( TRUE );
		if ( m_pdDownloadedMany ) m_pdDownloadedMany->Show( FALSE );
	}
	else
	{
		str.Format( m_sDownloadedMany, (int)Statistics.Today.Downloads.Files );

		if ( m_pdDownloadedNone ) m_pdDownloadedNone->Show( FALSE );
		if ( m_pdDownloadedOne )  m_pdDownloadedOne->Show( FALSE );

		if ( m_pdDownloadedMany )
		{
			m_pdDownloadedMany->SetText( str );
			m_pdDownloadedMany->Show( TRUE );
		}
	}

	if ( m_pdDownloadedVolume )
	{
		str = Settings.SmartVolume( Statistics.Today.Downloads.Volume, KiloBytes );
		m_pdDownloadedVolume->SetText( str );
		if ( Statistics.Last.Bandwidth.Incoming > 120 )		// More activity than idle connection
			GetView().Invalidate();
	}

	if ( GetView().IsModified() )
	{
		CRect rc;
		GetClientRect( &rc );
		m_nWidth = rc.Width();
		nCount += m_wndView.FullHeightMove( 0, nCount, m_nWidth );
	}
	else
	{
		CRect rc;
		m_wndView.GetWindowRect( &rc );
		ScreenToClient( &rc );

		if ( rc.top != nCount )
		{
			m_nWidth = rc.Width();
			nCount += m_wndView.FullHeightMove( 0, nCount, m_nWidth );
		}
		else
		{
			m_wndView.GetClientRect( &rc );
			nCount += rc.Height();
		}
	}

	SetSize( nCount );
}