⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ctrlsearchdetailpanel.cpp

📁 p2p软件
💻 CPP
📖 第 1 页 / 共 2 页
字号:
//
// CtrlSearchDetailPanel.cpp
//
// Copyright (c) Shareaza Development Team, 2002-2004.
// This file is part of SHAREAZA (www.shareaza.com)
//
// Shareaza is free software; you can redistribute it
// and/or modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2 of
// the License, or (at your option) any later version.
//
// Shareaza is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Shareaza; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
//

#include "StdAfx.h"
#include "Shareaza.h"
#include "Settings.h"
#include "MatchObjects.h"
#include "QueryHit.h"
#include "Buffer.h"
#include "XML.h"
#include "Schema.h"
#include "SchemaCache.h"
#include "Library.h"
#include "SHA.h"

#include "CoolInterface.h"
#include "ImageServices.h"
#include "ImageFile.h"
#include "RichElement.h"
#include "ShellIcons.h"
#include "Emoticons.h"
#include "Skin.h"
#include "CtrlSearchDetailPanel.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

IMPLEMENT_DYNAMIC(CSearchDetailPanel, CWnd)

BEGIN_MESSAGE_MAP(CSearchDetailPanel, CWnd)
	//{{AFX_MSG_MAP(CSearchDetailPanel)
	ON_WM_CREATE()
	ON_WM_DESTROY()
	ON_WM_SIZE()
	ON_WM_VSCROLL()
	ON_WM_PAINT()
	ON_WM_SETCURSOR()
	ON_WM_LBUTTONUP()
	ON_WM_ERASEBKGND()
	ON_NOTIFY(RVN_CLICK, IDC_REVIEW_VIEW, OnClickReview)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

#define SIZE_INTERNAL	1982


/////////////////////////////////////////////////////////////////////////////
// CSearchDetailPanel construction

CSearchDetailPanel::CSearchDetailPanel()
{
	m_pMatches	= NULL;
	m_bValid	= FALSE;
	m_pFile		= NULL;
	m_hThread	= NULL;
	m_bThread	= FALSE;
	m_crLight	=	CCoolInterface::CalculateColour(
					CoolInterface.m_crTipBack, RGB( 255, 255, 255 ), 128 );
	m_nThumbSize = 0;
}

CSearchDetailPanel::~CSearchDetailPanel()
{
	ClearReviews();
}

/////////////////////////////////////////////////////////////////////////////
// CSearchDetailPanel operations

BOOL CSearchDetailPanel::Create(CWnd* pParentWnd) 
{
	CRect rect( 0, 0, 0, 0 );
	return CWnd::Create( NULL, NULL, WS_CHILD|WS_VSCROLL|WS_CLIPCHILDREN, rect, pParentWnd, IDC_DETAIL_PANEL, NULL );
}

void CSearchDetailPanel::Update(CMatchFile* pFile)
{
	CSingleLock pLock( &m_pSection, TRUE );
	
	CancelPreview();
	ClearReviews();
	
	if ( pFile == NULL )
	{
		if ( m_bValid )
		{
			m_bValid = FALSE;
			OnSize( SIZE_INTERNAL, 0, 0 );
		}
		return;
	}
	
	m_pMatches	= pFile->m_pList;
	m_bValid	= TRUE;
	m_pFile		= pFile;
	m_pSHA1		= pFile->m_pSHA1;
	m_sName		= pFile->m_pBest->m_sName;
	m_sSize		= pFile->m_sSize;
	m_nIcon32	= ShellIcons.Get( pFile->m_pBest->m_sName, 32 );
	m_nIcon48	= ShellIcons.Get( pFile->m_pBest->m_sName, 48 );
	m_nRating	= pFile->m_nRated ? pFile->m_nRating / pFile->m_nRated : 0;
	
	m_bCanPreview	= FALSE;
	m_pSchema		= NULL;
	
	DWORD nSpeed = 0;
	
	for ( CQueryHit* pHit = pFile->m_pHits ; pHit ; pHit = pHit->m_pNext )
	{
		if ( m_pSchema == NULL ) m_pSchema = SchemaCache.Get( pHit->m_sSchemaURI );
		nSpeed += pHit->m_nSpeed;
		
		if ( pHit->m_bSHA1 && pHit->m_bPush == TS_FALSE )
		{
			if ( pHit->m_bPreview )
			{
				m_pPreviewURLs.AddTail( pHit->m_sPreview );
				m_bCanPreview = TRUE;
			}
#ifdef _DEBUG
			else if (	_tcsistr( pHit->m_sName, _T(".mpg") ) ||
						_tcsistr( pHit->m_sName, _T(".mpeg") ) ||
						_tcsistr( pHit->m_sName, _T(".avi") ) ||
						_tcsistr( pHit->m_sName, _T(".jpg") ) ||
						_tcsistr( pHit->m_sName, _T(".jpeg") ) )
			{
				CString strURL;
				strURL.Format( _T("http://%s:%i/gnutella/preview/v1?%s"),
					(LPCTSTR)CString( inet_ntoa( pHit->m_pAddress ) ), pHit->m_nPort,
					(LPCTSTR)CSHA::HashToString( &pHit->m_pSHA1, TRUE ) );
				m_pPreviewURLs.AddTail( strURL );
				m_bCanPreview = TRUE;
			}
#endif
		}
		
		if ( pHit->m_nRating > 0 || pHit->m_sComments.GetLength() > 0 )
		{
			m_pReviews.AddTail( new Review( &pHit->m_pClientID,
				&pHit->m_pAddress, pHit->m_sNick, pHit->m_nRating, pHit->m_sComments ) );
		}
	}
	
	m_pMetadata.Setup( m_pSchema );
	
	if ( m_pSchema != NULL )
	{
		for ( CQueryHit* pHit = pFile->m_pHits ; pHit ; pHit = pHit->m_pNext )
		{
			if ( pHit->m_pXML != NULL && m_pSchema->CheckURI( pHit->m_sSchemaURI ) )
			{
				m_pMetadata.Combine( pHit->m_pXML );
			}
		}
	}
	
	m_pMetadata.Vote();
	m_pMetadata.CreateLinks();
	m_pMetadata.Clean( 4096 );
	
	CString strFormat, strPart;
	m_sStatus.Empty();
	
	if ( pFile->m_nSources == 1 )
	{
		LoadString( strFormat, IDS_SEARCH_DETAILS_SOURCES_ONE );
		strPart.Format( strFormat, (LPCTSTR)Settings.SmartVolume( nSpeed, TRUE, TRUE ) );
		m_sStatus += strPart;
	}
	else
	{
		if ( pFile->m_nSources == 0 ) nSpeed = 0;
		LoadString( strFormat, IDS_SEARCH_DETAILS_SOURCES_MANY );
		strPart.Format( strFormat, pFile->m_nSources, (LPCTSTR)Settings.SmartVolume( nSpeed, TRUE, TRUE ) );
		m_sStatus += strPart;
	}
	
	if ( m_pReviews.GetCount() > 1 )
	{
		LoadString( strFormat, IDS_SEARCH_DETAILS_REVIEWS_MANY );
		strPart.Format( strFormat, m_pReviews.GetCount() );
		m_sStatus += strPart;
	}
	else if ( m_pReviews.GetCount() == 1 )
	{
		LoadString( strPart, IDS_SEARCH_DETAILS_REVIEWS_ONE );
		m_sStatus += strPart;
	}
	
	if ( pFile->m_pPreview != NULL && pFile->m_nPreview > 0 )
	{
		CImageServices pServices;
		CImageFile pImage( &pServices );
		
		if ( pImage.LoadFromMemory( _T(".jpg"), (LPCVOID)pFile->m_pPreview, pFile->m_nPreview, FALSE, TRUE ) )
		{
			pLock.Unlock();
			OnPreviewLoaded( &m_pSHA1, &pImage );
		}
	}
	
	OnSize( SIZE_INTERNAL, 0, 0 );
}

void CSearchDetailPanel::ClearReviews()
{
	for ( POSITION pos = m_pReviews.GetHeadPosition() ; pos ; )
	{
		delete (Review*)m_pReviews.GetNext( pos );
	}
	
	m_pReviews.RemoveAll();
}

/////////////////////////////////////////////////////////////////////////////
// CSearchDetailPanel message handlers

int CSearchDetailPanel::OnCreate(LPCREATESTRUCT lpCreateStruct) 
{
	if ( CWnd::OnCreate( lpCreateStruct ) == -1 ) return -1;
	return 0;
}

void CSearchDetailPanel::OnDestroy() 
{
	ClearReviews();

	m_bThread = FALSE;
	CancelPreview();
	
	if ( m_hThread != NULL )
	{
		m_pWakeup.SetEvent();
		
		for ( int nAttempt = 10 ; nAttempt > 0 ; nAttempt-- )
		{
			DWORD nCode;
			if ( ! GetExitCodeThread( m_hThread, &nCode ) ) break;
			if ( nCode != STILL_ACTIVE ) break;
			Sleep( 100 );
		}
		
		if ( nAttempt == 0 )
		{
			TerminateThread( m_hThread, 0 );
			theApp.Message( MSG_DEBUG, _T("WARNING: Terminating CSearchDetailPanel thread.") );
			Sleep( 100 );
		}
		
		m_hThread = NULL;
	}
	
	CWnd::OnDestroy();
}

void CSearchDetailPanel::OnSize(UINT nType, int cx, int cy) 
{
	if ( nType != SIZE_INTERNAL ) CWnd::OnSize( nType, cx, cy );
	
	SCROLLINFO pInfo;
	CRect rc;
	
	GetWindowRect( &rc );
	rc.OffsetRect( -rc.left, -rc.top );
	rc.right -= GetSystemMetrics( SM_CXVSCROLL );
	
	int nThumbSize = rc.Height() - 16;
	nThumbSize = max( nThumbSize, 64 );
	nThumbSize = min( nThumbSize, 128 );
	rc.left += nThumbSize + 16;
	rc.right -= 8;
	
	CClientDC dc( this );
	int nHeight = 54 + m_pMetadata.Layout( &dc, rc.Width() );
	
	for ( POSITION pos = m_pReviews.GetHeadPosition() ; pos ; )
	{
		Review* pReview = (Review*)m_pReviews.GetNext( pos );
		CRect rcReview( rc.left, nHeight, rc.right, nHeight );
		pReview->Layout( this, &rcReview );
		nHeight += rcReview.Height();
	}
	
	if ( ! m_bValid ) nHeight = 0;
	
	pInfo.cbSize	= sizeof(pInfo);
	pInfo.fMask		= SIF_ALL & ~SIF_TRACKPOS;
	pInfo.nMin		= 0;
	pInfo.nMax		= nHeight;
	pInfo.nPage		= rc.Height();
	pInfo.nPos		= 0;
	pInfo.nPos		= max( 0, min( pInfo.nPos, pInfo.nMax - (int)pInfo.nPage + 1 ) );
	
	SetScrollInfo( SB_VERT, &pInfo, TRUE );
	
	Invalidate();
}

void CSearchDetailPanel::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) 
{
	SCROLLINFO pScroll;
	
	ZeroMemory( &pScroll, sizeof(pScroll) );
	pScroll.cbSize	= sizeof(pScroll);
	pScroll.fMask	= SIF_ALL;
	
	GetScrollInfo( SB_VERT, &pScroll );
	
	switch ( nSBCode )
	{
	case SB_TOP:
		pScroll.nPos = 0;
		break;
	case SB_BOTTOM:
		pScroll.nPos = pScroll.nMax - 1;
		break;
	case SB_LINEUP:
		pScroll.nPos -= 8;
		break;
	case SB_LINEDOWN:
		pScroll.nPos += 8;
		break;
	case SB_PAGEUP:
		pScroll.nPos -= pScroll.nPage;
		break;
	case SB_PAGEDOWN:
		pScroll.nPos += pScroll.nPage;
		break;
	case SB_THUMBPOSITION:
	case SB_THUMBTRACK:
		pScroll.nPos = pScroll.nTrackPos;
		break;
	}
	
	pScroll.fMask	= SIF_POS;
	pScroll.nPos	= max( 0, min( pScroll.nPos, pScroll.nMax ) );
	
	SetScrollInfo( SB_VERT, &pScroll );

	for ( POSITION pos = m_pReviews.GetHeadPosition() ; pos ; )
	{
		Review* pReview = (Review*)m_pReviews.GetNext( pos );
		pReview->Reposition( pScroll.nPos );
	}
	
	Invalidate();
}

BOOL CSearchDetailPanel::OnEraseBkgnd(CDC* pDC) 
{
	return TRUE;
}

void CSearchDetailPanel::OnPaint() 
{
	CSingleLock pLock( &m_pSection, TRUE );
	CPaintDC dc( this );
	CRect rcClient;
	CString str;
	
	GetClientRect( &rcClient );
	
	CFont* pOldFont = dc.GetCurrentFont();
	dc.SetBkColor( CoolInterface.m_crWindow );
	dc.SetBkMode( OPAQUE );
	dc.SetTextColor( CoolInterface.m_crText );
	
	if ( ! m_bValid )
	{
		dc.SelectObject( &CoolInterface.m_fntNormal );
		LoadString( str, IDS_SEARCH_DETAILS_EMPTY );
		CSize sz = dc.GetTextExtent( str );
		CPoint pt = rcClient.CenterPoint();
		pt.x -= sz.cx / 2; pt.y -= sz.cy / 2;
		dc.ExtTextOut( pt.x, pt.y, ETO_OPAQUE, &rcClient, str, NULL );
		dc.SelectObject( pOldFont );
		return;
	}
	
	CRect rcWork( 0, 0, 0, 0 );
	DrawThumbnail( &dc, rcClient, rcWork );
	
	dc.SetViewportOrg( 0, -GetScrollPos( SB_VERT ) );
	
	dc.SetBkColor( CoolInterface.m_crWindow );
	dc.SetTextColor( CoolInterface.m_crText );
	
	dc.SelectObject( &CoolInterface.m_fntCaption );
	DrawText( &dc, rcWork.left, rcWork.top, m_sName );
	
	CPoint ptStar( rcWork.right - 3, rcWork.top - 2 );
	
	if ( m_nRating > 1 )
	{
		for ( int nRating = m_nRating - 1 ; nRating ; nRating-- )
		{
			ptStar.x -= 16;
			ShellIcons.Draw( &dc, SHI_STAR, 16, ptStar.x, ptStar.y, CoolInterface.m_crWindow );
		}
	}
	else if ( m_nRating == 1 )
	{
		ptStar.x -= 16;
		ShellIcons.Draw( &dc, SHI_FAKE, 16, ptStar.x, ptStar.y, CoolInterface.m_crWindow );
	}
	
	rcWork.top += 20;
	
	dc.FillSolidRect( rcWork.left, rcWork.top, rcWork.Width(), 1, CoolInterface.m_crMargin );
	dc.ExcludeClipRect( rcWork.left, rcWork.top, rcWork.right, rcWork.top + 1 );
	dc.SetBkColor( CoolInterface.m_crWindow );
	rcWork.top += 4;
	
	dc.SelectObject( &CoolInterface.m_fntBold );
	LoadString( str, IDS_TIP_SIZE );
	DrawText( &dc, rcWork.right - 100, rcWork.top, str + ':' );
	dc.SelectObject( &CoolInterface.m_fntNormal );
	DrawText( &dc, rcWork.right - 60, rcWork.top, m_sSize );
	if ( m_pReviews.GetCount() )
	{
		dc.SelectObject( &CoolInterface.m_fntUnder );
		dc.SetTextColor( RGB( 0, 0, 255 ) );
	}
	DrawText( &dc, rcWork.left, rcWork.top, m_sStatus, &m_rcStatus );
	rcWork.top += 18;
	
	m_pMetadata.Paint( &dc, &rcWork );
	
	dc.SetViewportOrg( 0, 0 );
	dc.SelectObject( &CoolInterface.m_fntCaption );
	dc.SetBkColor( CoolInterface.m_crWindow );
	dc.SetTextColor( 0 );
	
	for ( POSITION pos = m_pReviews.GetHeadPosition() ; pos ; )
	{
		Review* pReview = (Review*)m_pReviews.GetNext( pos );
		pReview->Paint( &dc, GetScrollPos( SB_VERT ) );
	}
	
	dc.SelectObject( pOldFont );
	dc.FillSolidRect( &rcClient, CoolInterface.m_crWindow );
}

void CSearchDetailPanel::DrawText(CDC* pDC, int nX, int nY, LPCTSTR pszText, RECT* pRect)
{
	CSize sz = pDC->GetTextExtent( pszText, _tcslen( pszText ) );
	CRect rc( nX - 2, nY - 2, nX + sz.cx + 2, nY + sz.cy + 2 );
	
	pDC->ExtTextOut( nX, nY, ETO_CLIPPED|ETO_OPAQUE, &rc, pszText, _tcslen( pszText ), NULL );
	pDC->ExcludeClipRect( &rc );
	
	if ( pRect != NULL ) CopyMemory( pRect, &rc, sizeof(RECT) );
}

void CSearchDetailPanel::DrawThumbnail(CDC* pDC, CRect& rcClient, CRect& rcWork)
{
	int nThumbSize = rcClient.Height() - 16;
	nThumbSize = max( nThumbSize, 64 );
	nThumbSize = min( nThumbSize, 128 );

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -